<machine/mcontext.h>

Change-Id: I2ad64018f3f402e7ccc5c4dc037dd0a3fe56a929
This commit is contained in:
Ben Gras 2013-12-10 14:55:46 +01:00 committed by Lionel Sambuc
parent 17587738d3
commit 5cecdfcb3e
8 changed files with 377 additions and 85 deletions

View file

@ -10,6 +10,7 @@
#include "kernel/system.h" #include "kernel/system.h"
#include <string.h> #include <string.h>
#include <assert.h>
#include <machine/mcontext.h> #include <machine/mcontext.h>
#if USE_MCONTEXT #if USE_MCONTEXT
@ -35,17 +36,18 @@ int do_getmcontext(struct proc * caller, message * m_ptr)
/* Get the mcontext structure into our address space. */ /* Get the mcontext structure into our address space. */
if ((r = data_copy(m_ptr->PR_ENDPT, (vir_bytes) m_ptr->PR_CTX_PTR, KERNEL, if ((r = data_copy(m_ptr->PR_ENDPT, (vir_bytes) m_ptr->PR_CTX_PTR, KERNEL,
(vir_bytes) &mc, (phys_bytes) sizeof(struct __mcontext))) != OK) (vir_bytes) &mc, (phys_bytes) sizeof(mcontext_t))) != OK)
return(r); return(r);
mc.mc_flags = 0;
#if defined(__i386__) #if defined(__i386__)
/* Copy FPU state */ /* Copy FPU state */
mc.mc_fpu_flags = 0;
if (proc_used_fpu(rp)) { if (proc_used_fpu(rp)) {
/* make sure that the FPU context is saved into proc structure first */ /* make sure that the FPU context is saved into proc structure first */
save_fpu(rp); save_fpu(rp);
mc.mc_fpu_flags = rp->p_misc_flags & MF_FPU_INITIALIZED; mc.mc_flags = (rp->p_misc_flags & MF_FPU_INITIALIZED) ? _MC_FPU_SAVED : 0;
memcpy(&(mc.mc_fpu_state), rp->p_seg.fpu_state, FPU_XFP_SIZE); assert(sizeof(mc.__fpregs.__fp_reg_set) == FPU_XFP_SIZE);
memcpy(&(mc.__fpregs.__fp_reg_set), rp->p_seg.fpu_state, FPU_XFP_SIZE);
} }
#endif #endif
@ -53,7 +55,7 @@ int do_getmcontext(struct proc * caller, message * m_ptr)
/* Copy the mcontext structure to the user's address space. */ /* Copy the mcontext structure to the user's address space. */
if ((r = data_copy(KERNEL, (vir_bytes) &mc, m_ptr->PR_ENDPT, if ((r = data_copy(KERNEL, (vir_bytes) &mc, m_ptr->PR_ENDPT,
(vir_bytes) m_ptr->PR_CTX_PTR, (vir_bytes) m_ptr->PR_CTX_PTR,
(phys_bytes) sizeof(struct __mcontext))) != OK) (phys_bytes) sizeof(mcontext_t))) != OK)
return(r); return(r);
return(OK); return(OK);
@ -76,14 +78,15 @@ int do_setmcontext(struct proc * caller, message * m_ptr)
/* Get the mcontext structure into our address space. */ /* Get the mcontext structure into our address space. */
if ((r = data_copy(m_ptr->PR_ENDPT, (vir_bytes) m_ptr->PR_CTX_PTR, KERNEL, if ((r = data_copy(m_ptr->PR_ENDPT, (vir_bytes) m_ptr->PR_CTX_PTR, KERNEL,
(vir_bytes) &mc, (phys_bytes) sizeof(struct __mcontext))) != OK) (vir_bytes) &mc, (phys_bytes) sizeof(mcontext_t))) != OK)
return(r); return(r);
#if defined(__i386__) #if defined(__i386__)
/* Copy FPU state */ /* Copy FPU state */
if (mc.mc_fpu_flags & MF_FPU_INITIALIZED) { if (mc.mc_flags & _MC_FPU_SAVED) {
rp->p_misc_flags |= MF_FPU_INITIALIZED; rp->p_misc_flags |= MF_FPU_INITIALIZED;
memcpy(rp->p_seg.fpu_state, &(mc.mc_fpu_state), FPU_XFP_SIZE); assert(sizeof(mc.__fpregs.__fp_reg_set) == FPU_XFP_SIZE);
memcpy(rp->p_seg.fpu_state, &(mc.__fpregs.__fp_reg_set), FPU_XFP_SIZE);
} else } else
rp->p_misc_flags &= ~MF_FPU_INITIALIZED; rp->p_misc_flags &= ~MF_FPU_INITIALIZED;
/* force reloading FPU in either case */ /* force reloading FPU in either case */

