Annotation of coherent/b/kernel/i386/trap.c, revision 1.1.1.1

1.1       root        1: /* (lgl-
                      2:  *     COHERENT Version 4.0
                      3:  *     Copyright (c) 1982, 1992.
                      4:  *     An unpublished work by Mark Williams Company, Chicago.
                      5:  *     All rights reserved.
                      6:  -lgl) */
                      7: #include <sys/coherent.h>
                      8: #include <sys/reg.h>
                      9: #include <sys/systab.h>
                     10: #include <errno.h>
                     11: #include <sys/proc.h>
                     12: #include <sys/seg.h>
                     13: #include <signal.h>
                     14: 
                     15: /* opcodes recognized, and partially emulated, in gp fault handler */
                     16: #define READ_CR0       1
                     17: #define WRITE_CR0      2
                     18: #define READ_CR2       3
                     19: #define READ_CR3       4
                     20: #define WRITE_CR3      5
                     21: #define HALT           6
                     22: #define IRET           7
                     23: #define READ_DR0       8
                     24: #define READ_DR1       9
                     25: #define READ_DR2       10
                     26: #define READ_DR3       11
                     27: #define READ_DR6       12
                     28: #define READ_DR7       13
                     29: #define WRITE_DR0      14
                     30: #define WRITE_DR1      15
                     31: #define WRITE_DR2      16
                     32: #define WRITE_DR3      17
                     33: #define WRITE_DR6      18
                     34: #define WRITE_DR7      19
                     35: 
                     36: #define ENTER_OP       0xC8    /* Opcode for 'enter' instruction.  */
                     37: #define IRET_RETRY_LIM 10
                     38: #define RESUME_FLAG    0x10000 /* RF bit in PSW */
                     39: #define TRAP_FLAG      0x00100 /* TF bit in PSW */
                     40: 
                     41: extern unsigned char selkcopy();
                     42: extern unsigned int DR0,DR1,DR2,DR3,DR7;
                     43: static int trap_op();
                     44: 
                     45: /*
                     46:  * Macro RDUMP does register dump, followed by final message.
                     47:  *
                     48:  * Callable only from within trap() or one of its cousins.
                     49:  */
                     50: #define RDUMP() { \
                     51:   printf("\neax=%x  ebx=%x  ecx=%x  edx=%x\n", eax, ebx, ecx, edx); \
                     52:   printf("esi=%x  edi=%x  ebp=%x  esp=%x\n", esi, edi, ebp, esp); \
                     53:   printf("cs=%x  ds=%x  es=%x  ss=%x  fs=%x  gs=%x\n", \
                     54:     cs&0xffff, ds&0xffff, es&0xffff, ss&0xffff, fs&0xffff, gs&0xffff); \
                     55:   printf("err #%d eip=%x  uesp=%x  cmd=%s\n", err, eip, uesp, u.u_comm); \
                     56:   printf("efl=%x  ", efl); }
                     57: /* end RDUMP */
                     58: 
                     59: /*
                     60:  * Debug only - display 64 words of stack traceback.
                     61:  */
                     62: #define SDUMP(frame) { \
                     63:   int *ip = frame, i; \
                     64:   for (i=0;i < 32;i++) { \
                     65:     if ((i % 8)==0) \
                     66:       putchar('\n'); \
                     67:     printf("%x ", *ip++); \
                     68:   } \
                     69:   putchar('\n'); \
                     70: }
                     71: /* end SDUMP */
                     72: 
                     73: /*
                     74:  * Global symbols from kernel text.
                     75:  */
                     76: extern unsigned int    _Idle;
                     77: extern unsigned int    __xtrap_break__;
                     78: extern unsigned int    __xtrap_off__;
                     79: extern unsigned int    __xtrap_on__;
                     80: extern unsigned int    sig32;
                     81: extern unsigned int    syc32;
                     82: 
                     83: /*
                     84:  * iret_flt is set when first bad iret is detected.
                     85:  */
                     86: static int iret_flt;
                     87: 
                     88: /*
                     89:  * Trap handler.
                     90:  * The arguments are the registers,
                     91:  * saved on the stack by machine code. This call
                     92:  * is different from most C calls in that the registers
                     93:  * get copied back; if you change a "trap" parameter then
                     94:  * the machine register will be altered when the trap is
                     95:  * dismissed.
                     96:  *
                     97:  * Argument "trapno" is the return eip for the code calling tsave().
                     98:  */
                     99: trap(gs, fs, es, ds, edi, esi, ebp, esp, ebx, edx, ecx, eax, trapno, err,
                    100:   eip, cs, efl, uesp, ss)
                    101: char *eip;
                    102: {
                    103:        register struct systab  *stp;
                    104:        register int    callnum;
                    105:        register int    sigcode;
                    106:        extern int      trapcode;
                    107:        extern  *mmdata[], mminit;
                    108:        cseg_t *pp;
                    109:        register SEG *segp;
                    110:        int     splo, datahi;
                    111:        unsigned int    txtlo, txthi;
                    112:        unsigned char opcode;   /* Opcode we trapped on.        */
                    113:        unsigned short e_arg;   /* Argument to 'enter' opcode.  */
                    114:        unsigned long newsp;    /* Anticipated value for stack pointer.  */
                    115:        unsigned int cr2 = 0;
                    116:        unsigned int cpl = cs & SEG_PL;
                    117: 
                    118:        /*
                    119:         * Avoid sign extension confusion on 286 ds
                    120:         */
                    121:        if (ds == (SEG_286_UD | R_USR))
                    122:                uesp = (unsigned short)uesp;
                    123: 
                    124:        if (err==SINMI) {
                    125:                printf("Parity error\n");
                    126:                RDUMP();
                    127:                panic("...");
                    128:        }
                    129: 
                    130:        /*
                    131:         * Expect this to never happen!
                    132:         */
                    133:        if (SELF->p_flags & PFKERN) {
                    134:                panic("pid%d: kernel process trap: err=%x, ip=%x ax=%d",
                    135:                        SELF->p_pid, err, eip, eax);
                    136:        }
                    137: 
                    138:        T_HAL(0x4000, printf("T%d ", err));
                    139:        sigcode = 0;
                    140: 
                    141:        u.u_regl = &gs; /* hook in register set for consave/conrest */
                    142: 
                    143:        switch (err) {
                    144:        case SIOSYS:
                    145:                /*
                    146:                 * 286 System call.
                    147:                 */
                    148:                sigcode = oldsys();
                    149:                break;
                    150:        case SISYS:
                    151:                /*
                    152:                 * 386 System call.
                    153:                 */
                    154:                u.u_error = 0;
                    155:                callnum = eax;
                    156: 
                    157:                T_PIGGY(4, printf("{%d}", callnum));
                    158: 
                    159:                if (callnum < NMICALL)
                    160:                        stp = sysitab + callnum;
                    161:                else if ( callnum == COHCALL )
                    162:                        stp = &cohcall;
                    163:                else if ( ((callnum&0xFF)==0x28) && ((callnum>>8)<=H28CALL) )
                    164:                        stp = h28itab + ((callnum>>8) - 1);
                    165:                else {
                    166:                        sigcode = SIGSYS;
                    167:                        goto trapend;
                    168:                }
                    169: 
                    170:                ukcopy(uesp+sizeof(long),u.u_args, stp->s_nargs*sizeof(long));
                    171:                if (u.u_error) {
                    172:                        sigcode = SIGSYS;
                    173:                        goto trapend;
                    174:                }
                    175: 
                    176:                u.u_io.io_seg = IOUSR;
                    177:                if (envsave(&u.u_sigenv)) {
                    178:                        u.u_error = EINTR;
                    179:                } else {
                    180:                        eax = (*stp->s_func)(u.u_args[0],
                    181:                              u.u_args[1],
                    182:                              u.u_args[2],
                    183:                              u.u_args[3],
                    184:                              u.u_args[4],
                    185:                              u.u_args[5]);
                    186:                        edx = u.u_rval2;
                    187:                }
                    188: 
                    189:                efl &= ~MFCBIT;         /* clear carry flag in return efl */
                    190:                if (u.u_error) {
                    191:                        eax = u.u_error;
                    192:                        efl |= MFCBIT;
                    193:                }
                    194:                break;
                    195:                /*
                    196:                 * Trap.
                    197:                 */
                    198:        case SIDIV:
                    199:                sigcode = SIGFPE;
                    200:                break;
                    201: 
                    202:        case SISST:
                    203:                sigcode = SIGTRAP;
                    204:                break;
                    205: 
                    206:        case SIBPT:
                    207:                sigcode = SIGTRAP;
                    208:                break;
                    209: 
                    210:        case SIOVF:
                    211:                sigcode = SIGEMT;
                    212:                break;
                    213: 
                    214:        case SIBND:
                    215:                /*
                    216:                 * Bound
                    217:                 */
                    218:                sigcode = SIGIOT;
                    219:                break;
                    220: 
                    221:        case SIOP:
                    222:                /*
                    223:                 * Invalid opcode
                    224:                 */
                    225:                if (cpl < 2) {
                    226:                        int *ip = (int *)eip;
                    227: 
                    228:                        RDUMP();
                    229:                        printf("(eip)=%x %x %x  ", ip[0], ip[1], ip[2]);
                    230:                        panic("Invalid Opcode");
                    231:                }
                    232:                sigcode = SIGILL;
                    233:                break;
                    234: 
                    235: #if 0
                    236:        case SIXNP:
                    237:                /*
                    238:                 * Processor extension not available
                    239:                 */
                    240:                if (int11() & 2)        /* NDP present */
                    241:                        ndpNewOwner();
                    242:                else
                    243:                        sigcode = SIGFPE;
                    244:                break;
                    245: #endif
                    246: 
                    247:        case SIDBL:
                    248:                /*
                    249:                 * Double exception
                    250:                 */
                    251:                panic("double exception: cs=%x ip=%x", cs, eip);
                    252:                sigcode = SIGSEGV;
                    253:                break;
                    254: 
                    255:        case SIXS:
                    256:                /*
                    257:                 * Processor extension segment overrun
                    258:                 */
                    259:                sigcode = SIGSEGV;
                    260:                break;
                    261: 
                    262:        case SITS:
                    263:                /*
                    264:                 * Invalid task state segment
                    265:                 */
                    266:                panic("invalid tss: cs=%x ip=%x", cs, eip);
                    267:                sigcode = SIGSEGV;
                    268:                break;
                    269: 
                    270:        case SINP:
                    271:                /*
                    272:                 * Segment not present
                    273:                 */
                    274:                sigcode = SIGSEGV;
                    275:                break;
                    276: 
                    277:        case SISS:
                    278:                /*
                    279:                 * Stack segment overrun/not present
                    280:                 */
                    281:                sigcode = SIGKILL;
                    282:                break;
                    283:        default:
                    284:                RDUMP();
                    285:                panic("Fatal Trap");
                    286:        }
                    287: 
                    288: trapend:
                    289:        /*
                    290:         * Send user a signal.
                    291:         * If not a breakpoint, do console register dump.
                    292:         */
                    293:        if (sigcode) {
                    294:                if (sigcode != SIGTRAP) {
                    295:                        RDUMP();
                    296:                        printf("sigcode=#%d  User Trap\n", sigcode);
                    297:                }
                    298:                sendsig(sigcode, SELF);
                    299:        }
                    300: }
                    301: 
                    302: /*
                    303:  * trap_op()
                    304:  *
                    305:  * Look at the trapped instruction.
                    306:  * If it's one of a select few, recognize and return the type.
                    307:  * Otherwise, return 0.
                    308:  *
                    309:  * This could be fancier, but all we want to look for is:
                    310:  * (for CRx and DRx, second operand is limited to %eax).
                    311:  *     0F 20 C0        READ_CR0
                    312:  *     0F 22 C0        WRITE_CR0
                    313:  *     0F 20 D0        READ_CR2
                    314:  *     0F 20 D8        READ_CR3
                    315:  *     0F 22 D8        WRITE_CR3
                    316:  *     CF              IRET
                    317:  *     F4              HALT
                    318:  *     0F 23 C0        WRITE_DR0
                    319:  *     0F 23 C8        WRITE_DR1
                    320:  *     0F 23 D0        WRITE_DR2
                    321:  *     0F 23 D8        WRITE_DR3
                    322:  *     0F 23 F0        WRITE_DR6
                    323:  *     0F 23 F8        WRITE_DR7
                    324:  *     0F 21 C0        READ_DR0
                    325:  *     0F 21 C8        READ_DR1
                    326:  *     0F 21 D0        READ_DR2
                    327:  *     0F 21 D8        READ_DR3
                    328:  *     0F 21 F0        READ_DR6
                    329:  *     0F 21 F8        READ_DR7
                    330:  */
                    331: static int
                    332: trap_op(cs,eip)
                    333: unsigned int cs, eip;
                    334: {
                    335:        int             ret = 0;
                    336: 
                    337:        switch (selkcopy(cs,eip)) {
                    338:        case 0x0F:
                    339:                switch (selkcopy(cs,eip+1)) {
                    340:                case 0x20:
                    341:                        switch (selkcopy(cs,eip+2)) {
                    342:                        case 0xC0:
                    343:                                ret = READ_CR0;
                    344:                                break;
                    345:                        case 0xD0:
                    346:                                ret = READ_CR2;
                    347:                                break;
                    348:                        case 0xD8:
                    349:                                ret = READ_CR3;
                    350:                                break;
                    351:                        }
                    352:                        break;
                    353:                case 0x21:
                    354:                        switch (selkcopy(cs,eip+2)) {
                    355:                        case 0xC0:
                    356:                                ret = READ_DR0;
                    357:                                break;
                    358:                        case 0xC8:
                    359:                                ret = READ_DR1;
                    360:                                break;
                    361:                        case 0xD0:
                    362:                                ret = READ_DR2;
                    363:                                break;
                    364:                        case 0xD8:
                    365:                                ret = READ_DR3;
                    366:                                break;
                    367:                        case 0xF0:
                    368:                                ret = READ_DR6;
                    369:                                break;
                    370:                        case 0xF8:
                    371:                                ret = READ_DR7;
                    372:                                break;
                    373:                        }
                    374:                        break;
                    375:                case 0x22:
                    376:                        switch (selkcopy(cs,eip+2)) {
                    377:                        case 0xC0:
                    378:                                ret = WRITE_CR0;
                    379:                                break;
                    380:                        case 0xD8:
                    381:                                ret = WRITE_CR3;
                    382:                                break;
                    383:                        }
                    384:                        break;
                    385:                case 0x23:
                    386:                        switch (selkcopy(cs,eip+2)) {
                    387:                        case 0xC0:
                    388:                                ret = WRITE_DR0;
                    389:                                break;
                    390:                        case 0xC8:
                    391:                                ret = WRITE_DR1;
                    392:                                break;
                    393:                        case 0xD0:
                    394:                                ret = WRITE_DR2;
                    395:                                break;
                    396:                        case 0xD8:
                    397:                                ret = WRITE_DR3;
                    398:                                break;
                    399:                        case 0xF0:
                    400:                                ret = WRITE_DR6;
                    401:                                break;
                    402:                        case 0xF8:
                    403:                                ret = WRITE_DR7;
                    404:                                break;
                    405:                        }
                    406:                        break;
                    407:                }
                    408:                break;
                    409:        case 0xF4:
                    410:                ret = HALT;
                    411:                break;
                    412:        case 0xCF:
                    413:                ret = IRET;
                    414:                break;
                    415:        }
                    416:        return ret;
                    417: }
                    418: 
                    419: /*
                    420:  * Kernel debugger.
                    421:  *
                    422:  * Runs in ring 0.
                    423:  */
                    424: __debug_ker__(gs, fs, es, ds, edi, esi, ebp, esp, ebx, edx, ecx, eax, trapno,
                    425:   err, eip, cs, efl, uesp, ss)
                    426: {
                    427:        unsigned int    dr6 = read_dr6();
                    428:        unsigned        cpl = cs & SEG_PL;
                    429:        int             do_rdump = 1;
                    430: 
                    431:        if (dr6 & 0xf) {        /* report breakpoint exception(s) */
                    432:                printf("Breakpoint  ");
                    433:                if (dr6 & 1)
                    434:                        printf("DR0=%x  ", DR0);
                    435:                if (dr6 & 2)
                    436:                        printf("DR1=%x  ", DR1);
                    437:                if (dr6 & 4)
                    438:                        printf("DR2=%x  ", DR2);
                    439:                if (dr6 & 8)
                    440:                        printf("DR3=%x  ", DR3);
                    441:                printf("DR7=%x\n", DR7);
                    442:        }
                    443:        if (dr6 &  0xf000) {    /* report other debug exception(s) */
                    444:                if (dr6 & 0x8000)
                    445:                        printf("Switch to debugged task\n");
                    446:                if (dr6 & 0x4000) {
                    447:                        /* Single Step */
                    448:                        switch(cpl) {
                    449:                        /*
                    450:                         * If user code trapped, send signal
                    451:                         * and suppress console register dump.
                    452:                         */
                    453:                        case DPL_1:
                    454:                                /*
                    455:                                 * Turn off single-stepping when entering
                    456:                                 * Ring 1.
                    457:                                 */
                    458:                                if (eip == &syc32 || eip == &sig32) {
                    459:                                        do_rdump = 0;
                    460:                                } else {
                    461: printf("/nefl=%x  No single stepping the kernel.\n", efl);
                    462:                                        SDUMP(uesp);
                    463:                                }
                    464:                                efl &= ~TRAP_FLAG;
                    465:                                break;
                    466:                        case DPL_3:
                    467:                                do_rdump = 0;
                    468: T_HAL(0x20000, printf("Kernel SSTEP eip=%x efl=%x  ", eip, efl));
                    469:                                sendsig(SIGTRAP, SELF);
                    470:                                break;
                    471:                        }
                    472:                }
                    473:                if (dr6 & 0x2000) {
                    474:                        printf("ICE in use\n");
                    475:                        eip += 3;
                    476:                }
                    477:        }
                    478:        if (do_rdump) {
                    479:                RDUMP();
                    480:        }
                    481:        write_dr6(0);
                    482:        efl |= RESUME_FLAG;
                    483:        return;
                    484: }
                    485: 
                    486: /*
                    487:  * General protection fault handler.
                    488:  * Entered via a ring 0 gate.
                    489:  */
                    490: gpfault(gs, fs, es, ds, edi, esi, ebp, esp, ebx, edx, ecx, eax, trapno, err,
                    491:   eip, cs, efl, uesp, ss)
                    492: char *eip;
                    493: {
                    494:        unsigned cpl = cs & SEG_PL;
                    495: 
                    496:        /*
                    497:         * Switch on CPL of code that trapped.
                    498:         */
                    499:        switch(cpl) {
                    500:        case DPL_0:
                    501:                /*
                    502:                 * Ring 0 should not gp fault.
                    503:                 */
                    504:                RDUMP();
                    505:                T_HAL(0x1000, SDUMP(&uesp));
                    506:                T_HAL(0x1000, SDUMP(*((&uesp) + 2)));
                    507:                panic("System GP Fault from Ring 0");
                    508:                break;
                    509:        case DPL_1:
                    510:                /*
                    511:                 * If ring 1 faulted on a valid request, emulate the
                    512:                 * request while running in ring 0.
                    513:                 */
                    514:                switch(trap_op(cs,eip)) {
                    515:                case READ_CR0:
                    516:                        eax = read_cr0();
                    517:                        eip += 3;
                    518:                        break;
                    519: #if 0
                    520:                case WRITE_CR0:
                    521:                        if (eax & 4)
                    522:                                setfpe(0);
                    523:                        else
                    524:                                setfpe(1);
                    525:                        eip += 3;
                    526:                        break;
                    527: #endif
                    528:                case READ_CR2:
                    529:                        eax = read_cr2();
                    530:                        eip += 3;
                    531:                        break;
                    532:                case READ_CR3:
                    533:                        eax = read_cr3();
                    534:                        eip += 3;
                    535:                        break;
                    536: #if 0
                    537:                case WRITE_CR3:
                    538:                        mmuupdnR0();
                    539:                        eip += 3;
                    540:                        break;
                    541: #endif
                    542:                case IRET:
                    543:                        /*
                    544:                         * Some CPU's wrongly generate GP faults on IRET
                    545:                         * from inner ring to ring 3.
                    546:                         * Fix is to retry the instruction a few times.
                    547:                         */
                    548:                        if (!iret_flt) {
                    549:                                iret_flt = 1;
                    550:                                printf("CPU Bug:  "
                    551:                                  "Spurious GP Fault on Iret to Ring 3.\n");
                    552:                        }
                    553:                        break;
                    554:                case READ_DR0:
                    555:                        eax = read_dr0();
                    556:                        eip += 3;
                    557:                        break;
                    558:                case READ_DR1:
                    559:                        eax = read_dr1();
                    560:                        eip += 3;
                    561:                        break;
                    562:                case READ_DR2:
                    563:                        eax = read_dr2();
                    564:                        eip += 3;
                    565:                        break;
                    566:                case READ_DR3:
                    567:                        eax = read_dr3();
                    568:                        eip += 3;
                    569:                        break;
                    570:                case READ_DR6:
                    571:                        eax = read_dr6();
                    572:                        eip += 3;
                    573:                        break;
                    574:                case READ_DR7:
                    575:                        eax = read_dr7();
                    576:                        eip += 3;
                    577:                        break;
                    578:                case WRITE_DR0:
                    579:                        write_dr0(eax);
                    580:                        eip += 3;
                    581:                        break;
                    582:                case WRITE_DR1:
                    583:                        write_dr1(eax);
                    584:                        eip += 3;
                    585:                        break;
                    586:                case WRITE_DR2:
                    587:                        write_dr2(eax);
                    588:                        eip += 3;
                    589:                        break;
                    590:                case WRITE_DR3:
                    591:                        write_dr3(eax);
                    592:                        eip += 3;
                    593:                        break;
                    594:                case WRITE_DR6:
                    595:                        write_dr6(eax);
                    596:                        eip += 3;
                    597:                        break;
                    598:                case WRITE_DR7:
                    599:                        write_dr7(eax);
                    600:                        eip += 3;
                    601:                        break;
                    602: #if 0
                    603:                case WRITE_DR7:
                    604:                        /*
                    605:                         * Expect breakpoint info in globals DR0-3,DR7.
                    606:                         */
                    607: printf("Setting DR0=%x  DR1=%x  DR2=%x  DR3=%x  DR7=%x\n",
                    608:   DR0, DR1, DR2, DR3, DR7);
                    609:                        write_dr0(DR0);
                    610:                        write_dr1(DR1);
                    611:                        write_dr2(DR2);
                    612:                        write_dr3(DR3);
                    613:                        write_dr7(DR7);
                    614:                        eip += 3;
                    615:                        break;
                    616: #endif
                    617:                default:
                    618:                        if (eip >= &__xtrap_on__ && eip < &__xtrap_off__) {
                    619:                                SET_U_ERROR(EFAULT, "copy gp");
                    620:                                eip = &__xtrap_break__;
                    621:                        } else {
                    622:                                RDUMP();
                    623:                                T_HAL(0x1000, SDUMP(uesp));
                    624:                                panic("System GP Fault from Ring 1");
                    625:                        }
                    626:                }
                    627:                goto gpdone;
                    628:                break;
                    629:        case DPL_2:
                    630:                /*
                    631:                 * Nothing should be running in Ring 2.
                    632:                 */
                    633:        case DPL_3:
                    634:                /*
                    635:                 * Ring 3 gp fault means errant user process.
                    636:                 */
                    637:                RDUMP();
                    638:                printf("User GP Violation\n");
                    639:                sendsig(SIGSEGV, SELF);
                    640:                break;
                    641:        }
                    642: gpdone:
                    643:        return;
                    644: }
                    645: 
                    646: /*
                    647:  * User debugger.
                    648:  *
                    649:  * Runs in ring 1.
                    650:  */
                    651: __debug_usr__(gs, fs, es, ds, edi, esi, ebp, esp, ebx, edx, ecx, eax, trapno,
                    652:   err, eip, cs, efl, uesp, ss)
                    653: {
                    654:        unsigned int    dr6 = read_dr6();
                    655:        unsigned        cpl = cs & SEG_PL;
                    656:        int             do_rdump = 1;
                    657: 
                    658:        if (dr6 & 0xf) {        /* report breakpoint exception(s) */
                    659:                printf("Breakpoint  ");
                    660:                if (dr6 & 1)
                    661:                        printf("DR0=%x  ", DR0);
                    662:                if (dr6 & 2)
                    663:                        printf("DR1=%x  ", DR1);
                    664:                if (dr6 & 4)
                    665:                        printf("DR2=%x  ", DR2);
                    666:                if (dr6 & 8)
                    667:                        printf("DR3=%x  ", DR3);
                    668:                printf("DR7=%x\n", DR7);
                    669:        }
                    670:        if (dr6 &  0xf000) {    /* report other debug exception(s) */
                    671:                if (dr6 & 0x8000)
                    672:                        printf("Switch to debugged task\n");
                    673:                if (dr6 & 0x4000) {
                    674:                        /* Single Step */
                    675:                        switch(cpl) {
                    676:                        /*
                    677:                         * If user code trapped, send signal
                    678:                         * and suppress console register dump.
                    679:                         */
                    680:                        case DPL_1:
                    681:                                /*
                    682:                                 * Turn off single-stepping when entering
                    683:                                 * Ring 1.
                    684:                                 */
                    685:                                if (eip == &syc32 || eip == &sig32) {
                    686:                                        do_rdump = 0;
                    687:                                } else {
                    688: printf("/nefl=%x  No single stepping the kernel.\n", efl);
                    689:                                        SDUMP(uesp);
                    690:                                }
                    691:                                efl &= ~TRAP_FLAG;
                    692:                                break;
                    693:                        case DPL_3:
                    694:                                do_rdump = 0;
                    695: T_HAL(0x20000, printf("User SSTEP eip=%x efl=%x  ", eip, efl));
                    696:                                sendsig(SIGTRAP, SELF);
                    697:                                break;
                    698:                        }
                    699:                }
                    700:                if (dr6 & 0x2000) {
                    701:                        printf("ICE in use\n");
                    702:                        eip += 3;
                    703:                }
                    704:        }
                    705:        if (do_rdump) {
                    706:                RDUMP();
                    707:        }
                    708:        write_dr6(0);
                    709:        efl |= RESUME_FLAG;
                    710:        return;
                    711: }
                    712: 
                    713: irqblab(gs, fs, es, ds, edi, esi, ebp, esp, ebx, edx, ecx, eax, trapno,
                    714:   err, eip, cs, efl, uesp, ss)
                    715: {
                    716:        puts("*ip=");
                    717:        print32(eip);
                    718:        puts(" *err=");
                    719:        print32(err);
                    720:        if ((err & 0xff) == 0x40) {
                    721:                int irqno = (err >> 8) & 0xFF;
                    722:                print8(irqno);
                    723:        } else if (err == 2) {
                    724:                puts("NMI ");
                    725:        }
                    726: }
                    727: 
                    728: pagefault(gs, fs, es, ds, edi, esi, ebp, esp, ebx, edx, ecx, eax, trapno, err,
                    729:   eip, cs, efl, uesp, ss)
                    730: char *eip;
                    731: {
                    732:        register struct systab  *stp;
                    733:        register int    callnum;
                    734:        register int    sigcode;
                    735:        extern int      trapcode;
                    736:        extern  *mmdata[], mminit;
                    737:        cseg_t *pp;
                    738:        register SEG *segp;
                    739:        int     splo, datahi;
                    740:        unsigned int    txtlo, txthi;
                    741:        unsigned char opcode;   /* Opcode we trapped on.        */
                    742:        unsigned short e_arg;   /* Argument to 'enter' opcode.  */
                    743:        unsigned long newsp;    /* Anticipated value for stack pointer.  */
                    744:        unsigned int cr2 = 0;
                    745:        unsigned int cpl = cs & SEG_PL;
                    746: 
                    747:        /*
                    748:         * Avoid sign extension confusion on 286 ds
                    749:         */
                    750:        if (ds == (SEG_286_UD | R_USR))
                    751:                uesp = (unsigned short)uesp;
                    752: 
                    753:        /*
                    754:         * Expect this to never happen!
                    755:         */
                    756:        if (SELF->p_flags&PFKERN) {
                    757:                panic("pid%d: kernel process trap: err=%x, ip=%x ax=%d",
                    758:                        SELF->p_pid, err, eip, eax);
                    759:        }
                    760: 
                    761:        T_HAL(0x4000, printf("T%d ", err));
                    762:        sigcode = 0;
                    763: 
                    764:        u.u_regl = &gs; /* hook in register set for consave/conrest */
                    765: 
                    766:        {
                    767:                /*
                    768:                 * Page fault
                    769:                 */
                    770:                cr2 = read_cr2();
                    771:                if (cpl < 2) {
                    772:                        /*
                    773:                         * If page fault during Ring 1 copy service routine,
                    774:                         * such as kucopy or ukcopy, set u_error and abort
                    775:                         * the copy, but don't send signal to the user.
                    776:                         */
                    777:                        if (eip >= &__xtrap_on__ && eip < &__xtrap_off__) {
                    778:                                T_HAL(0x1000, printf("copy trapped "));
                    779:                                SET_U_ERROR(EFAULT, "copy service");
                    780:                                eip = &__xtrap_break__;
                    781:                                goto pf_end;
                    782:                        } else {
                    783:                                printf("&uesp=>");
                    784:                                SDUMP(&uesp);
                    785: #if 0
                    786:                                printf("*(&uesp + 2)=>");
                    787:                                SDUMP(*((&uesp) + 2));
                    788: #endif
                    789:                                printf("cr2=%x", cr2);
                    790:                                RDUMP();
                    791:                                panic("Kernel Page Fault");
                    792:                        }
                    793:                }
                    794: 
                    795:                /* Check for stack underflow. */
                    796: 
                    797:                /*
                    798:                 * I think 'splo' is being calculated in a bass-ackwards way,
                    799:                 * and that 'datahi' is just wrong, but I'm not certain,
                    800:                 * so the fixes are #if 0'd out. -piggy
                    801:                 *
                    802:                 * I'll take out the 0 some day and test these changes.
                    803:                 */
                    804:                segp = u.u_segl[SISTACK].sr_segp;
                    805: #if 0
                    806:                splo = u.u_segl[SISTACK].sr_base - segp->s_size;
                    807:                datahi = u.u_segl[SIPDATA].sr_base + u.u_segl[SIPDATA].sr_size;
                    808: #else
                    809:                splo = (XMODE_286) ? ISP_286 : ISP_386;
                    810:                splo -= segp->s_size;
                    811:                datahi = u.u_segl[SIPDATA].sr_size;
                    812: #endif /* 0 */
                    813: 
                    814:                /*
                    815:                 * Catch bad function pointer here - don't want to restart
                    816:                 * the user instruction and get runaway segv's.
                    817:                 *
                    818:                 * For 286 executables, eip starts at 0, but cs points to
                    819:                 * descriptor SEG_286_UII which adds 0x400000 (UII_BASE).
                    820:                 */
                    821:                txtlo = u.u_segl[SISTEXT].sr_base;
                    822:                if (XMODE_286)
                    823:                        txtlo -= UII_BASE;
                    824:                txthi = txtlo + u.u_segl[SISTEXT].sr_size;
                    825:                if (eip < txtlo || eip > txthi) {
                    826:                        T_HAL(0x1000, printf("Bad eip, txtlo=%x txthi=%x\n",
                    827:                          txtlo, txthi));
                    828:                        goto bad_pf;
                    829:                }
                    830: 
                    831:                /*
                    832:                 * If we trapped on an 'enter' instruction, the stack
                    833:                 * pointer (uesp) has not yet been decremented.  In
                    834:                 * order to correctly process such a stack overflow,
                    835:                 * we must look at the _expected_ value for uesp.
                    836:                 * NB: We COPY uesp, because that arg gets loaded back
                    837:                 * into the real esp--when we return from the trap the
                    838:                 * enter instruction will decrement the esp.
                    839:                 */
                    840:                newsp = uesp;
                    841:                opcode = selkcopy(cs, eip);
                    842:                if (ENTER_OP == opcode) {
                    843:                        e_arg = (selkcopy(cs, eip+2)<<8) + selkcopy(cs, eip+1);
                    844:                        newsp -= e_arg;
                    845:                }
                    846: 
                    847:                if (cr2 <= splo
                    848:                  && newsp <= splo
                    849:                  && newsp > datahi
                    850:                  && btoc(datahi) < btocrd(splo)) {
                    851:                        pp = c_extend(segp->s_vmem, btoc(segp->s_size));
                    852:                        if (pp==0) {
                    853:                                T_HAL(0x1000, printf("c_extend(%x,%x)=0 ",
                    854:                                  segp->s_vmem, btoc(segp->s_size)));
                    855:                                goto bad_pf;
                    856:                        }
                    857: 
                    858:                        segp->s_vmem = pp;
                    859:                        segp->s_size += NBPC;
                    860:                        if (sproto(0)==0) {
                    861:                                T_HAL(0x1000, printf("sproto(0)=0 "));
                    862:                                goto bad_pf;
                    863:                        }
                    864: 
                    865:                        segload();
                    866:                        goto pf_end;
                    867:                }
                    868: 
                    869:                /*
                    870:                 * Catch bad data pointer here - don't want to restart
                    871:                 * the user instruction and get runaway segv's.
                    872:                 */
                    873:                {
                    874:                        T_HAL(0x1000, printf("Bad data, splo=%x datahi=%x\n",
                    875:                          splo, datahi));
                    876:                }
                    877: 
                    878:        bad_pf:
                    879:                /*
                    880:                 * User generated unacceptable page fault.
                    881:                 */
                    882:                sigcode = SIGSEGV;
                    883:                printf("\ncr2=%x  ", cr2);
                    884:        }
                    885: 
                    886: pf_end:
                    887:        /*
                    888:         * Send user a signal.
                    889:         * If not a breakpoint, do console register dump.
                    890:         */
                    891:        if (sigcode) {
                    892:                RDUMP();
                    893:                printf("sigcode=#%d  User Page Fault\n", sigcode);
                    894:                sendsig(sigcode, SELF);
                    895:        }
                    896: }

unix.superglobalmegacorp.com

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