diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-10-03 08:23:57 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-10-03 08:23:57 -0600 |
commit | 687cb950bae906c2744bca627913b2662d2980ae (patch) | |
tree | 789c12a730f0e9551e5c109faf764a7db00cde5e /nuttx | |
parent | 3588b6361e9ceea8f9b592594e348512f4d7df8d (diff) | |
download | px4-nuttx-687cb950bae906c2744bca627913b2662d2980ae.tar.gz px4-nuttx-687cb950bae906c2744bca627913b2662d2980ae.tar.bz2 px4-nuttx-687cb950bae906c2744bca627913b2662d2980ae.zip |
Add support for 64-bit lonjmp/setjmp in simulator platform
Diffstat (limited to 'nuttx')
-rw-r--r-- | nuttx/arch/sim/Kconfig | 29 | ||||
-rw-r--r-- | nuttx/arch/sim/include/irq.h | 29 | ||||
-rw-r--r-- | nuttx/arch/sim/src/Makefile | 13 | ||||
-rw-r--r-- | nuttx/arch/sim/src/up_initialstate.c | 4 | ||||
-rw-r--r-- | nuttx/arch/sim/src/up_internal.h | 72 | ||||
-rw-r--r-- | nuttx/arch/sim/src/up_setjmp32.S (renamed from nuttx/arch/sim/src/up_setjmp.S) | 6 | ||||
-rw-r--r-- | nuttx/arch/sim/src/up_setjmp64.S | 149 | ||||
-rw-r--r-- | nuttx/arch/sim/src/up_stackframe.c | 2 |
8 files changed, 259 insertions, 45 deletions
diff --git a/nuttx/arch/sim/Kconfig b/nuttx/arch/sim/Kconfig index 5d3b36beb..c2701aee3 100644 --- a/nuttx/arch/sim/Kconfig +++ b/nuttx/arch/sim/Kconfig @@ -6,33 +6,32 @@ if ARCH_SIM comment "Simulation Configuration Options" -config SIM_M32 -# bool "Build 32-bit simulation on 64-bit machine" - bool - default n - ---help--- - Simulation context switching is based on logic like setjmp and longjmp. This - context switching is only available for 32-bit targets. On 64-bit machines, - this context switching will fail. - - The workaround on 64-bit machines for now is to build for a 32-bit target on the - 64-bit machine. The workaround for this issue has been included in NuttX 6.15 and - beyond. For thoses versions, you must add SIM_M32=y to the .config file in - order to enable building a 32-bit image on a 64-bit platform. - choice prompt "Host CPU Type" default HOST_X86_64 config HOST_X86_64 bool "x86_64" - select SIM_M32 config HOST_X86 bool "x86" endchoice # Host CPU Type +config SIM_M32 + bool "Build 32-bit simulation on 64-bit machine" + default n + depends on HOST_X86_64 + ---help--- + Simulation context switching is based on logic like setjmp and longjmp. This + context switching is only available for 32-bit targets. On 64-bit machines, + this context switching will fail. + + The workaround on 64-bit machines for now is to build for a 32-bit target on the + 64-bit machine. The workaround for this issue has been included in NuttX 6.15 and + beyond. For thoses versions, you must add SIM_M32=y to the .config file in + order to enable building a 32-bit image on a 64-bit platform. + config SIM_WALLTIME bool "Execution simulation in near real-time" default n diff --git a/nuttx/arch/sim/include/irq.h b/nuttx/arch/sim/include/irq.h index ffc325790..41c9446eb 100644 --- a/nuttx/arch/sim/include/irq.h +++ b/nuttx/arch/sim/include/irq.h @@ -45,25 +45,44 @@ ************************************************************/ /************************************************************ - * Definitions + * Pre-processor Definitions ************************************************************/ +/* No interrupts */ #define NR_IRQS 0 +/* Number of registers saved in context switch */ + +#if defined(CONFIG_HOST_X86_64) && !defined(CONFIG_SIM_M32) + /* Storage order: %rbx, %rsp, %rbp, %r12, %r13, %r14, %r15, %rip */ + +# define XCPTCONTEXT_REGS 8 +#else + /* Storage order: %ebx, %esi, %edi, %ebp, sp, and return PC */ + +# define XCPTCONTEXT_REGS 6 +#endif + /************************************************************ * Public Types ************************************************************/ +#ifndef __ASSEMBLY__ +/* Number of registers saved in context switch */ + +#if defined(CONFIG_HOST_X86_64) && !defined(CONFIG_SIM_M32) +typedef unsigned long xcpt_reg_t; +#else +typedef int xcpt_reg_t; +#endif + /* This struct defines the way the registers are stored */ -#ifndef __ASSEMBLY__ struct xcptcontext { void *sigdeliver; /* Actual type is sig_deliver_t */ - /* Storage order: %ebx, $esi, %edi, %ebp, sp, and return PC */ - - int regs[6]; + xcpt_reg_t regs[6]; }; #endif diff --git a/nuttx/arch/sim/src/Makefile b/nuttx/arch/sim/src/Makefile index 0143dcffc..49222ff79 100644 --- a/nuttx/arch/sim/src/Makefile +++ b/nuttx/arch/sim/src/Makefile @@ -37,7 +37,18 @@ CFLAGS += -I$(TOPDIR)/sched -ASRCS = up_setjmp.S +ASRCS = + +ifeq ($(CONFIG_HOST_X86_64),y) +ifeq ($(CONFIG_SIM_M32),y) + ASRCS += up_setjmp32.S +else + ASRCS += up_setjmp64.S +endif +else + ASRCS += up_setjmp32.S +endif + AOBJS = $(ASRCS:.S=$(OBJEXT)) CSRCS = up_initialize.c up_idle.c up_interruptcontext.c up_initialstate.c diff --git a/nuttx/arch/sim/src/up_initialstate.c b/nuttx/arch/sim/src/up_initialstate.c index 3362f8424..574afe900 100644 --- a/nuttx/arch/sim/src/up_initialstate.c +++ b/nuttx/arch/sim/src/up_initialstate.c @@ -79,6 +79,6 @@ void up_initial_state(struct tcb_s *tcb) { memset(&tcb->xcp, 0, sizeof(struct xcptcontext)); - tcb->xcp.regs[JB_SP] = (uint32_t)tcb->adj_stack_ptr; - tcb->xcp.regs[JB_PC] = (uint32_t)tcb->start; + tcb->xcp.regs[JB_SP] = (xcpt_reg_t)tcb->adj_stack_ptr; + tcb->xcp.regs[JB_PC] = (xcpt_reg_t)tcb->start; } diff --git a/nuttx/arch/sim/src/up_internal.h b/nuttx/arch/sim/src/up_internal.h index 5cfb71560..dd6b36071 100644 --- a/nuttx/arch/sim/src/up_internal.h +++ b/nuttx/arch/sim/src/up_internal.h @@ -44,6 +44,7 @@ #include <nuttx/compiler.h> #include <sys/types.h> #include <nuttx/irq.h> +#include <arch/irq.h> /************************************************************************** * Pre-processor Definitions @@ -89,23 +90,58 @@ #undef CONFIG_SIM_UART_DATAPOST /* Context Switching Definitions ******************************************/ -/* Storage order: %ebx, $esi, %edi, %ebp, sp, and return PC */ -#ifdef __ASSEMBLY__ -# define JB_EBX (0*4) -# define JB_ESI (1*4) -# define JB_EDI (2*4) -# define JB_EBP (3*4) -# define JB_SP (4*4) -# define JB_PC (5*4) +#if defined(CONFIG_HOST_X86_64) && !defined(CONFIG_SIM_M32) + /* Storage order: %rbx, %rsp, %rbp, %r12, %r13, %r14, %r15, %rip */ + +# ifdef __ASSEMBLY__ +# define JB_RBX (0*8) +# define JB_RSP (1*8) +# define JB_RBP (2*8) +# define JB_R12 (3*8) +# define JB_R13 (4*8) +# define JB_R14 (5*8) +# define JB_R15 (6*8) +# define JB_RSI (7*8) + +# else +# define JB_RBX (0) +# define JB_RSP (1) +# define JB_RBP (2) +# define JB_R12 (3) +# define JB_R13 (4) +# define JB_R14 (5) +# define JB_R15 (6) +# define JB_RSI (7) + +# endif /* __ASSEMBLY__ */ + +/* Compatibility definitions */ + +# define JB_SP JB_RSI +# define JB_PC JB_RSP + #else -# define JB_EBX (0) -# define JB_ESI (1) -# define JB_EDI (2) -# define JB_EBP (3) -# define JB_SP (4) -# define JB_PC (5) -#endif /* __ASSEMBLY__ */ +/* Storage order: %ebx, $esi, %edi, %ebp, sp, and return PC */ + +# ifdef __ASSEMBLY__ +# define JB_EBX (0*4) +# define JB_ESI (1*4) +# define JB_EDI (2*4) +# define JB_EBP (3*4) +# define JB_SP (4*4) +# define JB_PC (5*4) + +# else +# define JB_EBX (0) +# define JB_ESI (1) +# define JB_EDI (2) +# define JB_EBP (3) +# define JB_SP (4) +# define JB_PC (5) + +# endif /* __ASSEMBLY__ */ +#endif /* CONFIG_HOST_X86_64 && !CONFIG_SIM_M32 */ /* Simulated Heap Definitions **********************************************/ /* Size of the simulated heap */ @@ -156,10 +192,10 @@ extern volatile int g_uart_data_available; * Public Function Prototypes **************************************************************************/ -/* up_setjmp.S ************************************************************/ +/* up_setjmp32.S **********************************************************/ -int up_setjmp(int *jb); -void up_longjmp(int *jb, int val) noreturn_function; +int up_setjmp(xcpt_reg_t *jb); +void up_longjmp(xcpt_reg_t *jb, int val) noreturn_function; /* up_tickless.c **********************************************************/ diff --git a/nuttx/arch/sim/src/up_setjmp.S b/nuttx/arch/sim/src/up_setjmp32.S index 3c61d3720..4951b2749 100644 --- a/nuttx/arch/sim/src/up_setjmp.S +++ b/nuttx/arch/sim/src/up_setjmp32.S @@ -1,5 +1,5 @@ /************************************************************************** - * arch/sim/src/up_setjmp.S + * arch/sim/src/up_setjmp32.S * * Copyright (C) 2007, 2012 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> @@ -58,7 +58,7 @@ **************************************************************************/ /************************************************************************** - * Global Variables + * Public Variables **************************************************************************/ /************************************************************************** @@ -114,7 +114,7 @@ SYMBOL(up_setjmp): .type SYMBOL(up_longjmp), @function #endif SYMBOL(up_longjmp): - movl 4(%esp), %ecx /* U_pthread_jmpbuf in %ecx. */ + movl 4(%esp), %ecx /* jmpbuf in %ecx. */ movl 8(%esp), %eax /* Second argument is return value. */ /* Save the return address now. */ diff --git a/nuttx/arch/sim/src/up_setjmp64.S b/nuttx/arch/sim/src/up_setjmp64.S new file mode 100644 index 000000000..34c2429af --- /dev/null +++ b/nuttx/arch/sim/src/up_setjmp64.S @@ -0,0 +1,149 @@ +/************************************************************************** + * arch/sim/src/up_setjmp64.S + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#include "up_internal.h" + +/************************************************************************** + * Pre-processor Definitions + **************************************************************************/ + +#ifdef __CYGWIN__ +//# define SYMBOL(s) _##s +# define SYMBOL(s) s +#else +# define SYMBOL(s) s +#endif + +/************************************************************************** + * Private Types + **************************************************************************/ + +/************************************************************************** + * Private Function Prototypes + **************************************************************************/ + +/************************************************************************** + * Public Variables + **************************************************************************/ + +/************************************************************************** + * Private Variables + **************************************************************************/ + +/************************************************************************** + * Private Functions + **************************************************************************/ + +/************************************************************************** + * Public Functions + **************************************************************************/ + + .text + .align 4 + .globl SYMBOL(up_setjmp) +#ifndef __CYGWIN__ + .type SYMBOL(up_setjmp), @function +#endif +SYMBOL(up_setjmp): + + /* Get the return address, adjusting the stack pointer */ + + pop %rsi + + /* Set up the return value */ + + xorl %eax,%eax + + /* Save 1: rbx */ + + movq %rbx, JB_RBX(%rdi) + + /* Save 2: Value of the rsp *after* returning */ + + movq %rsp, JB_RSP(%rdi) + + /* Fix up the return stack */ + + push %rsi + + /* Save registers */ + /* Storage order: %rbx, %rsp, %rbp, %r12, %r13, %r14, %r15, %rip */ + + movq %rbp, JB_RBP(%rdi) /* Save 3: rbp */ + movq %r12, JB_R12(%rdi) /* Save 4: r12 */ + movq %r13, JB_R13(%rdi) /* Save 5: r13 */ + movq %r14, JB_R14(%rdi) /* Save 6: r14 */ + movq %r15, JB_R15(%rdi) /* Save 7: r15 */ + movq %rsi, JB_RSI(%rdi) /* Save 8: Return address */ + + ret + +#ifndef __CYGWIN__ + .size SYMBOL(up_setjmp), . - SYMBOL(up_setjmp) +#endif + + .align 4 + .globl SYMBOL(up_longjmp) +#ifndef __CYGWIN__ + .type SYMBOL(up_longjmp), @function +#endif +SYMBOL(up_longjmp): + + /* Setup return value */ + + movl %esi,%eax + + /* Restore registers */ + + movq JB_RBX(%rdi),%rbx /* Save 1: rbx */ + movq JB_RSP(%rdi),%rsp /* Save 2: rsp */ + movq JB_RBP(%rdi),%rbp /* Save 3: rdi */ + movq JB_R12(%rdi),%r12 /* Save 4: r12 */ + movq JB_R13(%rdi),%r13 /* Save 5: r13 */ + movq JB_R14(%rdi),%r14 /* Save 6: r14 */ + movq JB_R15(%rdi),%r15 /* Save 7: rbp */ + + /* And return */ + + jmp *JB_RSI(%rdi) /* Save 8: rsi */ + +#ifndef __CYGWIN__ + .size SYMBOL(up_longjmp), . - SYMBOL(up_longjmp) +#endif + diff --git a/nuttx/arch/sim/src/up_stackframe.c b/nuttx/arch/sim/src/up_stackframe.c index ef6498598..7634dd842 100644 --- a/nuttx/arch/sim/src/up_stackframe.c +++ b/nuttx/arch/sim/src/up_stackframe.c @@ -132,7 +132,7 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) /* Reset the initial state */ - tcb->xcp.regs[JB_SP] = (uint32_t)tcb->adj_stack_ptr; + tcb->xcp.regs[JB_SP] = (xcpt_reg_t)tcb->adj_stack_ptr; /* And return a pointer to the allocated memory */ |