From 9ebd505748344c5ba8a8e27be7c51d626e8806f4 Mon Sep 17 00:00:00 2001 From: carl <115627588+carl-tud@users.noreply.github.com> Date: Mon, 10 Jun 2024 19:12:44 +0200 Subject: [PATCH] cpu/native: add support for aarch64/arm64 --- cpu/native/irq_cpu.c | 7 ++- cpu/native/native_cpu.c | 7 ++- cpu/native/tramp.S | 85 +++++++++++++++++++++++++++++++++++- makefiles/arch/native.inc.mk | 14 ++++-- 4 files changed, 104 insertions(+), 9 deletions(-) diff --git a/cpu/native/irq_cpu.c b/cpu/native/irq_cpu.c index c5e404115ae4..e00cbdc2934d 100644 --- a/cpu/native/irq_cpu.c +++ b/cpu/native/irq_cpu.c @@ -351,9 +351,12 @@ void native_isr_entry(int sig, siginfo_t *info, void *context) _native_saved_eip = ((struct sigcontext *)context)->sc_eip; ((struct sigcontext *)context)->sc_eip = (unsigned int)&_native_sig_leave_tramp; #else /* Linux */ -#if defined(__arm__) +#if defined(__arm64__) || defined(__aarch64__) + _native_saved_eip = ((ucontext_t *)context)->uc_mcontext.pc; + ((ucontext_t *)context)->uc_mcontext.pc = (uintptr_t)&_native_sig_leave_tramp; +#elif defined(__arm__) _native_saved_eip = ((ucontext_t *)context)->uc_mcontext.arm_pc; - ((ucontext_t *)context)->uc_mcontext.arm_pc = (unsigned int)&_native_sig_leave_tramp; + ((ucontext_t *)context)->uc_mcontext.arm_pc = (uintptr_t)&_native_sig_leave_tramp; #else /* Linux/x86 */ #ifdef __x86_64__ _native_saved_eip = ((ucontext_t *)context)->uc_mcontext.gregs[REG_RIP]; diff --git a/cpu/native/native_cpu.c b/cpu/native/native_cpu.c index c2c1a39ca4af..9b726421c6c0 100644 --- a/cpu/native/native_cpu.c +++ b/cpu/native/native_cpu.c @@ -78,9 +78,12 @@ static void _native_mod_ctx_leave_sigh(ucontext_t *ctx) _native_saved_eip = ((struct sigcontext *)ctx)->sc_eip; ((struct sigcontext *)ctx)->sc_eip = (unsigned int)&_native_sig_leave_handler; #else /* Linux */ -#if defined(__arm__) +#if defined(__arm64__) || defined(__aarch64__) + _native_saved_eip = ((ucontext_t *)ctx)->uc_mcontext.pc; + ((ucontext_t *)ctx)->uc_mcontext.pc = (uintptr_t)&_native_sig_leave_handler; +#elif defined(__arm__) _native_saved_eip = ((ucontext_t *)ctx)->uc_mcontext.arm_pc; - ((ucontext_t *)ctx)->uc_mcontext.arm_pc = (unsigned int)&_native_sig_leave_handler; + ((ucontext_t *)ctx)->uc_mcontext.arm_pc = (uintptr_t)&_native_sig_leave_handler; #else /* Linux/x86 */ #ifdef __x86_64__ _native_saved_eip = ctx->uc_mcontext.gregs[REG_RIP]; diff --git a/cpu/native/tramp.S b/cpu/native/tramp.S index 85c7c60dc05e..fd4838a200fd 100644 --- a/cpu/native/tramp.S +++ b/cpu/native/tramp.S @@ -9,7 +9,7 @@ .text -#ifdef __arm__ +#if defined(__arm__) .globl _native_sig_leave_tramp _native_sig_leave_tramp: @@ -65,6 +65,89 @@ _native_sig_leave_handler: ldmia sp!, {lr} ldmia sp!, {r0-r12} ldmia sp!, {pc} +#elif defined(__arm64__) || defined(__aarch64__) + +.globl _native_sig_leave_tramp +_native_sig_leave_tramp: + /* save _native_saved_eip and registers */ + sub sp, sp, #240 + + stp x0, x1, [sp] + stp x2, x3, [sp, #0x10] + stp x4, x5, [sp, #0x20] + stp x6, x7, [sp, #0x30] + stp x8, x9, [sp, #0x40] + stp x10, x11, [sp, #0x50] + stp x12, x13, [sp, #0x60] + stp x14, x15, [sp, #0x70] + /* x16 intentionally not preserved */ + stp x17, x18, [sp, #0x80] + stp x19, x20, [sp, #0x90] + stp x21, x22, [sp, #0xA0] + stp x23, x24, [sp, #0xB0] + stp x25, x26, [sp, #0xC0] + stp x27, x28, [sp, #0xD0] + stp x29, x30, [sp, #0xE0] + + /* call swapcontext ( _native_cur_ctx, _native_isr_ctx ) */ + ldr x2, =_native_cur_ctx + ldr x0, [x2] + ldr x2, =_native_isr_ctx + ldr x1, [x2] + bl swapcontext + + /* reeanble interrupts */ + bl irq_enable + + /* _native_in_isr = 0 */ + eor x0, x0, x0 + ldr x2, =_native_in_isr + str x0, [x2] + + /* restore registers, jump to (saved) _native_saved_eip */ + ldp x0, x1, [sp] + ldp x2, x3, [sp, #0x10] + ldp x4, x5, [sp, #0x20] + ldp x6, x7, [sp, #0x30] + ldp x8, x9, [sp, #0x40] + ldp x10, x11, [sp, #0x50] + ldp x12, x13, [sp, #0x60] + ldp x14, x15, [sp, #0x70] + /* x16 intentionally not preserved */ + ldp x17, x18, [sp, #0x80] + ldp x19, x20, [sp, #0x90] + ldp x21, x22, [sp, #0xA0] + ldp x23, x24, [sp, #0xB0] + ldp x25, x26, [sp, #0xC0] + ldp x27, x28, [sp, #0xD0] + ldp x29, x30, [sp, #0xE0] + + add sp, sp, #240 + + /* branch to _native_saved_eip */ + ldr x16, =_native_saved_eip + ldr x16, [x16] + br x16 + +.globl _native_sig_leave_handler +_native_sig_leave_handler: + /* save _native_saved_eip and registers */ + sub sp, sp, #16 + stp x0, x1, [sp] + + /* _native_in_isr = 0 */ + eor x0, x0, x0 + ldr x1, =_native_in_isr + str x0, [x1] + + /* restore registers, jump to (saved) _native_saved_eip */ + ldp x0, x1, [sp] + add sp, sp, #16 + + /* branch to _native_saved_eip */ + ldr x16, =_native_saved_eip + ldr x16, [x16] + br x16 #else .globl _native_sig_leave_tramp diff --git a/makefiles/arch/native.inc.mk b/makefiles/arch/native.inc.mk index 78cbdbb3f230..1b237a4e6157 100644 --- a/makefiles/arch/native.inc.mk +++ b/makefiles/arch/native.inc.mk @@ -32,12 +32,18 @@ ifeq (,$(filter -std=%, $(CFLAGS))) CFLAGS += -std=gnu11 endif +HOST_BIT := $(shell getconf LONG_BIT) + ifeq ($(NATIVE_ARCH_BIT),64) - CFLAGS += -m64 - LINKFLAGS += -m64 + ifneq ($(HOST_BIT),64) + CFLAGS += -m64 + LINKFLAGS += -m64 + endif else ifeq ($(NATIVE_ARCH_BIT),32) - CFLAGS += -m32 - LINKFLAGS += -m32 + ifneq ($(HOST_BIT),32) + CFLAGS += -m32 + LINKFLAGS += -m32 + endif else $(error Unsupported native architecture) endif