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

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

commit 1a0586826e09867f4f8a655412d448f0d649c350
Author: raiden00pl <[email protected]>
AuthorDate: Sat Aug 22 13:53:01 2026 +0200

    arch/x86_64: generalize intel64 idle stacks
    
    intel64 port explicitly enumerates five idle-stack
    addresses and rejects configurations with more than five CPUs.
    
    Store the CPU0 stack top and calculate every CPU stack address
    from its index.
    
    Signed-off-by: raiden00pl <[email protected]>
    Assisted-by: Claude Code
---
 arch/x86_64/src/common/x86_64_allocateheap.c   | 28 +++-----------------------
 arch/x86_64/src/common/x86_64_internal.h       | 13 ++++++++----
 arch/x86_64/src/intel64/intel64_cpuidlestack.c |  2 +-
 arch/x86_64/src/intel64/intel64_head.S         | 18 ++++++++---------
 arch/x86_64/src/intel64/intel64_initialstate.c |  2 +-
 arch/x86_64/src/intel64/intel64_start.c        |  8 ++++----
 6 files changed, 26 insertions(+), 45 deletions(-)

diff --git a/arch/x86_64/src/common/x86_64_allocateheap.c 
b/arch/x86_64/src/common/x86_64_allocateheap.c
index dc315f99e0e..762be0ad461 100644
--- a/arch/x86_64/src/common/x86_64_allocateheap.c
+++ b/arch/x86_64/src/common/x86_64_allocateheap.c
@@ -39,8 +39,6 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-#define IDLE_STACK_SIZE CONFIG_IDLETHREAD_STACKSIZE
-
 #if CONFIG_IDLETHREAD_STACKSIZE % 16 != 0
 #  error CONFIG_IDLETHREAD_STACKSIZE must be aligned to 16
 #endif
@@ -57,28 +55,8 @@
  * Public Functions
  ****************************************************************************/
 
-static const uintptr_t g_idle_stackalloc = (uintptr_t)_ebss +
-  CONFIG_IDLETHREAD_STACKSIZE * CONFIG_SMP_NCPUS;
-
-const uintptr_t g_idle_topstack[CONFIG_SMP_NCPUS] =
-{
-  (uintptr_t)g_idle_stackalloc + (1 * IDLE_STACK_SIZE) - 16,
-#if CONFIG_SMP_NCPUS > 1
-  (uintptr_t)g_idle_stackalloc + (2 * IDLE_STACK_SIZE) - 16,
-#endif
-#if CONFIG_SMP_NCPUS > 2
-  (uintptr_t)g_idle_stackalloc + (3 * IDLE_STACK_SIZE) - 16,
-#endif
-#if CONFIG_SMP_NCPUS > 3
-  (uintptr_t)g_idle_stackalloc + (4 * IDLE_STACK_SIZE) - 16,
-#endif
-#if CONFIG_SMP_NCPUS > 4
-  (uintptr_t)g_idle_stackalloc + (5 * IDLE_STACK_SIZE) - 16,
-#endif
-#if CONFIG_SMP_NCPUS > 5
-#  error missing logic
-#endif
-};
+const uintptr_t g_idle_topstack = (uintptr_t)_ebss +
+  (uintptr_t)CONFIG_IDLETHREAD_STACKSIZE * (CONFIG_SMP_NCPUS + 1) - 16;
 
 /****************************************************************************
  * Name: up_allocate_heap
@@ -106,7 +84,7 @@ void up_allocate_heap(void **heap_start, size_t *heap_size)
 
   board_autoled_on(LED_HEAPALLOCATE);
 
-  topstack = g_idle_topstack[CONFIG_SMP_NCPUS - 1] + 8;
+  topstack = x86_64_idle_topstack(CONFIG_SMP_NCPUS - 1) + 8;
 
   /* Calculate the end of .bss section */
 
diff --git a/arch/x86_64/src/common/x86_64_internal.h 
b/arch/x86_64/src/common/x86_64_internal.h
index 92c5afa5e0e..3c787352eec 100644
--- a/arch/x86_64/src/common/x86_64_internal.h
+++ b/arch/x86_64/src/common/x86_64_internal.h
@@ -145,12 +145,11 @@ typedef void (*up_vector_t)(void);
 
 #ifndef __ASSEMBLY__
 
-/* This is the beginning of heap as provided from up_head.S. This is the
- * first address in DRAM after the loaded program+bss+idle stack.  The
- * end of the heap is CONFIG_RAM_END
+/* Top of the CPU0 idle stack.  The remaining CPU idle stacks are
+ * contiguous.
  */
 
-extern const uintptr_t g_idle_topstack[];
+extern const uintptr_t g_idle_topstack;
 
 /* Address of the saved user stack pointer */
 
@@ -180,6 +179,12 @@ extern uint8_t _etbss[];           /* End+1 of .tbss */
  * Inline Functions
  ****************************************************************************/
 
+static inline uintptr_t x86_64_idle_topstack(int cpu)
+{
+  return g_idle_topstack +
+         (uintptr_t)cpu * CONFIG_IDLETHREAD_STACKSIZE;
+}
+
 static inline void x86_64_cpuid(uint32_t leaf, uint32_t subleaf,
                                 uint32_t *eax, uint32_t *ebx,
                                 uint32_t *ecx, uint32_t *edx)
diff --git a/arch/x86_64/src/intel64/intel64_cpuidlestack.c 
b/arch/x86_64/src/intel64/intel64_cpuidlestack.c
index 03ee8d3503d..c8d9e16d697 100644
--- a/arch/x86_64/src/intel64/intel64_cpuidlestack.c
+++ b/arch/x86_64/src/intel64/intel64_cpuidlestack.c
@@ -90,7 +90,7 @@ int up_cpu_idlestack(int cpu, struct tcb_s *tcb, size_t 
stack_size)
 
   /* Get the top of the stack */
 
-  stack_alloc          = (uintptr_t)g_idle_topstack[cpu] -
+  stack_alloc          = x86_64_idle_topstack(cpu) -
                          CONFIG_IDLETHREAD_STACKSIZE;
   tcb->adj_stack_size  = stack_size - 8;
   tcb->stack_alloc_ptr = (void *)stack_alloc;
diff --git a/arch/x86_64/src/intel64/intel64_head.S 
b/arch/x86_64/src/intel64/intel64_head.S
index 333640c200e..abccf511bb0 100644
--- a/arch/x86_64/src/intel64/intel64_head.S
+++ b/arch/x86_64/src/intel64/intel64_head.S
@@ -61,12 +61,10 @@
 #define X86_XSAVE_XCOMPBC_OFFSET   520
 #define X86_XSAVE_RESERVED0_OFFSET 528
 
-/* Memory Map: _sbss is the start of the BSS region (see ld.script) _ebss is
- * the end of the BSS region (see ld.script). The idle task stack starts at
- * the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE.  The IDLE thread
- * is the thread that the system boots on and, eventually, becomes the idle,
- * do nothing task that runs only when there is nothing else to run.  The
- * heap continues from there until the end of memory.  See g_idle_topstack 
below.
+/* Memory Map: _sbss is the start of the BSS region, _ebss is the end of the
+ * BSS region.  One idle task stack is reserved for each configured CPU.  The
+ * heap follows the reserved idle stack area and continues until the end of
+ * memory.  See g_idle_topstack below.
  */
 
 /****************************************************************************
@@ -87,7 +85,7 @@
        .global    __nxstart                       /* __nxstart is defined 
elsewhere */
        .global    nx_start                        /* nx_start is defined 
elsewhere */
        .global    x86_64_ap_boot                  /* x86_64_ap_boot is defined 
elsewhere */
-       .global    g_idle_topstack                 /* The end of the idle 
stack, the start of the heap */
+       .global    g_idle_topstack                 /* Top of the CPU0 idle 
stack */
        .global    g_mb_info_struct
        .global    g_mb_magic
        .global    g_cpu_count
@@ -413,10 +411,10 @@ ap_start:
 
        /* Setup AP stack */
        movabs  $g_idle_topstack,    %rbx
-       movl    %edi, %eax
-       imul    $8, %eax, %eax
-       add     %rax, %rbx
        mov     (%rbx),   %rsp
+       movl    %edi, %eax
+       imulq   $CONFIG_IDLETHREAD_STACKSIZE, %rax, %rax
+       add     %rax, %rsp
 
        /* Move initial RSP below IDLE TCB regs */
        sub     $XCPTCONTEXT_SIZE, %rsp
diff --git a/arch/x86_64/src/intel64/intel64_initialstate.c 
b/arch/x86_64/src/intel64/intel64_initialstate.c
index b05640ba1e3..5da7fbf44c7 100644
--- a/arch/x86_64/src/intel64/intel64_initialstate.c
+++ b/arch/x86_64/src/intel64/intel64_initialstate.c
@@ -80,7 +80,7 @@ void up_initial_state(struct tcb_s *tcb)
 
   if (tcb->pid == IDLE_PROCESS_ID)
     {
-      char *stack_ptr = (char *)(g_idle_topstack[0] -
+      char *stack_ptr = (char *)(x86_64_idle_topstack(0) -
                                  CONFIG_IDLETHREAD_STACKSIZE);
       tcb->stack_alloc_ptr = stack_ptr;
       tcb->stack_base_ptr  = stack_ptr;
diff --git a/arch/x86_64/src/intel64/intel64_start.c 
b/arch/x86_64/src/intel64/intel64_start.c
index e96a8bf61c0..a4a77470ea8 100644
--- a/arch/x86_64/src/intel64/intel64_start.c
+++ b/arch/x86_64/src/intel64/intel64_start.c
@@ -163,10 +163,10 @@ void __nxstart(void)
 #ifdef CONFIG_SCHED_THREAD_LOCAL
   /* Make sure that FS_BASE is not null */
 
-  write_fsbase((uintptr_t)(g_idle_topstack[0] -
-                           CONFIG_IDLETHREAD_STACKSIZE +
-                           sizeof(struct tls_info_s) +
-                           (_END_TBSS - _START_TDATA)));
+  write_fsbase(x86_64_idle_topstack(0) -
+               CONFIG_IDLETHREAD_STACKSIZE +
+               sizeof(struct tls_info_s) +
+               (_END_TBSS - _START_TDATA));
 #endif
 
   /* Low-level, pre-OS initialization */

Reply via email to