Every syscall stub now uses proper types from types/ — CapSlot,
EntryPoint, StackPointer, VirtualAddress, PageCount, ProcessId,
PermissionSet, Ticks. The compiler prevents swapping entry/stack,
passing a ProcessId where a CapSlot is expected, or using an
address as a page count.
New display types in types/display.rs:
- Color(u32) with rgb() constructor
- ScreenCoord(u16) for x/y positions
- Dimension(u16) for width/height
Updated throughout:
- userspace/syscall.rs: all params typed, returns Option instead
of sentinel usize::MAX
- server-framework: endpoint param is CapSlot
- port-framebuffer: trait uses Color, ScreenCoord, Dimension
- hw-virtio: DmaAddrs uses PhysicalAddress/VirtualAddress,
GPU commands use Dimension
- All servers, drivers, bins, apps updated for new signatures
- permission-manager: process field uses ProcessId
- PermissionSet: added bits() accessor
89 tests pass, full QEMU boot verified.
74 lines
2.3 KiB
Rust
74 lines
2.3 KiB
Rust
#![no_std]
|
|
|
|
use hw_virtio::mmio::MmioAccess;
|
|
use hw_virtio::queue::{QueueAddrs, VirtioQueue};
|
|
use hw_virtio::block::{self, DmaAddrs};
|
|
use port_block_device::{BlockDevice, SectorId};
|
|
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;
|
|
|
|
impl MmioAccess for UserMmio {
|
|
fn read(&self, offset: usize) -> u32 {
|
|
unsafe { core::ptr::read_volatile((MMIO_BASE + offset) as *const u32) }
|
|
}
|
|
fn write(&self, offset: usize, val: u32) {
|
|
unsafe { core::ptr::write_volatile((MMIO_BASE + offset) as *mut u32, val) }
|
|
}
|
|
}
|
|
|
|
pub struct VirtioBlockDevice {
|
|
mmio: UserMmio,
|
|
queue: VirtioQueue,
|
|
dma: DmaAddrs,
|
|
}
|
|
|
|
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,
|
|
)
|
|
};
|
|
|
|
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_va: VirtualAddress::from_raw(REQ_HDR_VA + 16),
|
|
data_pa: PhysicalAddress::from_raw(data_pa),
|
|
data_va: VirtualAddress::from_raw(REQ_HDR_VA + 32),
|
|
};
|
|
|
|
Self { mmio: UserMmio, queue, dma }
|
|
}
|
|
}
|
|
|
|
impl BlockDevice for VirtioBlockDevice {
|
|
fn sector_size(&self) -> usize { SECTOR_SIZE }
|
|
fn sector_count(&self) -> usize { 0xFFFF }
|
|
|
|
fn read_sector(&mut self, sector: SectorId, buf: &mut [u8]) -> bool {
|
|
if buf.len() < SECTOR_SIZE { return false; }
|
|
let mut sector_buf = [0u8; SECTOR_SIZE];
|
|
if !block::read_sector(&self.mmio, &self.queue, &self.dma, sector.raw(), &mut sector_buf) {
|
|
return false;
|
|
}
|
|
buf[..SECTOR_SIZE].copy_from_slice(§or_buf);
|
|
true
|
|
}
|
|
|
|
fn write_sector(&mut self, _sector: SectorId, _buf: &[u8]) -> bool { false }
|
|
}
|