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.
|
* fault handler will executed instead of the SVC.
|
||||||
*
|
*
|
||||||
* @param esf exception frame
|
* @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. */
|
/* Stacked R0 holds the exception reason. */
|
||||||
unsigned int reason = esf->basic.r0;
|
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)
|
#if !defined(CONFIG_EXTRA_EXCEPTION_INFO)
|
||||||
z_arm_fatal_error(reason, esf);
|
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
|
#else
|
||||||
/* extra exception info is not collected for kernel oops
|
/* extra exception info is not collected for kernel oops
|
||||||
* path today so we make a copy of the ESF and zero out
|
* path today so we make a copy of the ESF and zero out
|
||||||
* that information
|
* 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 };
|
esf_copy.extra_info = (struct __extra_esf_info) { 0 };
|
||||||
|
#endif /* CONFIG_ARMV7_M_ARMV8_M_MAINLINE */
|
||||||
|
|
||||||
z_arm_fatal_error(reason, &esf_copy);
|
z_arm_fatal_error(reason, &esf_copy);
|
||||||
#endif /* CONFIG_EXTRA_EXCEPTION_INFO */
|
#endif /* CONFIG_EXTRA_EXCEPTION_INFO */
|
||||||
}
|
}
|
||||||
|
|
|
@ -556,8 +556,29 @@ _stack_frame_endif:
|
||||||
|
|
||||||
_oops:
|
_oops:
|
||||||
push {r0, lr}
|
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
|
bl z_do_kernel_oops
|
||||||
/* return from SVC exception is done here */
|
/* 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}
|
pop {r0, pc}
|
||||||
|
|
||||||
#if defined(CONFIG_USERSPACE)
|
#if defined(CONFIG_USERSPACE)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue