hal_arm/
debug.rs

1#[cfg(not(feature = "host"))]
2unsafe extern "C" {
3    static __syms_area_start: usize;
4}
5
6#[cfg(not(feature = "host"))]
7#[repr(C)]
8struct SymtabEntry {
9    name: usize,  // Offset into the string table
10    value: usize, // Address of the symbol
11    size: usize,  // Size of the symbol
12    info: u8,     // Type and binding information
13    other: u8,    // Other information
14    shndx: u16,   // Section index
15}
16
17#[cfg(not(feature = "host"))]
18pub fn find_nearest_symbol(addr: usize) -> Option<&'static str> {
19    use core::ffi::CStr;
20    use core::ffi::c_char;
21
22    let mut syms_start = &raw const __syms_area_start as usize;
23
24    // Iterate through the symbol table to find the nearest symbol to the given address.
25    let mut nearest_symbol: Option<&'static str> = None;
26    let mut nearest_distance = usize::MAX;
27
28    // The first 4 bytes in LE are the size of the symbol table.
29    let size = unsafe { *(syms_start as *const usize) };
30    syms_start += core::mem::size_of::<usize>(); // Move past the size field.
31
32    // If we have no symbols, return None.
33    if size == 0 {
34        return None;
35    }
36
37    let mut current = syms_start;
38    let strtab_start = syms_start + size;
39
40    while current < syms_start + size - 1 {
41        let entry = unsafe { &*(current as *const SymtabEntry) };
42
43        // Calculate the distance from the address to the symbol value.
44        let distance = addr.abs_diff(entry.value);
45
46        // Check if this is the nearest symbol found so far.
47        if distance < nearest_distance {
48            nearest_distance = distance;
49
50            let entry_name =
51                unsafe { CStr::from_ptr((strtab_start + entry.name) as *const c_char) };
52            nearest_symbol = entry_name.to_str().ok();
53        }
54
55        // Move to the next entry in the symbol table.
56        current += core::mem::size_of::<SymtabEntry>();
57    }
58
59    nearest_symbol
60}
61
62#[cfg(feature = "host")]
63pub fn find_nearest_symbol(_addr: usize) -> Option<&'static str> {
64    // In host mode, we do not have a symbol table.
65    None
66}
67
68#[cfg(all(not(feature = "host"), cm4))]
69pub fn print_mem_manage_fault_status(
70    f: &mut core::fmt::Formatter<'_>,
71) -> Result<(), core::fmt::Error> {
72    let cfsr = unsafe { core::ptr::read_volatile(0xE000ED28 as *const u32) };
73
74    writeln!(f, "CFSR: 0x{cfsr:08x}")?;
75    if cfsr & 0x1 != 0 {
76        writeln!(f, "  IACCVIOL: Instruction access violation")?;
77    }
78    if cfsr & 0x2 != 0 {
79        writeln!(f, "  DACCVIOL: Data access violation")?;
80    }
81    if cfsr & 0x8 != 0 {
82        writeln!(f, "  MUNSTKERR: MemManage fault on unstacking")?;
83    }
84    if cfsr & 0x10 != 0 {
85        writeln!(f, "  MSTKERR: MemManage fault on stacking")?;
86    }
87    if cfsr & 0x20 != 0 {
88        writeln!(
89            f,
90            "  MLSPERR: MemManage fault during floating-point lazy state preservation"
91        )?;
92    }
93    if cfsr & 0x80 != 0 {
94        writeln!(
95            f,
96            "  MMARVALID: MemManage Fault Address Register (MMAR) is valid"
97        )?;
98    }
99
100    Ok(())
101}
102
103#[cfg(all(not(feature = "host"), cm4))]
104pub fn print_bus_fault_status(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
105    let cfsr = unsafe { core::ptr::read_volatile(0xE000ED28 as *const u32) };
106
107    writeln!(
108        f,
109        "---------------------------------------------------------------"
110    )?;
111
112    writeln!(f, "CFSR: 0x{cfsr:08x}")?;
113    if cfsr & 0x100 != 0 {
114        writeln!(f, "  IBUSERR: Instruction bus error")?;
115    }
116    if cfsr & 0x200 != 0 {
117        writeln!(f, "  PRECISERR: Precise data bus error")?;
118    }
119    if cfsr & 0x400 != 0 {
120        writeln!(f, "  IMPRECISERR: Imprecise data bus error")?;
121    }
122    if cfsr & 0x800 != 0 {
123        writeln!(f, "  UNSTKERR: Bus fault on unstacking")?;
124    }
125    if cfsr & 0x1000 != 0 {
126        writeln!(f, "  STKERR: Bus fault on stacking")?;
127    }
128    if cfsr & 0x2000 != 0 {
129        writeln!(
130            f,
131            "  LSPERR: Bus fault during floating-point lazy state preservation"
132        )?;
133    }
134    if cfsr & 0x8000 != 0 {
135        writeln!(f, "  BFARVALID: Bus Fault Address Register (BFAR) is valid")?;
136    }
137
138    Ok(())
139}
140
141#[cfg(all(not(feature = "host"), cm4))]
142pub fn print_usage_fault_status(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
143    let cfsr = unsafe { core::ptr::read_volatile(0xE000ED28 as *const u32) };
144
145    writeln!(
146        f,
147        "---------------------------------------------------------------"
148    )?;
149
150    writeln!(f, "CFSR: 0x{cfsr:08x}")?;
151    if cfsr & 0x10000 != 0 {
152        writeln!(f, "  UNDEFINSTR: Undefined instruction")?;
153    }
154    if cfsr & 0x20000 != 0 {
155        writeln!(f, "  INVSTATE: Invalid state")?;
156    }
157    if cfsr & 0x40000 != 0 {
158        writeln!(f, "  INVPC: Invalid PC load usage fault")?;
159    }
160    if cfsr & 0x80000 != 0 {
161        writeln!(f, "  NOCP: No coprocessor")?;
162    }
163    if cfsr & 0x100000 != 0 {
164        writeln!(f, "  UNALIGNED: Unaligned access")?;
165    }
166    if cfsr & 0x200000 != 0 {
167        writeln!(f, "  DIVBYZERO: Divide by zero")?;
168    }
169
170    Ok(())
171}
172
173#[cfg(any(feature = "host", not(cm4)))]
174pub fn print_mem_manage_fault_status(
175    _f: &mut core::fmt::Formatter<'_>,
176) -> Result<(), core::fmt::Error> {
177    Ok(())
178}
179
180#[cfg(any(feature = "host", not(cm4)))]
181pub fn print_bus_fault_status(_f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
182    Ok(())
183}
184
185#[cfg(any(feature = "host", not(cm4)))]
186pub fn print_usage_fault_status(_f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
187    Ok(())
188}