circuitpython/tools/cortex-m-fault-gdb.py
Scott Shawcroft 66edcf5d03
Add PicoDVI support
PicoDVI in CP support 640x480 and 800x480 on Feather DVI, Pico and
Pico W. 1 and 2 bit grayscale are full resolution. 8 and 16 bit
color are half resolution.

Memory layout is modified to give the top most 4k of ram to the
second core. Its MPU is used to prevent flash access after startup.

The port saved word is moved to a watchdog scratch register so that
it doesn't get overwritten by other things in RAM.

Right align status bar and scroll area. This normally gives a few
pixels of padding on the left hand side and improves the odds it is
readable in a case. Fixes #7562

Fixes c stack checking. The length was correct but the top was being
set to the current stack pointer instead of the correct top.
Fixes #7643

This makes Bitmap subscr raise IndexError instead of ValueError
when the index arguments are wrong.
2023-04-19 15:14:02 -07:00

143 lines
4.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", 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")
vectactive = icsr & 0x1FF
if vectactive != 0:
if vectactive in EXCEPTIONS:
print(EXCEPTIONS[vectactive])
else:
print(vectactive - 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()