e5b2fb7de3f0d5fe4fae45fbdf02fb6ee3cd0067
[pintos-anon] / src / devices / serial.c
1 #include "serial.h"
2 #include "16550a.h"
3 #include "debug.h"
4 #include "io.h"
5 #include "timer.h"
6
7 static void set_serial (int bps, int bits, enum parity_type parity, int stop);
8
9 /* Initializes the serial port device. */
10 void
11 serial_init (void) 
12 {
13   outb (IER_REG, 0);    /* Turn off all interrupts. */
14   outb (FCR_REG, 0);    /* Disable FIFO. */
15   set_serial (9600, 8, NONE, 1);
16   outb (MCR_REG, 0);    /* Turn off output lines. */
17 }
18
19 /* Sends BYTE to the serial port. */
20 void
21 serial_outb (uint8_t byte) 
22 {
23   while ((inb (LSR_REG) & LSR_THRE) == 0)
24     continue;
25   outb (THR_REG, byte);
26 }
27
28 /* Configures the first serial port for BPS bits per second,
29    BITS bits per byte, the given PARITY, and STOP stop bits. */
30 static void
31 set_serial (int bps, int bits, enum parity_type parity, int stop)
32 {
33   int baud_base = 1843200 / 16;         /* Base rate of 16550A. */
34   uint16_t divisor = baud_base / bps;   /* Clock rate divisor. */
35     
36   /* Enable DLAB. */
37   outb (LCR_REG, make_lcr (bits, parity, stop, false, true));
38
39   /* Set baud rate. */
40   outb (LS_REG, divisor & 0xff);
41   outb (MS_REG, divisor >> 8);
42   
43   /* Reset DLAB. */
44   outb (LCR_REG, make_lcr (bits, parity, stop, false, false));
45 }