arch/arm: Implement TLS support

Signed-off-by: Huang Qi <no1wudi@qq.com>
This commit is contained in:
Huang Qi 2021-12-03 21:35:39 +08:00 committed by Xiang Xiao
parent 3e8a3c9cc2
commit 58e0781e2e
72 changed files with 899 additions and 6 deletions

View file

@ -16,6 +16,7 @@ config ARCH_ARM
select ARCH_HAVE_STDARG_H
select ARCH_HAVE_SYSCALL_HOOKS
select ARCH_HAVE_RDWR_MEM_CPU_RUN
select ARCH_HAVE_THREAD_LOCAL
---help---
The ARM architectures
@ -352,6 +353,10 @@ config ARCH_HAVE_TESTSET
bool
default n
config ARCH_HAVE_THREAD_LOCAL
bool
default n
config ARCH_HAVE_FETCHADD
bool
default n

View file

@ -153,6 +153,10 @@
# define _DATA_INIT &_eronly
# define _START_DATA &_sdata
# define _END_DATA &_edata
# define _START_TDATA &_stdata
# define _END_TDATA &_etdata
# define _START_TBSS &_stbss
# define _END_TBSS &_etbss
#endif
/* This is the value used to mark the stack for subsequent stack monitoring
@ -240,6 +244,10 @@ EXTERN uint32_t _sdata; /* Start of .data */
EXTERN uint32_t _edata; /* End+1 of .data */
EXTERN uint32_t _sbss; /* Start of .bss */
EXTERN uint32_t _ebss; /* End+1 of .bss */
EXTERN uint32_t _stdata; /* Start of .tdata */
EXTERN uint32_t _etdata; /* End+1 of .tdata */
EXTERN uint32_t _stbss; /* Start of .tbss */
EXTERN uint32_t _etbss; /* End+1 of .tbss */
/* Sometimes, functions must be executed from RAM. In this case, the
* following macro may be used (with GCC!) to specify a function that will

View file

@ -0,0 +1,90 @@
/****************************************************************************
* arch/arm/src/common/arm_tls.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/arch.h>
#include <nuttx/tls.h>
#include "arm_internal.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_tls_size
*
* Description:
* Get TLS (sizeof(struct tls_info_s) + tdata + tbss) section size.
*
* Returned Value:
* Size of (sizeof(struct tls_info_s) + tdata + tbss).
*
****************************************************************************/
int up_tls_size(void)
{
/* Extra 8 bytes (2 pointer) according to GCC */
return sizeof(struct tls_info_s) +
sizeof(void *) * 2 +
sizeof(uint32_t) * (_END_TBSS - _START_TDATA);
}
/****************************************************************************
* Name: up_tls_initialize
*
* Description:
* Initialize thread local region.
*
* Input Parameters:
* info - The TLS structure to initialize.
*
****************************************************************************/
void up_tls_initialize(FAR struct tls_info_s *info)
{
FAR uint8_t *tls_data = info->tl_data;
uint32_t tdata_len = sizeof(uint32_t) * (_END_TDATA - _START_TDATA);
uint32_t tbss_len = sizeof(uint32_t) * (_END_TBSS - _START_TBSS);
tls_data += sizeof(void *) * 2;
memcpy(tls_data, _START_TDATA, tdata_len);
memset(tls_data + tdata_len, 0, tbss_len);
}
/****************************************************************************
* Name: __aeabi_read_tp
*
* Description:
* Read thread local storage region pointer.
*
****************************************************************************/
void *__aeabi_read_tp(void)
{
return tls_get_info()->tl_data;
}

View file

@ -76,6 +76,10 @@ ifeq ($(CONFIG_ARMV7M_ITMSYSLOG),y)
CMN_CSRCS += arm_itm_syslog.c
endif
ifeq ($(CONFIG_SCHED_THREAD_LOCAL),y)
CMN_CSRCS += arm_tls.c
endif
CHIP_CSRCS = stm32_allocateheap.c stm32_start.c stm32_rcc.c stm32_lse.c
CHIP_CSRCS += stm32_lsi.c stm32_gpio.c stm32_exti_gpio.c stm32_flash.c
CHIP_CSRCS += stm32_irq.c stm32_lowputc.c

View file

@ -75,6 +75,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The RAM vector table (if present) should lie at the beginning of SRAM */

View file

