feat(adapter-riscv): replace static mut with KernelCell, complete all 17 syscall decoders, wire timer and PLIC interrupts to kernel
This commit is contained in:
35
crates/adapter-riscv/src/kernel_cell.rs
Normal file
35
crates/adapter-riscv/src/kernel_cell.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
use core::cell::UnsafeCell;
|
||||
use core::mem::MaybeUninit;
|
||||
use core::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
pub struct KernelCell<T> {
|
||||
initialized: AtomicBool,
|
||||
inner: UnsafeCell<MaybeUninit<T>>,
|
||||
}
|
||||
|
||||
// Single-core: no concurrent access. Initialized once before traps are enabled.
|
||||
unsafe impl<T> Sync for KernelCell<T> {}
|
||||
|
||||
impl<T> KernelCell<T> {
|
||||
pub const fn uninit() -> Self {
|
||||
Self {
|
||||
initialized: AtomicBool::new(false),
|
||||
inner: UnsafeCell::new(MaybeUninit::uninit()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(&self, value: T) {
|
||||
unsafe { (*self.inner.get()).write(value) };
|
||||
self.initialized.store(true, Ordering::Release);
|
||||
}
|
||||
|
||||
pub fn get(&self) -> &T {
|
||||
debug_assert!(self.initialized.load(Ordering::Acquire));
|
||||
unsafe { (*self.inner.get()).assume_init_ref() }
|
||||
}
|
||||
|
||||
pub fn get_mut(&self) -> &mut T {
|
||||
debug_assert!(self.initialized.load(Ordering::Acquire));
|
||||
unsafe { (*self.inner.get()).assume_init_mut() }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user