diff options
author | Quinn Stephens <quinn@osmora.org> | 2025-02-14 23:46:17 -0500 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-02-15 01:11:00 -0500 |
commit | 187f684a91e9ad91d8b29a3405a7968be326bb2e (patch) | |
tree | 59fff74560d84052eea02283fd4f264448c3eb0f /sys/arch/amd64/amd64 | |
parent | 6f74de54f35042fa03e5e8626065de9998a88ea6 (diff) |
kernel: amd64: Add more defines to UART driver
Added more defines and comments to the UART driver, based on the 16550
chip datasheet, to make it more clear how each operation works.
Signed-off-by: Quinn Stephens <quinn@osmora.org>
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys/arch/amd64/amd64')
-rw-r--r-- | sys/arch/amd64/amd64/uart.c | 67 |
1 files changed, 52 insertions, 15 deletions
diff --git a/sys/arch/amd64/amd64/uart.c b/sys/arch/amd64/amd64/uart.c index 9c78434..3629425 100644 --- a/sys/arch/amd64/amd64/uart.c +++ b/sys/arch/amd64/amd64/uart.c @@ -31,51 +31,88 @@ #include <machine/uart.h> #include <machine/pio.h> +/* Channel port numbers */ #define UART_COM1 0x3F8 +#define UART_COM2 0x2F8 +#define UART_COM3 0x3E8 +#define UART_COM4 0x2E8 +#define UART_COM5 0x5F8 +#define UART_COM6 0x4F8 +#define UART_COM7 0x5E8 +#define UART_COM8 0x4E8 + +/* Register offsets */ #define UART_REG(OFFSET) (UART_COM1 + OFFSET) +#define UART_REG_FCR UART_REG(2) /* FIFO Control Register */ +#define UART_REG_LCR UART_REG(3) /* Line Control Register */ +#define UART_REG_MCR UART_REG(4) /* MODEM Control Register */ +#define UART_REG_LSR UART_REG(5) /* Line Status Register */ +#define UART_REG_MSR UART_REG(6) /* MODEM Status Register */ +#define UART_REG_SR UART_REG(7) /* Scratch Register */ + +/* Registers when LCR.DLAB=0 */ +#define UART_REG_RBR UART_REG(0) /* Receiver Buffer Register */ +#define UART_REG_THR UART_REG(0) /* Transmitter Holding Register */ +#define UART_REG_IER UART_REG(1) /* Interrupt Enable Register */ + +/* Registers when LCR.DLAB=1 */ +#define UART_REG_DLL UART_REG(0) /* Divisor Latch Low */ +#define UART_REG_DLH UART_REG(1) /* Divisor Latch High */ + +#define UART_LCR_WLS0 BIT(0) /* Word Length Select Bit 0 */ +#define UART_LCR_WLS1 BIT(1) /* Word Length Select Bit 1 */ +#define UART_LCR_DLAB BIT(7) /* Divisor Latch Access Bit*/ + +#define UART_MCR_DTR BIT(0) /* Data Terminal Ready*/ +#define UART_MCR_LOOP BIT(4) /* Loop */ + +#define UART_LSR_THRE BIT(5) /* Transmitter Holding Register */ + +#define UART_DIVISOR(RATE) (115200 / RATE) static inline bool uart_transmit_empty(void) { - return ISSET(UART_REG(5), BIT(5)); + return ISSET(UART_REG_LSR, UART_LSR_THRE); } void uart_write(char byte) { while (!uart_transmit_empty()); - outb(UART_COM1, byte); + outb(UART_REG_THR, byte); } int uart_init(void) { /* Disable interrupts */ - outb(UART_REG(1), 0x00); + outb(UART_REG_IER, 0x00); /* Set DLAB to set baud rate */ - outb(UART_REG(3), 0x80); + outb(UART_REG_LCR, UART_LCR_DLAB); - /* Set rate to 57600 baud */ - outb(UART_REG(0), 0x02); - outb(UART_REG(1), 0x00); + /* Set speed to 57600 baud */ + outb(UART_REG_DLL, UART_DIVISOR(57600)); + outb(UART_REG_IER, 0x00); - /* Set data word length to 8 bits and clear DLAB */ - outb(UART_REG(3), 0x03); + /* Set word size to 8 bits and clear DLAB */ + outb(UART_REG_LCR, UART_LCR_WLS0 | UART_LCR_WLS1); /* Disable FIFOs for now... (TODO: Use them) */ - outb(UART_REG(2), 0x00); + outb(UART_REG_FCR, 0x00); - /* Test chip with loopback mode */ - outb(UART_REG(4), 0x10); - outb(UART_REG(0), 0xF0); - if (inb(UART_REG(0) != 0xF0)) + /* Test chip in loopback mode */ + outb(UART_REG_MCR, UART_MCR_LOOP); + outb(UART_REG_THR, 0xF0); + if (inb(UART_REG_RBR != 0xF0)) return -1; /* * Mark the data terminal ready and clear * loopback mode. */ - outb(UART_REG(4), 0x01); + outb(UART_REG_MCR, UART_MCR_DTR); return 0; } +
\ No newline at end of file |