1 /* The kernel calls that are implemented in this file:
2 * m_type: SYS_SETMCONTEXT
3 * m_type: SYS_GETMCONTEXT
5 * The parameters for these kernel calls are:
6 * m1_i1: PR_ENDPT # proc endpoint doing call
7 * m1_p1: PR_MEM_PTR # pointer to mcontext structure
11 #include "kernel/system.h"
14 #include <machine/mcontext.h>
17 /*===========================================================================*
19 *===========================================================================*/
20 int do_getmcontext(struct proc
* caller
, message
* m_ptr
)
22 /* Retrieve machine context of a process */
24 register struct proc
*rp
;
28 if (! isokendpt(m_ptr
->PR_ENDPT
, &proc_nr
)) return(EINVAL
);
29 if (iskerneln(proc_nr
)) return(EPERM
);
30 rp
= proc_addr(proc_nr
);
33 if (!proc_used_fpu(rp
))
34 return(OK
); /* No state to copy */
37 /* Get the mcontext structure into our address space. */
38 if ((r
= data_copy(m_ptr
->PR_ENDPT
, (vir_bytes
) m_ptr
->PR_CTX_PTR
, KERNEL
,
39 (vir_bytes
) &mc
, (phys_bytes
) sizeof(mcontext_t
))) != OK
)
45 if (proc_used_fpu(rp
)) {
46 /* make sure that the FPU context is saved into proc structure first */
48 mc
.mc_flags
= (rp
->p_misc_flags
& MF_FPU_INITIALIZED
) ? _MC_FPU_SAVED
: 0;
49 assert(sizeof(mc
.__fpregs
.__fp_reg_set
) == FPU_XFP_SIZE
);
50 memcpy(&(mc
.__fpregs
.__fp_reg_set
), rp
->p_seg
.fpu_state
, FPU_XFP_SIZE
);
55 /* Copy the mcontext structure to the user's address space. */
56 if ((r
= data_copy(KERNEL
, (vir_bytes
) &mc
, m_ptr
->PR_ENDPT
,
57 (vir_bytes
) m_ptr
->PR_CTX_PTR
,
58 (phys_bytes
) sizeof(mcontext_t
))) != OK
)
65 /*===========================================================================*
67 *===========================================================================*/
68 int do_setmcontext(struct proc
* caller
, message
* m_ptr
)
70 /* Set machine context of a process */
72 register struct proc
*rp
;
76 if (!isokendpt(m_ptr
->PR_ENDPT
, &proc_nr
)) return(EINVAL
);
77 rp
= proc_addr(proc_nr
);
79 /* Get the mcontext structure into our address space. */
80 if ((r
= data_copy(m_ptr
->PR_ENDPT
, (vir_bytes
) m_ptr
->PR_CTX_PTR
, KERNEL
,
81 (vir_bytes
) &mc
, (phys_bytes
) sizeof(mcontext_t
))) != OK
)
86 if (mc
.mc_flags
& _MC_FPU_SAVED
) {
87 rp
->p_misc_flags
|= MF_FPU_INITIALIZED
;
88 assert(sizeof(mc
.__fpregs
.__fp_reg_set
) == FPU_XFP_SIZE
);
89 memcpy(rp
->p_seg
.fpu_state
, &(mc
.__fpregs
.__fp_reg_set
), FPU_XFP_SIZE
);
91 rp
->p_misc_flags
&= ~MF_FPU_INITIALIZED
;
92 /* force reloading FPU in either case */