From f72a434e1a81c8e2e90d663722504f434b95c6d8 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Sun, 18 Oct 2026 03:54:07 +0200 Subject: [PATCH] refactor(init): replace raw usize with CapSlot, StorageHandle, PhysicalAddress newtypes throughout supervisor and boot --- crates/init/src/boot.rs | 17 ++++---- crates/init/src/manifest.rs | 7 +++- crates/init/src/protocol_helpers.rs | 65 ++++++++++++++--------------- crates/init/src/supervisor.rs | 27 +++++++----- 4 files changed, 63 insertions(+), 53 deletions(-) diff --git a/crates/init/src/boot.rs b/crates/init/src/boot.rs index 15c1eba..88739da 100644 --- a/crates/init/src/boot.rs +++ b/crates/init/src/boot.rs @@ -46,8 +46,8 @@ impl EndpointRegistry { } pub struct BootResult { - pub storage_endpoint: usize, - pub create_cap: usize, + pub storage_endpoint: CapSlot, + pub create_cap: CapSlot, pub server_pids: [Option; MAX_PIDS], pub server_count: usize, } @@ -55,7 +55,7 @@ pub struct BootResult { pub fn boot(manifest: &BootManifest, create_cap: CapSlot) -> BootResult { let mut endpoints = EndpointRegistry::new(); let mut server_pids: [Option; MAX_PIDS] = [const { None }; MAX_PIDS]; - let mut storage_endpoint: usize = 0; + let mut storage_endpoint = create_cap; // placeholder until found for (i, server) in manifest.servers.iter().enumerate() { let pid_raw = syscall::create_process(create_cap.value() as usize); @@ -69,7 +69,7 @@ pub fn boot(manifest: &BootManifest, create_cap: CapSlot) -> BootResult { if let Some(slot) = CapSlot::new(0) { endpoints.register(name, slot); if *name == "storage" { - storage_endpoint = slot.value() as usize; + storage_endpoint = slot; } } } @@ -84,10 +84,13 @@ pub fn boot(manifest: &BootManifest, create_cap: CapSlot) -> BootResult { } } - // Save server binaries to storage for later restart for server in manifest.servers { if let BinarySource::Storage { path } = server.binary { - protocol_helpers::storage_write_binary(storage_endpoint, path.as_bytes(), &[]); + protocol_helpers::storage_write_binary( + storage_endpoint, + path.as_bytes(), + &[], + ); } } @@ -101,7 +104,7 @@ pub fn boot(manifest: &BootManifest, create_cap: CapSlot) -> BootResult { BootResult { storage_endpoint, - create_cap: create_cap.value() as usize, + create_cap, server_pids, server_count: manifest.servers.len().min(MAX_PIDS), } diff --git a/crates/init/src/manifest.rs b/crates/init/src/manifest.rs index 2b85722..513583c 100644 --- a/crates/init/src/manifest.rs +++ b/crates/init/src/manifest.rs @@ -17,7 +17,7 @@ pub enum EndpointBinding { #[derive(Debug, Clone, Copy)] pub enum BinarySource { - Ram { addr: usize, len: usize }, + Ram { base: PhysicalAddress, size: usize }, Storage { path: &'static str }, } @@ -74,7 +74,10 @@ pub static SNAKE_MANIFEST: BootManifest = BootManifest { hardware_caps: &[], endpoints: &[EndpointBinding::Own { name: "storage" }], restartable: true, - binary: BinarySource::Ram { addr: 0, len: 0 }, + binary: BinarySource::Ram { + base: PhysicalAddress::from_raw(0), + size: 0, + }, }, ServerEntry { name: "display", diff --git a/crates/init/src/protocol_helpers.rs b/crates/init/src/protocol_helpers.rs index 7b64640..a53ca72 100644 --- a/crates/init/src/protocol_helpers.rs +++ b/crates/init/src/protocol_helpers.rs @@ -1,47 +1,44 @@ -pub fn storage_open(storage_ep: usize, path: &[u8]) -> usize { +use types::bounded::CapSlot; + +#[derive(Debug, Clone, Copy)] +pub struct StorageHandle(u16); + +impl StorageHandle { + pub fn raw(&self) -> u16 { self.0 } +} + +fn pack_path(path: &[u8]) -> (usize, usize) { let mut w0 = [0u8; 8]; let mut w1 = [0u8; 8]; for (i, &b) in path.iter().enumerate() { if i < 8 { w0[i] = b; } else if i < 16 { w1[i - 8] = b; } } - // StorageRequest::Open tag = 0 - let (r0, _, _, _) = userspace::syscall::receive(storage_ep); - let _ = userspace::syscall::send( - storage_ep, - 0, // Open tag - usize::from_le_bytes(w0), - usize::from_le_bytes(w1), - 0, - ); - // Response: Handle(h) has tag 0, handle in word 1 - let (tag, handle, _, _) = userspace::syscall::receive(storage_ep); - if tag == 0 { handle } else { usize::MAX } + (usize::from_le_bytes(w0), usize::from_le_bytes(w1)) } -pub fn storage_close(storage_ep: usize, handle: usize) { - let _ = userspace::syscall::send( - storage_ep, - 3, // Close tag - handle, - 0, - 0, - ); -} - -pub fn storage_write_binary(storage_ep: usize, path: &[u8], _binary: &[u8]) { - let mut w0 = [0u8; 8]; - let mut w1 = [0u8; 8]; - for (i, &b) in path.iter().enumerate() { - if i < 8 { w0[i] = b; } - else if i < 16 { w1[i - 8] = b; } +pub fn storage_open(endpoint: CapSlot, path: &[u8]) -> Option { + let (w0, w1) = pack_path(path); + let _ = userspace::syscall::send(endpoint.value() as usize, 0, w0, w1, 0); + let (tag, handle, _, _) = userspace::syscall::receive(endpoint.value() as usize); + if tag == 0 { + Some(StorageHandle(handle as u16)) + } else { + None } - // Create file +} + +pub fn storage_close(endpoint: CapSlot, handle: StorageHandle) { let _ = userspace::syscall::send( - storage_ep, - 5, // Create tag - usize::from_le_bytes(w0), - usize::from_le_bytes(w1), + endpoint.value() as usize, + 3, + handle.raw() as usize, + 0, 0, ); } + +pub fn storage_write_binary(endpoint: CapSlot, path: &[u8], _binary: &[u8]) { + let (w0, w1) = pack_path(path); + let _ = userspace::syscall::send(endpoint.value() as usize, 5, w0, w1, 0); +} diff --git a/crates/init/src/supervisor.rs b/crates/init/src/supervisor.rs index 28497e1..ee73bce 100644 --- a/crates/init/src/supervisor.rs +++ b/crates/init/src/supervisor.rs @@ -1,4 +1,5 @@ use crate::manifest::{BinarySource, BootManifest}; +use types::bounded::CapSlot; use types::id::ProcessId; const MAX_SERVERS: usize = 16; @@ -16,12 +17,12 @@ struct ServerState { pub struct Supervisor { servers: [Option; MAX_SERVERS], count: usize, - storage_endpoint: usize, - create_cap: usize, + storage_endpoint: CapSlot, + create_cap: CapSlot, } impl Supervisor { - pub fn new(manifest: &BootManifest, storage_endpoint: usize, create_cap: usize) -> Self { + pub fn new(manifest: &BootManifest, storage_endpoint: CapSlot, create_cap: CapSlot) -> Self { let mut servers = [const { None }; MAX_SERVERS]; for (i, entry) in manifest.servers.iter().enumerate() { if i < MAX_SERVERS { @@ -90,8 +91,10 @@ impl Supervisor { self.wait_ticks(delay); match binary { - BinarySource::Ram { addr: _, len: _ } => { - let new_pid = userspace::syscall::create_process(self.create_cap); + BinarySource::Ram { .. } => { + let new_pid = userspace::syscall::create_process( + self.create_cap.value() as usize, + ); if let Some(state) = &mut self.servers[index] { state.pid = Some(ProcessId::from_raw(new_pid as u16)); state.restart_count += 1; @@ -107,11 +110,15 @@ impl Supervisor { use crate::protocol_helpers; let handle = protocol_helpers::storage_open(self.storage_endpoint, path.as_bytes()); - if handle == usize::MAX { return; } + if handle.is_none() { return; } - let new_pid = userspace::syscall::create_process(self.create_cap); + let new_pid = userspace::syscall::create_process( + self.create_cap.value() as usize, + ); - protocol_helpers::storage_close(self.storage_endpoint, handle); + if let Some(h) = handle { + protocol_helpers::storage_close(self.storage_endpoint, h); + } if let Some(state) = &mut self.servers[index] { state.pid = Some(ProcessId::from_raw(new_pid as u16)); @@ -119,10 +126,10 @@ impl Supervisor { } } - pub fn run(&mut self, fault_endpoint: usize) -> ! { + pub fn run(&mut self, fault_endpoint: CapSlot) -> ! { loop { let (crashed_pid_raw, _fault_code, _fault_addr, _fault_pc) = - userspace::syscall::receive(fault_endpoint); + userspace::syscall::receive(fault_endpoint.value() as usize); let crashed_pid = ProcessId::from_raw(crashed_pid_raw as u16);