diff options
| author | Arseney300 <Arseney300@gmail.com> | 2026-04-23 17:02:05 +0700 |
|---|---|---|
| committer | Arseney300 <Arseney300@gmail.com> | 2026-04-23 17:02:05 +0700 |
| commit | e935c3afba9b3a492ad804726fa0fd97d437d8f5 (patch) | |
| tree | c8c26fe36ed4db1ffec4dab5f5bf3b489c064a07 /kernel/drivers/char | |
| parent | 496246c92dabe6757480147016490ea6ae43bb66 (diff) | |
WIP: add driver objectsWIP/add_driver_obj
Diffstat (limited to 'kernel/drivers/char')
| -rw-r--r-- | kernel/drivers/char/pl011.cpp | 83 | ||||
| -rw-r--r-- | kernel/drivers/char/uart_16550.cpp | 85 |
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 |
