M carrera/clock.c => carrera/clock.c +10 -60
@@ 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;
}
M carrera/fns.h => carrera/fns.h +1 -1
@@ 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*, ...);
M carrera/mem.h => carrera/mem.h +1 -1
@@ 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 */
M pc/devether.c => pc/devether.c +1 -1
@@ 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);
M pc/ether2114x.c => pc/ether2114x.c +6 -5
@@ 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;
M pc/mp.c => pc/mp.c +58 -50
@@ 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<<irq))*/){
+ if(bus->type == BusEISA && !po && !el /*&& !(i8259elcr & (1<<irq))*/){
po = PcmpHIGH;
el = PcmpEDGE;
}
@@ 280,7 282,8 @@ mklintr(PCMPintr* p)
if(p->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
M port/taslock.c => port/taslock.c +1 -1
@@ 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++;