Add support for 64-bit lonjmp/setjmp in simulator platform
This commit is contained in:
parent
6e86d87ba5
commit
31049a203c
@ -6,10 +6,22 @@
|
||||
if ARCH_SIM
|
||||
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
|
||||
# bool "Build 32-bit simulation on 64-bit machine"
|
||||
bool
|
||||
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,
|
||||
@ -20,19 +32,6 @@ config SIM_M32
|
||||
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_WALLTIME
|
||||
bool "Execution simulation in near real-time"
|
||||
default n
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 ******************************************/
|
||||
|
||||
#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 */
|
||||
|
||||
#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__ */
|
||||
# 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 **********************************************************/
|
||||
|
||||
|
@ -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. */
|
149
arch/sim/src/up_setjmp64.S
Normal file
149
arch/sim/src/up_setjmp64.S
Normal 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
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user