You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gn...@apache.org on 2020/05/07 03:56:48 UTC

[incubator-nuttx] branch master updated (3e00d18 -> 6eb6d31)

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

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


    from 3e00d18  Fix nxstyle issue
     new 1e3ec6e  arch/: Implement Thread Local Storage for the rest of the architectures. The change consisted on modifying *_usestack.c and *_createstack.c
     new a4dd967  arch/: Implement up_tls_info() for the rest of the architectures.
     new d56c613  arch/avr,renesas,risc-v: The *_getsp function was moved to a header file, remove it from the different source files that used to implement it to avoid redefinitions.
     new 6eb6d31  Fix nxstyle complaints

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 arch/arm/include/tls.h                       |  6 +-
 arch/arm/src/common/arm_usestack.c           |  2 +-
 arch/avr/include/arch.h                      |  6 ++
 arch/avr/include/avr/arch.h                  | 88 ++++++++++++++++++++++++++++
 arch/avr/include/avr32/arch.h                | 85 +++++++++++++++++++++++++++
 arch/{arm => avr}/include/tls.h              | 28 ++-------
 arch/avr/src/avr/up_createstack.c            | 60 ++++++++++++++++++-
 arch/avr/src/avr/up_dumpstate.c              | 23 +-------
 arch/avr/src/avr/up_usestack.c               | 19 +++++-
 arch/avr/src/avr32/up_createstack.c          | 46 +++++++++++++++
 arch/avr/src/avr32/up_dumpstate.c            | 19 +-----
 arch/avr/src/avr32/up_usestack.c             | 15 ++++-
 arch/avr/src/common/up_assert.c              |  2 +-
 arch/{arm => hc}/include/tls.h               | 25 ++++----
 arch/hc/src/common/up_createstack.c          | 46 +++++++++++++++
 arch/hc/src/common/up_usestack.c             | 16 ++++-
 arch/{arm => mips}/include/tls.h             | 21 +++----
 arch/mips/src/common/mips_createstack.c      | 54 ++++++++++++++++-
 arch/mips/src/common/mips_usestack.c         | 21 ++++++-
 arch/{arm => misoc}/include/tls.h            | 25 ++++----
 arch/misoc/src/lm32/lm32_createstack.c       | 45 ++++++++++++++
 arch/misoc/src/minerva/minerva_createstack.c | 50 +++++++++++++++-
 arch/{arm => or1k}/include/tls.h             | 17 +++---
 arch/or1k/src/common/up_createstack.c        |  8 ++-
 arch/renesas/include/arch.h                  |  6 ++
 arch/renesas/include/m16c/arch.h             | 86 +++++++++++++++++++++++++++
 arch/renesas/include/rx65n/arch.h            | 87 +++++++++++++++++++++++++++
 arch/renesas/include/sh1/arch.h              | 86 +++++++++++++++++++++++++++
 arch/{arm => renesas}/include/tls.h          | 28 ++-------
 arch/renesas/src/common/up_assert.c          |  3 +-
 arch/renesas/src/common/up_createstack.c     | 46 +++++++++++++++
 arch/renesas/src/common/up_usestack.c        | 13 ++++
 arch/renesas/src/m16c/m16c_dumpstate.c       | 66 ++++++++-------------
 arch/renesas/src/rx65n/rx65n_dumpstate.c     | 15 +----
 arch/renesas/src/sh1/sh1_dumpstate.c         | 24 +-------
 arch/risc-v/include/arch.h                   |  9 ++-
 arch/risc-v/include/rv32im/arch.h            | 83 ++++++++++++++++++++++++++
 arch/risc-v/include/rv64gc/arch.h            | 83 ++++++++++++++++++++++++++
 arch/{arm => risc-v}/include/tls.h           | 28 ++-------
 arch/risc-v/src/common/riscv_createstack.c   | 69 +++++++++++++++++++++-
 arch/risc-v/src/common/riscv_usestack.c      | 13 ++++
 arch/risc-v/src/rv32im/riscv_assert.c        | 19 +-----
 arch/risc-v/src/rv64gc/riscv_assert.c        | 19 +-----
 arch/{arm => x86}/include/tls.h              | 26 ++------
 arch/x86/src/i486/up_createstack.c           | 46 +++++++++++++++
 arch/x86/src/i486/up_usestack.c              | 19 +++++-
 arch/{arm => x86_64}/include/tls.h           | 28 ++-------
 arch/x86_64/src/intel64/up_createstack.c     | 46 +++++++++++++++
 arch/x86_64/src/intel64/up_usestack.c        | 13 ++++
 arch/{arm => xtensa}/include/tls.h           | 25 ++++----
 arch/xtensa/src/common/xtensa_createstack.c  | 46 +++++++++++++++
 arch/xtensa/src/common/xtensa_usestack.c     | 13 ++++
 arch/{arm => z16}/include/tls.h              | 32 ++--------
 arch/z16/src/common/z16_createstack.c        | 61 ++++++++++++++++++-
 arch/z16/src/common/z16_usestack.c           | 13 ++++
 arch/{arm => z80}/include/tls.h              | 32 ++--------
 arch/z80/src/common/z80_createstack.c        | 46 +++++++++++++++
 arch/z80/src/common/z80_usestack.c           | 13 ++++
 58 files changed, 1561 insertions(+), 408 deletions(-)
 create mode 100644 arch/avr/include/avr/arch.h
 create mode 100644 arch/avr/include/avr32/arch.h
 copy arch/{arm => avr}/include/tls.h (84%)
 copy arch/{arm => hc}/include/tls.h (89%)
 copy arch/{arm => mips}/include/tls.h (90%)
 copy arch/{arm => misoc}/include/tls.h (89%)
 copy arch/{arm => or1k}/include/tls.h (91%)
 create mode 100644 arch/renesas/include/m16c/arch.h
 create mode 100644 arch/renesas/include/rx65n/arch.h
 create mode 100644 arch/renesas/include/sh1/arch.h
 copy arch/{arm => renesas}/include/tls.h (84%)
 create mode 100644 arch/risc-v/include/rv32im/arch.h
 create mode 100644 arch/risc-v/include/rv64gc/arch.h
 copy arch/{arm => risc-v}/include/tls.h (84%)
 copy arch/{arm => x86}/include/tls.h (85%)
 copy arch/{arm => x86_64}/include/tls.h (84%)
 copy arch/{arm => xtensa}/include/tls.h (89%)
 copy arch/{arm => z16}/include/tls.h (81%)
 copy arch/{arm => z80}/include/tls.h (81%)


[incubator-nuttx] 04/04: Fix nxstyle complaints

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 6eb6d31c323acf57525beae79df1b010c900ae9f
Author: Ouss4 <ab...@gmail.com>
AuthorDate: Thu May 7 01:40:46 2020 +0100

    Fix nxstyle complaints
---
 arch/avr/include/avr/arch.h            |  1 +
 arch/avr/include/avr32/arch.h          |  1 +
 arch/hc/include/tls.h                  |  2 +-
 arch/misoc/include/tls.h               |  1 -
 arch/renesas/src/common/up_assert.c    |  1 -
 arch/renesas/src/m16c/m16c_dumpstate.c | 46 ++++++++++++++++++----------------
 arch/renesas/src/sh1/sh1_dumpstate.c   |  4 +--
 arch/risc-v/include/arch.h             |  3 ++-
 8 files changed, 32 insertions(+), 27 deletions(-)

diff --git a/arch/avr/include/avr/arch.h b/arch/avr/include/avr/arch.h
index d7c695a..5556add 100644
--- a/arch/avr/include/avr/arch.h
+++ b/arch/avr/include/avr/arch.h
@@ -59,6 +59,7 @@ static inline uint16_t avr_getsp(void)
     : "=r" (spl), "=r" (sph)
     :
   );
+
   return (uint16_t)sph << 8 | spl;
 }
 
diff --git a/arch/avr/include/avr32/arch.h b/arch/avr/include/avr32/arch.h
index c765730..3137bd7 100644
--- a/arch/avr/include/avr32/arch.h
+++ b/arch/avr/include/avr32/arch.h
@@ -56,6 +56,7 @@ static inline uint32_t avr_getsp(void)
       : "=r" (retval)
       :
     );
+
   return retval;
 }
 
diff --git a/arch/hc/include/tls.h b/arch/hc/include/tls.h
index e7cc678..a8a5bf6 100644
--- a/arch/hc/include/tls.h
+++ b/arch/hc/include/tls.h
@@ -46,7 +46,7 @@ static inline uint16_t hc_getsp(void)
   __asm__
   (
     "\tsts %0\n"
-	: "=m"(ret) :
+  : "=m"(ret) :
   );
   return ret;
 }
diff --git a/arch/misoc/include/tls.h b/arch/misoc/include/tls.h
index e8af51f..4b093ea 100644
--- a/arch/misoc/include/tls.h
+++ b/arch/misoc/include/tls.h
@@ -49,7 +49,6 @@ static inline uint32_t misoc_getsp(void)
   return sp;
 }
 
-
 /****************************************************************************
  * Name: up_tls_info
  *
diff --git a/arch/renesas/src/common/up_assert.c b/arch/renesas/src/common/up_assert.c
index 131782e..fd7086c 100644
--- a/arch/renesas/src/common/up_assert.c
+++ b/arch/renesas/src/common/up_assert.c
@@ -90,7 +90,6 @@ static void _up_assert(int errorcode)
 
   if (g_current_regs || running_task()->flink == NULL)
     {
-      up_irq_save();
       for (; ; )
         {
 #if CONFIG_BOARD_RESET_ON_ASSERT >= 1
diff --git a/arch/renesas/src/m16c/m16c_dumpstate.c b/arch/renesas/src/m16c/m16c_dumpstate.c
index 95186e0..f76e566 100644
--- a/arch/renesas/src/m16c/m16c_dumpstate.c
+++ b/arch/renesas/src/m16c/m16c_dumpstate.c
@@ -69,8 +69,8 @@ static uint8_t s_last_regs[XCPTCONTEXT_REGS];
 #if CONFIG_ARCH_INTERRUPTSTACK > 3
 static inline uint16_t m16c_getusersp(void)
 {
-  uint8_t *ptr = (uint8_t*) g_current_regs;
-  return (uint16_t)ptr[REG_SP] << 8 | ptr[REG_SP+1];
+  uint8_t *ptr = (uint8_t *) g_current_regs;
+  return (uint16_t)ptr[REG_SP] << 8 | ptr[REG_SP + 1];
 }
 #endif
 
@@ -84,9 +84,10 @@ static void m16c_stackdump(uint16_t sp, uint16_t stack_base)
 
   for (stack = sp & ~7; stack < stack_base; stack += 8)
     {
-      uint8_t *ptr = (uint8_t*)stack;
+      uint8_t *ptr = (uint8_t *)stack;
       _alert("%04x: %02x %02x %02x %02x %02x %02x %02x %02x\n",
-             stack, ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]);
+             stack, ptr[0], ptr[1], ptr[2], ptr[3], ptr[4],
+             ptr[5], ptr[6], ptr[7]);
     }
 }
 
@@ -96,7 +97,7 @@ static void m16c_stackdump(uint16_t sp, uint16_t stack_base)
 
 static inline void m16c_registerdump(void)
 {
-  uint8_t *ptr = (uint8_t*) g_current_regs;
+  uint8_t *ptr = (uint8_t *) g_current_regs;
 
   /* Are user registers available from interrupt processing? */
 
@@ -110,17 +111,19 @@ static inline void m16c_registerdump(void)
 
   /* Dump the interrupt registers */
 
-  _alert("PC: %02x%02x%02x FLG: %02x00%02x FB: %02x%02x SB: %02x%02x SP: %02x%02x\n",
-        ptr[REG_FLGPCHI] & 0xff, ptr[REG_PC], ptr[REG_PC+1],
+  _alert("PC: %02x%02x%02x FLG: %02x00%02x FB: %02x%02x SB: %02x%02x "
+         "SP: %02x%02x\n",
+        ptr[REG_FLGPCHI] & 0xff, ptr[REG_PC], ptr[REG_PC + 1],
         ptr[REG_FLGPCHI] >> 8, ptr[REG_FLG],
-        ptr[REG_FB], ptr[REG_FB+1],
-        ptr[REG_SB], ptr[REG_SB+1],
-        ptr[REG_SP], ptr[REG_SP+1]);
-
-  _alert("R0: %02x%02x R1: %02x%02x R2: %02x%02x A0: %02x%02x A1: %02x%02x\n",
-        ptr[REG_R0], ptr[REG_R0+1], ptr[REG_R1], ptr[REG_R1+1],
-        ptr[REG_R2], ptr[REG_R2+1], ptr[REG_R3], ptr[REG_R3+1],
-        ptr[REG_A0], ptr[REG_A0+1], ptr[REG_A1], ptr[REG_A1+1]);
+        ptr[REG_FB], ptr[REG_FB + 1],
+        ptr[REG_SB], ptr[REG_SB + 1],
+        ptr[REG_SP], ptr[REG_SP + 1]);
+
+  _alert("R0: %02x%02x R1: %02x%02x R2: %02x%02x A0: %02x%02x "
+         "A1: %02x%02x\n",
+        ptr[REG_R0], ptr[REG_R0 + 1], ptr[REG_R1], ptr[REG_R1 + 1],
+        ptr[REG_R2], ptr[REG_R2 + 1], ptr[REG_R3], ptr[REG_R3 + 1],
+        ptr[REG_A0], ptr[REG_A0 + 1], ptr[REG_A1], ptr[REG_A1 + 1]);
 }
 
 /****************************************************************************
@@ -159,13 +162,14 @@ void up_dumpstate(void)
       ustacksize = (uint16_t)rtcb->adj_stack_size;
     }
 
-  /* Get the limits on the interrupt stack memory. The near RAM memory map is as follows:
+  /* Get the limits on the interrupt stack memory.
+   * The near RAM memory map is as follows:
    *
-   * 0x00400 - DATA		Size: Determined by linker
-   *           BSS		Size: Determined by linker
-   *           Interrupt stack	Size: CONFIG_ARCH_INTERRUPTSTACK
-   *           Idle stack		Size: CONFIG_IDLETHREAD_STACKSIZE
-   *           Heap		Size: Everything remaining
+   * 0x00400 - DATA   Size: Determined by linker
+   *           BSS    Size: Determined by linker
+   *           Interrupt stack Size: CONFIG_ARCH_INTERRUPTSTACK
+   *           Idle stack  Size: CONFIG_IDLETHREAD_STACKSIZE
+   *           Heap        Size: Everything remaining
    * 0x00bff - (end+1)
    */
 
diff --git a/arch/renesas/src/sh1/sh1_dumpstate.c b/arch/renesas/src/sh1/sh1_dumpstate.c
index 973a987..1028202 100644
--- a/arch/renesas/src/sh1/sh1_dumpstate.c
+++ b/arch/renesas/src/sh1/sh1_dumpstate.c
@@ -71,7 +71,7 @@ static void sh1_stackdump(uint32_t sp, uint32_t stack_base)
 
   for (stack = sp & ~0x1f; stack < stack_base; stack += 32)
     {
-      uint32_t *ptr = (uint32_t*)stack;
+      uint32_t *ptr = (uint32_t *)stack;
       _alert("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
              stack, ptr[0], ptr[1], ptr[2], ptr[3],
              ptr[4], ptr[5], ptr[6], ptr[7]);
@@ -84,7 +84,7 @@ static void sh1_stackdump(uint32_t sp, uint32_t stack_base)
 
 static inline void sh1_registerdump(void)
 {
-  uint32_t *ptr = (uint32_t*)g_current_regs;
+  uint32_t *ptr = (uint32_t *)g_current_regs;
 
   /* Are user registers available from interrupt processing? */
 
diff --git a/arch/risc-v/include/arch.h b/arch/risc-v/include/arch.h
index f2c45b6..4dfaf02 100644
--- a/arch/risc-v/include/arch.h
+++ b/arch/risc-v/include/arch.h
@@ -111,7 +111,8 @@ uint32_t time_hard_mul(uint32_t a, uint32_t b, uint32_t *t);
 
 #ifdef __cplusplus
 #define EXTERN extern "C"
-extern "C" {
+extern "C"
+{
 #else
 #define EXTERN extern
 #endif


[incubator-nuttx] 01/04: arch/: Implement Thread Local Storage for the rest of the architectures. The change consisted on modifying *_usestack.c and *_createstack.c

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 1e3ec6ecd0072cbff7b3d72ad76efeaf5c992799
Author: Ouss4 <ab...@gmail.com>
AuthorDate: Wed May 6 00:45:16 2020 +0100

    arch/: Implement Thread Local Storage for the rest of the architectures.
    The change consisted on modifying *_usestack.c and *_createstack.c
---
 arch/arm/src/common/arm_usestack.c           |  2 +-
 arch/avr/src/avr/up_createstack.c            | 60 ++++++++++++++++++++++-
 arch/avr/src/avr/up_usestack.c               | 19 ++++++--
 arch/avr/src/avr32/up_createstack.c          | 46 ++++++++++++++++++
 arch/avr/src/avr32/up_usestack.c             | 15 +++++-
 arch/hc/src/common/up_createstack.c          | 46 ++++++++++++++++++
 arch/hc/src/common/up_usestack.c             | 16 ++++++-
 arch/mips/src/common/mips_createstack.c      | 54 ++++++++++++++++++++-
 arch/mips/src/common/mips_usestack.c         | 21 +++++++-
 arch/misoc/src/lm32/lm32_createstack.c       | 45 +++++++++++++++++
 arch/misoc/src/minerva/minerva_createstack.c | 50 ++++++++++++++++++-
 arch/or1k/src/common/up_createstack.c        |  8 ++--
 arch/renesas/src/common/up_createstack.c     | 46 ++++++++++++++++++
 arch/renesas/src/common/up_usestack.c        | 13 +++++
 arch/risc-v/src/common/riscv_createstack.c   | 72 ++++++++++++++++++++++++++--
 arch/risc-v/src/common/riscv_usestack.c      | 13 +++++
 arch/x86/src/i486/up_createstack.c           | 46 ++++++++++++++++++
 arch/x86/src/i486/up_usestack.c              | 19 ++++++--
 arch/x86_64/src/intel64/up_createstack.c     | 46 ++++++++++++++++++
 arch/x86_64/src/intel64/up_usestack.c        | 13 +++++
 arch/xtensa/src/common/xtensa_createstack.c  | 46 ++++++++++++++++++
 arch/xtensa/src/common/xtensa_usestack.c     | 13 +++++
 arch/z16/src/common/z16_createstack.c        | 61 ++++++++++++++++++++++-
 arch/z16/src/common/z16_usestack.c           | 13 +++++
 arch/z80/src/common/z80_createstack.c        | 46 ++++++++++++++++++
 arch/z80/src/common/z80_usestack.c           | 13 +++++
 26 files changed, 819 insertions(+), 23 deletions(-)

diff --git a/arch/arm/src/common/arm_usestack.c b/arch/arm/src/common/arm_usestack.c
index b5b2c67..7aee3e8 100644
--- a/arch/arm/src/common/arm_usestack.c
+++ b/arch/arm/src/common/arm_usestack.c
@@ -49,7 +49,7 @@
 
 /* Stack alignment macros */
 
-#define STACK_ALIGN_MASK    (CONFIG_STACK_ALIGNMENT-1)
+#define STACK_ALIGN_MASK    (CONFIG_STACK_ALIGNMENT - 1)
 #define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
 #define STACK_ALIGN_UP(a)   (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
 
diff --git a/arch/avr/src/avr/up_createstack.c b/arch/avr/src/avr/up_createstack.c
index d54b204..859cb42 100644
--- a/arch/avr/src/avr/up_createstack.c
+++ b/arch/avr/src/avr/up_createstack.c
@@ -49,6 +49,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 #include <arch/board/board.h>
 
 #include "up_arch.h"
@@ -100,6 +101,24 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
+#ifdef CONFIG_TLS
+  /* Add the size of the TLS information structure */
+
+  stack_size += sizeof(struct tls_info_s);
+
+#ifdef CONFIG_TLS_ALIGNED
+  /* The allocated stack size must not exceed the maximum possible for the
+   * TLS feature.
+   */
+
+  DEBUGASSERT(stack_size <= TLS_MAXSTACK);
+  if (stack_size >= TLS_MAXSTACK)
+    {
+      stack_size = TLS_MAXSTACK;
+    }
+#endif
+#endif
+
   /* Is there already a stack allocated of a different size?  Because of
    * alignment issues, stack_size might erroneously appear to be of a
    * different size.  Fortunately, this is not a critical operation.
@@ -118,9 +137,42 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
     {
       /* Allocate the stack.  If DEBUG is enabled (but not stack debug),
        * then create a zeroed stack to make stack dumps easier to trace.
+       * If TLS is enabled, then we must allocate aligned stacks.
        */
+#ifdef CONFIG_TLS_ALIGNED
+#ifdef CONFIG_MM_KERNEL_HEAP
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
 
-      tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+#else /* CONFIG_TLS_ALIGNED */
+#ifdef CONFIG_MM_KERNEL_HEAP
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+        }
+#endif /* CONFIG_TLS_ALIGNED */
 
 #ifdef CONFIG_DEBUG_FEATURES
       /* Was the allocation successful? */
@@ -160,6 +212,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
       tcb->adj_stack_ptr  = (FAR void *)top_of_stack;
       tcb->adj_stack_size = stack_size;
 
+#ifdef CONFIG_TLS
+      /* Initialize the TLS data structure */
+
+      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
 #if defined(ARCH_HAVE_LEDS)
       board_autoled_on(LED_STACKCREATED);
 #endif
diff --git a/arch/avr/src/avr/up_usestack.c b/arch/avr/src/avr/up_usestack.c
index 652e601..03d741d 100644
--- a/arch/avr/src/avr/up_usestack.c
+++ b/arch/avr/src/avr/up_usestack.c
@@ -47,6 +47,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 
 #include "up_internal.h"
 
@@ -94,6 +95,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 {
   size_t top_of_stack;
 
+#ifdef CONFIG_TLS_ALIGNED
+  /* Make certain that the user provided stack is properly aligned */
+
+  DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0);
+#endif
+
   /* Is there already a stack allocated? */
 
   if (tcb->stack_alloc_ptr)
@@ -112,11 +119,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    */
 
 #ifdef CONFIG_STACK_COLORATION
-   memset(tcb->stack_alloc_ptr, STACK_COLOR, stack_size);
+  memset(tcb->stack_alloc_ptr, STACK_COLOR, stack_size);
 #endif
 
-  /* The AVR uses a push-down stack:  the stack grows toward loweraddresses in
-   * memory.  The stack pointer register, points to the lowest, valid work
+  /* The AVR uses a push-down stack:  the stack grows toward loweraddresses
+   * in memory.  The stack pointer register, points to the lowest, valid work
    * address (the "top" of the stack).  Items on the stack are referenced as
    * positive word offsets from sp.
    */
@@ -128,5 +135,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   tcb->adj_stack_ptr  = (FAR void *)top_of_stack;
   tcb->adj_stack_size = stack_size;
 
+#ifdef CONFIG_TLS
+  /* Initialize the TLS data structure */
+
+  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
   return OK;
 }
diff --git a/arch/avr/src/avr32/up_createstack.c b/arch/avr/src/avr32/up_createstack.c
index bcfb348..8c6aba8 100644
--- a/arch/avr/src/avr32/up_createstack.c
+++ b/arch/avr/src/avr32/up_createstack.c
@@ -48,6 +48,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 #include <nuttx/board.h>
 #include <arch/board/board.h>
 
@@ -105,6 +106,24 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
+#ifdef CONFIG_TLS
+  /* Add the size of the TLS information structure */
+
+  stack_size += sizeof(struct tls_info_s);
+
+#ifdef CONFIG_TLS_ALIGNED
+  /* The allocated stack size must not exceed the maximum possible for the
+   * TLS feature.
+   */
+
+  DEBUGASSERT(stack_size <= TLS_MAXSTACK);
+  if (stack_size >= TLS_MAXSTACK)
+    {
+      stack_size = TLS_MAXSTACK;
+    }
+#endif
+#endif
+
   /* Is there already a stack allocated of a different size?  Because of
    * alignment issues, stack_size might erroneously appear to be of a
    * different size.  Fortunately, this is not a critical operation.
@@ -123,8 +142,28 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
     {
       /* Allocate the stack.  If DEBUG is enabled (but not stack debug),
        * then create a zeroed stack to make stack dumps easier to trace.
+       * If TLS is enabled, then we must allocate aligned stacks.
        */
 
+#ifdef CONFIG_TLS_ALIGNED
+#ifdef CONFIG_MM_KERNEL_HEAP
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+
+#else /* CONFIG_TLS_ALIGNED */
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
@@ -139,6 +178,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
           tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
         }
+#endif /* CONFIG_TLS_ALIGNED */
 
 #ifdef CONFIG_DEBUG_FEATURES
       /* Was the allocation successful? */
@@ -186,6 +226,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
       tcb->adj_stack_ptr  = (FAR void *)top_of_stack;
       tcb->adj_stack_size = size_of_stack;
 
+#ifdef CONFIG_TLS
+      /* Initialize the TLS data structure */
+
+      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/avr/src/avr32/up_usestack.c b/arch/avr/src/avr32/up_usestack.c
index 8557f72..8a4986c 100644
--- a/arch/avr/src/avr32/up_usestack.c
+++ b/arch/avr/src/avr32/up_usestack.c
@@ -46,6 +46,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 
 #include "up_internal.h"
 
@@ -94,6 +95,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   size_t top_of_stack;
   size_t size_of_stack;
 
+#ifdef CONFIG_TLS_ALIGNED
+  /* Make certain that the user provided stack is properly aligned */
+
+  DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0);
+#endif
+
   /* Is there already a stack allocated? */
 
   if (tcb->stack_alloc_ptr)
@@ -112,7 +119,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    */
 
 #ifdef CONFIG_STACK_COLORATION
-   memset(tcb->stack_alloc_ptr, STACK_COLOR, stack_size);
+  memset(tcb->stack_alloc_ptr, STACK_COLOR, stack_size);
 #endif
 
   /* The AVR32 uses a push-down stack:  the stack grows
@@ -137,5 +144,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   tcb->adj_stack_ptr  = (FAR void *)top_of_stack;
   tcb->adj_stack_size = size_of_stack;
 
+#ifdef CONFIG_TLS
+  /* Initialize the TLS data structure */
+
+  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
   return OK;
 }
diff --git a/arch/hc/src/common/up_createstack.c b/arch/hc/src/common/up_createstack.c
index e0948f9..5496859 100644
--- a/arch/hc/src/common/up_createstack.c
+++ b/arch/hc/src/common/up_createstack.c
@@ -46,6 +46,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 #include <nuttx/board.h>
 
 #include "up_arch.h"
