@@ -103,7 +103,25 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
103103#define TASKTCB_XCOREID_OFFSET ( 0x38 + configMAX_TASK_NAME_LEN + 3 )&~ 3
104104. extern pxCurrentTCB
105105
106- / * Enable stack backtrace across exception/interrupt - see below * /
106+ / *
107+ --------------------------------------------------------------------------------
108+ In order for backtracing to be able to trace from the pre - exception stack
109+ across to the exception stack (including nested interrupts) , we need to create
110+ a pseudo base - save area to make it appear like the exception dispatcher was
111+ triggered by a CALL4 from the pre - exception code. In reality , the exception
112+ dispatcher uses the same window as pre - exception code , and only CALL0s are
113+ used within the exception dispatcher.
114+
115+ To create the pseudo base - save area , we need to store a copy of the pre - exception's
116+ base save area (a0 to a4) below the exception dispatcher's SP . EXCSAVE_x will
117+ be used to store a copy of the SP th at points to the interrupted code's exception
118+ frame just in case the exception dispatcher's SP does not point to the exception
119+ frame (which is the case when switching from task to interrupt stack).
120+
121+ Clearing the pseudo base - save area is uncessary as the interrupt dispatcher
122+ will restore the current SP to th at of the pre - exception SP .
123+ --------------------------------------------------------------------------------
124+ * /
107125#ifdef CONFIG_FREERTOS_INTERRUPT_BACKTRACE
108126#define XT_DEBUG_BACKTRACE 1
109127#endif
@@ -202,9 +220,22 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
202220 / * This bit of code provides a nice debug backtrace in the debugger.
203221 It does take a few more instructions , so undef XT_DEBUG_BACKTRACE
204222 if you want to save the cycles.
223+ At this point , the exception frame should have been allocated and filled ,
224+ and current sp points to the interrupt stack (for non - nested interrupt)
225+ or below the allocated exception frame (for nested interrupts). Copy the
226+ pre - exception's base save area below the current SP .
205227 * /
206228 #ifdef XT_DEBUG_BACKTRACE
207229 #ifndef __XTENSA_CALL0_ABI__
230+ rsr a0 , EXCSAVE_1 + \level - 1 / * Get exception frame pointer stored in EXCSAVE_x * /
231+ l32i a3 , a0 , XT_STK_A0 / * Copy pre - exception a0 (return address) * /
232+ s32e a3 , a1 , - 16
233+ l32i a3 , a0 , XT_STK_A1 / * Copy pre - exception a1 (stack pointer) * /
234+ s32e a3 , a1 , - 12
235+ / * Backtracing only needs a0 and a1 , no need to create full base save area.
236+ Also need to change current frame 's return address to point to pre-exception' s
237+ last run instruction.
238+ * /
208239 rsr a0 , EPC_1 + \level - 1 / * return address * /
209240 movi a4 , 0xC0000000 / * constant with top 2 bits set ( call size) * /
210241 or a0 , a0 , a4 / * set top 2 bits * /
@@ -670,8 +701,16 @@ _xt_user_exc:
670701 #endif
671702 wsr a0 , PS
672703
704+ / *
705+ Create pseudo base save area. At this point , sp is still pointing to the
706+ allocated and filled exception stack frame.
707+ * /
673708 #ifdef XT_DEBUG_BACKTRACE
674709 #ifndef __XTENSA_CALL0_ABI__
710+ l32i a3 , sp , XT_STK_A0 / * Copy pre - exception a0 (return address) * /
711+ s32e a3 , sp , - 16
712+ l32i a3 , sp , XT_STK_A1 / * Copy pre - exception a1 (stack pointer) * /
713+ s32e a3 , sp , - 12
675714 rsr a0 , EPC_1 / * return address for debug backtrace * /
676715 movi a5 , 0xC0000000 / * constant with top 2 bits set ( call size) * /
677716 rsync / * wait for WSR.PS to complete * /
@@ -1086,6 +1125,16 @@ _xt_lowint1:
10861125 movi a0 , _xt_user_exit / * save exit point for dispatch * /
10871126 s32i a0 , sp , XT_STK_EXIT
10881127
1128+ / * EXCSAVE_1 should now be free to use. Use it to keep a copy of the
1129+ current stack pointer th at points to the exception frame (XT_STK_FRAME). * /
1130+ #ifdef XT_DEBUG_BACKTRACE
1131+ #ifndef __XTENSA_CALL0_ABI__
1132+ mov a0 , sp
1133+ wsr a0 , EXCSAVE_1
1134+ #endif
1135+ #endif
1136+
1137+
10891138 / * Save rest of interrupt context and enter RTOS. * /
10901139 call0 XT_RTOS_INT_ENTER / * common RTOS interrupt entry * /
10911140
@@ -1166,6 +1215,15 @@ _xt_medint2:
11661215 movi a0 , _xt_medint2_exit / * save exit point for dispatch * /
11671216 s32i a0 , sp , XT_STK_EXIT
11681217
1218+ / * EXCSAVE_2 should now be free to use. Use it to keep a copy of the
1219+ current stack pointer th at points to the exception frame (XT_STK_FRAME). * /
1220+ #ifdef XT_DEBUG_BACKTRACE
1221+ #ifndef __XTENSA_CALL0_ABI__
1222+ mov a0 , sp
1223+ wsr a0 , EXCSAVE_2
1224+ #endif
1225+ #endif
1226+
11691227 / * Save rest of interrupt context and enter RTOS. * /
11701228 call0 XT_RTOS_INT_ENTER / * common RTOS interrupt entry * /
11711229
@@ -1237,6 +1295,15 @@ _xt_medint3:
12371295 movi a0 , _xt_medint3_exit / * save exit point for dispatch * /
12381296 s32i a0 , sp , XT_STK_EXIT
12391297
1298+ / * EXCSAVE_3 should now be free to use. Use it to keep a copy of the
1299+ current stack pointer th at points to the exception frame (XT_STK_FRAME). * /
1300+ #ifdef XT_DEBUG_BACKTRACE
1301+ #ifndef __XTENSA_CALL0_ABI__
1302+ mov a0 , sp
1303+ wsr a0 , EXCSAVE_3
1304+ #endif
1305+ #endif
1306+
12401307 / * Save rest of interrupt context and enter RTOS. * /
12411308 call0 XT_RTOS_INT_ENTER / * common RTOS interrupt entry * /
12421309
@@ -1307,6 +1374,15 @@ _xt_medint4:
13071374 movi a0 , _xt_medint4_exit / * save exit point for dispatch * /
13081375 s32i a0 , sp , XT_STK_EXIT
13091376
1377+ / * EXCSAVE_4 should now be free to use. Use it to keep a copy of the
1378+ current stack pointer th at points to the exception frame (XT_STK_FRAME). * /
1379+ #ifdef XT_DEBUG_BACKTRACE
1380+ #ifndef __XTENSA_CALL0_ABI__
1381+ mov a0 , sp
1382+ wsr a0 , EXCSAVE_4
1383+ #endif
1384+ #endif
1385+
13101386 / * Save rest of interrupt context and enter RTOS. * /
13111387 call0 XT_RTOS_INT_ENTER / * common RTOS interrupt entry * /
13121388
@@ -1377,6 +1453,15 @@ _xt_medint5:
13771453 movi a0 , _xt_medint5_exit / * save exit point for dispatch * /
13781454 s32i a0 , sp , XT_STK_EXIT
13791455
1456+ / * EXCSAVE_5 should now be free to use. Use it to keep a copy of the
1457+ current stack pointer th at points to the exception frame (XT_STK_FRAME). * /
1458+ #ifdef XT_DEBUG_BACKTRACE
1459+ #ifndef __XTENSA_CALL0_ABI__
1460+ mov a0 , sp
1461+ wsr a0 , EXCSAVE_5
1462+ #endif
1463+ #endif
1464+
13801465 / * Save rest of interrupt context and enter RTOS. * /
13811466 call0 XT_RTOS_INT_ENTER / * common RTOS interrupt entry * /
13821467
@@ -1447,6 +1532,15 @@ _xt_medint6:
14471532 movi a0 , _xt_medint6_exit / * save exit point for dispatch * /
14481533 s32i a0 , sp , XT_STK_EXIT
14491534
1535+ / * EXCSAVE_6 should now be free to use. Use it to keep a copy of the
1536+ current stack pointer th at points to the exception frame (XT_STK_FRAME). * /
1537+ #ifdef XT_DEBUG_BACKTRACE
1538+ #ifndef __XTENSA_CALL0_ABI__
1539+ mov a0 , sp
1540+ wsr a0 , EXCSAVE_6
1541+ #endif
1542+ #endif
1543+
14501544 / * Save rest of interrupt context and enter RTOS. * /
14511545 call0 XT_RTOS_INT_ENTER / * common RTOS interrupt entry * /
14521546
0 commit comments