]> Zhao Yanbai Git Server - minix.git/commitdiff
<machine/mcontext.h>
authorBen Gras <ben@minix3.org>
Tue, 10 Dec 2013 13:55:46 +0000 (14:55 +0100)
committerLionel Sambuc <lionel@minix3.org>
Mon, 3 Mar 2014 19:47:03 +0000 (20:47 +0100)
Change-Id: I2ad64018f3f402e7ccc5c4dc037dd0a3fe56a929

kernel/system/do_mcontext.c
lib/libc/arch/arm/sys-minix/ucontextoffsets.cf
lib/libc/arch/i386/sys-minix/ucontextoffsets.cf
lib/libc/sys-minix/_ucontext.c
lib/libmthread/misc.c
sys/arch/arm/include/mcontext.h
sys/arch/i386/include/mcontext.h
sys/sys/ucontext.h

index c72ac6fd7cf34ffcdbdf28e9709ce3d4296abf11..e5d74490100366a28990546eed22ffa4f4d965d0 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "kernel/system.h"
 #include <string.h>
+#include <assert.h>
 #include <machine/mcontext.h>
 
 #if USE_MCONTEXT 
@@ -35,17 +36,18 @@ int do_getmcontext(struct proc * caller, message * m_ptr)
 
   /* 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
 
@@ -53,7 +55,7 @@ int do_getmcontext(struct proc * caller, message * m_ptr)
   /* 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);
@@ -76,14 +78,15 @@ int do_setmcontext(struct proc * caller, message * m_ptr)
 
   /* 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 */
index bf21f9e3620940bcfadd4df8a0f5223038365ea2..ad449aac2c7cafd064a1bd41d100a83fc0fa62be 100644 (file)
@@ -8,22 +8,22 @@ struct __ucontext
 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
index 11e1a02c7d604b9d58ba7c6d64e1f06727e63ade..c06f9cdef5be5b89be75a4f4d8bd5925141f469a 100644 (file)
@@ -8,15 +8,15 @@ struct __ucontext
 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
index 96698c76f6e831e506a81d01009b0c72c2c5d3b7..bac0d6f60a959f48fafcf47ceae3b09a95a9b353 100644 (file)
@@ -84,7 +84,7 @@ void makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
   } 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;
   }
 
@@ -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
           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;
 
@@ -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
           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
@@ -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
           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);
@@ -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,
           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
@@ -226,7 +228,7 @@ int swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
        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);
index 51c99c8ab11f81d6dffff41a2aa871388760d50b..8a4ad3fbabe1b72f151dcb8b96922406f6220823 100644 (file)
@@ -116,11 +116,10 @@ void mthread_stats(void)
  *===========================================================================*/
 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;
@@ -130,9 +129,7 @@ void mthread_stacktrace(mthread_thread_t t)
 
   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];
@@ -149,6 +146,7 @@ void mthread_stacktrace(mthread_thread_t t)
   }
 
   printf("\n");
+#endif
 }
 
 /*===========================================================================*
index a016c0172998f5b593d6e7410a9934d92a282b7b..cdfb7c440cd4bf68b845d7984cbd6908ca31e2de 100644 (file)
-#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_ */
index 3f8ab00643a44e26055bbdc199893c29b4252b42..c7e36723e0057aa1def5afc2f9caf030e961e647 100644 (file)
-#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_ */
index 225d1087f78a82520df8f42b1da7a1b91c65167f..b4d0d08907729f4064b4a962dfb8b37ab176d4be 100644 (file)
@@ -109,7 +109,7 @@ struct __ucontext {
 #ifdef _KERNEL
 struct lwp;
 
-#ifdef __UCONTEXT_SIZE
+#if defined(__UCONTEXT_SIZE) && !defined(__minix)
 __CTASSERT(sizeof(ucontext_t) == __UCONTEXT_SIZE);
 #endif
 
@@ -123,7 +123,7 @@ int cpu_mcontext_validate(struct lwp *, const mcontext_t *);
 #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