View file

@ -8,22 +8,22 @@ struct __ucontext
member UC_FLAGS uc_flags member UC_FLAGS uc_flags
member UC_LINK uc_link member UC_LINK uc_link
member MAGIC uc_mcontext.mc_magic member MAGIC uc_mcontext.mc_magic
member REG0 uc_mcontext.mc_p_reg.retreg member REG0 uc_mcontext.__gregs[_REG_R0]
member REG1 uc_mcontext.mc_p_reg.r1 member REG1 uc_mcontext.__gregs[_REG_R1]
member REG2 uc_mcontext.mc_p_reg.r2 member REG2 uc_mcontext.__gregs[_REG_R2]
member REG3 uc_mcontext.mc_p_reg.r3 member REG3 uc_mcontext.__gregs[_REG_R3]
member REG4 uc_mcontext.mc_p_reg.r4 member REG4 uc_mcontext.__gregs[_REG_R4]
member REG5 uc_mcontext.mc_p_reg.r5 member REG5 uc_mcontext.__gregs[_REG_R5]
member REG6 uc_mcontext.mc_p_reg.r6 member REG6 uc_mcontext.__gregs[_REG_R6]
member REG7 uc_mcontext.mc_p_reg.r7 member REG7 uc_mcontext.__gregs[_REG_R7]
member REG8 uc_mcontext.mc_p_reg.r8 member REG8 uc_mcontext.__gregs[_REG_R8]
member REG9 uc_mcontext.mc_p_reg.r9 member REG9 uc_mcontext.__gregs[_REG_R9]
member REG10 uc_mcontext.mc_p_reg.r10 member REG10 uc_mcontext.__gregs[_REG_R10]
member FPREG uc_mcontext.mc_p_reg.fp member FPREG uc_mcontext.__gregs[_REG_FP]
member REG12 uc_mcontext.mc_p_reg.r12 member REG12 uc_mcontext.__gregs[_REG_R12]
member SPREG uc_mcontext.mc_p_reg.sp member SPREG uc_mcontext.__gregs[_REG_SP]
member LRREG uc_mcontext.mc_p_reg.lr member LRREG uc_mcontext.__gregs[_REG_LR]
member PCREG uc_mcontext.mc_p_reg.pc member PCREG uc_mcontext.__gregs[_REG_PC]
define EFAULT EFAULT define EFAULT EFAULT
define EINVAL EINVAL define EINVAL EINVAL
define MCF_MAGIC MCF_MAGIC define MCF_MAGIC MCF_MAGIC

View file

@ -8,15 +8,15 @@ struct __ucontext
member UC_FLAGS uc_flags member UC_FLAGS uc_flags
member UC_LINK uc_link member UC_LINK uc_link
member MAGIC uc_mcontext.mc_magic member MAGIC uc_mcontext.mc_magic
member DI uc_mcontext.mc_p_reg.di member DI uc_mcontext.__gregs[_REG_EDI]
member SI uc_mcontext.mc_p_reg.si member SI uc_mcontext.__gregs[_REG_ESI]
member BP uc_mcontext.mc_p_reg.fp member BP uc_mcontext.__gregs[_REG_EBP]
member AX uc_mcontext.mc_p_reg.retreg member AX uc_mcontext.__gregs[_REG_EAX]
member BX uc_mcontext.mc_p_reg.bx member BX uc_mcontext.__gregs[_REG_EBX]
member CX uc_mcontext.mc_p_reg.cx member CX uc_mcontext.__gregs[_REG_ECX]
member DX uc_mcontext.mc_p_reg.dx member DX uc_mcontext.__gregs[_REG_EDX]
member PC uc_mcontext.mc_p_reg.pc member PC uc_mcontext.__gregs[_REG_EIP]
member SP uc_mcontext.mc_p_reg.sp member SP uc_mcontext.__gregs[_REG_ESP]
define EFAULT EFAULT define EFAULT EFAULT
define EINVAL EINVAL define EINVAL EINVAL
define MCF_MAGIC MCF_MAGIC define MCF_MAGIC MCF_MAGIC

