Guest User

Untitled

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