1 static char rcsid[] = "$Id";
2
3 /* This task handles the interface between file system and kernel as well as
4 * between memory manager and kernel. System services are obtained by sending
5 * sys_task() a message specifying what is needed. To make life easier for
6 * MM and FS, a library is provided with routines whose names are of the
7 * form sys_xxx, e.g. sys_xit sends the SYS_XIT message to sys_task. The
8 * message types and parameters are:
9 *
10 * SYS_FORK informs kernel that a process has forked
11 * SYS_NEWMAP allows MM to set up a process memory map
12 * SYS_GETMAP allows MM to get a process' memory map
13 * SYS_EXEC sets program counter and stack pointer after EXEC
14 * SYS_XIT informs kernel that a process has exited
15 * SYS_GETSP caller wants to read out some process' stack pointer
16 * SYS_TIMES caller wants to get accounting times for a process
17 * SYS_ABORT MM or FS cannot go on; abort MINIX
18 * SYS_FRESH start with a fresh process image during EXEC (68000 & SPARC only)
19 * SYS_SENDSIG send a signal to a process (POSIX style)
20 * SYS_SIGRETURN complete POSIX-style signalling
21 * SYS_KILL cause a signal to be sent via MM
22 * SYS_ENDSIG finish up after SYS_KILL-type signal
23 * SYS_COPY request a block of data to be copied between processes
24 * SYS_VCOPY request a series of data blocks to be copied between procs
25 * SYS_GBOOT copies the boot parameters to a process
26 * SYS_MEM returns the next free chunk of physical memory
27 * SYS_UMAP compute the physical address for a given virtual address
28 * SYS_TRACE request a trace operation
29 *
30 * Message types and parameters:
31 *
32 * m_type PROC1 PROC2 PID MEM_PTR
33 * ------------------------------------------------------
34 * | SYS_FORK | parent | child | pid | |
35 * |------------+---------+---------+---------+---------|
36 * | SYS_NEWMAP | proc nr | | | map ptr |
37 * |------------+---------+---------+---------+---------|
38 * | SYS_EXEC | proc nr | traced | new sp | |
39 * |------------+---------+---------+---------+---------|
40 * | SYS_XIT | parent | exitee | | |
41 * |------------+---------+---------+---------+---------|
42 * | SYS_GETSP | proc nr | | | |
43 * |------------+---------+---------+---------+---------|
44 * | SYS_TIMES | proc nr | | buf ptr | |
45 * |------------+---------+---------+---------+---------|
46 * | SYS_ABORT | | | | |
47 * |------------+---------+---------+---------+---------|
48 * | SYS_FRESH | proc nr | data_cl | | |
49 * |------------+---------+---------+---------+---------|
50 * | SYS_GBOOT | proc nr | | | bootptr |
51 * |------------+---------+---------+---------+---------|
52 * | SYS_GETMAP | proc nr | | | map ptr |
53 * ------------------------------------------------------
54 *
55 * m_type m1_i1 m1_i2 m1_i3 m1_p1
56 * ----------------+---------+---------+---------+--------------
57 * | SYS_VCOPY | src p | dst p | vec siz | vc addr |
58 * |---------------+---------+---------+---------+-------------|
59 * | SYS_SENDSIG | proc nr | | | smp |
60 * |---------------+---------+---------+---------+-------------|
61 * | SYS_SIGRETURN | proc nr | | | scp |
62 * |---------------+---------+---------+---------+-------------|
63 * | SYS_ENDSIG | proc nr | | | |
64 * -------------------------------------------------------------
65 *
66 * m_type m2_i1 m2_i2 m2_l1 m2_l2
67 * ------------------------------------------------------
68 * | SYS_TRACE | proc_nr | request | addr | data |
69 * ------------------------------------------------------
70 *
71 *
72 * m_type m6_i1 m6_i2 m6_i3 m6_f1
73 * ------------------------------------------------------
74 * | SYS_KILL | proc_nr | sig | | |
75 * ------------------------------------------------------
76 *
77 *
78 * m_type m5_c1 m5_i1 m5_l1 m5_c2 m5_i2 m5_l2 m5_l3
79 * --------------------------------------------------------------------------
80 * | SYS_COPY |src seg|src proc|src vir|dst seg|dst proc|dst vir| byte ct |
81 * --------------------------------------------------------------------------
82 * | SYS_UMAP | seg |proc nr |vir adr| | | | byte ct |
83 * --------------------------------------------------------------------------
84 *
85 *
86 * m_type m1_i1 m1_i2 m1_i3
87 * |------------+----------+----------+----------
88 * | SYS_MEM | mem base | mem size | tot mem |
89 * ----------------------------------------------
90 *
91 * In addition to the main sys_task() entry point, there are 5 other minor
92 * entry points:
93 * cause_sig: take action to cause a signal to occur, sooner or later
94 * inform: tell MM about pending signals
95 * numap: umap D segment starting from process number instead of pointer
96 * umap: compute the physical address for a given virtual address
97 * alloc_segments: allocate segments for 8088 or higher processor
98 */
99
100 #include "kernel.h"
101 #include <signal.h>
102 #include <unistd.h>
103 #include <sys/sigcontext.h>
104 #include <sys/ptrace.h>
105 #include <minix/boot.h>
106 #include <minix/callnr.h>
107 #include <minix/com.h>
108 #include "proc.h"
109 #if (CHIP == INTEL)
110 #include "protect.h"
111 #endif
112 #if (MACHINE == SUN)
113 #include "logging.h"
114 #endif
115
116 /* PSW masks. */
117 #define IF_MASK 0x00000200
118 #define IOPL_MASK 0x003000
119
120 PRIVATE message m;
121 #if (MACHINE != SUN)
122 PRIVATE char sig_stuff[SIG_PUSH_BYTES]; /* used to send signals to processes */
123 #endif
124
125 FORWARD _PROTOTYPE( int do_abort, (message *m_ptr) );
126 FORWARD _PROTOTYPE( int do_copy, (message *m_ptr) );
127 FORWARD _PROTOTYPE( int do_exec, (message *m_ptr) );
128 FORWARD _PROTOTYPE( int do_fork, (message *m_ptr) );
129 FORWARD _PROTOTYPE( int do_gboot, (message *m_ptr) );
130 FORWARD _PROTOTYPE( int do_getsp, (message *m_ptr) );
131 FORWARD _PROTOTYPE( int do_kill, (message *m_ptr) );
132 FORWARD _PROTOTYPE( int do_mem, (message *m_ptr) );
133 FORWARD _PROTOTYPE( int do_newmap, (message *m_ptr) );
134 FORWARD _PROTOTYPE( int do_sendsig, (message *m_ptr) );
135 FORWARD _PROTOTYPE( int do_sigreturn, (message *m_ptr) );
136 FORWARD _PROTOTYPE( int do_endsig, (message *m_ptr) );
137 FORWARD _PROTOTYPE( int do_times, (message *m_ptr) );
138 FORWARD _PROTOTYPE( int do_trace, (message *m_ptr) );
139 FORWARD _PROTOTYPE( int do_umap, (message *m_ptr) );
140 FORWARD _PROTOTYPE( int do_xit, (message *m_ptr) );
141 FORWARD _PROTOTYPE( int do_vcopy, (message *m_ptr) );
142 FORWARD _PROTOTYPE( int do_getmap, (message *m_ptr) );
143
144 #if (SHADOWING == 1)
145 FORWARD _PROTOTYPE( int do_fresh, (message *m_ptr) );
146 #endif
147
148
149 /*===========================================================================*
150 * sys_task *
151 *===========================================================================*/
152 PUBLIC void sys_task()
153 {
154 /* Main entry point of sys_task. Get the message and dispatch on type. */
155
156 register int r;
157
158 debug_str("System task starting\n");
159
160 while (TRUE) {
161 receive(ANY, &m);
162
163 switch (m.m_type) { /* which system call */
164 case SYS_FORK: r = do_fork(&m); break;
165 case SYS_NEWMAP: r = do_newmap(&m); break;
166 case SYS_GETMAP: r = do_getmap(&m); break;
167 case SYS_EXEC: r = do_exec(&m); break;
168 case SYS_XIT: r = do_xit(&m); break;
169 case SYS_GETSP: r = do_getsp(&m); break;
170 case SYS_TIMES: r = do_times(&m); break;
171 case SYS_ABORT: r = do_abort(&m); break;
172 #if (SHADOWING == 1)
173 case SYS_FRESH: r = do_fresh(&m); break;
174 #endif
175 case SYS_SENDSIG: r = do_sendsig(&m); break;
176 case SYS_SIGRETURN: r = do_sigreturn(&m); break;
177 case SYS_KILL: r = do_kill(&m); break;
178 case SYS_ENDSIG: r = do_endsig(&m); break;
179 case SYS_COPY: r = do_copy(&m); break;
180 case SYS_VCOPY: r = do_vcopy(&m); break;
181 case SYS_GBOOT: r = do_gboot(&m); break;
182 case SYS_MEM: r = do_mem(&m); break;
183 case SYS_UMAP: r = do_umap(&m); break;
184 case SYS_TRACE: r = do_trace(&m); break;
185 default: r = E_BAD_FCN;
186 }
187
188 m.m_type = r; /* 'r' reports status of call */
189 send(m.m_source, &m); /* send reply to caller */
190 }
191 }
192
193
194 /*===========================================================================*
195 * do_fork *
196 *===========================================================================*/
197 PRIVATE int do_fork(m_ptr)
198 register message *m_ptr; /* pointer to request message */
199 {
200 /* Handle sys_fork(). m_ptr->PROC1 has forked. The child is m_ptr->PROC2. */
201
202 #if (CHIP == INTEL)
203 reg_t old_ldt_sel;
204 #endif
205 register struct proc *rpc;
206 struct proc *rpp;
207
208 if (!isoksusern(m_ptr->PROC1) || !isoksusern(m_ptr->PROC2))
209 return(E_BAD_PROC);
210 rpp = proc_addr(m_ptr->PROC1);
211 rpc = proc_addr(m_ptr->PROC2);
212
213 /* Copy parent 'proc' struct to child. */
214 #if (CHIP == INTEL)
215 old_ldt_sel = rpc->p_ldt_sel; /* stop this being obliterated by copy */
216 #endif
217
218 *rpc = *rpp; /* copy 'proc' struct */
219
220 #if (CHIP == INTEL)
221 rpc->p_ldt_sel = old_ldt_sel;
222 #endif
223 rpc->p_nr = m_ptr->PROC2; /* this was obliterated by copy */
224
225 #if (MACHINE == SUN)
226 if (rpp->p_stn != INVALID_STN) {
227 /*
228 * Only generate an stn for the child if the parent's is valid.
229 */
230 rpc->p_stn = next_stn();
231 }
232 event_log(EV_FORK, proc_ptr, rpc->p_stn, 0, 0);
233 #endif
234
235 #if (SHADOWING == 0)
236 rpc->p_flags |= NO_MAP; /* inhibit the process from running */
237 #endif
238
239 rpc->p_flags &= ~(PENDING | SIG_PENDING | P_STOP);
240
241 /* Only 1 in group should have PENDING, child does not inherit trace status*/
242 sigemptyset(&rpc->p_pending);
243 rpc->p_pendcount = 0;
244 rpc->p_pid = m_ptr->PID; /* install child's pid */
245 rpc->p_reg.retreg = 0; /* child sees pid = 0 to know it is child */
246
247 rpc->user_time = 0; /* set all the accounting times to 0 */
248 rpc->sys_time = 0;
249 rpc->child_utime = 0;
250 rpc->child_stime = 0;
251
252 #if (SHADOWING == 1)
253 rpc->p_nflips = 0;
254 mkshadow(rpp, (phys_clicks)m_ptr->m1_p1); /* run child first */
255 #endif
256
257 return(OK);
258 }
259
260
261 /*===========================================================================*
262 * do_newmap *
263 *===========================================================================*/
264 PRIVATE int do_newmap(m_ptr)
265 message *m_ptr; /* pointer to request message */
266 {
267 /* Handle sys_newmap(). Fetch the memory map from MM. */
268
269 register struct proc *rp;
270 phys_bytes src_phys;
271 int caller; /* whose space has the new map (usually MM) */
272 int k; /* process whose map is to be loaded */
273 #if (SHADOWING == 0)
274 int old_flags; /* value of flags before modification */
275 #endif
276 struct mem_map *map_ptr; /* virtual address of map inside caller (MM) */
277
278 /* Extract message parameters and copy new memory map from MM. */
279 caller = m_ptr->m_source;
280 k = m_ptr->PROC1;
281 map_ptr = (struct mem_map *) m_ptr->MEM_PTR;
282 if (!isokprocn(k)) return(E_BAD_PROC);
283 rp = proc_addr(k); /* ptr to entry of user getting new map */
284
285 #if (MACHINE == SUN)
286 mem_released(rp); /* old address space has been freed */
287 #endif
288
289 /* Copy the map from MM. */
290 src_phys = umap(proc_addr(caller), D, (vir_bytes) map_ptr, sizeof(rp->p_map));
291 if (src_phys == 0) panic("bad call to sys_newmap", NO_NUM);
292 phys_copy(src_phys, vir2phys(rp->p_map), (phys_bytes) sizeof(rp->p_map));
293
294 #if (SHADOWING == 0)
295 #if (CHIP== M68000)
296 pmmu_init_proc(rp);
297 #elif (MACHINE != SUN) /* Needn't do anything for Suns */
298 alloc_segments(rp);
299 #endif
300 old_flags = rp->p_flags; /* save the previous value of the flags */
301 rp->p_flags &= ~NO_MAP;
302 if (old_flags != 0 && rp->p_flags == 0) lock_ready(rp);
303 #endif
304
305 return(OK);
306 }
307
308
309 /*===========================================================================*
310 * do_getmap *
311 *===========================================================================*/
312 PRIVATE int do_getmap(m_ptr)
313 message *m_ptr; /* pointer to request message */
314 {
315 /* Handle sys_getmap(). Report the memory map to MM. */
316
317 register struct proc *rp;
318 phys_bytes dst_phys;
319 int caller; /* where the map has to be stored */
320 int k; /* process whose map is to be loaded */
321 struct mem_map *map_ptr; /* virtual address of map inside caller (MM) */
322
323 /* Extract message parameters and copy new memory map to MM. */
324 caller = m_ptr->m_source;
325 k = m_ptr->PROC1;
326 map_ptr = (struct mem_map *) m_ptr->MEM_PTR;
327
328 if (!isokprocn(k))
329 panic("do_getmap got bad proc: ", m_ptr->PROC1);
330
331 rp = proc_addr(k); /* ptr to entry of the map */
332
333 /* Copy the map to MM. */
334 dst_phys = umap(proc_addr(caller), D, (vir_bytes) map_ptr, sizeof(rp->p_map));
335 if (dst_phys == 0) panic("bad call to sys_getmap", NO_NUM);
336 phys_copy(vir2phys(rp->p_map), dst_phys, sizeof(rp->p_map));
337
338 return(OK);
339 }
340
341
342 /*===========================================================================*
343 * do_exec *
344 *===========================================================================*/
345 PRIVATE int do_exec(m_ptr)
346 register message *m_ptr; /* pointer to request message */
347 {
348 /* Handle sys_exec(). A process has done a successful EXEC. Patch it up. */
349
350 register struct proc *rp;
351 reg_t sp; /* new sp */
352 phys_bytes phys_name;
353 char *np;
354 #define NLEN (sizeof(rp->p_name)-1)
355
356 if (!isoksusern(m_ptr->PROC1)) return E_BAD_PROC;
357 /* PROC2 field is used as flag to indicate process is being traced */
358 if (m_ptr->PROC2) cause_sig(m_ptr->PROC1, SIGTRAP);
359 sp = (reg_t) m_ptr->STACK_PTR;
360 rp = proc_addr(m_ptr->PROC1);
361 rp->p_reg.pc = (reg_t) m_ptr->IP_PTR; /* set pc */
362 rp->p_reg.sp = sp; /* set the stack pointer */
363 #if (CHIP == M68000)
364 rp->p_splow = sp; /* set the stack pointer low water */
365 # ifdef FPP
366 /* Initialize fpp for this process */
367 fpp_new_state(rp);
368 # endif
369 #endif
370
371 #if (MACHINE == SUN)
372 rp->p_reg.npc = rp->p_reg.pc + 4;
373 #endif
374
375 rp->p_alarm = 0; /* reset alarm timer */
376 rp->p_flags &= ~RECEIVING; /* MM does not reply to EXEC call */
377 if (rp->p_flags == 0) lock_ready(rp);
378
379 /* Save command name for debugging, ps(1) output, etc. */
380 phys_name = numap(m_ptr->m_source, (vir_bytes) m_ptr->NAME_PTR,
381 (vir_bytes) NLEN);
382 if (phys_name != 0) {
383 phys_copy(phys_name, vir2phys(rp->p_name), (phys_bytes) NLEN);
384 for (np = rp->p_name; (*np & BYTE) >= ' '; np++) {}
385 *np = 0;
386 #if (MACHINE == SUN)
387 event_log(EV_NEW_NAME, rp, INVALID_STN, rp->p_name, np - rp->p_name+1);
388 #endif
389 }
390
391 return(OK);
392 }
393
394
395 /*===========================================================================*
396 * do_xit *
397 *===========================================================================*/
398 PRIVATE int do_xit(m_ptr)
399 message *m_ptr; /* pointer to request message */
400 {
401 /* Handle sys_xit(). A process has exited. */
402
403 register struct proc *rp, *rc;
404 struct proc *np, *xp;
405 int parent; /* number of exiting proc's parent */
406 int proc_nr; /* number of process doing the exit */
407 #if (SHADOWING == 1)
408 phys_clicks base, size;
409 #endif
410
411 parent = m_ptr->PROC1; /* slot number of parent process */
412 proc_nr = m_ptr->PROC2; /* slot number of exiting process */
413 if (!isoksusern(parent) || !isoksusern(proc_nr)) return(E_BAD_PROC);
414 rp = proc_addr(parent);
415 rc = proc_addr(proc_nr);
416 #if (MACHINE == SUN)
417 mem_released(rc); /* old address space has been freed */
418 #endif
419 lock();
420 rp->child_utime += rc->user_time + rc->child_utime; /* accum child times */
421 rp->child_stime += rc->sys_time + rc->child_stime;
422 rp->child_stime += rc->sys_time + rc->child_stime;
423 unlock();
424 rc->p_alarm = 0; /* turn off alarm timer */
425 if (rc->p_flags == 0) lock_unready(rc);
426
427 #if (SHADOWING == 1)
428 rmshadow(rc, &base, &size);
429 m_ptr->m1_i1 = (int)base;
430 m_ptr->m1_i2 = (int)size;
431 #endif
432
433 strcpy(rc->p_name, "<noname>"); /* process no longer has a name */
434
435 /* If the process being terminated happens to be queued trying to send a
436 * message (i.e., the process was killed by a signal, rather than it doing an
437 * EXIT), then it must be removed from the message queues.
438 */
439 if (rc->p_flags & SENDING) {
440 /* Check all proc slots to see if the exiting process is queued. */
441 for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++) {
442 if (rp->p_callerq == NIL_PROC) continue;
443 if (rp->p_callerq == rc) {
444 /* Exiting process is on front of this queue. */
445 rp->p_callerq = rc->p_sendlink;
446 break;
447 } else {
448 /* See if exiting process is in middle of queue. */
449 np = rp->p_callerq;
450 while ( ( xp = np->p_sendlink) != NIL_PROC)
451 if (xp == rc) {
452 np->p_sendlink = xp->p_sendlink;
453 break;
454 } else {
455 np = xp;
456 }
457 }
458 }
459 }
460 #if (CHIP == M68000) && (SHADOWING == 0)
461 pmmu_delete(rc); /* we're done remove tables */
462 #endif
463
464 if (rc->p_flags & PENDING) --sig_procs;
465 sigemptyset(&rc->p_pending);
466 rc->p_pendcount = 0;
467 rc->p_flags = P_SLOT_FREE;
468 #if (MACHINE == SUN)
469 event_log(EV_EXIT, rc, 0, 0, 0);
470 #endif
471 return(OK);
472 }
473
474
475 /*===========================================================================*
476 * do_getsp *
477 *===========================================================================*/
478 PRIVATE int do_getsp(m_ptr)
479 register message *m_ptr; /* pointer to request message */
480 {
481 /* Handle sys_getsp(). MM wants to know what sp is. */
482
483 register struct proc *rp;
484
485 if (!isoksusern(m_ptr->PROC1)) return(E_BAD_PROC);
486 rp = proc_addr(m_ptr->PROC1);
487 m_ptr->STACK_PTR = (char *) rp->p_reg.sp; /* return sp here (bad type) */
488 return(OK);
489 }
490
491
492 /*===========================================================================*
493 * do_times *
494 *===========================================================================*/
495 PRIVATE int do_times(m_ptr)
496 register message *m_ptr; /* pointer to request message */
497 {
498 /* Handle sys_times(). Retrieve the accounting information. */
499
500 register struct proc *rp;
501
502 if (!isoksusern(m_ptr->PROC1)) return E_BAD_PROC;
503 rp = proc_addr(m_ptr->PROC1);
504
505 /* Insert the times needed by the TIMES system call in the message. */
506 lock(); /* halt the volatile time counters in rp */
507 m_ptr->USER_TIME = rp->user_time;
508 m_ptr->SYSTEM_TIME = rp->sys_time;
509 unlock();
510 m_ptr->CHILD_UTIME = rp->child_utime;
511 m_ptr->CHILD_STIME = rp->child_stime;
512 m_ptr->BOOT_TICKS = get_uptime();
513 return(OK);
514 }
515
516
517 /*===========================================================================*
518 * do_abort *
519 *===========================================================================*/
520 PRIVATE int do_abort(m_ptr)
521 message *m_ptr; /* pointer to request message */
522 {
523 /* Handle sys_abort. MINIX is unable to continue. Terminate operation. */
524 #if (CHIP == INTEL)
525 char monitor_code[64];
526 phys_bytes src_phys;
527
528 if (m_ptr->m1_i1 == RBT_MONITOR) {
529 /* The monitor is to run user specified instructions. */
530 src_phys = numap(m_ptr->m_source, (vir_bytes) m_ptr->m1_p1,
531 (vir_bytes) sizeof(monitor_code));
532 if (src_phys == 0) panic("bad monitor code from", m_ptr->m_source);
533 phys_copy(src_phys, vir2phys(monitor_code),
534 (phys_bytes) sizeof(monitor_code));
535 reboot_code = vir2phys(monitor_code);
536 }
537 #endif
538 wreboot(m_ptr->m1_i1);
539 return(OK); /* pro-forma (really EDISASTER) */
540 }
541
542
543 #if (SHADOWING == 1)
544 /*===========================================================================*
545 * do_fresh *
546 *===========================================================================*/
547 PRIVATE int do_fresh(m_ptr) /* for 68000 only */
548 message *m_ptr; /* pointer to request message */
549 {
550 /* Handle sys_fresh. Start with fresh process image during EXEC. */
551
552 register struct proc *p;
553 int proc_nr; /* number of process doing the exec */
554 phys_clicks base, size;
555 phys_clicks c1, nc;
556
557 proc_nr = m_ptr->PROC1; /* slot number of exec-ing process */
558 if (!isokprocn(proc_nr)) return(E_BAD_PROC);
559 p = proc_addr(proc_nr);
560 rmshadow(p, &base, &size);
561 do_newmap(m_ptr);
562 c1 = p->p_map[D].mem_phys;
563 nc = p->p_map[S].mem_phys - p->p_map[D].mem_phys + p->p_map[S].mem_len;
564 c1 += m_ptr->m1_i2;
565 nc -= m_ptr->m1_i2;
566
567 zeroclicks(c1, nc);
568 m_ptr->m1_i1 = (int)base;
569 m_ptr->m1_i2 = (int)size;
570 return(OK);
571 }
572 #endif /* (SHADOWING == 1) */
573
574
575 /*===========================================================================*
576 * do_sendsig *
577 *===========================================================================*/
578 PRIVATE int do_sendsig(m_ptr)
579 message *m_ptr; /* pointer to request message */
580 {
581 /* Handle sys_sendsig, POSIX-style signal */
582
583 struct sigmsg smsg;
584 register struct proc *rp;
585 phys_bytes src_phys, dst_phys;
586 struct sigcontext sc, *scp;
587 #if (MACHINE != SUN)
588 struct sigframe fr, *frp;
589 #endif
590
591 if (!isokusern(m_ptr->PROC1)) return(E_BAD_PROC);
592 rp = proc_addr(m_ptr->PROC1);
593
594 /* Get the sigmsg structure into our address space. */
595 src_phys = umap(proc_addr(MM_PROC_NR), D, (vir_bytes) m_ptr->SIG_CTXT_PTR,
596 (vir_bytes) sizeof(struct sigmsg));
597 if (src_phys == 0)
598 panic("do_sendsig can't signal: bad sigmsg address from MM", NO_NUM);
599 phys_copy(src_phys, vir2phys(&smsg), (phys_bytes) sizeof(struct sigmsg));
600
601 /* Compute the usr stack pointer value where sigcontext will be stored. */
602 scp = (struct sigcontext *) smsg.sm_stkptr - 1;
603 #if (MACHINE == SUN)
604 scp = (struct sigcontext *) stack_align((phys_bytes) scp);
605 #endif
606
607 /* Copy the registers to the sigcontext structure. */
608 memcpy(&sc.sc_regs, &rp->p_reg, sizeof(struct sigregs));
609
610 /* Finish the sigcontext initialization. */
611 sc.sc_flags = SC_SIGCONTEXT;
612
613 sc.sc_mask = smsg.sm_mask;
614
615 /* Copy the sigcontext structure to the user's stack. */
616 dst_phys = umap(rp, D, (vir_bytes) scp,
617 (vir_bytes) sizeof(struct sigcontext));
618 if (dst_phys == 0) return(EFAULT);
619 phys_copy(vir2phys(&sc), dst_phys, (phys_bytes) sizeof(struct sigcontext));
620
621 #if (MACHINE != SUN)
622 /* Initialize the sigframe structure. */
623 frp = (struct sigframe *) scp - 1;
624 fr.sf_scpcopy = scp;
625 fr.sf_retadr2= (void (*)()) rp->p_reg.pc;
626 fr.sf_fp = rp->p_reg.fp;
627 rp->p_reg.fp = (reg_t) &frp->sf_fp;
628 fr.sf_scp = scp;
629 fr.sf_code = 0; /* XXX - should be used for type of FP exception */
630 fr.sf_signo = smsg.sm_signo;
631 fr.sf_retadr = (void (*)()) smsg.sm_sigreturn;
632
633 /* Copy the sigframe structure to the user's stack. */
634 dst_phys = umap(rp, D, (vir_bytes) frp, (vir_bytes) sizeof(struct sigframe));
635 if (dst_phys == 0) return(EFAULT);
636 phys_copy(vir2phys(&fr), dst_phys, (phys_bytes) sizeof(struct sigframe));
637
638 /* Reset user registers to execute the signal handler. */
639 rp->p_reg.sp = (reg_t) frp;
640 rp->p_reg.pc = (reg_t) smsg.sm_sighandler;
641
642 #else
643 rp->p_reg.context[O5] = (reg_t) smsg.sm_sighandler;
644 rp->p_reg.pc = (reg_t) smsg.sm_sigreturn;
645 rp->p_reg.npc = rp->p_reg.pc + 4;
646 rp->p_reg.sp = (reg_t) scp - INIT_SP; /* leave space for a stack frame */
647 rp->p_reg.context[O0] = smsg.sm_signo;
648 rp->p_reg.context[O1] = 0; /* XXX - should be used for type of FP exception */
649 rp->p_reg.context[O2] = (reg_t) scp;
650 #endif
651
652 return(OK);
653 }
654
655 /*===========================================================================*
656 * do_sigreturn *
657 *===========================================================================*/
658 PRIVATE int do_sigreturn(m_ptr)
659 register message *m_ptr;
660 {
661 /* POSIX style signals require sys_sigreturn to put things in order before the
662 * signalled process can resume execution
663 */
664
665 struct sigcontext sc;
666 register struct proc *rp;
667 phys_bytes src_phys;
668
669 if (!isokusern(m_ptr->PROC1)) return(E_BAD_PROC);
670 rp = proc_addr(m_ptr->PROC1);
671
672 /* Copy in the sigcontext structure. */
673 src_phys = umap(rp, D, (vir_bytes) m_ptr->SIG_CTXT_PTR,
674 (vir_bytes) sizeof(struct sigcontext));
675 if (src_phys == 0) return(EFAULT);
676 phys_copy(src_phys, vir2phys(&sc), (phys_bytes) sizeof(struct sigcontext));
677
678 /* Make sure that this is not just a jmp_buf. */
679 if ((sc.sc_flags & SC_SIGCONTEXT) == 0) return(EINVAL);
680
681 /* Fix up only certain key registers if the compiler doesn't use
682 * register variables within functions containing setjmp.
683 */
684 #if (MACHINE != SUN) /* SC_NOREGLOCALS not yet supported on the SUN version */
685 if (sc.sc_flags & SC_NOREGLOCALS) {
686 rp->p_reg.retreg = sc.sc_retreg;
687 rp->p_reg.FP = sc.sc_fp;
688 rp->p_reg.pc = sc.sc_pc;
689 rp->p_reg.sp = sc.sc_sp;
690 return (OK);
691 }
692 #endif
693 sc.sc_psw = rp->p_reg.psw;
694
695 #if (CHIP == INTEL)
696 /* Don't panic kernel if user gave bad selectors. */
697 sc.sc_cs = rp->p_reg.cs;
698 sc.sc_ds = rp->p_reg.ds;
699 sc.sc_es = rp->p_reg.es;
700 #if _WORD_SIZE == 4
701 sc.sc_fs = rp->p_reg.fs;
702 sc.sc_gs = rp->p_reg.gs;
703 #endif
704 #endif
705
706 /* Restore the registers. */
707 memcpy(&rp->p_reg, (char *)&sc.sc_regs, sizeof(struct sigregs));
708
709 return(OK);
710 }
711
712 /*===========================================================================*
713 * do_kill *
714 *===========================================================================*/
715 PRIVATE int do_kill(m_ptr)
716 register message *m_ptr; /* pointer to request message */
717 {
718 /* Handle sys_kill(). Cause a signal to be sent to a process via MM.
719 * Note that this has nothing to do with the kill (2) system call, this
720 * is how the FS (and possibly other servers) get access to cause_sig to
721 * send a KSIG message to MM
722 */
723
724 if (!isokusern(m_ptr->PR)) return(E_BAD_PROC);
725 cause_sig(m_ptr->PR, m_ptr->SIGNUM);
726 return(OK);
727 }
728
729
730 /*===========================================================================*
731 * do_endsig *
732 *===========================================================================*/
733 PRIVATE int do_endsig(m_ptr)
734 register message *m_ptr; /* pointer to request message */
735 {
736 /* Finish up after a KSIG-type signal, caused by a SYS_KILL message or a call
737 * to cause_sig by a task
738 */
739
740 register struct proc *rp;
741
742 if (!isokusern(m_ptr->PROC1)) return(E_BAD_PROC);
743 rp = proc_addr(m_ptr->PROC1);
744
745 /* MM has finished one KSIG. */
746 if (rp->p_pendcount != 0 && --rp->p_pendcount == 0
747 && (rp->p_flags &= ~SIG_PENDING) == 0)
748 lock_ready(rp);
749 return(OK);
750 }
751
752 /*===========================================================================*
753 * do_copy *
754 *===========================================================================*/
755 PRIVATE int do_copy(m_ptr)
756 register message *m_ptr; /* pointer to request message */
757 {
758 /* Handle sys_copy(). Copy data for MM or FS. */
759
760 int src_proc, dst_proc, src_space, dst_space;
761 vir_bytes src_vir, dst_vir;
762 phys_bytes src_phys, dst_phys, bytes;
763
764 /* Dismember the command message. */
765 src_proc = m_ptr->SRC_PROC_NR;
766 dst_proc = m_ptr->DST_PROC_NR;
767 src_space = m_ptr->SRC_SPACE;
768 dst_space = m_ptr->DST_SPACE;
769 src_vir = (vir_bytes) m_ptr->SRC_BUFFER;
770 dst_vir = (vir_bytes) m_ptr->DST_BUFFER;
771 bytes = (phys_bytes) m_ptr->COPY_BYTES;
772
773
774 /* Compute the source and destination addresses and do the copy. */
775 #if (SHADOWING == 0)
776 if (src_proc == ABS)
777 src_phys = (phys_bytes) m_ptr->SRC_BUFFER;
778 else {
779 if (bytes != (vir_bytes) bytes)
780 /* This would happen for 64K segments and 16-bit vir_bytes.
781 * It would happen a lot for do_fork except MM uses ABS
782 * copies for that case.
783 */
784 panic("overflow in count in do_copy", NO_NUM);
785 #endif
786
787 src_phys = umap(proc_addr(src_proc), src_space, src_vir,
788 (vir_bytes) bytes);
789 #if (SHADOWING == 0)
790 }
791 #endif
792
793 #if (SHADOWING == 0)
794 if (dst_proc == ABS)
795 dst_phys = (phys_bytes) m_ptr->DST_BUFFER;
796 else
797 #endif
798 dst_phys = umap(proc_addr(dst_proc), dst_space, dst_vir,
799 (vir_bytes) bytes);
800
801 if (src_phys == 0 || dst_phys == 0) return(EFAULT);
802 phys_copy(src_phys, dst_phys, bytes);
803 return(OK);
804 }
805
806
807 /*===========================================================================*
808 * do_vcopy *
809 *===========================================================================*/
810 PRIVATE int do_vcopy(m_ptr)
811 register message *m_ptr; /* pointer to request message */
812 {
813 /* Handle sys_vcopy(). Copy multiple blocks of memory */
814
815 int src_proc, dst_proc, vect_s, i;
816 vir_bytes src_vir, dst_vir, vect_addr;
817 phys_bytes src_phys, dst_phys, bytes;
818 cpvec_t cpvec_table[CPVEC_NR];
819
820 /* Dismember the command message. */
821 src_proc = m_ptr->m1_i1;
822 dst_proc = m_ptr->m1_i2;
823 vect_s = m_ptr->m1_i3;
824 vect_addr = (vir_bytes)m_ptr->m1_p1;
825
826 if (vect_s > CPVEC_NR) return EDOM;
827
828 src_phys= numap (m_ptr->m_source, vect_addr, vect_s * sizeof(cpvec_t));
829 if (!src_phys) return EFAULT;
830 phys_copy(src_phys, vir2phys(cpvec_table),
831 (phys_bytes) (vect_s * sizeof(cpvec_t)));
832
833 for (i = 0; i < vect_s; i++) {
834 src_vir= cpvec_table[i].cpv_src;
835 dst_vir= cpvec_table[i].cpv_dst;
836 bytes= cpvec_table[i].cpv_size;
837 src_phys = numap(src_proc,src_vir,(vir_bytes)bytes);
838 dst_phys = numap(dst_proc,dst_vir,(vir_bytes)bytes);
839 if (src_phys == 0 || dst_phys == 0) return(EFAULT);
840 phys_copy(src_phys, dst_phys, bytes);
841 }
842 return(OK);
843 }
844
845
846 /*==========================================================================*
847 * do_gboot *
848 *==========================================================================*/
849 PUBLIC struct bparam_s boot_parameters;
850
851 PRIVATE int do_gboot(m_ptr)
852 message *m_ptr; /* pointer to request message */
853 {
854 /* Copy the boot parameters. Normally only called during fs init. */
855
856 phys_bytes dst_phys;
857
858 dst_phys = umap(proc_addr(m_ptr->PROC1), D, (vir_bytes) m_ptr->MEM_PTR,
859 (vir_bytes) sizeof(boot_parameters));
860 if (dst_phys == 0) panic("bad call to SYS_GBOOT", NO_NUM);
861 phys_copy(vir2phys(&boot_parameters), dst_phys,
862 (phys_bytes) sizeof(boot_parameters));
863 return(OK);
864 }
865
866
867 /*===========================================================================*
868 * do_mem *
869 *===========================================================================*/
870 PRIVATE int do_mem(m_ptr)
871 register message *m_ptr; /* pointer to request message */
872 {
873 /* Return the base and size of the next chunk of memory. */
874
875 struct memory *memp;
876
877 for (memp = mem; memp < &mem[NR_MEMS]; ++memp) {
878 m_ptr->m1_i1 = memp->base;
879 m_ptr->m1_i2 = memp->size;
880 m_ptr->m1_i3 = tot_mem_size;
881 memp->size = 0;
882 if (m_ptr->m1_i2 != 0) break; /* found a chunk */
883 }
884 return(OK);
885 }
886
887
888 /*==========================================================================*
889 * do_umap *
890 *==========================================================================*/
891 PRIVATE int do_umap(m_ptr)
892 register message *m_ptr; /* pointer to request message */
893 {
894 /* Same as umap(), for non-kernel processes. */
895
896 m_ptr->SRC_BUFFER = umap(proc_addr((int) m_ptr->SRC_PROC_NR),
897 (int) m_ptr->SRC_SPACE,
898 (vir_bytes) m_ptr->SRC_BUFFER,
899 (vir_bytes) m_ptr->COPY_BYTES);
900 return(OK);
901 }
902
903
904 /*==========================================================================*
905 * do_trace *
906 *==========================================================================*/
907 #define TR_PROCNR (m_ptr->m2_i1)
908 #define TR_REQUEST (m_ptr->m2_i2)
909 #define TR_ADDR ((vir_bytes) m_ptr->m2_l1)
910 #define TR_DATA (m_ptr->m2_l2)
911 #define TR_VLSIZE ((vir_bytes) sizeof(long))
912
913 PRIVATE int do_trace(m_ptr)
914 register message *m_ptr;
915 {
916 /* Handle the debugging commands supported by the ptrace system call
917 * The commands are:
918 * T_STOP stop the process
919 * T_OK enable tracing by parent for this process
920 * T_GETINS return value from instruction space
921 * T_GETDATA return value from data space
922 * T_GETUSER return value from user process table
923 * T_SETINS set value from instruction space
924 * T_SETDATA set value from data space
925 * T_SETUSER set value in user process table
926 * T_RESUME resume execution
927 * T_EXIT exit
928 * T_STEP set trace bit
929 *
930 * The T_OK and T_EXIT commands are handled completely by the memory manager,
931 * all others come here.
932 */
933
934 register struct proc *rp;
935 phys_bytes src, dst;
936 int i;
937
938 rp = proc_addr(TR_PROCNR);
939 if (rp->p_flags & P_SLOT_FREE) return(EIO);
940 switch (TR_REQUEST) {
941 case T_STOP: /* stop process */
942 if (rp->p_flags == 0) lock_unready(rp);
943 rp->p_flags |= P_STOP;
944 rp->p_reg.psw &= ~TRACEBIT; /* clear trace bit */
945 return(OK);
946
947 case T_GETINS: /* return value from instruction space */
948 if (rp->p_map[T].mem_len != 0) {
949 if ((src = umap(rp, T, TR_ADDR, TR_VLSIZE)) == 0) return(EIO);
950 phys_copy(src, vir2phys(&TR_DATA), (phys_bytes) sizeof(long));
951 break;
952 }
953 /* Text space is actually data space - fall through. */
954
955 case T_GETDATA: /* return value from data space */
956 if ((src = umap(rp, D, TR_ADDR, TR_VLSIZE)) == 0) return(EIO);
957 phys_copy(src, vir2phys(&TR_DATA), (phys_bytes) sizeof(long));
958 break;
959
960 case T_GETUSER: /* return value from process table */
961 if ((TR_ADDR & (sizeof(long) - 1)) != 0 ||
962 TR_ADDR > sizeof(struct proc) - sizeof(long))
963 return(EIO);
964 TR_DATA = *(long *) ((char *) rp + (int) TR_ADDR);
965 break;
966
967 case T_SETINS: /* set value in instruction space */
968 if (rp->p_map[T].mem_len != 0) {
969 if ((dst = umap(rp, T, TR_ADDR, TR_VLSIZE)) == 0) return(EIO);
970 phys_copy(vir2phys(&TR_DATA), dst, (phys_bytes) sizeof(long));
971 TR_DATA = 0;
972 break;
973 }
974 /* Text space is actually data space - fall through. */
975
976 case T_SETDATA: /* set value in data space */
977 if ((dst = umap(rp, D, TR_ADDR, TR_VLSIZE)) == 0) return(EIO);
978 phys_copy(vir2phys(&TR_DATA), dst, (phys_bytes) sizeof(long));
979 TR_DATA = 0;
980 break;
981
982 case T_SETUSER: /* set value in process table */
983 if ((TR_ADDR & (sizeof(reg_t) - 1)) != 0 ||
984 TR_ADDR > sizeof(struct stackframe_s) - sizeof(reg_t))
985 return(EIO);
986 i = (int) TR_ADDR;
987 #if (CHIP == INTEL)
988 /* Altering segment registers might crash the kernel when it
989 * tries to load them prior to restarting a process, so do
990 * not allow it.
991 */
992 if (i == (int) &((struct proc *) 0)->p_reg.cs ||
993 i == (int) &((struct proc *) 0)->p_reg.ds ||
994 i == (int) &((struct proc *) 0)->p_reg.es ||
995 #if _WORD_SIZE == 4
996 i == (int) &((struct proc *) 0)->p_reg.gs ||
997 i == (int) &((struct proc *) 0)->p_reg.fs ||
998 #endif
999 i == (int) &((struct proc *) 0)->p_reg.ss)
1000 return(EIO);
1001 #endif
1002 #if (MACHINE != SUN) /* PSW can't be changed in the SUN version */
1003 if (i == (int) &((struct proc *) 0)->p_reg.psw)
1004 /* only selected bits are changeable */
1005 SETPSW(rp, TR_DATA);
1006 else
1007 *(reg_t *) ((char *) &rp->p_reg + i) = (reg_t) TR_DATA;
1008 TR_DATA = 0;
1009 #endif
1010 break;
1011
1012 case T_RESUME: /* resume execution */
1013 rp->p_flags &= ~P_STOP;
1014 if (rp->p_flags == 0) lock_ready(rp);
1015 TR_DATA = 0;
1016 break;
1017
1018 case T_STEP: /* set trace bit */
1019 rp->p_reg.psw |= TRACEBIT;
1020 rp->p_flags &= ~P_STOP;
1021 if (rp->p_flags == 0) lock_ready(rp);
1022 TR_DATA = 0;
1023 break;
1024
1025 default:
1026 return(EIO);
1027 }
1028 return(OK);
1029 }
1030
1031 /*===========================================================================*
1032 * cause_sig *
1033 *===========================================================================*/
1034 PUBLIC void cause_sig(proc_nr, sig_nr)
1035 int proc_nr; /* process to be signalled */
1036 int sig_nr; /* signal to be sent, 1 to _NSIG */
1037 {
1038 /* A task wants to send a signal to a process. Examples of such tasks are:
1039 * TTY wanting to cause SIGINT upon getting a DEL
1040 * CLOCK wanting to cause SIGALRM when timer expires
1041 * FS also uses this to send a signal, via the SYS_KILL message.
1042 * Signals are handled by sending a message to MM. The tasks don't dare do
1043 * that directly, for fear of what would happen if MM were busy. Instead they
1044 * call cause_sig, which sets bits in p_pending, and then carefully checks to
1045 * see if MM is free. If so, a message is sent to it. If not, when it becomes
1046 * free, a message is sent. The process being signaled is blocked while MM
1047 * has not seen or finished with all signals for it. These signals are
1048 * counted in p_pendcount, and the SIG_PENDING flag is kept nonzero while
1049 * there are some. It is not sufficient to ready the process when MM is
1050 * informed, because MM can block waiting for FS to do a core dump.
1051 */
1052
1053 register struct proc *rp, *mmp;
1054
1055 rp = proc_addr(proc_nr);
1056 if (sigismember(&rp->p_pending, sig_nr))
1057 return; /* this signal already pending */
1058 sigaddset(&rp->p_pending, sig_nr);
1059 ++rp->p_pendcount; /* count new signal pending */
1060 if (rp->p_flags & PENDING)
1061 return; /* another signal already pending */
1062 if (rp->p_flags == 0) lock_unready(rp);
1063 rp->p_flags |= PENDING | SIG_PENDING;
1064 ++sig_procs; /* count new process pending */
1065
1066 mmp = proc_addr(MM_PROC_NR);
1067 if ( ((mmp->p_flags & RECEIVING) == 0) || mmp->p_getfrom != ANY) return;
1068 inform();
1069 }
1070
1071
1072 /*===========================================================================*
1073 * inform *
1074 *===========================================================================*/
1075 PUBLIC void inform()
1076 {
1077 /* When a signal is detected by the kernel (e.g., DEL), or generated by a task
1078 * (e.g. clock task for SIGALRM), cause_sig() is called to set a bit in the
1079 * p_pending field of the process to signal. Then inform() is called to see
1080 * if MM is idle and can be told about it. Whenever MM blocks, a check is
1081 * made to see if 'sig_procs' is nonzero; if so, inform() is called.
1082 */
1083
1084 register struct proc *rp;
1085
1086 /* MM is waiting for new input. Find a process with pending signals. */
1087 for (rp = BEG_SERV_ADDR; rp < END_PROC_ADDR; rp++)
1088 if (rp->p_flags & PENDING) {
1089 m.m_type = KSIG;
1090 m.SIG_PROC = proc_number(rp);
1091 m.SIG_MAP = rp->p_pending;
1092 sig_procs--;
1093 if (lock_mini_send(proc_addr(HARDWARE), MM_PROC_NR, &m) != OK)
1094 panic("can't inform MM", NO_NUM);
1095 sigemptyset(&rp->p_pending); /* the ball is now in MM's court */
1096 rp->p_flags &= ~PENDING;/* remains inhibited by SIG_PENDING */
1097 #if (MACHINE == SUN)
1098 /* SIGSTKFLT is not generated in the PC version. */
1099 if (sigismember((sigset_t *) &m.SIG_MAP, SIGSTKFLT)) {
1100 if (rp->p_pendcount != 0 &&
1101 --rp->p_pendcount == 0 &&
1102 (rp->p_flags &= ~SIG_PENDING) == 0)
1103 lock_ready(rp);
1104 }
1105 #endif
1106 lock_pick_proc(); /* avoid delay in scheduling MM */
1107 return;
1108 }
1109 }
1110
1111
1112 /*===========================================================================*
1113 * umap *
1114 *===========================================================================*/
1115 PUBLIC phys_bytes umap(rp, seg, vir_addr, bytes)
1116 register struct proc *rp; /* pointer to proc table entry for process */
1117 int seg; /* T, D, or S segment */
1118 vir_bytes vir_addr; /* virtual address in bytes within the seg */
1119 vir_bytes bytes; /* # of bytes to be copied */
1120 {
1121 /* Calculate the physical memory address for a given virtual address. */
1122
1123 vir_clicks vc; /* the virtual address in clicks */
1124 phys_bytes pa; /* intermediate variables as phys_bytes */
1125 #if (CHIP == INTEL)
1126 phys_bytes seg_base;
1127 #endif
1128 #if (MACHINE == SUN)
1129 vir_clicks cstart; /* first click */
1130 #endif
1131
1132 /* If 'seg' is D it could really be S and vice versa. T really means T.
1133 * If the virtual address falls in the gap, it causes a problem. On the
1134 * 8088 it is probably a legal stack reference, since "stackfaults" are
1135 * not detected by the hardware. On 8088s, the gap is called S and
1136 * accepted, but on other machines it is called D and rejected.
1137 * The Atari ST behaves like the 8088 in this respect.
1138 */
1139
1140 if (bytes <= 0) return( (phys_bytes) 0);
1141 vc = (vir_addr + bytes - 1) >> CLICK_SHIFT; /* last click of data */
1142
1143 #if (MACHINE == SUN)
1144 /*
1145 * Read-only data is included in the text segment in smx. Writes to the
1146 * file-system may therefore be from the text segment. This check
1147 * will adjust the segment appropriately if the virtual address lies
1148 * in the text segment.
1149 */
1150 if (vc >= rp->p_map[T].mem_vir &&
1151 vc < rp->p_map[T].mem_vir + rp->p_map[T].mem_len) {
1152 seg = T;
1153 }
1154 #endif
1155
1156 #if (CHIP == INTEL) || (CHIP == M68000 || MACHINE == SUN)
1157 if (seg != T)
1158 seg = (vc < rp->p_map[D].mem_vir + rp->p_map[D].mem_len ? D : S);
1159 #else
1160 if (seg != T)
1161 seg = (vc < rp->p_map[S].mem_vir ? D : S);
1162 #endif
1163
1164 #if (MACHINE == SUN)
1165 /*
1166 * Check that the address is after the start of the segment. In the stack
1167 * case this just means checking that it's beyond the data segment.
1168 */
1169 cstart = vir_addr >> CLICK_SHIFT;
1170 if (seg == S) {
1171 if (cstart < rp->p_map[D].mem_vir + rp->p_map[D].mem_len) {
1172 return( (phys_bytes) 0 );
1173 }
1174 } else {
1175 if (cstart < rp->p_map[seg].mem_vir) {
1176 return( (phys_bytes) 0 );
1177 }
1178 }
1179 /*
1180 * Now check that the address is before the end of the segment.
1181 */
1182 if (cstart >= rp->p_map[seg].mem_vir + rp->p_map[seg].mem_len) {
1183 return( (phys_bytes) 0 );
1184 }
1185 #endif
1186
1187 if (vc >= rp->p_map[seg].mem_vir + rp->p_map[seg].mem_len) {
1188 return( (phys_bytes) 0 );
1189 }
1190 #if (CHIP == INTEL)
1191 seg_base = (phys_bytes) rp->p_map[seg].mem_phys;
1192 seg_base = seg_base << CLICK_SHIFT; /* segment origin in bytes */
1193 #endif
1194 pa = (phys_bytes) vir_addr;
1195 #if (CHIP != M68000 && MACHINE != SUN)
1196 pa -= rp->p_map[seg].mem_vir << CLICK_SHIFT;
1197 return(seg_base + pa);
1198 #endif
1199 #if (CHIP == M68000 || MACHINE == SUN)
1200 #if (SHADOWING == 0)
1201 pa -= (phys_bytes)rp->p_map[seg].mem_vir << CLICK_SHIFT;
1202 pa += (phys_bytes)rp->p_map[seg].mem_phys << CLICK_SHIFT;
1203 #else
1204 if (rp->p_shadow && seg != T) {
1205 pa -= (phys_bytes)rp->p_map[D].mem_phys << CLICK_SHIFT;
1206 pa += (phys_bytes)rp->p_shadow << CLICK_SHIFT;
1207 }
1208 #endif
1209 return(pa);
1210 #endif
1211 }
1212
1213
1214 /*==========================================================================*
1215 * numap *
1216 *==========================================================================*/
1217 PUBLIC phys_bytes numap(proc_nr, vir_addr, bytes)
1218 int proc_nr; /* process number to be mapped */
1219 vir_bytes vir_addr; /* virtual address in bytes within D seg */
1220 vir_bytes bytes; /* # of bytes required in segment */
1221 {
1222 /* Do umap() starting from a process number instead of a pointer. This
1223 * function is used by device drivers, so they need not know about the
1224 * process table. To save time, there is no 'seg' parameter. The segment
1225 * is always D.
1226 */
1227
1228 return(umap(proc_addr(proc_nr), D, vir_addr, bytes));
1229 }
1230
1231
1232 #if (CHIP == INTEL)
1233 /*==========================================================================*
1234 * alloc_segments *
1235 *==========================================================================*/
1236 PUBLIC void alloc_segments(rp)
1237 register struct proc *rp;
1238 {
1239 /* This is called only by do_newmap, but is broken out as a separate function
1240 * because so much is hardware-dependent.
1241 */
1242
1243 phys_bytes code_bytes;
1244 phys_bytes data_bytes;
1245 int privilege;
1246
1247 if (protected_mode) {
1248 data_bytes = (phys_bytes) (rp->p_map[S].mem_vir + rp->p_map[S].mem_len)
1249 << CLICK_SHIFT;
1250 if (rp->p_map[T].mem_len == 0)
1251 code_bytes = data_bytes; /* common I&D, poor protect */
1252 else
1253 code_bytes = (phys_bytes) rp->p_map[T].mem_len << CLICK_SHIFT;
1254 privilege = istaskp(rp) ? TASK_PRIVILEGE : USER_PRIVILEGE;
1255 init_codeseg(&rp->p_ldt[CS_LDT_INDEX],
1256 (phys_bytes) rp->p_map[T].mem_phys << CLICK_SHIFT,
1257 code_bytes, privilege);
1258 init_dataseg(&rp->p_ldt[DS_LDT_INDEX],
1259 (phys_bytes) rp->p_map[D].mem_phys << CLICK_SHIFT,
1260 data_bytes, privilege);
1261 rp->p_reg.cs = (CS_LDT_INDEX * DESC_SIZE) | TI | privilege;
1262 #if _WORD_SIZE == 4
1263 rp->p_reg.gs =
1264 rp->p_reg.fs =
1265 #endif
1266 rp->p_reg.ss =
1267 rp->p_reg.es =
1268 rp->p_reg.ds = (DS_LDT_INDEX*DESC_SIZE) | TI | privilege;
1269 } else {
1270 rp->p_reg.cs = click_to_hclick(rp->p_map[T].mem_phys);
1271 rp->p_reg.ss =
1272 rp->p_reg.es =
1273 rp->p_reg.ds = click_to_hclick(rp->p_map[D].mem_phys);
1274 }
1275 }
1276 #endif /* (CHIP == INTEL) */
1277
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.