home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V6 / usr / sys / ken / trap.c < prev   
Encoding:
C/C++ Source or Header  |  1975-07-18  |  4.4 KB  |  213 lines

  1. #
  2. #include "../param.h"
  3. #include "../systm.h"
  4. #include "../user.h"
  5. #include "../proc.h"
  6. #include "../reg.h"
  7. #include "../seg.h"
  8.  
  9. #define    EBIT    1        /* user error bit in PS: C-bit */
  10. #define    UMODE    0170000        /* user-mode bits in PS word */
  11. #define    SETD    0170011        /* SETD instruction */
  12. #define    SYS    0104400        /* sys (trap) instruction */
  13. #define    USER    020        /* user-mode flag added to dev */
  14.  
  15. /*
  16.  * structure of the system entry table (sysent.c)
  17.  */
  18. struct sysent    {
  19.     int    count;        /* argument count */
  20.     int    (*call)();    /* name of handler */
  21. } sysent[64];
  22.  
  23. /*
  24.  * Offsets of the user's registers relative to
  25.  * the saved r0. See reg.h
  26.  */
  27. char    regloc[9]
  28. {
  29.     R0, R1, R2, R3, R4, R5, R6, R7, RPS
  30. };
  31.  
  32. /*
  33.  * Called from l40.s or l45.s when a processor trap occurs.
  34.  * The arguments are the words saved on the system stack
  35.  * by the hardware and software during the trap processing.
  36.  * Their order is dictated by the hardware and the details
  37.  * of C's calling sequence. They are peculiar in that
  38.  * this call is not 'by value' and changed user registers
  39.  * get copied back on return.
  40.  * dev is the kind of trap that occurred.
  41.  */
  42. trap(dev, sp, r1, nps, r0, pc, ps)
  43. {
  44.     register i, a;
  45.     register struct sysent *callp;
  46.  
  47.     savfp();
  48.     if ((ps&UMODE) == UMODE)
  49.         dev =| USER;
  50.     u.u_ar0 = &r0;
  51.     switch(dev) {
  52.  
  53.     /*
  54.      * Trap not expected.
  55.      * Usually a kernel mode bus error.
  56.      * The numbers printed are used to
  57.      * find the hardware PS/PC as follows.
  58.      * (all numbers in octal 18 bits)
  59.      *    address_of_saved_ps =
  60.      *        (ka6*0100) + aps - 0140000;
  61.      *    address_of_saved_pc =
  62.      *        address_of_saved_ps - 2;
  63.      */
  64.     default:
  65.         printf("ka6 = %o\n", *ka6);
  66.         printf("aps = %o\n", &ps);
  67.         printf("trap type %o\n", dev);
  68.         panic("trap");
  69.  
  70.     case 0+USER: /* bus error */
  71.         i = SIGBUS;
  72.         break;
  73.  
  74.     /*
  75.      * If illegal instructions are not
  76.      * being caught and the offending instruction
  77.      * is a SETD, the trap is ignored.
  78.      * This is because C produces a SETD at
  79.      * the beginning of every program which
  80.      * will trap on CPUs without 11/45 FPU.
  81.      */
  82.     case 1+USER: /* illegal instruction */
  83.         if(fuiword(pc-2) == SETD && u.u_signal[SIGINS] == 0)
  84.             goto out;
  85.         i = SIGINS;
  86.         break;
  87.  
  88.     case 2+USER: /* bpt or trace */
  89.         i = SIGTRC;
  90.         break;
  91.  
  92.     case 3+USER: /* iot */
  93.         i = SIGIOT;
  94.         break;
  95.  
  96.     case 5+USER: /* emt */
  97.         i = SIGEMT;
  98.         break;
  99.  
  100.     case 6+USER: /* sys call */
  101.         u.u_error = 0;
  102.         ps =& ~EBIT;
  103.         callp = &sysent[fuiword(pc-2)&077];
  104.         if (callp == sysent) { /* indirect */
  105.             a = fuiword(pc);
  106.             pc =+ 2;
  107.             i = fuword(a);
  108.             if ((i & ~077) != SYS)
  109.                 i = 077;    /* illegal */
  110.             callp = &sysent[i&077];
  111.             for(i=0; i<callp->count; i++)
  112.                 u.u_arg[i] = fuword(a =+ 2);
  113.         } else {
  114.             for(i=0; i<callp->count; i++) {
  115.                 u.u_arg[i] = fuiword(pc);
  116.                 pc =+ 2;
  117.             }
  118.         }
  119.         u.u_dirp = u.u_arg[0];
  120.         trap1(callp->call);
  121.         if(u.u_intflg)
  122.             u.u_error = EINTR;
  123.         if(u.u_error < 100) {
  124.             if(u.u_error) {
  125.                 ps =| EBIT;
  126.                 r0 = u.u_error;
  127.             }
  128.             goto out;
  129.         }
  130.         i = SIGSYS;
  131.         break;
  132.  
  133.     /*
  134.      * Since the floating exception is an
  135.      * imprecise trap, a user generated
  136.      * trap may actually come from kernel
  137.      * mode. In this case, a signal is sent
  138.      * to the current process to be picked
  139.      * up later.
  140.      */
  141.     case 8: /* floating exception */
  142.         psignal(u.u_procp, SIGFPT);
  143.         return;
  144.  
  145.     case 8+USER:
  146.         i = SIGFPT;
  147.         break;
  148.  
  149.     /*
  150.      * If the user SP is below the stack segment,
  151.      * grow the stack automatically.
  152.      * This relies on the ability of the hardware
  153.      * to restart a half executed instruction.
  154.      * On the 11/40 this is not the case and
  155.      * the routine backup/l40.s may fail.
  156.      * The classic example is on the instruction
  157.      *    cmp    -(sp),-(sp)
  158.      */
  159.     case 9+USER: /* segmentation exception */
  160.         a = sp;
  161.         if(backup(u.u_ar0) == 0)
  162.         if(grow(a))
  163.             goto out;
  164.         i = SIGSEG;
  165.         break;
  166.     }
  167.     psignal(u.u_procp, i);
  168.  
  169. out:
  170.     if(issig())
  171.         psig();
  172.     setpri(u.u_procp);
  173. }
  174.  
  175. /*
  176.  * Call the system-entry routine f (out of the
  177.  * sysent table). This is a subroutine for trap, and
  178.  * not in-line, because if a signal occurs
  179.  * during processing, an (abnormal) return is simulated from
  180.  * the last caller to savu(qsav); if this took place
  181.  * inside of trap, it wouldn't have a chance to clean up.
  182.  *
  183.  * If this occurs, the return takes place without
  184.  * clearing u_intflg; if it's still set, trap
  185.  * marks an error which means that a system
  186.  * call (like read on a typewriter) got interrupted
  187.  * by a signal.
  188.  */
  189. trap1(f)
  190. int (*f)();
  191. {
  192.  
  193.     u.u_intflg = 1;
  194.     savu(u.u_qsav);
  195.     (*f)();
  196.     u.u_intflg = 0;
  197. }
  198.  
  199. /*
  200.  * nonexistent system call-- set fatal error code.
  201.  */
  202. nosys()
  203. {
  204.     u.u_error = 100;
  205. }
  206.  
  207. /*
  208.  * Ignored system call
  209.  */
  210. nullsys()
  211. {
  212. }
  213.