summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/9/pc/apic.c96
-rw-r--r--sys/src/9/pc/dat.h1
2 files changed, 53 insertions, 44 deletions
diff --git a/sys/src/9/pc/apic.c b/sys/src/9/pc/apic.c
index 4e006e8fb..f27adb81e 100644
--- a/sys/src/9/pc/apic.c
+++ b/sys/src/9/pc/apic.c
@@ -89,14 +89,17 @@ static uchar lapictdxtab[] = { /* LapicTDCR */
static ulong* lapicbase;
-struct
+typedef struct Apictimer Apictimer;
+struct Apictimer
{
uvlong hz;
ulong max;
ulong min;
ulong div;
int tdx;
-} lapictimer;
+};
+
+static Apictimer lapictimer[MAXMACH];
static ulong
lapicr(int r)
@@ -115,20 +118,24 @@ lapicw(int r, ulong data)
void
lapiconline(void)
{
+ Apictimer *a;
+
+ a = &lapictimer[m->machno];
+
/*
* Reload the timer to de-synchronise the processors,
* then lower the task priority to allow interrupts to be
* accepted by the APIC.
*/
microdelay((TK2MS(1)*1000/conf.nmach) * m->machno);
- lapicw(LapicTICR, lapictimer.max);
+ lapicw(LapicTICR, a->max);
lapicw(LapicTIMER, LapicCLKIN|LapicPERIODIC|(VectorPIC+IrqTIMER));
/*
* not strickly neccesary, but reported (osdev.org) to be
* required for some machines.
*/
- lapicw(LapicTDCR, lapictdxtab[lapictimer.tdx]);
+ lapicw(LapicTDCR, lapictdxtab[a->tdx]);
lapicw(LapicTPR, 0);
}
@@ -139,35 +146,44 @@ lapiconline(void)
static void
lapictimerinit(void)
{
+ uvlong x, v, hz;
+ Apictimer *a;
+ int s;
+
+ s = splhi();
+ a = &lapictimer[m->machno];
+ a->tdx = 0;
Retry:
lapicw(LapicTIMER, ApicIMASK|LapicCLKIN|LapicONESHOT|(VectorPIC+IrqTIMER));
- lapicw(LapicTDCR, lapictdxtab[lapictimer.tdx]);
-
- if(lapictimer.hz == 0ULL){
- uvlong x, v, hz;
-
- x = fastticks(&hz);
- x += hz/10;
- lapicw(LapicTICR, 0xffffffff);
- do{
- v = fastticks(nil);
- }while(v < x);
-
- v = (0xffffffffUL-lapicr(LapicTCCR))*10;
- if(v > hz-(hz/10)){
- if(v > hz+(hz/10) && lapictimer.tdx < nelem(lapictdxtab)-1){
- lapictimer.tdx++;
- goto Retry;
- }
- v = hz;
+ lapicw(LapicTDCR, lapictdxtab[a->tdx]);
+
+ x = fastticks(&hz);
+ x += hz/10;
+ lapicw(LapicTICR, 0xffffffff);
+ do{
+ v = fastticks(nil);
+ }while(v < x);
+
+ v = (0xffffffffUL-lapicr(LapicTCCR))*10;
+ if(v > hz-(hz/10)){
+ if(v > hz+(hz/10) && a->tdx < nelem(lapictdxtab)-1){
+ a->tdx++;
+ goto Retry;
}
- assert(v != 0);
-
- lapictimer.hz = v;
- lapictimer.div = hz/lapictimer.hz;
- lapictimer.max = lapictimer.hz/HZ;
- lapictimer.min = lapictimer.hz/(100*HZ);
+ v = hz;
}
+
+ assert(v >= (100*HZ));
+
+ a->hz = v;
+ a->div = hz/a->hz;
+ a->max = a->hz/HZ;
+ a->min = a->hz/(100*HZ);
+
+ splx(s);
+
+ v = (v+500000LL)/1000000LL;
+ print("cpu%d: lapic clock at %lludMHz\n", m->machno, v);
}
void
@@ -377,25 +393,19 @@ void
lapictimerset(uvlong next)
{
vlong period;
- int x;
+ Apictimer *a;
- x = splhi();
- lock(&m->apictimerlock);
-
- period = lapictimer.max;
+ a = &lapictimer[m->machno];
+ period = a->max;
if(next != 0){
period = next - fastticks(nil);
- period /= lapictimer.div;
-
- if(period < lapictimer.min)
- period = lapictimer.min;
- else if(period > lapictimer.max - lapictimer.min)
- period = lapictimer.max;
+ period /= a->div;
+ if(period < a->min)
+ period = a->min;
+ else if(period > a->max - a->min)
+ period = a->max;
}
lapicw(LapicTICR, period);
-
- unlock(&m->apictimerlock);
- splx(x);
}
void
diff --git a/sys/src/9/pc/dat.h b/sys/src/9/pc/dat.h
index 862dc344a..8ba2d018e 100644
--- a/sys/src/9/pc/dat.h
+++ b/sys/src/9/pc/dat.h
@@ -242,7 +242,6 @@ struct Mach
int loopconst;
- Lock apictimerlock;
int cpumhz;
uvlong cyclefreq; /* Frequency of user readable cycle counter */
uvlong cpuhz;