You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/12/12 16:19:10 UTC

[incubator-nuttx] branch master updated: arch/risc-v: Implement TLS support

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 8ce3337  arch/risc-v: Implement TLS support
8ce3337 is described below

commit 8ce3337e8599be342651e6258b98c7ff8daa1dd1
Author: Huang Qi <hu...@xiaomi.com>
AuthorDate: Sun Dec 12 22:41:32 2021 +0800

    arch/risc-v: Implement TLS support
    
    Signed-off-by: Huang Qi <hu...@xiaomi.com>
---
 arch/Kconfig                                       |  1 +
 arch/risc-v/include/rv32im/irq.h                   |  2 +-
 arch/risc-v/src/common/riscv_internal.h            |  8 +++
 arch/risc-v/src/common/riscv_tls.c                 | 72 ++++++++++++++++++++++
 arch/risc-v/src/qemu-rv32/Make.defs                |  4 ++
 arch/risc-v/src/rv32im/riscv_initialstate.c        | 11 ++++
 .../risc-v/qemu-rv32/rv32-virt/scripts/ld.script   | 12 ++++
 7 files changed, 109 insertions(+), 1 deletion(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 127ca68..557f31a 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -65,6 +65,7 @@ config ARCH_RISCV
 	select ARCH_HAVE_STDARG_H
 	select ARCH_HAVE_SYSCALL_HOOKS
 	select ARCH_HAVE_RDWR_MEM_CPU_RUN
+	select ARCH_HAVE_THREAD_LOCAL
 	---help---
 		RISC-V 32 and 64-bit RV32 / RV64 architectures.
 
diff --git a/arch/risc-v/include/rv32im/irq.h b/arch/risc-v/include/rv32im/irq.h
index 62b3956..8f94dfa 100644
--- a/arch/risc-v/include/rv32im/irq.h
+++ b/arch/risc-v/include/rv32im/irq.h
@@ -56,7 +56,7 @@
 
 #define REG_X1_NDX          1
 
-/* $2: Stack POinter
+/* $2: Stack  Pointer
  * $3: Global Pointer
  * $4: Thread Pointer
  */
diff --git a/arch/risc-v/src/common/riscv_internal.h b/arch/risc-v/src/common/riscv_internal.h
index dbea140..87ff92a 100644
--- a/arch/risc-v/src/common/riscv_internal.h
+++ b/arch/risc-v/src/common/riscv_internal.h
@@ -64,6 +64,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
 
 /* 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
@@ -138,6 +142,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 */
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/risc-v/src/common/riscv_tls.c b/arch/risc-v/src/common/riscv_tls.c
new file mode 100644
index 0000000..64c1854
--- /dev/null
+++ b/arch/risc-v/src/common/riscv_tls.c
@@ -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);
+}
diff --git a/arch/risc-v/src/qemu-rv32/Make.defs b/arch/risc-v/src/qemu-rv32/Make.defs
index cb579f9..30677bb 100644
--- a/arch/risc-v/src/qemu-rv32/Make.defs
+++ b/arch/risc-v/src/qemu-rv32/Make.defs
@@ -42,6 +42,10 @@ ifeq ($(CONFIG_ARCH_HAVE_VFORK),y)
 CMN_CSRCS  += riscv_vfork.c
 endif
 
+ifeq ($(CONFIG_SCHED_THREAD_LOCAL),y)
+CMN_CSRCS  += riscv_tls.c
+endif
+
 # 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_idle.c qemu_rv32_timerisr.c
diff --git a/arch/risc-v/src/rv32im/riscv_initialstate.c b/arch/risc-v/src/rv32im/riscv_initialstate.c
index 55983a2..24b965e 100644
--- a/arch/risc-v/src/rv32im/riscv_initialstate.c
+++ b/arch/risc-v/src/rv32im/riscv_initialstate.c
@@ -55,6 +55,11 @@
 void up_initial_state(struct tcb_s *tcb)
 {
   struct xcptcontext *xcp = &tcb->xcp;
+
+#ifdef CONFIG_SCHED_THREAD_LOCAL
+  struct tls_info_s *info = tcb->stack_alloc_ptr;
+#endif
+
   uint32_t regval;
 
   /* 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;
 
+  /* 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
    * address of the allocated D-Space region.
    */
diff --git a/boards/risc-v/qemu-rv32/rv32-virt/scripts/ld.script b/boards/risc-v/qemu-rv32/rv32-virt/scripts/ld.script
index 929e66c..c0d6d83 100644
--- a/boards/risc-v/qemu-rv32/rv32-virt/scripts/ld.script
+++ b/boards/risc-v/qemu-rv32/rv32-virt/scripts/ld.script
@@ -53,6 +53,18 @@ SECTIONS
       _erodata = . ;
     }
 
+  .tdata : {
+      _stdata = ABSOLUTE(.);
+      *(.tdata .tdata.* .gnu.linkonce.td.*);
+      _etdata = ABSOLUTE(.);
+  }
+
+  .tbss : {
+      _stbss = ABSOLUTE(.);
+      *(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon);
+      _etbss = ABSOLUTE(.);
+  }
+
   _eronly = ABSOLUTE(.);
 
   .data :