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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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 **********************************************************/

View File

@ -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
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

View File

@ -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 */