feat(kernel): seL4-style IPC, notifications, status ABI

- badges + Mint, Call/Reply/ReplyRecv w/ gen-checked reply slot
- cap transfer (1/msg, copy, needs Delegate, rechecked at delivery)
- notifications: signal/wait/poll/bind, irq -> notification routing
- WaitAny/WaitForInterrupt removed; a0=status, ErrorCode
- libkos: single ecall primitive, compat wrappers + typed new api
- fix: trap return clobbered user t0 on every trap
- fix: wait queues FIFO, delegate keeps badge, fault cap checked
- docs/ipc.md spec, ipc tests, ipc fuzz, kani ntfn + waitqueue
This commit is contained in:
2026-10-26 20:27:38 +01:00
parent d43421e33e
commit 76f10ff1f1
46 changed files with 3339 additions and 1296 deletions

View File

@@ -1,27 +1,4 @@
pub fn syscall0(_nr: usize) -> usize {
0
}
pub fn syscall1(_nr: usize, _a0: usize) -> usize {
0
}
pub fn syscall2(_nr: usize, _a0: usize, _a1: usize) -> usize {
0
}
pub fn syscall3(_nr: usize, _a0: usize, _a1: usize, _a2: usize) -> usize {
0
}
pub fn syscall4(_nr: usize, _a0: usize, _a1: usize, _a2: usize, _a3: usize) -> usize {
0
}
pub fn syscall5(_nr: usize, _a0: usize, _a1: usize, _a2: usize, _a3: usize, _a4: usize) -> usize {
0
}
pub fn syscall_receive(_nr: usize, _a0: usize) -> (usize, usize, usize, usize) {
(0, 0, 0, 0)
/// Host builds have no kernel; every call reports success with zeroes.
pub fn syscall(_nr: usize, _args: [usize; 6]) -> [usize; 8] {
[0; 8]
}

View File

@@ -1,106 +1,20 @@
/// One `ecall`: syscall number in `a7`, arguments in `a0..a5`. Returns the
/// eight result registers `a0..a7` (docs/ipc.md, register ABI).
#[inline(always)]
pub fn syscall0(nr: usize) -> usize {
let ret: usize;
pub fn syscall(nr: usize, args: [usize; 6]) -> [usize; 8] {
let mut r = [0usize; 8];
unsafe {
core::arch::asm!(
"ecall",
in("a7") nr,
lateout("a0") ret,
inlateout("a0") args[0] => r[0],
inlateout("a1") args[1] => r[1],
inlateout("a2") args[2] => r[2],
inlateout("a3") args[3] => r[3],
inlateout("a4") args[4] => r[4],
inlateout("a5") args[5] => r[5],
lateout("a6") r[6],
inlateout("a7") nr => r[7],
);
}
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 syscall3(nr: usize, a0: usize, a1: usize, a2: usize) -> usize {
let ret: usize;
unsafe {
core::arch::asm!(
"ecall",
in("a7") nr,
inlateout("a0") a0 => ret,
in("a1") a1,
in("a2") a2,
);
}
ret
}
#[inline(always)]
pub fn syscall4(nr: usize, a0: usize, a1: usize, a2: usize, a3: 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,
);
}
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)
r
}