~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Minix Cross Reference
Minix/kernel/mpx.c


  1 static char *rcsid = "$Id: mpx.c,v 1.2 1996/07/09 19:41:39 paul Exp $";
  2 
  3 /*
  4  * This file contains functions to handle context switching and SunOS signals
  5  * in smx.  As signals cause context switches, the two are closely related.
  6  * The entry points for the file are:
  7  *
  8  *       restart - called from the bootstrap code to schedule the first process
  9  *       idle_task - the main body of the idle task.
 10  *
 11  * The SunOSsig function could also be considered an entry point.  It is
 12  * the handler for all SunOS signals, and so is called whenever a SunOS
 13  * signal occurs.  It is the sole entry point for the layer 1 code once
 14  * the first process has been scheduled for the first time.
 15  */
 16 
 17 #include "kernel.h"
 18 #include "proc.h"
 19 #include "sunsighandle.h"
 20 
 21 #include <sun/syscall.h>
 22 
 23 /*
 24  * Check that the context size calculated by make_context (UC_SIZE)
 25  * matches the smx CONTEXT_SIZE.
 26  */
 27 #if (CONTEXT_SIZE != UC_SIZE)
 28 error "p_reg is the wrong size"
 29 #endif
 30 
 31 static double gwin_save_area[GWIN_SIZE / sizeof(double) + 1];
 32 struct proc *gwin_proc = 0;
 33 
 34 
 35 /*
 36  * mpx_start and mpx_end are dummy functions used to delimit the section
 37  * of this file (the resume and SunOSsig functions) that must remain
 38  * executable even when execution is outside the kernel.  These labels
 39  * are needed by code in sunprotect.c
 40  */
 41 
 42 void mpx_start() {}
 43 
 44 /*
 45  * Function: resume
 46  * Parameter: ctxt - double-word aligned context area that we can copy
 47  *                   the context of proc_ptr.
 48  *
 49  * Resume execution of the the current process as given by proc_ptr.
 50  * We make a local copy of the context to restore for two reasons: to double
 51  * word align it, and so that if full memory protection is enabled we
 52  * still have access to the context after leaving_kernel has done its work.
 53  * Callers must ensure that ctxt points to a double-word aligned area on the
 54  * stack.  If a gwin structure is to be restored, it is first copied to
 55  * an array local to resume for the same reasons.
 56  */
 57 static void resume(reg_t *ctxt)
 58 {
 59     double local_save_area[GWIN_SIZE / sizeof(double) + 1];
 60     
 61     memcpy(ctxt, &proc_ptr->p_reg, sizeof(proc_ptr->p_reg));
 62     
 63     /*
 64      * Clear signal mask---no SunOS signals are masked when execution is
 65      * outside layer 1.
 66      */
 67     memset(&ctxt[UC_SIGMASK], 0, SIGSET_SIZE);
 68 
 69     /*
 70      * Set the sig mask flag bit to ensure the signal mask gets restored.
 71      */
 72     ctxt[UC_FLAGS] |= 1;
 73     if (ctxt[UC_GWINS] != 0) {
 74         /*
 75          * A gwins structure must be restored.  Copy it in, and update the
 76          * gwin pointer in the context to be restored.
 77          */
 78         gwin_proc = 0;
 79         memcpy(local_save_area, gwin_save_area, sizeof(local_save_area));
 80         ctxt[UC_GWINS] = (reg_t) local_save_area;
 81     }
 82     leaving_kernel();
 83 
 84     /*
 85      * Do a context switch.  This call should never return, with layer 1 code
 86      * being re-entered via SunOSsig.
 87      */
 88     SunOS(SYS_context, 1, ctxt);
 89     printf("Gwin = 0x%x, fpuq = 0x%x, ctxt = 0x%x\n", ctxt[UC_GWINS],
 90            ctxt[UC_FPU_Q], ctxt);
 91     panic("resume: failed to resume an smx process", errno);
 92 }    
 93 
 94 
 95 /*
 96  * Function: SunOSsig
 97  * Parameters: sig - the SunOS signal that has occurred
 98  *             siginfo - additional info about the signal
 99  *             ucontext - context for the smx process that was running when
100  *                        the SunOS signal ocurred.
101  *
102  * This function is the handler for all signals received by the SunOS
103  * process running smx.  The 'ucontext' structure pushed onto the
104  * kernel (signal) stack by Solaris is copied into the MINIX proc
105  * table entry of the currently executing MINIX process. The array
106  * 'vectors' is used to determine which function within the smx
107  * kernel should then take responsibilty for the signal. Finally, the
108  * context of an smx process is restored.
109  */
110 void SunOSsig(int sig, void *siginfo, reg_t ucontext[])
111 {
112     entering_kernel();
113 
114     /*
115      * Is there a gwins structure to save (should only happen when the stack
116      * of a user process needs extending).  The single save area is sufficient
117      * because once it is in use the process using it will be the next user 
118      * process to run (the scheduler ensures this).
119      */
120     if (ucontext[UC_GWINS] != 0) {
121         if (gwin_proc != 0) {
122             panic("SunOSsig---save area used", NO_NUM);
123         }
124         if (!isuserp(proc_ptr)) {
125             panic("UC_GWINS non-zero in process", proc_number(proc_ptr));
126         }
127         gwin_proc = proc_ptr;
128         memcpy(gwin_save_area, (char *) ucontext[UC_GWINS],
129                sizeof(gwin_save_area));
130     }
131     /*
132      * Save the ucontext structure into the current proc table entry.
133      */
134      memcpy(&proc_ptr->p_reg, ucontext, sizeof(proc_ptr->p_reg));
135 
136 
137     if (sig < 0 || sig >= vectorlen)
138         panic("SunOS signal too large or too small", sig);
139     (*vectors[sig])(sig, siginfo, ucontext);      /* Call the handler */
140         
141     lock_pick_proc();         /* (possibly) choose a new process */
142 
143     resume(ucontext);
144     /*NOTREACHED*/
145 }
146 
147 void mpx_end() {}
148 
149 
150 /*
151  * Function: restart
152  *
153  * The 'restart' function is called (only once) from 'main.c' in order
154  * to get the the first process running. 
155  */
156 void restart(void)
157 {
158     struct stackframe_s dummy_regs;
159 
160     k_reenter = 0;      /* Nested interrupt handling is not supported */
161 
162     resume((reg_t *) &dummy_regs);
163     /*NOTREACHED*/
164 }
165 
166 
167 /*****************************************************************************
168  * Some of the functions found in the vectors array.                         *
169  *****************************************************************************/
170 
171 /*
172  * Function: s_call
173  *
174  * s_call is called from SunOSsig to handle the SunOS USR1 signal,
175  * which is sent by an smx process in layers 2-4 to force execution
176  * into layer 1 of smx.  The three system calls are send, receive,
177  * and sndrcv.  s_call simply sets up parameters for a call to the
178  * standard MINIX sys_call function, and passes the return result
179  * back to the calling smx process.
180  */
181 void s_call(void)
182 {
183     phys_bytes param_ptr;       /* ptr to the system call parameters */
184     int function;               /* SEND, RECEIVE, or BOTH */
185     int src_dest;               /* source to receive from or dest to send to */
186     message *m_ptr;             /* pointer to message */
187     int params[3];
188     struct proc *this_proc = proc_ptr;
189 
190     /*
191      * The arguments to sys_call are on the stack.  For the SPARC
192      * stack frame, the first argument is at sp + 92.
193      */
194     param_ptr = umap(this_proc, D, this_proc->p_reg.sp + 92, sizeof(params));
195     if (param_ptr == 0) {
196         panic("s_call: Can't map in parameter to system call", NO_NUM);
197     }
198 
199     /* Load the parameters */
200     phys_copy(param_ptr, vir2phys(&params[0]), sizeof(params));
201     function = params[0];
202     src_dest = params[1];
203     m_ptr = (message *)params[2];   /* Assumes ints can hold a pointer */
204 
205     this_proc->p_reg.retreg = sys_call(function, src_dest, m_ptr);
206 }
207 
208 
209 /*
210  * Function: smx_clock_handler
211  *
212  * Called by SunOSsig whenever a SIGALRM occurs.  Calls clock handler
213  * with 0 ticks, as in smx the SunOS clock is always consulted to
214  * update the time on a clock tick.
215  */
216 void smx_clock_handler(void)
217 {
218     clock_handler(0);
219 }
220 
221 
222 /*==========================================================================*
223  *                             idle_task                                    * 
224  *==========================================================================*/
225 
226 #define SIGPAUSE 0x1000
227 
228 /* Does nothing but sleep waiting for a signal*/
229 
230 void idle_task(void)
231 {
232     for (;;) {
233         SunOS(SYS_signal, (SIGPAUSE | 1));
234     }
235 }
236 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.