Merge branch 'bugfix/esp32s2_freertos_tls' into 'master'

esp32s2: fix THREADPTR calculation, re-enable FreeRTOS TLS tests

Closes IDF-1239

See merge request espressif/esp-idf!7403
This commit is contained in:
Ivan Grokhotkov
2020-01-24 17:47:43 +08:00
4 changed files with 18 additions and 7 deletions

View File

@@ -249,7 +249,8 @@ SECTIONS
ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)),
"DRAM segment data does not fit.")
.flash.rodata :
/* When modifying the alignment, update tls_section_alignment in pxPortInitialiseStack */
.flash.rodata : ALIGN(0x10)
{
_rodata_start = ABSOLUTE(.);

View File

@@ -246,7 +246,8 @@ SECTIONS
ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)),
"DRAM segment data does not fit.")
.flash.rodata :
/* When modifying the alignment, update tls_section_alignment in pxPortInitialiseStack */
.flash.rodata : ALIGN(0x10)
{
_rodata_start = ABSOLUTE(.);

View File

@@ -227,9 +227,20 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
task_thread_local_start = (void *)(((uint32_t)pxTopOfStack - XT_CP_SIZE - thread_local_sz) & ~0xf);
memcpy(task_thread_local_start, &_thread_local_start, thread_local_sz);
threadptr = (uint32_t *)(sp + XT_STK_EXTRA);
/* shift threadptr by the offset of _thread_local_start from DROM start;
need to take into account extra 16 bytes offset */
*threadptr = (uint32_t)task_thread_local_start - ((uint32_t)&_thread_local_start - (uint32_t)&_rodata_start) - 0x10;
/* Calculate THREADPTR value:
* The generated code will add THREADPTR value to a constant value determined at link time,
* to get the address of the TLS variable.
* The constant value is calculated by the linker as follows
* (search for 'tpoff' in elf32-xtensa.c in BFD):
* offset = address - tls_section_vma + align_up(TCB_SIZE, tls_section_alignment)
* where TCB_SIZE is hardcoded to 8. There doesn't seem to be a way to propagate
* the section alignment value from the ld script into the code, so it is hardcoded
* in both places.
*/
const uint32_t tls_section_alignment = 0x10; /* has to be in sync with ALIGN value of .flash.rodata section */
const uint32_t tcb_size = 8; /* Unrelated to FreeRTOS, this is the constant from BFD */
const uint32_t base = (tcb_size + tls_section_alignment - 1) & (~(tls_section_alignment - 1));
*threadptr = (uint32_t)task_thread_local_start - ((uint32_t)&_thread_local_start - (uint32_t)&_rodata_start) - base;
#if XCHAL_CP_NUM > 0
/* Init the coprocessor save area (see xtensa_context.h) */

View File

@@ -11,7 +11,6 @@
#include "test_utils.h"
#include "sdkconfig.h"
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
static __thread int tl_test_var1;
static __thread uint8_t tl_test_var2 = 55;
@@ -109,5 +108,4 @@ TEST_CASE("TLS test", "[freertos]")
}
vTaskDelay(10); /* Make sure idle task can clean up s_task, before it goes out of scope */
}
#endif