summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-10-03 08:23:57 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-10-03 08:23:57 -0600
commit687cb950bae906c2744bca627913b2662d2980ae (patch)
tree789c12a730f0e9551e5c109faf764a7db00cde5e
parent3588b6361e9ceea8f9b592594e348512f4d7df8d (diff)
downloadnuttx-687cb950bae906c2744bca627913b2662d2980ae.tar.gz
nuttx-687cb950bae906c2744bca627913b2662d2980ae.tar.bz2
nuttx-687cb950bae906c2744bca627913b2662d2980ae.zip
Add support for 64-bit lonjmp/setjmp in simulator platform
-rw-r--r--nuttx/arch/sim/Kconfig29
-rw-r--r--nuttx/arch/sim/include/irq.h29
-rw-r--r--nuttx/arch/sim/src/Makefile13
-rw-r--r--nuttx/arch/sim/src/up_initialstate.c4
-rw-r--r--nuttx/arch/sim/src/up_internal.h72
-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.S149
-rw-r--r--nuttx/arch/sim/src/up_stackframe.c2
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 */