Annotation of 43BSD/sys/vax/trap.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1982, 1986 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  *
                      6:  *     @(#)trap.c      7.1 (Berkeley) 6/5/86
                      7:  */
                      8: 
                      9: #include "psl.h"
                     10: #include "reg.h"
                     11: #include "pte.h"
                     12: 
                     13: #include "param.h"
                     14: #include "systm.h"
                     15: #include "dir.h"
                     16: #include "user.h"
                     17: #include "assym.s"
                     18: #include "proc.h"
                     19: #include "seg.h"
                     20: #include "trap.h"
                     21: #include "acct.h"
                     22: #include "kernel.h"
                     23: #ifdef SYSCALLTRACE
                     24: #include "../sys/syscalls.c"
                     25: #endif
                     26: 
                     27: #include "mtpr.h"
                     28: 
                     29: #define        USER    040             /* user-mode flag added to type */
                     30: 
                     31: struct sysent  sysent[];
                     32: int    nsysent;
                     33: 
                     34: char   *trap_type[] = {
                     35:        "Reserved addressing mode",
                     36:        "Privileged instruction",
                     37:        "Reserved operand",
                     38:        "Breakpoint",
                     39:        "Xfc trap",
                     40:        "Syscall trap",
                     41:        "Arithmetic fault",
                     42:        "Ast trap",
                     43:        "Segmentation fault",
                     44:        "Protection fault",
                     45:        "Trace trap",
                     46:        "Compatibility mode trap",
                     47: #ifdef notdef
                     48:        "Page fault",
                     49:        "Page table fault",
                     50: #endif
                     51: };
                     52: #define        TRAP_TYPES      (sizeof trap_type / sizeof trap_type[0])
                     53: 
                     54: /*
                     55:  * Called from the trap handler when a processor trap occurs.
                     56:  */
                     57: /*ARGSUSED*/
                     58: trap(sp, type, code, pc, psl)
                     59:        int sp, type;
                     60:        unsigned code;
                     61:        int pc, psl;
                     62: {
                     63:        register int *locr0 = ((int *)&psl)-PS;
                     64:        register int i;
                     65:        register struct proc *p;
                     66:        struct timeval syst;
                     67: 
                     68:        syst = u.u_ru.ru_stime;
                     69:        if (USERMODE(locr0[PS])) {
                     70:                type |= USER;
                     71:                u.u_ar0 = locr0;
                     72:        }
                     73:        switch (type) {
                     74: 
                     75:        default:
                     76:                printf("trap type %d, code = %x, pc = %x\n", type, code, pc);
                     77:                type &= ~USER;
                     78:                if ((unsigned)type < TRAP_TYPES)
                     79:                        panic(trap_type[type]);
                     80:                panic("trap");
                     81: 
                     82:        case T_PROTFLT+USER:    /* protection fault */
                     83:                i = SIGBUS;
                     84:                break;
                     85: 
                     86:        case T_PRIVINFLT+USER:  /* privileged instruction fault */
                     87:        case T_RESADFLT+USER:   /* reserved addressing fault */
                     88:        case T_RESOPFLT+USER:   /* resereved operand fault */
                     89:                u.u_code = type &~ USER;
                     90:                i = SIGILL;
                     91:                break;
                     92: 
                     93:        case T_ASTFLT+USER:
                     94:                astoff();
                     95:                if ((u.u_procp->p_flag & SOWEUPC) && u.u_prof.pr_scale) {
                     96:                        addupc(pc, &u.u_prof, 1);
                     97:                        u.u_procp->p_flag &= ~SOWEUPC;
                     98:                }
                     99:                goto out;
                    100: 
                    101:        case T_ARITHTRAP+USER:
                    102:                u.u_code = code;
                    103:                i = SIGFPE;
                    104:                break;
                    105: 
                    106:        /*
                    107:         * If the user SP is above the stack segment,
                    108:         * grow the stack automatically.
                    109:         */
                    110:        case T_SEGFLT+USER:
                    111:                if (grow((unsigned)locr0[SP]) || grow(code))
                    112:                        goto out;
                    113:                i = SIGSEGV;
                    114:                break;
                    115: 
                    116:        case T_TABLEFLT:        /* allow page table faults in kernel mode */
                    117:        case T_TABLEFLT+USER:   /* page table fault */
                    118:                panic("ptable fault");
                    119: 
                    120:        case T_PAGEFLT:         /* allow page faults in kernel mode */
                    121:        case T_PAGEFLT+USER:    /* page fault */
                    122:                i = u.u_error;
                    123:                pagein(code, 0);
                    124:                u.u_error = i;
                    125:                if (type == T_PAGEFLT)
                    126:                        return;
                    127:                goto out;
                    128: 
                    129:        case T_BPTFLT+USER:     /* bpt instruction fault */
                    130:        case T_TRCTRAP+USER:    /* trace trap */
                    131:                locr0[PS] &= ~PSL_T;
                    132:                i = SIGTRAP;
                    133:                break;
                    134: 
                    135:        case T_XFCFLT+USER:     /* xfc instruction fault */
                    136:                i = SIGEMT;
                    137:                break;
                    138: 
                    139:        case T_COMPATFLT+USER:  /* compatibility mode fault */
                    140:                u.u_acflag |= ACOMPAT;
                    141:                u.u_code = code;
                    142:                i = SIGILL;
                    143:                break;
                    144:        }
                    145:        psignal(u.u_procp, i);
                    146: out:
                    147:        p = u.u_procp;
                    148:        if (p->p_cursig || ISSIG(p))
                    149:                psig();
                    150:        p->p_pri = p->p_usrpri;
                    151:        if (runrun) {
                    152:                /*
                    153:                 * Since we are u.u_procp, clock will normally just change
                    154:                 * our priority without moving us from one queue to another
                    155:                 * (since the running process is not on a queue.)
                    156:                 * If that happened after we setrq ourselves but before we
                    157:                 * swtch()'ed, we might not be on the queue indicated by
                    158:                 * our priority.
                    159:                 */
                    160:                (void) splclock();
                    161:                setrq(p);
                    162:                u.u_ru.ru_nivcsw++;
                    163:                swtch();
                    164:        }
                    165:        if (u.u_prof.pr_scale) {
                    166:                int ticks;
                    167:                struct timeval *tv = &u.u_ru.ru_stime;
                    168: 
                    169:                ticks = ((tv->tv_sec - syst.tv_sec) * 1000 +
                    170:                        (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000);
                    171:                if (ticks)
                    172:                        addupc(locr0[PC], &u.u_prof, ticks);
                    173:        }
                    174:        curpri = p->p_pri;
                    175: }
                    176: 
                    177: #ifdef SYSCALLTRACE
                    178: int syscalltrace = 0;
                    179: #endif
                    180: /*
                    181:  * Called from the trap handler when a system call occurs
                    182:  */
                    183: /*ARGSUSED*/
                    184: syscall(sp, type, code, pc, psl)
                    185:        unsigned code;
                    186: {
                    187:        register int *locr0 = ((int *)&psl)-PS;
                    188:        register caddr_t params;                /* known to be r10 below */
                    189:        register int i;                         /* known to be r9 below */
                    190:        register struct sysent *callp;
                    191:        register struct proc *p;
                    192:        int opc;
                    193:        struct timeval syst;
                    194: 
                    195:        syst = u.u_ru.ru_stime;
                    196:        if (!USERMODE(locr0[PS]))
                    197:                panic("syscall");
                    198:        u.u_ar0 = locr0;
                    199:        if (code == 139) {                      /* XXX 4.2 COMPATIBILITY */
                    200:                osigcleanup();                  /* XXX 4.2 COMPATIBILITY */
                    201:                goto done;                      /* XXX 4.2 COMPATIBILITY */
                    202:        }                                       /* XXX 4.2 COMPATIBILITY */
                    203:        params = (caddr_t)locr0[AP] + NBPW;
                    204:        u.u_error = 0;
                    205:        opc = pc - 2;
                    206:        if (code > 63)
                    207:                opc -= 2;
                    208:        if (code >= nsysent)
                    209:                callp = &sysent[0];             /* indir (illegal) */
                    210:        else {
                    211:                callp = &sysent[code];
                    212:                if (callp == sysent) {          /* indir */
                    213:                        i = fuword(params);
                    214:                        params += NBPW;
                    215:                        if ((unsigned)i >= nsysent)
                    216:                                callp = &sysent[0];
                    217:                        else
                    218:                                callp = &sysent[i];
                    219:                }
                    220:        }
                    221:        if ((i = callp->sy_narg * sizeof (int)) &&
                    222:            (u.u_error = copyin(params, (caddr_t)u.u_arg, (u_int)i)) != 0) {
                    223:                locr0[R0] = u.u_error;
                    224:                locr0[PS] |= PSL_C;     /* carry bit */
                    225:                goto done;
                    226:        }
                    227:        u.u_r.r_val1 = 0;
                    228:        u.u_r.r_val2 = locr0[R1];
                    229:        if (setjmp(&u.u_qsave)) {
                    230:                if (u.u_error == 0 && u.u_eosys != RESTARTSYS)
                    231:                        u.u_error = EINTR;
                    232:        } else {
                    233:                u.u_eosys = NORMALRETURN;
                    234: #ifdef SYSCALLTRACE
                    235:                if (syscalltrace) {
                    236:                        register int i;
                    237:                        char *cp;
                    238: 
                    239:                        if (code >= nsysent)
                    240:                                printf("0x%x", code);
                    241:                        else
                    242:                                printf("%s", syscallnames[code]);
                    243:                        cp = "(";
                    244:                        for (i= 0; i < callp->sy_narg; i++) {
                    245:                                printf("%s%x", cp, u.u_arg[i]);
                    246:                                cp = ", ";
                    247:                        }
                    248:                        if (i)
                    249:                                putchar(')', 0);
                    250:                        putchar('\n', 0);
                    251:                }
                    252: #endif
                    253:                (*(callp->sy_call))();
                    254:        }
                    255:        if (u.u_eosys == NORMALRETURN) {
                    256:                if (u.u_error) {
                    257:                        locr0[R0] = u.u_error;
                    258:                        locr0[PS] |= PSL_C;     /* carry bit */
                    259:                } else {
                    260:                        locr0[R0] = u.u_r.r_val1;
                    261:                        locr0[R1] = u.u_r.r_val2;
                    262:                        locr0[PS] &= ~PSL_C;
                    263:                }
                    264:        } else if (u.u_eosys == RESTARTSYS)
                    265:                pc = opc;
                    266:        /* else if (u.u_eosys == JUSTRETURN) */
                    267:                /* nothing to do */
                    268: done:
                    269:        p = u.u_procp;
                    270:        if (p->p_cursig || ISSIG(p))
                    271:                psig();
                    272:        p->p_pri = p->p_usrpri;
                    273:        if (runrun) {
                    274:                /*
                    275:                 * Since we are u.u_procp, clock will normally just change
                    276:                 * our priority without moving us from one queue to another
                    277:                 * (since the running process is not on a queue.)
                    278:                 * If that happened after we setrq ourselves but before we
                    279:                 * swtch()'ed, we might not be on the queue indicated by
                    280:                 * our priority.
                    281:                 */
                    282:                (void) splclock();
                    283:                setrq(p);
                    284:                u.u_ru.ru_nivcsw++;
                    285:                swtch();
                    286:        }
                    287:        if (u.u_prof.pr_scale) {
                    288:                int ticks;
                    289:                struct timeval *tv = &u.u_ru.ru_stime;
                    290: 
                    291:                ticks = ((tv->tv_sec - syst.tv_sec) * 1000 +
                    292:                        (tv->tv_usec - syst.tv_usec) / 1000) / (tick / 1000);
                    293:                if (ticks)
                    294:                        addupc(locr0[PC], &u.u_prof, ticks);
                    295:        }
                    296:        curpri = p->p_pri;
                    297: }
                    298: 
                    299: /*
                    300:  * nonexistent system call-- signal process (may want to handle it)
                    301:  * flag error if process won't see signal immediately
                    302:  * Q: should we do that all the time ??
                    303:  */
                    304: nosys()
                    305: {
                    306:        if (u.u_signal[SIGSYS] == SIG_IGN || u.u_signal[SIGSYS] == SIG_HOLD)
                    307:                u.u_error = EINVAL;
                    308:        psignal(u.u_procp, SIGSYS);
                    309: }

unix.superglobalmegacorp.com

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