00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "debug.h"
00033 #include "kernel.h"
00034 #include "system.h"
00035 #include <stdlib.h>
00036 #include <signal.h>
00037 #include <unistd.h>
00038 #include <sys/sigcontext.h>
00039 #include <minix/endpoint.h>
00040 #if (CHIP == INTEL)
00041 #include <ibm/memory.h>
00042 #include "protect.h"
00043 #endif
00044
00045
00046
00047
00048
00049
00050
00051 PUBLIC int (*call_vec[NR_SYS_CALLS])(message *m_ptr);
00052
00053 #define map(call_nr, handler) \
00054 {extern int dummy[NR_SYS_CALLS>(unsigned)(call_nr-KERNEL_CALL) ? 1:-1];} \
00055 call_vec[(call_nr-KERNEL_CALL)] = (handler)
00056
00057 FORWARD _PROTOTYPE( void initialize, (void));
00058
00059
00060
00061
00062 PUBLIC void sys_task()
00063 {
00064
00065 static message m;
00066 register int result;
00067 register struct proc *caller_ptr;
00068 unsigned int call_nr;
00069 int s;
00070
00071
00072 initialize();
00073
00074 while (TRUE) {
00075
00076 receive(ANY, &m);
00077 call_nr = (unsigned) m.m_type - KERNEL_CALL;
00078 who_e = m.m_source;
00079 okendpt(who_e, &who_p);
00080 caller_ptr = proc_addr(who_p);
00081
00082
00083 if (! (priv(caller_ptr)->s_call_mask & (1<<call_nr))) {
00084 #if DEBUG_ENABLE_IPC_WARNINGS
00085 kprintf("SYSTEM: request %d from %d denied.\n", call_nr,m.m_source);
00086 #endif
00087 result = ECALLDENIED;
00088 } else if (call_nr >= NR_SYS_CALLS) {
00089 #if DEBUG_ENABLE_IPC_WARNINGS
00090 kprintf("SYSTEM: illegal request %d from %d.\n", call_nr,m.m_source);
00091 #endif
00092 result = EBADREQUEST;
00093 }
00094 else {
00095 result = (*call_vec[call_nr])(&m);
00096 }
00097
00098
00099
00100
00101
00102 if (result != EDONTREPLY) {
00103 m.m_type = result;
00104 if (OK != (s=lock_send(m.m_source, &m))) {
00105 kprintf("SYSTEM, reply to %d failed: %d\n", m.m_source, s);
00106 }
00107 }
00108 }
00109 }
00110
00111
00112
00113
00114 PRIVATE void initialize(void)
00115 {
00116 register struct priv *sp;
00117 int i;
00118
00119
00120 for (i=0; i<NR_IRQ_HOOKS; i++) {
00121 irq_hooks[i].proc_nr_e = NONE;
00122 }
00123
00124
00125 for (sp=BEG_PRIV_ADDR; sp < END_PRIV_ADDR; sp++) {
00126 tmr_inittimer(&(sp->s_alarm_timer));
00127 }
00128
00129
00130
00131
00132
00133
00134 for (i=0; i<NR_SYS_CALLS; i++) {
00135 call_vec[i] = do_unused;
00136 }
00137
00138
00139 map(SYS_FORK, do_fork);
00140 map(SYS_EXEC, do_exec);
00141 map(SYS_EXIT, do_exit);
00142 map(SYS_NICE, do_nice);
00143 map(SYS_PRIVCTL, do_privctl);
00144 map(SYS_TRACE, do_trace);
00145
00146
00147 map(SYS_KILL, do_kill);
00148 map(SYS_GETKSIG, do_getksig);
00149 map(SYS_ENDKSIG, do_endksig);
00150 map(SYS_SIGSEND, do_sigsend);
00151 map(SYS_SIGRETURN, do_sigreturn);
00152
00153
00154 map(SYS_IRQCTL, do_irqctl);
00155 map(SYS_DEVIO, do_devio);
00156 map(SYS_SDEVIO, do_sdevio);
00157 map(SYS_VDEVIO, do_vdevio);
00158 map(SYS_INT86, do_int86);
00159
00160
00161 map(SYS_NEWMAP, do_newmap);
00162 map(SYS_SEGCTL, do_segctl);
00163 map(SYS_MEMSET, do_memset);
00164 map(SYS_VM_SETBUF, do_vm_setbuf);
00165 map(SYS_VM_MAP, do_vm_map);
00166
00167
00168 map(SYS_UMAP, do_umap);
00169 map(SYS_VIRCOPY, do_vircopy);
00170 map(SYS_PHYSCOPY, do_physcopy);
00171 map(SYS_VIRVCOPY, do_virvcopy);
00172 map(SYS_PHYSVCOPY, do_physvcopy);
00173
00174
00175 map(SYS_TIMES, do_times);
00176 map(SYS_SETALARM, do_setalarm);
00177
00178
00179 map(SYS_ABORT, do_abort);
00180 map(SYS_GETINFO, do_getinfo);
00181 map(SYS_IOPENABLE, do_iopenable);
00182 }
00183
00184
00185
00186
00187 PUBLIC int get_priv(rc, proc_type)
00188 register struct proc *rc;
00189 int proc_type;
00190 {
00191
00192
00193
00194 register struct priv *sp;
00195
00196 if (proc_type == SYS_PROC) {
00197 for (sp = BEG_PRIV_ADDR; sp < END_PRIV_ADDR; ++sp)
00198 if (sp->s_proc_nr == NONE && sp->s_id != USER_PRIV_ID) break;
00199 if (sp->s_proc_nr != NONE) return(ENOSPC);
00200 rc->p_priv = sp;
00201 rc->p_priv->s_proc_nr = proc_nr(rc);
00202 rc->p_priv->s_flags = SYS_PROC;
00203 } else {
00204 rc->p_priv = &priv[USER_PRIV_ID];
00205 rc->p_priv->s_proc_nr = INIT_PROC_NR;
00206 rc->p_priv->s_flags = 0;
00207 }
00208 return(OK);
00209 }
00210
00211
00212
00213
00214 PUBLIC void get_randomness(source)
00215 int source;
00216 {
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 int r_next;
00227 unsigned long tsc_high, tsc_low;
00228
00229 source %= RANDOM_SOURCES;
00230 r_next= krandom.bin[source].r_next;
00231 if (machine.processor > 486) {
00232 read_tsc(&tsc_high, &tsc_low);
00233 krandom.bin[source].r_buf[r_next] = tsc_low;
00234 } else {
00235 krandom.bin[source].r_buf[r_next] = read_clock();
00236 }
00237 if (krandom.bin[source].r_size < RANDOM_ELEMENTS) {
00238 krandom.bin[source].r_size ++;
00239 }
00240 krandom.bin[source].r_next = (r_next + 1 ) % RANDOM_ELEMENTS;
00241 }
00242
00243
00244
00245
00246 PUBLIC void send_sig(int proc_nr, int sig_nr)
00247 {
00248
00249
00250
00251
00252
00253
00254
00255 register struct proc *rp;
00256 static int n;
00257
00258 if(!isokprocn(proc_nr) || isemptyn(proc_nr))
00259 return;
00260
00261 rp = proc_addr(proc_nr);
00262 sigaddset(&priv(rp)->s_sig_pending, sig_nr);
00263 lock_notify(SYSTEM, rp->p_endpoint);
00264 }
00265
00266
00267
00268
00269 PUBLIC void cause_sig(proc_nr, sig_nr)
00270 int proc_nr;
00271 int sig_nr;
00272 {
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 register struct proc *rp;
00287
00288
00289 rp = proc_addr(proc_nr);
00290 if (! sigismember(&rp->p_pending, sig_nr)) {
00291 sigaddset(&rp->p_pending, sig_nr);
00292 if (! (rp->p_rts_flags & SIGNALED)) {
00293 if (rp->p_rts_flags == 0) lock_dequeue(rp);
00294 rp->p_rts_flags |= SIGNALED | SIG_PENDING;
00295 send_sig(PM_PROC_NR, SIGKSIG);
00296 }
00297 }
00298 }
00299
00300
00301
00302
00303 PUBLIC phys_bytes umap_bios(rp, vir_addr, bytes)
00304 register struct proc *rp;
00305 vir_bytes vir_addr;
00306 vir_bytes bytes;
00307 {
00308
00309
00310
00311
00312
00313
00314
00315
00316 if (vir_addr >= BIOS_MEM_BEGIN && vir_addr + bytes <= BIOS_MEM_END)
00317 return (phys_bytes) vir_addr;
00318 else if (vir_addr >= BASE_MEM_TOP && vir_addr + bytes <= UPPER_MEM_END)
00319 return (phys_bytes) vir_addr;
00320
00321 #if DEAD_CODE
00322 if (vir_addr >= BIOS_MEM_BEGIN && vir_addr + bytes <= UPPER_MEM_END)
00323 return (phys_bytes) vir_addr;
00324 #endif
00325
00326 kprintf("Warning, error in umap_bios, virtual address 0x%x\n", vir_addr);
00327 return 0;
00328 }
00329
00330
00331
00332
00333 PUBLIC phys_bytes umap_local(rp, seg, vir_addr, bytes)
00334 register struct proc *rp;
00335 int seg;
00336 vir_bytes vir_addr;
00337 vir_bytes bytes;
00338 {
00339
00340 vir_clicks vc;
00341 phys_bytes pa;
00342 #if (CHIP == INTEL)
00343 phys_bytes seg_base;
00344 #endif
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 if (bytes <= 0) return( (phys_bytes) 0);
00355 if (vir_addr + bytes <= vir_addr) return 0;
00356 vc = (vir_addr + bytes - 1) >> CLICK_SHIFT;
00357
00358 #if (CHIP == INTEL) || (CHIP == M68000)
00359 if (seg != T)
00360 seg = (vc < rp->p_memmap[D].mem_vir + rp->p_memmap[D].mem_len ? D : S);
00361 #else
00362 if (seg != T)
00363 seg = (vc < rp->p_memmap[S].mem_vir ? D : S);
00364 #endif
00365
00366 if ((vir_addr>>CLICK_SHIFT) >= rp->p_memmap[seg].mem_vir +
00367 rp->p_memmap[seg].mem_len) return( (phys_bytes) 0 );
00368
00369 if (vc >= rp->p_memmap[seg].mem_vir +
00370 rp->p_memmap[seg].mem_len) return( (phys_bytes) 0 );
00371
00372 #if (CHIP == INTEL)
00373 seg_base = (phys_bytes) rp->p_memmap[seg].mem_phys;
00374 seg_base = seg_base << CLICK_SHIFT;
00375 #endif
00376 pa = (phys_bytes) vir_addr;
00377 #if (CHIP != M68000)
00378 pa -= rp->p_memmap[seg].mem_vir << CLICK_SHIFT;
00379 return(seg_base + pa);
00380 #endif
00381 #if (CHIP == M68000)
00382 pa -= (phys_bytes)rp->p_memmap[seg].mem_vir << CLICK_SHIFT;
00383 pa += (phys_bytes)rp->p_memmap[seg].mem_phys << CLICK_SHIFT;
00384 return(pa);
00385 #endif
00386 }
00387
00388
00389
00390
00391 PUBLIC phys_bytes umap_remote(rp, seg, vir_addr, bytes)
00392 register struct proc *rp;
00393 int seg;
00394 vir_bytes vir_addr;
00395 vir_bytes bytes;
00396 {
00397
00398 struct far_mem *fm;
00399
00400 if (bytes <= 0) return( (phys_bytes) 0);
00401 if (seg < 0 || seg >= NR_REMOTE_SEGS) return( (phys_bytes) 0);
00402
00403 fm = &rp->p_priv->s_farmem[seg];
00404 if (! fm->in_use) return( (phys_bytes) 0);
00405 if (vir_addr + bytes > fm->mem_len) return( (phys_bytes) 0);
00406
00407 return(fm->mem_phys + (phys_bytes) vir_addr);
00408 }
00409
00410
00411
00412
00413 PUBLIC int virtual_copy(src_addr, dst_addr, bytes)
00414 struct vir_addr *src_addr;
00415 struct vir_addr *dst_addr;
00416 vir_bytes bytes;
00417 {
00418
00419
00420
00421 struct vir_addr *vir_addr[2];
00422 phys_bytes phys_addr[2];
00423 int seg_index;
00424 int i;
00425
00426
00427 if (bytes <= 0) return(EDOM);
00428
00429
00430 vir_addr[_SRC_] = src_addr;
00431 vir_addr[_DST_] = dst_addr;
00432 for (i=_SRC_; i<=_DST_; i++) {
00433 int proc_nr, type;
00434 struct proc *p;
00435
00436 type = vir_addr[i]->segment & SEGMENT_TYPE;
00437 if(type != PHYS_SEG && isokendpt(vir_addr[i]->proc_nr_e, &proc_nr))
00438 p = proc_addr(proc_nr);
00439 else
00440 p = NULL;
00441
00442
00443 switch(type) {
00444 case LOCAL_SEG:
00445 if(!p) return EDEADSRCDST;
00446 seg_index = vir_addr[i]->segment & SEGMENT_INDEX;
00447 phys_addr[i] = umap_local(p, seg_index, vir_addr[i]->offset, bytes);
00448 break;
00449 case REMOTE_SEG:
00450 if(!p) return EDEADSRCDST;
00451 seg_index = vir_addr[i]->segment & SEGMENT_INDEX;
00452 phys_addr[i] = umap_remote(p, seg_index, vir_addr[i]->offset, bytes);
00453 break;
00454 case BIOS_SEG:
00455 if(!p) return EDEADSRCDST;
00456 phys_addr[i] = umap_bios(p, vir_addr[i]->offset, bytes );
00457 break;
00458 case PHYS_SEG:
00459 phys_addr[i] = vir_addr[i]->offset;
00460 break;
00461 default:
00462 return(EINVAL);
00463 }
00464
00465
00466 if (phys_addr[i] <= 0 && vir_addr[i]->segment != PHYS_SEG)
00467 return(EFAULT);
00468 }
00469
00470
00471 phys_copy(phys_addr[_SRC_], phys_addr[_DST_], (phys_bytes) bytes);
00472 return(OK);
00473 }
00474
00475
00476
00477
00478
00479 PUBLIC void clear_endpoint(rc)
00480 register struct proc *rc;
00481 {
00482 register struct proc *rp;
00483 register struct proc **xpp;
00484 int i;
00485 int sys_id;
00486
00487 if(isemptyp(rc)) panic("clear_proc: empty process", proc_nr(rc));
00488
00489
00490 if (rc->p_rts_flags == 0) lock_dequeue(rc);
00491 rc->p_rts_flags |= NO_ENDPOINT;
00492
00493
00494
00495
00496 if (rc->p_rts_flags & SENDING) {
00497 int target_proc;
00498
00499 okendpt(rc->p_sendto_e, &target_proc);
00500 xpp = &proc_addr(target_proc)->p_caller_q;
00501 while (*xpp != NIL_PROC) {
00502 if (*xpp == rc) {
00503 *xpp = (*xpp)->p_q_link;
00504 #if DEBUG_ENABLE_IPC_WARNINGS
00505 kprintf("Proc %d removed from queue at %d\n",
00506 proc_nr(rc), rc->p_sendto_e);
00507 #endif
00508 break;
00509 }
00510 xpp = &(*xpp)->p_q_link;
00511 }
00512 rc->p_rts_flags &= ~SENDING;
00513 }
00514 rc->p_rts_flags &= ~RECEIVING;
00515
00516
00517
00518
00519
00520 for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++) {
00521 if(isemptyp(rp))
00522 continue;
00523
00524
00525 unset_sys_bit(priv(rp)->s_notify_pending, priv(rc)->s_id);
00526
00527
00528 if ((rp->p_rts_flags & RECEIVING) && rp->p_getfrom_e == rc->p_endpoint) {
00529 rp->p_reg.retreg = ESRCDIED;
00530 rp->p_rts_flags &= ~RECEIVING;
00531 #if DEBUG_ENABLE_IPC_WARNINGS
00532 kprintf("Proc %d receive dead src %d\n", proc_nr(rp), proc_nr(rc));
00533 #endif
00534 if (rp->p_rts_flags == 0) lock_enqueue(rp);
00535 }
00536 if ((rp->p_rts_flags & SENDING) && rp->p_sendto_e == rc->p_endpoint) {
00537 rp->p_reg.retreg = EDSTDIED;
00538 rp->p_rts_flags &= ~SENDING;
00539 #if DEBUG_ENABLE_IPC_WARNINGS
00540 kprintf("Proc %d send dead dst %d\n", proc_nr(rp), proc_nr(rc));
00541 #endif
00542 if (rp->p_rts_flags == 0) lock_enqueue(rp);
00543 }
00544 }
00545 }
00546
00547