1use crate::register::{SysReg, SysRegRead, SysRegWrite};
4
5use arbitrary_int::{u2, u25, u3, u4, u6};
6
7#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"))]
9pub struct Hsr {
10 #[bits(26..=31, rw)]
15 ec: Option<ExceptionClass>,
16 #[bit(25, rw)]
20 il: InstructionLength,
21 #[bits(0..=24, rw)]
27 iss: u25,
28}
29
30impl Hsr {
31 pub fn get_iss(&self) -> Option<Iss> {
33 if let Ok(ec) = self.ec() {
34 Some(ec.decode_iss(self.iss()))
35 } else {
36 None
37 }
38 }
39}
40
41#[bitbybit::bitenum(u6, exhaustive = false)]
42#[cfg_attr(feature = "defmt", derive(defmt::Format))]
43#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
44#[derive(Debug, PartialEq, Eq)]
45pub enum ExceptionClass {
47 Unknown = 0b00_0000,
49 TrappedWfiWfe = 0b00_0001,
51 TrappedCp15McrMrc = 0b00_0011,
53 TrappedCp15McrrMrrc = 0b00_0100,
55 TrappedCp14McrMrc = 0b00_0101,
57 TrappedLdcStc = 0b00_0110,
59 TrappedFpu = 0b00_0111,
61 TrappedVmrs = 0b00_1000,
63 TrappedCp14McrrMrrc = 0b00_1100,
65 IllegalAArch32Eret = 0b00_1110,
67 Svc = 0b01_0001,
69 Hvc = 0b01_0010,
71 Smc = 0b01_0011,
73 PrefetchAbortFromLower = 0b10_0000,
75 PrefetchAbortFromCurrent = 0b10_0001,
77 PcAlignment = 0b10_0010,
79 DataAbortFromLower = 0b10_0100,
81 DataAbortFromCurrent = 0b10_0101,
83}
84
85#[derive(Debug, Clone)]
89pub enum Iss {
90 Unknown(IssUnknown),
92 TrappedWfiWfe(IssTrappedWfiWfe),
94 TrappedCp15McrMrc(IssTrappedMcrMrc),
96 TrappedCp15McrrMrrc(IssTrappedMcrrMrrc),
98 TrappedCp14McrMrc(IssTrappedMcrMrc),
100 TrappedLdcStc(IssTrappedLdcStc),
102 TrappedFpu(IssTrappedFpu),
104 TrappedVmrs(IssTrappedVmrs),
106 TrappedCp14McrrMrrc(IssTrappedMcrrMrrc),
108 IllegalAArch32Eret,
110 Svc(IssCall),
112 Hvc(IssCall),
114 Smc(IssSmc),
116 PrefetchAbortFromLower(IssPrefetchAbort),
118 PrefetchAbortFromCurrent(IssPrefetchAbort),
120 PcAlignment,
122 DataAbortFromLower(IssDataAbort),
124 DataAbortFromCurrent(IssDataAbort),
126}
127
128impl ExceptionClass {
129 pub fn decode_iss(&self, iss: u25) -> Iss {
131 match self {
132 ExceptionClass::Unknown => Iss::Unknown(IssUnknown(iss.value())),
133 ExceptionClass::TrappedWfiWfe => {
134 Iss::TrappedWfiWfe(IssTrappedWfiWfe::new_with_raw_value(iss))
135 }
136 ExceptionClass::TrappedCp15McrMrc => {
137 Iss::TrappedCp15McrMrc(IssTrappedMcrMrc::new_with_raw_value(iss))
138 }
139 ExceptionClass::TrappedCp15McrrMrrc => {
140 Iss::TrappedCp15McrrMrrc(IssTrappedMcrrMrrc::new_with_raw_value(iss))
141 }
142 ExceptionClass::TrappedCp14McrMrc => {
143 Iss::TrappedCp14McrMrc(IssTrappedMcrMrc::new_with_raw_value(iss))
144 }
145 ExceptionClass::TrappedLdcStc => {
146 Iss::TrappedLdcStc(IssTrappedLdcStc::new_with_raw_value(iss))
147 }
148 ExceptionClass::TrappedFpu => Iss::TrappedFpu(IssTrappedFpu::new_with_raw_value(iss)),
149 ExceptionClass::TrappedVmrs => Iss::TrappedVmrs(IssTrappedVmrs(iss.value())),
150 ExceptionClass::TrappedCp14McrrMrrc => {
151 Iss::TrappedCp14McrrMrrc(IssTrappedMcrrMrrc::new_with_raw_value(iss))
152 }
153 ExceptionClass::IllegalAArch32Eret => Iss::IllegalAArch32Eret,
154 ExceptionClass::Svc => Iss::Svc(IssCall::new_with_raw_value(iss)),
155 ExceptionClass::Hvc => Iss::Hvc(IssCall::new_with_raw_value(iss)),
156 ExceptionClass::Smc => Iss::Smc(IssSmc(iss.value())),
157 ExceptionClass::PrefetchAbortFromLower => {
158 Iss::PrefetchAbortFromLower(IssPrefetchAbort::new_with_raw_value(iss))
159 }
160 ExceptionClass::PrefetchAbortFromCurrent => {
161 Iss::PrefetchAbortFromCurrent(IssPrefetchAbort::new_with_raw_value(iss))
162 }
163 ExceptionClass::PcAlignment => Iss::PcAlignment,
164 ExceptionClass::DataAbortFromLower => {
165 Iss::DataAbortFromLower(IssDataAbort::new_with_raw_value(iss))
166 }
167 ExceptionClass::DataAbortFromCurrent => {
168 Iss::DataAbortFromCurrent(IssDataAbort::new_with_raw_value(iss))
169 }
170 }
171 }
172}
173
174#[derive(Debug, Copy, Clone, PartialEq, Eq)]
178pub struct IssUnknown(pub u32);
179
180#[bitbybit::bitfield(u25, debug, defmt_bitfields(feature = "defmt"))]
182pub struct IssTrappedWfiWfe {
183 #[bit(24, r)]
185 cv: bool,
186 #[bits(20..=23, r)]
188 cc: u4,
189 #[bit(0, r)]
191 ti: bool,
192}
193
194#[bitbybit::bitfield(u25, debug, defmt_bitfields(feature = "defmt"))]
196pub struct IssTrappedMcrMrc {
197 #[bit(24, r)]
199 cv: bool,
200 #[bits(20..=23, r)]
202 cc: u4,
203 #[bits(17..=19, r)]
205 opc2: u3,
206 #[bits(14..=16, r)]
208 opc1: u3,
209 #[bits(10..=13, r)]
211 crn: u4,
212 #[bits(5..=8, r)]
214 rt: u4,
215 #[bits(1..=4, r)]
217 crm: u4,
218 #[bit(0, r)]
220 is_read: bool,
221}
222
223#[bitbybit::bitfield(u25, debug, defmt_bitfields(feature = "defmt"))]
225pub struct IssTrappedMcrrMrrc {
226 #[bit(24, r)]
228 cv: bool,
229 #[bits(20..=23, r)]
231 cc: u4,
232 #[bits(16..=19, r)]
234 opc2: u4,
235 #[bits(10..=13, r)]
237 rt2: u4,
238 #[bits(5..=8, r)]
240 rt: u4,
241 #[bits(1..=4, r)]
243 crm: u4,
244 #[bit(0, r)]
246 is_read: bool,
247}
248
249#[bitbybit::bitfield(u25, debug, defmt_bitfields(feature = "defmt"))]
251pub struct IssTrappedLdcStc {
252 #[bit(24, r)]
254 cv: bool,
255 #[bits(20..=23, r)]
257 cc: u4,
258 #[bits(12..=19, r)]
260 imm8: u8,
261 #[bits(5..=8, r)]
263 rn: u4,
264 #[bit(4, r)]
266 offset: bool,
267 #[bits(1..=3, r)]
269 am: u3,
270 #[bit(0, r)]
272 is_read: bool,
273}
274
275#[bitbybit::bitfield(u25, debug, defmt_bitfields(feature = "defmt"))]
277pub struct IssTrappedFpu {
278 #[bit(24, r)]
280 cv: bool,
281 #[bits(20..=23, r)]
283 cc: u4,
284 #[bit(5, r)]
286 ta: bool,
287 #[bits(0..=3, r)]
289 coproc: u4,
290}
291
292#[derive(Debug, Copy, Clone, PartialEq, Eq)]
294pub struct IssTrappedVmrs(pub u32);
295
296#[bitbybit::bitfield(u25, debug, defmt_bitfields(feature = "defmt"))]
298pub struct IssCall {
299 #[bits(0..=15, r)]
301 imm16: u16,
302}
303
304#[derive(Debug, Copy, Clone, PartialEq, Eq)]
306pub struct IssSmc(pub u32);
307
308#[bitbybit::bitfield(u25, debug, defmt_bitfields(feature = "defmt"))]
310pub struct IssPrefetchAbort {
311 #[bit(10, r)]
313 fnv: bool,
314 #[bit(9, r)]
318 ea: bool,
319 #[bits(0..=5, r)]
321 ifsc: u6,
322}
323
324#[bitbybit::bitfield(u25, debug, defmt_bitfields(feature = "defmt"))]
326pub struct IssDataAbort {
327 #[bit(24, r)]
329 isv: bool,
330 #[bits(22..=23, r)]
332 sas: u2,
333 #[bit(21, r)]
335 sae: bool,
336 #[bits(16..=19, r)]
338 srt: u4,
339 #[bit(14, r)]
341 ar: bool,
342 #[bit(10, r)]
344 fnv: bool,
345 #[bit(9, r)]
349 ea: bool,
350 #[bit(8, r)]
352 cm: bool,
353 #[bit(6, r)]
355 wnr: bool,
356 #[bits(0..=5, r)]
358 dfsc: u6,
359}
360
361#[bitbybit::bitenum(u1, exhaustive = true)]
362#[cfg_attr(feature = "defmt", derive(defmt::Format))]
363#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
364#[derive(Debug, PartialEq, Eq)]
365pub enum InstructionLength {
367 SixteenBit = 0b0,
369 ThirtyTwoBit = 0b1,
371}
372
373impl SysReg for Hsr {
374 const CP: u32 = 15;
375 const CRN: u32 = 5;
376 const OP1: u32 = 4;
377 const CRM: u32 = 2;
378 const OP2: u32 = 0;
379}
380
381impl crate::register::SysRegRead for Hsr {}
382
383impl Hsr {
384 #[inline]
385 pub fn read() -> Hsr {
387 Self::new_with_raw_value(<Self as SysRegRead>::read_raw())
388 }
389}
390
391impl crate::register::SysRegWrite for Hsr {}
392
393impl Hsr {
394 #[inline]
395 pub unsafe fn write(value: Self) {
401 unsafe {
402 <Self as SysRegWrite>::write_raw(value.raw_value());
403 }
404 }
405}