1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
//! Hazard3 Interrupt Controller (Xh3irq) Driver
//!
//! > Xh3irq controls up to 512 external interrupts, with up to 16 levels of
//! > pre-emption. It is architected as a layer on top of the standard mip.meip
//! > external interrupt line, and all standard RISC-V interrupt behaviour still
//! > applies.
//!
//! See [Section 3.8.6.1](https://rptl.io/rp2350-datasheet#extension-xh3irq-section) for more details
/// The Machine External Interrupt Enable Array
///
/// The array contains a read-write bit for each external interrupt request: a
/// `1` bit indicates that interrupt is currently enabled. At reset, all
/// external interrupts are disabled.
///
/// If enabled, an external interrupt can cause assertion of the standard RISC-V
/// machine external interrupt pending flag (`mip.meip`), and therefore cause
/// the processor to enter the external interrupt vector. See `meipa`.
///
/// There are up to 512 external interrupts. The upper half of this register
/// contains a 16-bit window into the full 512-bit vector. The window is indexed
/// by the 5 LSBs of the write data.
pub const RVCSR_MEIEA_OFFSET: u32 = 0xbe0;
/// Machine External Interrupt Pending Array
///
/// Contains a read-only bit for each external interrupt request. Similarly to
/// `meiea`, this register is a window into an array of up to 512 external
/// interrupt flags. The status appears in the upper 16 bits of the value read
/// from `meipa`, and the lower 5 bits of the value _written_ by the same CSR
/// instruction (or 0 if no write takes place) select a 16-bit window of the
/// full interrupt pending array.
///
/// A `1` bit indicates that interrupt is currently asserted. IRQs are assumed
/// to be level-sensitive, and the relevant `meipa` bit is cleared by servicing
/// the requestor so that it deasserts its interrupt request.
///
/// When any interrupt of sufficient priority is both set in `meipa` and enabled
/// in `meiea`, the standard RISC-V external interrupt pending bit `mip.meip` is
/// asserted. In other words, `meipa` is filtered by `meiea` to generate the
/// standard `mip.meip` flag.
pub const RVCSR_MEIPA_OFFSET: u32 = 0xbe1;
/// Machine External Interrupt Force Array
//
/// Contains a read-write bit for every interrupt request. Writing a 1 to a bit
/// in the interrupt force array causes the corresponding bit to become pending
/// in `meipa`. Software can use this feature to manually trigger a particular
/// interrupt.
///
/// There are no restrictions on using `meifa` inside of an interrupt. The more
/// useful case here is to schedule some lower- priority handler from within a
/// high-priority interrupt, so that it will execute before the core returns to
/// the foreground code. Implementers may wish to reserve some external IRQs
/// with their external inputs tied to 0 for this purpose.
///
/// Bits can be cleared by software, and are cleared automatically by hardware
/// upon a read of `meinext` which returns the corresponding IRQ number in
/// `meinext.irq` with `mienext.noirq` clear (no matter whether `meinext.update`
/// is written).
///
/// `meifa` implements the same array window indexing scheme as `meiea` and
/// `meipa`.
pub const RVCSR_MEIFA_OFFSET: u32 = 0xbe2;
/// Machine External Interrupt Priority Array
///
/// Each interrupt has an (up to) 4-bit priority value associated with it, and
/// each access to this register reads and/or writes a 16-bit window containing
/// four such priority values. When less than 16 priority levels are available,
/// the LSBs of the priority fields are hardwired to 0.
///
/// When an interrupt's priority is lower than the current preemption priority
/// `meicontext.preempt`, it is treated as not being pending for the purposes of
/// `mip.meip`. The pending bit in `meipa` will still assert, but the machine
/// external interrupt pending bit `mip.meip` will not, so the processor will
/// ignore this interrupt. See `meicontext`.
pub const RVCSR_MEIPRA_OFFSET: u32 = 0xbe3;
/// Machine External Get Next Interrupt
///
/// Contains the index of the highest-priority external interrupt which is both
/// asserted in `meipa` and enabled in `meiea`, left- shifted by 2 so that it
/// can be used to index an array of 32-bit function pointers. If there is no
/// such interrupt, the MSB is set.
///
/// When multiple interrupts of the same priority are both pending and enabled,
/// the lowest-numbered wins. Interrupts with priority less than
/// `meicontext.ppreempt` -- the _previous_ preemption priority -- are treated
/// as though they are not pending. This is to ensure that a preempting
/// interrupt frame does not service interrupts which may be in progress in the
/// frame that was preempted.
pub const RVCSR_MEINEXT_OFFSET: u32 = 0xbe4;
/// Check if a given interrupt is pending
/// Enable an interrupt
///
/// # Safety
///
/// This function is unsafe because it can break mask-based critical
/// sections. Do not call inside a critical section.
pub unsafe
/// Disable an interrupt
/// Check if an interrupt is enabled
/// Set an interrupt as pending, even if it isn't.
/// Check which interrupt should be handled next
///
/// Also updates the state so next time you call this you'll get a different
/// answer.
/// Convert an IRQ into a window selection value and separate a bitmask for that
/// window.
pub const
/// Convert an IRQ into a 32-bit value that selects a window and a bit within
/// that window.
pub const
// End of file