From bcb85167444ac39a811a34650bf479d28023da6c Mon Sep 17 00:00:00 2001 From: Omar Chebib Date: Fri, 11 Nov 2022 15:00:42 +0800 Subject: [PATCH] FreeRTOS: Make the default stack alignment 16 for Xtensa --- .../freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c | 6 ++++++ .../portable/xtensa/include/freertos/portmacro.h | 2 +- .../FreeRTOS-Kernel-SMP/portable/xtensa/port.c | 7 +++++++ .../freertos/FreeRTOS-Kernel/portable/riscv/port.c | 6 +++++- .../portable/xtensa/include/freertos/portmacro.h | 2 +- .../freertos/FreeRTOS-Kernel/portable/xtensa/port.c | 10 ++++++++-- 6 files changed, 28 insertions(+), 5 deletions(-) diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c index f99f405342..65de90fde6 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c @@ -44,6 +44,8 @@ #include "esp_gdbstub.h" #endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME +_Static_assert(portBYTE_ALIGNMENT == 16, "portBYTE_ALIGNMENT must be set to 16"); + /* ---------------------------------------------------- Variables ------------------------------------------------------ * * ------------------------------------------------------------------------------------------------------------------ */ @@ -703,13 +705,17 @@ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxC */ UBaseType_t uxStackPointer = (UBaseType_t)pxTopOfStack; + configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0); // Initialize GCC TLS area uint32_t threadptr_reg_init; uxStackPointer = uxInitialiseStackTLS(uxStackPointer, &threadptr_reg_init); + configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0); // Initialize the starting interrupt stack frame 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 (StackType_t *)uxStackPointer; //TODO: IDF-2393 diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/include/freertos/portmacro.h b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/include/freertos/portmacro.h index 3830b28368..6121f981cb 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/include/freertos/portmacro.h +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/include/freertos/portmacro.h @@ -72,7 +72,7 @@ typedef uint32_t TickType_t; #define portCRITICAL_NESTING_IN_TCB 1 #define portSTACK_GROWTH ( -1 ) #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 /* ---------------------------------------------- Forward Declarations ------------------------------------------------- diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c index 458c607c33..d1400a64e6 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c @@ -50,6 +50,8 @@ #include "hal/systimer_ll.h" #endif // CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER +_Static_assert(portBYTE_ALIGNMENT == 16, "portBYTE_ALIGNMENT must be set to 16"); + /* OS state variables */ @@ -884,18 +886,23 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, */ UBaseType_t uxStackPointer = (UBaseType_t)pxTopOfStack; + configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0); #if XCHAL_CP_NUM > 0 // Initialize the coprocessor save area uxStackPointer = uxInitialiseStackCPSA(uxStackPointer); + configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0); #endif /* XCHAL_CP_NUM > 0 */ // Initialize the GCC TLS area uint32_t threadptr_reg_init; uxStackPointer = uxInitialiseStackTLS(uxStackPointer, &threadptr_reg_init); + configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0); // Initialize the starting interrupt stack frame 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 (StackType_t *)uxStackPointer; } diff --git a/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c b/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c index 85b92fa2c8..f5b3d08545 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c @@ -57,7 +57,7 @@ #include "port_systick.h" #include "esp_memory_utils.h" - +_Static_assert(portBYTE_ALIGNMENT == 16, "portBYTE_ALIGNMENT must be set to 16"); /* ---------------------------------------------------- Variables ------------------------------------------------------ * @@ -284,13 +284,17 @@ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxC */ UBaseType_t uxStackPointer = (UBaseType_t)pxTopOfStack; + configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0); // Initialize GCC TLS area uint32_t threadptr_reg_init; uxStackPointer = uxInitialiseStackTLS(uxStackPointer, &threadptr_reg_init); + configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0); // Initialize the starting interrupt stack frame 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 (StackType_t *)uxStackPointer; //TODO: IDF-2393 diff --git a/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h b/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h index 06b52e908e..9cabfb63ed 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h +++ b/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h @@ -139,7 +139,7 @@ typedef uint32_t TickType_t; #define portCRITICAL_NESTING_IN_TCB 0 #define portSTACK_GROWTH ( -1 ) #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 portNOP() XT_NOP() diff --git a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c index 004bf10bb3..5237b6a9b3 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c @@ -78,6 +78,8 @@ #include "esp_cpu.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"); @@ -415,20 +417,24 @@ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxC - 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 */ - 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 // Initialize the coprocessor save area 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 */ // Initialize the GCC TLS area uint32_t threadptr_reg_init; uxStackPointer = uxInitialiseStackTLS(uxStackPointer, &threadptr_reg_init); + configASSERT((uxStackPointer & portBYTE_ALIGNMENT_MASK) == 0); // Initialize the starting interrupt stack frame 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 (StackType_t *)uxStackPointer; }