refactor: apply newtypes throughout userspace API and display types
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.
This commit is contained in:
@@ -6,3 +6,4 @@ edition = "2024"
|
||||
[dependencies]
|
||||
port-framebuffer = { workspace = true }
|
||||
hw-virtio = { workspace = true }
|
||||
types = { workspace = true }
|
||||
|
||||
@@ -4,6 +4,8 @@ use hw_virtio::mmio::MmioAccess;
|
||||
use hw_virtio::queue::{QueueAddrs, VirtioQueue};
|
||||
use hw_virtio::gpu::{self, GpuDmaAddrs};
|
||||
use port_framebuffer::Framebuffer;
|
||||
use types::address::{PhysicalAddress, VirtualAddress};
|
||||
use types::display::{Color, Dimension, ScreenCoord};
|
||||
|
||||
const GPU_MMIO_VA: usize = 0x20000;
|
||||
const VQUEUE_VA: usize = 0x21000;
|
||||
@@ -24,8 +26,8 @@ impl MmioAccess for GpuMmio {
|
||||
}
|
||||
|
||||
struct PhysInfo {
|
||||
cmd_pa: u64,
|
||||
resp_pa: u64,
|
||||
cmd_pa: PhysicalAddress,
|
||||
resp_pa: PhysicalAddress,
|
||||
width: u16,
|
||||
height: u16,
|
||||
}
|
||||
@@ -34,8 +36,8 @@ fn read_phys_info() -> PhysInfo {
|
||||
unsafe {
|
||||
let p = PHYSINFO_VA as *const u64;
|
||||
PhysInfo {
|
||||
cmd_pa: core::ptr::read_volatile(p),
|
||||
resp_pa: core::ptr::read_volatile(p.add(1)),
|
||||
cmd_pa: PhysicalAddress::from_raw(core::ptr::read_volatile(p) as usize),
|
||||
resp_pa: PhysicalAddress::from_raw(core::ptr::read_volatile(p.add(1)) as usize),
|
||||
width: core::ptr::read_volatile(p.add(3)) as u16,
|
||||
height: core::ptr::read_volatile(p.add(4)) as u16,
|
||||
}
|
||||
@@ -46,50 +48,56 @@ pub struct VirtioFramebuffer {
|
||||
mmio: GpuMmio,
|
||||
queue: VirtioQueue,
|
||||
dma: GpuDmaAddrs,
|
||||
width: u16,
|
||||
height: u16,
|
||||
width: Dimension,
|
||||
height: Dimension,
|
||||
stride: usize,
|
||||
}
|
||||
|
||||
impl VirtioFramebuffer {
|
||||
pub fn new() -> Self {
|
||||
let phys = read_phys_info();
|
||||
let width = Dimension::new(phys.width);
|
||||
let height = Dimension::new(phys.height);
|
||||
let stride = phys.width as usize * FB_BPP;
|
||||
Self {
|
||||
mmio: GpuMmio,
|
||||
queue: VirtioQueue::new(QueueAddrs::from_base(VQUEUE_VA)),
|
||||
dma: GpuDmaAddrs { cmd_pa: phys.cmd_pa, cmd_va: CMDBUF_VA, resp_pa: phys.resp_pa },
|
||||
width: phys.width,
|
||||
height: phys.height,
|
||||
dma: GpuDmaAddrs { cmd_pa: phys.cmd_pa, cmd_va: VirtualAddress::from_raw(CMDBUF_VA), resp_pa: phys.resp_pa },
|
||||
width,
|
||||
height,
|
||||
stride,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Framebuffer for VirtioFramebuffer {
|
||||
fn width(&self) -> u16 { self.width }
|
||||
fn height(&self) -> u16 { self.height }
|
||||
fn width(&self) -> Dimension { self.width }
|
||||
fn height(&self) -> Dimension { self.height }
|
||||
|
||||
fn write_pixel(&mut self, x: u16, y: u16, color: u32) {
|
||||
if x >= self.width || y >= self.height { return; }
|
||||
let offset = (y as usize) * self.stride + (x as usize) * FB_BPP;
|
||||
unsafe { core::ptr::write_volatile((FB_VA + offset) as *mut u32, color); }
|
||||
fn write_pixel(&mut self, x: ScreenCoord, y: ScreenCoord, color: Color) {
|
||||
if x.raw() >= self.width.raw() || y.raw() >= self.height.raw() { return; }
|
||||
let offset = (y.raw() as usize) * self.stride + (x.raw() as usize) * FB_BPP;
|
||||
unsafe { core::ptr::write_volatile((FB_VA + offset) as *mut u32, color.raw()); }
|
||||
}
|
||||
|
||||
fn fill_rect(&mut self, x: u16, y: u16, w: u16, h: u16, color: u32) {
|
||||
for dy in 0..h { for dx in 0..w { self.write_pixel(x + dx, y + dy, color); } }
|
||||
fn fill_rect(&mut self, x: ScreenCoord, y: ScreenCoord, w: Dimension, h: Dimension, color: Color) {
|
||||
for dy in 0..h.raw() {
|
||||
for dx in 0..w.raw() {
|
||||
self.write_pixel(ScreenCoord::new(x.raw() + dx), ScreenCoord::new(y.raw() + dy), color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn clear(&mut self, color: u32) {
|
||||
let total = self.width as usize * self.height as usize;
|
||||
fn clear(&mut self, color: Color) {
|
||||
let total = self.width.raw() as usize * self.height.raw() as usize;
|
||||
for i in 0..total {
|
||||
unsafe { core::ptr::write_volatile((FB_VA as *mut u32).add(i), color); }
|
||||
unsafe { core::ptr::write_volatile((FB_VA as *mut u32).add(i), color.raw()); }
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&mut self) {
|
||||
let w = self.width as u32;
|
||||
let h = self.height as u32;
|
||||
let w = self.width.raw() as u32;
|
||||
let h = self.height.raw() as u32;
|
||||
gpu::transfer_to_host(&self.mmio, &self.queue, &self.dma, 1, 0, 0, w, h);
|
||||
gpu::resource_flush(&self.mmio, &self.queue, &self.dma, 1, 0, 0, w, h);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user