test/termination/spin.rad 1.1 KiB raw
1
//! User termination and CPU-fault entry paths.
2
export mod abi;
3
export mod sys;
4
5
/// Issue a raw call to test the kernel error boundary.
6
@intrinsic fn ecall(operation: u32, a0: i64, a1: i64, a2: i64, a3: i64) -> i64;
7
8
/// Startup values used to select the termination operation.
9
record Env: Copy {
10
    /// Optional argument bytes supplied by the parent.
11
    argsPointer: *abi::Handle,
12
    /// Termination case selected by the parent.
13
    argsSize: u64,
14
    /// Installed event handle.
15
    eventsHandle: u64,
16
    /// Shared event-ring address.
17
    eventsPointer: u64,
18
}
19
20
/// Exercise an explicit exit, explicit abort, or a user breakpoint fault.
21
@default fn main(env: *Env) {
22
    if env.argsSize == 0 { sys::exit(37); }
23
    if env.argsSize == 1 { sys::abort(); }
24
    if env.argsSize == 3 { try! sys::domainDestroy(abi::Handle(0), 0); }
25
    if env.argsSize == 4 {
26
        let result = ecall(47, 0, 0, 0, 0);
27
        sys::exit(99);
28
    }
29
    if env.argsSize == 8 {
30
        let device = sys::queryDevice(*env.argsPointer);
31
        assert device.base == 0x10001000 and device.size >= 4;
32
        sys::exit(51);
33
    }
34
    assert false;
35
}