|
23 | 23 |
|
24 | 24 | #include "image.h" |
25 | 25 | #include "loader.h" |
| 26 | +#include "printf.h" |
26 | 27 | #include "wolfboot/wolfboot.h" |
27 | 28 |
|
28 | 29 | extern unsigned int _start_text; |
@@ -296,11 +297,97 @@ asm( |
296 | 297 |
|
297 | 298 | #endif /* CORTEX_R5 */ |
298 | 299 |
|
| 300 | +#ifdef DEBUG_HARDFAULT |
| 301 | +__attribute__((section(".boot"))) __attribute__((used)) |
| 302 | +void HardFault_HandlerC( uint32_t *hardfault_args ) |
| 303 | +{ |
| 304 | + /* Using volatile to prevent the compiler/linker optimizing them out */ |
| 305 | + volatile uint32_t stacked_r0; |
| 306 | + volatile uint32_t stacked_r1; |
| 307 | + volatile uint32_t stacked_r2; |
| 308 | + volatile uint32_t stacked_r3; |
| 309 | + volatile uint32_t stacked_r12; |
| 310 | + volatile uint32_t stacked_lr; |
| 311 | + volatile uint32_t stacked_pc; |
| 312 | + volatile uint32_t stacked_psr; |
| 313 | + volatile uint32_t _CFSR; |
| 314 | + volatile uint32_t _HFSR; |
| 315 | + volatile uint32_t _DFSR; |
| 316 | + volatile uint32_t _AFSR; |
| 317 | + volatile uint32_t _BFAR; |
| 318 | + volatile uint32_t _MMAR; |
| 319 | + |
| 320 | + stacked_r0 = ((uint32_t)hardfault_args[0]); |
| 321 | + stacked_r1 = ((uint32_t)hardfault_args[1]); |
| 322 | + stacked_r2 = ((uint32_t)hardfault_args[2]); |
| 323 | + stacked_r3 = ((uint32_t)hardfault_args[3]); |
| 324 | + stacked_r12 = ((uint32_t)hardfault_args[4]); |
| 325 | + stacked_lr = ((uint32_t)hardfault_args[5]); |
| 326 | + stacked_pc = ((uint32_t)hardfault_args[6]); |
| 327 | + stacked_psr = ((uint32_t)hardfault_args[7]); |
| 328 | + |
| 329 | + /* Configurable Fault Status Register */ |
| 330 | + /* Consists of MMSR, BFSR and UFSR */ |
| 331 | + _CFSR = (*((volatile uint32_t *)(0xE000ED28))); |
| 332 | + /* Hard Fault Status Register */ |
| 333 | + _HFSR = (*((volatile uint32_t *)(0xE000ED2C))); |
| 334 | + /* Debug Fault Status Register */ |
| 335 | + _DFSR = (*((volatile uint32_t *)(0xE000ED30))); |
| 336 | + /* Auxiliary Fault Status Register */ |
| 337 | + _AFSR = (*((volatile uint32_t *)(0xE000ED3C))); |
| 338 | + /* MemManage Fault Address Register */ |
| 339 | + _MMAR = (*((volatile uint32_t *)(0xE000ED34))); |
| 340 | + /* Bus Fault Address Register */ |
| 341 | + _BFAR = (*((volatile uint32_t *)(0xE000ED38))); |
| 342 | + |
| 343 | + wolfBoot_printf("\n\nHard fault handler (all numbers in hex):\n"); |
| 344 | + wolfBoot_printf("R0 = %lx\n", stacked_r0); |
| 345 | + wolfBoot_printf("R1 = %lx\n", stacked_r1); |
| 346 | + wolfBoot_printf("R2 = %lx\n", stacked_r2); |
| 347 | + wolfBoot_printf("R3 = %lx\n", stacked_r3); |
| 348 | + wolfBoot_printf("R12 = %lx\n", stacked_r12); |
| 349 | + wolfBoot_printf("LR [R14] = %lx subroutine call return address\n", |
| 350 | + stacked_lr); |
| 351 | + wolfBoot_printf("PC [R15] = %lx program counter\n", stacked_pc); |
| 352 | + wolfBoot_printf("PSR = %lx\n", stacked_psr); |
| 353 | + wolfBoot_printf("CFSR = %lx\n", _CFSR); |
| 354 | + wolfBoot_printf("HFSR = %lx\n", _HFSR); |
| 355 | + wolfBoot_printf("DFSR = %lx\n", _DFSR); |
| 356 | + wolfBoot_printf("AFSR = %lx\n", _AFSR); |
| 357 | + wolfBoot_printf("MMAR = %lx\n", _MMAR); |
| 358 | + wolfBoot_printf("BFAR = %lx\n", _BFAR); |
| 359 | + |
| 360 | + /* Break into the debugger */ |
| 361 | + __asm("BKPT #0\n"); |
| 362 | +} |
| 363 | + |
| 364 | +__attribute__((section(".boot"))) __attribute__((naked)) |
| 365 | +void isr_fault(void) |
| 366 | +{ |
| 367 | + __asm volatile |
| 368 | + ( |
| 369 | + " movs r0,#4 \n" /* load bit mask into R0 */ |
| 370 | + " mov r1, lr \n" /* load link register into R1 */ |
| 371 | + " tst r0, r1 \n" /* compare with bitmask */ |
| 372 | + " beq _MSP \n" /* if bitmask is set: stack pointer is in PSP. Otherwise in MSP */ |
| 373 | + " mrs r0, psp \n" /* otherwise: stack pointer is in PSP */ |
| 374 | + " b _GetPC \n" /* go to part which loads the PC */ |
| 375 | + "_MSP: \n" /* stack pointer is in MSP register */ |
| 376 | + " mrs r0, msp \n" /* load stack pointer into R0 */ |
| 377 | + "_GetPC: \n" /* find out where the hard fault happened */ |
| 378 | + " ldr r1,[r0,#20] \n" /* load program counter into R1. R1 contains address of the next instruction where the hard fault happened */ |
| 379 | + " ldr r2, =HardFault_HandlerC \n" |
| 380 | + " bx r2 \n" |
| 381 | + " bx lr \n" /* decode more information. R0 contains pointer to stack frame */ |
| 382 | + ); |
| 383 | +} |
| 384 | +#else |
299 | 385 | void isr_fault(void) |
300 | 386 | { |
301 | 387 | /* Panic. */ |
302 | 388 | wolfBoot_panic(); |
303 | 389 | } |
| 390 | +#endif /* DEBUG_HARDFAULT */ |
304 | 391 |
|
305 | 392 | void isr_empty(void) |
306 | 393 | { |
|
0 commit comments