refactor(userspace): split syscall stubs into arch-agnostic API + arch/riscv backend

This commit is contained in:
2026-10-18 02:19:30 +02:00
parent 570fe22bee
commit ededdb2ed9
4 changed files with 100 additions and 75 deletions

View File

@@ -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::*;

View File

@@ -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)
}

View File

@@ -1,3 +1,4 @@
#![no_std]
mod arch;
pub mod syscall;

View File

@@ -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)
}