X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=sys%2Fsrc%2F9%2Fpc%2Ftrap.c;h=97931807faf37b02f75074b5021b976c610c007b;hb=e38f75fc45bba789ceea05d5e62f1d8662bf508b;hp=9bf7550f962b8562e8043ffafe7017836fcc8253;hpb=c6069e28ac0e5a66000f0a887367d7c68410e253;p=plan9front.git diff --git a/sys/src/9/pc/trap.c b/sys/src/9/pc/trap.c index 9bf7550f9..97931807f 100644 --- a/sys/src/9/pc/trap.c +++ b/sys/src/9/pc/trap.c @@ -13,6 +13,7 @@ static int trapinited; void noted(Ureg*, ulong); +static void debugexc(Ureg*, void*); static void debugbpt(Ureg*, void*); static void fault386(Ureg*, void*); static void doublefault(Ureg*, void*); @@ -39,13 +40,20 @@ intrenable(int irq, void (*f)(Ureg*, void*), void* a, int tbdf, char *name) irq, tbdf, name); return; } - if(tbdf != BUSUNKNOWN && (irq == 0xff || irq == 0)){ print("intrenable: got unassigned irq %d, tbdf 0x%uX for %s\n", irq, tbdf, name); irq = -1; } + /* + * IRQ2 doesn't really exist, it's used to gang the interrupt + * controllers together. A device set to IRQ2 will appear on + * the second interrupt controller as IRQ9. + */ + if(irq == 2) + irq = 9; + if((v = xalloc(sizeof(Vctl))) == nil) panic("intrenable: out of memory"); v->isintr = 1; @@ -82,6 +90,8 @@ intrdisable(int irq, void (*f)(Ureg *, void *), void *a, int tbdf, char *name) Vctl **pv, *v; int vno; + if(irq == 2) + irq = 9; if(arch->intrvecno == nil || (tbdf != BUSUNKNOWN && (irq == 0xff || irq == 0))){ /* * on APIC machine, irq is pretty meaningless @@ -175,7 +185,7 @@ nmienable(void) outb(0x70, 0); x = inb(0x61) & 0x07; /* Enable NMI */ - outb(0x61, 0x08|x); + outb(0x61, 0x0C|x); outb(0x61, x); } @@ -222,6 +232,7 @@ trapinit(void) * Special traps. * Syscall() is called directly without going through trap(). */ + trapenable(VectorDE, debugexc, 0, "debugexc"); trapenable(VectorBPT, debugbpt, 0, "debugpt"); trapenable(VectorPF, fault386, 0, "fault386"); trapenable(Vector2F, doublefault, 0, "doublefault"); @@ -400,8 +411,8 @@ trap(Ureg* ureg) if(0)print("cpu%d: spurious interrupt %d, last %d\n", m->machno, vno, m->lastintr); if(0)if(conf.nmach > 1){ - for(i = 0; i < 32; i++){ - if(!(active.machs & (1<machno == mach->machno) @@ -422,7 +433,8 @@ trap(Ureg* ureg) * Don't re-enable, it confuses the crash dumps. nmienable(); */ - iprint("cpu%d: PC %#8.8lux\n", m->machno, ureg->pc); + iprint("cpu%d: nmi PC %#8.8lux, status %ux\n", + m->machno, ureg->pc, inb(0x61)); while(m->machno != 0) ; } @@ -438,6 +450,7 @@ trap(Ureg* ureg) extern void _forkretiret(void); extern void _rdmsrinst(void); extern void _wrmsrinst(void); + extern void _peekinst(void); extern void load_fs(ulong); extern void load_gs(ulong); @@ -466,6 +479,11 @@ trap(Ureg* ureg) ureg->pc += 2; return; } + } else if(pc == _peekinst){ + if(vno == VectorGPF){ + ureg->pc += 2; + return; + } } } @@ -625,6 +643,40 @@ dumpstack(void) callwithureg(_dumpstack); } +static void +debugexc(Ureg *ureg, void *) +{ + u32int dr6, m; + char buf[ERRMAX]; + char *p, *e; + int i; + + dr6 = getdr6(); + if(up == nil) + panic("kernel debug exception dr6=%#.8ux", dr6); + putdr6(up->dr[6]); + if(userureg(ureg)) + qlock(&up->debug); + else if(!canqlock(&up->debug)) + return; + m = up->dr[7]; + m = (m >> 4 | m >> 3) & 8 | (m >> 3 | m >> 2) & 4 | (m >> 2 | m >> 1) & 2 | (m >> 1 | m) & 1; + m &= dr6; + if(m == 0){ + sprint(buf, "sys: debug exception dr6=%#.8ux", dr6); + postnote(up, 0, buf, NDebug); + }else{ + p = buf; + e = buf + sizeof(buf); + p = seprint(p, e, "sys: watchpoint "); + for(i = 0; i < 4; i++) + if((m & 1<> i + 1 != 0) ? "," : ""); + postnote(up, 0, buf, NDebug); + } + qunlock(&up->debug); +} + static void debugbpt(Ureg* ureg, void*) { @@ -666,6 +718,13 @@ fault386(Ureg* ureg, void*) if(!user){ if(vmapsync(addr)) return; + { + extern void _peekinst(void); + if((void(*)(void))ureg->pc == _peekinst){ + ureg->pc += 2; + return; + } + } if(addr >= USTKTOP) panic("kernel fault: bad address pc=0x%.8lux addr=0x%.8lux", ureg->pc, addr); if(up == nil) @@ -676,7 +735,7 @@ fault386(Ureg* ureg, void*) insyscall = up->insyscall; up->insyscall = 1; - n = fault(addr, read); + n = fault(addr, ureg->pc, read); if(n < 0){ if(!user){ dumpregs(ureg); @@ -817,7 +876,7 @@ notify(Ureg* ureg) return 0; if(up->fpstate == FPactive){ - fpsave(&up->fpsave); + fpsave(up->fpsave); up->fpstate = FPinactive; } up->fpstate |= FPillegal;