summaryrefslogtreecommitdiff
path: root/kernel/drivers/char
diff options
context:
space:
mode:
authorArseney300 <Arseney300@gmail.com>2026-04-23 17:02:05 +0700
committerArseney300 <Arseney300@gmail.com>2026-04-23 17:02:05 +0700
commite935c3afba9b3a492ad804726fa0fd97d437d8f5 (patch)
treec8c26fe36ed4db1ffec4dab5f5bf3b489c064a07 /kernel/drivers/char
parent496246c92dabe6757480147016490ea6ae43bb66 (diff)
WIP: add driver objectsWIP/add_driver_obj
Diffstat (limited to 'kernel/drivers/char')
-rw-r--r--kernel/drivers/char/pl011.cpp83
-rw-r--r--kernel/drivers/char/uart_16550.cpp85
2 files changed, 168 insertions, 0 deletions
diff --git a/kernel/drivers/char/pl011.cpp b/kernel/drivers/char/pl011.cpp
new file mode 100644
index 0000000..7615370
--- /dev/null
+++ b/kernel/drivers/char/pl011.cpp
@@ -0,0 +1,83 @@
+// ============================================================================
+// drivers/char/pl011.cpp — PL011 UART console driver + device (aarch64)
+//
+// Stub implementation that compiles but does no real I/O yet.
+// TODO: Program IBRD, FBRD, LCR_H, CR registers for actual UART output.
+// ============================================================================
+
+#include <kernel/console_driver.h>
+#include <kernel/early_driver.h>
+#include <kernel/early_device.h>
+#include <kernel/platform_bus.h>
+
+// ── PL011Device ───────────────────────────────────────────────────────────
+
+class PL011Device : public Device, public EarlyDevice<PL011Device> {
+public:
+ explicit PL011Device(uintptr_t base_addr) : base_(base_addr) {}
+
+ const char* name() const override { return "uart0"; }
+ uintptr_t base() const { return base_; }
+
+private:
+ uintptr_t base_;
+};
+
+// ── PL011Console driver ──────────────────────────────────────────────────
+
+class PL011Console : public ConsoleDriver,
+ public EarlyDriver<PL011Console> {
+public:
+ PL011Console() = default;
+
+ const char* name() const override { return "pl011-uart"; }
+
+ bool init() override {
+ auto* dev = static_cast<PL011Device*>(device());
+ base_ = dev->base();
+
+ // TODO: Configure UART registers at base_:
+ // UARTIBRD (offset 0x24) — integer baud rate divisor
+ // UARTFBRD (offset 0x28) — fractional baud rate divisor
+ // UARTLCR_H (offset 0x2C) — line control (8N1, FIFO enable)
+ // UARTCR (offset 0x30) — control register (TX enable, UART enable)
+ initialized_ = true;
+ return true;
+ }
+
+ void shutdown() override {
+ initialized_ = false;
+ }
+
+ void putchar(char c) override {
+ if (!initialized_) return;
+ // TODO: while (*(volatile uint32_t*)(base_ + 0x18) & (1 << 5)) {}
+ // *(volatile uint32_t*)(base_ + 0x00) = c;
+ (void)c;
+ }
+
+ void clear() override {
+ // UART has no screen to clear
+ }
+
+private:
+ uintptr_t base_ = 0;
+ bool initialized_ = false;
+};
+
+// ── Driver init function ──────────────────────────────────────────────────
+
+namespace console {
+
+void init_pl011(uintptr_t base_addr) {
+ auto* dev = PL011Device::create(base_addr);
+ platform::bus().add_device(dev);
+
+ auto* drv = PL011Console::create();
+ drv->bind(dev);
+ drv->init();
+
+ console::register_driver(drv);
+}
+
+} // namespace console
diff --git a/kernel/drivers/char/uart_16550.cpp b/kernel/drivers/char/uart_16550.cpp
new file mode 100644
index 0000000..a85b5e7
--- /dev/null
+++ b/kernel/drivers/char/uart_16550.cpp
@@ -0,0 +1,85 @@
+// ============================================================================
+// drivers/char/uart_16550.cpp — 16550 UART console driver + device (x86_64)
+//
+// Stub implementation that compiles but does no real I/O yet.
+// TODO: Program divisor latch, 8N1, FIFO, implement actual port I/O.
+// ============================================================================
+
+#include <kernel/console_driver.h>
+#include <kernel/early_driver.h>
+#include <kernel/early_device.h>
+#include <kernel/platform_bus.h>
+
+// ── UART16550Device ───────────────────────────────────────────────────────
+
+class UART16550Device : public Device, public EarlyDevice<UART16550Device> {
+public:
+ explicit UART16550Device(uint16_t port) : port_(port) {}
+
+ const char* name() const override { return "uart0"; }
+ uint16_t port() const { return port_; }
+
+private:
+ uint16_t port_;
+};
+
+// ── UART16550Console driver ───────────────────────────────────────────────
+
+class UART16550Console : public ConsoleDriver,
+ public EarlyDriver<UART16550Console> {
+public:
+ UART16550Console() = default;
+
+ const char* name() const override { return "uart-16550"; }
+
+ bool init() override {
+ auto* dev = static_cast<UART16550Device*>(device());
+ port_ = dev->port();
+
+ // TODO: outb(port_ + 1, 0x00) — disable interrupts
+ // TODO: outb(port_ + 3, 0x80) — enable DLAB
+ // TODO: outb(port_ + 0, 0x03) — set divisor (lo) 38400 baud
+ // TODO: outb(port_ + 1, 0x00) — set divisor (hi)
+ // TODO: outb(port_ + 3, 0x03) — 8 bits, no parity, one stop
+ // TODO: outb(port_ + 2, 0xC7) — enable FIFO, clear, 14-byte threshold
+ // TODO: outb(port_ + 4, 0x0B) — IRQs enabled, RTS/DSR set
+ initialized_ = true;
+ return true;
+ }
+
+ void shutdown() override {
+ initialized_ = false;
+ }
+
+ void putchar(char c) override {
+ if (!initialized_) return;
+ // TODO: while (!(inb(port_ + 5) & 0x20)) {} — wait for THR empty
+ // TODO: outb(port_, c)
+ (void)c;
+ }
+
+ void clear() override {
+ // UART has no screen to clear
+ }
+
+private:
+ uint16_t port_ = 0;
+ bool initialized_ = false;
+};
+
+// ── Driver init function ──────────────────────────────────────────────────
+
+namespace console {
+
+void init_uart_16550(uint16_t port) {
+ auto* dev = UART16550Device::create(port);
+ platform::bus().add_device(dev);
+
+ auto* drv = UART16550Console::create();
+ drv->bind(dev);
+ drv->init();
+
+ console::register_driver(drv);
+}
+
+} // namespace console