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