Hello,
I want to use the abort-handler to store some data from the environment where the abort happened. once a colleague already answered me:
https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1265729/mcu-plus-sdk-am243x-change-in-abort-handling-in-sdk-08-06/4801821?tisearch=e2e-sitesearch&keymatch=%2525252525252520user%252525252525253A453845#4801821
So today I tried implementing this.
So I have two questions:
1. the repairing of the stackframe
Looking at HwiP_armv7r_handlers_nortos_asm.S this is what happens before the new HwiP_data_abort_handler_c -abort-handler is called:
/* Push used registers. */ PUSH {r0-r4, r12} /* SPSR has the snapshot of CPSR before data abort. Compare thumb state bit in SPSR */ MRS r0, SPSR AND r1, r0, #0x20 CMP R1, #0 /* branches to label ARM_STATE if the thumb state bit is not set */ BEQ ARM_STATE SUB lr, lr, #2 ARM_STATE: SUB lr, lr, #4 END: /* Push the return address and SPSR. */ PUSH {lr} MRS lr, SPSR PUSH {lr} /* Call the interrupt handler. */ LDR r1, HwiP_data_abort_handler_const BLX r1
We an see some registers are pushed onto the stack, the LR is corrected and later on the HwiP_data_abort_handler_c is called.
So Abishek already wrote a solution to pop the correct LR to at least get the stackframe working again:
/* Restore used registers, LR and SPSR before returning. */
POP {LR}
MSR SPSR_cxsf, LR
POP {LR}
POP {r0-r4, r12}
unfortunately this is not working out of the box. I would've thought that calling the HwiP_data_abort_handler_c would push only two registers on the stack (for the ARM 8-byte-alignment) but unfortunately the correct registers are 16 Bytes away from the original LR.
For a better understanding let's look what happens in case of an abort:
we see in the LR the previous PC (+8) which caused the abort. That's good.
Then the corrected LR gets pushed onto the stack (see the memory view right hand):
as soon as the new HwiP_data_abort_handler_c is entered the LR is messed up:
also the stackframe is:
and check the SP. As soon as I step above the entry point of the function it progresses 16 bytes instead of my suggested 8 Bytes:
I now wanted to add the previous sugested solution but this does not work since of course the LR is not there to be popped. it's 16 Bytes away. That's because of the 00000d28: E24DD008 sub r13, r13, #8 instruction which I don't understand to be honest.
well it's not a problem to take that into account and to correct this value afterwards.
then it will look like this:
as you can see the LR is now correct. but unfortunately the stack-frame is not fixed again, it stays in the old view:
How can I force CCS to show the correct stack-frame again?
2. I want to store the occuring PC and SP
Well now we can at least get the PC/LR correctly. but what about the SP? In my example the SP before the abort would be:
as soon as the abort happens the SP is overwritten of course. But it is still available in the User-register:
How can I access the user register and retrieve the value from there? Unfortunately I am no arm-developer and I guess I can switch the mode to user mode and get it somehow but the documentation out there is not really helping and links to the arm-documentation are not reliable since it changes like every some years.
Best regards
Felix