a9dc31a881
This adds a script to generate the peripherals files (except clock). It adds support for the 1015, 1020, 1040, and 1050 EVKs. Some work was started on 1176 but it isn't working. So, the board def is in a separate branch. Fixes #3521. Fixes #2477.
150 lines
5.0 KiB
Python
150 lines
5.0 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", 0xC60: "Cortex M0+"}
|
|
|
|
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 _armv6m_fault(self):
|
|
vtor = self._read(VTOR)
|
|
print("vtor", hex(vtor))
|
|
|
|
icsr = self._read(ICSR)
|
|
if (icsr & (1 << 23)) != 0:
|
|
print("No preempted exceptions")
|
|
else:
|
|
print("Another exception was preempted")
|
|
vectactive = icsr & 0x1FF
|
|
print(hex(icsr), vectactive)
|
|
if vectactive != 0:
|
|
if vectactive in EXCEPTIONS:
|
|
vectactive = EXCEPTIONS[vectactive]
|
|
else:
|
|
vectactive -= 16
|
|
|
|
print("Active interrupt:", vectactive)
|
|
|
|
vectpending = (icsr >> 12) & 0x1FF
|
|
if vectpending != 0:
|
|
if vectpending in EXCEPTIONS:
|
|
vectpending = EXCEPTIONS[vectpending]
|
|
else:
|
|
vectpending -= 16
|
|
|
|
print("Pending interrupt:", vectpending)
|
|
|
|
def _armv7m_fault(self):
|
|
icsr = self._read(ICSR)
|
|
if (icsr & (1 << 11)) != 0:
|
|
print("No preempted exceptions")
|
|
else:
|
|
print("Another exception was preempted")
|
|
print("icsr", hex(icsr))
|
|
vectactive = icsr & 0x1FF
|
|
if vectactive != 0:
|
|
if vectactive in EXCEPTIONS:
|
|
print(EXCEPTIONS[vectactive])
|
|
else:
|
|
print(vectactive - 16)
|
|
vectpending = (icsr >> 12) & 0x1FF
|
|
if vectpending != 0:
|
|
if vectpending in EXCEPTIONS:
|
|
print(EXCEPTIONS[vectpending])
|
|
else:
|
|
print(vectpending - 16)
|
|
|
|
vtor = self._read(VTOR)
|
|
print("vtor", hex(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))
|
|
|
|
def invoke(self, arg, from_tty):
|
|
cpuid = self._read(CPUID)
|
|
implementer = cpuid >> 24
|
|
if implementer != 0x41:
|
|
raise RuntimeError()
|
|
variant = (cpuid >> 20) & 0xF
|
|
architecture = (cpuid >> 16) & 0xF
|
|
revision = cpuid & 0xF
|
|
part_no = (cpuid >> 4) & 0xFFF
|
|
print(PARTS[part_no])
|
|
|
|
if architecture == 0xF:
|
|
self._armv7m_fault()
|
|
elif architecture == 0xC:
|
|
self._armv6m_fault()
|
|
else:
|
|
raise RuntimeError(f"Unknown architecture {architecture:x}")
|
|
|
|
|
|
CortexMFault()
|