From 2ba50734e9d1b0f44c13acefccd6edab287f15f4 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 2 Apr 1999 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1999-04-02 --- carrera/clock.c | 70 +++++-------------------------- carrera/fns.h | 2 +- carrera/mem.h | 2 +- pc/devether.c | 2 +- pc/ether2114x.c | 11 ++--- pc/mp.c | 108 ++++++++++++++++++++++++++---------------------- port/taslock.c | 2 +- 7 files changed, 78 insertions(+), 119 deletions(-) diff --git a/carrera/clock.c b/carrera/clock.c index 0fafe182f3d65a7e0af80c8b3da2769de944869c..1d725554e6e465dcf72da22d1946a572f74ac43a 100644 --- a/carrera/clock.c +++ b/carrera/clock.c @@ -18,7 +18,8 @@ typedef struct Clock0link { static Clock0link *clock0link; static Lock clock0lock; static ulong incr; /* compare register increment */ -static uvlong fasthz; /* ticks/sec of fast clock */ +static ulong lastcmp; + void addclock0link(void (*clock)(void)) @@ -51,8 +52,6 @@ delay(int l) ; } -ulong lastcmp; - void clockinit(void) { @@ -73,23 +72,9 @@ clockinit(void) m->delayloop = 1; incr = (m->speed*1000000)/HZ; - fasthz = m->speed*1000000; wrcompare(lastcmp = rdcount()+incr); } -uvlong -updatefastclock(ulong count) -{ - ulong delta; - - /* keep track of higher precision time */ - delta = count - m->lastcyclecount; - m->lastcyclecount = count; - m->fastclock += delta; - - return m->fastclock; -} - void clock(Ureg *ur) { @@ -97,8 +82,11 @@ clock(Ureg *ur) ulong count; count = rdcount(); - wrcompare(lastcmp = count+incr); - updatefastclock(count); + if(lastcmp+incr < count+100) + lastcmp = count+incr; + else + lastcmp += incr; + wrcompare(lastcmp); m->ticks++; if(m->proc) @@ -146,48 +134,10 @@ clock(Ureg *ur) sched(); } -ulong timewarp; - vlong fastticks(uvlong *hz) { - uvlong cyclecount; - ulong cnt, d; - int x; - - x = splhi(); - cnt = rdcount(); - cyclecount = updatefastclock(cnt); - d = lastcmp - cnt + 100; - if(d > incr+100){ - wrcompare(lastcmp = cnt+incr); - timewarp++; - } - splx(x); - - if(hz) - *hz = fasthz; - - return (vlong)cyclecount; -} - -void -idlehands(void) -{ -#ifdef adsfasdf - ulong cnt, cmp, d; - int x; - - x = splhi(); - cnt = rdcount(); - cmp = rdcompare(); - cnt -= 100; /* to cover for time from splhi to rdcount */ - d = cmp - cnt; - if(d > incr+100){ - wrcompare(lastcmp = cnt+incr); - timewarp++; -// print("%lud %lud %d %lux\n", cnt, cmp, cnt-cmp, d); - } - splx(x); -#endif + if(hz != nil) + *hz = HZ*100; + return m->ticks*100; } diff --git a/carrera/fns.h b/carrera/fns.h index af43073d57a399c2d485449926fc3e364e80558b..d42ea4ff89d183557bdc5dc2c200fbb453d6e251 100644 --- a/carrera/fns.h +++ b/carrera/fns.h @@ -25,7 +25,7 @@ void gettlb(int, ulong*); int gettlbp(ulong, ulong*); ulong gettlbvirt(int); void icflush(void *, ulong); -void idlehands(void); +#define idlehands() void intr(Ureg*); void ioinit(int); int iprint(char*, ...); diff --git a/carrera/mem.h b/carrera/mem.h index 70a972c7537395328b0b17f0b8f5cc7467f20726..c7a5e71d7c14bbaf720cdd4def865515abba2344 100644 --- a/carrera/mem.h +++ b/carrera/mem.h @@ -22,7 +22,7 @@ /* * Time */ -#define HZ 500 /* clock frequency */ +#define HZ 1000 /* clock frequency */ #define MS2HZ (1000/HZ) /* millisec per clock tick */ #define TK2SEC(t) ((t)/HZ) /* ticks to seconds */ #define TK2MS(t) ((t)*MS2HZ) /* ticks to milliseconds */ diff --git a/pc/devether.c b/pc/devether.c index 2d679c9246afdadc1d1c1e0e00437e7e2c1666b3..e26b3a933b4c3681d9fe3e9443effcd6ced7c1b8 100644 --- a/pc/devether.c +++ b/pc/devether.c @@ -213,7 +213,7 @@ etheroq(Ether* ether, Block* bp) * If it's a loopback packet indicate to etheriq that the data isn't * needed and return, etheriq will pass-on or free the block. * To enable bridging to work, only packets that were originated - * by this interface are feedback + * by this interface are fed back. */ pkt = (Etherpkt*)bp->rp; len = BLEN(bp); diff --git a/pc/ether2114x.c b/pc/ether2114x.c index c32c146f09d6f36e10dc45f1e34c688298b4614a..8eff8b71dfa1efa6a568b8c80550cba255cd58d2 100644 --- a/pc/ether2114x.c +++ b/pc/ether2114x.c @@ -827,7 +827,8 @@ typephylink(Ctlr* ctlr, uchar*) csr6 |= Fd; if(ctlr->ttm & x) csr6 |= Ttm; - debug("csr6 0x%2.2uX 0x%2.2uX\n", csr6, ctlr->csr6); + debug("csr6 0x%8.8uX 0x%8.8uX 0x%8.8luX\n", + csr6, ctlr->csr6, csr32r(ctlr, 6)); if(csr6 != ctlr->csr6){ ctlr->csr6 = csr6; csr32w(ctlr, 6, csr6); @@ -1226,16 +1227,16 @@ srom(Ctlr* ctlr) p += (*p & ~0x80)+1; } else{ -debug("type0: 0x%2.2uX 0x%2.2uX 0x%2.2uX 0x%2.2uX\n", - p[0], p[1], p[2], p[3]); + debug("type0: 0x%2.2uX 0x%2.2uX 0x%2.2uX 0x%2.2uX\n", + p[0], p[1], p[2], p[3]); if(ctlr->sct != 0x0800 && *p == (ctlr->sct & 0xFF)) ctlr->sctk = k; p += 4; } } ctlr->curk = ctlr->sctk; -debug("sct 0x%uX medium 0x%uX k %d curk %d phy %d\n", - ctlr->sct, ctlr->medium, ctlr->k, ctlr->curk, phy); + debug("sct 0x%uX medium 0x%uX k %d curk %d phy %d\n", + ctlr->sct, ctlr->medium, ctlr->k, ctlr->curk, phy); if(phy){ x = 0; diff --git a/pc/mp.c b/pc/mp.c index e9cf5f8d23b09ebf35da7b792bd02c457fb7560c..218c7f2a9c2a980a7e0c76dec3c4251e578dcf53 100644 --- a/pc/mp.c +++ b/pc/mp.c @@ -19,6 +19,7 @@ static int machno2apicno[MaxAPICNO+1]; /* inverse map: machno -> APIC ID */ static Lock mprdthilock; static int mprdthi; static Ref mpvnoref; /* unique vector assignment */ +static Lock mpclocksynclock; static char* buses[] = { "CBUSI ", @@ -214,13 +215,14 @@ mpintrinit(Bus* bus, PCMPintr* intr, int vno, int /*irq*/) case PcmpExtINT: v |= ApicExtINT; /* - * The AMI Goliath doesn't boot successfully with it's LINTR0 entry - * which decodes to low+level. The PPro manual says ExtINT should be - * level, whereas the Pentium is edge. Setting the Goliath to edge+high - * seems to cure the problem. Other PPro MP tables (e.g. ASUS P/I-P65UP5 - * have a entry which decodes to edge+high, so who knows. - * Perhaps it would be best just to not set an ExtINT entry at all, - * it shouldn't be needed for SMP mode. + * The AMI Goliath doesn't boot successfully with it's LINTR0 + * entry which decodes to low+level. The PPro manual says ExtINT + * should be level, whereas the Pentium is edge. Setting the + * Goliath to edge+high seems to cure the problem. Other PPro + * MP tables (e.g. ASUS P/I-P65UP5 have a entry which decodes + * to edge+high, so who knows. + * Perhaps it would be best just to not set an ExtINT entry at + * all, it shouldn't be needed for SMP mode. */ po = PcmpHIGH; el = PcmpEDGE; @@ -229,7 +231,7 @@ mpintrinit(Bus* bus, PCMPintr* intr, int vno, int /*irq*/) /* */ - if(bus->type == BusEISA && !po && !el /*&& !(elcr & (1<type == BusEISA && !po && !el /*&& !(i8259elcr & (1<apicno == 0xFF){ for(apic = mpapic; apic <= &mpapic[MaxAPICNO]; apic++){ - if((apic->flags & PcmpEN) && apic->type == PcmpPROCESSOR) + if((apic->flags & PcmpEN) + && apic->type == PcmpPROCESSOR) apic->lintr[intin] = v; } } @@ -348,8 +351,6 @@ checkmtrr(void) #define PDX(va) ((((ulong)(va))>>22) & 0x03FF) #define PTX(va) ((((ulong)(va))>>12) & 0x03FF) -Lock clocksynclock; - static void squidboy(Apic* apic) { @@ -371,12 +372,12 @@ squidboy(Apic* apic) /* * Restrain your octopus! Don't let it go out on the sea! */ - ilock(&clocksynclock); + ilock(&mpclocksynclock); x = MACHP(0)->ticks; while(MACHP(0)->ticks == x) ; wrmsr(0x10, MACHP(0)->fastclock); /* synchronize fast counters */ - iunlock(&clocksynclock); + iunlock(&mpclocksynclock); lapicinit(apic); lapiconline(); @@ -480,16 +481,17 @@ mpinit(void) bpapic = 0; /* - * Run through the table saving information needed for starting application - * processors and initialising any I/O APICs. The table is guaranteed to be in - * order such that only one pass is necessary. + * Run through the table saving information needed for starting + * application processors and initialising any I/O APICs. The table + * is guaranteed to be in order such that only one pass is necessary. */ p = ((uchar*)pcmp)+sizeof(PCMP); e = ((uchar*)pcmp)+pcmp->length; while(p < e) switch(*p){ default: - print("mpinit: unknown PCMP type 0x%uX (e-p 0x%luX)\n", *p, e-p); + print("mpinit: unknown PCMP type 0x%uX (e-p 0x%luX)\n", + *p, e-p); while(p < e){ print("%uX ", *p); p++; @@ -562,7 +564,8 @@ mpinit(void) */ memmove((void*)APBOOTSTRAP, apbootstrap, sizeof(apbootstrap)); for(apic = mpapic; apic <= &mpapic[MaxAPICNO]; apic++){ - if((apic->flags & (PcmpBP|PcmpEN)) == PcmpEN && apic->type == PcmpPROCESSOR) + if((apic->flags & (PcmpBP|PcmpEN)) == PcmpEN + && apic->type == PcmpPROCESSOR) mpstartap(apic); } @@ -575,7 +578,7 @@ mpinit(void) } static int -mpintrenablex(Vctl* v) +mpintrenablex(Vctl* v, int tbdf) { Bus *bus; Aintr *aintr; @@ -584,12 +587,11 @@ mpintrenablex(Vctl* v) int bno, dno, irq, lo, n, type, vno; /* - * Find the bus, default is ISA. - * There cannot be multiple ISA or EISA buses. + * Find the bus. */ - type = BUSTYPE(v->tbdf); - bno = BUSBNO(v->tbdf); - dno = BUSDNO(v->tbdf); + type = BUSTYPE(tbdf); + bno = BUSBNO(tbdf); + dno = BUSDNO(tbdf); n = 0; for(bus = mpbus; bus != nil; bus = bus->next){ if(bus->type != type) @@ -610,12 +612,12 @@ mpintrenablex(Vctl* v) * obtained from the PCI config space. */ if(bus->type == BusPCI){ - pcidev = pcimatchtbdf(v->tbdf); + pcidev = pcimatchtbdf(tbdf); if(pcidev != nil && (n = pcicfgr8(pcidev, PciINTP)) != 0) irq = (dno<<2)|(n-1); else irq = -1; - //print("pcidev %uX: irq %uX v->irq %uX\n", v->tbdf, irq, v->irq); + //print("pcidev %uX: irq %uX v->irq %uX\n", tbdf, irq, v->irq); } else irq = v->irq; @@ -629,37 +631,42 @@ mpintrenablex(Vctl* v) continue; /* - * Check not already enabled. This is a bad thing as it implies the - * same device is requesting the same interrupt to be enabled multiple - * times. The RDT read here is safe for now as currently interrupts - * are never disabled once enabled. + * Check not already enabled. This is a bad thing as it implies + * the same device is requesting the same interrupt to be + * enabled multiple times. The RDT read here is safe for now + * as currently interrupts are never disabled once enabled. */ apic = aintr->apic; ioapicrdtr(apic, aintr->intr->intin, 0, &lo); if(!(lo & ApicIMASK)){ - print("mpintrenable: multiple enable of irq %d, tbdf %uX\n", - v->irq, v->tbdf); + print("mpintrenable: multiple enable irq%d, tbdf %uX\n", + v->irq, tbdf); return -1; } /* - * With the APIC a unique vector can be assigned to each request - * to enable an interrupt. There are two reasons this is a good idea: - * 1) to prevent lost interrupts, no more than 2 interrupts should - * be assigned per block of 16 vectors (there is an in-service - * entry and a holding entry for each priority level and there is - * a priority level per block of 16 interrupts). - * 2) each input pin on the IOAPIC will receive a different vector - * regardless of whether the devices on that pin use the same IRQ - * as devices on another pin. + * With the APIC a unique vector can be assigned to each + * request to enable an interrupt. There are two reasons this + * is a good idea: + * 1) to prevent lost interrupts, no more than 2 interrupts + * should be assigned per block of 16 vectors (there is an + * in-service entry and a holding entry for each priority + * level and there is one priority level per block of 16 + * interrupts). + * 2) each input pin on the IOAPIC will receive a different + * vector regardless of whether the devices on that pin use + * the same IRQ as devices on another pin. */ vno = VectorAPIC + (incref(&mpvnoref)-1)*8; if(vno > MaxVectorAPIC){ print("mpintrenable: vno %d, irq %d, tbdf %uX\n", - vno, v->irq, v->tbdf); + vno, v->irq, tbdf); return -1; } lo = mpintrinit(bus, aintr->intr, vno, v->irq); + //print("lo 0x%uX: busno %d intr %d vno %d irq %d elcr 0x%uX\n", + // lo, bus->busno, aintr->intr->irq, vno, + // v->irq, i8259elcr); if(lo & ApicIMASK) return -1; lo |= ApicLOGICAL; @@ -669,6 +676,9 @@ mpintrenablex(Vctl* v) ioapicrdtw(apic, aintr->intr->intin, mprdthi, lo); unlock(&mprdthilock); } + //else + // print("lo not enabled 0x%uX %d\n", + // apic->flags, apic->type); v->isr = lapicisr; v->eoi = lapiceoi; @@ -691,7 +701,7 @@ mpintrenable(Vctl* v) * breakpoint and page-fault). */ tbdf = v->tbdf; - if(tbdf != BUSUNKNOWN && (vno = mpintrenablex(v)) != -1) + if(tbdf != BUSUNKNOWN && (vno = mpintrenablex(v, tbdf)) != -1) return vno; irq = v->irq; @@ -716,15 +726,13 @@ mpintrenable(Vctl* v) * polarity set to 'default for this bus' which wouldn't * be compatible with ISA. */ - if(mpisabus != -1){ - v->tbdf = MKBUS(BusISA, 0, 0, 0); - vno = mpintrenablex(v); + if(mpeisabus != -1){ + vno = mpintrenablex(v, MKBUS(BusEISA, 0, 0, 0)); if(vno != -1) return vno; } - if(mpeisabus != -1){ - v->tbdf = MKBUS(BusEISA, 0, 0, 0); - vno = mpintrenablex(v); + if(mpisabus != -1){ + vno = mpintrenablex(v, MKBUS(BusISA, 0, 0, 0)); if(vno != -1) return vno; } @@ -767,7 +775,7 @@ mpshutdown(void) * warm-boot sequence is tried. The following is Intel specific and * seems to perform a cold-boot, but at least it comes back. */ - *(ushort*)KADDR(0x472) = 0x1234; /* BIOS warm-boot flag */ + *(ushort*)KADDR(0x472) = 0x1234; /* BIOS warm-boot flag */ outb(0xCF9, 0x02); outb(0xCF9, 0x06); #else diff --git a/port/taslock.c b/port/taslock.c index 837b19cde2309b55251314a9e9f1c3a4379f49d3..5286970a0a59e96ed36360c7417b22b5c4bd3763 100644 --- a/port/taslock.c +++ b/port/taslock.c @@ -110,7 +110,7 @@ lockstats.glare++; } else oldpri = 0; if(conf.nmach < 2) - panic("ilock: no way out: pc %uX held by %uX\n", pc, l->pc); + panic("ilock: no way out: pc %uX\n", pc); for(;;){ lockstats.inglare++;