@@ -102,6 +103,24 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
+#ifdef CONFIG_TLS
+  /* Add the size of the TLS information structure */
+
+  stack_size += sizeof(struct tls_info_s);
+
+#ifdef CONFIG_TLS_ALIGNED
+  /* The allocated stack size must not exceed the maximum possible for the
+   * TLS feature.
+   */
+
+  DEBUGASSERT(stack_size <= TLS_MAXSTACK);
+  if (stack_size >= TLS_MAXSTACK)
+    {
+      stack_size = TLS_MAXSTACK;
+    }
+#endif
+#endif
+
   /* Is there already a stack allocated of a different size?  Because of
    * alignment issues, stack_size might erroneously appear to be of a
    * different size.  Fortunately, this is not a critical operation.
@@ -120,8 +139,28 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
     {
       /* Allocate the stack.  If DEBUG is enabled (but not stack debug),
        * then create a zeroed stack to make stack dumps easier to trace.
+       * If TLS is enabled, then we must allocate aligned stacks.
        */
 
+#ifdef CONFIG_TLS_ALIGNED
+#ifdef CONFIG_MM_KERNEL_HEAP
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+
+#else /* CONFIG_TLS_ALIGNED */
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
@@ -136,6 +175,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
           tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
         }
+#endif /* CONFIG_TLS_ALIGNED */
 
 #ifdef CONFIG_DEBUG_FEATURES
       /* Was the allocation successful? */
@@ -185,6 +225,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
       tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
       tcb->adj_stack_size = size_of_stack;
 
+#ifdef CONFIG_TLS
+      /* Initialize the TLS data structure */
+
+      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/hc/src/common/up_usestack.c b/arch/hc/src/common/up_usestack.c
index 4ecf535..d3d5836 100644
--- a/arch/hc/src/common/up_usestack.c
+++ b/arch/hc/src/common/up_usestack.c
@@ -45,6 +45,7 @@
 #include <debug.h>
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 
 #include "up_internal.h"
 
@@ -93,6 +94,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   size_t top_of_stack;
   size_t size_of_stack;
 
+#ifdef CONFIG_TLS_ALIGNED
+  /* Make certain that the user provided stack is properly aligned */
+
+  DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0);
+#endif
+
   /* Is there already a stack allocated? */
 
   if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size)
@@ -125,7 +132,14 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_ptr  = (uint32_t*)top_of_stack;
+  tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
   tcb->adj_stack_size = size_of_stack;
+
+#ifdef CONFIG_TLS
+  /* Initialize the TLS data structure */
+
+  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
   return OK;
 }
diff --git a/arch/mips/src/common/mips_createstack.c b/arch/mips/src/common/mips_createstack.c
index 1e1ba28..bc57aba 100644
--- a/arch/mips/src/common/mips_createstack.c
+++ b/arch/mips/src/common/mips_createstack.c
@@ -46,6 +46,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 #include <nuttx/board.h>
 #include <arch/board/board.h>
 
@@ -123,6 +124,24 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
+#ifdef CONFIG_TLS
+  /* Add the size of the TLS information structure */
+
+  stack_size += sizeof(struct tls_info_s);
+
+#ifdef CONFIG_TLS_ALIGNED
+  /* The allocated stack size must not exceed the maximum possible for the
+   * TLS feature.
+   */
+
+  DEBUGASSERT(stack_size <= TLS_MAXSTACK);
+  if (stack_size >= TLS_MAXSTACK)
+    {
+      stack_size = TLS_MAXSTACK;
+    }
+#endif
+#endif
+
   /* Is there already a stack allocated of a different size?  Because of
    * alignment issues, stack_size might erroneously appear to be of a
    * different size.  Fortunately, this is not a critical operation.
@@ -143,6 +162,25 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        * then create a zeroed stack to make stack dumps easier to trace.
        */
 
+#ifdef CONFIG_TLS_ALIGNED
+#ifdef CONFIG_MM_KERNEL_HEAP
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+
+#else /* CONFIG_TLS_ALIGNED */
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
@@ -157,6 +195,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
           tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
         }
+#endif /* CONFIG_TLS_ALIGNED */
 
 #ifdef CONFIG_DEBUG_FEATURES
       /* Was the allocation successful? */
@@ -199,13 +238,26 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        */
 
       top_of_stack = STACK_ALIGN_DOWN(top_of_stack);
+
+      /* The size of the stack in bytes is then the difference between
+       * the top and the bottom of the stack (+4 because if the top
+       * is the same as the bottom, then the size is one 32-bit element).
+       * The size need not be aligned.
+       */
+
       size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4;
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->adj_stack_ptr  = (FAR uint32_t *)top_of_stack;
+      tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
       tcb->adj_stack_size = size_of_stack;
 
+#ifdef CONFIG_TLS
+      /* Initialize the TLS data structure */
+
+      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/mips/src/common/mips_usestack.c b/arch/mips/src/common/mips_usestack.c
index fcfd184..dc52292 100644
--- a/arch/mips/src/common/mips_usestack.c
+++ b/arch/mips/src/common/mips_usestack.c
@@ -65,7 +65,7 @@
 
 /* Stack alignment macros */
 
-#define STACK_ALIGN_MASK    (STACK_ALIGNMENT-1)
+#define STACK_ALIGN_MASK    (STACK_ALIGNMENT - 1)
 #define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
 #define STACK_ALIGN_UP(a)   (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
 
@@ -114,6 +114,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   size_t top_of_stack;
   size_t size_of_stack;
 
+#ifdef CONFIG_TLS_ALIGNED
+  /* Make certain that the user provided stack is properly aligned */
+
+  DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0);
+#endif
+
   /* Is there already a stack allocated? */
 
   if (tcb->stack_alloc_ptr)
@@ -141,6 +147,13 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    */
 
   top_of_stack = STACK_ALIGN_DOWN(top_of_stack);
+
+  /* The size of the stack in bytes is then the difference between
+   * the top and the bottom of the stack (+4 because if the top
+   * is the same as the bottom, then the size is one 32-bit element).
+   * The size need not be aligned.
+   */
+
   size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4;
 
   /* Save the adjusted stack values in the struct tcb_s */
@@ -148,5 +161,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
   tcb->adj_stack_size = size_of_stack;
 
+#ifdef CONFIG_TLS
+  /* Initialize the TLS data structure */
+
+  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
   return OK;
 }
diff --git a/arch/misoc/src/lm32/lm32_createstack.c b/arch/misoc/src/lm32/lm32_createstack.c
index 12da119..6071440 100644
--- a/arch/misoc/src/lm32/lm32_createstack.c
+++ b/arch/misoc/src/lm32/lm32_createstack.c
@@ -47,6 +47,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 #include <nuttx/board.h>
 #include <arch/board/board.h>
 
@@ -123,6 +124,24 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
+#ifdef CONFIG_TLS
+  /* Add the size of the TLS information structure */
+
+  stack_size += sizeof(struct tls_info_s);
+
+#ifdef CONFIG_TLS_ALIGNED
+  /* The allocated stack size must not exceed the maximum possible for the
+   * TLS feature.
+   */
+
+  DEBUGASSERT(stack_size <= TLS_MAXSTACK);
+  if (stack_size >= TLS_MAXSTACK)
+    {
+      stack_size = TLS_MAXSTACK;
+    }
+#endif
+#endif
+
   /* Is there already a stack allocated of a different size?  Because of
    * alignment issues, stack_size might erroneously appear to be of a
    * different size.  Fortunately, this is not a critical operation.
@@ -143,6 +162,25 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        * then create a zeroed stack to make stack dumps easier to trace.
        */
 
+#ifdef CONFIG_TLS_ALIGNED
+#ifdef CONFIG_MM_KERNEL_HEAP
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+
+#else /* CONFIG_TLS_ALIGNED */
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
@@ -157,6 +195,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
           tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
         }
+#endif /* CONFIG_TLS_ALIGNED */
 
 #ifdef CONFIG_DEBUG_FEATURES
       /* Was the allocation successful? */
@@ -206,6 +245,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
       tcb->adj_stack_ptr  = (FAR uint32_t *)top_of_stack;
       tcb->adj_stack_size = size_of_stack;
 
+#ifdef CONFIG_TLS
+      /* Initialize the TLS data structure */
+
+      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/misoc/src/minerva/minerva_createstack.c b/arch/misoc/src/minerva/minerva_createstack.c
index c9d26ad..b493de1 100644
--- a/arch/misoc/src/minerva/minerva_createstack.c
+++ b/arch/misoc/src/minerva/minerva_createstack.c
@@ -47,6 +47,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 #include <nuttx/board.h>
 #include <arch/board/board.h>
 
@@ -115,6 +116,24 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
+#ifdef CONFIG_TLS
+  /* Add the size of the TLS information structure */
+
+  stack_size += sizeof(struct tls_info_s);
+
+#ifdef CONFIG_TLS_ALIGNED
+  /* The allocated stack size must not exceed the maximum possible for the
+   * TLS feature.
+   */
+
+  DEBUGASSERT(stack_size <= TLS_MAXSTACK);
+  if (stack_size >= TLS_MAXSTACK)
+    {
+      stack_size = TLS_MAXSTACK;
+    }
+#endif
+#endif
+
   /* Is there already a stack allocated of a different size? Because of
    * alignment issues, stack_size might erroneously appear to be of a
    * different size.  Fortunately, this is not a critical operation.
@@ -133,23 +152,44 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
     {
       /* Allocate the stack.  If DEBUG is enabled (but not stack debug), then
        * create a zeroed stack to make stack dumps easier to trace.
+       * If TLS is enabled, then we must allocate aligned stacks.
        */
 
+#ifdef CONFIG_TLS_ALIGNED
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr = (uint32_t *) kmm_malloc(stack_size);
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr = (uint32_t *) kumm_malloc(stack_size);
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
         }
 
+#else /* CONFIG_TLS_ALIGNED */
+#ifdef CONFIG_MM_KERNEL_HEAP
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+        }
+#endif /* CONFIG_TLS_ALIGNED */
+
 #ifdef CONFIG_DEBUG_FEATURES
       /* Was the allocation successful? */
 
@@ -198,6 +238,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
       tcb->adj_stack_ptr = (FAR uint32_t *) top_of_stack;
       tcb->adj_stack_size = size_of_stack;
 
+#ifdef CONFIG_TLS
+      /* Initialize the TLS data structure */
+
+      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/or1k/src/common/up_createstack.c b/arch/or1k/src/common/up_createstack.c
index 78cfee2..ffa8d80 100644
--- a/arch/or1k/src/common/up_createstack.c
+++ b/arch/or1k/src/common/up_createstack.c
@@ -122,6 +122,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
   stack_size += sizeof(struct tls_info_s);
 
+#ifdef CONFIG_TLS_ALIGNED
   /* The allocated stack size must not exceed the maximum possible for the
    * TLS feature.
    */
@@ -132,6 +133,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
       stack_size = TLS_MAXSTACK;
     }
 #endif
+#endif
 
   /* Is there already a stack allocated of a different size?  Because of
    * alignment issues, stack_size might erroneously appear to be of a
@@ -154,7 +156,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        * If TLS is enabled, then we must allocate aligned stacks.
        */
 
-#ifdef CONFIG_TLS
+#ifdef CONFIG_TLS_ALIGNED
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
@@ -172,7 +174,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
             (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
         }
 
-#else /* CONFIG_TLS */
+#else /* CONFIG_TLS_ALIGNED */
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
@@ -187,7 +189,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
           tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
         }
-#endif /* CONFIG_TLS */
+#endif /* CONFIG_TLS_ALIGNED */
 
 #ifdef CONFIG_DEBUG_FEATURES
       /* Was the allocation successful? */
diff --git a/arch/renesas/src/common/up_createstack.c b/arch/renesas/src/common/up_createstack.c
index bb6b974..88e6720 100644
--- a/arch/renesas/src/common/up_createstack.c
+++ b/arch/renesas/src/common/up_createstack.c
@@ -46,6 +46,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 #include <nuttx/board.h>
 
 #include "up_arch.h"
@@ -102,6 +103,24 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
+#ifdef CONFIG_TLS
+  /* Add the size of the TLS information structure */
+
+  stack_size += sizeof(struct tls_info_s);
+
+#ifdef CONFIG_TLS_ALIGNED
+  /* The allocated stack size must not exceed the maximum possible for the
+   * TLS feature.
+   */
+
+  DEBUGASSERT(stack_size <= TLS_MAXSTACK);
+  if (stack_size >= TLS_MAXSTACK)
+    {
+      stack_size = TLS_MAXSTACK;
+    }
+#endif
+#endif
+
   /* Is there already a stack allocated of a different size?  Because of
    * alignment issues, stack_size might erroneously appear to be of a
    * different size.  Fortunately, this is not a critical operation.
@@ -120,8 +139,28 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
     {
       /* Allocate the stack.  If DEBUG is enabled (but not stack debug),
        * then create a zeroed stack to make stack dumps easier to trace.
+       * If TLS is enabled, then we must allocate aligned stacks.
        */
 
+#ifdef CONFIG_TLS_ALIGNED
+#ifdef CONFIG_MM_KERNEL_HEAP
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+
+#else /* CONFIG_TLS_ALIGNED */
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
@@ -136,6 +175,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
           tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
         }
+#endif /* CONFIG_TLS_ALIGNED */
 
 #ifdef CONFIG_DEBUG_FEATURES
       /* Was the allocation successful? */
@@ -185,6 +225,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
       tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
       tcb->adj_stack_size = size_of_stack;
 
+#ifdef CONFIG_TLS
+      /* Initialize the TLS data structure */
+
+      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/renesas/src/common/up_usestack.c b/arch/renesas/src/common/up_usestack.c
index c089e54..f7525e8 100644
--- a/arch/renesas/src/common/up_usestack.c
+++ b/arch/renesas/src/common/up_usestack.c
@@ -46,6 +46,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 
 #include "up_internal.h"
 
@@ -94,6 +95,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   size_t top_of_stack;
   size_t size_of_stack;
 