View file

@ -84,7 +84,7 @@ void makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
} else if ((ucp->uc_stack.ss_sp == NULL) || } else if ((ucp->uc_stack.ss_sp == NULL) ||
(ucp->uc_stack.ss_size < MINSIGSTKSZ)) { (ucp->uc_stack.ss_size < MINSIGSTKSZ)) {
ucp->uc_mcontext.mc_magic = 0; ucp->uc_mcontext.mc_magic = 0;
ucp->uc_mcontext.mc_p_reg.sp = 0; _UC_MACHINE_SET_STACK(ucp, 0);
return; return;
} }
@ -121,9 +121,9 @@ void makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
/* Adjust the machine context to point to the top of this stack and the /* Adjust the machine context to point to the top of this stack and the
program counter to the context start wrapper. */ program counter to the context start wrapper. */
ucp->uc_mcontext.mc_p_reg.fp = 0; /* Clear frame pointer */ _UC_MACHINE_SET_EBP(ucp, 0); /* Clear frame pointer */
ucp->uc_mcontext.mc_p_reg.sp = (reg_t) stack_top; _UC_MACHINE_SET_STACK(ucp, (reg_t) stack_top);
ucp->uc_mcontext.mc_p_reg.pc = (reg_t) ctx_start; _UC_MACHINE_SET_PC(ucp, (reg_t) ctx_start);
*stack_top++ = (uintptr_t) func; *stack_top++ = (uintptr_t) func;
@ -140,13 +140,14 @@ void makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
/* Set ESI to point to the base of the stack where ucp is stored, so /* Set ESI to point to the base of the stack where ucp is stored, so
that the wrapper function knows how to clean up the stack after that the wrapper function knows how to clean up the stack after
calling `func' (i.e., how to adjust ESP). */ calling `func' (i.e., how to adjust ESP). */
ucp->uc_mcontext.mc_p_reg.si = (reg_t) stack_top; _UC_MACHINE_SET_ESI(ucp, (reg_t) stack_top);
/* If we ran out of stack space, invalidate stack pointer. Eventually, /* If we ran out of stack space, invalidate stack pointer. Eventually,
swapcontext will choke on this and return ENOMEM. */ swapcontext will choke on this and return ENOMEM. */
if (stack_top == ucp->uc_stack.ss_sp) if (stack_top == ucp->uc_stack.ss_sp) {
ucp->uc_mcontext.mc_p_reg.sp = 0; _UC_MACHINE_SET_STACK(ucp, 0);
}
#elif defined(__arm__) #elif defined(__arm__)
/* The caller provides a pointer to a stack that we can use to run our /* The caller provides a pointer to a stack that we can use to run our
context on. When the context starts, control is given to the context on. When the context starts, control is given to the
@ -180,23 +181,23 @@ void makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
/* Adjust the machine context to point to the top of this stack and the /* Adjust the machine context to point to the top of this stack and the
program counter to the 'func' entry point. Set lr to ctx_start, so program counter to the 'func' entry point. Set lr to ctx_start, so
ctx_start runs after 'func'. Save ucp in r4 */ ctx_start runs after 'func'. Save ucp in r4 */
ucp->uc_mcontext.mc_p_reg.fp = 0; /* Clear frame pointer */ _UC_MACHINE_SET_FP(ucp, 0); /* Clear frame pointer */
ucp->uc_mcontext.mc_p_reg.sp = (reg_t) stack_top; _UC_MACHINE_SET_STACK(ucp, (reg_t) stack_top);
ucp->uc_mcontext.mc_p_reg.pc = (reg_t) func; _UC_MACHINE_SET_PC(ucp, (reg_t) func);
ucp->uc_mcontext.mc_p_reg.lr = (reg_t) ctx_start; _UC_MACHINE_SET_LR(ucp, (reg_t) ctx_start);
ucp->uc_mcontext.mc_p_reg.r4 = (reg_t) ucp; _UC_MACHINE_SET_R4(ucp, (reg_t) ucp);
/* Copy arguments to r0-r3 and stack. */ /* Copy arguments to r0-r3 and stack. */
va_start(ap, argc); va_start(ap, argc);
/* Pass up to four arguments in registers. */ /* Pass up to four arguments in registers. */
if (argc-- > 0) if (argc-- > 0)
ucp->uc_mcontext.mc_p_reg.retreg = va_arg(ap, uintptr_t); _UC_MACHINE_SET_R0(ucp, va_arg(ap, uintptr_t));
if (argc-- > 0) if (argc-- > 0)
ucp->uc_mcontext.mc_p_reg.r1 = va_arg(ap, uintptr_t); _UC_MACHINE_SET_R1(ucp, va_arg(ap, uintptr_t));
if (argc-- > 0) if (argc-- > 0)
ucp->uc_mcontext.mc_p_reg.r2 = va_arg(ap, uintptr_t); _UC_MACHINE_SET_R2(ucp, va_arg(ap, uintptr_t));
if (argc-- > 0) if (argc-- > 0)
ucp->uc_mcontext.mc_p_reg.r3 = va_arg(ap, uintptr_t); _UC_MACHINE_SET_R3(ucp, va_arg(ap, uintptr_t));
/* Pass the rest on the stack. */ /* Pass the rest on the stack. */
while (argc-- > 0) { while (argc-- > 0) {
*stack_top++ = va_arg(ap, uintptr_t); *stack_top++ = va_arg(ap, uintptr_t);
@ -205,8 +206,9 @@ void makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
/* If we ran out of stack space, invalidate stack pointer. Eventually, /* If we ran out of stack space, invalidate stack pointer. Eventually,
swapcontext will choke on this and return ENOMEM. */ swapcontext will choke on this and return ENOMEM. */
if (stack_top == ucp->uc_stack.ss_sp) if (stack_top == ucp->uc_stack.ss_sp) {
ucp->uc_mcontext.mc_p_reg.sp = 0; _UC_MACHINE_SET_STACK(ucp, 0);
}
#else #else
# error "Unsupported platform" # error "Unsupported platform"
#endif #endif
@ -226,7 +228,7 @@ int swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
return(-1); return(-1);
} }
if (ucp->uc_mcontext.mc_p_reg.sp == 0) { if (_UC_MACHINE_STACK(ucp) == 0) {
/* No stack space. Bail out. */ /* No stack space. Bail out. */
errno = ENOMEM; errno = ENOMEM;
return(-1); return(-1);

View file

@ -116,11 +116,10 @@ void mthread_stats(void)
*===========================================================================*/ *===========================================================================*/
void mthread_stacktrace(mthread_thread_t t) void mthread_stacktrace(mthread_thread_t t)
{ {
#ifdef __i386__ /* stacktrace only implemented on x86 */
unsigned long bp, hbp, pc; unsigned long bp, hbp, pc;
mthread_tcb_t *tcb; mthread_tcb_t *tcb;
ucontext_t *ctx; ucontext_t *ctx;
mcontext_t *mtx;
struct stackframe_s *frame;
tcb = mthread_find_tcb(t); tcb = mthread_find_tcb(t);
ctx = &tcb->m_context; ctx = &tcb->m_context;
@ -130,9 +129,7 @@ void mthread_stacktrace(mthread_thread_t t)
printf("thread %d: ", t); printf("thread %d: ", t);
mtx = &ctx->uc_mcontext; bp = _UC_MACHINE_EBP(ctx);
frame = &mtx->mc_p_reg;
bp = frame->fp;
while (bp) { while (bp) {
pc = ((unsigned long *) bp)[1]; pc = ((unsigned long *) bp)[1];
@ -149,6 +146,7 @@ void mthread_stacktrace(mthread_thread_t t)
} }
printf("\n"); printf("\n");
#endif
} }
/*===========================================================================* /*===========================================================================*

View file

@ -1,19 +1,165 @@
#ifndef _MACHINE_MCONTEXT_H /* $NetBSD: mcontext.h,v 1.11 2012/08/03 07:59:23 matt Exp $ */
#define _MACHINE_MCONTEXT_H
#include <machine/stackframe.h> /*-
* Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Klaus Klein and by Jason R. Thorpe of Wasabi Systems, Inc.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#define MCF_MAGIC 0xc0ffee #ifndef _ARM_MCONTEXT_H_
#define _ARM_MCONTEXT_H_
/* Context to describe processor state */ /*
typedef struct __mcontext { * General register state
*/
#define _NGREG 17
typedef unsigned int __greg_t;
typedef __greg_t __gregset_t[_NGREG];
#define _REG_R0 0
#define _REG_R1 1
#define _REG_R2 2
#define _REG_R3 3
#define _REG_R4 4
#define _REG_R5 5
#define _REG_R6 6
#define _REG_R7 7
#define _REG_R8 8
#define _REG_R9 9
#define _REG_R10 10
#define _REG_R11 11
#define _REG_R12 12
#define _REG_R13 13
#define _REG_R14 14
#define _REG_R15 15
#define _REG_CPSR 16
/* Convenience synonyms */
#define _REG_FP _REG_R11
#define _REG_SP _REG_R13
#define _REG_LR _REG_R14
#define _REG_PC _REG_R15
/*
* Floating point register state
*/
/* Note: the storage layout of this structure must be identical to ARMFPE! */
typedef struct {
unsigned int __fp_fpsr;
struct {
unsigned int __fp_exponent;
unsigned int __fp_mantissa_hi;
unsigned int __fp_mantissa_lo;
} __fp_fr[8];
} __fpregset_t;
typedef struct {
unsigned int __vfp_fpscr;
unsigned int __vfp_fstmx[33];
unsigned int __vfp_fpsid;
} __vfpregset_t;
typedef struct {
__gregset_t __gregs;
union {
__fpregset_t __fpregs;
__vfpregset_t __vfpregs;
} __fpu;
__greg_t _mc_tlsbase;
#ifdef __minix
int mc_flags;
int mc_magic; int mc_magic;
struct stackframe_s mc_p_reg; #endif
} mcontext_t; } mcontext_t, mcontext32_t;
__BEGIN_DECLS /* Machine-dependent uc_flags */
#define _UC_ARM_VFP 0x00010000 /* FPU field is VFP */
/* used by signal delivery to indicate status of signal stack */
#define _UC_SETSTACK 0x00020000
#define _UC_CLRSTACK 0x00040000
#define _UC_TLSBASE 0x00080000
#define _UC_MACHINE_PAD 2 /* Padding appended to ucontext_t */
#define _UC_MACHINE_SP(uc) ((uc)->uc_mcontext.__gregs[_REG_SP])
#define _UC_MACHINE_PC(uc) ((uc)->uc_mcontext.__gregs[_REG_PC])
#define _UC_MACHINE_INTRV(uc) ((uc)->uc_mcontext.__gregs[_REG_R0])
#define _UC_MACHINE_SET_PC(uc, pc) _UC_MACHINE_PC(uc) = (pc)
#ifdef __minix
#define _UC_MACHINE_STACK(uc) ((uc)->uc_mcontext.__gregs[_REG_SP])
#define _UC_MACHINE_SET_STACK(uc, sp) _UC_MACHINE_STACK(uc) = (sp)
#define _UC_MACHINE_FP(uc) ((uc)->uc_mcontext.__gregs[_REG_FP])
#define _UC_MACHINE_SET_FP(uc, fp) _UC_MACHINE_FP(uc) = (fp)
#define _UC_MACHINE_LR(uc) ((uc)->uc_mcontext.__gregs[_REG_LR])
#define _UC_MACHINE_SET_LR(uc, lr) _UC_MACHINE_LR(uc) = (lr)
#define _UC_MACHINE_R0(uc) ((uc)->uc_mcontext.__gregs[_REG_R0])
#define _UC_MACHINE_SET_R0(uc, setreg) _UC_MACHINE_R0(uc) = (setreg)
#define _UC_MACHINE_R1(uc) ((uc)->uc_mcontext.__gregs[_REG_R1])
#define _UC_MACHINE_SET_R1(uc, setreg) _UC_MACHINE_R1(uc) = (setreg)
#define _UC_MACHINE_R2(uc) ((uc)->uc_mcontext.__gregs[_REG_R2])
#define _UC_MACHINE_SET_R2(uc, setreg) _UC_MACHINE_R2(uc) = (setreg)
#define _UC_MACHINE_R3(uc) ((uc)->uc_mcontext.__gregs[_REG_R3])
#define _UC_MACHINE_SET_R3(uc, setreg) _UC_MACHINE_R3(uc) = (setreg)
#define _UC_MACHINE_R4(uc) ((uc)->uc_mcontext.__gregs[_REG_R4])
#define _UC_MACHINE_SET_R4(uc, setreg) _UC_MACHINE_R4(uc) = (setreg)
#endif
#define __UCONTEXT_SIZE 256
static __inline void *
__lwp_getprivate_fast(void)
{
extern void *_lwp_getprivate(void);
void *rv;
__asm("mrc p15, 0, %0, c13, c0, 3" : "=r"(rv));
if (__predict_true(rv))
return rv;
/*
* Some ARM cores are broken and don't raise an undefined fault when an
* unrecogized mrc instruction is encountered, but just return zero.
* To do deal with that, if we get a zero we (re-)fetch the value using
* syscall.
*/
return _lwp_getprivate();
}
#ifdef __minix
int setmcontext(const mcontext_t *mcp); int setmcontext(const mcontext_t *mcp);
int getmcontext(mcontext_t *mcp); int getmcontext(mcontext_t *mcp);
__END_DECLS #define MCF_MAGIC 0xc0ffee
#endif
#endif /* _MACHINE_MCONTEXT_H */ #endif /* !_ARM_MCONTEXT_H_ */

View file

@ -1,22 +1,165 @@
#ifndef _MACHINE_MCONTEXT_H /* $NetBSD: mcontext.h,v 1.10 2011/02/25 14:07:13 joerg Exp $ */
#define _MACHINE_MCONTEXT_H 1
#include <machine/fpu.h> /*-
#include <machine/stackframe.h> * Copyright (c) 1999 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Klaus Klein.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#define MCF_MAGIC 0xc0ffee #ifndef _I386_MCONTEXT_H_
#define _I386_MCONTEXT_H_
/* Context to describe processor state */
typedef struct __mcontext { /*
* mcontext extensions to handle signal delivery.
*/
#define _UC_SETSTACK 0x00010000
#define _UC_CLRSTACK 0x00020000
#define _UC_VM 0x00040000
#define _UC_TLSBASE 0x00080000
/*
* Layout of mcontext_t according to the System V Application Binary Interface,
* Intel386(tm) Architecture Processor Supplement, Fourth Edition.
*/
/*
* General register state
*/
#define _NGREG 19
typedef int __greg_t;
typedef __greg_t __gregset_t[_NGREG];
#define _REG_GS 0
#define _REG_FS 1
#define _REG_ES 2
#define _REG_DS 3
#define _REG_EDI 4
#define _REG_ESI 5
#define _REG_EBP 6
#define _REG_ESP 7
#define _REG_EBX 8
#define _REG_EDX 9
#define _REG_ECX 10
#define _REG_EAX 11
#define _REG_TRAPNO 12
#define _REG_ERR 13
#define _REG_EIP 14
#define _REG_CS 15
#define _REG_EFL 16
#define _REG_UESP 17
#define _REG_SS 18
/*
* Floating point register state
*/
typedef struct {
union {
struct {
int __fp_state[27]; /* Environment and registers */
int __fp_status; /* Software status word */
} __fpchip_state;
struct {
char __fp_emul[246];
char __fp_epad[2];
} __fp_emul_space;
struct {
char __fp_xmm[512];
} __fp_xmm_state;
int __fp_fpregs[128];
} __fp_reg_set;
long __fp_wregs[33]; /* Weitek? */
} __fpregset_t;
typedef struct {
__gregset_t __gregs;
__fpregset_t __fpregs;
__greg_t _mc_tlsbase;
#ifdef __minix
int mc_magic; int mc_magic;
struct stackframe_s mc_p_reg; int mc_flags;
union fpu_state_u mc_fpu_state; #endif
short mc_fpu_flags;
} mcontext_t; } mcontext_t;
__BEGIN_DECLS #ifdef __minix
#define _MC_FPU_SAVED 0x001
#endif
#define _UC_FXSAVE 0x20 /* FP state is in FXSAVE format in XMM space */
#define _UC_MACHINE_PAD 4 /* Padding appended to ucontext_t */
#define _UC_UCONTEXT_ALIGN (~0xf)
#ifdef _KERNEL_OPT
#include "opt_vm86.h"
#ifdef VM86
/*#include <machine/psl.h>*/
#define PSL_VM 0x00020000
#define _UC_MACHINE_SP(uc) ((uc)->uc_mcontext.__gregs[_REG_UESP] + \
((uc)->uc_mcontext.__gregs[_REG_EFL] & PSL_VM ? \
((uc)->uc_mcontext.__gregs[_REG_SS] << 4) : 0))
#endif /* VM86 */
#endif /* _KERNEL_OPT */
#ifndef _UC_MACHINE_SP
#define _UC_MACHINE_SP(uc) ((uc)->uc_mcontext.__gregs[_REG_UESP])
#endif
#define _UC_MACHINE_PC(uc) ((uc)->uc_mcontext.__gregs[_REG_EIP])
#define _UC_MACHINE_INTRV(uc) ((uc)->uc_mcontext.__gregs[_REG_EAX])
#define _UC_MACHINE_SET_PC(uc, pc) _UC_MACHINE_PC(uc) = (pc)
#ifdef __minix
#define _UC_MACHINE_STACK(uc) ((uc)->uc_mcontext.__gregs[_REG_ESP])
#define _UC_MACHINE_SET_STACK(uc, esp) _UC_MACHINE_STACK(uc) = (esp)
#define _UC_MACHINE_EBP(uc) ((uc)->uc_mcontext.__gregs[_REG_EBP])
#define _UC_MACHINE_SET_EBP(uc, ebp) _UC_MACHINE_EBP(uc) = (ebp)
#define _UC_MACHINE_ESI(uc) ((uc)->uc_mcontext.__gregs[_REG_ESI])
#define _UC_MACHINE_SET_ESI(uc, esi) _UC_MACHINE_ESI(uc) = (esi)
#endif
#define __UCONTEXT_SIZE 776
static __inline void *
__lwp_getprivate_fast(void)
{
void *__tmp;
__asm volatile("movl %%gs:0, %0" : "=r" (__tmp));
return __tmp;
}
#ifdef __minix
int setmcontext(const mcontext_t *mcp); int setmcontext(const mcontext_t *mcp);
int getmcontext(mcontext_t *mcp); int getmcontext(mcontext_t *mcp);
__END_DECLS #define MCF_MAGIC 0xc0ffee
#endif
#endif /* _MACHINE_MCONTEXT_H */ #endif /* !_I386_MCONTEXT_H_ */

View file

@ -109,7 +109,7 @@ struct __ucontext {
#ifdef _KERNEL #ifdef _KERNEL
struct lwp; struct lwp;
#ifdef __UCONTEXT_SIZE #if defined(__UCONTEXT_SIZE) && !defined(__minix)
__CTASSERT(sizeof(ucontext_t) == __UCONTEXT_SIZE); __CTASSERT(sizeof(ucontext_t) == __UCONTEXT_SIZE);
#endif #endif
@ -123,7 +123,7 @@ int cpu_mcontext_validate(struct lwp *, const mcontext_t *);
#ifdef __minix #ifdef __minix
__BEGIN_DECLS __BEGIN_DECLS
void resumecontext(ucontext_t *ucp); void resumecontext(ucontext_t *ucp);
#ifdef __UCONTEXT_SIZE #if defined(__UCONTEXT_SIZE) && !defined(__minix)
__CTASSERT(sizeof(ucontext_t) == __UCONTEXT_SIZE); __CTASSERT(sizeof(ucontext_t) == __UCONTEXT_SIZE);
#endif #endif