From ededdb2ed9d3c9749a8576faa8d0ca94825fbac6 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Sun, 18 Oct 2026 02:19:30 +0200 Subject: [PATCH] refactor(userspace): split syscall stubs into arch-agnostic API + arch/riscv backend --- crates/userspace/src/arch/mod.rs | 14 +++++ crates/userspace/src/arch/riscv.rs | 75 ++++++++++++++++++++++++++ crates/userspace/src/lib.rs | 1 + crates/userspace/src/syscall.rs | 85 ++++-------------------------- 4 files changed, 100 insertions(+), 75 deletions(-) create mode 100644 crates/userspace/src/arch/mod.rs create mode 100644 crates/userspace/src/arch/riscv.rs diff --git a/crates/userspace/src/arch/mod.rs b/crates/userspace/src/arch/mod.rs new file mode 100644 index 0000000..4f8d016 --- /dev/null +++ b/crates/userspace/src/arch/mod.rs @@ -0,0 +1,14 @@ +#[cfg(target_arch = "riscv64")] +mod riscv; +#[cfg(target_arch = "riscv64")] +pub use riscv::*; + +#[cfg(target_arch = "aarch64")] +mod arm; +#[cfg(target_arch = "aarch64")] +pub use arm::*; + +#[cfg(target_arch = "x86_64")] +mod x86; +#[cfg(target_arch = "x86_64")] +pub use x86::*; diff --git a/crates/userspace/src/arch/riscv.rs b/crates/userspace/src/arch/riscv.rs new file mode 100644 index 0000000..2622fcc --- /dev/null +++ b/crates/userspace/src/arch/riscv.rs @@ -0,0 +1,75 @@ +#[inline(always)] +pub fn syscall0(nr: usize) -> usize { + let ret: usize; + unsafe { + core::arch::asm!( + "ecall", + in("a7") nr, + lateout("a0") ret, + ); + } + ret +} + +#[inline(always)] +pub fn syscall1(nr: usize, a0: usize) -> usize { + let ret: usize; + unsafe { + core::arch::asm!( + "ecall", + in("a7") nr, + inlateout("a0") a0 => ret, + ); + } + ret +} + +#[inline(always)] +pub fn syscall2(nr: usize, a0: usize, a1: usize) -> usize { + let ret: usize; + unsafe { + core::arch::asm!( + "ecall", + in("a7") nr, + inlateout("a0") a0 => ret, + in("a1") a1, + ); + } + ret +} + +#[inline(always)] +pub fn syscall5(nr: usize, a0: usize, a1: usize, a2: usize, a3: usize, a4: usize) -> usize { + let ret: usize; + unsafe { + core::arch::asm!( + "ecall", + in("a7") nr, + inlateout("a0") a0 => ret, + in("a1") a1, + in("a2") a2, + in("a3") a3, + in("a4") a4, + ); + } + ret +} + +#[inline(always)] +pub fn syscall_receive(nr: usize, a0: usize) -> (usize, usize, usize, usize) { + let r0: usize; + let r1: usize; + let r2: usize; + let r3: usize; + unsafe { + core::arch::asm!( + "ecall", + in("a7") nr, + inlateout("a0") a0 => r0, + lateout("a1") r1, + lateout("a2") r2, + lateout("a3") r3, + ); + } + (r0, r1, r2, r3) +} diff --git a/crates/userspace/src/lib.rs b/crates/userspace/src/lib.rs index 7b3b5ed..90edb3e 100644 --- a/crates/userspace/src/lib.rs +++ b/crates/userspace/src/lib.rs @@ -1,3 +1,4 @@ #![no_std] +mod arch; pub mod syscall; diff --git a/crates/userspace/src/syscall.rs b/crates/userspace/src/syscall.rs index e135e96..056f0ed 100644 --- a/crates/userspace/src/syscall.rs +++ b/crates/userspace/src/syscall.rs @@ -1,105 +1,40 @@ +use crate::arch; use types::syscall_abi::*; -#[inline(always)] -fn ecall0(nr: usize) -> usize { - let ret: usize; - unsafe { - core::arch::asm!( - "ecall", - in("a7") nr, - lateout("a0") ret, - ); - } - ret -} - -#[inline(always)] -fn ecall1(nr: usize, a0: usize) -> usize { - let ret: usize; - unsafe { - core::arch::asm!( - "ecall", - in("a7") nr, - inlateout("a0") a0 => ret, - ); - } - ret -} - -#[inline(always)] -fn ecall2(nr: usize, a0: usize, a1: usize) -> usize { - let ret: usize; - unsafe { - core::arch::asm!( - "ecall", - in("a7") nr, - inlateout("a0") a0 => ret, - in("a1") a1, - ); - } - ret -} - pub fn exit() -> ! { - ecall0(SYS_EXIT); + arch::syscall0(SYS_EXIT); loop {} } pub fn exit_thread() -> ! { - ecall0(SYS_EXIT_THREAD); + arch::syscall0(SYS_EXIT_THREAD); loop {} } pub fn yield_now() { - ecall0(SYS_YIELD); + arch::syscall0(SYS_YIELD); } pub fn get_time() -> usize { - ecall0(SYS_GET_TIME) + arch::syscall0(SYS_GET_TIME) } pub fn get_process_id() -> usize { - ecall0(SYS_GET_PROCESS_ID) + arch::syscall0(SYS_GET_PROCESS_ID) } pub fn spawn_thread(entry: usize, stack: usize) -> usize { - ecall2(SYS_SPAWN_THREAD, entry, stack) + arch::syscall2(SYS_SPAWN_THREAD, entry, stack) } pub fn request_pages(count: usize) -> usize { - ecall1(SYS_REQUEST_PAGES, count) + arch::syscall1(SYS_REQUEST_PAGES, count) } pub fn send(endpoint: usize, w0: usize, w1: usize, w2: usize, w3: usize) -> usize { - let ret: usize; - unsafe { - core::arch::asm!( - "ecall", - in("a7") SYS_SEND, - inlateout("a0") endpoint => ret, - in("a1") w0, - in("a2") w1, - in("a3") w2, - in("a4") w3, - ); - } - ret + arch::syscall5(SYS_SEND, endpoint, w0, w1, w2, w3) } pub fn receive(endpoint: usize) -> (usize, usize, usize, usize) { - let r0: usize; - let r1: usize; - let r2: usize; - let r3: usize; - unsafe { - core::arch::asm!( - "ecall", - in("a7") SYS_RECEIVE, - inlateout("a0") endpoint => r0, - lateout("a1") r1, - lateout("a2") r2, - lateout("a3") r3, - ); - } - (r0, r1, r2, r3) + arch::syscall_receive(SYS_RECEIVE, endpoint) }