1*433d6423SLionel Sambuc /* The kernel calls that are implemented in this file:
2*433d6423SLionel Sambuc * m_type: SYS_SETMCONTEXT
3*433d6423SLionel Sambuc * m_type: SYS_GETMCONTEXT
4*433d6423SLionel Sambuc *
5*433d6423SLionel Sambuc * The parameters for SYS_SETMCONTEXT kernel call are:
6*433d6423SLionel Sambuc * m_lsys_krn_sys_setmcontext.endpt # proc endpoint doing call
7*433d6423SLionel Sambuc * m_lsys_krn_sys_setmcontext.ctx_ptr # pointer to mcontext structure
8*433d6423SLionel Sambuc *
9*433d6423SLionel Sambuc * The parameters for SYS_GETMCONTEXT kernel call are:
10*433d6423SLionel Sambuc * m_lsys_krn_sys_getmcontext.endpt # proc endpoint doing call
11*433d6423SLionel Sambuc * m_lsys_krn_sys_getmcontext.ctx_ptr # pointer to mcontext structure
12*433d6423SLionel Sambuc */
13*433d6423SLionel Sambuc
14*433d6423SLionel Sambuc #include "kernel/system.h"
15*433d6423SLionel Sambuc #include <string.h>
16*433d6423SLionel Sambuc #include <assert.h>
17*433d6423SLionel Sambuc #include <machine/mcontext.h>
18*433d6423SLionel Sambuc
19*433d6423SLionel Sambuc #if USE_MCONTEXT
20*433d6423SLionel Sambuc /*===========================================================================*
21*433d6423SLionel Sambuc * do_getmcontext *
22*433d6423SLionel Sambuc *===========================================================================*/
do_getmcontext(struct proc * caller,message * m_ptr)23*433d6423SLionel Sambuc int do_getmcontext(struct proc * caller, message * m_ptr)
24*433d6423SLionel Sambuc {
25*433d6423SLionel Sambuc /* Retrieve machine context of a process */
26*433d6423SLionel Sambuc
27*433d6423SLionel Sambuc register struct proc *rp;
28*433d6423SLionel Sambuc int proc_nr, r;
29*433d6423SLionel Sambuc mcontext_t mc;
30*433d6423SLionel Sambuc
31*433d6423SLionel Sambuc if (!isokendpt(m_ptr->m_lsys_krn_sys_getmcontext.endpt, &proc_nr))
32*433d6423SLionel Sambuc return(EINVAL);
33*433d6423SLionel Sambuc if (iskerneln(proc_nr)) return(EPERM);
34*433d6423SLionel Sambuc rp = proc_addr(proc_nr);
35*433d6423SLionel Sambuc
36*433d6423SLionel Sambuc #if defined(__i386__)
37*433d6423SLionel Sambuc if (!proc_used_fpu(rp))
38*433d6423SLionel Sambuc return(OK); /* No state to copy */
39*433d6423SLionel Sambuc #endif
40*433d6423SLionel Sambuc
41*433d6423SLionel Sambuc /* Get the mcontext structure into our address space. */
42*433d6423SLionel Sambuc if ((r = data_copy(m_ptr->m_lsys_krn_sys_getmcontext.endpt,
43*433d6423SLionel Sambuc m_ptr->m_lsys_krn_sys_getmcontext.ctx_ptr, KERNEL,
44*433d6423SLionel Sambuc (vir_bytes) &mc, (phys_bytes) sizeof(mcontext_t))) != OK)
45*433d6423SLionel Sambuc return(r);
46*433d6423SLionel Sambuc
47*433d6423SLionel Sambuc mc.mc_flags = 0;
48*433d6423SLionel Sambuc #if defined(__i386__)
49*433d6423SLionel Sambuc /* Copy FPU state */
50*433d6423SLionel Sambuc if (proc_used_fpu(rp)) {
51*433d6423SLionel Sambuc /* make sure that the FPU context is saved into proc structure first */
52*433d6423SLionel Sambuc save_fpu(rp);
53*433d6423SLionel Sambuc mc.mc_flags = (rp->p_misc_flags & MF_FPU_INITIALIZED) ? _MC_FPU_SAVED : 0;
54*433d6423SLionel Sambuc assert(sizeof(mc.__fpregs.__fp_reg_set) == FPU_XFP_SIZE);
55*433d6423SLionel Sambuc memcpy(&(mc.__fpregs.__fp_reg_set), rp->p_seg.fpu_state, FPU_XFP_SIZE);
56*433d6423SLionel Sambuc }
57*433d6423SLionel Sambuc #endif
58*433d6423SLionel Sambuc
59*433d6423SLionel Sambuc
60*433d6423SLionel Sambuc /* Copy the mcontext structure to the user's address space. */
61*433d6423SLionel Sambuc if ((r = data_copy(KERNEL, (vir_bytes) &mc,
62*433d6423SLionel Sambuc m_ptr->m_lsys_krn_sys_getmcontext.endpt,
63*433d6423SLionel Sambuc m_ptr->m_lsys_krn_sys_getmcontext.ctx_ptr,
64*433d6423SLionel Sambuc (phys_bytes) sizeof(mcontext_t))) != OK)
65*433d6423SLionel Sambuc return(r);
66*433d6423SLionel Sambuc
67*433d6423SLionel Sambuc return(OK);
68*433d6423SLionel Sambuc }
69*433d6423SLionel Sambuc
70*433d6423SLionel Sambuc
71*433d6423SLionel Sambuc /*===========================================================================*
72*433d6423SLionel Sambuc * do_setmcontext *
73*433d6423SLionel Sambuc *===========================================================================*/
do_setmcontext(struct proc * caller,message * m_ptr)74*433d6423SLionel Sambuc int do_setmcontext(struct proc * caller, message * m_ptr)
75*433d6423SLionel Sambuc {
76*433d6423SLionel Sambuc /* Set machine context of a process */
77*433d6423SLionel Sambuc
78*433d6423SLionel Sambuc register struct proc *rp;
79*433d6423SLionel Sambuc int proc_nr, r;
80*433d6423SLionel Sambuc mcontext_t mc;
81*433d6423SLionel Sambuc
82*433d6423SLionel Sambuc if (!isokendpt(m_ptr->m_lsys_krn_sys_setmcontext.endpt, &proc_nr)) return(EINVAL);
83*433d6423SLionel Sambuc rp = proc_addr(proc_nr);
84*433d6423SLionel Sambuc
85*433d6423SLionel Sambuc /* Get the mcontext structure into our address space. */
86*433d6423SLionel Sambuc if ((r = data_copy(m_ptr->m_lsys_krn_sys_setmcontext.endpt,
87*433d6423SLionel Sambuc m_ptr->m_lsys_krn_sys_setmcontext.ctx_ptr, KERNEL,
88*433d6423SLionel Sambuc (vir_bytes) &mc, (phys_bytes) sizeof(mcontext_t))) != OK)
89*433d6423SLionel Sambuc return(r);
90*433d6423SLionel Sambuc
91*433d6423SLionel Sambuc #if defined(__i386__)
92*433d6423SLionel Sambuc /* Copy FPU state */
93*433d6423SLionel Sambuc if (mc.mc_flags & _MC_FPU_SAVED) {
94*433d6423SLionel Sambuc rp->p_misc_flags |= MF_FPU_INITIALIZED;
95*433d6423SLionel Sambuc assert(sizeof(mc.__fpregs.__fp_reg_set) == FPU_XFP_SIZE);
96*433d6423SLionel Sambuc memcpy(rp->p_seg.fpu_state, &(mc.__fpregs.__fp_reg_set), FPU_XFP_SIZE);
97*433d6423SLionel Sambuc } else
98*433d6423SLionel Sambuc rp->p_misc_flags &= ~MF_FPU_INITIALIZED;
99*433d6423SLionel Sambuc /* force reloading FPU in either case */
100*433d6423SLionel Sambuc release_fpu(rp);
101*433d6423SLionel Sambuc #endif
102*433d6423SLionel Sambuc
103*433d6423SLionel Sambuc return(OK);
104*433d6423SLionel Sambuc }
105*433d6423SLionel Sambuc
106*433d6423SLionel Sambuc #endif
107