refactor: unsafe only in adapter + libkos; forbid(unsafe_code) everywhere else; libkos Window (volatile, bounds-checked MMIO/DMA/shared mem), entry!, thread::spawn; MapRegion returns pages; kernel const-built (with_cores/install_platform); newtype addrs

This commit is contained in:
2026-10-27 21:43:24 +01:00
parent 83809bbe94
commit 842d14987c
107 changed files with 771 additions and 647 deletions

View File

@@ -32,31 +32,26 @@ pub const DEVICE_ID_INPUT: u32 = 18;
pub const PAGE_SIZE: usize = 4096;
pub struct DirectMmio {
base: usize,
}
/// A virtio-mmio device's registers: 32-bit accesses at register offsets.
pub struct Registers(libkos::Window);
impl DirectMmio {
pub fn new(base: usize) -> Self {
Self { base }
}
pub fn base(&self) -> usize {
self.base
impl Registers {
pub fn new(window: libkos::Window) -> Self {
Self(window)
}
}
impl MmioAccess for DirectMmio {
impl MmioAccess for Registers {
fn read(&self, offset: usize) -> u32 {
unsafe { core::ptr::read_volatile((self.base + offset) as *const u32) }
self.0.read(offset)
}
fn write(&self, offset: usize, val: u32) {
unsafe { core::ptr::write_volatile((self.base + offset) as *mut u32, val) }
self.0.write(offset, val)
}
}
pub fn init_legacy_device(mmio: &impl MmioAccess, queue_phys: usize, queue_size: u32) {
pub fn init_legacy_device(mmio: &impl MmioAccess, queue: types::address::PhysicalAddress, queue_size: u32) {
mmio.write(REG_STATUS, 0);
while mmio.read(REG_STATUS) != 0 {}
@@ -71,30 +66,7 @@ pub fn init_legacy_device(mmio: &impl MmioAccess, queue_phys: usize, queue_size:
mmio.write(REG_QUEUE_SEL, 0);
let queue_max = mmio.read(REG_QUEUE_NUM_MAX);
mmio.write(REG_QUEUE_NUM, queue_size.min(queue_max));
mmio.write(REG_QUEUE_PFN, (queue_phys / PAGE_SIZE) as u32);
mmio.write(REG_QUEUE_PFN, (queue.raw() / PAGE_SIZE) as u32);
mmio.write(REG_STATUS, mmio.read(REG_STATUS) | STATUS_DRIVER_OK);
}
pub fn probe_slot(base: usize, device_id: u32) -> Option<DirectMmio> {
let mmio = DirectMmio::new(base);
if mmio.read(REG_MAGIC) == MAGIC && mmio.read(REG_DEVICE_ID) == device_id {
Some(mmio)
} else {
None
}
}
pub const MMIO_FIRST: usize = 0x10001000;
pub const MMIO_STRIDE: usize = 0x1000;
pub const MMIO_SLOTS: usize = 8;
/// Probes the MMIO slots, with slot 0 at `first` as the caller maps it.
pub fn scan_for_device(first: usize, device_id: u32) -> Option<DirectMmio> {
for slot in 0..MMIO_SLOTS {
if let Some(mmio) = probe_slot(first + slot * MMIO_STRIDE, device_id) {
return Some(mmio);
}
}
None
}