From 3f264d26f4ede7c23475afdc3aafd02eee14b94c Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 20 Mar 1998 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1998-03-20 --- ip/arp.c | 2 +- ip/ipaux.c | 3 +- pc/etherelnk3.c | 2 +- pc/i8259.c | 6 ++- pc/io.h | 3 ++ pc/mp.c | 106 ++++++++++++++++++++++++++++++------------------ pc/trap.c | 14 +++---- port/sysfile.c | 2 +- 8 files changed, 86 insertions(+), 52 deletions(-) diff --git a/ip/arp.c b/ip/arp.c index 9cc9a20de76b0879111a5f4176a1c6a517b89c15..131a7f6773ef92186a55a908bdb3387416b38e34 100644 --- a/ip/arp.c +++ b/ip/arp.c @@ -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) diff --git a/ip/ipaux.c b/ip/ipaux.c index 1a5111e521739d314d68bdfba2e82588016f5c65..7dd0f65fc8a4ee6c80a02f62b5fa35b6f5550847 100644 --- a/ip/ipaux.c +++ b/ip/ipaux.c @@ -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; diff --git a/pc/etherelnk3.c b/pc/etherelnk3.c index 9a2f7591e5d32793cf067061569884d2bb90b268..124f909883684a4c5dbeeca802353f8da8a96b8b 100644 --- a/pc/etherelnk3.c +++ b/pc/etherelnk3.c @@ -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); } diff --git a/pc/i8259.c b/pc/i8259.c index f9f6c086d2597b1aeaf5f5d7bfc15e75d290d048..d269dc651d673912c9323890663c4b1a15da341c 100644 --- a/pc/i8259.c +++ b/pc/i8259.c @@ -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; /* diff --git a/pc/io.h b/pc/io.h index a541313483124c4eb47ffd87ade6f9346be97c3e..01feea69aa569267110909c1c7957749bb0535f0 100644 --- a/pc/io.h +++ b/pc/io.h @@ -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, diff --git a/pc/mp.c b/pc/mp.c index a97b966bf2e7301050e3119fcb69925c2cedad01..8b980036e6ff0ecebde33164a974d0c2323c7157 100644 --- a/pc/mp.c +++ b/pc/mp.c @@ -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 diff --git a/pc/trap.c b/pc/trap.c index c54a8597200c5e90363fd6da251797d981a3fec2..07d44abcfa434560134e1cf919cc4627a98b78bf 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -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)) diff --git a/port/sysfile.c b/port/sysfile.c index 943642d3d297511f392acdedd0454ac51ce7c3c4..c2486f1bd8a6691b4ae8b45570562afc140e3d06 100644 --- a/port/sysfile.c +++ b/port/sysfile.c @@ -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; }