diff --git a/arch/x86/kernel/uart.c b/arch/x86/kernel/uart.c index 12e7a3f..e39adbb 100644 --- a/arch/x86/kernel/uart.c +++ b/arch/x86/kernel/uart.c @@ -53,6 +53,7 @@ #define UART_DLL 0 /* Out: Divisor Latch Low */ #define UART_DLM 1 /* Out: Divisor Latch High */ #define UART_LCR 3 /* Out: Line Control Register */ +#define UART_LSR 5 /* Line Status Register */ #define UART_IER_MSI 0x08 /* Enable Modem status interrupt */ #define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */ @@ -70,7 +71,11 @@ #define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */ #define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */ #define UART_FCR_TRIGGER_MASK 0xC0 /* Mask for the FIFO trigger range */ -#define UART_FCR_TRIGGER_1 0x00 /* Mask for trigger set at 1 */ +#define UART_FCR_TRIGGER_1 0x00 /* Trigger RDI at FIFO level 1 byte */ +#define UART_FCR_TRIGGER_4 0x40 /* Trigger RDI at FIFO level 4 byte */ +#define UART_FCR_TRIGGER_8 0x80 /* Trigger RDI at FIFO level 8 byte */ +#define UART_FCR_TRIGGER_14 0xc0 /* Trigger RDI at FIFO level 14 byte*/ + #define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ #define UART_LCR_SBC 0x40 /* Set break control */ @@ -163,13 +168,31 @@ static void uart_handler(struct state *s) unsigned char c = read_from_uart(UART_IIR); while (!(c & UART_IIR_NO_INT)) { - kprintf("c = 0x%x\n", c); + //kprintf("c = 0x%x\n", c); + if (c & UART_IIR_RDI) { c = uart_getchar(); mailbox_uint8_post(&input_queue, c); + + goto out; } + if(c & UART_IIR_THRI) { + // acknowledge interrupt + c = read_from_uart(UART_IIR); + + goto out; + } + + if(c & UART_IIR_RLSI) { + // acknowledge interrupt + c = read_from_uart(UART_LSR); + + goto out; + } + +out: c = read_from_uart(UART_IIR); } } @@ -227,7 +250,7 @@ static void uart_config(void) write_to_uart(UART_LCR, lcr & (~UART_LCR_DLAB)); /* enable interrupt */ - write_to_uart(UART_IER, UART_IER_RDI /*| UART_IER_RLSI | UART_IER_THRI*/); + write_to_uart(UART_IER, UART_IER_RDI | UART_IER_RLSI | UART_IER_THRI); int err = create_kernel_task(&id, uart_thread, NULL, HIGH_PRIO); if (BUILTIN_EXPECT(err, 0)) @@ -248,6 +271,13 @@ int uart_init(void) // Searching for Qemu's UART device if (pci_get_device_info(0x1b36, 0x0002, &pci_info) == 0) goto Lsuccess; + // Searching for Qemu's 2x UART device (pci-serial-2x) + if (pci_get_device_info(0x1b36, 0x0003, &pci_info) == 0) + goto Lsuccess; + // Searching for Qemu's 4x UART device (pci-serial-4x) + if (pci_get_device_info(0x1b36, 0x0003, &pci_info) == 0) + goto Lsuccess; + return -1;