Annotation of cci/sys/tahoe/trap.c, revision 1.1.1.1

1.1       root        1: /*     trap.c  4.10    84/02/09        */
                      2: 
                      3: #include "../machine/psl.h"
                      4: #include "../machine/reg.h"
                      5: #include "../machine/pte.h"
                      6: 
                      7: #include "../h/param.h"
                      8: #include "../h/systm.h"
                      9: #include "../h/dir.h"
                     10: #include "../h/user.h"
                     11: #include "../h/proc.h"
                     12: #include "../h/seg.h"
                     13: #include "../machine/trap.h"
                     14: #include "../h/acct.h"
                     15: #include "../h/kernel.h"
                     16: #include "../machine/mtpr.h"
                     17: #ifdef SYSCALLTRACE
                     18: #include "../sys/syscalls.c"
                     19: #endif
                     20: #include "../machine/fp_in_krnl.h"
                     21: 
                     22: #define        USER    040             /* user-mode flag added to type */
                     23: 
                     24: struct sysent  sysent[];
                     25: int nsysent;
                     26: 
                     27: /*
                     28:  * Called from the trap handler when a processor trap occurs.
                     29:  */
                     30: trap(sp, type, hfs, accmst, acclst, dbl, code, pc, psl)
                     31: unsigned code;
                     32: {
                     33:        /* Next 2 dummy variables MUST BE the first local */
                     34:        /* variables; leaving place for registers 0 and 1 */
                     35:        /* which are not preserved by the 'cct' */
                     36: 
                     37:        int     dumm1;          /* register 1 */
                     38:        int     dumm0;          /* register 0 */
                     39:        register dumm3;         /* register 12 is the 1'st register variable */
                     40:                                /* in TAHOE  (register 11 in VAX) */
                     41: 
                     42:        register int *locr0 = ((int *)&psl)-PS;
                     43:        register int i;
                     44:        register struct proc *p;
                     45:        struct timeval syst;
                     46:        char    *typename;
                     47: 
                     48:        syst = u.u_ru.ru_stime;
                     49:        if (USERMODE(locr0[PS])) {
                     50:                type |= USER;
                     51:                u.u_ar0 = locr0;
                     52:        }
                     53:        switch (type) {
                     54: 
                     55:        default: switch (type) {
                     56:                case T_RESADFLT:
                     57:                        typename = "reserved addressing mode";break;
                     58:                case T_PRIVINFLT:
                     59:                        typename = "illegal opcode";break;
                     60:                case T_RESOPFLT:
                     61:                        typename = "reserved operand";break;
                     62:                case T_BPTFLT:
                     63:                        typename = "breakpoint";break;
                     64:                case T_SYSCALL:
                     65:                        typename = "kernel call";break;
                     66:                case T_ARITHTRAP:
                     67:                        typename = "arithmetic exception";break;
                     68:                case T_ASTFLT:
                     69:                        typename = "system forced exception";break;
                     70:                case T_SEGFLT:
                     71:                        typename = "limit fault";break;
                     72:                case T_PROTFLT:
                     73:                        typename = "illegal access type";break;
                     74:                case T_TRCTRAP:
                     75:                        typename = "trace trap";break;
                     76:                case T_PAGEFLT:
                     77:                        typename = "page fault";break;
                     78:                case T_TABLEFLT:
                     79:                        typename = "page table fault";break;
                     80:                case T_ALIGNFLT:
                     81:                        typename = "alignment fault";break;
                     82:                case T_KSPNOTVAL:
                     83:                        typename = "kernel stack not valid";break;
                     84:                }
                     85:                printf("System trap (%s), code = %x, pc = %x\n", 
                     86:                                typename, code, pc);
                     87:                panic("trap");
                     88: 
                     89:        case T_PROTFLT + USER:  /* protection fault */
                     90:                i = SIGBUS;
                     91:                break;
                     92: 
                     93:        case T_PRIVINFLT + USER:        /* privileged instruction fault */
                     94:        case T_RESADFLT + USER: /* reserved addressing fault */
                     95:        case T_RESOPFLT + USER: /* resereved operand fault */
                     96:        case T_ALIGNFLT + USER: /* unaligned data fault */
                     97:                u.u_code = type &~ USER;
                     98:                i = SIGILL;
                     99:                break;
                    100: 
                    101:        case T_ASTFLT + USER:   /* Allow process switch */
                    102:        case T_ASTFLT:
                    103:                astoff();
                    104:                if ((u.u_procp->p_flag & SOWEUPC) && u.u_prof.pr_scale) {
                    105:                        addupc(pc, &u.u_prof, 1);
                    106:                        u.u_procp->p_flag &= ~SOWEUPC;
                    107:                }
                    108:                goto out;
                    109: 
                    110:        case T_ARITHTRAP + USER:
                    111:                u.u_code = code;
                    112:                i = SIGFPE;
                    113:                break;
                    114: 
                    115:        /*
                    116:         * If the user SP is above the stack segment,
                    117:         * grow the stack automatically.
                    118:         */
                    119:        case T_SEGFLT + USER:
                    120:                if (grow((unsigned)locr0[SP]) || grow(code))
                    121:                        goto out;
                    122:                i = SIGSEGV;
                    123:                break;
                    124: 
                    125:        case T_TABLEFLT:                /* allow page table faults in kernel mode */
                    126:        case T_TABLEFLT + USER:   /* page table fault */
                    127:                panic("ptable fault");
                    128: 
                    129:        case T_PAGEFLT:         /* allow page faults in kernel mode */
                    130:        case T_PAGEFLT + USER:  /* page fault */
                    131:                i = u.u_error;
                    132:                pagein(code, 0);
                    133:                u.u_error = i;
                    134:                if (type == T_PAGEFLT)
                    135:                        return;
                    136:                goto out;
                    137: 
                    138:        case T_BPTFLT + USER:   /* bpt instruction fault */
                    139:        case T_TRCTRAP + USER:  /* trace trap */
                    140:                locr0[PS] &= ~PSL_T;
                    141:                i = SIGTRAP;
                    142:                break;
                    143:        case T_KSPNOTVAL:
                    144:        case T_KSPNOTVAL + USER:
                    145:                i = SIGKILL;    /* There is nothing to do but to kill the 
                    146:                                 * process.. */
                    147:                printf("KSP NOT VALID.\n");
                    148:                break;
                    149: 
                    150:        }
                    151:        psignal(u.u_procp, i);
                    152: out:
                    153:        p = u.u_procp;
                    154:        if (p->p_cursig || ISSIG(p))
                    155:                psig();
                    156:        p->p_pri = p->p_usrpri;
                    157:        if (runrun) {
                    158:                /*
                    159:                 * Since we are u.u_procp, clock will normally just change
                    160:                 * our priority without moving us from one queue to another
                    161:                 * (since the running process is not on a queue.)
                    162:                 * If that happened after we setrq ourselves but before we
                    163:                 * swtch()'ed, we might not be on the queue indicated by
                    164:                 * our priority.
                    165:                 */
                    166:                (void) spl8();
                    167:                setrq(p);
                    168:                u.u_ru.ru_nivcsw++;
                    169:                swtch();
                    170:        }
                    171:        if (u.u_prof.pr_scale) {
                    172:                int ticks;
                    173:                struct timeval *tv = &u.u_ru.ru_stime;
                    174: 
                    175:                ticks = ((tv->tv_sec - syst.tv_sec) * 1000 +
                    176:                        (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000);
                    177:                if (ticks)
                    178:                        addupc(locr0[PC], &u.u_prof, ticks);
                    179:        }
                    180:        curpri = p->p_pri;
                    181: }
                    182: 
                    183: #ifdef SYSCALLTRACE
                    184: int syscalltrace = 0;
                    185: #endif
                    186: 
                    187: /*
                    188:  * Called from the trap handler when a system call occurs
                    189:  */
                    190: syscall(sp, type, hfs, accmst, acclst, dbl, code, pc, psl)
                    191: unsigned code;
                    192: {
                    193:        /* Next 2 dummy variables MUST BE the first local */
                    194:        /* variables; leaving place for registers 0 and 1 */
                    195:        /* which are not preserved by the 'cct' */
                    196: 
                    197:        int     dumm1;          /* register 1 */
                    198:        int     dumm0;          /* register 0 */
                    199:        register dumm3;         /* register 12 is the 1'st register variable */
                    200:                                /* in TAHOE  (register 11 in VAX) */
                    201: 
                    202:        register int *locr0 = ((int *)&psl)-PS;
                    203:        register caddr_t params;                /* known to be r10 below */
                    204:        register int i;                         /* known to be r9 below */
                    205:        register struct sysent *callp;
                    206:        register struct proc *p;
                    207:        struct  timeval syst;
                    208:        int opc;
                    209: 
                    210:        syst = u.u_ru.ru_stime;
                    211:        if (!USERMODE(locr0[PS]))
                    212:                panic("syscall");
                    213:        u.u_ar0 = locr0;
                    214:        if (code == 139) {                      /* XXX */
                    215:                sigcleanup();                   /* XXX */
                    216:                goto done;                      /* XXX */
                    217:        }
                    218:        params = (caddr_t)locr0[FP] + NBPW;
                    219:        u.u_error = 0;
                    220:        /*------ DIRTY CODE !!!!!!!!!---------*/
                    221:        /* try to reconstruct pc, assuming code is an immediate constant */
                    222:        opc = pc - 2;           /* short literal */
                    223:        if (code > 0x3f) {
                    224:                opc--;  /* byte immediate */
                    225:                if (code > 0x7f) {
                    226:                        opc--;  /* word immediate */
                    227:                        if (code > 0x7fff)
                    228:                                opc -= 2;       /* long immediate */
                    229:                }
                    230:        }
                    231:        /*------------------------------------*/
                    232:        callp = (code >= nsysent) ? &sysent[63] : &sysent[code];
                    233:        if (callp == sysent) {
                    234:                i = fuword(params);
                    235:                params += NBPW;
                    236:        callp = (code >= nsysent) ? &sysent[63] : &sysent[code];
                    237:        }
                    238:        if (i = callp->sy_narg * sizeof (int)) {
                    239:                asm("prober $1,(r10),r9");              /* GROT */
                    240:                asm("bnequ ok");                        /* GROT */
                    241:                u.u_error = EFAULT;                     /* GROT */
                    242:                goto bad;                               /* GROT */
                    243: asm("ok:");                                            /* GROT */
                    244:                bcopy(params,u.u_arg,i);
                    245:        }
                    246:        u.u_ap = u.u_arg;
                    247:        u.u_dirp = (caddr_t)u.u_arg[0];
                    248:        u.u_r.r_val1 = 0;
                    249:        u.u_r.r_val2 = locr0[R1]; /*------------ CHECK again */
                    250:        if (setjmp(&u.u_qsave)) {
                    251:                if (u.u_error == 0 && u.u_eosys == JUSTRETURN)
                    252:                        u.u_error = EINTR;
                    253:        } else {
                    254:                u.u_eosys = JUSTRETURN;
                    255: #ifdef SYSCALLTRACE
                    256:                if (syscalltrace) {
                    257:                        register int i;
                    258:                        char *cp;
                    259: 
                    260:                        if (code >= nsysent)
                    261:                                printf("0x%x", code);
                    262:                        else
                    263:                                printf("%s", syscallnames[code]);
                    264:                        cp = "(";
                    265:                        for (i= 0; i < callp->sy_narg; i++) {
                    266:                                printf("%s%x", cp, u.u_arg[i]);
                    267:                                cp = ", ";
                    268:                        }
                    269:                        if (i)
                    270:                                putchar(')', 0);
                    271:                        putchar('\n', 0);
                    272:                }
                    273: #endif
                    274: 
                    275:                (*(callp->sy_call))();
                    276:        }
                    277:        if (u.u_eosys == RESTARTSYS)
                    278:                pc = opc;
                    279:        else if (u.u_error) {
                    280: bad:
                    281:                locr0[R0] = u.u_error;
                    282:                locr0[PS] |= PSL_C;     /* carry bit */
                    283:        } else {
                    284:                locr0[PS] &= ~PSL_C;    /* clear carry bit */
                    285:                locr0[R0] = u.u_r.r_val1;
                    286:                locr0[R1] = u.u_r.r_val2;
                    287:        }
                    288: done:
                    289:        p = u.u_procp;
                    290:        if (p->p_cursig || ISSIG(p))
                    291:                psig();
                    292:        p->p_pri = p->p_usrpri;
                    293:        if (runrun) {
                    294:                /*
                    295:                 * Since we are u.u_procp, clock will normally just change
                    296:                 * our priority without moving us from one queue to another
                    297:                 * (since the running process is not on a queue.)
                    298:                 * If that happened after we setrq ourselves but before we
                    299:                 * swtch()'ed, we might not be on the queue indicated by
                    300:                 * our priority.
                    301:                 */
                    302:                (void) spl8();
                    303:                setrq(p);
                    304:                u.u_ru.ru_nivcsw++;
                    305:                swtch();
                    306:        }
                    307:        if (u.u_prof.pr_scale) {
                    308:                int ticks;
                    309:                struct timeval *tv = &u.u_ru.ru_stime;
                    310: 
                    311:                ticks = ((tv->tv_sec - syst.tv_sec) * 1000 +
                    312:                        (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000);
                    313:                if (ticks)
                    314:                        addupc(locr0[PC], &u.u_prof, ticks);
                    315:        }
                    316:        curpri = p->p_pri;
                    317: }
                    318: 
                    319: /*
                    320:  * nonexistent system call-- signal process (may want to handle it)
                    321:  * flag error if process won't see signal immediately
                    322:  * Q: should we do that all the time ??
                    323:  */
                    324: nosys()
                    325: {
                    326:        if (u.u_signal[SIGSYS] == SIG_IGN || u.u_signal[SIGSYS] == SIG_HOLD)
                    327:                u.u_error = EINVAL;
                    328:        psignal(u.u_procp, SIGSYS);
                    329: }
                    330: 
                    331: /*
                    332:  * Ignored system call
                    333:  */
                    334: nullsys()
                    335: {
                    336: 
                    337: }
                    338: 
                    339: fpemulate(hfsreg,acc_most,acc_least,dbl,op_most,op_least,opcode,pc,psl)
                    340: {
                    341: /*
                    342:  * Emulate the F.P. 'opcode'. Update psl flags as necessary.
                    343:  * If all OK, set 'opcode' to 0, else to the F.P. exception #.
                    344:  * Not all parameter longwords are relevant - depends on opcode.
                    345:  *
                    346:  * The entry mask is set so ALL registers are saved - courtesy of
                    347:  *  locore.s. This enables F.P. opcodes to change 'user' registers
                    348:  *  before return.
                    349:  */
                    350: 
                    351:  /* WARNING!!!! THIS CODE MUST NOT PRODUCE ANY FLOATING POINT EXCEPTIONS. */
                    352: 
                    353:        /* Next 2 dummy variables MUST BE the first local */
                    354:        /* variables; leaving place for registers 0 and 1 */
                    355:        /* which are not preserved by the 'cct' */
                    356: 
                    357:        int     dumm1;          /* register 1 */
                    358:        int     dumm0;          /* register 0 */
                    359:        register dumm3;         /* register 12 is the 1'st register variable */
                    360:                                /* in TAHOE  (register 11 in VAX) */
                    361: 
                    362:        register int *locr0 = ((int *)&psl)-PS; /* R11 */
                    363:        int hfs = 0;                    /* returned data about exceptions */
                    364:        float (*f_proc)();              /* fp procedure to be called.   */
                    365:        double (*d_proc)();             /* fp procedure to be called.   */
                    366:        int dest_type;                  /* float or double.     */
                    367:        union{
                    368:                float ff;                       /* float result.        */
                    369:                int fi;
                    370:        }f_res;
                    371:        union{
                    372:                double  dd;                     /* double result.       */
                    373:                int     di[2] ;
                    374:        }d_res;
                    375:        extern float    Kcvtlf(), Kaddf(), Ksubf(), Kmulf(), Kdivf();
                    376:        extern double   Kcvtld(), Kaddd(), Ksubd(), Kmuld(), Kdivd();
                    377:        extern float    Ksinf(), Kcosf(), Katanf(), Klogf(), Ksqrtf(), Kexpf();
                    378:        
                    379:        
                    380: 
                    381:        switch(opcode & 0x0FF){
                    382: 
                    383:        case CVLF:      f_proc = Kcvtlf; dest_type = FLOAT; 
                    384:                        locr0[PS] &= ~PSL_DBL;
                    385:                        dbl &= ~1;break;        /* clear double bit */
                    386:        case CVLD:      d_proc = Kcvtld; dest_type = DOUBLE; 
                    387:                        locr0[PS] |= PSL_DBL;
                    388:                        dbl |= 1; break;        /* turn on double bit */
                    389:        case ADDF:      f_proc = Kaddf; dest_type = FLOAT;
                    390:                        break;
                    391:        case ADDD:      d_proc = Kaddd; dest_type = DOUBLE;
                    392:                        break;
                    393:        case SUBF:      f_proc = Ksubf; dest_type = FLOAT;
                    394:                        break;
                    395:        case SUBD:      d_proc = Ksubd; dest_type = DOUBLE;
                    396:                        break;
                    397:        case MULF:      f_proc = Kmulf; dest_type = FLOAT;
                    398:                        break;
                    399:        case MULD:      d_proc = Kmuld; dest_type = DOUBLE;
                    400:                        break;
                    401:        case DIVF:      f_proc = Kdivf; dest_type = FLOAT;
                    402:                        break;
                    403:        case DIVD:      d_proc = Kdivd; dest_type = DOUBLE;
                    404:                        break;
                    405:        case SINF:      f_proc = Ksinf; dest_type = FLOAT;
                    406:                        break;
                    407:        case COSF:      f_proc = Kcosf; dest_type = FLOAT;
                    408:                        break;
                    409:        case ATANF:     f_proc = Katanf; dest_type = FLOAT;
                    410:                        break;
                    411:        case LOGF:      f_proc = Klogf; dest_type = FLOAT;
                    412:                        break;
                    413:        case SQRTF:     f_proc = Ksqrtf; dest_type = FLOAT;
                    414:                        break;
                    415:        case EXPF:      f_proc = Kexpf; dest_type = FLOAT;
                    416:                        break;
                    417:        }
                    418: 
                    419:        switch(dest_type){
                    420: 
                    421:        case FLOAT: 
                    422:                f_res.ff = (*f_proc)(acc_most,acc_least,op_most,op_least,&hfs);
                    423: 
                    424:                if (f_res.fi == 0 ) locr0[PS] |= PSL_Z;
                    425:                if (f_res.fi < 0 ) locr0[PS] |= PSL_N;
                    426:                break;
                    427:        case DOUBLE:
                    428:                d_res.dd = (*d_proc)(acc_most,acc_least,op_most,op_least,&hfs);
                    429:                if ((d_res.di[0] == 0) && (d_res.di[1] == 0))
                    430:                                                locr0[PS] |= PSL_Z;
                    431:                if (d_res.di[0] < 0 ) locr0[PS] |= PSL_N;
                    432:                break;
                    433:        }
                    434: 
                    435:        if (hfs & HFS_OVF){
                    436:                locr0[PS] |= PSL_V;     /* turn on overflow bit */
                    437:                /* if (locr0[PS] & PSL_IV)   {  /* overflow elabled?    */
                    438:                        opcode = OVF_EXC;
                    439:                        u.u_error = (hfs & HFS_DOM) ? EDOM : ERANGE;
                    440:                        return;
                    441:                /*}*/
                    442:        }
                    443:        else if (hfs & HFS_UNDF){
                    444:                if (locr0[PS] & PSL_FU){  /* underflow elabled? */
                    445:                        opcode = UNDF_EXC;
                    446:                        u.u_error = (hfs & HFS_DOM) ? EDOM : ERANGE;
                    447:                        return;
                    448:                } 
                    449:        }
                    450:        else if (hfs & HFS_DIVZ){
                    451:                opcode = DIV0_EXC;
                    452:                return;
                    453:        }
                    454:        else if (hfs & HFS_DOM)
                    455:                u.u_error = EDOM;
                    456:        else if (hfs & HFS_RANGE)
                    457:                u.u_error = ERANGE;
                    458: 
                    459:        switch(dest_type){
                    460:        case FLOAT:
                    461:                if ((hfs & HFS_OVF) || (hfs & HFS_UNDF)) {
                    462:                        f_res.ff = 0.0;
                    463:                        locr0[PS] |= PSL_Z;
                    464:                }
                    465:                mvtofacc(f_res.ff, &acc_most);
                    466:                break;
                    467:        case DOUBLE:
                    468:                if ((hfs & HFS_OVF) || (hfs & HFS_UNDF)) {
                    469:                        d_res.dd = 0.0;
                    470:                        locr0[PS] |= PSL_Z;
                    471:                }
                    472:                mvtodacc(d_res.di[0], d_res.di[1], &acc_most);
                    473:                break;
                    474:        }
                    475:        opcode=0;
                    476: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.