sim: Initial support on MacOS M1 and Linux AARCH64 based hosts.

This commit is contained in:
Peter Kalbus 2022-02-02 23:36:23 +01:00 committed by Xiang Xiao
parent 1d963058b4
commit 6abdf73535
12 changed files with 322 additions and 21 deletions

View File

@ -23,6 +23,10 @@ config HOST_ARM
bool "arm"
select ARCH_HAVE_STACKCHECK
config HOST_ARM64
bool "arm64"
select ARCH_HAVE_STACKCHECK
endchoice # Host CPU Type
config ARCH_CHIP

View File

@ -104,7 +104,8 @@
# define UINT16_C(x) x
# define UINT32_C(x) x ## u
#if defined(CONFIG_HOST_X86_64) && !defined(CONFIG_SIM_M32)
#if (defined(CONFIG_HOST_X86_64) && !defined(CONFIG_SIM_M32)) || \
defined(CONFIG_HOST_ARM64)
# define PRIdPTR "ld"
# define PRIiPTR "li"
# define PRIoPTR "lo"

View File

@ -54,14 +54,15 @@
/* These change on 32-bit and 64-bit platforms */
#if !defined(CONFIG_HOST_X86_64) || defined(CONFIG_SIM_M32)
# define LONG_MIN (-LONG_MAX - 1)
# define LONG_MAX 2147483647L
# define ULONG_MAX 4294967295UL
#else
#if (defined(CONFIG_HOST_X86_64) && !defined(CONFIG_SIM_M32)) || \
defined(CONFIG_HOST_ARM64)
# define LONG_MIN (-LONG_MAX - 1)
# define LONG_MAX 9223372036854775807L
# define ULONG_MAX 18446744073709551615UL
#else
# define LONG_MIN (-LONG_MAX - 1)
# define LONG_MAX 2147483647L
# define ULONG_MAX 4294967295UL
#endif
#define LLONG_MIN (-LLONG_MAX - 1)
@ -71,12 +72,13 @@
/* A pointer is 4 or 8 bytes */
#define PTR_MIN (-PTR_MAX - 1)
#if !defined(CONFIG_HOST_X86_64) || defined(CONFIG_SIM_M32)
# define PTR_MAX 2147483647
# define UPTR_MAX 4294967295U
#else
#if (defined(CONFIG_HOST_X86_64) && !defined(CONFIG_SIM_M32)) || \
defined(CONFIG_HOST_ARM64)
# define PTR_MAX 9223372036854775807LL
# define UPTR_MAX 18446744073709551615ULL
#else
# define PTR_MAX 2147483647
# define UPTR_MAX 4294967295U
#endif
#endif /* __ARCH_SIM_INCLUDE_LIMITS_H */

View File

