From fd2333e81ce9bd9a2f279a2e7cd7a846814a0515 Mon Sep 17 00:00:00 2001 From: quackerd Date: Wed, 20 Nov 2024 13:37:41 -0500 Subject: [PATCH] uart rx --- sys/arm64/machine.c | 14 ++++++--- sys/arm64/timer.c | 4 +-- sys/arm64/trap.c | 1 - sys/dev/arm64/uart.c | 67 +++++++++++++++++++++++++++++++++++++++++-- sys/dev/arm64/uart.h | 3 ++ sys/dev/console.c | 4 +-- sys/dev/console.h | 1 + sys/include/kassert.h | 4 +-- sys/include/sysctl.h | 2 +- 9 files changed, 84 insertions(+), 16 deletions(-) diff --git a/sys/arm64/machine.c b/sys/arm64/machine.c index eeb4fa2..4b2a794 100644 --- a/sys/arm64/machine.c +++ b/sys/arm64/machine.c @@ -30,9 +30,10 @@ #include #include -extern void MachineBoot_AddMem(); -extern void Loader_LoadInit(); -extern void PAlloc_LateInit(); +extern void MachineBoot_AddMem(void); +extern void Loader_LoadInit(void); +extern void PAlloc_LateInit(void); +extern void Console_LateInit(void); /** * Machine_SyscallInit -- @@ -71,7 +72,11 @@ Machine_EarlyInit() static void Machine_IdleThread(UNUSED void *test) { - while (1) { kprintf("Idle Thread!\n"); enable_interrupts(); hlt(); } + while (1) { + // kprintf("Idle Thread!\n"); + enable_interrupts(); + hlt(); + } } /** @@ -102,6 +107,7 @@ void Machine_Init() * Initialize Interrupts */ IRQ_Init(); + Console_LateInit(); /* * Initialize Time Keeping diff --git a/sys/arm64/timer.c b/sys/arm64/timer.c index d85aebb..7e8abb2 100644 --- a/sys/arm64/timer.c +++ b/sys/arm64/timer.c @@ -13,7 +13,7 @@ #include #include -#define KTIMER_HZ (1) +#define KTIMER_HZ (100) #define KTIMER_IRQ (30) // hardcode to 2024/03/14 12:34:56 AM EST #define KTIMER_EPOCH (1710390896ull) @@ -36,7 +36,7 @@ PTimer_Tick(UNUSED void * arg) gic_send_eoi(KTIMER_IRQ); KTimer_Process(); - kprintf("Hardware timer tick, epoch = %lu, tsc = %lu, CVAL = %lu.\n", KTime_GetEpoch(), Time_GetTSC(), SYSREG_GET(CNTP_CVAL_EL0)); + //kprintf("Hardware timer tick, epoch = %lu, tsc = %lu, CVAL = %lu.\n", KTime_GetEpoch(), Time_GetTSC(), SYSREG_GET(CNTP_CVAL_EL0)); Sched_Scheduler(); } diff --git a/sys/arm64/trap.c b/sys/arm64/trap.c index cf3e02c..fd54230 100644 --- a/sys/arm64/trap.c +++ b/sys/arm64/trap.c @@ -32,7 +32,6 @@ IRQ_Init() LIST_INIT(&handlers[i]); } - enable_interrupts(); kprintf("Initialized IRQ!\n"); } diff --git a/sys/dev/arm64/uart.c b/sys/dev/arm64/uart.c index 7c84ae9..d695e66 100644 --- a/sys/dev/arm64/uart.c +++ b/sys/dev/arm64/uart.c @@ -3,6 +3,9 @@ #include #include +#include +#include "../console.h" +#include #include #include @@ -11,6 +14,7 @@ #define UART_DR_OFFSET (0x000) #define UART_FR_OFFSET (0x018) #define UART_FR_BUSY (1 << 3) +#define UART_FR_RXFE (1 << 4) #define UART_IBRD_OFFSET (0x024) #define UART_FBRD_OFFSET (0x028) #define UART_LCR_OFFSET (0x02c) @@ -19,9 +23,16 @@ #define UART_CR_OFFSET (0x030) #define UART_CR_UARTEN (1) #define UART_CR_TXEN (1 << 8) +#define UART_CR_RXEN (1 << 9) #define UART_IMSC_OFFSET (0x038) +#define UART_IMSC_RXIM (1 << 4) #define UART_DMACR_OFFSET (0x048) +#define UART_ISR_OFFSET (0x3C) +#define UART_ICR_OFFSET (0x44) +#define UART_ICR_RXIC (1 << 4) +#define UART_INTR_NUM (37) + struct uart { uintptr_t base; uint64_t clock; @@ -40,6 +51,8 @@ static struct uart g_uart0 = { .initialized = 0 }; +static struct IRQHandler uartRx; + static void uart_writereg(const struct uart *dev, uintptr_t offset, uint32_t val) { @@ -117,14 +130,14 @@ uart_init(struct uart *dev) lcr |= UART_LCR_STP2; // parity disabled, FIFO disabled, stick parity disabled - // Mask all interrupts by setting corresponding bits to 1 - uart_writereg(dev, UART_IMSC_OFFSET, 0x7ff); + // enable only RX interrupt + uart_writereg(dev, UART_IMSC_OFFSET, UART_IMSC_RXIM); // Disable DMA by setting all bits to 0 uart_writereg(dev, UART_DMACR_OFFSET, 0x0); // enable tx & uart - uart_writereg(dev, UART_CR_OFFSET, UART_CR_TXEN | UART_CR_UARTEN); + uart_writereg(dev, UART_CR_OFFSET, UART_CR_TXEN | UART_CR_UARTEN | UART_CR_RXEN); dev->initialized = 1; } @@ -145,6 +158,47 @@ uart_send(const struct uart *dev, const char *data, size_t size) } } +static inline char +uart_char_sanitize(char ch) +{ + if (ch == 13) { + return 0x0A; + } else { + return ch; + } +} + +static void +uart_rx_intr(void * arg) +{ + const struct uart * dev = (const struct uart *)arg; + + while(true) { + const uint16_t flags = uart_readreg(dev, UART_FR_OFFSET); + + if (flags & UART_FR_RXFE) { + break; + } + const uint16_t data = uart_readreg(dev, UART_DR_OFFSET); + const char ch = data & 0xff; + // kprintf("UART KEY: %d\n", ch); + Console_EnqueueKey(uart_char_sanitize(ch)); + } + + // clear RX interrupt flag + uart_writereg(dev, UART_ICR_OFFSET, UART_ICR_RXIC); + gic_send_eoi(UART_INTR_NUM); +} + +static void +uart_rx_init(const struct uart *dev) +{ + uartRx.arg = &g_uart0; + uartRx.irq = UART_INTR_NUM; + uartRx.cb = uart_rx_intr; + IRQ_Register(UART_INTR_NUM, &uartRx); +} + void Serial_Send(const char *data, size_t size) { @@ -158,4 +212,11 @@ Serial_Init(void) { uart_init(&g_uart0); kprintf("Initialized PL011 UART, base = 0x%lx.\n", g_uart0.base); +} + +void +Serial_LateInit(void) +{ + uart_rx_init(&g_uart0); + kprintf("Initialized PL011 RX mode.\n"); } \ No newline at end of file diff --git a/sys/dev/arm64/uart.h b/sys/dev/arm64/uart.h index bf2cc9c..ea38551 100644 --- a/sys/dev/arm64/uart.h +++ b/sys/dev/arm64/uart.h @@ -5,5 +5,8 @@ void Serial_Init(void); +void +Serial_LateInit(void); + void Serial_Send(const char *data, size_t size); diff --git a/sys/dev/console.c b/sys/dev/console.c index c4b27fd..a288025 100644 --- a/sys/dev/console.c +++ b/sys/dev/console.c @@ -50,9 +50,7 @@ Console_Init() void Console_LateInit() { -#if defined(__x86_64__) - Serial_LateInit(); -#endif + Serial_LateInit(); } char diff --git a/sys/dev/console.h b/sys/dev/console.h index af1fbf8..0084e4e 100644 --- a/sys/dev/console.h +++ b/sys/dev/console.h @@ -28,6 +28,7 @@ typedef struct Console { } Console; void Console_Init(); +void Console_LateInit(); char Console_Getc(); void Console_Gets(char *str, size_t n); void Console_Putc(char ch); diff --git a/sys/include/kassert.h b/sys/include/kassert.h index 5dcdf9b..1170565 100644 --- a/sys/include/kassert.h +++ b/sys/include/kassert.h @@ -42,12 +42,12 @@ NO_RETURN void Debug_Assert(const char *fmt, ...); #define Warning(_module, _format, ...) kprintf(#_module ": " _format, ##__VA_ARGS__) // Normal Logging #define Log(_module, _format, ...) \ - if (SYSCTL_GETINT(log_##_module) >= 1 || 1) { \ + if (SYSCTL_GETINT(log_##_module) >= 1) { \ kprintf(#_module ": " _format, ##__VA_ARGS__); \ } // Debug Logging #define DLOG(_module, _format, ...) \ - if (SYSCTL_GETINT(log_##_module) >= 5 || 1) { \ + if (SYSCTL_GETINT(log_##_module) >= 5) { \ kprintf(#_module ": " _format, ##__VA_ARGS__); \ } // Verbose Logging diff --git a/sys/include/sysctl.h b/sys/include/sysctl.h index d5c8785..81a9148 100644 --- a/sys/include/sysctl.h +++ b/sys/include/sysctl.h @@ -25,7 +25,7 @@ SYSCTL_INT(kern_hz, SYSCTL_FLAG_RW, "Tick frequency", 100) \ SYSCTL_INT(time_tzadj, SYSCTL_FLAG_RW, "Time zone offset in seconds", 0) \ SYSCTL_INT(log_e1000, SYSCTL_FLAG_RW, "E1000 log level", 10) \ - SYSCTL_INT(log_ide, SYSCTL_FLAG_RW, "IDE log level", 0) \ + SYSCTL_INT(log_ide, SYSCTL_FLAG_RW, "IDE log level", 1) \ SYSCTL_INT(log_loader, SYSCTL_FLAG_RW, "Loader log level", 0) \ SYSCTL_INT(log_o2fs, SYSCTL_FLAG_RW, "O2FS log level", 0) \ SYSCTL_INT(log_syscall, SYSCTL_FLAG_RW, "Syscall log level", 0) \