coredump: arm: Capture callee registers during k_panic() / k_oops
Ensure callee registers included in coredump. Push callee registers onto stack and pass as param to z_do_kernel_oops for CONFIG_ARMV7_M_ARMV8_M_MAINLINE when CONFIG_EXTRA_EXCEPTION_INFO enabled. Signed-off-by: Mark Holden <mholden@fb.com>
This commit is contained in:
parent
b6377cce6a
commit
df6b8c3cc4
2 changed files with 40 additions and 4 deletions
|
@ -77,9 +77,13 @@ void z_arm_fatal_error(unsigned int reason, const z_arch_esf_t *esf)
|
|||
* fault handler will executed instead of the SVC.
|
||||
*
|
||||
* @param esf exception frame
|
||||
* @param callee_regs Callee-saved registers (R4-R11)
|
||||
*/
|
||||
void z_do_kernel_oops(const z_arch_esf_t *esf)
|
||||
void z_do_kernel_oops(const z_arch_esf_t *esf, _callee_saved_t *callee_regs)
|
||||
{
|
||||
#if !(defined(CONFIG_EXTRA_EXCEPTION_INFO) && defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE))
|
||||
ARG_UNUSED(callee_regs);
|
||||
#endif
|
||||
/* Stacked R0 holds the exception reason. */
|
||||
unsigned int reason = esf->basic.r0;
|
||||
|
||||
|
@ -102,15 +106,26 @@ void z_do_kernel_oops(const z_arch_esf_t *esf)
|
|||
|
||||
#if !defined(CONFIG_EXTRA_EXCEPTION_INFO)
|
||||
z_arm_fatal_error(reason, esf);
|
||||
#else
|
||||
z_arch_esf_t esf_copy;
|
||||
|
||||
memcpy(&esf_copy, esf, offsetof(z_arch_esf_t, extra_info));
|
||||
#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
|
||||
/* extra exception info is collected in callee_reg param
|
||||
* on CONFIG_ARMV7_M_ARMV8_M_MAINLINE
|
||||
*/
|
||||
|
||||
esf_copy.extra_info = (struct __extra_esf_info) {
|
||||
.callee = callee_regs,
|
||||
};
|
||||
#else
|
||||
/* extra exception info is not collected for kernel oops
|
||||
* path today so we make a copy of the ESF and zero out
|
||||
* that information
|
||||
*/
|
||||
z_arch_esf_t esf_copy;
|
||||
|
||||
memcpy(&esf_copy, esf, offsetof(z_arch_esf_t, extra_info));
|
||||
esf_copy.extra_info = (struct __extra_esf_info) { 0 };
|
||||
#endif /* CONFIG_ARMV7_M_ARMV8_M_MAINLINE */
|
||||
|
||||
z_arm_fatal_error(reason, &esf_copy);
|
||||
#endif /* CONFIG_EXTRA_EXCEPTION_INFO */
|
||||
}
|
||||
|
|
|
@ -556,8 +556,29 @@ _stack_frame_endif:
|
|||
|
||||
_oops:
|
||||
push {r0, lr}
|
||||
#if defined(CONFIG_EXTRA_EXCEPTION_INFO)
|
||||
#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
|
||||
/* Build _callee_saved_t. To match the struct
|
||||
* definition we push the psp & then r11-r4
|
||||
*/
|
||||
mrs r1, PSP
|
||||
push {r1, r2}
|
||||
push {r4-r11}
|
||||
mov r1, sp /* pointer to _callee_saved_t */
|
||||
#endif /* CONFIG_ARMV7_M_ARMV8_M_MAINLINE */
|
||||
#endif /* CONFIG_EXTRA_EXCEPTION_INFO */
|
||||
bl z_do_kernel_oops
|
||||
/* return from SVC exception is done here */
|
||||
#if defined(CONFIG_EXTRA_EXCEPTION_INFO)
|
||||
#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
|
||||
/* We do not need to restore any register state here
|
||||
* because we did not use any callee-saved registers
|
||||
* in this routine. Therefore, we can just reset
|
||||
* the MSP to its value prior to entering the function
|
||||
*/
|
||||
add sp, #40
|
||||
#endif /* CONFIG_ARMV7_M_ARMV8_M_MAINLINE */
|
||||
#endif /* CONFIG_EXTRA_EXCEPTION_INFO */
|
||||
pop {r0, pc}
|
||||
|
||||
#if defined(CONFIG_USERSPACE)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue