|
|
@@ -103,7 +103,25 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
#define TASKTCB_XCOREID_OFFSET (0x38+configMAX_TASK_NAME_LEN+3)&~3
|
|
|
.extern pxCurrentTCB
|
|
|
|
|
|
-/* Enable stack backtrace across exception/interrupt - see below */
|
|
|
+/*
|
|
|
+--------------------------------------------------------------------------------
|
|
|
+ In order for backtracing to be able to trace from the pre-exception stack
|
|
|
+ across to the exception stack (including nested interrupts), we need to create
|
|
|
+ a pseudo base-save area to make it appear like the exception dispatcher was
|
|
|
+ triggered by a CALL4 from the pre-exception code. In reality, the exception
|
|
|
+ dispatcher uses the same window as pre-exception code, and only CALL0s are
|
|
|
+ used within the exception dispatcher.
|
|
|
+
|
|
|
+ To create the pseudo base-save area, we need to store a copy of the pre-exception's
|
|
|
+ base save area (a0 to a4) below the exception dispatcher's SP. EXCSAVE_x will
|
|
|
+ be used to store a copy of the SP that points to the interrupted code's exception
|
|
|
+ frame just in case the exception dispatcher's SP does not point to the exception
|
|
|
+ frame (which is the case when switching from task to interrupt stack).
|
|
|
+
|
|
|
+ Clearing the pseudo base-save area is uncessary as the interrupt dispatcher
|
|
|
+ will restore the current SP to that of the pre-exception SP.
|
|
|
+--------------------------------------------------------------------------------
|
|
|
+*/
|
|
|
#ifdef CONFIG_FREERTOS_INTERRUPT_BACKTRACE
|
|
|
#define XT_DEBUG_BACKTRACE 1
|
|
|
#endif
|
|
|
@@ -202,9 +220,22 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
/* This bit of code provides a nice debug backtrace in the debugger.
|
|
|
It does take a few more instructions, so undef XT_DEBUG_BACKTRACE
|
|
|
if you want to save the cycles.
|
|
|
+ At this point, the exception frame should have been allocated and filled,
|
|
|
+ and current sp points to the interrupt stack (for non-nested interrupt)
|
|
|
+ or below the allocated exception frame (for nested interrupts). Copy the
|
|
|
+ pre-exception's base save area below the current SP.
|
|
|
*/
|
|
|
#ifdef XT_DEBUG_BACKTRACE
|
|
|
#ifndef __XTENSA_CALL0_ABI__
|
|
|
+ rsr a0, EXCSAVE_1 + \level - 1 /* Get exception frame pointer stored in EXCSAVE_x */
|
|
|
+ l32i a3, a0, XT_STK_A0 /* Copy pre-exception a0 (return address) */
|
|
|
+ s32e a3, a1, -16
|
|
|
+ l32i a3, a0, XT_STK_A1 /* Copy pre-exception a1 (stack pointer) */
|
|
|
+ s32e a3, a1, -12
|
|
|
+ /* Backtracing only needs a0 and a1, no need to create full base save area.
|
|
|
+ Also need to change current frame's return address to point to pre-exception's
|
|
|
+ last run instruction.
|
|
|
+ */
|
|
|
rsr a0, EPC_1 + \level - 1 /* return address */
|
|
|
movi a4, 0xC0000000 /* constant with top 2 bits set (call size) */
|
|
|
or a0, a0, a4 /* set top 2 bits */
|
|
|
@@ -670,8 +701,16 @@ _xt_user_exc:
|
|
|
#endif
|
|
|
wsr a0, PS
|
|
|
|
|
|
+ /*
|
|
|
+ Create pseudo base save area. At this point, sp is still pointing to the
|
|
|
+ allocated and filled exception stack frame.
|
|
|
+ */
|
|
|
#ifdef XT_DEBUG_BACKTRACE
|
|
|
#ifndef __XTENSA_CALL0_ABI__
|
|
|
+ l32i a3, sp, XT_STK_A0 /* Copy pre-exception a0 (return address) */
|
|
|
+ s32e a3, sp, -16
|
|
|
+ l32i a3, sp, XT_STK_A1 /* Copy pre-exception a1 (stack pointer) */
|
|
|
+ s32e a3, sp, -12
|
|
|
rsr a0, EPC_1 /* return address for debug backtrace */
|
|
|
movi a5, 0xC0000000 /* constant with top 2 bits set (call size) */
|
|
|
rsync /* wait for WSR.PS to complete */
|
|
|
@@ -1086,6 +1125,16 @@ _xt_lowint1:
|
|
|
movi a0, _xt_user_exit /* save exit point for dispatch */
|
|
|
s32i a0, sp, XT_STK_EXIT
|
|
|
|
|
|
+ /* EXCSAVE_1 should now be free to use. Use it to keep a copy of the
|
|
|
+ current stack pointer that points to the exception frame (XT_STK_FRAME).*/
|
|
|
+ #ifdef XT_DEBUG_BACKTRACE
|
|
|
+ #ifndef __XTENSA_CALL0_ABI__
|
|
|
+ mov a0, sp
|
|
|
+ wsr a0, EXCSAVE_1
|
|
|
+ #endif
|
|
|
+ #endif
|
|
|
+
|
|
|
+
|
|
|
/* Save rest of interrupt context and enter RTOS. */
|
|
|
call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */
|
|
|
|
|
|
@@ -1166,6 +1215,15 @@ _xt_medint2:
|
|
|
movi a0, _xt_medint2_exit /* save exit point for dispatch */
|
|
|
s32i a0, sp, XT_STK_EXIT
|
|
|
|
|
|
+ /* EXCSAVE_2 should now be free to use. Use it to keep a copy of the
|
|
|
+ current stack pointer that points to the exception frame (XT_STK_FRAME).*/
|
|
|
+ #ifdef XT_DEBUG_BACKTRACE
|
|
|
+ #ifndef __XTENSA_CALL0_ABI__
|
|
|
+ mov a0, sp
|
|
|
+ wsr a0, EXCSAVE_2
|
|
|
+ #endif
|
|
|
+ #endif
|
|
|
+
|
|
|
/* Save rest of interrupt context and enter RTOS. */
|
|
|
call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */
|
|
|
|
|
|
@@ -1237,6 +1295,15 @@ _xt_medint3:
|
|
|
movi a0, _xt_medint3_exit /* save exit point for dispatch */
|
|
|
s32i a0, sp, XT_STK_EXIT
|
|
|
|
|
|
+ /* EXCSAVE_3 should now be free to use. Use it to keep a copy of the
|
|
|
+ current stack pointer that points to the exception frame (XT_STK_FRAME).*/
|
|
|
+ #ifdef XT_DEBUG_BACKTRACE
|
|
|
+ #ifndef __XTENSA_CALL0_ABI__
|
|
|
+ mov a0, sp
|
|
|
+ wsr a0, EXCSAVE_3
|
|
|
+ #endif
|
|
|
+ #endif
|
|
|
+
|
|
|
/* Save rest of interrupt context and enter RTOS. */
|
|
|
call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */
|
|
|
|
|
|
@@ -1307,6 +1374,15 @@ _xt_medint4:
|
|
|
movi a0, _xt_medint4_exit /* save exit point for dispatch */
|
|
|
s32i a0, sp, XT_STK_EXIT
|
|
|
|
|
|
+ /* EXCSAVE_4 should now be free to use. Use it to keep a copy of the
|
|
|
+ current stack pointer that points to the exception frame (XT_STK_FRAME).*/
|
|
|
+ #ifdef XT_DEBUG_BACKTRACE
|
|
|
+ #ifndef __XTENSA_CALL0_ABI__
|
|
|
+ mov a0, sp
|
|
|
+ wsr a0, EXCSAVE_4
|
|
|
+ #endif
|
|
|
+ #endif
|
|
|
+
|
|
|
/* Save rest of interrupt context and enter RTOS. */
|
|
|
call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */
|
|
|
|
|
|
@@ -1377,6 +1453,15 @@ _xt_medint5:
|
|
|
movi a0, _xt_medint5_exit /* save exit point for dispatch */
|
|
|
s32i a0, sp, XT_STK_EXIT
|
|
|
|
|
|
+ /* EXCSAVE_5 should now be free to use. Use it to keep a copy of the
|
|
|
+ current stack pointer that points to the exception frame (XT_STK_FRAME).*/
|
|
|
+ #ifdef XT_DEBUG_BACKTRACE
|
|
|
+ #ifndef __XTENSA_CALL0_ABI__
|
|
|
+ mov a0, sp
|
|
|
+ wsr a0, EXCSAVE_5
|
|
|
+ #endif
|
|
|
+ #endif
|
|
|
+
|
|
|
/* Save rest of interrupt context and enter RTOS. */
|
|
|
call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */
|
|
|
|
|
|
@@ -1447,6 +1532,15 @@ _xt_medint6:
|
|
|
movi a0, _xt_medint6_exit /* save exit point for dispatch */
|
|
|
s32i a0, sp, XT_STK_EXIT
|
|
|
|
|
|
+ /* EXCSAVE_6 should now be free to use. Use it to keep a copy of the
|
|
|
+ current stack pointer that points to the exception frame (XT_STK_FRAME).*/
|
|
|
+ #ifdef XT_DEBUG_BACKTRACE
|
|
|
+ #ifndef __XTENSA_CALL0_ABI__
|
|
|
+ mov a0, sp
|
|
|
+ wsr a0, EXCSAVE_6
|
|
|
+ #endif
|
|
|
+ #endif
|
|
|
+
|
|
|
/* Save rest of interrupt context and enter RTOS. */
|
|
|
call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */
|
|
|
|