Annotation of lucent/sys/src/9/pc/trap.c, revision 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.