xref: /minix3/minix/kernel/system/do_mcontext.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
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