void noted(Ureg*, ulong);
+static void debugexc(Ureg*, void*);
static void debugbpt(Ureg*, void*);
static void fault386(Ureg*, void*);
static void doublefault(Ureg*, void*);
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;
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
outb(0x70, 0);
x = inb(0x61) & 0x07; /* Enable NMI */
- outb(0x61, 0x08|x);
+ outb(0x61, 0x0C|x);
outb(0x61, x);
}
* 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");
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<<i)))
+ for(i = 0; i < MAXMACH; i++){
+ if(active.machs[i] == 0)
continue;
mach = MACHP(i);
if(m->machno == mach->machno)
* 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)
;
}
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);
ureg->pc += 2;
return;
}
+ } else if(pc == _peekinst){
+ if(vno == VectorGPF){
+ ureg->pc += 2;
+ return;
+ }
}
}
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) != 0)
+ p = seprint(p, e, "%d%s", i, (m >> i + 1 != 0) ? "," : "");
+ postnote(up, 0, buf, NDebug);
+ }
+ qunlock(&up->debug);
+}
+
static void
debugbpt(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)
insyscall = up->insyscall;
up->insyscall = 1;
- n = fault(addr, read);
+ n = fault(addr, ureg->pc, read);
if(n < 0){
if(!user){
dumpregs(ureg);
return 0;
if(up->fpstate == FPactive){
- fpsave(&up->fpsave);
+ fpsave(up->fpsave);
up->fpstate = FPinactive;
}
up->fpstate |= FPillegal;