Better user programs with a special std. Sleep and exit are calling scheduler instead of wfi.
This commit is contained in:
12
crates/os-std-macros/Cargo.toml
Normal file
12
crates/os-std-macros/Cargo.toml
Normal file
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "os-std-macros"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1"
|
||||
quote = "1"
|
||||
syn = { version = "2", features = ["full"] }
|
||||
1
crates/os-std-macros/src/lib.rs
Normal file
1
crates/os-std-macros/src/lib.rs
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
8
crates/os-std/Cargo.toml
Normal file
8
crates/os-std/Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "os-std"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
os-std-macros = { path = "../os-std-macros" }
|
||||
shared = { path = "../shared" }
|
||||
21
crates/os-std/src/lib.rs
Normal file
21
crates/os-std/src/lib.rs
Normal file
@@ -0,0 +1,21 @@
|
||||
#![no_std]
|
||||
|
||||
mod prelude;
|
||||
|
||||
pub use shared::syscall;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! custom_std_setup {
|
||||
() => {
|
||||
#[panic_handler]
|
||||
fn panic(_panic_info: &core::panic::PanicInfo) -> ! {
|
||||
// TODO print
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn _start() {
|
||||
main()
|
||||
}
|
||||
};
|
||||
}
|
||||
1
crates/os-std/src/prelude.rs
Normal file
1
crates/os-std/src/prelude.rs
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
6
crates/shared/Cargo.toml
Normal file
6
crates/shared/Cargo.toml
Normal file
@@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "shared"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
3
crates/shared/src/lib.rs
Normal file
3
crates/shared/src/lib.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
#![no_std]
|
||||
|
||||
pub mod syscall;
|
||||
106
crates/shared/src/syscall.rs
Normal file
106
crates/shared/src/syscall.rs
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user