forked from nuttx/nuttx-update
arch/x86_64: add support for thread_local
Signed-off-by: liwenxiang1 <liwenxiang1@xiaomi.com>
This commit is contained in:
parent
5e15fff58a
commit
8b86f5de60
9 changed files with 141 additions and 4 deletions
|
@ -138,6 +138,7 @@ config ARCH_X86_64
|
||||||
select ARCH_HAVE_TESTSET
|
select ARCH_HAVE_TESTSET
|
||||||
select ARCH_HAVE_INTERRUPTSTACK
|
select ARCH_HAVE_INTERRUPTSTACK
|
||||||
select ARCH_HAVE_CUSTOMOPT
|
select ARCH_HAVE_CUSTOMOPT
|
||||||
|
select ARCH_HAVE_THREAD_LOCAL
|
||||||
select PCI_LATE_DRIVERS_REGISTER if PCI
|
select PCI_LATE_DRIVERS_REGISTER if PCI
|
||||||
select LIBC_ARCH_ELF_64BIT if LIBC_ARCH_ELF
|
select LIBC_ARCH_ELF_64BIT if LIBC_ARCH_ELF
|
||||||
select ARCH_TOOLCHAIN_GNU
|
select ARCH_TOOLCHAIN_GNU
|
||||||
|
|
|
@ -45,6 +45,10 @@ if(CONFIG_ARCH_X86_64_ACPI)
|
||||||
list(APPEND SRCS x86_64_acpi.c)
|
list(APPEND SRCS x86_64_acpi.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_SCHED_THREAD_LOCAL)
|
||||||
|
list(APPEND SRCS x86_64_tls.c)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(CONFIG_ARCH_USE_MMU)
|
if(CONFIG_ARCH_USE_MMU)
|
||||||
list(APPEND SRCS x86_64_mmu.c)
|
list(APPEND SRCS x86_64_mmu.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -38,6 +38,10 @@ ifeq ($(CONFIG_ARCH_X86_64_ACPI),y)
|
||||||
CMN_CSRCS += x86_64_acpi.c
|
CMN_CSRCS += x86_64_acpi.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_SCHED_THREAD_LOCAL),y)
|
||||||
|
CMN_CSRCS += x86_64_tls.c
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_ARCH_USE_MMU),y)
|
ifeq ($(CONFIG_ARCH_USE_MMU),y)
|
||||||
CMN_CSRCS += x86_64_mmu.c
|
CMN_CSRCS += x86_64_mmu.c
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -134,6 +134,20 @@
|
||||||
# define IRQ_STACK_SIZE CONFIG_ARCH_INTERRUPTSTACK
|
# define IRQ_STACK_SIZE CONFIG_ARCH_INTERRUPTSTACK
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Linker defined section addresses */
|
||||||
|
|
||||||
|
#define _START_TEXT _stext
|
||||||
|
#define _END_TEXT _etext
|
||||||
|
#define _START_BSS _sbss
|
||||||
|
#define _END_BSS _ebss
|
||||||
|
#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
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Types
|
* Public Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -171,6 +185,10 @@ extern uint8_t _sdata[]; /* Start of .data */
|
||||||
extern uint8_t _edata[]; /* End+1 of .data */
|
extern uint8_t _edata[]; /* End+1 of .data */
|
||||||
extern uint8_t _sbss[]; /* Start of .bss */
|
extern uint8_t _sbss[]; /* Start of .bss */
|
||||||
extern uint8_t _ebss[]; /* End+1 of .bss */
|
extern uint8_t _ebss[]; /* End+1 of .bss */
|
||||||
|
extern uint8_t _stdata[]; /* Start of .tdata */
|
||||||
|
extern uint8_t _etdata[]; /* End+1 of .tdata */
|
||||||
|
extern uint8_t _stbss[]; /* Start of .tbss */
|
||||||
|
extern uint8_t _etbss[]; /* End+1 of .tbss */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|
71
arch/x86_64/src/common/x86_64_tls.c
Normal file
71
arch/x86_64/src/common/x86_64_tls.c
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/****************************************************************************
|
||||||
|
* arch/x86_64/src/common/x86_64_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 "x86_64_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)
|
||||||
|
{
|
||||||
|
return sizeof(struct tls_info_s) +
|
||||||
|
_END_TBSS - _START_TDATA + sizeof(void *);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_tls_initialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initialize thread local region.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* info - The TLS structure to initialize.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void up_tls_initialize(struct tls_info_s *info)
|
||||||
|
{
|
||||||
|
uint8_t *tls_data = (uint8_t *)(info + 1);
|
||||||
|
uint32_t tdata_len = _END_TDATA - _START_TDATA;
|
||||||
|
uint32_t tbss_len = _END_TBSS - _START_TBSS;
|
||||||
|
|
||||||
|
memcpy(tls_data, _START_TDATA, tdata_len);
|
||||||
|
memset(tls_data + tdata_len, 0, tbss_len);
|
||||||
|
}
|
|
@ -108,7 +108,6 @@ x86_64_fullcontextrestore:
|
||||||
movq (8*REG_R10)(%rdi), %r10
|
movq (8*REG_R10)(%rdi), %r10
|
||||||
movq (8*REG_RBP)(%rdi), %rbp
|
movq (8*REG_RBP)(%rdi), %rbp
|
||||||
movq (8*REG_RBX)(%rdi), %rbx
|
movq (8*REG_RBX)(%rdi), %rbx
|
||||||
movq (8*REG_RAX)(%rdi), %rax
|
|
||||||
|
|
||||||
/* Restore the data segment register. I think there is an issue that will
|
/* Restore the data segment register. I think there is an issue that will
|
||||||
* need to be address here at some time: If the register save area is in
|
* need to be address here at some time: If the register save area is in
|
||||||
|
@ -124,6 +123,13 @@ x86_64_fullcontextrestore:
|
||||||
* XXX: Should use wrgsbase and wrfsbase to restore the gs and fs register
|
* XXX: Should use wrgsbase and wrfsbase to restore the gs and fs register
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_THREAD_LOCAL
|
||||||
|
mov (8*REG_FS)(%rdi), %rax
|
||||||
|
wrfsbase %rax
|
||||||
|
#endif
|
||||||
|
|
||||||
|
movq (8*REG_RAX)(%rdi), %rax
|
||||||
|
|
||||||
/* Restore the correct value of EAX and then return */
|
/* Restore the correct value of EAX and then return */
|
||||||
|
|
||||||
popq %rdi
|
popq %rdi
|
||||||
|
|
|
@ -30,6 +30,10 @@
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
#include <arch/arch.h>
|
#include <arch/arch.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_THREAD_LOCAL
|
||||||
|
# include <nuttx/tls.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "x86_64_internal.h"
|
#include "x86_64_internal.h"
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
|
|
||||||
|
@ -132,12 +136,25 @@ void up_initial_state(struct tcb_s *tcb)
|
||||||
xcp->regs[REG_SS] = up_getss();
|
xcp->regs[REG_SS] = up_getss();
|
||||||
xcp->regs[REG_ES] = up_getes();
|
xcp->regs[REG_ES] = up_getes();
|
||||||
|
|
||||||
/* Aux GS and FS are set to be 0 */
|
/* FS used by for TLS
|
||||||
|
* used by some libc for TLS and segment reference
|
||||||
|
*/
|
||||||
|
|
||||||
/* used by some libc for TLS and segment reference */
|
#ifdef CONFIG_SCHED_THREAD_LOCAL
|
||||||
|
xcp->regs[REG_FS] = (uintptr_t)tcb->stack_alloc_ptr
|
||||||
|
+ sizeof(struct tls_info_s)
|
||||||
|
+ (_END_TBSS - _START_TDATA);
|
||||||
|
|
||||||
|
*(uint64_t *)(xcp->regs[REG_FS]) = xcp->regs[REG_FS];
|
||||||
|
|
||||||
|
write_fsbase(xcp->regs[REG_FS]);
|
||||||
|
#else
|
||||||
|
xcp->regs[REG_FS] = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* GS used for CPU private data */
|
||||||
|
|
||||||
xcp->regs[REG_GS] = 0;
|
xcp->regs[REG_GS] = 0;
|
||||||
xcp->regs[REG_FS] = 0;
|
|
||||||
|
|
||||||
/* Set supervisor- or user-mode, depending on how NuttX is configured and
|
/* Set supervisor- or user-mode, depending on how NuttX is configured and
|
||||||
* what kind of thread is being started. Disable FIQs in any event
|
* what kind of thread is being started. Disable FIQs in any event
|
||||||
|
|
|
@ -45,6 +45,7 @@ CONFIG_PTHREAD_STACK_MIN=4194304
|
||||||
CONFIG_RAM_SIZE=268435456
|
CONFIG_RAM_SIZE=268435456
|
||||||
CONFIG_SCHED_CHILD_STATUS=y
|
CONFIG_SCHED_CHILD_STATUS=y
|
||||||
CONFIG_SCHED_HAVE_PARENT=y
|
CONFIG_SCHED_HAVE_PARENT=y
|
||||||
|
CONFIG_SCHED_THREAD_LOCAL=y
|
||||||
CONFIG_SCHED_TICKLESS=y
|
CONFIG_SCHED_TICKLESS=y
|
||||||
CONFIG_SCHED_TICKLESS_ALARM=y
|
CONFIG_SCHED_TICKLESS_ALARM=y
|
||||||
CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP=y
|
CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP=y
|
||||||
|
|
|
@ -48,6 +48,11 @@ SECTIONS
|
||||||
*(.loader.rodata)
|
*(.loader.rodata)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader.tdata_tbss : {
|
||||||
|
*(.loader.tdata)
|
||||||
|
*(.loader.tbss)
|
||||||
|
}
|
||||||
|
|
||||||
.loader.data : {
|
.loader.data : {
|
||||||
*(.loader.data)
|
*(.loader.data)
|
||||||
}
|
}
|
||||||
|
@ -89,6 +94,16 @@ SECTIONS
|
||||||
_erodata = ABSOLUTE(.);
|
_erodata = ABSOLUTE(.);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tdata_tbss ALIGN(0x1000) :
|
||||||
|
{
|
||||||
|
_stdata = ABSOLUTE(.);
|
||||||
|
*(.tdata .tdata.* .gnu.linkonce.td.*);
|
||||||
|
_etdata = ABSOLUTE(.);
|
||||||
|
_stbss = ABSOLUTE(.);
|
||||||
|
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
|
||||||
|
_etbss = ABSOLUTE(.);
|
||||||
|
}
|
||||||
|
|
||||||
.data ALIGN(0x1000) :
|
.data ALIGN(0x1000) :
|
||||||
{
|
{
|
||||||
_sdata = ABSOLUTE(.);
|
_sdata = ABSOLUTE(.);
|
||||||
|
|
Loading…
Reference in a new issue