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:
2026-10-18 13:45:40 +02:00
parent 3a0395453b
commit 7c7e3b8748
42 changed files with 416 additions and 307 deletions

View File

@@ -1,5 +1,6 @@
use crate::mmio::MmioAccess;
use crate::queue::{Descriptor, VirtioQueue};
use types::address::{PhysicalAddress, VirtualAddress};
const SECTOR_SIZE: usize = 512;
@@ -11,12 +12,12 @@ pub struct BlockReqHeader {
}
pub struct DmaAddrs {
pub header_pa: u64,
pub header_va: usize,
pub status_pa: u64,
pub status_va: usize,
pub data_pa: u64,
pub data_va: usize,
pub header_pa: PhysicalAddress,
pub header_va: VirtualAddress,
pub status_pa: PhysicalAddress,
pub status_va: VirtualAddress,
pub data_pa: PhysicalAddress,
pub data_va: VirtualAddress,
}
pub fn read_sector(
@@ -29,28 +30,28 @@ pub fn read_sector(
if buf.len() < SECTOR_SIZE { return false; }
unsafe {
let hdr = dma.header_va as *mut BlockReqHeader;
let hdr = dma.header_va.raw() as *mut BlockReqHeader;
core::ptr::write_volatile(&raw mut (*hdr).req_type, 0);
core::ptr::write_volatile(&raw mut (*hdr).reserved, 0);
core::ptr::write_volatile(&raw mut (*hdr).sector, sector as u64);
core::ptr::write_volatile(dma.status_va as *mut u8, 0xFF);
core::ptr::write_volatile(dma.status_va.raw() as *mut u8, 0xFF);
}
let descs = [
Descriptor { addr: dma.header_pa, len: 16, writable: false },
Descriptor { addr: dma.data_pa, len: SECTOR_SIZE as u32, writable: true },
Descriptor { addr: dma.status_pa, len: 1, writable: true },
Descriptor { addr: dma.header_pa.raw() as u64, len: 16, writable: false },
Descriptor { addr: dma.data_pa.raw() as u64, len: SECTOR_SIZE as u32, writable: true },
Descriptor { addr: dma.status_pa.raw() as u64, len: 1, writable: true },
];
if !queue.submit(mmio, &descs) { return false; }
let status = unsafe { core::ptr::read_volatile(dma.status_va as *const u8) };
let status = unsafe { core::ptr::read_volatile(dma.status_va.raw() as *const u8) };
if status != 0 { return false; }
if dma.data_va != buf.as_ptr() as usize {
if dma.data_va.raw() != buf.as_ptr() as usize {
unsafe {
core::ptr::copy_nonoverlapping(
dma.data_va as *const u8,
dma.data_va.raw() as *const u8,
buf.as_mut_ptr(),
SECTOR_SIZE,
);

View File

@@ -1,42 +1,44 @@
use crate::mmio::MmioAccess;
use crate::queue::{Descriptor, VirtioQueue};
use types::address::{PhysicalAddress, VirtualAddress};
use types::display::Dimension;
pub struct GpuDmaAddrs {
pub cmd_pa: u64,
pub cmd_va: usize,
pub resp_pa: u64,
pub cmd_pa: PhysicalAddress,
pub cmd_va: VirtualAddress,
pub resp_pa: PhysicalAddress,
}
pub fn create_2d(mmio: &impl MmioAccess, queue: &VirtioQueue, dma: &GpuDmaAddrs, resource_id: u32, width: u32, height: u32) {
pub fn create_2d(mmio: &impl MmioAccess, queue: &VirtioQueue, dma: &GpuDmaAddrs, resource_id: u32, width: Dimension, height: Dimension) {
write_cmd_header(dma.cmd_va, 0x0101);
unsafe {
let p = dma.cmd_va as *mut u8;
let p = dma.cmd_va.raw() as *mut u8;
core::ptr::write_volatile(p.add(24) as *mut u32, resource_id);
core::ptr::write_volatile(p.add(28) as *mut u32, 1); // B8G8R8A8_UNORM
core::ptr::write_volatile(p.add(32) as *mut u32, width);
core::ptr::write_volatile(p.add(36) as *mut u32, height);
core::ptr::write_volatile(p.add(32) as *mut u32, width.raw() as u32);
core::ptr::write_volatile(p.add(36) as *mut u32, height.raw() as u32);
}
submit_cmd(mmio, queue, dma, 40);
}
pub fn attach_backing(mmio: &impl MmioAccess, queue: &VirtioQueue, dma: &GpuDmaAddrs, resource_id: u32, fb_pa: u64, fb_size: u32) {
pub fn attach_backing(mmio: &impl MmioAccess, queue: &VirtioQueue, dma: &GpuDmaAddrs, resource_id: u32, fb_pa: PhysicalAddress, fb_size: u32) {
write_cmd_header(dma.cmd_va, 0x0104);
unsafe {
let p = dma.cmd_va as *mut u8;
let p = dma.cmd_va.raw() as *mut u8;
core::ptr::write_volatile(p.add(24) as *mut u32, resource_id);
core::ptr::write_volatile(p.add(28) as *mut u32, 1);
core::ptr::write_volatile(p.add(32) as *mut u64, fb_pa);
core::ptr::write_volatile(p.add(32) as *mut u64, fb_pa.raw() as u64);
core::ptr::write_volatile(p.add(40) as *mut u32, fb_size);
}
submit_cmd(mmio, queue, dma, 48);
}
pub fn set_scanout(mmio: &impl MmioAccess, queue: &VirtioQueue, dma: &GpuDmaAddrs, scanout_id: u32, resource_id: u32, width: u32, height: u32) {
pub fn set_scanout(mmio: &impl MmioAccess, queue: &VirtioQueue, dma: &GpuDmaAddrs, scanout_id: u32, resource_id: u32, width: Dimension, height: Dimension) {
write_cmd_header(dma.cmd_va, 0x0103);
unsafe {
let p = dma.cmd_va as *mut u8;
core::ptr::write_volatile(p.add(32) as *mut u32, width);
core::ptr::write_volatile(p.add(36) as *mut u32, height);
let p = dma.cmd_va.raw() as *mut u8;
core::ptr::write_volatile(p.add(32) as *mut u32, width.raw() as u32);
core::ptr::write_volatile(p.add(36) as *mut u32, height.raw() as u32);
core::ptr::write_volatile(p.add(40) as *mut u32, scanout_id);
core::ptr::write_volatile(p.add(44) as *mut u32, resource_id);
}
@@ -46,7 +48,7 @@ pub fn set_scanout(mmio: &impl MmioAccess, queue: &VirtioQueue, dma: &GpuDmaAddr
pub fn transfer_to_host(mmio: &impl MmioAccess, queue: &VirtioQueue, dma: &GpuDmaAddrs, resource_id: u32, x: u32, y: u32, w: u32, h: u32) {
write_cmd_header(dma.cmd_va, 0x0105);
unsafe {
let p = dma.cmd_va as *mut u8;
let p = dma.cmd_va.raw() as *mut u8;
core::ptr::write_volatile(p.add(24) as *mut u32, x);
core::ptr::write_volatile(p.add(28) as *mut u32, y);
core::ptr::write_volatile(p.add(32) as *mut u32, w);
@@ -60,7 +62,7 @@ pub fn transfer_to_host(mmio: &impl MmioAccess, queue: &VirtioQueue, dma: &GpuDm
pub fn resource_flush(mmio: &impl MmioAccess, queue: &VirtioQueue, dma: &GpuDmaAddrs, resource_id: u32, x: u32, y: u32, w: u32, h: u32) {
write_cmd_header(dma.cmd_va, 0x0106);
unsafe {
let p = dma.cmd_va as *mut u8;
let p = dma.cmd_va.raw() as *mut u8;
core::ptr::write_volatile(p.add(24) as *mut u32, x);
core::ptr::write_volatile(p.add(28) as *mut u32, y);
core::ptr::write_volatile(p.add(32) as *mut u32, w);
@@ -70,9 +72,9 @@ pub fn resource_flush(mmio: &impl MmioAccess, queue: &VirtioQueue, dma: &GpuDmaA
submit_cmd(mmio, queue, dma, 48);
}
fn write_cmd_header(cmd_va: usize, cmd_type: u32) {
fn write_cmd_header(cmd_va: VirtualAddress, cmd_type: u32) {
unsafe {
let p = cmd_va as *mut u8;
let p = cmd_va.raw() as *mut u8;
core::ptr::write_bytes(p, 0, 512);
core::ptr::write_volatile(p as *mut u32, cmd_type);
}
@@ -80,8 +82,8 @@ fn write_cmd_header(cmd_va: usize, cmd_type: u32) {
fn submit_cmd(mmio: &impl MmioAccess, queue: &VirtioQueue, dma: &GpuDmaAddrs, cmd_len: u32) {
let descs = [
Descriptor { addr: dma.cmd_pa, len: cmd_len, writable: false },
Descriptor { addr: dma.resp_pa, len: 24, writable: true },
Descriptor { addr: dma.cmd_pa.raw() as u64, len: cmd_len, writable: false },
Descriptor { addr: dma.resp_pa.raw() as u64, len: 24, writable: true },
];
queue.submit(mmio, &descs);
}