refactor(init): replace raw usize with CapSlot, StorageHandle, PhysicalAddress newtypes throughout supervisor and boot
This commit is contained in:
@@ -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<ProcessId>; 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<ProcessId>; 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),
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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) {
|
||||
pub fn storage_open(endpoint: CapSlot, path: &[u8]) -> Option<StorageHandle> {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
pub fn storage_close(endpoint: CapSlot, handle: StorageHandle) {
|
||||
let _ = userspace::syscall::send(
|
||||
storage_ep,
|
||||
3, // Close tag
|
||||
handle,
|
||||
endpoint.value() as usize,
|
||||
3,
|
||||
handle.raw() as usize,
|
||||
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; }
|
||||
}
|
||||
// Create file
|
||||
let _ = userspace::syscall::send(
|
||||
storage_ep,
|
||||
5, // Create tag
|
||||
usize::from_le_bytes(w0),
|
||||
usize::from_le_bytes(w1),
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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<ServerState>; 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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user