aarch32_cpu/register/
dfsr.rs

1//! Code for managing DFSR (*Data Fault Status Register*)
2
3use arbitrary_int::{prelude::*, u4, u5};
4
5use crate::register::{SysReg, SysRegRead, SysRegWrite};
6
7use super::ifsr::FsrStatus;
8
9#[derive(Debug, Copy, Clone, PartialEq, Eq)]
10#[cfg_attr(feature = "defmt", derive(defmt::Format))]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12#[repr(u8)]
13pub enum DfsrStatus {
14    AlignmentFault = 0b00001,
15    FaultOnInstructionCacheMaintenance = 0b00100,
16    AsyncExternalAbort = 0b10110,
17    AsyncParityErrorOnMemAccess = 0b11000,
18    CommonFsr(FsrStatus),
19}
20
21impl TryFrom<u8> for DfsrStatus {
22    type Error = u8;
23    fn try_from(value: u8) -> Result<Self, Self::Error> {
24        match value {
25            0b00001 => Ok(DfsrStatus::AlignmentFault),
26            0b00100 => Ok(DfsrStatus::FaultOnInstructionCacheMaintenance),
27            0b10110 => Ok(DfsrStatus::AsyncExternalAbort),
28            0b11000 => Ok(DfsrStatus::AsyncParityErrorOnMemAccess),
29            _ => FsrStatus::try_from(value)
30                .map(DfsrStatus::CommonFsr)
31                .map_err(|_| value),
32        }
33    }
34}
35
36/// DFSR (*Data Fault Status Register*)
37#[bitbybit::bitfield(u32, defmt_bitfields(feature = "defmt"))]
38pub struct Dfsr {
39    /// External abort qualifier
40    #[bit(12, rw)]
41    ext: bool,
42    /// Write Not Read bit.
43    #[bit(11, rw)]
44    wnr: bool,
45    #[bits(4..=7, rw)]
46    domain: u4,
47    /// Status bitfield.
48    #[bits([0..=3, 10], rw)]
49    status_raw: u5,
50}
51
52impl SysReg for Dfsr {
53    const CP: u32 = 15;
54    const CRN: u32 = 5;
55    const OP1: u32 = 0;
56    const CRM: u32 = 0;
57    const OP2: u32 = 0;
58}
59
60impl crate::register::SysRegRead for Dfsr {}
61
62impl Dfsr {
63    pub fn status(&self) -> Result<DfsrStatus, u8> {
64        let status = self.status_raw().as_u8();
65        DfsrStatus::try_from(status).map_err(|_| status)
66    }
67
68    #[inline]
69    /// Reads DFSR (*Data Fault Status Register*)
70    pub fn read() -> Dfsr {
71        unsafe { Self::new_with_raw_value(<Self as SysRegRead>::read_raw()) }
72    }
73}
74
75impl crate::register::SysRegWrite for Dfsr {}
76
77impl Dfsr {
78    #[inline]
79    /// Writes DFSR (*Data Fault Status Register*)
80    ///
81    /// # Safety
82    ///
83    /// Ensure that this value is appropriate for this register
84    pub unsafe fn write(value: Self) {
85        unsafe {
86            <Self as SysRegWrite>::write_raw(value.raw_value());
87        }
88    }
89}
90
91impl core::fmt::Debug for Dfsr {
92    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
93        write!(
94            f,
95            "DFSR {{ ext={} wnr={} Domain={:#06b} Status={:#07b} }}",
96            self.ext(),
97            self.wnr(),
98            self.domain(),
99            self.status_raw()
100        )
101    }
102}