Add support for 64-bit lonjmp/setjmp in simulator platform

This commit is contained in:
Gregory Nutt
2014-10-03 08:23:57 -06:00
parent 6e86d87ba5
commit 31049a203c
8 changed files with 259 additions and 45 deletions
+14 -15
View File
@@ -6,10 +6,22 @@
if ARCH_SIM if ARCH_SIM
comment "Simulation Configuration Options" comment "Simulation Configuration Options"
choice
prompt "Host CPU Type"
default HOST_X86_64
config HOST_X86_64
bool "x86_64"
config HOST_X86
bool "x86"
endchoice # Host CPU Type
config SIM_M32 config SIM_M32
# bool "Build 32-bit simulation on 64-bit machine" bool "Build 32-bit simulation on 64-bit machine"
bool
default n default n
depends on HOST_X86_64
---help--- ---help---
Simulation context switching is based on logic like setjmp and longjmp. This 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, context switching is only available for 32-bit targets. On 64-bit machines,
@@ -20,19 +32,6 @@ config SIM_M32
beyond. For thoses versions, you must add SIM_M32=y to the .config file in 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. 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_WALLTIME config SIM_WALLTIME
bool "Execution simulation in near real-time" bool "Execution simulation in near real-time"
default n default n
+24 -5
View File
@@ -45,25 +45,44 @@
************************************************************/ ************************************************************/
/************************************************************ /************************************************************
* Definitions * Pre-processor Definitions
************************************************************/ ************************************************************/
/* No interrupts */
#define NR_IRQS 0 #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 * 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 */ /* This struct defines the way the registers are stored */
#ifndef __ASSEMBLY__
struct xcptcontext struct xcptcontext
{ {
void *sigdeliver; /* Actual type is sig_deliver_t */ void *sigdeliver; /* Actual type is sig_deliver_t */
/* Storage order: %ebx, $esi, %edi, %ebp, sp, and return PC */ xcpt_reg_t regs[6];
int regs[6];
}; };
#endif #endif
+12 -1
View File
@@ -37,7 +37,18 @@
CFLAGS += -I$(TOPDIR)/sched 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)) AOBJS = $(ASRCS:.S=$(OBJEXT))
CSRCS = up_initialize.c up_idle.c up_interruptcontext.c up_initialstate.c CSRCS = up_initialize.c up_idle.c up_interruptcontext.c up_initialstate.c
+2 -2
View File
@@ -79,6 +79,6 @@
void up_initial_state(struct tcb_s *tcb) void up_initial_state(struct tcb_s *tcb)
{ {
memset(&tcb->xcp, 0, sizeof(struct xcptcontext)); memset(&tcb->xcp, 0, sizeof(struct xcptcontext));
tcb->xcp.regs[JB_SP] = (uint32_t)tcb->adj_stack_ptr; tcb->xcp.regs[JB_SP] = (xcpt_reg_t)tcb->adj_stack_ptr;
tcb->xcp.regs[JB_PC] = (uint32_t)tcb->start; tcb->xcp.regs[JB_PC] = (xcpt_reg_t)tcb->start;
} }
+54 -18
View File
@@ -44,6 +44,7 @@
#include <nuttx/compiler.h> #include <nuttx/compiler.h>
#include <sys/types.h> #include <sys/types.h>
#include <nuttx/irq.h> #include <nuttx/irq.h>
#include <arch/irq.h>
/************************************************************************** /**************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
@@ -89,23 +90,58 @@
#undef CONFIG_SIM_UART_DATAPOST #undef CONFIG_SIM_UART_DATAPOST
/* Context Switching Definitions ******************************************/ /* Context Switching Definitions ******************************************/
#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
/* Storage order: %ebx, $esi, %edi, %ebp, sp, and return PC */ /* Storage order: %ebx, $esi, %edi, %ebp, sp, and return PC */
#ifdef __ASSEMBLY__ # ifdef __ASSEMBLY__
# define JB_EBX (0*4) # define JB_EBX (0*4)
# define JB_ESI (1*4) # define JB_ESI (1*4)
# define JB_EDI (2*4) # define JB_EDI (2*4)
# define JB_EBP (3*4) # define JB_EBP (3*4)
# define JB_SP (4*4) # define JB_SP (4*4)
# define JB_PC (5*4) # define JB_PC (5*4)
#else
# define JB_EBX (0) # else
# define JB_ESI (1) # define JB_EBX (0)
# define JB_EDI (2) # define JB_ESI (1)
# define JB_EBP (3) # define JB_EDI (2)
# define JB_SP (4) # define JB_EBP (3)
# define JB_PC (5) # define JB_SP (4)
#endif /* __ASSEMBLY__ */ # define JB_PC (5)
# endif /* __ASSEMBLY__ */
#endif /* CONFIG_HOST_X86_64 && !CONFIG_SIM_M32 */
/* Simulated Heap Definitions **********************************************/ /* Simulated Heap Definitions **********************************************/
/* Size of the simulated heap */ /* Size of the simulated heap */
@@ -156,10 +192,10 @@ extern volatile int g_uart_data_available;
* Public Function Prototypes * Public Function Prototypes
**************************************************************************/ **************************************************************************/
/* up_setjmp.S ************************************************************/ /* up_setjmp32.S **********************************************************/
int up_setjmp(int *jb); int up_setjmp(xcpt_reg_t *jb);
void up_longjmp(int *jb, int val) noreturn_function; void up_longjmp(xcpt_reg_t *jb, int val) noreturn_function;
/* up_tickless.c **********************************************************/ /* up_tickless.c **********************************************************/
@@ -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. * Copyright (C) 2007, 2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * 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 .type SYMBOL(up_longjmp), @function
#endif #endif
SYMBOL(up_longjmp): 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. */ movl 8(%esp), %eax /* Second argument is return value. */
/* Save the return address now. */ /* Save the return address now. */
+149
View File
@@ -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
+1 -1
View File
@@ -132,7 +132,7 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
/* Reset the initial state */ /* 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 */ /* And return a pointer to the allocated memory */