66edcf5d03
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.
143 lines
4.7 KiB
Python
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()
|