/* * crash_handler_asm.S * * Created: 10/8/2023 10:06:07 PM * Author: david */ #include "crash_handler_asm.h" .text .syntax unified .arch armv7-m /* Called when something pends our special handler assigned to an unused IRQ that is specifically for handling crashes. extern "C" void HardFault_Handler(void); */ .global HardFault_Handler .type HardFault_Handler, %function .thumb_func HardFault_Handler: // disable IRQs so we don't get any randos messing with our stacks cpsid i cpsid f /* Push the following onto the stack msp psp exceptionPSR r4 r5 r6 r7 r8 r9 r10 r11 exceptionLR */ mrs r3, xpsr mrs r2, psp mrs r1, msp // change stack to our own stack which probably hasn't been touched yet ldr sp, =(crashdump_stack + 4 * CRASHDUMP_STACK_SIZE) push.w {r1-r11,lr} // Call our entry function with this stack as an argument. mov r0, sp bl crashdump_start // If for some reason we make it back here, we can restore old values and return to the calling thread. pop.w {r1-r11,lr} mov sp, r1 bx lr // Let assembler know that we have hit the end of the HardFault_Handler function. .pool .size HardFault_Handler, .-HardFault_Handler // Copy ALL of the floating point registers to the array given in R0 // Use this if FPU wasn't used before entering interrupt // Otherwise, you can just copy the higher 16 registers and grab // the lower ones off the stack. .global Copy_All_FPU_Regs .type Copy_All_FPU_Regs, %function .thumb_func Copy_All_FPU_Regs: // Copy the FPSCR before issuing any more FPU instructions // This will preserve its state vmrs r1, fpscr // Assume we have an array address given in R0 // Copy each single-precision register to the // pointer in r0, and increment the pointer each // time vstmia.32 r0!, {S0-S31} // Now we can plop the saved FPSCR in the // address pointed to by R0 (after it has been // auto-incremented to the end of the array) str r1, [r0] // back to whoever called us bx lr .pool .size Copy_All_FPU_Regs, .-Copy_All_FPU_Regs // Copy just the upper 16 registers // Use this when the lower 16 and FPSCR have already been // automatically stacked upon interrupt entry .global Copy_Upper_FPU_Regs .type Copy_Upper_FPU_Regs, %function .thumb_func Copy_Upper_FPU_Regs: // Assume we have an array address given in R0 // Copy upper 16 single-precision register to the // pointer in r0, and increment the pointer each // time vstmia.32 r0!, {S16-S31} // back to whoever called us bx lr .pool .size Copy_Upper_FPU_Regs, .-Copy_Upper_FPU_Regs