Initial revision
[pintos-anon] / src / devices / 16550a.h
1 #ifndef HEADER_16550A_H
2 #define HEADER_16550A_H 1
3
4 #include <stdbool.h>
5 #include <stdint.h>
6 #include "debug.h"
7
8 /* Register definitions for the 16550A UART used in PCs.  This is
9    a full definition of all the registers and their bits.  We
10    only use a few of them, however.  */
11    
12 /* I/O port base address for the first serial port. */
13 #define IO_BASE 0x3f8
14
15 /* DLAB=0 registers. */
16 #define RBR_REG (IO_BASE + 0)   /* Receiver Buffer Reg. (read-only). */
17 #define THR_REG (IO_BASE + 0)   /* Transmitter Holding Reg. (write-only). */
18 #define IER_REG (IO_BASE + 1)   /* Interrupt Enable Reg. (read-only). */
19 #define IIR_REG (IO_BASE + 2)   /* Interrupt Ident. Reg. (read-only). */
20 #define FCR_REG (IO_BASE + 2)   /* FIFO Control Reg. (write-only). */
21 #define LCR_REG (IO_BASE + 3)   /* Line Control Register. */
22 #define MCR_REG (IO_BASE + 4)   /* MODEM Control Register. */
23 #define LSR_REG (IO_BASE + 5)   /* Line Status Register (read-only). */
24 #define MSR_REG (IO_BASE + 6)   /* MODEM Status Register. */
25 #define SCR_REG (IO_BASE + 7)   /* Scratch Register. */
26
27 /* DLAB=1 registers. */
28 #define LS_REG (IO_BASE + 0)    /* Divisor Latch (LSB). */
29 #define MS_REG (IO_BASE + 1)    /* Divisor Latch (MSB). */
30
31 /* Interrupt Enable Register bits. */
32 #define IER_RECV 0x01           /* Enable interrupt when data received. */
33 #define IER_XMIT 0x02           /* Interrupt when transmit finishes. */
34 #define IER_LSR  0x04           /* Interrupt when LSR changes. */
35 #define IER_MSR  0x08           /* Interrupt when MSR changes. */
36
37 /* Interrupt Identification Register bits. */
38 #define IIR_PENDING 0x01        /* 0=interrupt pending. */
39 #define IIR_ID(IIR) (((IIR) >> 1) & 7)      /* Interrupt ID. */
40 #define IIR_FIFO 0xc0           /* Set when FIFO is enabled. */
41
42 /* FIFO Control Register bits. */
43 #define FCR_FIFO 0x01           /* 1=Enable FIFOs. */
44 #define FCR_RECV_RESET 0x02     /* 1=Reset receive FIFO. */
45 #define FCR_XMIT_RESET 0x04     /* 1=Reset transmit FIFO. */
46 #define FCR_DMA_MODE 0x08       /* 0=DMA mode 0, 1=DMA mode 1. */
47 #define FCR_FIFO_TRIGGER 0xc0   /* Mask for FIFO trigger level. */
48
49 /* Line Control Register bits. */
50 enum parity_type
51   {
52     NONE,               /* No parity bit. */
53     ODD,                /* Odd parity. */
54     EVEN,               /* Even parity. */
55     MARK,               /* Parity bit set to 1. */
56     SPACE               /* Parity bit set to 0. */
57   };
58
59 static inline uint8_t
60 make_lcr (int bits, enum parity_type parity, int stop, bool send_break,
61           bool dlab) 
62 {
63   uint8_t lcr = 0;
64
65   ASSERT (bits >= 5 && bits <= 8);
66   switch (bits) 
67     {
68     case 5: lcr |= 0x00; break;
69     case 6: lcr |= 0x01; break;
70     case 7: lcr |= 0x02; break;
71     case 8: lcr |= 0x03; break;
72     }
73
74   switch (parity)
75     { 
76     case NONE: lcr |= 0x00; break;
77     case ODD: lcr |= 0x08; break;
78     case EVEN: lcr |= 0x18; break;
79     case MARK: lcr |= 0x28; break;
80     case SPACE: lcr |= 0x38; break;
81     default: panic ("bad parity %d", (int) parity); 
82     }
83
84   ASSERT (stop == 1 || stop == 2);
85   if (stop > 1)
86     lcr |= 0x04;
87
88   if (send_break)
89     lcr |= 0x40;
90   if (dlab)
91     lcr |= 0x80;
92
93   return lcr;
94 }
95
96 /* MODEM Control Register. */
97 #define MCR_DTR 0x01            /* Data Terminal Ready. */
98 #define MCR_RTS 0x02            /* Request to Send. */
99 #define MCR_OUT1 0x04           /* Output line 1. */
100 #define MCR_OUT2 0x08           /* Output line 2. */
101 #define MCR_LOOP 0x10           /* Loopback enable. */
102
103 /* Line Status Register. */
104 #define LSR_DR 0x01             /* Data Ready. */
105 #define LSR_OE 0x02             /* Overrun Error. */
106 #define LSR_PE 0x04             /* Parity Error. */
107 #define LSR_FE 0x08             /* Framing Error. */
108 #define LSR_BI 0x10             /* Break Interrupt. */
109 #define LSR_THRE 0x20           /* THR Empty. */
110 #define LSR_TEMT 0x40           /* Transmitter Empty. */
111 #define LSR_ERF 0x80            /* Error in Receiver FIFO. */
112
113 /* MODEM Status Register. */
114 #define MSR_DCTS 0x01           /* Delta Clear to Send. */
115 #define MSR_DDSR 0x02           /* Delta Data Set Ready. */
116 #define MSR_TERI 0x04           /* Trailing Edge Ring Indicator. */
117 #define MSR_DDCD 0x08           /* Delta Data Carrier Detect. */
118 #define MSR_CTS  0x10           /* Clear To Send. */
119 #define MSR_DSR  0x20           /* Data Set Ready. */
120 #define MSR_RI   0x40           /* Ring Indicator. */
121 #define MSR_DCD  0x80           /* Data Carrier Detect. */
122
123 #endif /* 16550a.h */