#include "kernel/system.h"
#include <string.h>
+#include <assert.h>
#include <machine/mcontext.h>
#if USE_MCONTEXT
/* Get the mcontext structure into our address space. */
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);
+ mc.mc_flags = 0;
#if defined(__i386__)
/* Copy FPU state */
- mc.mc_fpu_flags = 0;
if (proc_used_fpu(rp)) {
/* make sure that the FPU context is saved into proc structure first */
save_fpu(rp);
- mc.mc_fpu_flags = rp->p_misc_flags & MF_FPU_INITIALIZED;
- memcpy(&(mc.mc_fpu_state), rp->p_seg.fpu_state, FPU_XFP_SIZE);
+ mc.mc_flags = (rp->p_misc_flags & MF_FPU_INITIALIZED) ? _MC_FPU_SAVED : 0;
+ 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
/* Copy the mcontext structure to the user's address space. */
if ((r = data_copy(KERNEL, (vir_bytes) &mc, m_ptr->PR_ENDPT,
(vir_bytes) m_ptr->PR_CTX_PTR,
- (phys_bytes) sizeof(struct __mcontext))) != OK)
+ (phys_bytes) sizeof(mcontext_t))) != OK)
return(r);
return(OK);
/* Get the mcontext structure into our address space. */
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);
#if defined(__i386__)
/* 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;
- 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
rp->p_misc_flags &= ~MF_FPU_INITIALIZED;
/* force reloading FPU in either case */
member UC_FLAGS uc_flags
member UC_LINK uc_link
member MAGIC uc_mcontext.mc_magic
-member REG0 uc_mcontext.mc_p_reg.retreg
-member REG1 uc_mcontext.mc_p_reg.r1
-member REG2 uc_mcontext.mc_p_reg.r2
-member REG3 uc_mcontext.mc_p_reg.r3
-member REG4 uc_mcontext.mc_p_reg.r4
-member REG5 uc_mcontext.mc_p_reg.r5
-member REG6 uc_mcontext.mc_p_reg.r6
-member REG7 uc_mcontext.mc_p_reg.r7
-member REG8 uc_mcontext.mc_p_reg.r8
-member REG9 uc_mcontext.mc_p_reg.r9
-member REG10 uc_mcontext.mc_p_reg.r10
-member FPREG uc_mcontext.mc_p_reg.fp
-member REG12 uc_mcontext.mc_p_reg.r12
-member SPREG uc_mcontext.mc_p_reg.sp
-member LRREG uc_mcontext.mc_p_reg.lr
-member PCREG uc_mcontext.mc_p_reg.pc
+member REG0 uc_mcontext.__gregs[_REG_R0]
+member REG1 uc_mcontext.__gregs[_REG_R1]
+member REG2 uc_mcontext.__gregs[_REG_R2]
+member REG3 uc_mcontext.__gregs[_REG_R3]
+member REG4 uc_mcontext.__gregs[_REG_R4]
+member REG5 uc_mcontext.__gregs[_REG_R5]
+member REG6 uc_mcontext.__gregs[_REG_R6]
+member REG7 uc_mcontext.__gregs[_REG_R7]
+member REG8 uc_mcontext.__gregs[_REG_R8]
+member REG9 uc_mcontext.__gregs[_REG_R9]
+member REG10 uc_mcontext.__gregs[_REG_R10]
+member FPREG uc_mcontext.__gregs[_REG_FP]
+member REG12 uc_mcontext.__gregs[_REG_R12]
+member SPREG uc_mcontext.__gregs[_REG_SP]
+member LRREG uc_mcontext.__gregs[_REG_LR]
+member PCREG uc_mcontext.__gregs[_REG_PC]
define EFAULT EFAULT
define EINVAL EINVAL
define MCF_MAGIC MCF_MAGIC
member UC_FLAGS uc_flags
member UC_LINK uc_link
member MAGIC uc_mcontext.mc_magic
-member DI uc_mcontext.mc_p_reg.di
-member SI uc_mcontext.mc_p_reg.si
-member BP uc_mcontext.mc_p_reg.fp
-member AX uc_mcontext.mc_p_reg.retreg
-member BX uc_mcontext.mc_p_reg.bx
-member CX uc_mcontext.mc_p_reg.cx
-member DX uc_mcontext.mc_p_reg.dx
-member PC uc_mcontext.mc_p_reg.pc
-member SP uc_mcontext.mc_p_reg.sp
+member DI uc_mcontext.__gregs[_REG_EDI]
+member SI uc_mcontext.__gregs[_REG_ESI]
+member BP uc_mcontext.__gregs[_REG_EBP]
+member AX uc_mcontext.__gregs[_REG_EAX]
+member BX uc_mcontext.__gregs[_REG_EBX]
+member CX uc_mcontext.__gregs[_REG_ECX]
+member DX uc_mcontext.__gregs[_REG_EDX]
+member PC uc_mcontext.__gregs[_REG_EIP]
+member SP uc_mcontext.__gregs[_REG_ESP]
define EFAULT EFAULT
define EINVAL EINVAL
define MCF_MAGIC MCF_MAGIC
} else if ((ucp->uc_stack.ss_sp == NULL) ||
(ucp->uc_stack.ss_size < MINSIGSTKSZ)) {
ucp->uc_mcontext.mc_magic = 0;
- ucp->uc_mcontext.mc_p_reg.sp = 0;
+ _UC_MACHINE_SET_STACK(ucp, 0);
return;
}
/* Adjust the machine context to point to the top of this stack and the
program counter to the context start wrapper. */
- ucp->uc_mcontext.mc_p_reg.fp = 0; /* Clear frame pointer */
- ucp->uc_mcontext.mc_p_reg.sp = (reg_t) stack_top;
- ucp->uc_mcontext.mc_p_reg.pc = (reg_t) ctx_start;
+ _UC_MACHINE_SET_EBP(ucp, 0); /* Clear frame pointer */
+ _UC_MACHINE_SET_STACK(ucp, (reg_t) stack_top);
+ _UC_MACHINE_SET_PC(ucp, (reg_t) ctx_start);
*stack_top++ = (uintptr_t) func;
/* 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
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,
swapcontext will choke on this and return ENOMEM. */
- if (stack_top == ucp->uc_stack.ss_sp)
- ucp->uc_mcontext.mc_p_reg.sp = 0;
+ if (stack_top == ucp->uc_stack.ss_sp) {
+ _UC_MACHINE_SET_STACK(ucp, 0);
+ }
#elif defined(__arm__)
/* 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
/* 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
ctx_start runs after 'func'. Save ucp in r4 */
- ucp->uc_mcontext.mc_p_reg.fp = 0; /* Clear frame pointer */
- ucp->uc_mcontext.mc_p_reg.sp = (reg_t) stack_top;
- ucp->uc_mcontext.mc_p_reg.pc = (reg_t) func;
- ucp->uc_mcontext.mc_p_reg.lr = (reg_t) ctx_start;
- ucp->uc_mcontext.mc_p_reg.r4 = (reg_t) ucp;
+ _UC_MACHINE_SET_FP(ucp, 0); /* Clear frame pointer */
+ _UC_MACHINE_SET_STACK(ucp, (reg_t) stack_top);
+ _UC_MACHINE_SET_PC(ucp, (reg_t) func);
+ _UC_MACHINE_SET_LR(ucp, (reg_t) ctx_start);
+ _UC_MACHINE_SET_R4(ucp, (reg_t) ucp);
/* Copy arguments to r0-r3 and stack. */
va_start(ap, argc);
/* Pass up to four arguments in registers. */
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)
- 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)
- 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)
- 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. */
while (argc-- > 0) {
*stack_top++ = va_arg(ap, uintptr_t);
/* If we ran out of stack space, invalidate stack pointer. Eventually,
swapcontext will choke on this and return ENOMEM. */
- if (stack_top == ucp->uc_stack.ss_sp)
- ucp->uc_mcontext.mc_p_reg.sp = 0;
+ if (stack_top == ucp->uc_stack.ss_sp) {
+ _UC_MACHINE_SET_STACK(ucp, 0);
+ }
#else
# error "Unsupported platform"
#endif
return(-1);
}
- if (ucp->uc_mcontext.mc_p_reg.sp == 0) {
+ if (_UC_MACHINE_STACK(ucp) == 0) {
/* No stack space. Bail out. */
errno = ENOMEM;
return(-1);
*===========================================================================*/
void mthread_stacktrace(mthread_thread_t t)
{
+#ifdef __i386__ /* stacktrace only implemented on x86 */
unsigned long bp, hbp, pc;
mthread_tcb_t *tcb;
ucontext_t *ctx;
- mcontext_t *mtx;
- struct stackframe_s *frame;
tcb = mthread_find_tcb(t);
ctx = &tcb->m_context;
printf("thread %d: ", t);
- mtx = &ctx->uc_mcontext;
- frame = &mtx->mc_p_reg;
- bp = frame->fp;
+ bp = _UC_MACHINE_EBP(ctx);
while (bp) {
pc = ((unsigned long *) bp)[1];
}
printf("\n");
+#endif
}
/*===========================================================================*
-#ifndef _MACHINE_MCONTEXT_H
-#define _MACHINE_MCONTEXT_H
+/* $NetBSD: mcontext.h,v 1.11 2012/08/03 07:59:23 matt Exp $ */
-#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_
+
+/*
+ * 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;
+#endif
+} mcontext_t, mcontext32_t;
+
+/* 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])
-/* Context to describe processor state */
-typedef struct __mcontext {
- int mc_magic;
- struct stackframe_s mc_p_reg;
-} mcontext_t;
+#define _UC_MACHINE_SET_PC(uc, pc) _UC_MACHINE_PC(uc) = (pc)
-__BEGIN_DECLS
+#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 getmcontext(mcontext_t *mcp);
-__END_DECLS
+#define MCF_MAGIC 0xc0ffee
+#endif
-#endif /* _MACHINE_MCONTEXT_H */
+#endif /* !_ARM_MCONTEXT_H_ */
-#ifndef _MACHINE_MCONTEXT_H
-#define _MACHINE_MCONTEXT_H 1
+/* $NetBSD: mcontext.h,v 1.10 2011/02/25 14:07:13 joerg Exp $ */
-#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_
+
+
+/*
+ * 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
-/* Context to describe processor state */
-typedef struct __mcontext {
- int mc_magic;
- struct stackframe_s mc_p_reg;
- union fpu_state_u mc_fpu_state;
- short mc_fpu_flags;
+/*
+ * 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_flags;
+#endif
} 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 getmcontext(mcontext_t *mcp);
-__END_DECLS
+#define MCF_MAGIC 0xc0ffee
+#endif
-#endif /* _MACHINE_MCONTEXT_H */
+#endif /* !_I386_MCONTEXT_H_ */
#ifdef _KERNEL
struct lwp;
-#ifdef __UCONTEXT_SIZE
+#if defined(__UCONTEXT_SIZE) && !defined(__minix)
__CTASSERT(sizeof(ucontext_t) == __UCONTEXT_SIZE);
#endif
#ifdef __minix
__BEGIN_DECLS
void resumecontext(ucontext_t *ucp);
-#ifdef __UCONTEXT_SIZE
+#if defined(__UCONTEXT_SIZE) && !defined(__minix)
__CTASSERT(sizeof(ucontext_t) == __UCONTEXT_SIZE);
#endif