@ -41,6 +41,7 @@
# define XCPTCONTEXT_SIZE (8 * XCPTCONTEXT_REGS)
# ifdef __ASSEMBLY__
# define JB_RBX (0*8)
# define JB_RSP (1*8)
# define JB_RBP (2*8)
@ -51,6 +52,7 @@
# define JB_RSI (7*8)
# else
# define JB_RBX (0)
# define JB_RSP (1)
# define JB_RBP (2)
@ -75,6 +77,7 @@
# define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS)
# ifdef __ASSEMBLY__
# define JB_EBX (0*4)
# define JB_ESI (1*4)
# define JB_EDI (2*4)
@ -83,6 +86,7 @@
# define JB_PC (5*4)
# else
# define JB_EBX (0)
# define JB_ESI (1)
# define JB_EDI (2)
@ -97,12 +101,42 @@
# define JB_FP JB_EBP
#elif defined(CONFIG_HOST_ARM)
# define XCPTCONTEXT_REGS 16
# define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS)
# define JB_FP 7
# define JB_SP 8
# define JB_PC 9
#elif defined(CONFIG_HOST_ARM64)
# define XCPTCONTEXT_REGS 32
# define XCPTCONTEXT_SIZE (8 * XCPTCONTEXT_REGS)
# ifdef __ASSEMBLY__
# define JB_X19_X20 #0x00
# define JB_X21_X22 #0x10
# define JB_X23_X24 #0x20
# define JB_X25_X26 #0x30
# define JB_X27_X28 #0x40
# define JB_X29_XLR #0x50
# define JB_XFP_XSP #0x60
# define JB_D08_D09 #0x70
# define JB_D10_D11 #0x80
# define JB_D12_D13 #0x90
# define JB_D14_D15 #0xA0
# else
# define JB_PC (11)
# define JB_FP (12)
# define JB_SP (13)
# endif /* __ASSEMBLY__ */
#endif
/****************************************************************************
@ -113,6 +147,7 @@
typedef unsigned long xcpt_reg_t;
typedef xcpt_reg_t jmp_buf[XCPTCONTEXT_REGS];
#endif
/****************************************************************************

View File

@ -49,6 +49,8 @@ else ifeq ($(CONFIG_HOST_X86),y)
ASRCS += up_vfork_x86.S
else ifeq ($(CONFIG_HOST_ARM),y)
ASRCS += up_vfork_arm.S
else ifeq ($(CONFIG_HOST_ARM64),y)
ASRCS += up_vfork_arm64.S
endif
AOBJS = $(ASRCS:.S=$(OBJEXT))

View File

@ -63,8 +63,16 @@ void *host_alloc_heap(size_t sz)
{
void *p;
#if defined(CONFIG_HOST_MACOS) && defined(CONFIG_HOST_ARM64)
/* see: https://developer.apple.com/forums/thread/672804 */
p = mmap(NULL, sz, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_SHARED, -1, 0);
#else
p = mmap(NULL, sz, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANON | MAP_PRIVATE, -1, 0);
#endif
if (p == MAP_FAILED)
{
return NULL;

View File

@ -82,12 +82,19 @@ void up_initial_state(struct tcb_s *tcb)
* Thus, we need to emulate the effect of a CALL here, by subtracting
* sizeof(xcpt_reg_t), which is the amount a CALL would move RSP to store
* the return address.
*
* Note: On ARM64 architectures the return address is passed via LR
* register. No extra adjustment for the stack needed.
*/
tcb->xcp.regs[JB_SP] = (xcpt_reg_t)tcb->stack_base_ptr +
tcb->adj_stack_size -
sizeof(xcpt_reg_t);
tcb->xcp.regs[JB_SP] = (xcpt_reg_t)tcb->stack_base_ptr
#if !defined(CONFIG_HOST_ARM64)
- sizeof(xcpt_reg_t)
#endif
+ tcb->adj_stack_size;
tcb->xcp.regs[JB_PC] = (xcpt_reg_t)tcb->start;
#ifdef CONFIG_SIM_ASAN
__asan_unpoison_memory_region(tcb->stack_alloc_ptr, tcb->adj_stack_size);
#endif

View File

@ -0,0 +1,116 @@
/****************************************************************************
* arch/sim/src/sim/up_vfork_arm64.S
*
* 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.
*
***************************************************************************/
/****************************************************************************
* Included Files
***************************************************************************/
#include <nuttx/config.h>
#include <arch/irq.h>
/****************************************************************************
* Pre-processor Definitions
***************************************************************************/
#if defined(CONFIG_HOST_MACOS)
#define SYMBOL(x) _##x
#else
#define SYMBOL(x) x
#endif
/****************************************************************************
* Public Symbols
***************************************************************************/
.file "up_vfork_arm64.S"
.globl SYMBOL(up_vfork)
.globl SYMBOL(setjmp)
/****************************************************************************
* Public Functions
***************************************************************************/
/****************************************************************************
* Name: vfork
*
* Description:
* The vfork() function has the same effect as fork(), except that the
* behavior is undefined if the process created by vfork() either modifies
* any data other than a variable of type pid_t used to store the return
* value from vfork(), or returns from the function in which vfork() was
* called, or calls any other function before successfully calling _exit()
* or one of the exec family of functions.
*
* This thin layer implements vfork by simply calling up_vfork() with the
* vfork() context as an argument. The overall sequence is:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
* 6) nxtask_start_vfork() then executes the child thread.
*
* Input Parameters:
* None
*
* Returned Value:
* Upon successful completion, vfork() returns 0 to the child process and
* returns the process ID of the child process to the parent process.
* Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error.
*
***************************************************************************/
.text
.globl SYMBOL(vfork)
.align 4
SYMBOL(vfork):
stp x29, x30, [sp] /* save FP/LR register */
sub sp, sp, #XCPTCONTEXT_SIZE /* area from stack for setjmp() */
mov x0, sp /* pass stack area to setjmp() */
bl SYMBOL(setjmp) /* save register for longjmp() */
subs x0, x0, #1 /* 0: parent / 1: child */
cbz x0, 1f /* child --> return */
mov x0, sp /* pass stack area to up_vfork() */
bl SYMBOL(up_vfork) /* further process task creation */
1:
add sp, sp, #XCPTCONTEXT_SIZE /* release area from stack */
ldp x29, x30, [sp] /* restore FP/LR register */
ret
.end

View File

@ -472,6 +472,7 @@ Common Configuration Information
CONFIG_HOST_WINDOWS=n
CONFIG_HOST_X86=y
CONFIG_HOST_X86_64=n
CONFIG_HOST_ARM64=n
b. Linux, 64-bit CPU, 32-bit build
@ -479,6 +480,7 @@ Common Configuration Information
CONFIG_HOST_WINDOWS=n
CONFIG_HOST_X86=n
CONFIG_HOST_X86_64=y
CONFIG_HOST_ARM64=n
CONFIG_SIM_X8664_MICROSOFT=n
CONFIG_SIM_X8664_SYSTEMV=y
CONFIG_SIM_M32=y
@ -489,6 +491,7 @@ Common Configuration Information
CONFIG_HOST_WINDOWS=n
CONFIG_HOST_X86=n
CONFIG_HOST_X86_64=y
CONFIG_HOST_ARM64=n
CONFIG_SIM_X8664_MICROSOFT=n
CONFIG_SIM_X8664_SYSTEMV=y
CONFIG_SIM_M32=n
@ -500,6 +503,7 @@ Common Configuration Information
CONFIG_WINDOWS_CYGWIN=y
CONFIG_HOST_X86=y
CONFIG_HOST_X86_64=n
CONFIG_HOST_ARM64=n
e. Cygwin64, 64-bit, 32-bit build
@ -512,6 +516,7 @@ Common Configuration Information
CONFIG_WINDOWS_CYGWIN=y
CONFIG_HOST_X86=n
CONFIG_HOST_X86_64=y
CONFIG_HOST_ARM64=n
CONFIG_SIM_X8664_MICROSOFT=y
CONFIG_SIM_X8664_SYSTEMV=n
CONFIG_SIM_M32=n
@ -523,6 +528,31 @@ Common Configuration Information
CONFIG_HOST_WINDOWS=n
CONFIG_HOST_X86=n
CONFIG_HOST_X86_64=y
CONFIG_HOST_ARM64=n
CONFIG_SIM_X8664_MICROSOFT=n
CONFIG_SIM_X8664_SYSTEMV=y
CONFIG_SIM_M32=n
h. macOS M1, 64-bit, 64-bit build
CONFIG_HOST_LINUX=n
CONFIG_HOST_MACOS=y
CONFIG_HOST_WINDOWS=n
CONFIG_HOST_X86=n
CONFIG_HOST_X86_64=n
CONFIG_HOST_ARM64=y
CONFIG_SIM_X8664_MICROSOFT=n
CONFIG_SIM_X8664_SYSTEMV=y
CONFIG_SIM_M32=n
i. Linux ARM64, 64-bit, 64-bit build
CONFIG_HOST_LINUX=y
CONFIG_HOST_MACOS=n
CONFIG_HOST_WINDOWS=n
CONFIG_HOST_X86=n
CONFIG_HOST_X86_64=n
CONFIG_HOST_ARM64=y
CONFIG_SIM_X8664_MICROSOFT=n
CONFIG_SIM_X8664_SYSTEMV=y
CONFIG_SIM_M32=n

View File

@ -48,6 +48,10 @@ else ifeq ($(CONFIG_HOST_ARM),y)
ifeq ($(CONFIG_ARCH_SETJMP_H),y)
ASRCS += arch_setjmp_arm.S
endif
else ifeq ($(CONFIG_HOST_ARM64),y)
ifeq ($(CONFIG_ARCH_SETJMP_H),y)
ASRCS += arch_setjmp_arm64.S
endif
endif
DEPPATH += --dep-path machine/sim

View File

@ -0,0 +1,92 @@
/****************************************************************************
* libs/libc/machine/sim/arch_setjmp_arm64.S
*
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <arch/setjmp.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#if defined(CONFIG_HOST_MACOS)
#define SYMBOL(x) _##x
#else
#define SYMBOL(x) x
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
.text
.globl SYMBOL(setjmp)
.align 4
SYMBOL(setjmp):
stp x19, x20, [x0, JB_X19_X20]
stp x21, x22, [x0, JB_X21_X22]
stp x23, x24, [x0, JB_X23_X24]
stp x25, x26, [x0, JB_X25_X26]
stp x27, x28, [x0, JB_X27_X28]
stp x29, lr, [x0, JB_X29_XLR]
mov x1, sp /* STP can't access SP */
stp fp, x1, [x0, JB_XFP_XSP]
stp d8, d9, [x0, JB_D08_D09]
stp d10, d11, [x0, JB_D10_D11]
stp d12, d13, [x0, JB_D12_D13]
stp d14, d15, [x0, JB_D14_D15]
mov x0,#0 /* return value */
ret
.text
.globl SYMBOL(longjmp)
.align 4
SYMBOL(longjmp):
ldp x19, x20, [x0, JB_X19_X20]
ldp x21, x22, [x0, JB_X21_X22]
ldp x23, x24, [x0, JB_X23_X24]
ldp x25, x26, [x0, JB_X25_X26]
ldp x27, x28, [x0, JB_X27_X28]
ldp x29, lr, [x0, JB_X29_XLR]
ldp fp, x2, [x0, JB_XFP_XSP]
ldp d8, d9, [x0, JB_D08_D09]
ldp d10, d11, [x0, JB_D10_D11]
ldp d12, d13, [x0, JB_D12_D13]
ldp d14, d15, [x0, JB_D14_D15]
mov sp, x2 /* LDP can't access SP */
mov x0, x1
cmp x0, #0
b.ne 1f /* return 1, if val is 0 */
mov x0,#1 /* return value */
1:
ret
.end

View File

@ -112,10 +112,10 @@ fi
if [ -z "$cpu" ]; then
case $(uname -m) in
arm64)
cpu=arm
cpu=arm64
;;
aarch64)
cpu=arm
cpu=arm64
;;
*)
# Assume x86_64 as default
@ -164,9 +164,9 @@ if [ "X$host" == "Xlinux" -o "X$host" == "Xmacos" -o "X$host" == "Xbsd" ]; then
kconfig-tweak --file $nuttx/.config --disable CONFIG_HOST_BSD
kconfig-tweak --file $nuttx/.config --enable CONFIG_HOST_LINUX
if [ "X$cpu" == "Xarm" ]; then
echo " Select CONFIG_HOST_ARM=y"
kconfig-tweak --file $nuttx/.config --enable CONFIG_HOST_ARM
if [ "X$cpu" == "Xarm64" ]; then
echo " Select CONFIG_HOST_ARM64=y"
kconfig-tweak --file $nuttx/.config --enable CONFIG_HOST_ARM64
fi
elif [ "X$host" == "Xbsd" ]; then
@ -181,9 +181,9 @@ if [ "X$host" == "Xlinux" -o "X$host" == "Xmacos" -o "X$host" == "Xbsd" ]; then
kconfig-tweak --file $nuttx/.config --disable CONFIG_HOST_BSD
kconfig-tweak --file $nuttx/.config --enable CONFIG_HOST_MACOS
if [ "X$cpu" == "Xarm" ]; then
echo " Select CONFIG_HOST_ARM=y"
kconfig-tweak --file $nuttx/.config --enable CONFIG_HOST_ARM
if [ "X$cpu" == "Xarm64" ]; then
echo " Select CONFIG_HOST_ARM64=y"
kconfig-tweak --file $nuttx/.config --enable CONFIG_HOST_ARM64
fi
fi