From e2e9e7cbfcf9fe5a330f383e2952d758954699d8 Mon Sep 17 00:00:00 2001 From: magicse7en Date: Wed, 12 Aug 2020 22:36:06 +0800 Subject: [PATCH] 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 --- portable/ThirdParty/XCC/Xtensa/port.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/portable/ThirdParty/XCC/Xtensa/port.c b/portable/ThirdParty/XCC/Xtensa/port.c index 141263929..8fe15252c 100644 --- a/portable/ThirdParty/XCC/Xtensa/port.c +++ b/portable/ThirdParty/XCC/Xtensa/port.c @@ -221,8 +221,9 @@ BaseType_t xPortSysTickHandler( void ) uint32_t ulStackDepth ) { #if XCHAL_CP_NUM > 0 - xMPUSettings->coproc_area = ( StackType_t * ) ( ( ( ( uint32_t ) ( pxBottomOfStack + ulStackDepth - 1 ) ) - XT_CP_SIZE ) & ~0xf ); - + 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 * clear the stack area after we return. This is done in pxPortInitialiseStack().