FreeRTOS: Make the default stack alignment 16 for Xtensa

This commit is contained in:
Omar Chebib 2022-11-11 15:00:42 +08:00
parent bae4a5c30c
commit bcb8516744
6 changed files with 28 additions and 5 deletions

View File

@ -44,6 +44,8 @@
#include "esp_gdbstub.h" #include "esp_gdbstub.h"
#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME #endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
_Static_assert(portBYTE_ALIGNMENT == 16, "portBYTE_ALIGNMENT must be set to 16");
/* ---------------------------------------------------- Variables ------------------------------------------------------ /* ---------------------------------------------------- Variables ------------------------------------------------------
* *
* ------------------------------------------------------------------------------------------------------------------ */ * ------------------------------------------------------------------------------------------------------------------ */
@ -703,13 +705,17 @@ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxC
*/ */
UBaseType_t uxStackPointer = (UBaseType_t)pxTopOfStack; UBaseType_t uxStackPointer = (UBaseType_t)pxTopOfStack;
configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0);
// Initialize GCC TLS area // Initialize GCC TLS area
uint32_t threadptr_reg_init; uint32_t threadptr_reg_init;
uxStackPointer = uxInitialiseStackTLS(uxStackPointer, &threadptr_reg_init); uxStackPointer = uxInitialiseStackTLS(uxStackPointer, &threadptr_reg_init);
configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0);
// Initialize the starting interrupt stack frame // Initialize the starting interrupt stack frame
uxStackPointer = uxInitialiseStackFrame(uxStackPointer, pxCode, pvParameters, threadptr_reg_init); uxStackPointer = uxInitialiseStackFrame(uxStackPointer, pxCode, pvParameters, threadptr_reg_init);
configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0);
// Return the task's current stack pointer address which should point to the starting interrupt stack frame // Return the task's current stack pointer address which should point to the starting interrupt stack frame
return (StackType_t *)uxStackPointer; return (StackType_t *)uxStackPointer;
//TODO: IDF-2393 //TODO: IDF-2393

View File

@ -72,7 +72,7 @@ typedef uint32_t TickType_t;
#define portCRITICAL_NESTING_IN_TCB 1 #define portCRITICAL_NESTING_IN_TCB 1
#define portSTACK_GROWTH ( -1 ) #define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 4 #define portBYTE_ALIGNMENT 16 // Xtensa Windowed ABI requires the stack pointer to always be 16-byte aligned. See "isa_rm.pdf 8.1.1 Windowed Register Usage and Stack Layout"
#define portNOP() XT_NOP() //Todo: Check if XT_NOP exists #define portNOP() XT_NOP() //Todo: Check if XT_NOP exists
/* ---------------------------------------------- Forward Declarations ------------------------------------------------- /* ---------------------------------------------- Forward Declarations -------------------------------------------------

View File

@ -50,6 +50,8 @@
#include "hal/systimer_ll.h" #include "hal/systimer_ll.h"
#endif // CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER #endif // CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER
_Static_assert(portBYTE_ALIGNMENT == 16, "portBYTE_ALIGNMENT must be set to 16");
/* /*
OS state variables OS state variables
*/ */
@ -884,18 +886,23 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
*/ */
UBaseType_t uxStackPointer = (UBaseType_t)pxTopOfStack; UBaseType_t uxStackPointer = (UBaseType_t)pxTopOfStack;
configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0);
#if XCHAL_CP_NUM > 0 #if XCHAL_CP_NUM > 0
// Initialize the coprocessor save area // Initialize the coprocessor save area
uxStackPointer = uxInitialiseStackCPSA(uxStackPointer); uxStackPointer = uxInitialiseStackCPSA(uxStackPointer);
configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0);
#endif /* XCHAL_CP_NUM > 0 */ #endif /* XCHAL_CP_NUM > 0 */
// Initialize the GCC TLS area // Initialize the GCC TLS area
uint32_t threadptr_reg_init; uint32_t threadptr_reg_init;
uxStackPointer = uxInitialiseStackTLS(uxStackPointer, &threadptr_reg_init); uxStackPointer = uxInitialiseStackTLS(uxStackPointer, &threadptr_reg_init);
configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0);
// Initialize the starting interrupt stack frame // Initialize the starting interrupt stack frame
uxStackPointer = uxInitialiseStackFrame(uxStackPointer, pxCode, pvParameters, threadptr_reg_init); uxStackPointer = uxInitialiseStackFrame(uxStackPointer, pxCode, pvParameters, threadptr_reg_init);
configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0);
// Return the task's current stack pointer address which should point to the starting interrupt stack frame // Return the task's current stack pointer address which should point to the starting interrupt stack frame
return (StackType_t *)uxStackPointer; return (StackType_t *)uxStackPointer;
} }

View File

