hardware 0.0.9

A no_std bare-metal hardware abstraction layer — all port I/O, memory and swap allocations are guarded at runtime. Do not consider this dependency stable before x.1.x
Documentation
use core::sync::atomic::{AtomicUsize, Ordering};

#[derive(Debug, Copy, Clone)]
pub enum SyscallResult {
    Ok(usize),
    Denied,
    NotFound,
    Fault,
}

const MAX_SYSCALLS: usize = 256;

struct SyscallStorage {
    handlers: [AtomicUsize; MAX_SYSCALLS],
}

unsafe impl Sync for SyscallStorage {}

static SYSCALL_TABLE: SyscallStorage = SyscallStorage {
    handlers: [const { AtomicUsize::new(0) }; MAX_SYSCALLS],
};

pub fn register_syscall(nr: usize, handler: usize) -> bool {
    if nr >= MAX_SYSCALLS {
        return false;
    }
    SYSCALL_TABLE.handlers[nr].store(handler, Ordering::Release);
    true
}

pub fn handle_syscall(nr: usize, arg0: usize, arg1: usize, arg2: usize) -> SyscallResult {
    if nr >= MAX_SYSCALLS {
        return SyscallResult::NotFound;
    }
    let h = SYSCALL_TABLE.handlers[nr].load(Ordering::Acquire);
    if h == 0 {
        return SyscallResult::NotFound;
    }
    let func: fn(usize, usize, usize) -> usize = unsafe { core::mem::transmute(h) };
    SyscallResult::Ok(func(arg0, arg1, arg2))
}