aarch32_cpu/register/
ifsr.rs

1//! Code for managing IFSR (*Instruction Fault Status Register*)
2
3use arbitrary_int::{prelude::*, u4, u5};
4
5use crate::register::{SysReg, SysRegRead, SysRegWrite};
6
7/// IFSR (*Instruction Fault Status Register*)
8#[bitbybit::bitfield(u32, defmt_bitfields(feature = "defmt"))]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10pub struct Ifsr {
11    /// External abort qualifier
12    #[bit(12, rw)]
13    ext: bool,
14    #[bits(4..=7, rw)]
15    domain: u4,
16    /// Status bitfield.
17    #[bits([0..=3, 10], rw)]
18    status_raw: u5,
19}
20
21/// Fault status register enumeration for IFSR, which is also part of the DFSR
22#[derive(Debug, Copy, Clone, PartialEq, Eq, num_enum::TryFromPrimitive)]
23#[cfg_attr(feature = "defmt", derive(defmt::Format))]
24#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
25#[repr(u8)]
26pub enum FsrStatus {
27    SyncExtAbortOnTranslationTableWalkFirstLevel = 0b01100,
28    SyncExtAbortOnTranslationTableWalkSecondLevel = 0b01110,
29    SyncParErrorOnTranslationTableWalkFirstLevel = 0b11100,
30    SyncParErrorOnTranslationTableWalkSecondLevel = 0b11110,
31    TranslationFaultFirstLevel = 0b00101,
32    TranslationFaultSecondLevel = 0b00111,
33    AccessFlagFaultFirstLevel = 0b00011,
34    AccessFlagFaultSecondLevel = 0b00110,
35    DomainFaultFirstLevel = 0b01001,
36    DomainFaultSecondLevel = 0b01011,
37    PermissionFaultFirstLevel = 0b01101,
38    PermissionFaultSecondLevel = 0b01111,
39    DebugEvent = 0b00010,
40    SyncExtAbort = 0b01000,
41    TlbConflictAbort = 0b10000,
42    Lockdown = 0b10100,
43    CoprocessorAbort = 0b11010,
44    SyncParErrorOnMemAccess = 0b11001,
45}
46
47impl Ifsr {
48    pub fn status(&self) -> Result<FsrStatus, u8> {
49        let status = self.status_raw().as_u8();
50        FsrStatus::try_from(status).map_err(|_| status)
51    }
52}
53
54impl SysReg for Ifsr {
55    const CP: u32 = 15;
56    const CRN: u32 = 5;
57    const OP1: u32 = 0;
58    const CRM: u32 = 0;
59    const OP2: u32 = 1;
60}
61
62impl crate::register::SysRegRead for Ifsr {}
63
64impl Ifsr {
65    #[inline]
66    /// Reads IFSR (*Instruction Fault Status Register*)
67    pub fn read() -> Ifsr {
68        unsafe { Self::new_with_raw_value(<Self as SysRegRead>::read_raw()) }
69    }
70}
71
72impl crate::register::SysRegWrite for Ifsr {}
73
74impl Ifsr {
75    #[inline]
76    /// Writes IFSR (*Instruction Fault Status Register*)
77    ///
78    /// # Safety
79    ///
80    /// Ensure that this value is appropriate for this register
81    pub unsafe fn write(value: Self) {
82        unsafe {
83            <Self as SysRegWrite>::write_raw(value.raw_value());
84        }
85    }
86}
87
88impl core::fmt::Debug for Ifsr {
89    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
90        write!(
91            f,
92            "IFSR {{ ext={} Domain={:#06b} Status={:#07b} }}",
93            self.ext(),
94            self.domain(),
95            self.status_raw()
96        )
97    }
98}