M ip/arp.c => ip/arp.c +1 -1
@@ 231,7 231,7 @@ arpwrite(Arp *arp, char *s, int len)
Block *bp;
Arpent *a;
char *f[4], buf[256];
- uchar ip[], mac[MAClen];
+ uchar ip[IPaddrlen], mac[MAClen];
Medium *m;
if(len == 0)
M ip/ipaux.c => ip/ipaux.c +2 -1
@@ 280,7 280,8 @@ parseip(uchar *to, char *from)
x = strtoul(p, &p, 16);
if(*p == '.' || (*p == 0 && i == 0)){
p = v4parseip(to+i, op);
- i += 2;
+ i += 4;
+ break;
} else {
to[i] = x>>8;
to[i+1] = x;
M pc/etherelnk3.c => pc/etherelnk3.c +1 -1
@@ 959,7 959,7 @@ interrupt(Ureg*, void* arg)
if(ctlr->busmaster == 0)
COMMAND(port, TxReset, 0);
else
- COMMAND(port, TxReset, dmaReset);
+ COMMAND(port, TxReset, (updnReset|dmaReset));
COMMAND(port, TxEnable, 0);
}
M pc/i8259.c => pc/i8259.c +4 -2
@@ 121,8 121,10 @@ i8259isr(int v)
int
i8259enable(int v, int, Irqctl* irqctl)
{
- if(v < VectorPIC || v > MaxVectorPIC)
- return 0;
+ if(v < VectorPIC || v > MaxVectorPIC){
+ print("i8259enable: vector %d out of range\n", v);
+ return -1;
+ }
v -= VectorPIC;
/*
M pc/io.h => pc/io.h +3 -0
@@ 3,12 3,15 @@
#define X86FAMILY(x) (((x)>>8) & 0x0F)
enum {
+ VectorNMI = 2, /* non-maskable interrupt */
VectorBPT = 3, /* breakpoint */
VectorCNA = 7, /* coprocessor not available */
VectorCSO = 9, /* coprocessor segment overrun */
VectorPF = 14, /* page fault */
VectorCERR = 16, /* coprocessor error */
+ VectorINTR = 32, /* maskable interrupts */
+
VectorLAPIC = 32, /* local APIC interrupts */
VectorLINT0 = VectorLAPIC+0,/* LINT[01] must be offsets 0 and 1 */
VectorLINT1 = VectorLAPIC+1,
M pc/mp.c => pc/mp.c +67 -39
@@ 12,6 12,8 @@ extern int elcr;
static Bus* mpbus;
static Bus* mpbuslast;
+static int mpisabus = -1;
+static int mpeisabus = -1;
static Apic mpapic[MaxAPICNO+1];
static int machno2apicno[MaxAPICNO+1]; /* inverse map: machno -> APIC ID */
static Lock mprdthilock;
@@ 93,11 95,21 @@ mkbus(PCMPbus* p)
if(bus->type == BusEISA){
bus->po = PcmpLOW;
bus->el = PcmpLEVEL;
+ if(mpeisabus != -1)
+ print("mkbus: more than one EISA bus\n");
+ mpeisabus = bus->busno;
}
else if(bus->type == BusPCI){
bus->po = PcmpLOW;
bus->el = PcmpLEVEL;
}
+ else if(bus->type == BusISA){
+ bus->po = PcmpHIGH;
+ bus->el = PcmpEDGE;
+ if(mpisabus != -1)
+ print("mkbus: more than one ISA bus\n");
+ mpisabus = bus->busno;
+ }
else{
bus->po = PcmpHIGH;
bus->el = PcmpEDGE;
@@ 495,30 507,13 @@ mpintrenablex(int v, int tbdf, Irqctl* irqctl)
Apic *apic;
int bno, dno, lo, n, type;
- if(v >= VectorLAPIC && v <= MaxVectorLAPIC){
- if(v != VectorSPURIOUS)
- irqctl->isr = lapiceoi;
- irqctl->isintr = 1;
- return v;
- }
-
- if(v < VectorPIC || v > MaxVectorPIC)
- return 0;
-
/*
* Find the bus, default is ISA.
* There cannot be multiple ISA or EISA buses.
*/
- if(tbdf == BUSUNKNOWN){
- type = BusISA;
- bno = 0;
- dno = -1;
- }
- else{
- type = BUSTYPE(tbdf);
- bno = BUSBNO(tbdf);
- dno = BUSDNO(tbdf);
- }
+ type = BUSTYPE(tbdf);
+ bno = BUSBNO(tbdf);
+ dno = BUSDNO(tbdf);
n = 0;
for(bus = mpbus; bus; bus = bus->next){
if(bus->type != type)
@@ 528,21 523,8 @@ mpintrenablex(int v, int tbdf, Irqctl* irqctl)
n++;
}
if(bus == 0){
- /*
- * The MP configuration table on some older systems
- * (e.g. ASUS PCI/E-P54NP4) has an entry for the EISA bus
- * but none for ISA. It also has the interrupt type and
- * polarity set to 'default for this bus' which wouldn't
- * be compatible with ISA.
- */
- for(bus = mpbus; bus; bus = bus->next){
- if(bus->type == BusEISA)
- break;
- }
- if(bus == 0){
- print("ioapicirq: can't find bus type %d\n", type);
- return -1;
- }
+ print("ioapicirq: can't find bus type %d\n", type);
+ return -1;
}
/*
@@ 553,6 535,13 @@ mpintrenablex(int v, int tbdf, Irqctl* irqctl)
n = (aintr->intr->irq>>2) & 0x1F;
if(n != dno)
continue;
+ /*
+ * Problem: there can be an entry for
+ * each of the device #INT[ABCD] lines.
+ * For now look only for #INTA.
+ */
+ if(aintr->intr->irq & 0x03)
+ continue;
}
else{
n = aintr->intr->irq;
@@ 587,10 576,49 @@ mpintrenable(int v, int tbdf, Irqctl* irqctl)
{
int r;
- r = mpintrenablex(v, tbdf, irqctl);
- if(r == -1 && tbdf != BUSUNKNOWN /*&& _mp_->specrev == 1*/)
- return mpintrenablex(v, BUSUNKNOWN, irqctl);
- return r;
+ /*
+ * If the bus is known, try it.
+ * BUSUNKNOWN is given both by [E]ISA devices and by
+ * interrupts local to the processor (local APIC, coprocessor
+ * breakpoint and page-fault).
+ */
+ if(tbdf != BUSUNKNOWN && (r = mpintrenablex(v, tbdf, irqctl)) != -1)
+ return r;
+
+ if(v >= VectorLAPIC && v <= MaxVectorLAPIC){
+ if(v != VectorSPURIOUS)
+ irqctl->isr = lapiceoi;
+ irqctl->isintr = 1;
+ return v;
+ }
+ if(v < VectorPIC || v > MaxVectorPIC){
+ print("mpintrenable: vector %d out of range\n", v);
+ return -1;
+ }
+
+ /*
+ * Either didn't find it or we have to try the default
+ * buses (ISA and EISA). This hack is due to either over-zealousness
+ * or laziness on the part of some manufacturers.
+ *
+ * The MP configuration table on some older systems
+ * (e.g. ASUS PCI/E-P54NP4) has an entry for the EISA bus
+ * but none for ISA. It also has the interrupt type and
+ * polarity set to 'default for this bus' which wouldn't
+ * be compatible with ISA.
+ */
+ if(mpisabus != -1){
+ r = mpintrenablex(v, MKBUS(BusISA, 0, 0, 0), irqctl);
+ if(r != -1)
+ return r;
+ }
+ if(mpeisabus != -1){
+ r = mpintrenablex(v, MKBUS(BusEISA, 0, 0, 0), irqctl);
+ if(r != -1)
+ return r;
+ }
+
+ return -1;
}
void
M pc/trap.c => pc/trap.c +7 -7
@@ 24,7 24,7 @@ intrenable(int v, void (*f)(Ureg*, void*), void* a, int tbdf)
lock(&irqctllock);
if(irqctl[v] == 0){
ctl = xalloc(sizeof(Irqctl));
- if(arch->intrenable(v, tbdf, ctl) == -1){
+ if(v >= VectorINTR && arch->intrenable(v, tbdf, ctl) == -1){
unlock(&irqctllock);
/*
print("intrenable: didn't find v %d, tbdf 0x%uX\n", v, tbdf);
@@ 51,12 51,12 @@ nmienable(void)
/*
* Hack: should be locked with NVRAM access.
*/
- outb(0x70, 0x80);
+ outb(0x70, 0x80); /* NMI latch clear */
outb(0x70, 0);
- x = inb(0x61);
+ x = inb(0x61) & 0x07; /* Enable NMI */
outb(0x61, 0x08|x);
- outb(0x61, x & ~0x08);
+ outb(0x61, x);
}
void
@@ 99,7 99,7 @@ trapinit(void)
nmienable();
}
-char *excname[] = {
+static char *excname[] = {
[0] "divide error",
[1] "debug exception",
[2] "nonmaskable interrupt",
@@ 187,10 187,10 @@ trap(Ureg* ureg)
return;
}
else{
- if(v == 2){
+ if(v == VectorNMI){
if(m->machno != 0)
for(;;);
- nmienable();
+ //nmienable();
}
dumpregs(ureg);
if(v < nelem(excname))
M port/sysfile.c => port/sysfile.c +1 -1
@@ 505,7 505,7 @@ sysvseek(ulong *arg)
case 2:
devtab[c->type]->stat(c, buf);
convM2D(buf, &dir);
- off = (long)dir.length2 + o.v; /* BOTCH */
+ off = (long)dir.length1 + o.v; /* BOTCH */
c->offset = off;
break;
}