Merge branch 'feature/add_panic_extra_stack' into 'master'

Add function to panic NMI/ISR/task stack data and keep its stack safe

See merge request sdk/ESP8266_RTOS_SDK!568
This commit is contained in:
Dong Heng
2018-10-19 15:39:10 +08:00
2 changed files with 65 additions and 36 deletions

View File

@ -98,11 +98,11 @@ static void panic_stack(StackType_t *start_stk, StackType_t *end_stk)
{ {
uint32_t *start = (uint32_t *)start_stk, *end = (uint32_t *)end_stk; uint32_t *start = (uint32_t *)start_stk, *end = (uint32_t *)end_stk;
size_t i, j; size_t i, j;
size_t size = end - start + 1; size_t size = end - start;
panic_str(" "); panic_str(" ");
for (i = 0; i < STACK_VOL_NUM; i++) { for (i = 0; i < STACK_VOL_NUM; i++) {
panic_data32(i * sizeof(StackType_t), 16); panic_data32(i * sizeof(void *), 16);
panic_str(" "); panic_str(" ");
} }
panic_str("\r\n\r\n"); panic_str("\r\n\r\n");
@ -133,6 +133,8 @@ static void panic_stack(StackType_t *start_stk, StackType_t *end_stk)
*/ */
static void panic_info(void *frame, int wdt) static void panic_info(void *frame, int wdt)
{ {
extern int _chip_nmi_cnt;
task_info_t *task; task_info_t *task;
int *regs = (int *)frame; int *regs = (int *)frame;
int x, y; int x, y;
@ -151,29 +153,43 @@ static void panic_info(void *frame, int wdt)
show_critical_info(); show_critical_info();
} }
if (xPortInIsrContext()) if (_chip_nmi_cnt) {
panic_str("Core 0 was running in ISR context:\r\n\r\n"); extern StackType_t _chip_nmi_stk, LoadStoreErrorHandlerStack;
if ((task = (task_info_t *)xTaskGetCurrentTaskHandle())) { _chip_nmi_cnt = 0;
StackType_t *pdata = task->pxStack; panic_str("Core 0 was running in NMI context:\r\n\r\n");
StackType_t *end = task->pxEndOfStack + 4;
// "Task stack [%s] stack from [%p] to [%p], total [%d] size\r\n\r\n" panic_stack(&_chip_nmi_stk, &LoadStoreErrorHandlerStack);
panic_str("Task stack [");
panic_str(task->pcTaskName);
panic_str("] stack from [");
panic_data32((uint32_t)pdata, 16);
panic_str("] to [");
panic_data32((uint32_t)end, 16);
panic_str("], total [");
panic_data32((uint32_t)(end - pdata + 4), 10);
panic_str("] size\r\n\r\n");
panic_stack(pdata, end);
panic_str("\r\n\r\n");
} else { } else {
panic_str("No task\r\n\r\n"); if (xPortInIsrContext()) {
extern StackType_t _chip_interrupt_stk, _chip_interrupt_tmp;
panic_str("Core 0 was running in ISR context:\r\n\r\n");
panic_stack(&_chip_interrupt_stk, &_chip_interrupt_tmp);
} else {
if ((task = (task_info_t *)xTaskGetCurrentTaskHandle())) {
StackType_t *pdata = task->pxStack;
StackType_t *end = task->pxEndOfStack + 4;
// "Task stack [%s] stack from [%p] to [%p], total [%d] size\r\n\r\n"
panic_str("Task stack [");
panic_str(task->pcTaskName);
panic_str("] stack from [");
panic_data32((uint32_t)pdata, 16);
panic_str("] to [");
panic_data32((uint32_t)end, 16);
panic_str("], total [");
panic_data32((uint32_t)(end - pdata), 10);
panic_str("] size\r\n\r\n");
panic_stack(pdata, end);
panic_str("\r\n\r\n");
} else {
panic_str("No task\r\n\r\n");
}
}
} }
for (x = 0; x < 20; x += 4) { for (x = 0; x < 20; x += 4) {

View File

@ -128,10 +128,12 @@ STRUCT_END(HighPriFrame)
// Allocate save area and stack: // Allocate save area and stack:
// (must use .bss, not .comm, because the subsequent .set does not work otherwise) // (must use .bss, not .comm, because the subsequent .set does not work otherwise)
.global _chip_nmi_stk
.section .bss, "aw" .section .bss, "aw"
.align 16 .align 16
LABEL(_Pri_,_Stack): .space PRI_N_STACK_SIZE + HESF_TOTALSIZE + PRI_N_STACK_SIZE2 + HESF_TOTALSIZE _chip_nmi_stk: .space PRI_N_STACK_SIZE + HESF_TOTALSIZE + PRI_N_STACK_SIZE2 + HESF_TOTALSIZE
.global LoadStoreErrorHandlerStack
.balign 16 .balign 16
LoadStoreErrorHandlerStack: LoadStoreErrorHandlerStack:
.word 0 # a0 .word 0 # a0
@ -155,8 +157,8 @@ LoadStoreErrorHandlerStack_reentry:
.data .data
.global LABEL(_Pri_,_HandlerAddress) .global LABEL(_Pri_,_HandlerAddress)
LABEL(_Pri_,_HandlerAddress): .space 4 LABEL(_Pri_,_HandlerAddress): .space 4
.global LABEL(_Pri_, _NMICount) .global _chip_nmi_cnt
LABEL(_Pri_,_NMICount): .space 4 _chip_nmi_cnt: .space 4
#endif #endif
.section .data, "aw" .section .data, "aw"
@ -189,7 +191,7 @@ LoadStoreErrorHandler:
rsr a0, excsave1 # restore a0 saved by UserExceptionVector rsr a0, excsave1 # restore a0 saved by UserExceptionVector
wsr a1, excsave1 # save a1 to excsave1, a1 can be used as varalbe wsr a1, excsave1 # save a1 to excsave1, a1 can be used as varalbe
movi a1, LABEL(_Pri_,_NMICount) movi a1, _chip_nmi_cnt
l32i a1, a1, 0 l32i a1, a1, 0
bnez a1, LoadStoreErrorHandler_reentry bnez a1, LoadStoreErrorHandler_reentry
@ -1080,14 +1082,14 @@ _xt_nmi:
ADD HIGH PRIORITY NON-MASKABLE INTERRUPT (NMI) HANDLER CODE HERE. ADD HIGH PRIORITY NON-MASKABLE INTERRUPT (NMI) HANDLER CODE HERE.
*/ */
movi a0, LABEL(_Pri_,_NMICount) movi a0, _chip_nmi_cnt
l32i a0, a0, 0 l32i a0, a0, 0
bnez a0, nmi_reentry bnez a0, nmi_reentry
movi a0, LABEL(_Pri_,_Stack) + PRI_N_STACK_SIZE // get ptr to save area movi a0, _chip_nmi_stk + PRI_N_STACK_SIZE // get ptr to save area
j nmi_common j nmi_common
nmi_reentry: nmi_reentry:
movi a0, LABEL(_Pri_,_Stack) + PRI_N_STACK_SIZE + HESF_TOTALSIZE + PRI_N_STACK_SIZE2// get ptr to save area movi a0, _chip_nmi_stk + PRI_N_STACK_SIZE + HESF_TOTALSIZE + PRI_N_STACK_SIZE2// get ptr to save area
nmi_common: nmi_common:
// interlock // interlock
@ -1186,7 +1188,7 @@ nmi_reentried:
#endif /* __XTENSA_WINDOWED_ABI__ */ #endif /* __XTENSA_WINDOWED_ABI__ */
//movi a1, LABEL(_Pri_,_Stack) + PRI_N_STACK_SIZE // get ptr to save area (is also initial stack ptr) //movi a1, _chip_nmi_stk + PRI_N_STACK_SIZE // get ptr to save area (is also initial stack ptr)
mov a1, a0 mov a1, a0
movi a0, 0 // mark start of call frames in stack movi a0, 0 // mark start of call frames in stack
@ -1247,7 +1249,7 @@ nmi_reentried:
#endif #endif
//save NMI Count //save NMI Count
movi a2, LABEL(_Pri_,_NMICount) movi a2, _chip_nmi_cnt
l32i a3, a2, 0 l32i a3, a2, 0
addi a3, a3, 1 addi a3, a3, 1
s32i a3, a2, 0 s32i a3, a2, 0
@ -1262,16 +1264,16 @@ nmi_reentried:
#endif #endif
//Restore NMI level //Restore NMI level
movi a2, LABEL(_Pri_,_NMICount) movi a2, _chip_nmi_cnt
l32i a3, a2, 0 l32i a3, a2, 0
addi a3, a3, -1 addi a3, a3, -1
s32i a3, a2, 0 s32i a3, a2, 0
beqi a3, 1, nmi_reentry2 beqi a3, 1, nmi_reentry2
movi a1, LABEL(_Pri_,_Stack) + PRI_N_STACK_SIZE // get ptr to save area movi a1, _chip_nmi_stk + PRI_N_STACK_SIZE // get ptr to save area
j nmi_common2 j nmi_common2
nmi_reentry2: nmi_reentry2:
movi a1, LABEL(_Pri_,_Stack) + PRI_N_STACK_SIZE + HESF_TOTALSIZE + PRI_N_STACK_SIZE2// get ptr to save area movi a1, _chip_nmi_stk + PRI_N_STACK_SIZE + HESF_TOTALSIZE + PRI_N_STACK_SIZE2// get ptr to save area
nmi_common2: nmi_common2:
@ -1331,7 +1333,7 @@ nmi_common2:
// Note: register window has rotated, ie. a0..a15 clobbered. // Note: register window has rotated, ie. a0..a15 clobbered.
// Reload initial stack pointer: // Reload initial stack pointer:
movi a1, LABEL(_Pri_,_Stack) + PRI_N_STACK_SIZE // - 16 movi a1, _chip_nmi_stk + PRI_N_STACK_SIZE // - 16
movi a6, XCHAL_NUM_AREGS - 8 // how many saved so far movi a6, XCHAL_NUM_AREGS - 8 // how many saved so far
addi a7, a1, -8*4 addi a7, a1, -8*4
@ -1438,9 +1440,20 @@ _xt_ext_panic:
movi a0, PS_INTLEVEL(5) | PS_UM movi a0, PS_INTLEVEL(5) | PS_UM
wsr a0, PS wsr a0, PS
/* Allocate exception frame and save minimal context. */
mov a0, sp mov a0, sp
movi sp, _chip_nmi_cnt
l32i sp, sp, 0
beqz sp, _panic_add_nmi_stk
/* Allocate exception frame and save minimal context. */
movi sp, _chip_interrupt_tmp movi sp, _chip_interrupt_tmp
j _panic_dump_reg
_panic_add_nmi_stk:
movi sp, LoadStoreErrorHandlerStack
_panic_dump_reg:
addi sp, sp, -XT_STK_FRMSZ addi sp, sp, -XT_STK_FRMSZ
s32i a0, sp, XT_STK_A1 s32i a0, sp, XT_STK_A1