diff options
Diffstat (limited to 'src/drivers')
| -rw-r--r-- | src/drivers/plic.cc | 40 | ||||
| -rw-r--r-- | src/drivers/uart.cc | 22 | ||||
| -rw-r--r-- | src/drivers/virtio_dist.cc | 10 |
3 files changed, 45 insertions, 27 deletions
diff --git a/src/drivers/plic.cc b/src/drivers/plic.cc index f9e306b..a975c44 100644 --- a/src/drivers/plic.cc +++ b/src/drivers/plic.cc @@ -1,18 +1,18 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* - * Copyright (C) 2026 Richard QIn + * Copyright (C) 2026 Richard Qin */ #include "common/types.h" #include "kernel/riscv.h" #include "drivers/plic.h" #include "drivers/uart.h" +#include "kernel/fdt.h" -// Base Constants -constexpr uint64 PLIC_BASE = 0x0c000000L; -constexpr uint64 PLIC_PRIORITY = PLIC_BASE + 0x0; -constexpr uint64 PLIC_PENDING = PLIC_BASE + 0x1000; +// Helper Macros — all relative to PLIC base from FDT +#define PLIC_BASE (g_devices.plic.base_addr) +#define PLIC_PRIORITY (PLIC_BASE + 0x0) +#define PLIC_PENDING (PLIC_BASE + 0x1000) -// Helper Macros to calculate addresses #define PLIC_SENABLE_ADDR(hart) (PLIC_BASE + 0x2080 + (hart) * 0x100) #define PLIC_STHRESHOLD_ADDR(hart) (PLIC_BASE + 0x201000 + (hart) * 0x2000) #define PLIC_SCLAIM_ADDR(hart) (PLIC_BASE + 0x201004 + (hart) * 0x2000) @@ -27,12 +27,15 @@ namespace PLIC { void init() { - // Set Priority for UART (IRQ 10) and VirtIO (IRQ 1) - // Must use volatile write - *REG32(PLIC_PRIORITY + 10 * 4) = 1; - for (int i = 1; i <= 8; i++) + // Set priority for UART IRQ + if (g_devices.uart.irq > 0) + *REG32(PLIC_PRIORITY + g_devices.uart.irq * 4) = 1; + + // Set priority for all VirtIO IRQs + for (int i = 0; i < g_devices.virtio_count; i++) { - *REG32(PLIC_PRIORITY + i * 4) = 1; + if (g_devices.virtio[i].irq > 0) + *REG32(PLIC_PRIORITY + g_devices.virtio[i].irq * 4) = 1; } } @@ -40,8 +43,19 @@ namespace PLIC { int hart = static_cast<int>(r_tp()); - // Enable UART(10) and VirtIO(1) for this Hart (S-Mode) - *REG32(PLIC_SENABLE_ADDR(hart)) = (1 << 10) | 0x1FE; + // Build enable bitmask from discovered devices + uint32 enable = 0; + + if (g_devices.uart.irq > 0 && g_devices.uart.irq < 32) + enable |= (1 << g_devices.uart.irq); + + for (int i = 0; i < g_devices.virtio_count; i++) + { + if (g_devices.virtio[i].irq > 0 && g_devices.virtio[i].irq < 32) + enable |= (1 << g_devices.virtio[i].irq); + } + + *REG32(PLIC_SENABLE_ADDR(hart)) = enable; // Set Priority Threshold to 0 (Allow all) *REG32(PLIC_STHRESHOLD_ADDR(hart)) = 0; diff --git a/src/drivers/uart.cc b/src/drivers/uart.cc index 96ae182..397a402 100644 --- a/src/drivers/uart.cc +++ b/src/drivers/uart.cc @@ -40,29 +40,29 @@ namespace Drivers uart_rx.w = 0; // Disable interrupts and configure - *(volatile uint8 *)(UART0 + IER) = 0x00; + *(volatile uint8 *)(uart_base() + IER) = 0x00; // Enter baud rate setting mode (LCR_DLAB) = 0x80; - *(volatile uint8 *)(UART0 + LCR) = 0x80; - *(volatile uint8 *)(UART0 + 0) = 0x03; // DLL: 38.4K baud - *(volatile uint8 *)(UART0 + 1) = 0x00; // DLM + *(volatile uint8 *)(uart_base() + LCR) = 0x80; + *(volatile uint8 *)(uart_base() + 0) = 0x03; // DLL: 38.4K baud + *(volatile uint8 *)(uart_base() + 1) = 0x00; // DLM // Exit baud rate setting, set 8-bit word length, no parity - *(volatile uint8 *)(UART0 + LCR) = 0x03; + *(volatile uint8 *)(uart_base() + LCR) = 0x03; // Reset and enable FIFO - *(volatile uint8 *)(UART0 + FCR) = 0x07; + *(volatile uint8 *)(uart_base() + FCR) = 0x07; // Enable Receive Data Available Interrupt - *(volatile uint8 *)(UART0 + IER) = 0x01; + *(volatile uint8 *)(uart_base() + IER) = 0x01; } void uart_putc(char c) { uart_tx_lock.acquire(); - while ((*(volatile uint8 *)(UART0 + LSR) & LSR_TX_IDLE) == 0) + while ((*(volatile uint8 *)(uart_base() + LSR) & LSR_TX_IDLE) == 0) ; - *(volatile uint8 *)(UART0 + THR) = c; + *(volatile uint8 *)(uart_base() + THR) = c; uart_tx_lock.release(); } @@ -113,10 +113,10 @@ namespace Drivers while (1) { - if ((*(volatile uint8 *)(UART0 + LSR) & LSR_RX_READY) == 0) + if ((*(volatile uint8 *)(uart_base() + LSR) & LSR_RX_READY) == 0) break; - char c = *(volatile uint8 *)(UART0 + RHR); + char c = *(volatile uint8 *)(uart_base() + RHR); uart_rx.buf[uart_rx.w % UART_RX_BUF_SIZE] = c; uart_rx.w++; diff --git a/src/drivers/virtio_dist.cc b/src/drivers/virtio_dist.cc index b2acd8e..8292874 100644 --- a/src/drivers/virtio_dist.cc +++ b/src/drivers/virtio_dist.cc @@ -3,6 +3,7 @@ * Copyright (C) 2026 Richard QIn */ #include "drivers/virtio.h" +#include "kernel/fdt.h" #include "kernel/riscv.h" #include "kernel/pmm.h" #include "kernel/spinlock.h" @@ -67,11 +68,14 @@ namespace VirtIO { disk.lock.init("virtio_disk"); - // 1. Probing for VirtIO-MMIO device + // 1. Probe VirtIO devices discovered by FDT bool found = false; - // Probe common VirtIO addresses in QEMU virt machine - for (uint64 addr = 0x10001000; addr < 0x10009000; addr += 0x1000) + for (int i = 0; i < g_devices.virtio_count; i++) { + uint64 addr = g_devices.virtio[i].base_addr; + if (addr == 0) + continue; + volatile uint32 *magic = (volatile uint32 *)(addr + VIRTIO_MMIO_MAGIC_VALUE); volatile uint32 *dev_id = (volatile uint32 *)(addr + VIRTIO_MMIO_DEVICE_ID); |
