Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel'
[palacios.git] / kitten / drivers / console / serial.c
1 #include <lwk/driver.h>
2 #include <lwk/console.h>
3 #include <lwk/interrupt.h>
4 #include <arch/io.h>
5
6 // Serial port registers
7 #define TXB             0       // Transmitter Holding Buffer            W
8 #define RXB             0       // Receiver Buffer                       R
9 #define DLL             0       // Divisor Latch Low Byte               R/W
10 #define IER             1       // Interrupt Enable Register            R/W
11 #define DLH             1       // Divisor Latch High Byte              R/W
12 #define IIR             2       // Interrupt Identification Register     R
13 #define FCR             2       // FIFO Control Register                 W
14 #define LCR             3       // Line Control Register                R/W
15 #define MCR             4       // Modem Control Register               R/W
16 #define LSR             5       // Line Status Register                  R
17 #define MSR             6       // Modem Status Register                 R
18 #define SCR             7       // Scratch Register                     R/W
19
20 // IER bits
21 #define IER_RLSI        0x08    // RX interrupt
22 #define IER_THRI        0x02    // TX interrupt
23 #define IER_RDI         0x01    // Reciver data interrupt
24
25 // MCR bits
26 #define MCR_DTR         0x01    // Enable DTR
27 #define MCR_RTS         0x02    // Enable RTS
28 #define MCR_OUT2        0x08    // Enable Out2 (?)
29
30 // LSR bits
31 #define LSR_TXEMPT      0x20    // Empty TX holding register
32 #define LSR_RXRDY       0x01    // Ready to receive
33
34 // LCR bits
35 #define LCR_DLAB        0x80    // Divisor latch access bit
36
37 /** IO port address of the serial port. */
38 static unsigned int port = 0x3F8;  // COM1
39
40 /** Serial port baud rate. */
41 static unsigned int baud = 9600;
42 #define SERIAL_MAX_BAUD 115200
43
44 /** Set when serial console has been initialized. */
45 static int initialized = 0;
46
47 /**
48  * Prints a single character to the serial port.
49  */
50 static void serial_putc(unsigned char c)
51 {
52         // Wait until the TX buffer is empty
53         while ((inb_p(port + LSR) & LSR_TXEMPT) == 0)
54                 ;
55         // Slam the 8 bits down the 1 bit pipe... meeeooowwwy!
56         outb(c, port);
57 }
58
59 /**
60  * Writes a string to the serial port.
61  */
62 static void serial_write(struct console *con, const char *str)
63 {
64         unsigned char c;
65         while ((c = *str++) != '\0') {
66                 serial_putc(c);
67                 if (c == '\n')                  // new line
68                         serial_putc('\r');      // tack on carriage return
69         }
70 }
71
72 /**
73  * Serial port console device.
74  */
75 static struct console serial_console = {
76         .name  = "Serial Console",
77         .write = serial_write
78 };
79
80 /**
81  * Initializes and registers the serial console driver.
82  */
83 void serial_console_init(void)
84 {
85         // Setup the divisor latch registers for the specified baud rate
86         unsigned int div = SERIAL_MAX_BAUD / baud;
87
88         if (initialized) {
89                 printk(KERN_ERR "Serial console already initialized.\n");
90                 return;
91         }
92
93         outb( inb(port+LCR) | LCR_DLAB  , port+LCR ); // set DLAB
94         outb( (div>>0) & 0xFF           , port+DLL ); // set divisor low byte
95         outb( (div>>8) & 0xFF           , port+DLH ); // set divisor high byte
96         outb( inb(port+LCR) & ~LCR_DLAB , port+LCR ); // unset DLAB
97         
98         outb( 0x0 , port+IER ); // Disable serial port interrupts
99         outb( 0x0 , port+FCR ); // Don't use the FIFOs
100         outb( 0x3 , port+LCR ); // 8n1
101
102         // Setup modem control register
103         outb( MCR_RTS | MCR_DTR | MCR_OUT2 , port+MCR);
104
105         console_register(&serial_console);
106         initialized = 1;
107 }
108
109 driver_init(serial_console_init);
110
111 /**
112  * Configurable parameters for controlling the serial port
113  * I/O port address and baud.
114  */
115 driver_param(port, uint);
116 driver_param(baud, uint);
117