Return result type from syscall and format info on panic.

This commit is contained in:
Drew Galbraith 2024-07-26 16:31:57 -07:00
parent e310eee468
commit 51d40f6db6
4 changed files with 91 additions and 14 deletions

View File

@ -32,7 +32,7 @@ pub fn parse_init_port(port_cap: syscall::zcap) {
num_caps: &mut num_caps as *mut u64, num_caps: &mut num_caps as *mut u64,
}; };
let resp = syscall::syscall(syscall::kZionPortPoll, &req); let resp = syscall::syscall(syscall::kZionPortPoll, &req);
if resp != 0 { if let Err(_) = resp {
break; break;
} }
unsafe { unsafe {
@ -59,7 +59,7 @@ macro_rules! define_entry {
unsafe { unsafe {
let err = main(); let err = main();
let req = mammoth::syscall::ZProcessExitReq { code: err }; let req = mammoth::syscall::ZProcessExitReq { code: err };
mammoth::syscall::syscall(mammoth::syscall::kZionProcessExit, &req); let _ = mammoth::syscall::syscall(mammoth::syscall::kZionProcessExit, &req);
} }
unreachable!() unreachable!()
} }

View File

@ -5,6 +5,8 @@ use linked_list_allocator::LockedHeap;
#[global_allocator] #[global_allocator]
static ALLOCATOR: LockedHeap = LockedHeap::empty(); static ALLOCATOR: LockedHeap = LockedHeap::empty();
pub static mut CAN_ALLOC: bool = false;
pub fn init_heap() { pub fn init_heap() {
// 1 MiB // 1 MiB
let size = 0x10_0000; let size = 0x10_0000;
@ -13,7 +15,8 @@ pub fn init_heap() {
size, size,
vmmo_cap: &mut vmmo_cap as *mut u64, 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 { unsafe {
let mut vaddr: u64 = 0; let mut vaddr: u64 = 0;
@ -25,7 +28,9 @@ pub fn init_heap() {
vmas_offset: 0, 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); ALLOCATOR.lock().init(vaddr as *mut u8, size as usize);
CAN_ALLOC = true;
} }
} }

View File

@ -8,22 +8,84 @@ use core::panic::PanicInfo;
include!("bindings.rs"); include!("bindings.rs");
pub fn syscall<T>(id: u64, req: &T) -> u64 { pub enum ZError {
unsafe { SysCall1(id, req as *const T as *const c_void) } 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<T>(id: u64, req: &T) { impl From<u64> for ZError {
if syscall(id, req) != 0 { fn from(value: u64) -> Self {
debug("Bad syscall response."); match value {
panic!(); 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<T>(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] #[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. // Internal error.
let req = ZProcessExitReq { code: 0x100 }; let req = ZProcessExitReq { code: 0x100 };
syscall(kZionProcessExit, &req); let _ = syscall(kZionProcessExit, &req);
unreachable!() unreachable!()
} }
@ -32,7 +94,7 @@ pub fn debug(msg: &str) {
message: msg.as_ptr() as *const i8, message: msg.as_ptr() as *const i8,
size: msg.len() as u64, size: msg.len() as u64,
}; };
syscall(kZionDebug, &req); syscall(kZionDebug, &req).expect("Failed to write");
} }
pub struct Writer { pub struct Writer {
@ -73,7 +135,9 @@ macro_rules! debug {
($fmt:literal, $($val:expr),+) => {{ ($fmt:literal, $($val:expr),+) => {{
use core::fmt::Write as _; use core::fmt::Write as _;
use alloc::string::String; 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"); write!(&mut w, $fmt, $($val),*).expect("Failed to format");
let s: String = w.into(); let s: String = w.into();
debug(&s); debug(&s);

View File

@ -8,6 +8,7 @@ use mammoth::debug;
use mammoth::define_entry; use mammoth::define_entry;
use mammoth::syscall::debug; use mammoth::syscall::debug;
use mammoth::syscall::z_err_t; use mammoth::syscall::z_err_t;
use mammoth::syscall::Writer;
define_entry!(); define_entry!();
@ -17,5 +18,12 @@ pub extern "C" fn main() -> z_err_t {
let x = Box::new("Heap str"); let x = Box::new("Heap str");
debug(&x); debug(&x);
debug!("Formatted {}", "string"); 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 0
} }