@ -57,7 +57,7 @@
#include "port_systick.h" #include "port_systick.h"
#include "esp_memory_utils.h" #include "esp_memory_utils.h"
_Static_assert(portBYTE_ALIGNMENT == 16, "portBYTE_ALIGNMENT must be set to 16");
/* ---------------------------------------------------- Variables ------------------------------------------------------ /* ---------------------------------------------------- Variables ------------------------------------------------------
* *
@ -284,13 +284,17 @@ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxC
*/ */
UBaseType_t uxStackPointer = (UBaseType_t)pxTopOfStack; UBaseType_t uxStackPointer = (UBaseType_t)pxTopOfStack;
configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0);
// Initialize GCC TLS area // Initialize GCC TLS area
uint32_t threadptr_reg_init; uint32_t threadptr_reg_init;
uxStackPointer = uxInitialiseStackTLS(uxStackPointer, &threadptr_reg_init); uxStackPointer = uxInitialiseStackTLS(uxStackPointer, &threadptr_reg_init);
configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0);
// Initialize the starting interrupt stack frame // Initialize the starting interrupt stack frame
uxStackPointer = uxInitialiseStackFrame(uxStackPointer, pxCode, pvParameters, threadptr_reg_init); uxStackPointer = uxInitialiseStackFrame(uxStackPointer, pxCode, pvParameters, threadptr_reg_init);
configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0);
// Return the task's current stack pointer address which should point to the starting interrupt stack frame // Return the task's current stack pointer address which should point to the starting interrupt stack frame
return (StackType_t *)uxStackPointer; return (StackType_t *)uxStackPointer;
//TODO: IDF-2393 //TODO: IDF-2393

View File

@ -139,7 +139,7 @@ typedef uint32_t TickType_t;
#define portCRITICAL_NESTING_IN_TCB 0 #define portCRITICAL_NESTING_IN_TCB 0
#define portSTACK_GROWTH ( -1 ) #define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 4 #define portBYTE_ALIGNMENT 16 // Xtensa Windowed ABI requires the stack pointer to always be 16-byte aligned. See "isa_rm.pdf 8.1.1 Windowed Register Usage and Stack Layout"
#define portTICK_TYPE_IS_ATOMIC 1 #define portTICK_TYPE_IS_ATOMIC 1
#define portNOP() XT_NOP() #define portNOP() XT_NOP()

View File

@ -78,6 +78,8 @@
#include "esp_cpu.h" #include "esp_cpu.h"
#include "esp_memory_utils.h" #include "esp_memory_utils.h"
_Static_assert(portBYTE_ALIGNMENT == 16, "portBYTE_ALIGNMENT must be set to 16");
_Static_assert(tskNO_AFFINITY == CONFIG_FREERTOS_NO_AFFINITY, "incorrect tskNO_AFFINITY value"); _Static_assert(tskNO_AFFINITY == CONFIG_FREERTOS_NO_AFFINITY, "incorrect tskNO_AFFINITY value");
@ -415,20 +417,24 @@ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxC
- All stack areas are aligned to 16 byte boundary - All stack areas are aligned to 16 byte boundary
- We use UBaseType_t for all of stack area initialization functions for more convenient pointer arithmetic - We use UBaseType_t for all of stack area initialization functions for more convenient pointer arithmetic
*/ */
UBaseType_t uxStackPointer = (UBaseType_t)pxTopOfStack; UBaseType_t uxStackPointer = (UBaseType_t)pxTopOfStack;
// Make sure the incoming stack pointer is aligned on 16
configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0);
#if XCHAL_CP_NUM > 0 #if XCHAL_CP_NUM > 0
// Initialize the coprocessor save area // Initialize the coprocessor save area
uxStackPointer = uxInitialiseStackCPSA(uxStackPointer); uxStackPointer = uxInitialiseStackCPSA(uxStackPointer);
// Each allocated section on the stack must have a size aligned on 16
configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0);
#endif /* XCHAL_CP_NUM > 0 */ #endif /* XCHAL_CP_NUM > 0 */
// Initialize the GCC TLS area // Initialize the GCC TLS area
uint32_t threadptr_reg_init; uint32_t threadptr_reg_init;
uxStackPointer = uxInitialiseStackTLS(uxStackPointer, &threadptr_reg_init); uxStackPointer = uxInitialiseStackTLS(uxStackPointer, &threadptr_reg_init);
configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0);
// Initialize the starting interrupt stack frame // Initialize the starting interrupt stack frame
uxStackPointer = uxInitialiseStackFrame(uxStackPointer, pxCode, pvParameters, threadptr_reg_init); uxStackPointer = uxInitialiseStackFrame(uxStackPointer, pxCode, pvParameters, threadptr_reg_init);
configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0);
// Return the task's current stack pointer address which should point to the starting interrupt stack frame // Return the task's current stack pointer address which should point to the starting interrupt stack frame
return (StackType_t *)uxStackPointer; return (StackType_t *)uxStackPointer;
} }