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 {
23
        sys::exit(37);
24
    }
25
    if env.argsSize == 1 {
26
        sys::abort();
27
    }
28
    if env.argsSize == 3 {
29
        try! sys::domainDestroy(abi::Handle(0), 0);
30
    }
31
    if env.argsSize == 4 {
32
        let result = ecall(47, 0, 0, 0, 0);
33
        sys::exit(99);
34
    }
35
    if env.argsSize == 8 {
36
        let device = sys::queryDevice(*env.argsPointer);
37
        assert device.base == 0x10001000 and device.size >= 4;
38
        sys::exit(51);
39
    }
40
    assert false;
41
}