107 lines
3.7 KiB
Python
107 lines
3.7 KiB
Python
|
"""Source this file into gdb `source ../../tools/cortex-m-fault-gdb.py` then run
|
||
|
`cortex-m-fault` to print basic info about the fault registers."""
|
||
|
|
||
|
SCS = 0xE000E000
|
||
|
SCB = SCS + 0x0D00
|
||
|
CPUID = SCB + 0x000 # (R/ ) CPUID Base Register */
|
||
|
ICSR = SCB + 0x004 # (R/W) Interrupt Control and State Register */
|
||
|
VTOR = SCB + 0x008 # (R/W) Vector Table Offset Register */
|
||
|
AIRCR = SCB + 0x00C # (R/W) Application Interrupt and Reset Control Register */
|
||
|
SCR = SCB + 0x010 # (R/W) System Control Register */
|
||
|
CCR = SCB + 0x014 # (R/W) Configuration Control Register */
|
||
|
SHCSR = SCB + 0x024 # (R/W) System Handler Control and State Register */
|
||
|
CFSR = SCB + 0x028 # (R/W) Configurable Fault Status Register */
|
||
|
HFSR = SCB + 0x02C # (R/W) HardFault Status Register */
|
||
|
DFSR = SCB + 0x030 # (R/W) Debug Fault Status Register */
|
||
|
MMFAR = SCB + 0x034 # (R/W) MemManage Fault Address Register */
|
||
|
BFAR = SCB + 0x038 # (R/W) BusFault Address Register */
|
||
|
AFSR = SCB + 0x03C # (R/W) Auxiliary Fault Status Register */
|
||
|
|
||
|
PARTS = {0xC27: "Cortex M7"}
|
||
|
|
||
|
EXCEPTIONS = {
|
||
|
0: "Thread mode",
|
||
|
2: "Non Maskable Interrupt",
|
||
|
3: "Hard Fault",
|
||
|
4: "MemManage Fault",
|
||
|
5: "Bus Fault",
|
||
|
6: "Usage Fault",
|
||
|
11: "SVCAll",
|
||
|
14: "PendSV",
|
||
|
15: "SysTick",
|
||
|
}
|
||
|
|
||
|
|
||
|
class CortexMFault(gdb.Command):
|
||
|
def __init__(self):
|
||
|
super(CortexMFault, self).__init__("cortex-m-fault", gdb.COMMAND_USER)
|
||
|
|
||
|
def _read(self, address):
|
||
|
i = gdb.selected_inferior()
|
||
|
return i.read_memory(address, 4).cast("I")[0]
|
||
|
|
||
|
def invoke(self, arg, from_tty):
|
||
|
cpuid = self._read(CPUID)
|
||
|
implementer = cpuid >> 24
|
||
|
if implementer != 0x41:
|
||
|
raise RuntimeError()
|
||
|
variant = (cpuid >> 20) & 0xF
|
||
|
constant = (cpuid >> 16) & 0xF
|
||
|
if constant != 0xF:
|
||
|
raise RuntimeError()
|
||
|
revision = cpuid & 0xF
|
||
|
part_no = (cpuid >> 4) & 0xFFF
|
||
|
print(PARTS[part_no])
|
||
|
icsr = self._read(ICSR)
|
||
|
if (icsr & (1 << 11)) != 0:
|
||
|
print("No preempted exceptions")
|
||
|
else:
|
||
|
print("Another exception was preempted")
|
||
|
vectactive = icsr & 0x1FF
|
||
|
if vectactive != 0:
|
||
|
if vectactive in EXCEPTIONS:
|
||
|
print(EXCEPTIONS[vectactive])
|
||
|
else:
|
||
|
print(vectactive - 16)
|
||
|
|
||
|
vtor = self._read(VTOR)
|
||
|
# print(hex(self._read(SHCSR)))
|
||
|
cfsr = self._read(CFSR)
|
||
|
ufsr = cfsr >> 16
|
||
|
bfsr = (cfsr >> 8) & 0xFF
|
||
|
mmfsr = cfsr & 0xFF
|
||
|
print("ufsr", hex(ufsr), "bfsr", hex(bfsr), "mmfsr", hex(mmfsr))
|
||
|
if (bfsr & (1 << 7)) != 0:
|
||
|
print("Bad address", hex(self._read(BFAR)))
|
||
|
if (bfsr & (1 << 3)) != 0:
|
||
|
print("Unstacking from exception error")
|
||
|
if (bfsr & (1 << 2)) != 0:
|
||
|
print("Imprecise data bus error")
|
||
|
if (bfsr & (1 << 1)) != 0:
|
||
|
print("Precise data bus error")
|
||
|
if (bfsr & (1 << 0)) != 0:
|
||
|
print("Instruction bus error")
|
||
|
|
||
|
if (mmfsr & (1 << 7)) != 0:
|
||
|
print("Bad address", hex(self._read(MMFAR)))
|
||
|
if (mmfsr & (1 << 3)) != 0:
|
||
|
print("Unstacking from exception error")
|
||
|
if (mmfsr & (1 << 1)) != 0:
|
||
|
print("Data access violation")
|
||
|
if (mmfsr & (1 << 0)) != 0:
|
||
|
print("Instruction access violation")
|
||
|
|
||
|
if (ufsr & (1 << 8)) != 0:
|
||
|
print("Unaligned access")
|
||
|
if (ufsr & (1 << 0)) != 0:
|
||
|
print("Undefined instruction")
|
||
|
hfsr = self._read(HFSR)
|
||
|
if (hfsr & (1 << 30)) != 0:
|
||
|
print("Forced hard fault")
|
||
|
if (hfsr & (1 << 1)) != 0:
|
||
|
print("Bus fault when reading vector table")
|
||
|
print("VTOR", hex(vtor))
|
||
|
|
||
|
|
||
|
CortexMFault()
|