1-- platform/riscv's critical section, nested, on rv32: masking clears
2-- mstatus.MIE, a nested mask returns it already clear, and restoring in
3-- reverse order gives back exactly the state the program started with,
4-- whether reset left interrupts enabled or not. The module declares
5-- nothing on the other targets (D687), so the program imports it
6-- everywhere and calls it from the rv32 arm.
7import platform/riscv
8
9fixed if compiler.arch == rv32 then
10 nested_masks_restore: () -> (ok: bool) =
11 before: u32 = riscv.interrupt_mask()
12 outer: u32 = riscv.disable_interrupts()
13 inner: u32 = riscv.disable_interrupts()
14 masked: u32 = riscv.interrupt_mask()
15 riscv.compiler_barrier()
16 riscv.restore_interrupts(inner)
17 still: u32 = riscv.interrupt_mask()
18 riscv.restore_interrupts(outer)
19 after: u32 = riscv.interrupt_mask()
20 riscv.device_barrier()
21 riscv.completion_barrier()
22 ok = outer == before and inner == 0 and masked == 0 and still == 0
23 and after == before
24 end nested_masks_restore
25else
26 nested_masks_restore: () -> (ok: bool) =
27 ok = true
28 end nested_masks_restore
29end if
30
31public main: () -> (code: i32) =
32 code = 1
33 if nested_masks_restore() then
34 code = 42
35 end if
36end main