Better user programs with a special std. Sleep and exit are calling scheduler instead of wfi.

This commit is contained in:
2026-02-21 18:29:27 +01:00
parent 235f17e7cf
commit 8a8034bd11
25 changed files with 263 additions and 210 deletions

View File

@@ -0,0 +1,106 @@
use core::time::Duration;
#[repr(u64)]
pub enum SysCall {
Exit = 60,
NanoSleep = 101,
WriteIntTemp = 998,
WriteTemp = 999,
Unimplemented = 1 << 31,
}
impl From<u64> for SysCall {
fn from(value: u64) -> Self {
match value {
60 => SysCall::Exit,
101 => SysCall::NanoSleep,
998 => SysCall::WriteIntTemp,
999 => SysCall::WriteTemp,
_ => SysCall::Unimplemented,
}
}
}
#[allow(clippy::too_many_arguments)]
unsafe fn _syscall(
syscall: SysCall,
mut a1: u64,
mut a2: u64,
mut a3: u64,
mut a4: u64,
mut a5: u64,
mut a6: u64,
mut a7: u64,
) -> (u64, u64, u64, u64, u64, u64, u64, u64) {
let mut a0 = syscall as u64;
unsafe {
core::arch::asm!(
"ecall",
inlateout("a0") a0,
inlateout("a1") a1,
inlateout("a2") a2,
inlateout("a3") a3,
inlateout("a4") a4,
inlateout("a5") a5,
inlateout("a6") a6,
inlateout("a7") a7,
clobber_abi("system")
);
}
(a0, a1, a2, a3, a4, a5, a6, a7)
}
macro_rules! syscall {
($syscall:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr, $a6:expr, $a7:expr) => {
_syscall($syscall, $a1, $a2, $a3, $a4, $a5, $a6, $a7)
};
($syscall:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr, $a6:expr) => {
syscall!($syscall, $a1, $a2, $a3, $a4, $a5, $a6, 0)
};
($syscall:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr) => {
syscall!($syscall, $a1, $a2, $a3, $a4, $a5, 0)
};
($syscall:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr) => {
syscall!($syscall, $a1, $a2, $a3, $a4, 0)
};
($syscall:expr, $a1:expr, $a2:expr, $a3:expr) => {
syscall!($syscall, $a1, $a2, $a3, 0)
};
($syscall:expr, $a1:expr, $a2:expr) => {
syscall!($syscall, $a1, $a2, 0)
};
($syscall:expr, $a1:expr) => {
syscall!($syscall, $a1, 0)
};
($syscall:expr) => {
syscall!($syscall, 0)
};
}
pub fn exit() {
unsafe {
syscall!(SysCall::Exit);
}
}
pub fn sleep(duration: Duration) {
unsafe {
let (duration_secs, duration_nanos) = (duration.as_secs(), duration.subsec_nanos() as u64);
syscall!(SysCall::NanoSleep, duration_secs, duration_nanos);
}
}
pub fn write_string_temp(content: &'static str) {
unsafe {
syscall!(
SysCall::WriteTemp,
content.as_ptr() as u64,
content.len() as u64
);
}
}
pub fn write_int_temp(content: u64) {
unsafe {
syscall!(SysCall::WriteIntTemp, content);
}
}