+#ifdef CONFIG_TLS_ALIGNED
+  /* Make certain that the user provided stack is properly aligned */
+
+  DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0);
+#endif
+
   /* Is there already a stack allocated? */
 
   if (tcb->stack_alloc_ptr)
@@ -127,5 +134,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   tcb->adj_stack_ptr = top_of_stack;
   tcb->adj_stack_size = size_of_stack;
 
+#ifdef CONFIG_TLS
+  /* Initialize the TLS data structure */
+
+  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
   return OK;
 }
diff --git a/arch/risc-v/src/common/riscv_createstack.c b/arch/risc-v/src/common/riscv_createstack.c
index da674e5..449fec6 100644
--- a/arch/risc-v/src/common/riscv_createstack.c
+++ b/arch/risc-v/src/common/riscv_createstack.c
@@ -46,6 +46,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 #include <nuttx/board.h>
 #include <arch/board/board.h>
 
@@ -123,6 +124,24 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
+#ifdef CONFIG_TLS
+  /* Add the size of the TLS information structure */
+
+  stack_size += sizeof(struct tls_info_s);
+
+#ifdef CONFIG_TLS_ALIGNED
+  /* The allocated stack size must not exceed the maximum possible for the
+   * TLS feature.
+   */
+
+  DEBUGASSERT(stack_size <= TLS_MAXSTACK);
+  if (stack_size >= TLS_MAXSTACK)
+    {
+      stack_size = TLS_MAXSTACK;
+    }
+#endif
+#endif
+
   /* Is there already a stack allocated of a different size?  Because of
    * alignment issues, stack_size might erroneously appear to be of a
    * different size.  Fortunately, this is not a critical operation.
@@ -141,8 +160,28 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
     {
       /* Allocate the stack.  If DEBUG is enabled (but not stack debug),
        * then create a zeroed stack to make stack dumps easier to trace.
+       * If TLS is enabled, then we must allocate aligned stacks.
        */
 
+#ifdef CONFIG_TLS_ALIGNED
+#ifdef CONFIG_MM_KERNEL_HEAP
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+
+#else /* CONFIG_TLS_ALIGNED */
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
@@ -157,6 +196,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
           tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
         }
+#endif /* CONFIG_TLS_ALIGNED */
 
 #ifdef CONFIG_DEBUG_FEATURES
       /* Was the allocation successful? */
@@ -172,10 +212,13 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
   if (tcb->stack_alloc_ptr)
     {
+#if defined(CONFIG_TLS) && defined(CONFIG_STACK_COLORATION)
+      uintptr_t stack_base;
+#endif
       size_t top_of_stack;
       size_t size_of_stack;
 
-      /* MIPS uses a push-down stack:  the stack grows toward lower
+      /* RISCV uses a push-down stack:  the stack grows toward lower
        * addresses in memory.  The stack pointer register points to the
        * lowest, valid working address (the "top" of the stack).  Items on
        * the stack are referenced as positive word offsets from sp.
@@ -197,13 +240,32 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
       tcb->adj_stack_ptr  = (FAR uint32_t *)top_of_stack;
       tcb->adj_stack_size = size_of_stack;
 
-      /* Yes.. If stack debug is enabled, then fill the stack with a
+#ifdef CONFIG_TLS
+      /* Initialize the TLS data structure */
+
+      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+
+#ifdef CONFIG_STACK_COLORATION
+      /* If stack debug is enabled, then fill the stack with a
        * recognizable value that we can use later to test for high
        * water marks.
        */
 
+      stack_base = (uintptr_t)tcb->stack_alloc_ptr +
+                   sizeof(struct tls_info_s);
+      stack_size = tcb->adj_stack_size -
+                   sizeof(struct tls_info_s);
+      riscv_stack_color((FAR void *)stack_base, stack_size);
+
+#endif /* CONFIG_STACK_COLORATION */
+#else /* CONFIG_TLS */
 #ifdef CONFIG_STACK_COLORATION
-      up_stack_color(tcb->stack_alloc_ptr, tcb->adj_stack_size);
+      /* If stack debug is enabled, then fill the stack with a
+       * recognizable value that we can use later to test for high
+       * water marks.
+       */
+
+      riscv_stack_color(tcb->stack_alloc_ptr, tcb->adj_stack_size);
 #endif
 
       board_autoled_on(LED_STACKCREATED);
@@ -214,7 +276,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 }
 
 /****************************************************************************
- * Name: up_stack_color
+ * Name: riscv_stack_color
  *
  * Description:
  *   Write a well know value into the stack
@@ -222,7 +284,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
  ****************************************************************************/
 
 #ifdef CONFIG_STACK_COLORATION
-void up_stack_color(FAR void *stackbase, size_t nbytes)
+void riscv_stack_color(FAR void *stackbase, size_t nbytes)
 {
   /* Take extra care that we do not write outsize the stack boundaries */
 
diff --git a/arch/risc-v/src/common/riscv_usestack.c b/arch/risc-v/src/common/riscv_usestack.c
index ec033a2..8da809d 100644
--- a/arch/risc-v/src/common/riscv_usestack.c
+++ b/arch/risc-v/src/common/riscv_usestack.c
@@ -46,6 +46,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 
 #include "riscv_internal.h"
 
@@ -114,6 +115,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   size_t top_of_stack;
   size_t size_of_stack;
 
+#ifdef CONFIG_TLS_ALIGNED
+  /* Make certain that the user provided stack is properly aligned */
+
+  DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0);
+#endif
+
   /* Is there already a stack allocated? */
 
   if (tcb->stack_alloc_ptr)
@@ -148,5 +155,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   tcb->adj_stack_ptr  = (uintptr_t *)top_of_stack;
   tcb->adj_stack_size = size_of_stack;
 
+#ifdef CONFIG_TLS
+  /* Initialize the TLS data structure */
+
+  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
   return OK;
 }
diff --git a/arch/x86/src/i486/up_createstack.c b/arch/x86/src/i486/up_createstack.c
index 20b6486..7e9a308 100644
--- a/arch/x86/src/i486/up_createstack.c
+++ b/arch/x86/src/i486/up_createstack.c
@@ -47,6 +47,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 #include <nuttx/board.h>
 #include <arch/board/board.h>
 
@@ -104,6 +105,24 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
+#ifdef CONFIG_TLS
+  /* Add the size of the TLS information structure */
+
+  stack_size += sizeof(struct tls_info_s);
+
+#ifdef CONFIG_TLS_ALIGNED
+  /* The allocated stack size must not exceed the maximum possible for the
+   * TLS feature.
+   */
+
+  DEBUGASSERT(stack_size <= TLS_MAXSTACK);
+  if (stack_size >= TLS_MAXSTACK)
+    {
+      stack_size = TLS_MAXSTACK;
+    }
+#endif
+#endif
+
   /* Is there already a stack allocated of a different size?  Because of
    * alignment issues, stack_size might erroneously appear to be of a
    * different size.  Fortunately, this is not a critical operation.
@@ -122,8 +141,28 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
     {
       /* Allocate the stack.  If DEBUG is enabled (but not stack debug),
        * then create a zeroed stack to make stack dumps easier to trace.
+       * If TLS is enabled, then we must allocate aligned stacks.
        */
 
+#ifdef CONFIG_TLS_ALIGNED
+#ifdef CONFIG_MM_KERNEL_HEAP
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+
+#else /* CONFIG_TLS_ALIGNED */
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
@@ -138,6 +177,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
           tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
         }
+#endif /* CONFIG_TLS_ALIGNED */
 
 #ifdef CONFIG_DEBUG_FEATURES
       /* Was the allocation successful? */
@@ -185,6 +225,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
       tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
       tcb->adj_stack_size = size_of_stack;
 
+#ifdef CONFIG_TLS
+      /* Initialize the TLS data structure */
+
+      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/x86/src/i486/up_usestack.c b/arch/x86/src/i486/up_usestack.c
index 59221be..347d48c 100644
--- a/arch/x86/src/i486/up_usestack.c
+++ b/arch/x86/src/i486/up_usestack.c
@@ -46,6 +46,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 
 #include "up_internal.h"
 
@@ -94,6 +95,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   size_t top_of_stack;
   size_t size_of_stack;
 
+#ifdef CONFIG_TLS_ALIGNED
+  /* Make certain that the user provided stack is properly aligned */
+
+  DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0);
+#endif
+
   /* Is there already a stack allocated? */
 
   if (tcb->stack_alloc_ptr)
@@ -107,8 +114,8 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 
   tcb->stack_alloc_ptr = stack;
 
-  /* The i486 uses a push-down stack:  the stack grows toward loweraddresses in
-   * memory.  The stack pointer register, points to the lowest, valid work
+  /* The i486 uses a push-down stack:  the stack grows toward loweraddresses
+   * in memory.  The stack pointer register, points to the lowest, valid work
    * address (the "top" of the stack).  Items on the stack are referenced as
    * positive word offsets from sp.
    */
@@ -124,8 +131,14 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_ptr  = (uint32_t*)top_of_stack;
+  tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
   tcb->adj_stack_size = size_of_stack;
 
+#ifdef CONFIG_TLS
+  /* Initialize the TLS data structure */
+
+  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
   return OK;
 }
diff --git a/arch/x86_64/src/intel64/up_createstack.c b/arch/x86_64/src/intel64/up_createstack.c
index 10e2b08..4d23d8f 100644
--- a/arch/x86_64/src/intel64/up_createstack.c
+++ b/arch/x86_64/src/intel64/up_createstack.c
@@ -32,6 +32,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 #include <nuttx/board.h>
 #include <arch/board/board.h>
 
@@ -89,6 +90,24 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
+#ifdef CONFIG_TLS
+  /* Add the size of the TLS information structure */
+
+  stack_size += sizeof(struct tls_info_s);
+
+#ifdef CONFIG_TLS_ALIGNED
+  /* The allocated stack size must not exceed the maximum possible for the
+   * TLS feature.
+   */
+
+  DEBUGASSERT(stack_size <= TLS_MAXSTACK);
+  if (stack_size >= TLS_MAXSTACK)
+    {
+      stack_size = TLS_MAXSTACK;
+    }
+#endif
+#endif
+
   /* Is there already a stack allocated of a different size?  Because of
    * alignment issues, stack_size might erroneously appear to be of a
    * different size.  Fortunately, this is not a critical operation.
@@ -107,8 +126,28 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
     {
       /* Allocate the stack.  If DEBUG is enabled (but not stack debug),
        * then create a zeroed stack to make stack dumps easier to trace.
+       * If TLS is enabled, then we must allocate aligned stacks.
        */
 
+#ifdef CONFIG_TLS_ALIGNED
+#ifdef CONFIG_MM_KERNEL_HEAP
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+
+#else /* CONFIG_TLS_ALIGNED */
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
@@ -123,6 +162,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
           tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
         }
+#endif /* CONFIG_TLS_ALIGNED */
 
 #ifdef CONFIG_DEBUG_FEATURES
       /* Was the allocation successful? */
@@ -173,6 +213,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
       tcb->adj_stack_ptr  = (uint64_t *)top_of_stack;
       tcb->adj_stack_size = size_of_stack;
 
+#ifdef CONFIG_TLS
+      /* Initialize the TLS data structure */
+
+      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/x86_64/src/intel64/up_usestack.c b/arch/x86_64/src/intel64/up_usestack.c
index 30e022c..dd5720f 100644
--- a/arch/x86_64/src/intel64/up_usestack.c
+++ b/arch/x86_64/src/intel64/up_usestack.c
@@ -31,6 +31,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 
 #include "up_internal.h"
 
@@ -79,6 +80,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   size_t top_of_stack;
   size_t size_of_stack;
 
+#ifdef CONFIG_TLS_ALIGNED
+  /* Make certain that the user provided stack is properly aligned */
+
+  DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0);
+#endif
+
   /* Is there already a stack allocated? */
 
   if (tcb->stack_alloc_ptr)
@@ -115,5 +122,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   tcb->adj_stack_ptr  = (uint64_t *)top_of_stack;
   tcb->adj_stack_size = size_of_stack;
 
+#ifdef CONFIG_TLS
+  /* Initialize the TLS data structure */
+
+  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
   return OK;
 }
diff --git a/arch/xtensa/src/common/xtensa_createstack.c b/arch/xtensa/src/common/xtensa_createstack.c
index b96633d..1166272 100644
--- a/arch/xtensa/src/common/xtensa_createstack.c
+++ b/arch/xtensa/src/common/xtensa_createstack.c
@@ -46,6 +46,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 #include <nuttx/board.h>
 
 #include <arch/xtensa/xtensa_coproc.h>
@@ -120,6 +121,24 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
   uintptr_t cpstart;
 #endif
 
+#ifdef CONFIG_TLS
+  /* Add the size of the TLS information structure */
+
+  stack_size += sizeof(struct tls_info_s);
+
+#ifdef CONFIG_TLS_ALIGNED
+  /* The allocated stack size must not exceed the maximum possible for the
+   * TLS feature.
+   */
+
+  DEBUGASSERT(stack_size <= TLS_MAXSTACK);
+  if (stack_size >= TLS_MAXSTACK)
+    {
+      stack_size = TLS_MAXSTACK;
+    }
+#endif
+#endif
+
   /* Is there already a stack allocated of a different size?  Because of
    * alignment issues, stack_size might erroneously appear to be of a
    * different size.  Fortunately, this is not a critical operation.
@@ -148,8 +167,28 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
     {
       /* Allocate the stack.  If DEBUG is enabled (but not stack debug),
        * then create a zeroed stack to make stack dumps easier to trace.
+       * If TLS is enabled, then we must allocate aligned stacks.
        */
 
+#ifdef CONFIG_TLS_ALIGNED
+#ifdef CONFIG_MM_KERNEL_HEAP
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+
+#else /* CONFIG_TLS_ALIGNED */
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
@@ -164,6 +203,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
           tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
         }
+#endif /* CONFIG_TLS_ALIGNED */
 
 #ifdef CONFIG_DEBUG_FEATURES
       /* Was the allocation successful? */
@@ -247,6 +287,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
       tcb->adj_stack_ptr  = (FAR uint32_t *)top_of_stack;
       tcb->adj_stack_size = size_of_stack;
 
+#ifdef CONFIG_TLS
+      /* Initialize the TLS data structure */
+
+      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/xtensa/src/common/xtensa_usestack.c b/arch/xtensa/src/common/xtensa_usestack.c
index dfcfeb0..71fa7ba 100644
--- a/arch/xtensa/src/common/xtensa_usestack.c
+++ b/arch/xtensa/src/common/xtensa_usestack.c
@@ -46,6 +46,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 
 #include "xtensa.h"
 
@@ -106,6 +107,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   size_t top_of_stack;
   size_t size_of_stack;
 
+#ifdef CONFIG_TLS_ALIGNED
+  /* Make certain that the user provided stack is properly aligned */
+
+  DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0);
+#endif
+
   /* Is there already a stack allocated? */
 
   if (tcb->stack_alloc_ptr)
@@ -140,5 +147,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
   tcb->adj_stack_size = size_of_stack;
 
+#ifdef CONFIG_TLS
+  /* Initialize the TLS data structure */
+
+  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
   return OK;
 }
diff --git a/arch/z16/src/common/z16_createstack.c b/arch/z16/src/common/z16_createstack.c
index 6420cb0..e77edec 100644
--- a/arch/z16/src/common/z16_createstack.c
+++ b/arch/z16/src/common/z16_createstack.c
@@ -31,6 +31,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 #include <nuttx/board.h>
 #include <arch/board/board.h>
 
@@ -83,6 +84,24 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
+#ifdef CONFIG_TLS
+  /* Add the size of the TLS information structure */
+
+  stack_size += sizeof(struct tls_info_s);
+
+#ifdef CONFIG_TLS_ALIGNED
+  /* The allocated stack size must not exceed the maximum possible for the
+   * TLS feature.
+   */
+
+  DEBUGASSERT(stack_size <= TLS_MAXSTACK);
+  if (stack_size >= TLS_MAXSTACK)
+    {
+      stack_size = TLS_MAXSTACK;
+    }
+#endif
+#endif
+
   /* Is there already a stack allocated of a different size?  Because of
    * alignment issues, stack_size might erroneously appear to be of a
    * different size.  Fortunately, this is not a critical operation.
@@ -101,9 +120,43 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
     {
       /* Allocate the stack.  If DEBUG is enabled (but not stack debug),
        * then create a zeroed stack to make stack dumps easier to trace.
+       * If TLS is enabled, then we must allocate aligned stacks.
        */
 
-      tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+#ifdef CONFIG_TLS_ALIGNED
+#ifdef CONFIG_MM_KERNEL_HEAP
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+
+#else /* CONFIG_TLS_ALIGNED */
+#ifdef CONFIG_MM_KERNEL_HEAP
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+        }
+#endif /* CONFIG_TLS_ALIGNED */
 
 #ifdef CONFIG_DEBUG_FEATURES
       /* Was the allocation successful? */
@@ -151,6 +204,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
       tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
       tcb->adj_stack_size = size_of_stack;
 
+#ifdef CONFIG_TLS
+      /* Initialize the TLS data structure */
+
+      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/z16/src/common/z16_usestack.c b/arch/z16/src/common/z16_usestack.c
index 3971f6f..3ced8aa 100644
--- a/arch/z16/src/common/z16_usestack.c
+++ b/arch/z16/src/common/z16_usestack.c
@@ -31,6 +31,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 
 #include "z16_internal.h"
 
@@ -79,6 +80,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   size_t top_of_stack;
   size_t size_of_stack;
 
+#ifdef CONFIG_TLS_ALIGNED
+  /* Make certain that the user provided stack is properly aligned */
+
+  DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0);
+#endif
+
   /* Is there already a stack allocated? */
 
   if (tcb->stack_alloc_ptr)
@@ -112,5 +119,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   tcb->adj_stack_size = top_of_stack;
   tcb->adj_stack_size = size_of_stack;
 
+#ifdef CONFIG_TLS
+  /* Initialize the TLS data structure */
+
+  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
   return OK;
 }
diff --git a/arch/z80/src/common/z80_createstack.c b/arch/z80/src/common/z80_createstack.c
index ba557e8..59ab44d 100644
--- a/arch/z80/src/common/z80_createstack.c
+++ b/arch/z80/src/common/z80_createstack.c
@@ -31,6 +31,7 @@
 
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 #include <nuttx/board.h>
 
 #include "z80_arch.h"
@@ -87,6 +88,24 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
+#ifdef CONFIG_TLS
+  /* Add the size of the TLS information structure */
+
+  stack_size += sizeof(struct tls_info_s);
+
+#ifdef CONFIG_TLS_ALIGNED
+  /* The allocated stack size must not exceed the maximum possible for the
+   * TLS feature.
+   */
+
+  DEBUGASSERT(stack_size <= TLS_MAXSTACK);
+  if (stack_size >= TLS_MAXSTACK)
+    {
+      stack_size = TLS_MAXSTACK;
+    }
+#endif
+#endif
+
   /* Is there already a stack allocated of a different size?  Because of
    * alignment issues, stack_size might erroneously appear to be of a
    * different size.  Fortunately, this is not a critical operation.
@@ -105,8 +124,28 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
     {
       /* Allocate the stack.  If DEBUG is enabled (but not stack debug),
        * then create a zeroed stack to make stack dumps easier to trace.
+       * If TLS is enabled, then we must allocate aligned stacks.
        */
 
+#ifdef CONFIG_TLS_ALIGNED
+#ifdef CONFIG_MM_KERNEL_HEAP
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          tcb->stack_alloc_ptr =
+            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+        }
+
+#else /* CONFIG_TLS_ALIGNED */
 #ifdef CONFIG_MM_KERNEL_HEAP
       /* Use the kernel allocator if this is a kernel thread */
 
@@ -121,6 +160,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
           tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
         }
+#endif /* CONFIG_TLS_ALIGNED */
 
 #ifdef CONFIG_DEBUG_FEATURES
       /* Was the allocation successful? */
@@ -169,6 +209,12 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
       tcb->adj_stack_ptr  = (FAR uint32_t *)top_of_stack;
       tcb->adj_stack_size = size_of_stack;
 
+#ifdef CONFIG_TLS
+      /* Initialize the TLS data structure */
+
+      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/z80/src/common/z80_usestack.c b/arch/z80/src/common/z80_usestack.c
index 90c53b5..2e746c0 100644
--- a/arch/z80/src/common/z80_usestack.c
+++ b/arch/z80/src/common/z80_usestack.c
@@ -30,6 +30,7 @@
 #include <debug.h>
 #include <nuttx/kmalloc.h>
 #include <nuttx/arch.h>
+#include <nuttx/tls.h>
 
 #include "z80_internal.h"
 
@@ -78,6 +79,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   size_t top_of_stack;
   size_t size_of_stack;
 
+#ifdef CONFIG_TLS_ALIGNED
+  /* Make certain that the user provided stack is properly aligned */
+
+  DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0);
+#endif
+
   /* Is there already a stack allocated? */
 
   if (tcb->stack_alloc_ptr)
@@ -111,5 +118,11 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   tcb->adj_stack_size = top_of_stack;
   tcb->adj_stack_size = size_of_stack;
 
+#ifdef CONFIG_TLS
+  /* Initialize the TLS data structure */
+
+  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+#endif
+
   return OK;
 }


[incubator-nuttx] 02/04: arch/: Implement up_tls_info() for the rest of the architectures.

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit a4dd9674406545ad38e5acbfc90309fd3bdd6bcc
Author: Ouss4 <ab...@gmail.com>
AuthorDate: Thu May 7 00:32:41 2020 +0100

    arch/: Implement up_tls_info() for the rest of the architectures.
---
 arch/arm/include/tls.h                     |  6 +--
 arch/avr/include/arch.h                    |  6 +++
 arch/avr/include/avr/arch.h                | 87 ++++++++++++++++++++++++++++++
 arch/avr/include/avr32/arch.h              | 84 +++++++++++++++++++++++++++++
 arch/{arm => avr}/include/tls.h            | 28 ++--------
 arch/{arm => hc}/include/tls.h             | 25 ++++-----
 arch/{arm => mips}/include/tls.h           | 21 ++++----
 arch/{arm => misoc}/include/tls.h          | 26 ++++-----
 arch/{arm => or1k}/include/tls.h           | 17 +++---
 arch/renesas/include/arch.h                |  6 +++
 arch/renesas/include/m16c/arch.h           | 86 +++++++++++++++++++++++++++++
 arch/renesas/include/rx65n/arch.h          | 87 ++++++++++++++++++++++++++++++
 arch/renesas/include/sh1/arch.h            | 86 +++++++++++++++++++++++++++++
 arch/{arm => renesas}/include/tls.h        | 28 ++--------
 arch/risc-v/include/arch.h                 |  6 +++
 arch/risc-v/include/rv32im/arch.h          | 83 ++++++++++++++++++++++++++++
 arch/risc-v/include/rv64gc/arch.h          | 83 ++++++++++++++++++++++++++++
 arch/{arm => risc-v}/include/tls.h         | 28 ++--------
 arch/risc-v/src/common/riscv_createstack.c |  9 ++--
 arch/{arm => x86}/include/tls.h            | 26 ++-------
 arch/{arm => x86_64}/include/tls.h         | 28 ++--------
 arch/{arm => xtensa}/include/tls.h         | 25 +++++----
 arch/{arm => z16}/include/tls.h            | 32 ++---------
 arch/{arm => z80}/include/tls.h            | 32 ++---------
 24 files changed, 707 insertions(+), 238 deletions(-)

diff --git a/arch/arm/include/tls.h b/arch/arm/include/tls.h
index b96610c..49c5045 100644
--- a/arch/arm/include/tls.h
+++ b/arch/arm/include/tls.h
@@ -37,12 +37,12 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_getsp
+ * Name: arm_getsp
  ****************************************************************************/
 
 /* I don't know if the builtin to get SP is enabled */
 
-static inline uint32_t up_getsp(void)
+static inline uint32_t arm_getsp(void)
 {
   uint32_t sp;
   __asm__
@@ -86,7 +86,7 @@ static inline uint32_t up_getsp(void)
 static inline FAR struct tls_info_s *up_tls_info(void)
 {
   DEBUGASSERT(!up_interrupt_context());
-  return TLS_INFO((uintptr_t)up_getsp());
+  return TLS_INFO((uintptr_t)arm_getsp());
 }
 #else
 #  define up_tls_info() tls_get_info()
diff --git a/arch/avr/include/arch.h b/arch/avr/include/arch.h
index ccbf889..51219aa 100644
--- a/arch/avr/include/arch.h
+++ b/arch/avr/include/arch.h
@@ -46,6 +46,12 @@
 
 #include <nuttx/config.h>
 
+#ifdef CONFIG_ARCH_FAMILY_AVR32
+# include <arch/avr32/arch.h>
+#else
+# include <arch/avr/arch.h>
+#endif
+
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
diff --git a/arch/avr/include/avr/arch.h b/arch/avr/include/avr/arch.h
new file mode 100644
index 0000000..d7c695a
--- /dev/null
+++ b/arch/avr/include/avr/arch.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+ * arch/avr/include/avr/arch.h
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* This file should never be included directly but, rather,
+ * only indirectly through nuttx/arch.h
+ */
+
+#ifndef __ARCH_AVR_INCLUDE_AVR_ARCH_H
+#define __ARCH_AVR_INCLUDE_AVR_ARCH_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/****************************************************************************
+ * Inline functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: avr_getsp
+ ****************************************************************************/
+
+static inline uint16_t avr_getsp(void)
+{
+  uint8_t spl;
+  uint8_t sph;
+
+  __asm__ __volatile__
+  (
+    "in %0, __SP_L__\n\t"
+    "in %1, __SP_H__\n"
+    : "=r" (spl), "=r" (sph)
+    :
+  );
+  return (uint16_t)sph << 8 | spl;
+}
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_AVR_INCLUDE_AVR_ARCH_H */
diff --git a/arch/avr/include/avr32/arch.h b/arch/avr/include/avr32/arch.h
new file mode 100644
index 0000000..c765730
--- /dev/null
+++ b/arch/avr/include/avr32/arch.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * arch/avr/include/avr32/arch.h
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* This file should never be included directly but, rather,
+ * only indirectly through nuttx/arch.h
+ */
+
+#ifndef __ARCH_AVR_INCLUDE_AVR32_ARCH_H
+#define __ARCH_AVR_INCLUDE_AVR32_ARCH_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/****************************************************************************
+ * Inline functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: avr_getsp
+ ****************************************************************************/
+
+static inline uint32_t avr_getsp(void)
+{
+  uint32_t retval;
+  __asm__ __volatile__
+    (
+      "mov\t%0,sp\n\t"
+      : "=r" (retval)
+      :
+    );
+  return retval;
+}
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_AVR_INCLUDE_AVR32_ARCH_H */
diff --git a/arch/arm/include/tls.h b/arch/avr/include/tls.h
similarity index 84%
copy from arch/arm/include/tls.h
copy to arch/avr/include/tls.h
index b96610c..06ed9f3 100644
--- a/arch/arm/include/tls.h
+++ b/arch/avr/include/tls.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * arch/arm/include/tls.h
+ * arch/avr/include/tls.h
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -18,8 +18,8 @@
  *
  ****************************************************************************/
 
-#ifndef __ARCH_ARM_INCLUDE_TLS_H
-#define __ARCH_ARM_INCLUDE_TLS_H
+#ifndef __ARCH_AVR_INCLUDE_TLS_H
+#define __ARCH_AVR_INCLUDE_TLS_H
 
 /****************************************************************************
  * Included Files
@@ -37,24 +37,6 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_getsp
- ****************************************************************************/
-
-/* I don't know if the builtin to get SP is enabled */
-
-static inline uint32_t up_getsp(void)
-{
-  uint32_t sp;
-  __asm__
-  (
-    "\tmov %0, sp\n\t"
-    : "=r"(sp)
-  );
-
-  return sp;
-}
-
-/****************************************************************************
  * Name: up_tls_info
  *
  * Description:
@@ -86,11 +68,11 @@ static inline uint32_t up_getsp(void)
 static inline FAR struct tls_info_s *up_tls_info(void)
 {
   DEBUGASSERT(!up_interrupt_context());
-  return TLS_INFO((uintptr_t)up_getsp());
+  return TLS_INFO((uintptr_t)avr_getsp());
 }
 #else
 #  define up_tls_info() tls_get_info()
 #endif
 
 #endif /* CONFIG_TLS */
-#endif /* __ARCH_ARM_INCLUDE_TLS_H */
+#endif /* __ARCH_AVR_INCLUDE_TLS_H */
diff --git a/arch/arm/include/tls.h b/arch/hc/include/tls.h
similarity index 89%
copy from arch/arm/include/tls.h
copy to arch/hc/include/tls.h
index b96610c..e7cc678 100644
--- a/arch/arm/include/tls.h
+++ b/arch/hc/include/tls.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * arch/arm/include/tls.h
+ * arch/hc/include/tls.h
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -18,8 +18,8 @@
  *
  ****************************************************************************/
 
-#ifndef __ARCH_ARM_INCLUDE_TLS_H
-#define __ARCH_ARM_INCLUDE_TLS_H
+#ifndef __ARCH_HC_INCLUDE_TLS_H
+#define __ARCH_HC_INCLUDE_TLS_H
 
 /****************************************************************************
  * Included Files
@@ -37,21 +37,18 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_getsp
+ * Name: hc_getsp
  ****************************************************************************/
 
-/* I don't know if the builtin to get SP is enabled */
-
-static inline uint32_t up_getsp(void)
+static inline uint16_t hc_getsp(void)
 {
-  uint32_t sp;
+  uint16_t ret;
   __asm__
   (
-    "\tmov %0, sp\n\t"
-    : "=r"(sp)
+    "\tsts %0\n"
+	: "=m"(ret) :
   );
-
-  return sp;
+  return ret;
 }
 
 /****************************************************************************
@@ -86,11 +83,11 @@ static inline uint32_t up_getsp(void)
 static inline FAR struct tls_info_s *up_tls_info(void)
 {
   DEBUGASSERT(!up_interrupt_context());
-  return TLS_INFO((uintptr_t)up_getsp());
+  return TLS_INFO((uintptr_t)hc_getsp());
 }
 #else
 #  define up_tls_info() tls_get_info()
 #endif
 
 #endif /* CONFIG_TLS */
-#endif /* __ARCH_ARM_INCLUDE_TLS_H */
+#endif /* __ARCH_HC_INCLUDE_TLS_H */
diff --git a/arch/arm/include/tls.h b/arch/mips/include/tls.h
similarity index 90%
copy from arch/arm/include/tls.h
copy to arch/mips/include/tls.h
index b96610c..bd88d26 100644
--- a/arch/arm/include/tls.h
+++ b/arch/mips/include/tls.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * arch/arm/include/tls.h
+ * arch/mips/include/tls.h
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -18,8 +18,8 @@
  *
  ****************************************************************************/
 
-#ifndef __ARCH_ARM_INCLUDE_TLS_H
-#define __ARCH_ARM_INCLUDE_TLS_H
+#ifndef __ARCH_MIPS_INCLUDE_TLS_H
+#define __ARCH_MIPS_INCLUDE_TLS_H
 
 /****************************************************************************
  * Included Files
@@ -37,20 +37,17 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_getsp
+ * Name: mips_getsp
  ****************************************************************************/
 
-/* I don't know if the builtin to get SP is enabled */
-
-static inline uint32_t up_getsp(void)
+static inline uint32_t mips_getsp(void)
 {
-  uint32_t sp;
+  register uint32_t sp;
   __asm__
   (
-    "\tmov %0, sp\n\t"
+    "\tadd  %0, $0, $29\n"
     : "=r"(sp)
   );
-
   return sp;
 }
 
@@ -86,11 +83,11 @@ static inline uint32_t up_getsp(void)
 static inline FAR struct tls_info_s *up_tls_info(void)
 {
   DEBUGASSERT(!up_interrupt_context());
-  return TLS_INFO((uintptr_t)up_getsp());
+  return TLS_INFO((uintptr_t)mips_getsp());
 }
 #else
 #  define up_tls_info() tls_get_info()
 #endif
 
 #endif /* CONFIG_TLS */
-#endif /* __ARCH_ARM_INCLUDE_TLS_H */
+#endif /* __ARCH_MIPS_INCLUDE_TLS_H */
diff --git a/arch/arm/include/tls.h b/arch/misoc/include/tls.h
similarity index 89%
copy from arch/arm/include/tls.h
copy to arch/misoc/include/tls.h
index b96610c..e8af51f 100644
--- a/arch/arm/include/tls.h
+++ b/arch/misoc/include/tls.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * arch/arm/include/tls.h
+ * arch/misoc/include/tls.h
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -18,8 +18,8 @@
  *
  ****************************************************************************/
 
-#ifndef __ARCH_ARM_INCLUDE_TLS_H
-#define __ARCH_ARM_INCLUDE_TLS_H
+#ifndef __ARCH_MISOC_INCLUDE_TLS_H
+#define __ARCH_MISOC_INCLUDE_TLS_H
 
 /****************************************************************************
  * Included Files
@@ -37,23 +37,19 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_getsp
+ * Name: misoc_getsp
  ****************************************************************************/
 
-/* I don't know if the builtin to get SP is enabled */
-
-static inline uint32_t up_getsp(void)
+static inline uint32_t misoc_getsp(void)
 {
-  uint32_t sp;
-  __asm__
-  (
-    "\tmov %0, sp\n\t"
-    : "=r"(sp)
-  );
+  register uint32_t sp;
+
+  __asm__ __volatile__("addi %0, sp, 0" : "=r" (sp));
 
   return sp;
 }
 
+
 /****************************************************************************
  * Name: up_tls_info
  *
@@ -86,11 +82,11 @@ static inline uint32_t up_getsp(void)
 static inline FAR struct tls_info_s *up_tls_info(void)
 {
   DEBUGASSERT(!up_interrupt_context());
-  return TLS_INFO((uintptr_t)up_getsp());
+  return TLS_INFO((uintptr_t)misoc_getsp());
 }
 #else
 #  define up_tls_info() tls_get_info()
 #endif
 
 #endif /* CONFIG_TLS */
-#endif /* __ARCH_ARM_INCLUDE_TLS_H */
+#endif /* __ARCH_MISOC_INCLUDE_TLS_H */
diff --git a/arch/arm/include/tls.h b/arch/or1k/include/tls.h
similarity index 91%
copy from arch/arm/include/tls.h
copy to arch/or1k/include/tls.h
index b96610c..1b8fd22 100644
--- a/arch/arm/include/tls.h
+++ b/arch/or1k/include/tls.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * arch/arm/include/tls.h
+ * arch/or1k/include/tls.h
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -18,8 +18,8 @@
  *
  ****************************************************************************/
 
-#ifndef __ARCH_ARM_INCLUDE_TLS_H
-#define __ARCH_ARM_INCLUDE_TLS_H
+#ifndef __ARCH_OR1K_INCLUDE_TLS_H
+#define __ARCH_OR1K_INCLUDE_TLS_H
 
 /****************************************************************************
  * Included Files
@@ -37,14 +37,13 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_getsp
+ * Name: or1k_getsp
  ****************************************************************************/
 
-/* I don't know if the builtin to get SP is enabled */
-
-static inline uint32_t up_getsp(void)
+static inline uint32_t or1k_getsp(void)
 {
   uint32_t sp;
+
   __asm__
   (
     "\tmov %0, sp\n\t"
@@ -86,11 +85,11 @@ static inline uint32_t up_getsp(void)
 static inline FAR struct tls_info_s *up_tls_info(void)
 {
   DEBUGASSERT(!up_interrupt_context());
-  return TLS_INFO((uintptr_t)up_getsp());
+  return TLS_INFO((uintptr_t)or1k_getsp());
 }
 #else
 #  define up_tls_info() tls_get_info()
 #endif
 
 #endif /* CONFIG_TLS */
-#endif /* __ARCH_ARM_INCLUDE_TLS_H */
+#endif /* __ARCH_OR1K_INCLUDE_TLS_H */
diff --git a/arch/renesas/include/arch.h b/arch/renesas/include/arch.h
index 5bb9298..bf8973a 100644
--- a/arch/renesas/include/arch.h
+++ b/arch/renesas/include/arch.h
@@ -44,6 +44,12 @@
  * Included Files
  ****************************************************************************/
 
+#include <nuttx/config.h>
+
+/* Include chip-specific definitions */
+
+#include <arch/chip/arch.h>
+
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
diff --git a/arch/renesas/include/m16c/arch.h b/arch/renesas/include/m16c/arch.h
new file mode 100644
index 0000000..f76e9c4
--- /dev/null
+++ b/arch/renesas/include/m16c/arch.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+ * arch/renesas/include/m16c/arch.h
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* This file should never be included directly but, rather,
+ * only indirectly through nuttx/arch.h
+ */
+
+#ifndef __ARCH_RENESAS_INCLUDE_M16C_ARCH_H
+#define __ARCH_RENESAS_INCLUDE_M16C_ARCH_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/****************************************************************************
+ * Inline functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: renesas_getsp
+ ****************************************************************************/
+
+static inline uint16_t renesas_getsp(void)
+{
+  uint16_t sp;
+
+  __asm__ __volatile__
+    (
+      "\tstc sp, %0\n\t"
+      : "=r" (sp)
+      :
+      : "memory"
+    );
+  return sp;
+}
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_RENESAS_INCLUDE_M16C_ARCH_H */
diff --git a/arch/renesas/include/rx65n/arch.h b/arch/renesas/include/rx65n/arch.h
new file mode 100644
index 0000000..e08e961
--- /dev/null
+++ b/arch/renesas/include/rx65n/arch.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+ * arch/renesas/include/rx65n/arch.h
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* This file should never be included directly but, rather,
+ * only indirectly through nuttx/arch.h
+ */
+
+#ifndef __ARCH_RENESAS_INCLUDE_RX65N_ARCH_H
+#define __ARCH_RENESAS_INCLUDE_RX65N_ARCH_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/****************************************************************************
+ * Inline functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: renesas_getsp
+ ****************************************************************************/
+
+static inline uint16_t renesas_getsp(void)
+{
+  uint16_t sp;
+
+  __asm__ __volatile__
+    (
+      "\tmvfc usp, %0\n\t"
+      : "=r" (sp)
+      :
+      :"memory"
+    );
+
+  return sp;
+}
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_RENESAS_INCLUDE_RX65N_ARCH_H */
diff --git a/arch/renesas/include/sh1/arch.h b/arch/renesas/include/sh1/arch.h
new file mode 100644
index 0000000..e20826c
--- /dev/null
+++ b/arch/renesas/include/sh1/arch.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+ * arch/renesas/include/sh1/arch.h
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* This file should never be included directly but, rather,
+ * only indirectly through nuttx/arch.h
+ */
+
+#ifndef __ARCH_RENESAS_INCLUDE_SHA1_ARCH_H
+#define __ARCH_RENESAS_INCLUDE_SHA1_ARCH_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/****************************************************************************
+ * Inline functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: renesas_getsp
+ ****************************************************************************/
+
+static inline uint32_t renesas_getsp(void)
+{
+  uint32_t sp;
+
+  __asm__ __volatile__
+    (
+      "mov   r15, %0\n\t"
+      : "=&z" (sp)
+      :
+      : "memory"
+    );
+  return sp;
+}
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_RENESAS_INCLUDE_SHA1_ARCH_H */
diff --git a/arch/arm/include/tls.h b/arch/renesas/include/tls.h
similarity index 84%
copy from arch/arm/include/tls.h
copy to arch/renesas/include/tls.h
index b96610c..8998cd8 100644
--- a/arch/arm/include/tls.h
+++ b/arch/renesas/include/tls.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * arch/arm/include/tls.h
+ * arch/renesas/include/tls.h
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -18,8 +18,8 @@
  *
  ****************************************************************************/
 
-#ifndef __ARCH_ARM_INCLUDE_TLS_H
-#define __ARCH_ARM_INCLUDE_TLS_H
+#ifndef __ARCH_RENESAS_INCLUDE_TLS_H
+#define __ARCH_RENESAS_INCLUDE_TLS_H
 
 /****************************************************************************
  * Included Files
@@ -37,24 +37,6 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_getsp
- ****************************************************************************/
-
-/* I don't know if the builtin to get SP is enabled */
-
-static inline uint32_t up_getsp(void)
-{
-  uint32_t sp;
-  __asm__
-  (
-    "\tmov %0, sp\n\t"
-    : "=r"(sp)
-  );
-
-  return sp;
-}
-
-/****************************************************************************
  * Name: up_tls_info
  *
  * Description:
@@ -86,11 +68,11 @@ static inline uint32_t up_getsp(void)
 static inline FAR struct tls_info_s *up_tls_info(void)
 {
   DEBUGASSERT(!up_interrupt_context());
-  return TLS_INFO((uintptr_t)up_getsp());
+  return TLS_INFO((uintptr_t)renesas_getsp());
 }
 #else
 #  define up_tls_info() tls_get_info()
 #endif
 
 #endif /* CONFIG_TLS */
-#endif /* __ARCH_ARM_INCLUDE_TLS_H */
+#endif /* __ARCH_RENESAS_INCLUDE_TLS_H */
diff --git a/arch/risc-v/include/arch.h b/arch/risc-v/include/arch.h
index 970bd5b..f2c45b6 100644
--- a/arch/risc-v/include/arch.h
+++ b/arch/risc-v/include/arch.h
@@ -49,6 +49,11 @@
 
 #ifdef CONFIG_ARCH_RV32IM
 #  include "rv32im/csr.h"
+#  include "rv32im/arch.h"
+#endif
+
+#ifdef CONFIG_ARCH_RV64GC
+#  include "rv64gc/arch.h"
 #endif
 
 /****************************************************************************
@@ -57,6 +62,7 @@
 
 /* Macros to get the core and vendor ID, HART, arch and ISA codes, etc.
  */
+
 #ifdef CONFIG_RV32IM_SYSTEM_CSRRS_SUPPORT
 
 uint32_t up_getmisa(void);
diff --git a/arch/risc-v/include/rv32im/arch.h b/arch/risc-v/include/rv32im/arch.h
new file mode 100644
index 0000000..ff9418f
--- /dev/null
+++ b/arch/risc-v/include/rv32im/arch.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+ * arch/risc-v/include/rv32im/arch.h
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* This file should never be included directly but, rather,
+ * only indirectly through nuttx/arch.h
+ */
+
+#ifndef __ARCH_RISCV_INCLUDE_RV32IM_ARCH_H
+#define __ARCH_RISCV_INCLUDE_RV32IM_ARCH_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/****************************************************************************
+ * Inline functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: riscv_getsp
+ ****************************************************************************/
+
+static inline uint32_t riscv_getsp(void)
+{
+  register uint32_t sp;
+  __asm__
+  (
+    "\tadd  %0, x0, x2\n"
+    : "=r"(sp)
+  );
+  return sp;
+}
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_RISCV_INCLUDE_RV32IM_ARCH_H */
diff --git a/arch/risc-v/include/rv64gc/arch.h b/arch/risc-v/include/rv64gc/arch.h
new file mode 100644
index 0000000..58a7b3a
--- /dev/null
+++ b/arch/risc-v/include/rv64gc/arch.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+ * arch/risc-v/include/rv64gc/arch.h
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* This file should never be included directly but, rather,
+ * only indirectly through nuttx/arch.h
+ */
+
+#ifndef __ARCH_RISCV_INCLUDE_RV64GC_ARCH_H
+#define __ARCH_RISCV_INCLUDE_RV64GC_ARCH_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/****************************************************************************
+ * Inline functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: riscv_getsp
+ ****************************************************************************/
+
+static inline uint64_t riscv_getsp(void)
+{
+  register uint64_t sp;
+  __asm__
+  (
+    "\tadd  %0, x0, x2\n"
+    : "=r"(sp)
+  );
+  return sp;
+}
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_RISCV_INCLUDE_RV64GC_ARCH_H */
diff --git a/arch/arm/include/tls.h b/arch/risc-v/include/tls.h
similarity index 84%
copy from arch/arm/include/tls.h
copy to arch/risc-v/include/tls.h
index b96610c..70afee9 100644
--- a/arch/arm/include/tls.h
+++ b/arch/risc-v/include/tls.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * arch/arm/include/tls.h
+ * arch/riscv/include/tls.h
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -18,8 +18,8 @@
  *
  ****************************************************************************/
 
-#ifndef __ARCH_ARM_INCLUDE_TLS_H
-#define __ARCH_ARM_INCLUDE_TLS_H
+#ifndef __ARCH_RISCV_INCLUDE_TLS_H
+#define __ARCH_RISCV_INCLUDE_TLS_H
 
 /****************************************************************************
  * Included Files
@@ -37,24 +37,6 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_getsp
- ****************************************************************************/
-
-/* I don't know if the builtin to get SP is enabled */
-
-static inline uint32_t up_getsp(void)
-{
-  uint32_t sp;
-  __asm__
-  (
-    "\tmov %0, sp\n\t"
-    : "=r"(sp)
-  );
-
-  return sp;
-}
-
-/****************************************************************************
  * Name: up_tls_info
  *
  * Description:
@@ -86,11 +68,11 @@ static inline uint32_t up_getsp(void)
 static inline FAR struct tls_info_s *up_tls_info(void)
 {
   DEBUGASSERT(!up_interrupt_context());
-  return TLS_INFO((uintptr_t)up_getsp());
+  return TLS_INFO((uintptr_t)riscv_getsp());
 }
 #else
 #  define up_tls_info() tls_get_info()
 #endif
 
 #endif /* CONFIG_TLS */
-#endif /* __ARCH_ARM_INCLUDE_TLS_H */
+#endif /* __ARCH_RISCV_INCLUDE_TLS_H */
diff --git a/arch/risc-v/src/common/riscv_createstack.c b/arch/risc-v/src/common/riscv_createstack.c
index 449fec6..472e097 100644
--- a/arch/risc-v/src/common/riscv_createstack.c
+++ b/arch/risc-v/src/common/riscv_createstack.c
@@ -265,8 +265,9 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        * water marks.
        */
 
-      riscv_stack_color(tcb->stack_alloc_ptr, tcb->adj_stack_size);
-#endif
+      up_stack_color(tcb->stack_alloc_ptr, tcb->adj_stack_size);
+#endif /* CONFIG_STACK_COLORATION */
+#endif /* CONFIG_TLS */
 
       board_autoled_on(LED_STACKCREATED);
       return OK;
@@ -276,7 +277,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 }
 
 /****************************************************************************
- * Name: riscv_stack_color
+ * Name: up_stack_color
  *
  * Description:
  *   Write a well know value into the stack
@@ -284,7 +285,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
  ****************************************************************************/
 
 #ifdef CONFIG_STACK_COLORATION
-void riscv_stack_color(FAR void *stackbase, size_t nbytes)
+void up_stack_color(FAR void *stackbase, size_t nbytes)
 {
   /* Take extra care that we do not write outsize the stack boundaries */
 
diff --git a/arch/arm/include/tls.h b/arch/x86/include/tls.h
similarity index 85%
copy from arch/arm/include/tls.h
copy to arch/x86/include/tls.h
index b96610c..fbec9a2 100644
--- a/arch/arm/include/tls.h
+++ b/arch/x86/include/tls.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * arch/arm/include/tls.h
+ * arch/x86/include/tls.h
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -18,8 +18,8 @@
  *
  ****************************************************************************/
 
-#ifndef __ARCH_ARM_INCLUDE_TLS_H
-#define __ARCH_ARM_INCLUDE_TLS_H
+#ifndef __ARCH_X86_INCLUDE_TLS_H
+#define __ARCH_X86_INCLUDE_TLS_H
 
 /****************************************************************************
  * Included Files
@@ -37,24 +37,6 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_getsp
- ****************************************************************************/
-
-/* I don't know if the builtin to get SP is enabled */
-
-static inline uint32_t up_getsp(void)
-{
-  uint32_t sp;
-  __asm__
-  (
-    "\tmov %0, sp\n\t"
-    : "=r"(sp)
-  );
-
-  return sp;
-}
-
-/****************************************************************************
  * Name: up_tls_info
  *
  * Description:
@@ -93,4 +75,4 @@ static inline FAR struct tls_info_s *up_tls_info(void)
 #endif
 
 #endif /* CONFIG_TLS */
-#endif /* __ARCH_ARM_INCLUDE_TLS_H */
+#endif /* __ARCH_X86_INCLUDE_TLS_H */
diff --git a/arch/arm/include/tls.h b/arch/x86_64/include/tls.h
similarity index 84%
copy from arch/arm/include/tls.h
copy to arch/x86_64/include/tls.h
index b96610c..e9462ab 100644
--- a/arch/arm/include/tls.h
+++ b/arch/x86_64/include/tls.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * arch/arm/include/tls.h
+ * arch/x86_64/include/tls.h
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -18,8 +18,8 @@
  *
  ****************************************************************************/
 
-#ifndef __ARCH_ARM_INCLUDE_TLS_H
-#define __ARCH_ARM_INCLUDE_TLS_H
+#ifndef __ARCH_X86_64_INCLUDE_TLS_H
+#define __ARCH_X86_64_INCLUDE_TLS_H
 
 /****************************************************************************
  * Included Files
@@ -37,24 +37,6 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_getsp
- ****************************************************************************/
-
-/* I don't know if the builtin to get SP is enabled */
-
-static inline uint32_t up_getsp(void)
-{
-  uint32_t sp;
-  __asm__
-  (
-    "\tmov %0, sp\n\t"
-    : "=r"(sp)
-  );
-
-  return sp;
-}
-
-/****************************************************************************
  * Name: up_tls_info
  *
  * Description:
@@ -86,11 +68,11 @@ static inline uint32_t up_getsp(void)
 static inline FAR struct tls_info_s *up_tls_info(void)
 {
   DEBUGASSERT(!up_interrupt_context());
-  return TLS_INFO((uintptr_t)up_getsp());
+  return TLS_INFO((uintptr_t)up_getrsp());
 }
 #else
 #  define up_tls_info() tls_get_info()
 #endif
 
 #endif /* CONFIG_TLS */
-#endif /* __ARCH_ARM_INCLUDE_TLS_H */
+#endif /* __ARCH_X86_64_INCLUDE_TLS_H */
diff --git a/arch/arm/include/tls.h b/arch/xtensa/include/tls.h
similarity index 89%
copy from arch/arm/include/tls.h
copy to arch/xtensa/include/tls.h
index b96610c..33735ca 100644
--- a/arch/arm/include/tls.h
+++ b/arch/xtensa/include/tls.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * arch/arm/include/tls.h
+ * arch/xtensa/include/tls.h
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -18,8 +18,8 @@
  *
  ****************************************************************************/
 
-#ifndef __ARCH_ARM_INCLUDE_TLS_H
-#define __ARCH_ARM_INCLUDE_TLS_H
+#ifndef __ARCH_XTENSA_INCLUDE_TLS_H
+#define __ARCH_XTENSA_INCLUDE_TLS_H
 
 /****************************************************************************
  * Included Files
@@ -37,18 +37,17 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_getsp
+ * Name: xtensa_getsp
  ****************************************************************************/
 
-/* I don't know if the builtin to get SP is enabled */
-
-static inline uint32_t up_getsp(void)
+static inline uint32_t xtensa_getsp(void)
 {
-  uint32_t sp;
-  __asm__
+  register uint32_t sp;
+
+  __asm__ __volatile__
   (
-    "\tmov %0, sp\n\t"
-    : "=r"(sp)
+    "mov %0, sp\n"
+    : "=r" (sp)
   );
 
   return sp;
@@ -86,11 +85,11 @@ static inline uint32_t up_getsp(void)
 static inline FAR struct tls_info_s *up_tls_info(void)
 {
   DEBUGASSERT(!up_interrupt_context());
-  return TLS_INFO((uintptr_t)up_getsp());
+  return TLS_INFO((uintptr_t)xtensa_getsp());
 }
 #else
 #  define up_tls_info() tls_get_info()
 #endif
 
 #endif /* CONFIG_TLS */
-#endif /* __ARCH_ARM_INCLUDE_TLS_H */
+#endif /* __ARCH_XTENSA_INCLUDE_TLS_H */
diff --git a/arch/arm/include/tls.h b/arch/z16/include/tls.h
similarity index 81%
copy from arch/arm/include/tls.h
copy to arch/z16/include/tls.h
index b96610c..d2a1a16 100644
--- a/arch/arm/include/tls.h
+++ b/arch/z16/include/tls.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * arch/arm/include/tls.h
+ * arch/z16/include/tls.h
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -18,8 +18,8 @@
  *
  ****************************************************************************/
 
-#ifndef __ARCH_ARM_INCLUDE_TLS_H
-#define __ARCH_ARM_INCLUDE_TLS_H
+#ifndef __ARCH_Z16_INCLUDE_TLS_H
+#define __ARCH_Z16_INCLUDE_TLS_H
 
 /****************************************************************************
  * Included Files
@@ -37,24 +37,6 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_getsp
- ****************************************************************************/
-
-/* I don't know if the builtin to get SP is enabled */
-
-static inline uint32_t up_getsp(void)
-{
-  uint32_t sp;
-  __asm__
-  (
-    "\tmov %0, sp\n\t"
-    : "=r"(sp)
-  );
-
-  return sp;
-}
-
-/****************************************************************************
  * Name: up_tls_info
  *
  * Description:
@@ -83,14 +65,10 @@ static inline uint32_t up_getsp(void)
  ****************************************************************************/
 
 #ifdef CONFIG_TLS_ALIGNED
-static inline FAR struct tls_info_s *up_tls_info(void)
-{
-  DEBUGASSERT(!up_interrupt_context());
-  return TLS_INFO((uintptr_t)up_getsp());
-}
+#  error "Aligned TLS not supported"
 #else
 #  define up_tls_info() tls_get_info()
 #endif
 
 #endif /* CONFIG_TLS */
-#endif /* __ARCH_ARM_INCLUDE_TLS_H */
+#endif /* __ARCH_Z16_INCLUDE_TLS_H */
diff --git a/arch/arm/include/tls.h b/arch/z80/include/tls.h
similarity index 81%
copy from arch/arm/include/tls.h
copy to arch/z80/include/tls.h
index b96610c..381a103 100644
--- a/arch/arm/include/tls.h
+++ b/arch/z80/include/tls.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * arch/arm/include/tls.h
+ * arch/z80/include/tls.h
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -18,8 +18,8 @@
  *
  ****************************************************************************/
 
-#ifndef __ARCH_ARM_INCLUDE_TLS_H
-#define __ARCH_ARM_INCLUDE_TLS_H
+#ifndef __ARCH_Z80_INCLUDE_TLS_H
+#define __ARCH_Z80_INCLUDE_TLS_H
 
 /****************************************************************************
  * Included Files
@@ -37,24 +37,6 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_getsp
- ****************************************************************************/
-
-/* I don't know if the builtin to get SP is enabled */
-
-static inline uint32_t up_getsp(void)
-{
-  uint32_t sp;
-  __asm__
-  (
-    "\tmov %0, sp\n\t"
-    : "=r"(sp)
-  );
-
-  return sp;
-}
-
-/****************************************************************************
  * Name: up_tls_info
  *
  * Description:
@@ -83,14 +65,10 @@ static inline uint32_t up_getsp(void)
  ****************************************************************************/
 
 #ifdef CONFIG_TLS_ALIGNED
-static inline FAR struct tls_info_s *up_tls_info(void)
-{
-  DEBUGASSERT(!up_interrupt_context());
-  return TLS_INFO((uintptr_t)up_getsp());
-}
+#  error "Aligned TLS not supported"
 #else
 #  define up_tls_info() tls_get_info()
 #endif
 
 #endif /* CONFIG_TLS */
-#endif /* __ARCH_ARM_INCLUDE_TLS_H */
+#endif /* __ARCH_Z80_INCLUDE_TLS_H */


[incubator-nuttx] 03/04: arch/avr, renesas, risc-v: The *_getsp function was moved to a header file, remove it from the different source files that used to implement it to avoid redefinitions.

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit d56c613b7dadd2966fed2900acd8b4b5e69bbf70
Author: Ouss4 <ab...@gmail.com>
AuthorDate: Thu May 7 00:45:42 2020 +0100

    arch/avr,renesas,risc-v: The *_getsp function was moved to a header
    file, remove it from the different source files that used to implement
    it to avoid redefinitions.
---
 arch/avr/src/avr/up_dumpstate.c          | 23 +----------------------
 arch/avr/src/avr32/up_dumpstate.c        | 19 +------------------
 arch/avr/src/common/up_assert.c          |  2 +-
 arch/renesas/src/common/up_assert.c      |  2 +-
 arch/renesas/src/m16c/m16c_dumpstate.c   | 20 +-------------------
 arch/renesas/src/rx65n/rx65n_dumpstate.c | 15 +--------------
 arch/renesas/src/sh1/sh1_dumpstate.c     | 20 +-------------------
 arch/risc-v/src/rv32im/riscv_assert.c    | 19 ++-----------------
 arch/risc-v/src/rv64gc/riscv_assert.c    | 19 ++-----------------
 9 files changed, 11 insertions(+), 128 deletions(-)

diff --git a/arch/avr/src/avr/up_dumpstate.c b/arch/avr/src/avr/up_dumpstate.c
index f94d1bf..0dc4c69 100644
--- a/arch/avr/src/avr/up_dumpstate.c
+++ b/arch/avr/src/avr/up_dumpstate.c
@@ -59,27 +59,6 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_getsp
- ****************************************************************************/
-
-/* There may be a built-in to do this, but I don't know if it is enabled */
-
-static inline uint16_t up_getsp(void)
-{
-  uint8_t spl;
-  uint8_t sph;
-
-  __asm__ __volatile__
-  (
-    "in %0, __SP_L__\n\t"
-    "in %1, __SP_H__\n"
-    : "=r" (spl), "=r" (sph)
-    :
-  );
-  return (uint16_t)sph << 8 | spl;
-}
-
-/****************************************************************************
  * Name: up_stackdump
  ****************************************************************************/
 
@@ -161,7 +140,7 @@ static inline void up_registerdump(void)
 void up_dumpstate(void)
 {
   struct tcb_s *rtcb = running_task();
-  uint16_t sp = up_getsp();
+  uint16_t sp = avr_getsp();
   uint16_t ustackbase;
   uint16_t ustacksize;
 #if CONFIG_ARCH_INTERRUPTSTACK > 0
diff --git a/arch/avr/src/avr32/up_dumpstate.c b/arch/avr/src/avr32/up_dumpstate.c
index 41837db..f818041 100644
--- a/arch/avr/src/avr32/up_dumpstate.c
+++ b/arch/avr/src/avr32/up_dumpstate.c
@@ -59,23 +59,6 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_getsp
- ****************************************************************************/
-
-/* I don't know if the builtin to get SP is enabled */
-
-static inline uint32_t up_getsp(void)
-{
-  uint32_t retval;
-  __asm__ __volatile__ (
-    "mov\t%0,sp\n\t"
-    : "=r" (retval)
-    :
-  );
-  return retval;
-}
-
-/****************************************************************************
  * Name: up_stackdump
  ****************************************************************************/
 
@@ -127,7 +110,7 @@ static inline void up_registerdump(void)
 void up_dumpstate(void)
 {
   struct tcb_s *rtcb = running_task();
-  uint32_t sp = up_getsp();
+  uint32_t sp = avr_getsp();
   uint32_t ustackbase;
   uint32_t ustacksize;
 #if CONFIG_ARCH_INTERRUPTSTACK > 3
diff --git a/arch/avr/src/common/up_assert.c b/arch/avr/src/common/up_assert.c
index 2bba6af..c5c21ea 100644
--- a/arch/avr/src/common/up_assert.c
+++ b/arch/avr/src/common/up_assert.c
@@ -172,7 +172,7 @@ void up_assert(const uint8_t *filename, int lineno)
   syslog_flush();
 
 #ifdef CONFIG_BOARD_CRASHDUMP
-  board_crashdump(up_getsp(), running_task(), filename, lineno);
+  board_crashdump(avr_getsp(), running_task(), filename, lineno);
 #endif
 
 #ifdef CONFIG_ARCH_USBDUMP
diff --git a/arch/renesas/src/common/up_assert.c b/arch/renesas/src/common/up_assert.c
index 6d9ad53..131782e 100644
--- a/arch/renesas/src/common/up_assert.c
+++ b/arch/renesas/src/common/up_assert.c
@@ -178,7 +178,7 @@ void up_assert(const uint8_t *filename, int lineno)
   syslog_flush();
 
 #ifdef CONFIG_BOARD_CRASHDUMP
-  board_crashdump(up_getsp(), running_task(), filename, lineno);
+  board_crashdump(renesas_getsp(), running_task(), filename, lineno);
 #endif
 
   _up_assert(EXIT_FAILURE);
diff --git a/arch/renesas/src/m16c/m16c_dumpstate.c b/arch/renesas/src/m16c/m16c_dumpstate.c
index 09c7ce4..95186e0 100644
--- a/arch/renesas/src/m16c/m16c_dumpstate.c
+++ b/arch/renesas/src/m16c/m16c_dumpstate.c
@@ -63,24 +63,6 @@ static uint8_t s_last_regs[XCPTCONTEXT_REGS];
  ****************************************************************************/
 
 /****************************************************************************
- * Name: m16c_getsp
- ****************************************************************************/
-
-static inline uint16_t m16c_getsp(void)
-{
-  uint16_t sp;
-
-  __asm__ __volatile__
-    (
-      "\tstc sp, %0\n\t"
-      : "=r" (sp)
-      :
-      : "memory"
-    );
-  return sp;
-}
-
-/****************************************************************************
  * Name: m16c_getusersp
  ****************************************************************************/
 
@@ -152,7 +134,7 @@ static inline void m16c_registerdump(void)
 void up_dumpstate(void)
 {
   struct tcb_s *rtcb = running_task();
-  uint16_t sp = m16c_getsp();
+  uint16_t sp = renesas_getsp();
   uint16_t ustackbase;
   uint16_t ustacksize;
 #if CONFIG_ARCH_INTERRUPTSTACK > 3
diff --git a/arch/renesas/src/rx65n/rx65n_dumpstate.c b/arch/renesas/src/rx65n/rx65n_dumpstate.c
index e72cdd4..225131f 100644
--- a/arch/renesas/src/rx65n/rx65n_dumpstate.c
+++ b/arch/renesas/src/rx65n/rx65n_dumpstate.c
@@ -49,19 +49,6 @@ static uint32_t s_last_regs[XCPTCONTEXT_REGS];
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_getsp
- ****************************************************************************/
-
-uint16_t up_getsp(void)
-{
-  uint16_t sp;
-
-  __asm__ __volatile__("\tmvfc usp, %0\n\t": "=r" (sp):: "memory"); /* check */
-
-  return sp;
-}
-
-/****************************************************************************
  * Name: rx65n_getusersp
  ****************************************************************************/
 
@@ -141,7 +128,7 @@ static inline void rx65n_registerdump(void)
 void up_dumpstate(void)
 {
   struct tcb_s *rtcb = running_task();
-  uint32_t sp = up_getsp();
+  uint32_t sp = renesas_getsp();
   uint32_t ustackbase;
   uint32_t ustacksize;
 #if CONFIG_ARCH_INTERRUPTSTACK > 3
diff --git a/arch/renesas/src/sh1/sh1_dumpstate.c b/arch/renesas/src/sh1/sh1_dumpstate.c
index 7a1b6a2..973a987 100644
--- a/arch/renesas/src/sh1/sh1_dumpstate.c
+++ b/arch/renesas/src/sh1/sh1_dumpstate.c
@@ -62,24 +62,6 @@ static uint32_t s_last_regs[XCPTCONTEXT_REGS];
  ****************************************************************************/
 
 /****************************************************************************
- * Name: sh1_getsp
- ****************************************************************************/
-
-static inline uint32_t sh1_getsp(void)
-{
-  uint32_t sp;
-
-  __asm__ __volatile__
-    (
-      "mov   r15, %0\n\t"
-      : "=&z" (sp)
-      :
-      : "memory"
-    );
-  return sp;
-}
-
-/****************************************************************************
  * Name: sh1_stackdump
  ****************************************************************************/
 
@@ -142,7 +124,7 @@ static inline void sh1_registerdump(void)
 void up_dumpstate(void)
 {
   struct tcb_s *rtcb = running_task();
-  uint32_t sp = sh1_getsp();
+  uint32_t sp = renesas_getsp();
   uint32_t ustackbase;
   uint32_t ustacksize;
 #if CONFIG_ARCH_INTERRUPTSTACK > 3
diff --git a/arch/risc-v/src/rv32im/riscv_assert.c b/arch/risc-v/src/rv32im/riscv_assert.c
index 7711ad8..f0688ed 100644
--- a/arch/risc-v/src/rv32im/riscv_assert.c
+++ b/arch/risc-v/src/rv32im/riscv_assert.c
@@ -81,21 +81,6 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_getsp
- ****************************************************************************/
-
-static inline uint32_t up_getsp(void)
-{
-  register uint32_t sp;
-  __asm__
-  (
-    "\tadd  %0, x0, x2\n"
-    : "=r"(sp)
-  );
-  return sp;
-}
-
-/****************************************************************************
  * Name: up_stackdump
  ****************************************************************************/
 
@@ -200,7 +185,7 @@ static inline void up_registerdump(void)
 static void up_dumpstate(void)
 {
   struct tcb_s *rtcb = running_task();
-  uint32_t sp = up_getsp();
+  uint32_t sp = riscv_getsp();
   uint32_t ustackbase;
   uint32_t ustacksize;
 #if CONFIG_ARCH_INTERRUPTSTACK > 3
@@ -396,7 +381,7 @@ void up_assert(const uint8_t *filename, int lineno)
   syslog_flush();
 
 #ifdef CONFIG_BOARD_CRASHDUMP
-  board_crashdump(up_getsp(), running_task(), filename, lineno);
+  board_crashdump(riscv_getsp(), running_task(), filename, lineno);
 #endif
 
   _up_assert(EXIT_FAILURE);
diff --git a/arch/risc-v/src/rv64gc/riscv_assert.c b/arch/risc-v/src/rv64gc/riscv_assert.c
index 42d3cbd..cae90de 100644
--- a/arch/risc-v/src/rv64gc/riscv_assert.c
+++ b/arch/risc-v/src/rv64gc/riscv_assert.c
@@ -83,21 +83,6 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_getsp
- ****************************************************************************/
-
-static inline uint64_t up_getsp(void)
-{
-  register uint64_t sp;
-  __asm__
-  (
-    "\tadd  %0, x0, x2\n"
-    : "=r"(sp)
-  );
-  return sp;
-}
-
-/****************************************************************************
  * Name: up_stackdump
  ****************************************************************************/
 
@@ -211,7 +196,7 @@ static inline void up_registerdump(void)
 static void up_dumpstate(void)
 {
   struct tcb_s *rtcb = running_task();
-  uint64_t sp = up_getsp();
+  uint64_t sp = riscv_getsp();
   uintptr_t ustackbase;
   uintptr_t ustacksize;
 #if CONFIG_ARCH_INTERRUPTSTACK > 7
@@ -427,7 +412,7 @@ void up_assert(const uint8_t *filename, int lineno)
   syslog_flush();
 
 #ifdef CONFIG_BOARD_CRASHDUMP
-  board_crashdump(up_getsp(), running_task(), filename, lineno);
+  board_crashdump(riscv_getsp(), running_task(), filename, lineno);
 #endif
 
   _up_assert(EXIT_FAILURE);