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:
@@ -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 }
|
||||
|
||||
@@ -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(®s, 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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user