Annotation of lucent/sys/src/9/pc/trap.c, revision 1.1.1.1

1.1       root        1: #include       "u.h"
                      2: #include       "../port/lib.h"
                      3: #include       "mem.h"
                      4: #include       "dat.h"
                      5: #include       "fns.h"
                      6: #include       "io.h"
                      7: #include       "ureg.h"
                      8: #include       "../port/error.h"
                      9: 
                     10: void   noted(Ureg*, ulong);
                     11: 
                     12: void   intr0(void), intr1(void), intr2(void), intr3(void);
                     13: void   intr4(void), intr5(void), intr6(void), intr7(void);
                     14: void   intr8(void), intr9(void), intr10(void), intr11(void);
                     15: void   intr12(void), intr13(void), intr14(void), intr15(void);
                     16: void   intr16(void);
                     17: void   intr24(void), intr25(void), intr26(void), intr27(void);
                     18: void   intr28(void), intr29(void), intr30(void), intr31(void);
                     19: void   intr32(void), intr33(void), intr34(void), intr35(void);
                     20: void   intr36(void), intr37(void), intr38(void), intr39(void);
                     21: void   intr64(void);
                     22: void   intrbad(void);
                     23: 
                     24: int    int0mask = 0xff;        /* interrupts enabled for first 8259 */
                     25: int    int1mask = 0xff;        /* interrupts enabled for second 8259 */
                     26: 
                     27: /*
                     28:  *  trap/interrupt gates
                     29:  */
                     30: Segdesc ilt[256];
                     31: int badintr[16];
                     32: 
                     33: enum 
                     34: {
                     35:        Maxhandler=     128,            /* max number of interrupt handlers */
                     36: };
                     37: 
                     38: typedef struct Handler Handler;
                     39: struct Handler
                     40: {
                     41:        void    (*r)(void*, void*);
                     42:        void    *arg;
                     43:        Handler *next;
                     44: };
                     45: 
                     46: struct
                     47: {
                     48:        Lock;
                     49:        Handler *ivec[256];
                     50:        Handler h[Maxhandler];
                     51:        int     free;
                     52: } halloc;
                     53: 
                     54: void
                     55: sethvec(int v, void (*r)(void), int type, int pri)
                     56: {
                     57:        ilt[v].d0 = ((ulong)r)&0xFFFF|(KESEL<<16);
                     58:        ilt[v].d1 = ((ulong)r)&0xFFFF0000|SEGP|SEGPL(pri)|type;
                     59: }
                     60: 
                     61: void
                     62: setvec(int v, void (*r)(Ureg*, void*), void *arg)
                     63: {
                     64:        Handler *h;
                     65: 
                     66:        lock(&halloc);
                     67:        if(halloc.free >= Maxhandler)
                     68:                panic("out of interrupt handlers");
                     69:        h = &halloc.h[halloc.free++];
                     70:        h->next = halloc.ivec[v];
                     71:        h->r = r;
                     72:        h->arg = arg;
                     73:        halloc.ivec[v] = h;
                     74:        unlock(&halloc);
                     75: 
                     76:        /*
                     77:         *  enable corresponding interrupt in 8259
                     78:         */
                     79:        if((v&~0x7) == Int0vec){
                     80:                int0mask &= ~(1<<(v&7));
                     81:                outb(Int0aux, int0mask);
                     82:        } else if((v&~0x7) == Int1vec){
                     83:                int1mask &= ~(1<<(v&7));
                     84:                outb(Int1aux, int1mask);
                     85:        }
                     86: }
                     87: 
                     88: void
                     89: debugbpt(Ureg *ur, void *a)
                     90: {
                     91:        char buf[ERRLEN];
                     92: 
                     93:        USED(a);
                     94: 
                     95:        if(u == 0)
                     96:                panic("kernel bpt");
                     97:        /* restore pc to instruction that caused the trap */
                     98:        ur->pc--;
                     99:        sprint(buf, "sys: breakpoint");
                    100:        postnote(u->p, 1, buf, NDebug);
                    101: }
                    102: 
                    103: /*
                    104:  *  set up the interrupt/trap gates
                    105:  */
                    106: void
                    107: trapinit(void)
                    108: {
                    109:        int i;
                    110: 
                    111:        /*
                    112:         *  set all interrupts to panics
                    113:         */
                    114:        for(i = 0; i < 256; i++)
                    115:                sethvec(i, intrbad, SEGTG, 0);
                    116: 
                    117:        /*
                    118:         *  80386 processor (and coprocessor) traps
                    119:         */
                    120:        sethvec(0, intr0, SEGTG, 0);
                    121:        sethvec(1, intr1, SEGTG, 0);
                    122:        sethvec(2, intr2, SEGTG, 0);
                    123:        sethvec(4, intr4, SEGTG, 0);
                    124:        sethvec(5, intr5, SEGTG, 0);
                    125:        sethvec(6, intr6, SEGTG, 0);
                    126:        sethvec(7, intr7, SEGTG, 0);
                    127:        sethvec(8, intr8, SEGTG, 0);
                    128:        sethvec(9, intr9, SEGTG, 0);
                    129:        sethvec(10, intr10, SEGTG, 0);
                    130:        sethvec(11, intr11, SEGTG, 0);
                    131:        sethvec(12, intr12, SEGTG, 0);
                    132:        sethvec(13, intr13, SEGTG, 0);
                    133:        sethvec(14, intr14, SEGIG, 0);  /* page fault, interrupts off */
                    134:        sethvec(15, intr15, SEGTG, 0);
                    135:        sethvec(16, intr16, SEGIG, 0);  /* math coprocessor, interrupts off */
                    136: 
                    137:        /*
                    138:         *  device interrupts
                    139:         */
                    140:        sethvec(24, intr24, SEGIG, 0);
                    141:        sethvec(25, intr25, SEGIG, 0);
                    142:        sethvec(26, intr26, SEGIG, 0);
                    143:        sethvec(27, intr27, SEGIG, 0);
                    144:        sethvec(28, intr28, SEGIG, 0);
                    145:        sethvec(29, intr29, SEGIG, 0);
                    146:        sethvec(30, intr30, SEGIG, 0);
                    147:        sethvec(31, intr31, SEGIG, 0);
                    148:        sethvec(32, intr32, SEGIG, 0);
                    149:        sethvec(33, intr33, SEGIG, 0);
                    150:        sethvec(34, intr34, SEGIG, 0);
                    151:        sethvec(35, intr35, SEGIG, 0);
                    152:        sethvec(36, intr36, SEGIG, 0);
                    153:        sethvec(37, intr37, SEGIG, 0);
                    154:        sethvec(38, intr38, SEGIG, 0);
                    155:        sethvec(39, intr39, SEGIG, 0);
                    156: 
                    157:        /*
                    158:         *  system calls and break points
                    159:         */
                    160:        sethvec(Syscallvec, intr64, SEGTG, 3);
                    161:        setvec(Syscallvec, (void (*)(Ureg*, void*))syscall, 0);
                    162:        sethvec(Bptvec, intr3, SEGTG, 3);
                    163:        setvec(Bptvec, debugbpt, 0);
                    164: 
                    165:        /*
                    166:         *  tell the hardware where the table is (and how long)
                    167:         */
                    168:        putidt(ilt, sizeof(ilt));
                    169: 
                    170:        /*
                    171:         *  Set up the first 8259 interrupt processor.
                    172:         *  Make 8259 interrupts start at CPU vector Int0vec.
                    173:         *  Set the 8259 as master with edge triggered
                    174:         *  input with fully nested interrupts.
                    175:         */
                    176:        outb(Int0ctl, (1<<4)|(0<<3)|(1<<0));    /* ICW1 - edge triggered, master,
                    177:                                           ICW4 will be sent */
                    178:        outb(Int0aux, Int0vec);         /* ICW2 - interrupt vector offset */
                    179:        outb(Int0aux, 0x04);            /* ICW3 - have slave on level 2 */
                    180:        outb(Int0aux, 0x01);            /* ICW4 - 8086 mode, not buffered */
                    181: 
                    182:        /*
                    183:         *  Set up the second 8259 interrupt processor.
                    184:         *  Make 8259 interrupts start at CPU vector Int0vec.
                    185:         *  Set the 8259 as master with edge triggered
                    186:         *  input with fully nested interrupts.
                    187:         */
                    188:        outb(Int1ctl, (1<<4)|(0<<3)|(1<<0));    /* ICW1 - edge triggered, master,
                    189:                                           ICW4 will be sent */
                    190:        outb(Int1aux, Int1vec);         /* ICW2 - interrupt vector offset */
                    191:        outb(Int1aux, 0x02);            /* ICW3 - I am a slave on level 2 */
                    192:        outb(Int1aux, 0x01);            /* ICW4 - 8086 mode, not buffered */
                    193: 
                    194:        /*
                    195:         *  pass #2 8259 interrupts to #1
                    196:         */
                    197:        int0mask &= ~0x04;
                    198:        outb(Int0aux, int0mask);
                    199: 
                    200:        /*
                    201:         * Set Ocw3 to return the ISR when ctl read.
                    202:         */
                    203:        outb(Int0ctl, Ocw3|0x03);
                    204:        outb(Int1ctl, Ocw3|0x03);
                    205: }
                    206: 
                    207: char *excname[] = {
                    208:        [0]     "divide error",
                    209:        [1]     "debug exception",
                    210:        [2]     " nonmaskable interrupt",
                    211:        [3]     "breakpoint",
                    212:        [4]     "overflow",
                    213:        [5]     "bounds check",
                    214:        [6]     "invalid opcode",
                    215:        [7]     "coprocessor not available",
                    216:        [8]     "double fault",
                    217:        [9]     "9 (reserved)",
                    218:        [10]    "invalid TSS",
                    219:        [11]    "segment not present",
                    220:        [12]    "stack exception",
                    221:        [13]    "general protection violation",
                    222:        [14]    "page fault",
                    223:        [15]    "15 (reserved)",
                    224:        [16]    "coprocessor error",
                    225: };
                    226: 
                    227: 
                    228: /*
                    229:  *  All traps
                    230:  */
                    231: void
                    232: trap(Ureg *ur)
                    233: {
                    234:        int v, user;
                    235:        int c;
                    236:        char buf[ERRLEN];
                    237:        Handler *h;
                    238:        static ulong intrtime;
                    239:        static int snoozing;
                    240:        static int iret_traps;
                    241:        ushort isr;
                    242: 
                    243:        v = ur->trap;
                    244: 
                    245:        user = ((ur->cs)&0xffff)!=KESEL && v!=Syscallvec;
                    246:        if(user)
                    247:                u->dbgreg = ur;
                    248:        else if(ur->pc >= KTZERO && ur->pc < (ulong)end && *(uchar*)ur->pc == 0xCF) {
                    249:                if(iret_traps++ > 10)
                    250:                        panic("iret trap");
                    251:                return;
                    252:        }
                    253:        iret_traps = 0;
                    254: 
                    255:        /*
                    256:         *  tell the 8259 that we're done with the
                    257:         *  highest level interrupt (interrupts are still
                    258:         *  off at this point)
                    259:         */
                    260:        c = v&~0x7;
                    261:        isr = 0;
                    262:        if(c==Int0vec || c==Int1vec){
                    263:                isr = inb(Int0ctl);
                    264:                outb(Int0ctl, EOI);
                    265:                if(c == Int1vec){
                    266:                        isr |= inb(Int1ctl)<<8;
                    267:                        outb(Int1ctl, EOI);
                    268:                }
                    269:        }
                    270: 
                    271:        if(v>=256 || (h = halloc.ivec[v]) == 0){
                    272:                /* an old 386 generates these fairly often, no idea why */
                    273:                if(v == 13)
                    274:                        return;
                    275: 
                    276:                /* a processor or coprocessor error */
                    277:                if(v <= 16){
                    278:                        if(user){
                    279:                                sprint(buf, "sys: trap: %s", excname[v]);
                    280:                                postnote(u->p, 1, buf, NDebug);
                    281:                                return;
                    282:                        } else {
                    283:                                dumpregs(ur);
                    284:                                panic("%s pc=0x%lux", excname[v], ur->pc);
                    285:                        }
                    286:                }
                    287: 
                    288:                if(v >= Int0vec && v < Int0vec+16){
                    289:                        /* an unknown interrupt */
                    290:                        v -= Int0vec;
                    291:                        /*
                    292:                         * Check for a default IRQ7. This can happen when
                    293:                         * the IRQ input goes away before the acknowledge.
                    294:                         * In this case, a 'default IRQ7' is generated, but
                    295:                         * the corresponding bit in the ISR isn't set.
                    296:                         * In fact, just ignore all such interrupts.
                    297:                         */
                    298:                        if((isr & (1<<v)) == 0)
                    299:                                return;
                    300:                        if(badintr[v]++ == 0 || (badintr[v]%100000) == 0){
                    301:                                print("unknown interrupt %d pc=0x%lux: total %d\n", v,
                    302:                                        ur->pc, badintr[v]);
                    303:                                print("isr = 0x%4.4ux\n", isr);
                    304:                        }
                    305:                } else {
                    306:                        /* unimplemented traps */
                    307:                        print("illegal trap %d pc=0x%lux\n", v, ur->pc);
                    308:                }
                    309:                return;
                    310:        }
                    311: 
                    312:        /* there may be multiple handlers on one interrupt level */
                    313:        do {
                    314:                (*h->r)(ur, h->arg);
                    315:                h = h->next;
                    316:        } while(h);
                    317:        splhi();
                    318: 
                    319:        /* power management */
                    320:        if(v == Clockvec){
                    321:                /* allow power sheding on clock ticks */
                    322:                if(arch->snooze)
                    323:                        snoozing = (*arch->snooze)(intrtime, 0);
                    324:        } else {
                    325:                /* turn power back on when anything else happens */
                    326:                if(snoozing && arch->snooze)
                    327:                        snoozing = (*arch->snooze)(intrtime, 1);
                    328:                intrtime = m->ticks;
                    329:        }
                    330: 
                    331:        /* check user since syscall does its own notifying */
                    332:        if(user && (u->p->procctl || u->nnote))
                    333:                notify(ur);
                    334: }
                    335: 
                    336: /*
                    337:  *  dump registers
                    338:  */
                    339: void
                    340: dumpregs2(Ureg *ur)
                    341: {
                    342:        if(u)
                    343:                print("registers for %s %d\n", u->p->text, u->p->pid);
                    344:        else
                    345:                print("registers for kernel\n");
                    346:        print("FLAGS=%lux TRAP=%lux ECODE=%lux CS=%lux PC=%lux", ur->flags, ur->trap,
                    347:                ur->ecode, ur->cs&0xff, ur->pc);
                    348:        if(ur == (Ureg*)UREGADDR)
                    349:                print(" SS=%lux USP=%lux\n", ur->ss&0xff, ur->usp);
                    350:        else
                    351:                print("\n");
                    352:        print("  AX %8.8lux  BX %8.8lux  CX %8.8lux  DX %8.8lux\n",
                    353:                ur->ax, ur->bx, ur->cx, ur->dx);
                    354:        print("  SI %8.8lux  DI %8.8lux  BP %8.8lux\n",
                    355:                ur->si, ur->di, ur->bp);
                    356:        print("  DS %4.4ux  ES %4.4ux  FS %4.4ux  GS %4.4ux\n",
                    357:                ur->ds&0xffff, ur->es&0xffff, ur->fs&0xffff, ur->gs&0xffff);
                    358: 
                    359: }
                    360: 
                    361: void
                    362: dumpregs(Ureg *ur)
                    363: {
                    364:        dumpregs2(ur);
                    365:        print("  ur %lux\n", ur);
                    366: }
                    367: 
                    368: void
                    369: dumpstack(void)
                    370: {
                    371:        ulong l, v, i;
                    372:        extern ulong etext;
                    373: 
                    374:        if(u == 0)
                    375:                return;
                    376: 
                    377:        i = 0;
                    378:        for(l=(ulong)&l; l<USERADDR+BY2PG; l+=4){
                    379:                v = *(ulong*)l;
                    380:                if(KTZERO < v && v < (ulong)&etext){
                    381:                        print("%lux ", v);
                    382:                        i++;
                    383:                }
                    384:                if(i == 4){
                    385:                        i = 0;
                    386:                        print("\n");
                    387:                }
                    388:        }
                    389: 
                    390: }
                    391: 
                    392: long
                    393: execregs(ulong entry, ulong ssize, ulong nargs)
                    394: {
                    395:        ulong *sp;
                    396: 
                    397:        sp = (ulong*)(USTKTOP - ssize);
                    398:        *--sp = nargs;
                    399:        ((Ureg*)UREGADDR)->usp = (ulong)sp;
                    400:        ((Ureg*)UREGADDR)->pc = entry;
                    401:        return USTKTOP-BY2WD;                   /* address of user-level clock */
                    402: }
                    403: 
                    404: ulong
                    405: userpc(void)
                    406: {
                    407:        return ((Ureg*)UREGADDR)->pc;
                    408: }
                    409: 
                    410: /*
                    411:  *  system calls
                    412:  */
                    413: #include "../port/systab.h"
                    414: 
                    415: /*
                    416:  *  syscall is called spllo()
                    417:  */
                    418: long
                    419: syscall(Ureg *ur, void *a)
                    420: {
                    421:        ulong   sp;
                    422:        long    ret;
                    423:        int     i;
                    424: 
                    425:        USED(a);
                    426: 
                    427:        u->p->insyscall = 1;
                    428:        u->p->pc = ur->pc;
                    429:        if((ur->cs)&0xffff == KESEL)
                    430:                panic("recursive system call");
                    431: 
                    432:        u->scallnr = ur->ax;
                    433:        if(u->scallnr == RFORK && u->p->fpstate == FPactive){
                    434:                /*
                    435:                 *  so that the child starts out with the
                    436:                 *  same registers as the parent
                    437:                 */
                    438:                splhi();
                    439:                if(u->p->fpstate == FPactive){
                    440:                        fpsave(&u->fpsave);
                    441:                        u->p->fpstate = FPinactive;
                    442:                }
                    443:                spllo();
                    444:        }
                    445:        sp = ur->usp;
                    446:        u->nerrlab = 0;
                    447:        ret = -1;
                    448:        if(!waserror()){
                    449:                if(u->scallnr >= sizeof systab/BY2WD){
                    450:                        pprint("bad sys call number %d pc %lux\n", u->scallnr, ur->pc);
                    451:                        postnote(u->p, 1, "sys: bad sys call", NDebug);
                    452:                        error(Ebadarg);
                    453:                }
                    454: 
                    455:                if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(1+MAXSYSARG)*BY2WD))
                    456:                        validaddr(sp, (1+MAXSYSARG)*BY2WD, 0);
                    457: 
                    458:                u->s = *((Sargs*)(sp+1*BY2WD));
                    459:                u->p->psstate = sysctab[u->scallnr];
                    460: 
                    461:                ret = (*systab[u->scallnr])(u->s.args);
                    462:                poperror();
                    463:        }
                    464:        if(u->nerrlab){
                    465:                print("bad errstack [%d]: %d extra\n", u->scallnr, u->nerrlab);
                    466:                for(i = 0; i < NERR; i++)
                    467:                        print("sp=%lux pc=%lux\n", u->errlab[i].sp, u->errlab[i].pc);
                    468:                panic("error stack");
                    469:        }
                    470: 
                    471:        u->p->insyscall = 0;
                    472:        u->p->psstate = 0;
                    473: 
                    474:        /*
                    475:         *  Put return value in frame.  On the safari the syscall is
                    476:         *  just another trap and the return value from syscall is
                    477:         *  ignored.  On other machines the return value is put into
                    478:         *  the results register by caller of syscall.
                    479:         */
                    480:        ur->ax = ret;
                    481: 
                    482:        if(u->scallnr == NOTED)
                    483:                noted(ur, *(ulong*)(sp+BY2WD));
                    484: 
                    485:        splhi(); /* avoid interrupts during the iret */
                    486:        if(u->scallnr!=RFORK && (u->p->procctl || u->nnote))
                    487:                notify(ur);
                    488: 
                    489:        return ret;
                    490: }
                    491: 
                    492: /*
                    493:  *  Call user, if necessary, with note.
                    494:  *  Pass user the Ureg struct and the note on his stack.
                    495:  */
                    496: int
                    497: notify(Ureg *ur)
                    498: {
                    499:        int l;
                    500:        ulong s, sp;
                    501:        Note *n;
                    502: 
                    503:        if(u->p->procctl)
                    504:                procctl(u->p);
                    505:        if(u->nnote == 0)
                    506:                return 0;
                    507: 
                    508:        s = spllo();
                    509:        qlock(&u->p->debug);
                    510:        u->p->notepending = 0;
                    511:        n = &u->note[0];
                    512:        if(strncmp(n->msg, "sys:", 4) == 0){
                    513:                l = strlen(n->msg);
                    514:                if(l > ERRLEN-15)       /* " pc=0x12345678\0" */
                    515:                        l = ERRLEN-15;
                    516:                sprint(n->msg+l, " pc=0x%.8lux", ur->pc);
                    517:        }
                    518: 
                    519:        if(n->flag!=NUser && (u->notified || u->notify==0)){
                    520:                if(n->flag == NDebug){
                    521:                        qunlock(&u->p->debug);
                    522:                        pprint("suicide: %s\n", n->msg);
                    523:                }else
                    524:                        qunlock(&u->p->debug);
                    525:                pexit(n->msg, n->flag!=NDebug);
                    526:        }
                    527: 
                    528:        if(u->notified) {
                    529:                qunlock(&u->p->debug);
                    530:                splhi();
                    531:                return 0;
                    532:        }
                    533:                
                    534:        if(!u->notify){
                    535:                qunlock(&u->p->debug);
                    536:                pexit(n->msg, n->flag!=NDebug);
                    537:        }
                    538:        sp = ur->usp;
                    539:        sp -= sizeof(Ureg);
                    540: 
                    541:        if(!okaddr((ulong)u->notify, 1, 0)
                    542:        || !okaddr(sp-ERRLEN-4*BY2WD, sizeof(Ureg)+ERRLEN+4*BY2WD, 1)){
                    543:                qunlock(&u->p->debug);
                    544:                pprint("suicide: bad address in notify\n");
                    545:                pexit("Suicide", 0);
                    546:        }
                    547: 
                    548:        u->ureg = (void*)sp;
                    549:        memmove((Ureg*)sp, ur, sizeof(Ureg));
                    550:        *(Ureg**)(sp-BY2WD) = u->ureg;  /* word under Ureg is old u->ureg */
                    551:        u->ureg = (void*)sp;
                    552:        sp -= BY2WD+ERRLEN;
                    553:        memmove((char*)sp, u->note[0].msg, ERRLEN);
                    554:        sp -= 3*BY2WD;
                    555:        *(ulong*)(sp+2*BY2WD) = sp+3*BY2WD;     /* arg 2 is string */
                    556:        *(ulong*)(sp+1*BY2WD) = (ulong)u->ureg; /* arg 1 is ureg* */
                    557:        *(ulong*)(sp+0*BY2WD) = 0;              /* arg 0 is pc */
                    558:        ur->usp = sp;
                    559:        ur->pc = (ulong)u->notify;
                    560:        u->notified = 1;
                    561:        u->nnote--;
                    562:        memmove(&u->lastnote, &u->note[0], sizeof(Note));
                    563:        memmove(&u->note[0], &u->note[1], u->nnote*sizeof(Note));
                    564: 
                    565:        qunlock(&u->p->debug);
                    566:        splx(s);
                    567:        return 1;
                    568: }
                    569: 
                    570: /*
                    571:  *   Return user to state before notify()
                    572:  */
                    573: void
                    574: noted(Ureg *ur, ulong arg0)
                    575: {
                    576:        Ureg *nur;
                    577:        ulong oureg, sp;
                    578: 
                    579:        qlock(&u->p->debug);
                    580:        if(arg0!=NRSTR && !u->notified) {
                    581:                qunlock(&u->p->debug);
                    582:                pprint("call to noted() when not notified\n");
                    583:                pexit("Suicide", 0);
                    584:        }
                    585:        u->notified = 0;
                    586: 
                    587:        nur = u->ureg;          /* pointer to user returned Ureg struct */
                    588: 
                    589:        /* sanity clause */
                    590:        oureg = (ulong)nur;
                    591:        if(!okaddr((ulong)oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){
                    592:                qunlock(&u->p->debug);
                    593:                pprint("bad u->ureg in noted or call to noted() when not notified\n");
                    594:                pexit("Suicide", 0);
                    595:        }
                    596: 
                    597:        /* don't let user change text or stack segments */
                    598:        nur->cs = ur->cs;
                    599:        nur->ss = ur->ss;
                    600: 
                    601:        /* don't let user change system flags */
                    602:        nur->flags = (ur->flags & ~0xCD5) | (nur->flags & 0xCD5);
                    603: 
                    604:        memmove(ur, nur, sizeof(Ureg));
                    605: 
                    606:        switch(arg0){
                    607:        case NCONT:
                    608:        case NRSTR:
                    609:                if(!okaddr(nur->pc, 1, 0) || !okaddr(nur->usp, BY2WD, 0)){
                    610:                        qunlock(&u->p->debug);
                    611:                        pprint("suicide: trap in noted\n");
                    612:                        pexit("Suicide", 0);
                    613:                }
                    614:                u->ureg = (Ureg*)(*(ulong*)(oureg-BY2WD));
                    615:                qunlock(&u->p->debug);
                    616:                break;
                    617: 
                    618:        case NSAVE:
                    619:                if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->usp, BY2WD, 0)){
                    620:                        qunlock(&u->p->debug);
                    621:                        pprint("suicide: trap in noted\n");
                    622:                        pexit("Suicide", 0);
                    623:                }
                    624:                qunlock(&u->p->debug);
                    625:                sp = oureg-4*BY2WD-ERRLEN;
                    626:                splhi();
                    627:                ur->sp = sp;
                    628:                ((ulong*)sp)[1] = oureg;        /* arg 1 0(FP) is ureg* */
                    629:                ((ulong*)sp)[0] = 0;            /* arg 0 is pc */
                    630:                break;
                    631: 
                    632:        default:
                    633:                u->lastnote.flag = NDebug;
                    634:                qunlock(&u->p->debug);
                    635:                pprint("unknown noted arg 0x%lux\n", arg0);
                    636:                pprint("suicide: %s\n", u->lastnote.msg);
                    637:                pexit(u->lastnote.msg, 0);
                    638:                break;
                    639:                
                    640:        case NDFLT:
                    641:                if(u->lastnote.flag == NDebug){
                    642:                        qunlock(&u->p->debug);
                    643:                        pprint("suicide: %s\n", u->lastnote.msg);
                    644:                }else
                    645:                        qunlock(&u->p->debug);
                    646:                pexit(u->lastnote.msg, u->lastnote.flag!=NDebug);
                    647:        }
                    648: }
                    649: 
                    650: /* This routine must save the values of registers the user is not permitted to write
                    651:  * from devproc and the restore the saved values before returning
                    652:  */
                    653: void
                    654: setregisters(Ureg *xp, char *pureg, char *uva, int n)
                    655: {
                    656:        ulong flags;
                    657:        ulong cs;
                    658:        ulong ss;
                    659: 
                    660:        flags = xp->flags;
                    661:        cs = xp->cs;
                    662:        ss = xp->ss;
                    663:        memmove(pureg, uva, n);
                    664:        xp->flags = (xp->flags & 0xff) | (flags & 0xff00);
                    665:        xp->cs = cs;
                    666:        xp->ss = ss;
                    667: }

unix.superglobalmegacorp.com

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