From 51d40f6db694cba162c0d19f6ffc48098862d0d3 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Fri, 26 Jul 2024 16:31:57 -0700 Subject: [PATCH] Return result type from syscall and format info on panic. --- rust/lib/mammoth/src/lib.rs | 4 +- rust/lib/mammoth/src/mem.rs | 9 +++- rust/lib/mammoth/src/syscall.rs | 84 +++++++++++++++++++++++++++++---- rust/usr/testbed/src/main.rs | 8 ++++ 4 files changed, 91 insertions(+), 14 deletions(-) diff --git a/rust/lib/mammoth/src/lib.rs b/rust/lib/mammoth/src/lib.rs index 7878923..d55a2a1 100644 --- a/rust/lib/mammoth/src/lib.rs +++ b/rust/lib/mammoth/src/lib.rs @@ -32,7 +32,7 @@ pub fn parse_init_port(port_cap: syscall::zcap) { num_caps: &mut num_caps as *mut u64, }; let resp = syscall::syscall(syscall::kZionPortPoll, &req); - if resp != 0 { + if let Err(_) = resp { break; } unsafe { @@ -59,7 +59,7 @@ macro_rules! define_entry { unsafe { let err = main(); let req = mammoth::syscall::ZProcessExitReq { code: err }; - mammoth::syscall::syscall(mammoth::syscall::kZionProcessExit, &req); + let _ = mammoth::syscall::syscall(mammoth::syscall::kZionProcessExit, &req); } unreachable!() } diff --git a/rust/lib/mammoth/src/mem.rs b/rust/lib/mammoth/src/mem.rs index 12b3832..74bb1c4 100644 --- a/rust/lib/mammoth/src/mem.rs +++ b/rust/lib/mammoth/src/mem.rs @@ -5,6 +5,8 @@ use linked_list_allocator::LockedHeap; #[global_allocator] static ALLOCATOR: LockedHeap = LockedHeap::empty(); +pub static mut CAN_ALLOC: bool = false; + pub fn init_heap() { // 1 MiB let size = 0x10_0000; @@ -13,7 +15,8 @@ pub fn init_heap() { size, vmmo_cap: &mut vmmo_cap as *mut u64, }; - syscall::checked_syscall(syscall::kZionMemoryObjectCreate, &obj_req); + syscall::syscall(syscall::kZionMemoryObjectCreate, &obj_req) + .expect("Failed to create memory object"); unsafe { let mut vaddr: u64 = 0; @@ -25,7 +28,9 @@ pub fn init_heap() { vmas_offset: 0, }; - syscall::checked_syscall(syscall::kZionAddressSpaceMap, &vmas_req); + syscall::syscall(syscall::kZionAddressSpaceMap, &vmas_req) + .expect("Failed to map memory object"); ALLOCATOR.lock().init(vaddr as *mut u8, size as usize); + CAN_ALLOC = true; } } diff --git a/rust/lib/mammoth/src/syscall.rs b/rust/lib/mammoth/src/syscall.rs index 768a85f..3c7b912 100644 --- a/rust/lib/mammoth/src/syscall.rs +++ b/rust/lib/mammoth/src/syscall.rs @@ -8,22 +8,84 @@ use core::panic::PanicInfo; include!("bindings.rs"); -pub fn syscall(id: u64, req: &T) -> u64 { - unsafe { SysCall1(id, req as *const T as *const c_void) } +pub enum ZError { + UNKNOWN = 0x0, + // First set of error codes generally indicate user errors. + INVALID_ARGUMENT = 0x1, + NOT_FOUND = 0x2, + PERMISSION_DENIED = 0x3, + NULL_PTR = 0x4, + EMPTY = 0x5, + ALREADY_EXISTS = 0x6, + BUFFER_SIZE = 0x7, + FAILED_PRECONDITION = 0x8, + + // Second set of error codes generally indicate service errors. + INTERNAL = 0x100, + UNIMPLEMENTED = 0x101, + EXHAUSTED = 0x102, + INVALID_RESPONSE = 0x103, + + // Kernel specific error codes (relating to capabilities). + CAP_NOT_FOUND = 0x1000, + CAP_WRONG_TYPE = 0x1001, + CAP_PERMISSION_DENIED = 0x1002, } -pub fn checked_syscall(id: u64, req: &T) { - if syscall(id, req) != 0 { - debug("Bad syscall response."); - panic!(); +impl From for ZError { + fn from(value: u64) -> Self { + match value { + 0x1 => ZError::INVALID_ARGUMENT, + 0x2 => ZError::NOT_FOUND, + 0x3 => ZError::PERMISSION_DENIED, + 0x4 => ZError::NULL_PTR, + 0x5 => ZError::EMPTY, + 0x6 => ZError::ALREADY_EXISTS, + 0x7 => ZError::BUFFER_SIZE, + 0x8 => ZError::FAILED_PRECONDITION, + + 0x100 => ZError::INTERNAL, + 0x101 => ZError::UNIMPLEMENTED, + 0x102 => ZError::EXHAUSTED, + 0x103 => ZError::INVALID_RESPONSE, + + 0x1000 => ZError::CAP_NOT_FOUND, + 0x1001 => ZError::CAP_WRONG_TYPE, + 0x1002 => ZError::CAP_PERMISSION_DENIED, + _ => ZError::UNKNOWN, + } } } +impl fmt::Debug for ZError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("ZError") + } +} + +#[must_use] +pub fn syscall(id: u64, req: &T) -> Result<(), ZError> { + unsafe { + let resp = SysCall1(id, req as *const T as *const c_void); + if resp != 0 { + return Err(ZError::from(resp)); + } + } + Ok(()) +} + #[panic_handler] -fn panic(_info: &PanicInfo) -> ! { +fn panic(info: &PanicInfo) -> ! { + unsafe { + if crate::mem::CAN_ALLOC { + crate::debug!("Panic occured: {}", info); + } else { + debug("Panic occured before heap initialized.") + } + } // Internal error. let req = ZProcessExitReq { code: 0x100 }; - syscall(kZionProcessExit, &req); + let _ = syscall(kZionProcessExit, &req); unreachable!() } @@ -32,7 +94,7 @@ pub fn debug(msg: &str) { message: msg.as_ptr() as *const i8, size: msg.len() as u64, }; - syscall(kZionDebug, &req); + syscall(kZionDebug, &req).expect("Failed to write"); } pub struct Writer { @@ -73,7 +135,9 @@ macro_rules! debug { ($fmt:literal, $($val:expr),+) => {{ use core::fmt::Write as _; use alloc::string::String; - let mut w = mammoth::syscall::Writer::new(); + // TODO: Find a way to do this so we don't have to import writer. + // We can't fully qualify this if we want to use it in this crate. + let mut w = Writer::new(); write!(&mut w, $fmt, $($val),*).expect("Failed to format"); let s: String = w.into(); debug(&s); diff --git a/rust/usr/testbed/src/main.rs b/rust/usr/testbed/src/main.rs index d771249..0452781 100644 --- a/rust/usr/testbed/src/main.rs +++ b/rust/usr/testbed/src/main.rs @@ -8,6 +8,7 @@ use mammoth::debug; use mammoth::define_entry; use mammoth::syscall::debug; use mammoth::syscall::z_err_t; +use mammoth::syscall::Writer; define_entry!(); @@ -17,5 +18,12 @@ pub extern "C" fn main() -> z_err_t { let x = Box::new("Heap str"); debug(&x); debug!("Formatted {}", "string"); + let mut vmmo_cap: u64 = 0; + let obj_req = mammoth::syscall::ZMemoryObjectCreateReq { + size: 0, + vmmo_cap: &mut vmmo_cap as *mut u64, + }; + mammoth::syscall::syscall(mammoth::syscall::kZionMemoryObjectCreate, &obj_req) + .expect("Failed to create memory object"); 0 }