mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 00:14:22 +08:00
arch/risc-v: Implement TLS support
Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
This commit is contained in:
@@ -65,6 +65,7 @@ config ARCH_RISCV
|
|||||||
select ARCH_HAVE_STDARG_H
|
select ARCH_HAVE_STDARG_H
|
||||||
select ARCH_HAVE_SYSCALL_HOOKS
|
select ARCH_HAVE_SYSCALL_HOOKS
|
||||||
select ARCH_HAVE_RDWR_MEM_CPU_RUN
|
select ARCH_HAVE_RDWR_MEM_CPU_RUN
|
||||||
|
select ARCH_HAVE_THREAD_LOCAL
|
||||||
---help---
|
---help---
|
||||||
RISC-V 32 and 64-bit RV32 / RV64 architectures.
|
RISC-V 32 and 64-bit RV32 / RV64 architectures.
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
|
|
||||||
#define REG_X1_NDX 1
|
#define REG_X1_NDX 1
|
||||||
|
|
||||||
/* $2: Stack POinter
|
/* $2: Stack Pointer
|
||||||
* $3: Global Pointer
|
* $3: Global Pointer
|
||||||
* $4: Thread Pointer
|
* $4: Thread Pointer
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -64,6 +64,10 @@
|
|||||||
#define _DATA_INIT &_eronly
|
#define _DATA_INIT &_eronly
|
||||||
#define _START_DATA &_sdata
|
#define _START_DATA &_sdata
|
||||||
#define _END_DATA &_edata
|
#define _END_DATA &_edata
|
||||||
|
#define _START_TDATA &_stdata
|
||||||
|
#define _END_TDATA &_etdata
|
||||||
|
#define _START_TBSS &_stbss
|
||||||
|
#define _END_TBSS &_etbss
|
||||||
|
|
||||||
/* Determine which (if any) console driver to use. If a console is enabled
|
/* Determine which (if any) console driver to use. If a console is enabled
|
||||||
* and no other console device is specified, then a serial console is
|
* and no other console device is specified, then a serial console is
|
||||||
@@ -138,6 +142,10 @@ EXTERN uint32_t _sdata; /* Start of .data */
|
|||||||
EXTERN uint32_t _edata; /* End+1 of .data */
|
EXTERN uint32_t _edata; /* End+1 of .data */
|
||||||
EXTERN uint32_t _sbss; /* Start of .bss */
|
EXTERN uint32_t _sbss; /* Start of .bss */
|
||||||
EXTERN uint32_t _ebss; /* End+1 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 */
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* arch/risc-v/src/common/riscv_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 "riscv_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) +
|
||||||
|
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);
|
||||||
|
|
||||||
|
memcpy(tls_data, _START_TDATA, tdata_len);
|
||||||
|
memset(tls_data + tdata_len, 0, tbss_len);
|
||||||
|
}
|
||||||
@@ -42,6 +42,10 @@ ifeq ($(CONFIG_ARCH_HAVE_VFORK),y)
|
|||||||
CMN_CSRCS += riscv_vfork.c
|
CMN_CSRCS += riscv_vfork.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_SCHED_THREAD_LOCAL),y)
|
||||||
|
CMN_CSRCS += riscv_tls.c
|
||||||
|
endif
|
||||||
|
|
||||||
# Specify our C code within this directory to be included
|
# Specify our C code within this directory to be included
|
||||||
CHIP_CSRCS = qemu_rv32_start.c qemu_rv32_irq_dispatch.c qemu_rv32_irq.c
|
CHIP_CSRCS = qemu_rv32_start.c qemu_rv32_irq_dispatch.c qemu_rv32_irq.c
|
||||||
CHIP_CSRCS += qemu_rv32_idle.c qemu_rv32_timerisr.c
|
CHIP_CSRCS += qemu_rv32_idle.c qemu_rv32_timerisr.c
|
||||||
|
|||||||
@@ -55,6 +55,11 @@
|
|||||||
void up_initial_state(struct tcb_s *tcb)
|
void up_initial_state(struct tcb_s *tcb)
|
||||||
{
|
{
|
||||||
struct xcptcontext *xcp = &tcb->xcp;
|
struct xcptcontext *xcp = &tcb->xcp;
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_THREAD_LOCAL
|
||||||
|
struct tls_info_s *info = tcb->stack_alloc_ptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
|
|
||||||
/* Initialize the idle thread stack */
|
/* Initialize the idle thread stack */
|
||||||
@@ -93,6 +98,12 @@ void up_initial_state(struct tcb_s *tcb)
|
|||||||
|
|
||||||
xcp->regs[REG_EPC] = (uint32_t)tcb->start;
|
xcp->regs[REG_EPC] = (uint32_t)tcb->start;
|
||||||
|
|
||||||
|
/* Setup thread local storage pointer */
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_THREAD_LOCAL
|
||||||
|
xcp->regs[REG_TP] = (uint32_t)info->tl_data;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* If this task is running PIC, then set the PIC base register to the
|
/* If this task is running PIC, then set the PIC base register to the
|
||||||
* address of the allocated D-Space region.
|
* address of the allocated D-Space region.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -53,6 +53,18 @@ SECTIONS
|
|||||||
_erodata = . ;
|
_erodata = . ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tdata : {
|
||||||
|
_stdata = ABSOLUTE(.);
|
||||||
|
*(.tdata .tdata.* .gnu.linkonce.td.*);
|
||||||
|
_etdata = ABSOLUTE(.);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tbss : {
|
||||||
|
_stbss = ABSOLUTE(.);
|
||||||
|
*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
|
||||||
|
_etbss = ABSOLUTE(.);
|
||||||
|
}
|
||||||
|
|
||||||
_eronly = ABSOLUTE(.);
|
_eronly = ABSOLUTE(.);
|
||||||
|
|
||||||
.data :
|
.data :
|
||||||
|
|||||||
Reference in New Issue
Block a user