summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/plic.cc40
-rw-r--r--src/drivers/uart.cc22
-rw-r--r--src/drivers/virtio_dist.cc10
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);