diff --git a/rust/lib/mammoth/src/cap.rs b/rust/lib/mammoth/src/cap.rs new file mode 100644 index 0000000..29f3d47 --- /dev/null +++ b/rust/lib/mammoth/src/cap.rs @@ -0,0 +1,48 @@ +use crate::cap_syscall; +use crate::zion::{z_cap_t, ZError}; + +pub struct Capability { + cap: z_cap_t, +} + +impl Capability { + pub fn take(cap: z_cap_t) -> Self { + Self { cap } + } + + pub fn take_copy(cap: z_cap_t) -> Result { + Ok(Self::take(cap_syscall::cap_duplicate( + cap, + Self::PERMS_ALL, + )?)) + } + + pub fn raw(&self) -> z_cap_t { + self.cap + } + + pub fn release(mut self) -> z_cap_t { + let cap = self.cap; + self.cap = 0; + cap + } + + pub const PERMS_ALL: u64 = u64::MAX; + pub fn duplicate(&self, perm_mask: u64) -> Result { + Ok(Self::take(cap_syscall::cap_duplicate(self.cap, perm_mask)?)) + } +} + +impl Drop for Capability { + fn drop(&mut self) { + if self.cap != 0 { + if let Err(e) = cap_syscall::cap_release(self.cap) { + crate::debug!( + "WARN: error during cap release for cap {:#x}: {:?}", + self.cap, + e + ); + } + } + } +} diff --git a/rust/lib/mammoth/src/cap_syscall.rs b/rust/lib/mammoth/src/cap_syscall.rs new file mode 100644 index 0000000..eb9567a --- /dev/null +++ b/rust/lib/mammoth/src/cap_syscall.rs @@ -0,0 +1,31 @@ +use core::ffi::c_void; + +use crate::zion::{self, z_cap_t, ZError}; + +#[must_use] +fn syscall(id: u64, req: &T) -> Result<(), ZError> { + unsafe { + let resp = zion::SysCall1(id, req as *const T as *const c_void); + if resp != 0 { + return Err(zion::ZError::from(resp)); + } + } + Ok(()) +} + +pub fn cap_duplicate(cap: z_cap_t, perm_mask: u64) -> Result { + let mut new_cap = 0; + syscall( + zion::kZionCapDuplicate, + &zion::ZCapDuplicateReq { + cap_in: cap, + perm_mask, + cap_out: &mut new_cap, + }, + )?; + Ok(new_cap) +} + +pub fn cap_release(cap: z_cap_t) -> Result<(), ZError> { + syscall(zion::kZionCapRelease, &zion::ZCapReleaseReq { cap }) +} diff --git a/rust/lib/mammoth/src/elf.rs b/rust/lib/mammoth/src/elf.rs index aa4daf9..321063d 100644 --- a/rust/lib/mammoth/src/elf.rs +++ b/rust/lib/mammoth/src/elf.rs @@ -1,7 +1,7 @@ +use crate::cap::Capability; use crate::debug; use crate::init; use crate::syscall; -use crate::zion::z_cap_t; use crate::zion::ZError; use alloc::fmt::Debug; @@ -225,7 +225,7 @@ impl Debug for Elf64ProgramHeader { fn load_program_segment( prog_header: &Elf64ProgramHeader, file: &[u8], - vmas: z_cap_t, + vmas: &Capability, ) -> Result<(), ZError> { debug!("{:?}", prog_header); match prog_header.prog_type { @@ -282,7 +282,7 @@ fn load_program_segment( } } -fn load_elf_program(elf_file: &[u8], vmas: z_cap_t) -> Result { +fn load_elf_program(elf_file: &[u8], vmas: &Capability) -> Result { assert!(elf_file.len() > size_of::()); let header: &Elf64Header = unsafe { elf_file @@ -312,32 +312,28 @@ fn load_elf_program(elf_file: &[u8], vmas: z_cap_t) -> Result { Ok(header.entry) } -pub fn spawn_process_from_elf(elf_file: &[u8]) -> Result { - let self_cap = unsafe { init::SELF_PROC_CAP }; +pub fn spawn_process_from_elf(elf_file: &[u8]) -> Result { + let self_cap = Capability::take_copy(unsafe { init::SELF_PROC_CAP })?; let port_cap = syscall::port_create()?; - let port_cap_dup = syscall::cap_duplicate(port_cap, u64::MAX)?; let (new_proc_cap, new_as_cap, foreign_port_id) = - syscall::process_spawn(self_cap, port_cap_dup)?; + syscall::process_spawn(&self_cap, port_cap.duplicate(Capability::PERMS_ALL)?)?; - let entry_point = load_elf_program(elf_file, new_as_cap)?; + let entry_point = load_elf_program(elf_file, &new_as_cap)?; let port = crate::port::PortClient::take_from(port_cap); port.write_u64_and_cap( crate::init::Z_INIT_SELF_PROC, - syscall::cap_duplicate(new_proc_cap, u64::MAX)?, + new_proc_cap.duplicate(Capability::PERMS_ALL)?, )?; port.write_u64_and_cap(crate::init::Z_INIT_SELF_VMAS, new_as_cap)?; - port.write_u64_and_cap( - crate::init::Z_INIT_ENDPOINT, - self_cap.duplicate(Capability::PERMS_ALL)?, - )?; + let yellowstone = Capability::take_copy(unsafe { crate::init::INIT_ENDPOINT })?; + port.write_u64_and_cap(crate::init::Z_INIT_ENDPOINT, yellowstone)?; - let thread_cap = syscall::thread_create(new_proc_cap)?; - syscall::thread_start(thread_cap, entry_point, foreign_port_id, 0)?; + let thread_cap = syscall::thread_create(&new_proc_cap)?; - syscall::cap_release(thread_cap)?; + syscall::thread_start(&thread_cap, entry_point, foreign_port_id, 0)?; Ok(new_proc_cap) } diff --git a/rust/lib/mammoth/src/init.rs b/rust/lib/mammoth/src/init.rs index 752a446..a03eed7 100644 --- a/rust/lib/mammoth/src/init.rs +++ b/rust/lib/mammoth/src/init.rs @@ -1,3 +1,4 @@ +use crate::cap::Capability; use crate::syscall; use crate::zion::z_cap_t; @@ -11,11 +12,12 @@ pub static mut SELF_VMAS_CAP: z_cap_t = 0; pub static mut INIT_ENDPOINT: z_cap_t = 0; pub fn parse_init_port(port_cap: z_cap_t) { + let init_port = Capability::take(port_cap); loop { let mut bytes: [u8; 8] = [0; 8]; let mut caps: [u64; 1] = [0]; - let resp = syscall::port_poll(port_cap, &mut bytes, &mut caps); + let resp = syscall::port_poll(&init_port, &mut bytes, &mut caps); if let Err(_) = resp { break; } diff --git a/rust/lib/mammoth/src/lib.rs b/rust/lib/mammoth/src/lib.rs index 7f8d665..b0891a6 100644 --- a/rust/lib/mammoth/src/lib.rs +++ b/rust/lib/mammoth/src/lib.rs @@ -8,6 +8,8 @@ extern crate alloc; #[macro_use] pub mod macros; +pub mod cap; +mod cap_syscall; pub mod elf; pub mod init; pub mod mem; diff --git a/rust/lib/mammoth/src/mem.rs b/rust/lib/mammoth/src/mem.rs index 96653d7..5f58904 100644 --- a/rust/lib/mammoth/src/mem.rs +++ b/rust/lib/mammoth/src/mem.rs @@ -1,5 +1,6 @@ +use crate::cap::Capability; use crate::syscall; -use crate::zion::{z_cap_t, ZError}; +use crate::zion::ZError; use alloc::slice; use linked_list_allocator::LockedHeap; @@ -12,7 +13,7 @@ pub fn init_heap() { // 1 MiB let size = 0x10_0000; let vmmo_cap = syscall::memory_object_create(size).expect("Failed to create memory object"); - let vaddr = syscall::address_space_map(vmmo_cap).expect("Failed to map memory object"); + let vaddr = syscall::address_space_map(&vmmo_cap).expect("Failed to map memory object"); unsafe { ALLOCATOR.lock().init(vaddr as *mut u8, size as usize); CAN_ALLOC = true; @@ -20,7 +21,7 @@ pub fn init_heap() { } pub struct MemoryRegion { - mem_cap: z_cap_t, + mem_cap: Capability, virt_addr: u64, size: u64, } @@ -28,7 +29,7 @@ pub struct MemoryRegion { impl MemoryRegion { pub fn direct_physical(paddr: u64, size: u64) -> Result { let mem_cap = syscall::memory_object_direct_physical(paddr, size)?; - let virt_addr = syscall::address_space_map(mem_cap)?; + let virt_addr = syscall::address_space_map(&mem_cap)?; Ok(Self { mem_cap, virt_addr, @@ -36,9 +37,9 @@ impl MemoryRegion { }) } - pub fn from_cap(mem_cap: z_cap_t) -> Result { - let virt_addr = syscall::address_space_map(mem_cap)?; - let size = syscall::memory_object_inspect(mem_cap)?; + pub fn from_cap(mem_cap: Capability) -> Result { + let virt_addr = syscall::address_space_map(&mem_cap)?; + let size = syscall::memory_object_inspect(&mem_cap)?; Ok(Self { mem_cap, virt_addr, @@ -48,7 +49,7 @@ impl MemoryRegion { pub fn new(size: u64) -> Result { let mem_cap = syscall::memory_object_create(size)?; - let virt_addr = syscall::address_space_map(mem_cap)?; + let virt_addr = syscall::address_space_map(&mem_cap)?; Ok(Self { mem_cap, virt_addr, @@ -74,8 +75,8 @@ impl MemoryRegion { } } - pub fn cap(&self) -> z_cap_t { - self.mem_cap + pub fn cap(&self) -> &Capability { + &self.mem_cap } } @@ -87,6 +88,5 @@ impl Drop for MemoryRegion { max += 0x1000 - (max & 0xFFF); } syscall::address_space_unmap(self.virt_addr, max).expect("Failed to unmap memory"); - syscall::cap_release(self.mem_cap).expect("Failed to release memory cap"); } } diff --git a/rust/lib/mammoth/src/port.rs b/rust/lib/mammoth/src/port.rs index 854b8d8..8a86518 100644 --- a/rust/lib/mammoth/src/port.rs +++ b/rust/lib/mammoth/src/port.rs @@ -1,8 +1,9 @@ -use crate::syscall::{cap_duplicate, cap_release, port_create, port_recv}; +use crate::cap::Capability; +use crate::syscall::{port_create, port_recv}; use crate::zion::{kZionPerm_Read, z_cap_t, ZError}; pub struct PortServer { - port_cap: z_cap_t, + port_cap: Capability, } impl PortServer { @@ -13,14 +14,16 @@ impl PortServer { } pub fn create_client_cap(&self) -> Result { - cap_duplicate(self.port_cap, !kZionPerm_Read) + self.port_cap + .duplicate(!kZionPerm_Read) + .map(|c| c.release()) } pub fn recv_byte(&self) -> Result { let mut caps: [z_cap_t; 0] = []; let mut bytes: [u8; 1] = [0]; - port_recv(self.port_cap, &mut bytes, &mut caps)?; + port_recv(&self.port_cap, &mut bytes, &mut caps)?; Ok(bytes[0]) } @@ -29,42 +32,24 @@ impl PortServer { let mut caps: [z_cap_t; 0] = []; let mut bytes: [u8; 2] = [0; 2]; - port_recv(self.port_cap, &mut bytes, &mut caps)?; + port_recv(&self.port_cap, &mut bytes, &mut caps)?; Ok(u16::from_le_bytes(bytes)) } } -impl Drop for PortServer { - fn drop(&mut self) { - cap_release(self.port_cap).expect("Failed to release port cap"); - } -} - pub struct PortClient { - port_cap: z_cap_t, + port_cap: Capability, } impl PortClient { - pub fn take_from(port_cap: z_cap_t) -> Self { + pub fn take_from(port_cap: Capability) -> Self { Self { port_cap } } - pub fn copy_from(port_cap: z_cap_t) -> Result { - Ok(Self { - port_cap: cap_duplicate(port_cap, u64::MAX)?, - }) - } - #[warn(unused_results)] - pub fn write_u64_and_cap(&self, bytes: u64, cap: z_cap_t) -> Result<(), ZError> { - let mut caps: [z_cap_t; 1] = [cap]; - crate::syscall::port_send(self.port_cap, &bytes.to_le_bytes(), &mut caps) - } -} - -impl Drop for PortClient { - fn drop(&mut self) { - cap_release(self.port_cap).expect("Failed to release port cap"); + pub fn write_u64_and_cap(&self, bytes: u64, cap: Capability) -> Result<(), ZError> { + let mut caps: [z_cap_t; 1] = [cap.release()]; + crate::syscall::port_send(&self.port_cap, &bytes.to_le_bytes(), &mut caps) } } diff --git a/rust/lib/mammoth/src/syscall.rs b/rust/lib/mammoth/src/syscall.rs index 09c1c6e..1c2d892 100644 --- a/rust/lib/mammoth/src/syscall.rs +++ b/rust/lib/mammoth/src/syscall.rs @@ -1,5 +1,6 @@ extern crate alloc; +use crate::cap::Capability; use crate::zion; use crate::zion::z_cap_t; use crate::zion::ZError; @@ -41,9 +42,9 @@ pub fn debug(msg: &str) { } pub fn process_spawn( - proc_cap: z_cap_t, - bootstrap_cap: z_cap_t, -) -> Result<(z_cap_t, z_cap_t, z_cap_t), ZError> { + proc_cap: &Capability, + bootstrap_cap: Capability, +) -> Result<(Capability, Capability, u64), ZError> { let mut new_proc_cap = 0; let mut new_as_cap = 0; let mut new_bootstrap_cap = 0; @@ -51,15 +52,19 @@ pub fn process_spawn( syscall( zion::kZionProcessSpawn, &zion::ZProcessSpawnReq { - proc_cap, - bootstrap_cap, + proc_cap: proc_cap.raw(), + bootstrap_cap: bootstrap_cap.release(), new_proc_cap: &mut new_proc_cap, new_vmas_cap: &mut new_as_cap, new_bootstrap_cap: &mut new_bootstrap_cap, }, )?; - Ok((new_proc_cap, new_as_cap, new_bootstrap_cap)) + Ok(( + Capability::take(new_proc_cap), + Capability::take(new_as_cap), + new_bootstrap_cap, + )) } pub fn process_exit(code: u64) -> ! { @@ -68,39 +73,44 @@ pub fn process_exit(code: u64) -> ! { unreachable!() } -pub fn process_wait(proc_cap: z_cap_t) -> Result { +pub fn process_wait(proc_cap: &Capability) -> Result { let mut err_code = 0; syscall( zion::kZionProcessWait, &zion::ZProcessWaitReq { - proc_cap, + proc_cap: proc_cap.raw(), exit_code: &mut err_code, }, )?; Ok(err_code) } -pub fn thread_create(proc_cap: z_cap_t) -> Result { +pub fn thread_create(proc_cap: &Capability) -> Result { let mut cap = 0; syscall( zion::kZionThreadCreate, &zion::ZThreadCreateReq { - proc_cap, - thread_cap: &mut cap as *mut z_cap_t, + proc_cap: proc_cap.raw(), + thread_cap: &mut cap, }, )?; - Ok(cap) + Ok(Capability::take(cap)) } pub fn thread_sleep(millis: u64) -> Result<(), ZError> { syscall(zion::kZionThreadSleep, &zion::ZThreadSleepReq { millis }) } -pub fn thread_start(thread_cap: z_cap_t, entry: u64, arg1: u64, arg2: u64) -> Result<(), ZError> { +pub fn thread_start( + thread_cap: &Capability, + entry: u64, + arg1: u64, + arg2: u64, +) -> Result<(), ZError> { syscall( zion::kZionThreadStart, &zion::ZThreadStartReq { - thread_cap, + thread_cap: thread_cap.raw(), entry, arg1, arg2, @@ -108,8 +118,13 @@ pub fn thread_start(thread_cap: z_cap_t, entry: u64, arg1: u64, arg2: u64) -> Re ) } -pub fn thread_wait(thread_cap: z_cap_t) -> Result<(), ZError> { - syscall(zion::kZionThreadWait, &zion::ZThreadWaitReq { thread_cap }) +pub fn thread_wait(thread_cap: &Capability) -> Result<(), ZError> { + syscall( + zion::kZionThreadWait, + &zion::ZThreadWaitReq { + thread_cap: thread_cap.raw(), + }, + ) } pub fn thread_exit() -> ! { @@ -117,17 +132,17 @@ pub fn thread_exit() -> ! { unreachable!(); } -pub fn memory_object_create(size: u64) -> Result { +pub fn memory_object_create(size: u64) -> Result { let mut vmmo_cap = 0; let obj_req = zion::ZMemoryObjectCreateReq { size, vmmo_cap: &mut vmmo_cap as *mut u64, }; syscall(zion::kZionMemoryObjectCreate, &obj_req)?; - Ok(vmmo_cap) + Ok(Capability::take(vmmo_cap)) } -pub fn memory_object_direct_physical(paddr: u64, size: u64) -> Result { +pub fn memory_object_direct_physical(paddr: u64, size: u64) -> Result { let mut vmmo_cap = 0; syscall( zion::kZionMemoryObjectCreatePhysical, @@ -137,26 +152,26 @@ pub fn memory_object_direct_physical(paddr: u64, size: u64) -> Result Result { +pub fn memory_object_inspect(mem_cap: &Capability) -> Result { let mut mem_size = 0; syscall( zion::kZionMemoryObjectInspect, &zion::ZMemoryObjectInspectReq { - vmmo_cap: mem_cap, + vmmo_cap: mem_cap.raw(), size: &mut mem_size, }, )?; Ok(mem_size) } -pub fn address_space_map(vmmo_cap: z_cap_t) -> Result { +pub fn address_space_map(vmmo_cap: &Capability) -> Result { let mut vaddr: u64 = 0; // FIXME: Allow caller to pass these options. let vmas_req = zion::ZAddressSpaceMapReq { - vmmo_cap, + vmmo_cap: vmmo_cap.raw(), vmas_cap: unsafe { crate::init::SELF_VMAS_CAP }, align: 0x2000, vaddr: &mut vaddr as *mut u64, @@ -168,14 +183,14 @@ pub fn address_space_map(vmmo_cap: z_cap_t) -> Result { } pub fn address_space_map_external( - vmas_cap: z_cap_t, - vmmo_cap: z_cap_t, + vmas_cap: &Capability, + vmmo_cap: &Capability, vaddr: u64, ) -> Result<(), ZError> { let mut vaddr_throw: u64 = 0; let vmas_req = zion::ZAddressSpaceMapReq { - vmmo_cap, - vmas_cap, + vmas_cap: vmas_cap.raw(), + vmmo_cap: vmmo_cap.raw(), align: 0, vaddr: &mut vaddr_throw as *mut u64, vmas_offset: vaddr, @@ -196,7 +211,7 @@ pub fn address_space_unmap(lower_addr: u64, upper_addr: u64) -> Result<(), ZErro ) } -pub fn port_create() -> Result { +pub fn port_create() -> Result { let mut port_cap = 0; syscall( zion::kZionPortCreate, @@ -204,14 +219,14 @@ pub fn port_create() -> Result { port_cap: &mut port_cap, }, )?; - Ok(port_cap) + Ok(Capability::take(port_cap)) } -pub fn port_send(port_cap: z_cap_t, bytes: &[u8], caps: &mut [z_cap_t]) -> Result<(), ZError> { +pub fn port_send(port_cap: &Capability, bytes: &[u8], caps: &mut [z_cap_t]) -> Result<(), ZError> { syscall( zion::kZionPortSend, &zion::ZPortSendReq { - port_cap, + port_cap: port_cap.raw(), num_bytes: bytes.len() as u64, data: bytes.as_ptr() as *const c_void, num_caps: caps.len() as u64, @@ -222,7 +237,7 @@ pub fn port_send(port_cap: z_cap_t, bytes: &[u8], caps: &mut [z_cap_t]) -> Resul } pub fn port_recv( - port_cap: z_cap_t, + port_cap: &Capability, bytes: &mut [u8], caps: &mut [u64], ) -> Result<(u64, u64), ZError> { @@ -231,7 +246,7 @@ pub fn port_recv( syscall( zion::kZionPortRecv, &zion::ZPortRecvReq { - port_cap, + port_cap: port_cap.raw(), data: bytes.as_mut_ptr() as *mut c_void, num_bytes: &mut num_bytes as *mut u64, caps: caps.as_mut_ptr(), @@ -242,14 +257,14 @@ pub fn port_recv( } pub fn port_poll( - port_cap: z_cap_t, + port_cap: &Capability, bytes: &mut [u8], caps: &mut [u64], ) -> Result<(u64, u64), ZError> { let mut num_bytes = bytes.len() as u64; let mut num_caps = caps.len() as u64; let req = zion::ZPortPollReq { - port_cap, + port_cap: port_cap.raw(), data: bytes.as_mut_ptr() as *mut c_void, num_bytes: &mut num_bytes as *mut u64, caps: caps.as_mut_ptr(), @@ -259,7 +274,7 @@ pub fn port_poll( Ok((num_bytes, num_caps)) } -pub fn endpoint_create() -> Result { +pub fn endpoint_create() -> Result { let mut endpoint_cap: z_cap_t = 0; syscall( zion::kZionEndpointCreate, @@ -267,19 +282,19 @@ pub fn endpoint_create() -> Result { endpoint_cap: &mut endpoint_cap, }, )?; - Ok(endpoint_cap) + Ok(Capability::take(endpoint_cap)) } pub fn endpoint_send( - endpoint_cap: z_cap_t, + endpoint_cap: &Capability, bytes: &[u8], caps: &[z_cap_t], -) -> Result { +) -> Result { let mut reply_port_cap: u64 = 0; let send_req = zion::ZEndpointSendReq { caps: caps.as_ptr(), num_caps: caps.len() as u64, - endpoint_cap, + endpoint_cap: endpoint_cap.raw(), data: bytes.as_ptr() as *const c_void, num_bytes: bytes.len() as u64, reply_port_cap: &mut reply_port_cap, @@ -287,19 +302,19 @@ pub fn endpoint_send( syscall(zion::kZionEndpointSend, &send_req)?; - Ok(reply_port_cap) + Ok(Capability::take(reply_port_cap)) } pub fn endpoint_recv( - endpoint_cap: z_cap_t, + endpoint_cap: &Capability, bytes: &mut [u8], caps: &mut [z_cap_t], -) -> Result<(u64, u64, z_cap_t), ZError> { +) -> Result<(u64, u64, Capability), ZError> { let mut num_bytes = bytes.len() as u64; let mut num_caps = caps.len() as u64; let mut reply_port_cap = 0; let recv_req = zion::ZEndpointRecvReq { - endpoint_cap, + endpoint_cap: endpoint_cap.raw(), data: bytes.as_mut_ptr() as *mut c_void, num_bytes: &mut num_bytes, caps: caps.as_mut_ptr(), @@ -309,18 +324,18 @@ pub fn endpoint_recv( syscall(zion::kZionEndpointRecv, &recv_req)?; - Ok((num_bytes, num_caps, reply_port_cap)) + Ok((num_bytes, num_caps, Capability::take(reply_port_cap))) } pub fn reply_port_send( - reply_port_cap: z_cap_t, + reply_port_cap: Capability, bytes: &[u8], caps: &[z_cap_t], ) -> Result<(), ZError> { syscall( zion::kZionReplyPortSend, &zion::ZReplyPortSendReq { - reply_port_cap, + reply_port_cap: reply_port_cap.raw(), data: bytes.as_ptr() as *const c_void, num_bytes: bytes.len() as u64, caps: caps.as_ptr(), @@ -330,14 +345,14 @@ pub fn reply_port_send( } pub fn reply_port_recv( - reply_port_cap: z_cap_t, + reply_port_cap: Capability, bytes: &mut [u8], caps: &mut [z_cap_t], ) -> Result<(u64, u64), ZError> { let mut num_bytes = bytes.len() as u64; let mut num_caps = caps.len() as u64; let recv_req = zion::ZReplyPortRecvReq { - reply_port_cap, + reply_port_cap: reply_port_cap.raw(), caps: caps.as_mut_ptr(), num_caps: &mut num_caps, data: bytes.as_mut_ptr() as *mut c_void, @@ -348,20 +363,3 @@ pub fn reply_port_recv( Ok((num_bytes, num_caps)) } - -pub fn cap_duplicate(cap: z_cap_t, perm_mask: u64) -> Result { - let mut new_cap = 0; - syscall( - zion::kZionCapDuplicate, - &zion::ZCapDuplicateReq { - cap_in: cap, - perm_mask, - cap_out: &mut new_cap, - }, - )?; - Ok(new_cap) -} - -pub fn cap_release(cap: z_cap_t) -> Result<(), ZError> { - syscall(zion::kZionCapRelease, &zion::ZCapReleaseReq { cap }) -} diff --git a/rust/lib/mammoth/src/thread.rs b/rust/lib/mammoth/src/thread.rs index 92fd086..9d2e688 100644 --- a/rust/lib/mammoth/src/thread.rs +++ b/rust/lib/mammoth/src/thread.rs @@ -1,6 +1,6 @@ +use crate::cap::Capability; use crate::syscall; use crate::zion; -use crate::zion::z_cap_t; use alloc::boxed::Box; use core::ffi::c_void; @@ -17,7 +17,7 @@ extern "C" fn internal_entry_point(thread_ptr: *const Thread, arg1: *const c_voi } // TODO: Add a Drop implementation that kills this thread and drops its capability. pub struct Thread { - cap: z_cap_t, + cap: Capability, // This field only exists to ensure that the entry reference will outlive the thread object // itself. entry: ThreadEntry, @@ -25,11 +25,11 @@ pub struct Thread { impl Thread { pub fn spawn(entry: ThreadEntry, arg1: *const c_void) -> Result, zion::ZError> { - let proc_cap = unsafe { crate::init::SELF_PROC_CAP }; - let cap = syscall::thread_create(proc_cap)?; + let proc_cap = Capability::take_copy(unsafe { crate::init::SELF_PROC_CAP })?; + let cap = syscall::thread_create(&proc_cap)?; let thread = Box::new(Self { cap, entry }); syscall::thread_start( - cap, + &thread.cap, internal_entry_point as u64, thread.as_ref() as *const Thread as u64, arg1 as u64, @@ -39,6 +39,6 @@ impl Thread { } pub fn join(&self) -> Result<(), zion::ZError> { - syscall::thread_wait(self.cap) + syscall::thread_wait(&self.cap) } } diff --git a/rust/lib/victoriafalls/src/file.rs b/rust/lib/victoriafalls/src/file.rs index 4877a09..619c4c7 100644 --- a/rust/lib/victoriafalls/src/file.rs +++ b/rust/lib/victoriafalls/src/file.rs @@ -1,6 +1,6 @@ use crate::OpenFileRequest; use alloc::string::ToString; -use mammoth::zion::ZError; +use mammoth::{cap::Capability, zion::ZError}; pub struct File { memory: mammoth::mem::MemoryRegion, @@ -14,7 +14,7 @@ impl File { })?; Ok(Self { - memory: mammoth::mem::MemoryRegion::from_cap(resp.memory)?, + memory: mammoth::mem::MemoryRegion::from_cap(Capability::take(resp.memory))?, }) } diff --git a/rust/lib/victoriafalls/src/lib.rs b/rust/lib/victoriafalls/src/lib.rs index b1532a9..6248bc5 100644 --- a/rust/lib/victoriafalls/src/lib.rs +++ b/rust/lib/victoriafalls/src/lib.rs @@ -18,7 +18,7 @@ fn get_client() -> &'static mut VFSClient { }) .expect("Failed to get VFS endpoint"); - VFS_CLIENT = Some(VFSClient::new(endpoint_cap.endpoint)); + VFS_CLIENT = Some(VFSClient::new(Capability::take(endpoint_cap.endpoint))); } VFS_CLIENT.as_mut().unwrap() } diff --git a/rust/lib/voyageurs/src/listener.rs b/rust/lib/voyageurs/src/listener.rs index a64626e..b340ed3 100644 --- a/rust/lib/voyageurs/src/listener.rs +++ b/rust/lib/voyageurs/src/listener.rs @@ -3,6 +3,7 @@ use core::cell::RefCell; use alloc::boxed::Box; use alloc::rc::Rc; use alloc::string::ToString; +use mammoth::cap::Capability; use mammoth::port::PortServer; use mammoth::thread::Thread; use mammoth::zion::ZError; @@ -216,7 +217,7 @@ impl KeyboardListener { })? .endpoint; - let mut voyageur_client = crate::VoyageursClient::new(voyageur_endpoint); + let mut voyageur_client = crate::VoyageursClient::new(Capability::take(voyageur_endpoint)); voyageur_client.register_keyboard_listener(&crate::KeyboardListener { port_capability: listnr.listen_port.create_client_cap()?, diff --git a/rust/lib/yellowstone/src/lib.rs b/rust/lib/yellowstone/src/lib.rs index 0fc673f..76659ef 100644 --- a/rust/lib/yellowstone/src/lib.rs +++ b/rust/lib/yellowstone/src/lib.rs @@ -11,7 +11,7 @@ static mut YELLOWSTONE_INIT: Option = None; pub fn from_init_endpoint() -> &'static mut YellowstoneClient { unsafe { if let None = YELLOWSTONE_INIT { - YELLOWSTONE_INIT = Some(YellowstoneClient::new(INIT_ENDPOINT)); + YELLOWSTONE_INIT = Some(YellowstoneClient::new(Capability::take(INIT_ENDPOINT))); } YELLOWSTONE_INIT.as_mut().unwrap() diff --git a/rust/lib/yunq/src/client.rs b/rust/lib/yunq/src/client.rs index ad3a761..e90698e 100644 --- a/rust/lib/yunq/src/client.rs +++ b/rust/lib/yunq/src/client.rs @@ -1,14 +1,14 @@ use crate::buffer::ByteBuffer; use crate::message::YunqMessage; use alloc::vec::Vec; -use mammoth::zion::z_cap_t; +use mammoth::cap::Capability; use mammoth::zion::ZError; pub fn call_endpoint( request_id: u64, req: &Req, byte_buffer: &mut ByteBuffer, - endpoint_cap: z_cap_t, + endpoint_cap: &Capability, ) -> Result { let mut cap_buffer = Vec::new(); let length = req.serialize_as_request(request_id, byte_buffer, &mut cap_buffer)?; diff --git a/rust/lib/yunq/src/server.rs b/rust/lib/yunq/src/server.rs index c8c4f36..9616d6e 100644 --- a/rust/lib/yunq/src/server.rs +++ b/rust/lib/yunq/src/server.rs @@ -1,5 +1,6 @@ use crate::buffer::ByteBuffer; use alloc::vec::Vec; +use mammoth::cap::Capability; use mammoth::syscall; use mammoth::zion::z_cap_t; use mammoth::zion::ZError; @@ -36,7 +37,7 @@ pub trait YunqServer { } } - fn endpoint_cap(&self) -> z_cap_t; + fn endpoint_cap(&self) -> &Capability; fn handle_request( &self, method_number: u64, diff --git a/rust/sys/teton/src/terminal.rs b/rust/sys/teton/src/terminal.rs index 0ce7a53..5c7d314 100644 --- a/rust/sys/teton/src/terminal.rs +++ b/rust/sys/teton/src/terminal.rs @@ -117,9 +117,9 @@ impl Terminal { Some(prog) => { let file = victoriafalls::file::File::open(prog).expect("Failed to open file"); let proc_cap = mammoth::elf::spawn_process_from_elf(file.slice()) - .expect("Faield to spawn process"); + .expect("Failed to spawn process"); - let exit_code = mammoth::syscall::process_wait(proc_cap) + let exit_code = mammoth::syscall::process_wait(&proc_cap) .expect("Failed to wait on process."); self.write_line(&format!("Process exit code: {}", exit_code)); diff --git a/rust/usr/testbed/src/main.rs b/rust/usr/testbed/src/main.rs index 0e994b5..9b6ad6b 100644 --- a/rust/usr/testbed/src/main.rs +++ b/rust/usr/testbed/src/main.rs @@ -9,7 +9,6 @@ use mammoth::define_entry; use mammoth::thread; use mammoth::zion::z_err_t; use yellowstone::GetEndpointRequest; -use yellowstone::YellowstoneClient; define_entry!(); @@ -17,10 +16,9 @@ define_entry!(); pub extern "C" fn main() -> z_err_t { debug!("Testing!"); - let mut yellowstone; - unsafe { - yellowstone = YellowstoneClient::new(mammoth::init::INIT_ENDPOINT); - } + let yellowstone = yellowstone::from_init_endpoint(); + + debug!("Get endpoint"); let endpoint = yellowstone .get_endpoint(&GetEndpointRequest { diff --git a/yunq/rust/src/codegen.rs b/yunq/rust/src/codegen.rs index 31f61e4..34477cf 100644 --- a/yunq/rust/src/codegen.rs +++ b/yunq/rust/src/codegen.rs @@ -33,17 +33,17 @@ fn generate_method(method: &Method) -> TokenStream { match (maybe_req, maybe_resp) { (Some(req), Some(resp)) => quote! { pub fn #name (&mut self, req: & #req) -> Result<#resp, ZError> { - yunq::client::call_endpoint(#id, req, &mut self.byte_buffer, self.endpoint_cap) + yunq::client::call_endpoint(#id, req, &mut self.byte_buffer, &self.endpoint_cap) } }, (Some(req), None) => quote! { pub fn #name (&mut self, req: & #req) -> Result { - yunq::client::call_endpoint(#id, req, &mut self.byte_buffer, self.endpoint_cap) + yunq::client::call_endpoint(#id, req, &mut self.byte_buffer, &self.endpoint_cap) } }, (None, Some(resp)) => quote! { pub fn #name (&mut self) -> Result<#resp, ZError> { - yunq::client::call_endpoint(#id, &yunq::message::Empty{}, &mut self.byte_buffer, self.endpoint_cap) + yunq::client::call_endpoint(#id, &yunq::message::Empty{}, &mut self.byte_buffer, &self.endpoint_cap) } }, _ => unreachable!(), @@ -56,12 +56,12 @@ fn generate_client(interface: &Interface) -> TokenStream { let methods = interface.methods.iter().map(|m| generate_method(&m)); quote! { pub struct #name { - endpoint_cap: z_cap_t, + endpoint_cap: Capability, byte_buffer: ByteBuffer<0x1000>, } impl #name { - pub fn new(endpoint_cap: z_cap_t) -> Self { + pub fn new(endpoint_cap: Capability) -> Self { Self { endpoint_cap, byte_buffer: ByteBuffer::new(), @@ -139,7 +139,7 @@ fn generate_server(interface: &Interface) -> TokenStream { } pub struct #server_name { - endpoint_cap: z_cap_t, + endpoint_cap: Capability, handler: T } @@ -164,8 +164,8 @@ fn generate_server(interface: &Interface) -> TokenStream { } impl yunq::server::YunqServer for #server_name { - fn endpoint_cap(&self) -> z_cap_t { - self.endpoint_cap + fn endpoint_cap(&self) -> &Capability { + &self.endpoint_cap } fn handle_request( @@ -206,6 +206,7 @@ pub fn generate_code(ast: &Vec) -> String { use core::ffi::c_void; use mammoth::syscall; use mammoth::thread; + use mammoth::cap::Capability; use mammoth::zion::z_cap_t; use mammoth::zion::ZError; use yunq::ByteBuffer;