Xtensa: fix the coproc_area incorrect issue (#117)
* Xtensa: fix the coproc_area incorrect issue
foss-xtensa/amazon-freertos#2 mentioned a issue:
1.
In function pxPortInitialiseStack(StackType_t *pxTopOfStack....)
p = (uint32_t *)(((uint32_t) pxTopOfStack - XT_CP_SIZE) & ~0xf);
In function prvInitialiseNewTask (file: task.c)
pxTopOfStack = (pxStack + (ulStackDepth - 1)) & (~portBYTE_ALIGNMENT_MASK)
So the co-processor area is at
p = (uint32_t *)(((uint32_t)((pxStack + (ulStackDepth - 1)) & (~portBYTE_ALIGNMENT_MASK)) - XT_CP_SIZE) & ~0xf);
2.
In function vPortStoreTaskMPUSettings( .... , StackType_t pxBottomOfStack ...)
xMPUSettings->coproc_area = (StackType_t)((((uint32_t)(pxBottomOfStack + usStackDepth - 1)) - XT_CP_SIZE) & ~0xf);
pxBottomOfStack = pxStack
=> xMPUSettings->coproc_area = (StackType_t*)((((uint32_t)(pxStack+ ulStackDepth - 1)) - XT_CP_SIZE ) & ~0xf);
The p is coproc_area that should be equal to xMPUSettings->coproc_area.
For example, assume pxStack is 0xa0000000, ulStackDepth is 0x2000,
portBYTE_ALIGNMENT_MASK is 0x7f, XT_CP_SIZE is 0x100.
The p = (uint32_t)(((uint32_t)((pxStack + (ulStackDepth - 1)) & (~portBYTE_ALIGNMENT_MASK)) - XT_CP_SIZE) & ~0xf)
= 0xa0001e80
The xMPUSettings->coproc_area = (StackType_t)((((uint32_t)(pxStack+ usStackDepth - 1)) - XT_CP_SIZE ) & ~0xf)
= 0xa0001ef0
Obviously, the p is not equal to the xMPUSettings->coproc_area, which will cause context switching error.
Signed-off-by: magicse7en <magicse7en@outlook.com>
* Update port.c
Co-authored-by: Carl Lundin <53273776+lundinc2@users.noreply.github.com>
diff --git a/portable/ThirdParty/XCC/Xtensa/port.c b/portable/ThirdParty/XCC/Xtensa/port.c
index 8b34b49..a62a0de 100644
--- a/portable/ThirdParty/XCC/Xtensa/port.c
+++ b/portable/ThirdParty/XCC/Xtensa/port.c
@@ -212,16 +212,19 @@
* Used to set coprocessor area in stack. Current hack is to reuse MPU pointer for coprocessor area.
*/
#if portUSING_MPU_WRAPPERS
-void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth )
+void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
+ const struct xMEMORY_REGION * const xRegions,
+ StackType_t * pxBottomOfStack,
+ uint32_t ulStackDepth )
{
- #if XCHAL_CP_NUM > 0
- xMPUSettings->coproc_area = (StackType_t*)((((uint32_t)(pxBottomOfStack + ulStackDepth - 1)) - XT_CP_SIZE ) & ~0xf);
+ #if XCHAL_CP_NUM > 0
+ xMPUSettings->coproc_area = ( StackType_t * ) ( ( uint32_t ) ( pxBottomOfStack + ulStackDepth - 1 ));
+ xMPUSettings->coproc_area = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) xMPUSettings->coproc_area ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );
+ xMPUSettings->coproc_area = ( Stacktype_t * ) ( ( ( uint32_t ) xMPUSettings->coproc_area - XT_CP_SIZE ) & ~0xf );
-
- /* NOTE: we cannot initialize the coprocessor save area here because FreeRTOS is going to
+ /* NOTE: we cannot initialize the coprocessor save area here because FreeRTOS is going to
* clear the stack area after we return. This is done in pxPortInitialiseStack().
- */
- #endif
+ */
+ #endif
}
-#endif
-
+#endif /* if portUSING_MPU_WRAPPERS */