Return result type from syscall and format info on panic.
This commit is contained in:
		
							parent
							
								
									e310eee468
								
							
						
					
					
						commit
						51d40f6db6
					
				| 
						 | 
				
			
			@ -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!()
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,22 +8,84 @@ use core::panic::PanicInfo;
 | 
			
		|||
 | 
			
		||||
include!("bindings.rs");
 | 
			
		||||
 | 
			
		||||
pub fn syscall<T>(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<T>(id: u64, req: &T) {
 | 
			
		||||
    if syscall(id, req) != 0 {
 | 
			
		||||
        debug("Bad syscall response.");
 | 
			
		||||
        panic!();
 | 
			
		||||
impl From<u64> 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<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]
 | 
			
		||||
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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue