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

janc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit b5e9553b3b052c8d1a337744eb0452a4e3af1a9f
Author: Michal Gorecki <[email protected]>
AuthorDate: Fri Jul 14 10:54:08 2023 +0200

    kernel: Add 64-bit stack frame init assembly function
---
 kernel/os/src/arch/sim/os_arch.c             |  2 +-
 kernel/os/src/arch/sim/os_arch_stack_frame.s | 54 +++++++++++++++++++++++++++-
 kernel/sim/include/sim/sim.h                 |  2 +-
 3 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/kernel/os/src/arch/sim/os_arch.c b/kernel/os/src/arch/sim/os_arch.c
index 5c938b2f3..f2b7b98cb 100644
--- a/kernel/os/src/arch/sim/os_arch.c
+++ b/kernel/os/src/arch/sim/os_arch.c
@@ -25,7 +25,7 @@
  * os_arch_frame_init() expects them to be.
  */
 CTASSERT(offsetof(struct stack_frame, sf_mainsp) == 0);
-CTASSERT(offsetof(struct stack_frame, sf_jb) == 4);
+CTASSERT(offsetof(struct stack_frame, sf_jb) == __SIZEOF_POINTER__);
 
 void
 os_arch_task_start(struct stack_frame *sf, int rc)
diff --git a/kernel/os/src/arch/sim/os_arch_stack_frame.s 
b/kernel/os/src/arch/sim/os_arch_stack_frame.s
index 81e5c066e..5ef5aa302 100644
--- a/kernel/os/src/arch/sim/os_arch_stack_frame.s
+++ b/kernel/os/src/arch/sim/os_arch_stack_frame.s
@@ -30,8 +30,14 @@
 #error "unsupported platform"
 #endif
 
-    .text
+#if __SIZEOF_POINTER__ == 8
+    .code64
+#elif __SIZEOF_POINTER__ == 4
     .code32
+#else
+    #error "Void pointer should be either 4 or 8 bytes."
+#endif
+    .text
     .p2align 4, 0x90    /* align on 16-byte boundary and fill with NOPs */
 
     .globl CNAME(os_arch_frame_init)
@@ -40,6 +46,51 @@
      * void os_arch_frame_init(struct stack_frame *sf)
      */
 CNAME(os_arch_frame_init):
+#if __SIZEOF_POINTER__ == 8
+    pushq   %rbp                    /* function prologue for backtrace */
+    movq    %rsp,%rbp
+
+    movq    %rsp,(%rdi) /* sf->mainsp = %rsp */
+
+    /*
+     * Switch the stack so the stack pointer stored in 'sf->sf_jb' points
+     * to the task stack. This is slightly complicated because OS X wants
+     * the incoming stack pointer to be 16-byte aligned.
+     *
+     * ----------------
+     * sf (other fields)
+     * ----------------
+     * sf (sf_jb)           0x8(%rdi)
+     * ----------------
+     * sf (sf_mainsp)       0x0(%rdi)
+     * ----------------
+     * alignment padding    variable (0 to 12 bytes)
+     * ----------------
+     */
+    movq    %rdi,%rsp
+    andq    $0xfffffffffffffff0,%rsp  /* align %rsp on 16-byte boundary */
+    leaq    0x8(%rdi),%rax            /* %rax = &sf->sf_jb */
+    pushq   %rdi
+    movq    %rax, %rdi
+    movq    $0, %rsi
+    call    CNAME(sigsetjmp)          /* sigsetjmp(sf->sf_jb, 0) */
+    popq    %rdi
+    testq   %rax,%rax
+    jne     1f
+    movq    0x0(%rdi),%rsp            /* switch back to the main() stack */
+    popq    %rbp
+    ret                               /* return to os_arch_task_stack_init() */
+1:
+    leaq    2f(%rip),%rcx
+    pushq   %rcx                      /* retaddr */
+    pushq   $0                        /* frame pointer */
+    movq    %rsp,%rbp                 /* handcrafted prologue for backtrace */
+    pushq   %rax                      /* rc */
+    pushq   %rsi                      /* sf */
+    call    CNAME(os_arch_task_start) /* os_arch */
+2:
+    nop
+#elif __SIZEOF_POINTER__ == 4
     push    %ebp                    /* function prologue for backtrace */
     mov     %esp,%ebp
     push    %esi                    /* save %esi before using it as a tmpreg */
@@ -102,3 +153,4 @@ CNAME(os_arch_frame_init):
     /* never returns */
 2:
     nop
+#endif
diff --git a/kernel/sim/include/sim/sim.h b/kernel/sim/include/sim/sim.h
index 84ded14ba..b56d17b11 100644
--- a/kernel/sim/include/sim/sim.h
+++ b/kernel/sim/include/sim/sim.h
@@ -31,7 +31,7 @@ struct os_task;
 struct stack_frame;
 
 struct stack_frame {
-    int sf_mainsp;              /* stack on which main() is executing */
+    uintptr_t sf_mainsp;              /* stack on which main() is executing */
     sigjmp_buf sf_jb;
     struct os_task *sf_task;
 };

Reply via email to