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; };
