summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlessandro Gatti <a.gatti@frob.it>2025-07-23 13:25:31 +0200
committerDamien George <damien@micropython.org>2025-08-26 12:27:21 +1000
commit64cac4690fad4df240056f5e15900d7ef5274a4c (patch)
tree25af4321ab254b405fc2ba337f982974964c150e
parent19be404ad899701b655b2da78e57b34d7fb686be (diff)
qemu/mcu/arm/errorhandler: Add ARMv7-M debug registers.
This commit extends the QEMU port's CPU error handler for the Arm target by printing out in detail the ARMv7-M debug registers if the firmware is compiled for such a target. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
-rw-r--r--ports/qemu/mcu/arm/errorhandler.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/ports/qemu/mcu/arm/errorhandler.c b/ports/qemu/mcu/arm/errorhandler.c
index a647c0e15..278bc8d4e 100644
--- a/ports/qemu/mcu/arm/errorhandler.c
+++ b/ports/qemu/mcu/arm/errorhandler.c
@@ -63,6 +63,8 @@ static const char *EXCEPTION_NAMES_TABLE[] = {
// R0-R15, PSR, Kind
uintptr_t registers_copy[18] = { 0 };
+#define BIT(v, b) (((v) & (1U << (b))) != 0)
+
__attribute__((naked)) MP_NORETURN void exception_handler(uintptr_t kind) {
// Save registers
__asm volatile (
@@ -127,13 +129,33 @@ __attribute__((naked)) MP_NORETURN void exception_handler(uintptr_t kind) {
}
break;
}
- printf(" exception caught:\n");
+ printf(" exception caught:\n\n");
+ printf("CPU registers:\n");
printf("R0: %08X R1: %08X R2: %08X R3: %08X\n", registers_copy[0], registers_copy[1], registers_copy[2], registers_copy[3]);
printf("R4: %08X R5: %08X R6: %08X R7: %08X\n", registers_copy[4], registers_copy[5], registers_copy[6], registers_copy[7]);
printf("R8: %08X R9: %08X R10: %08X R11: %08X\n", registers_copy[8], registers_copy[9], registers_copy[10], registers_copy[11]);
printf("R12: %08X R13: %08X R14: %08X R15: %08X\n", registers_copy[12], registers_copy[13], registers_copy[14], registers_copy[15]);
printf("xPSR: %08X\n", registers_copy[16]);
+ #if __ARM_ARCH == 7
+ uint32_t cfsr = *(volatile uint32_t *)0xE000ED28;
+ uint32_t hfsr = *(volatile uint32_t *)0xE000ED2C;
+ uint32_t dfsr = *(volatile uint32_t *)0xE000ED30;
+ uint32_t mmfar = *(volatile uint32_t *)0xE000ED34;
+ uint32_t bfar = *(volatile uint32_t *)0xE000ED38;
+
+ printf("\nDebug registers:\n");
+ printf("CFSR: %08lX HFSR: %08lX DFSR: %08lX MMFAR: %08lX BFAR: %08lX\n", cfsr, hfsr, dfsr, mmfar, bfar);
+ printf("CFSR.IACCVIOL: %d CFSR.DACCVIOL: %d CFSR.MUNSTKERR: %d CFSR.MSTKERR: %d\n", BIT(cfsr, 0), BIT(cfsr, 1), BIT(cfsr, 3), BIT(cfsr, 4));
+ printf("CFSR.MLSPERR: %d CFSR.MMARVALID: %d CFSR.IBUSERR: %d CFSR.PRECISERR: %d\n", BIT(cfsr, 5), BIT(cfsr, 7), BIT(cfsr, 8), BIT(cfsr, 9));
+ printf("CFSR.IMPRECISERR: %d CFSR.UNSTKERR: %d CFSR.STKERR: %d CFSR.LSPERR: %d\n", BIT(cfsr, 10), BIT(cfsr, 11), BIT(cfsr, 12), BIT(cfsr, 13));
+ printf("CFSR.BFARVALID: %d CFSR.UNDEFINSTR: %d CFSR.INVSTATE: %d CFSR.INVPC: %d\n", BIT(cfsr, 15), BIT(cfsr, 16), BIT(cfsr, 17), BIT(cfsr, 18));
+ printf("CFSR.NOCP: %d CFSR.UNALIGNED: %d CFSR.DIVBYZERO: %d\n", BIT(cfsr, 19), BIT(cfsr, 24), BIT(cfsr, 25));
+ printf("HFSR.VECTTBL: %d HFSR.FORCED: %d HFSR.DEBUGEVT: %d\n", BIT(hfsr, 1), BIT(hfsr, 30), BIT(hfsr, 31));
+ printf("DFSR.HALTED: %d DFSR.BKPT: %d DFSR.DWTTRAP: %d DFSR.VCATCH: %d\n", BIT(dfsr, 0), BIT(dfsr, 1), BIT(dfsr, 2), BIT(dfsr, 3));
+ printf("DFSR.EXTERNAL: %d\n", BIT(dfsr, 4));
+ #endif
+
for (;;) {}
}