Landin library reference discuss source

platform/xtensa/xtensa.ldn

1-- Xtensa CPU operations for the windowed LX6/LX7 configurations.
2-- Saved PS values are explicit and must be restored in lexical reverse
3-- order. Masking does not stop DMA, exceptions, NMI or the debugger.
4fixed if compiler.arch == xtensa then
5    --- Mask ordinary interrupts and return the preceding PS.
6    public disable_interrupts: () -> (previous: u32) =
7        previous = assembler.block("rsil {state}, 15", out state: u32 at general)
8    end disable_interrupts
9
10    --- Restore the PS that disable_interrupts or mask_level_one returned.
11    public restore_interrupts: (previous: u32) -> none =
12        assembler.block("wsr {state}, ps\nrsync", in state: u32 at general = previous)
13    end restore_interrupts
14
15    --- Mask level-one interrupts, leaving higher-priority interrupts able
16    --- to run. Call only when raising the current level from zero or one.
17    public mask_level_one: () -> (previous: u32) =
18        previous = assembler.block("rsil {state}, 1", out state: u32 at general)
19    end mask_level_one
20
21    --- The current PS.INTLEVEL: zero permits every enabled interrupt.
22    public interrupt_mask: () -> (current: u32) =
23        current = assembler.block("rsr {state}, ps\nextui {state}, {state}, 0, 4",
24                                  out state: u32 at general)
25    end interrupt_mask
26
27    --- Replace INTENABLE with the selected CPU interrupt lines. The
28    --- device's interrupt matrix routes its sources to these lines.
29    public set_enabled_lines: (lines: u32) -> none =
30        assembler.block("wsr {bits}, intenable\nrsync", in bits: u32 at general = lines)
31    end set_enabled_lines
32
33    --- Read the CPU interrupt enables.
34    public enabled_lines: () -> (lines: u32) =
35        lines = assembler.block("rsr {bits}, intenable", out bits: u32 at general)
36    end enabled_lines
37
38    --- Read the CPU interrupt-pending bits, before interrupt masking.
39    public pending_lines: () -> (lines: u32) =
40        lines = assembler.block("rsr {bits}, interrupt", out bits: u32 at general)
41    end pending_lines
42
43    --- Read the cycle counter; arithmetic across wrapping uses +% and -%.
44    public cycles: () -> (ticks: u32) =
45        ticks = assembler.block("rsr {value}, ccount", out value: u32 at general)
46    end cycles
47
48    --- Complete earlier accesses and wait with ordinary interrupts enabled.
49    --- WAITI sets INTLEVEL to zero. Recheck the condition after waking;
50    --- a wakeup need not mean the awaited device completed.
51    public wait_for_interrupt: () -> none =
52        assembler.block("memw\nwaiti 0")
53    end wait_for_interrupt
54
55    --- Order memory and peripheral accesses. The peripheral's completion
56    --- status must still be checked separately.
57    public device_barrier: () -> none = compiler.device_barrier() end device_barrier
58
59    --- Complete preceding explicit memory accesses as MEMW specifies.
60    public completion_barrier: () -> none = compiler.completion_barrier() end completion_barrier
61
62    --- Prevent compiler memory knowledge from crossing this point.
63    public compiler_barrier: () -> none = compiler.compiler_barrier() end compiler_barrier
64end if