summaryrefslogtreecommitdiff
path: root/na/drivers/uart.cc
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-04-21 23:20:56 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-04-21 23:20:56 +0800
commit92ac3931ec7c2ee7746d38499edd9179c943c5ac (patch)
treef524c59467df9317cbf0a480fd542601a3f1c981 /na/drivers/uart.cc
parentf5272c51b11ec06627d748901c7747154f3bbf04 (diff)
downloadlume-92ac3931ec7c2ee7746d38499edd9179c943c5ac.tar.gz
lume-92ac3931ec7c2ee7746d38499edd9179c943c5ac.tar.xz
feat: add initial implementation of PLIC and UART drivers
Diffstat (limited to 'na/drivers/uart.cc')
-rw-r--r--na/drivers/uart.cc44
1 files changed, 44 insertions, 0 deletions
diff --git a/na/drivers/uart.cc b/na/drivers/uart.cc
new file mode 100644
index 0000000..802e88d
--- /dev/null
+++ b/na/drivers/uart.cc
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* Copyright (C) 2026 Richard Qin */
+
+/*
+ * uart.cc — 16550a UART driver (early console)
+ *
+ * Implements the early UART output mapping required by panic and kernel_main.
+ */
+
+#include <lume/console.h>
+#include <lume/fdt.h>
+#include <lume/vmm.h>
+#include <lume/addr.h>
+#include <arch/config.h>
+
+static uint64 g_uart_pa = arch::kDefaultUartPA;
+
+extern "C" void early_putc(char c) {
+ if (!g_uart_pa) return;
+ volatile auto* uart = reinterpret_cast<volatile uint8*>(pa_to_va(g_uart_pa));
+ *uart = static_cast<uint8>(c);
+}
+
+extern "C" void early_puts(const char* s) {
+ while (*s) early_putc(*s++);
+}
+
+void console_early_init(uint64 fdt_paddr) {
+ uint64 pa = 0;
+ FdtManager::early_scan_uart(fdt_paddr, &pa);
+ if (pa != 0) {
+ g_uart_pa = pa;
+ }
+}
+
+void console_init() {
+ /*
+ * Once vmm_init() activates the new page table, the 1GB identity map is dropped.
+ * The UART must be explicitly registered into the active page table.
+ */
+ if (g_uart_pa != 0) {
+ vmm_map_kernel_mmio(g_uart_pa, 0x1000);
+ }
+}