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
pub type Handler = fn();

pub struct Idt {
    handlers: core::cell::UnsafeCell<[Option<Handler>; 256]>,
}

unsafe impl Sync for Idt {}

impl Default for Idt {
    fn default() -> Self {
        Self::new()
    }
}

impl Idt {
    pub fn new() -> Self {
        Idt {
            handlers: core::cell::UnsafeCell::new([None; 256]),
        }
    }

    pub fn register(&self, vec: usize, h: Handler) -> bool {
        if vec >= 256 {
            return false;
        }
        unsafe {
            (*self.handlers.get())[vec] = Some(h);
        }
        true
    }

    pub fn unregister(&self, vec: usize) -> bool {
        if vec >= 256 {
            return false;
        }
        unsafe {
            (*self.handlers.get())[vec] = None;
        }
        true
    }

    pub fn handle(&self, vec: usize) {
        if vec >= 256 {
            return;
        }
        unsafe {
            if let Some(h) = (*self.handlers.get())[vec] {
                h();
            }
        }
    }

    pub fn get() -> Option<&'static Idt> {
        get()
    }
}

use crate::common::once::Once;

static IDT_ONCE: Once<Idt> = Once::new();

pub fn init() {
    let idt = Idt::new();
    if IDT_ONCE.set(idt) {
        if let Some(i) = IDT_ONCE.get() {
            for v in 0x20usize..0x30usize {
                let ok = i.register(v, default_handler);
                debug_assert!(ok);
                if let crate::arch::Architecture::X86_64 = crate::arch::detect_arch() {
                    let ok2 = crate::arch::x86_64::interrupt::idt::set_handler(v, default_handler);
                    debug_assert!(ok2);
                }
            }
        }
    }
}

fn default_handler() {}

pub fn get() -> Option<&'static Idt> {
    IDT_ONCE.get()
}