feat: devices via caps (BootInfo, init assigns devices, drivers map MMIO/DMA themselves, IRQ-driven input); drop boot device wiring and info pages; headless display fallback

This commit is contained in:
2026-10-27 12:28:39 +01:00
parent 8bc5402a29
commit 694c675a40
39 changed files with 731 additions and 387 deletions

View File

@@ -4,6 +4,7 @@ version = "0.1.0"
edition = "2024"
[dependencies]
libkos = { workspace = true }
port-block-device = { workspace = true }
hw-virtio = { workspace = true }
types = { workspace = true }

View File

@@ -9,7 +9,6 @@ use types::address::{PhysicalAddress, VirtualAddress};
const MMIO_BASE: usize = 0x20000;
const VQUEUE_VA: usize = 0x21000;
const REQ_HDR_VA: usize = 0x23000;
const PHYSINFO_VA: usize = 0x24000;
const SECTOR_SIZE: usize = 512;
struct UserMmio;
@@ -30,28 +29,35 @@ pub struct VirtioBlockDevice {
}
impl VirtioBlockDevice {
pub fn new() -> Self {
let queue = VirtioQueue::new(QueueAddrs::from_base(VQUEUE_VA));
let (hdr_pa, status_pa, data_pa) = unsafe {
let p = PHYSINFO_VA as *const u64;
(
core::ptr::read_volatile(p) as usize,
core::ptr::read_volatile(p.add(1)) as usize,
core::ptr::read_volatile(p.add(2)) as usize,
)
};
/// Takes over the block device whose MMIO region `mmio` names: maps
/// it, allocates the queue and request buffers, and resets the device
/// onto them. `None` if any step fails or it is not a block device.
pub fn new(mmio: types::bounded::CapSlot) -> Option<Self> {
libkos::device::map_mmio(mmio, MMIO_BASE).ok()?;
let regs = UserMmio;
if regs.read(hw_virtio::mmio::REG_MAGIC) != hw_virtio::mmio::MAGIC
|| regs.read(hw_virtio::mmio::REG_DEVICE_ID) != hw_virtio::mmio::DEVICE_ID_BLOCK
{
return None;
}
let vq_pa = libkos::device::dma(2, VQUEUE_VA).ok()?;
let hdr_pa = libkos::device::dma(1, REQ_HDR_VA).ok()?;
hw_virtio::mmio::init_legacy_device(&regs, vq_pa, hw_virtio::queue::QUEUE_SIZE as u32);
// Header, status byte and one sector share the request page.
let dma = DmaAddrs {
header_pa: PhysicalAddress::from_raw(hdr_pa),
header_va: VirtualAddress::from_raw(REQ_HDR_VA),
status_pa: PhysicalAddress::from_raw(status_pa),
status_pa: PhysicalAddress::from_raw(hdr_pa + 16),
status_va: VirtualAddress::from_raw(REQ_HDR_VA + 16),
data_pa: PhysicalAddress::from_raw(data_pa),
data_pa: PhysicalAddress::from_raw(hdr_pa + 32),
data_va: VirtualAddress::from_raw(REQ_HDR_VA + 32),
};
Self { mmio: UserMmio, queue, dma }
Some(Self {
mmio: UserMmio,
queue: VirtioQueue::new(QueueAddrs::from_base(VQUEUE_VA)),
dma,
})
}
}