@ -87,6 +87,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {

View file

@ -87,6 +87,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {

View file

@ -90,6 +90,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {

View file

@ -77,6 +77,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data :

View file

@ -65,6 +65,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The STM32F107VC has 64Kb of SRAM beginning at the following address */

View file

@ -79,6 +79,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : {

View file

@ -69,6 +69,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The STM32F103RET6 has 64Kb of SRAM beginning at the following address */

View file

@ -67,6 +67,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The STM32F103Z has 64Kb of SRAM beginning at the following address */

View file

@ -68,6 +68,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The STM32F103Z has 64Kb of SRAM beginning at the following address */

View file

@ -68,6 +68,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The STM32F103VCT6 has 48Kb of SRAM beginning at the following address */

View file

@ -68,6 +68,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The STM32F103VCT6 has 48Kb of SRAM beginning at the following address */

View file

@ -74,6 +74,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {

View file

@ -69,6 +69,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The RAM vector table (if present) should lie at the beginning of SRAM */

View file

@ -72,6 +72,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {

View file

@ -69,6 +69,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The RAM vector table (if present) should lie at the beginning of SRAM */

View file

@ -69,6 +69,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {

View file

@ -69,6 +69,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {

View file

@ -69,6 +69,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The RAM vector table (if present) should lie at the beginning of SRAM */

View file

@ -68,6 +68,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The STM32F410RBT6 has 32Kb of SRAM beginning at the following address */

View file

@ -68,6 +68,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : {

View file

@ -75,6 +75,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The RAM vector table (if present) should lie at the beginning of SRAM */

View file

@ -68,6 +68,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The STM32F103VCT6 has 48Kb of SRAM beginning at the following address */

View file

@ -58,6 +58,18 @@ SECTIONS
_einit = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
.ARM.extab : {
*(.ARM.extab*)
} > flash

View file

@ -87,6 +87,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {

View file

@ -87,6 +87,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {

View file

@ -69,6 +69,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The RAM vector table (if present) should lie at the beginning of SRAM */

View file

@ -74,6 +74,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {

View file

@ -74,6 +74,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {

View file

@ -74,6 +74,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {

View file

@ -73,6 +73,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {

View file

@ -61,6 +61,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The STM32F107VC has 64Kb of SRAM beginning at the following address */

View file

@ -73,6 +73,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {

View file

@ -73,6 +73,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : {

View file

@ -68,6 +68,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {

View file

@ -62,6 +62,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The STM32F103Z has 64Kb of SRAM beginning at the following address */

View file

@ -74,6 +74,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {

View file

@ -82,6 +82,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : {

View file

@ -70,6 +70,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : {

View file

@ -65,6 +65,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The STM32F107VC has 64Kb of SRAM beginning at the following address */

View file

@ -67,6 +67,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The STM32F107VC has 64Kb of SRAM beginning at the following address */

View file

@ -68,6 +68,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The STM32F103Z has 64Kb of SRAM beginning at the following address */

View file

@ -67,6 +67,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The STM32F103Z has 64Kb of SRAM beginning at the following address */

View file

@ -73,6 +73,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {

View file

@ -74,6 +74,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {

View file

@ -68,6 +68,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The STM32F103C8T6 has 20Kb of SRAM beginning at the following address */

View file

@ -61,6 +61,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The RAM vector table (if present) should lie at the beginning of SRAM */

View file

@ -61,6 +61,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The RAM vector table (if present) should lie at the beginning of SRAM */

View file

@ -73,6 +73,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The STM32F103C8T6 has 20Kb of SRAM beginning at the following address */

View file

@ -67,6 +67,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The STM32F103C8T6 has 20Kb of SRAM beginning at the following address */

View file

@ -69,6 +69,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The RAM vector table (if present) should lie at the beginning of SRAM */

View file

@ -69,6 +69,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {

View file

@ -68,6 +68,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The STM32F103VCT6 has 48Kb of SRAM beginning at the following address */

View file

@ -68,6 +68,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The STM32F103VCT6 has 48Kb of SRAM beginning at the following address */

View file

@ -75,6 +75,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The RAM vector table (if present) should lie at the beginning of SRAM */

View file

@ -74,6 +74,18 @@ SECTIONS
__exidx_end = ABSOLUTE(.);
} > flash
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {

View file

@ -73,6 +73,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data :

View file

@ -73,6 +73,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data :

View file

@ -68,6 +68,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
.data : {

View file

@ -61,6 +61,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The RAM vector table (if present) should lie at the beginning of SRAM */

View file

@ -61,6 +61,18 @@ SECTIONS
} > flash
__exidx_end = ABSOLUTE(.);
.tdata : {
_stdata = ABSOLUTE(.);
*(.tdata .tdata.* .gnu.linkonce.td.*);
_etdata = ABSOLUTE(.);
} > flash
.tbss : {
_stbss = ABSOLUTE(.);
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
_etbss = ABSOLUTE(.);
} > flash
_eronly = ABSOLUTE(.);
/* The RAM vector table (if present) should lie at the beginning of SRAM */

View file

@ -85,6 +85,7 @@
#include <nuttx/compiler.h>
#include <nuttx/cache.h>
#include <nuttx/sched.h>
#include <nuttx/tls.h>
/****************************************************************************
* Pre-processor definitions
@ -1803,6 +1804,40 @@ int up_timer_start(FAR const struct timespec *ts);
# endif
#endif
/****************************************************************************
* Name: up_tls_size
*
* Description:
* Get TLS (sizeof(struct tls_info_s) + tdata + tbss) section size.
*
* Returned Value:
* Size of (sizeof(struct tls_info_s) + tdata + tbss).
*
****************************************************************************/
#ifdef CONFIG_SCHED_THREAD_LOCAL
int up_tls_size(void);
#else
#define up_tls_size() sizeof(struct tls_info_s)
#endif
/****************************************************************************
* Name: up_tls_initialize
*
* Description:
* Initialize thread local region
*
* Input Parameters:
* tls_data - The memory region to initialize
*
****************************************************************************/
#ifdef CONFIG_SCHED_THREAD_LOCAL
void up_tls_initialize(FAR struct tls_info_s *info);
#else
#define up_tls_initialize(x)
#endif
/****************************************************************************
* Multiple CPU support
****************************************************************************/

View file

@ -167,6 +167,9 @@ struct tls_info_s
#endif
int tl_errno; /* Per-thread error number */
#ifdef CONFIG_SCHED_THREAD_LOCAL
uint8_t tl_data[0];
#endif
};
/****************************************************************************

View file

@ -600,6 +600,14 @@ config SCHED_USER_IDENTITY
Those can then be managed using the interfaces. Child tasks will
inherit the UID and GID of its parent.
config SCHED_THREAD_LOCAL
bool "Support __thread/thread_local keyword"
default n
depends on ARCH_HAVE_THREAD_LOCAL
---help---
This option enables architecture-sepecific TLS supports (__thread/thread_local keyword)
Note: Toolchain must be compiled with '--enable-tls' enabled
endmenu # Tasks and Scheduling
menu "Pthread Options"

View file

@ -580,7 +580,9 @@ void nx_start(void)
up_initial_state(&g_idletcb[i].cmn);
/* Initialize the thread local storage */
/* Initialize the thread local storage
* Note: Don't copy tdata and tss for idle task to improve footprint
*/
info = up_stack_frame(&g_idletcb[i].cmn, sizeof(struct tls_info_s));
DEBUGASSERT(info == g_idletcb[i].cmn.stack_alloc_ptr);

View file

@ -315,7 +315,7 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR pthread_t *thread,
/* Allocate the stack for the TCB */
ret = up_create_stack((FAR struct tcb_s *)ptcb,
sizeof(struct tls_info_s) + attr->stacksize,
up_tls_size() + attr->stacksize,
TCB_FLAG_TTYPE_PTHREAD);
}
@ -327,7 +327,7 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR pthread_t *thread,
/* Initialize thread local storage */
info = up_stack_frame(&ptcb->cmn, sizeof(struct tls_info_s));
info = up_stack_frame(&ptcb->cmn, up_tls_size());
if (info == NULL)
{
errcode = ENOMEM;
@ -336,6 +336,8 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR pthread_t *thread,
DEBUGASSERT(info == ptcb->cmn.stack_alloc_ptr);
up_tls_initialize(info);
/* Attach per-task info in group to TLS */
info->tl_task = ptcb->cmn.group->tg_info;

View file

@ -122,7 +122,7 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
/* Allocate the stack for the TCB */
ret = up_create_stack(&tcb->cmn,
sizeof(struct tls_info_s) + stack_size,
up_tls_size() + stack_size,
ttype);
}
@ -133,7 +133,7 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
/* Initialize thread local storage */
info = up_stack_frame(&tcb->cmn, sizeof(struct tls_info_s));
info = up_stack_frame(&tcb->cmn, up_tls_size());
if (info == NULL)
{
ret = -ENOMEM;
@ -144,6 +144,8 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
info->tl_task = tcb->cmn.group->tg_info;
up_tls_initialize(info);
/* Initialize the task control block */
ret = nxtask_setup_scheduler(tcb, priority, nxtask_start,

View file

@ -173,7 +173,7 @@ FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr)
/* Setup thread local storage */
info = up_stack_frame(&child->cmn, sizeof(struct tls_info_s));
info = up_stack_frame(&child->cmn, up_tls_size());
if (info == NULL)
{
ret = -ENOMEM;
@ -184,6 +184,8 @@ FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr)
memcpy(info, parent->cmn.stack_alloc_ptr, sizeof(struct tls_info_s));
info->tl_task = child->cmn.group->tg_info;
up_tls_initialize(info);
/* Get the priority of the parent task */
#ifdef CONFIG_PRIORITY_INHERITANCE