Skip to content

Commit b9748e5

Browse files
magicse7enlundinc2
andauthored
Xtensa: fix stack overlap coproc_area issue (#118)
In function pxPortInitialiseStack of port.c: sp = ( StackType_t * ) ( ( ( UBaseType_t ) ( pxTopOfStack + 1 ) - XT_CP_SIZE - XT_STK_FRMSZ ) & ~0xf ); We assume XT_CP_SIZE is 0xE4, XT_STK_FRMSZ is 0xA0, pxTopOfStack is 0xA0000000, sp is 0x9FFFFE80. From port.c, we know the frame->a1 as below: frame->a1 = ( UBaseType_t ) sp + XT_STK_FRMSZ; /* physical top of stack frame */ So frame->a1 is 0x9FFFFF20. Therefore the interrupt stack frame range is 0x9FFFFE80 ~ 0x9FFFFF20. The coproc_area is: p = ( uint32_t * ) ( ( ( uint32_t ) pxTopOfStack - XT_CP_SIZE ) & ~0xf ); So its value is 0x9FFFFF10. Obviously, the interrupt stack frame overlaps the coproc_area. Co-authored-by: Carl Lundin <53273776+lundinc2@users.noreply.github.com>
1 parent f376c3b commit b9748e5

File tree

1 file changed

+53
-48
lines changed
  • portable/ThirdParty/XCC/Xtensa

1 file changed

+53
-48
lines changed

portable/ThirdParty/XCC/Xtensa/port.c

Lines changed: 53 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -90,55 +90,60 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
9090
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
9191
#endif
9292
{
93-
StackType_t *sp, *tp;
94-
XtExcFrame *frame;
95-
#if XCHAL_CP_NUM > 0
96-
uint32_t *p;
97-
#endif
98-
99-
/* Create interrupt stack frame aligned to 16 byte boundary */
100-
sp = (StackType_t *) (((UBaseType_t)(pxTopOfStack + 1) - XT_CP_SIZE - XT_STK_FRMSZ) & ~0xf);
101-
102-
/* Clear the entire frame (do not use memset() because we don't depend on C library) */
103-
for (tp = sp; tp <= pxTopOfStack; ++tp)
104-
*tp = 0;
105-
106-
frame = (XtExcFrame *) sp;
107-
108-
/* Explicitly initialize certain saved registers */
109-
frame->pc = (UBaseType_t) pxCode; /* task entrypoint */
110-
frame->a0 = 0; /* to terminate GDB backtrace */
111-
frame->a1 = (UBaseType_t) sp + XT_STK_FRMSZ; /* physical top of stack frame */
112-
frame->exit = (UBaseType_t) _xt_user_exit; /* user exception exit dispatcher */
113-
114-
/* Set initial PS to int level 0, EXCM disabled ('rfe' will enable), user mode. */
115-
/* Also set entry point argument parameter. */
116-
#ifdef __XTENSA_CALL0_ABI__
117-
frame->a2 = (UBaseType_t) pvParameters;
118-
frame->ps = PS_UM | PS_EXCM;
119-
#else
120-
/* + for windowed ABI also set WOE and CALLINC (pretend task was 'call4'd). */
121-
frame->a6 = (UBaseType_t) pvParameters;
122-
frame->ps = PS_UM | PS_EXCM | PS_WOE | PS_CALLINC(1);
123-
#endif
124-
125-
#ifdef XT_USE_SWPRI
126-
/* Set the initial virtual priority mask value to all 1's. */
127-
frame->vpri = 0xFFFFFFFF;
128-
#endif
129-
130-
#if XCHAL_CP_NUM > 0
131-
/* Init the coprocessor save area (see xtensa_context.h) */
132-
/* No access to TCB here, so derive indirectly. Stack growth is top to bottom.
93+
StackType_t * sp, * tp;
94+
XtExcFrame * frame;
95+
96+
#if XCHAL_CP_NUM > 0
97+
uint32_t * p;
98+
#endif
99+
100+
/* Create interrupt stack frame aligned to 16 byte boundary */
101+
sp = ( StackType_t * ) ( ( ( UBaseType_t ) pxTopOfStack - XT_CP_SIZE - XT_STK_FRMSZ ) & ~0xf );
102+
103+
/* Clear the entire frame (do not use memset() because we don't depend on C library) */
104+
for( tp = sp; tp <= pxTopOfStack; ++tp )
105+
{
106+
*tp = 0;
107+
}
108+
109+
frame = ( XtExcFrame * ) sp;
110+
111+
/* Explicitly initialize certain saved registers */
112+
frame->pc = ( UBaseType_t ) pxCode; /* task entrypoint */
113+
frame->a0 = 0; /* to terminate GDB backtrace */
114+
frame->a1 = ( UBaseType_t ) sp + XT_STK_FRMSZ; /* physical top of stack frame */
115+
frame->exit = ( UBaseType_t ) _xt_user_exit; /* user exception exit dispatcher */
116+
117+
/* Set initial PS to int level 0, EXCM disabled ('rfe' will enable), user mode. */
118+
/* Also set entry point argument parameter. */
119+
#ifdef __XTENSA_CALL0_ABI__
120+
frame->a2 = ( UBaseType_t ) pvParameters;
121+
frame->ps = PS_UM | PS_EXCM;
122+
#else
123+
/* + for windowed ABI also set WOE and CALLINC (pretend task was 'call4'd). */
124+
frame->a6 = ( UBaseType_t ) pvParameters;
125+
frame->ps = PS_UM | PS_EXCM | PS_WOE | PS_CALLINC( 1 );
126+
#endif
127+
128+
#ifdef XT_USE_SWPRI
129+
/* Set the initial virtual priority mask value to all 1's. */
130+
frame->vpri = 0xFFFFFFFF;
131+
#endif
132+
133+
#if XCHAL_CP_NUM > 0
134+
/* Init the coprocessor save area (see xtensa_context.h) */
135+
136+
/* No access to TCB here, so derive indirectly. Stack growth is top to bottom.
133137
* //p = (uint32_t *) xMPUSettings->coproc_area;
134-
*/
135-
p = (uint32_t *)(((uint32_t) pxTopOfStack - XT_CP_SIZE) & ~0xf);
136-
p[0] = 0;
137-
p[1] = 0;
138-
p[2] = (((uint32_t) p) + 12 + XCHAL_TOTAL_SA_ALIGN - 1) & -XCHAL_TOTAL_SA_ALIGN;
139-
#endif
140-
141-
return sp;
138+
*/
139+
p = ( uint32_t * ) ( ( ( uint32_t ) pxTopOfStack - XT_CP_SIZE ) & ~0xf );
140+
configASSERT( ( uint32_t ) p >= frame->a1 );
141+
p[ 0 ] = 0;
142+
p[ 1 ] = 0;
143+
p[ 2 ] = ( ( ( uint32_t ) p ) + 12 + XCHAL_TOTAL_SA_ALIGN - 1 ) & -XCHAL_TOTAL_SA_ALIGN;
144+
#endif
145+
146+
return sp;
142147
}
143148

144149
/*-----------------------------------------------------------*/

0 commit comments

Comments
 (0)