summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2013-06-22 00:47:24 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2013-06-22 00:47:24 +0200
commit3487653524efc9c79e7173407446f6b83f8de81b (patch)
tree5921900d6ca7e94e31e1572ed63c09a1a7e41b15
parenta59b0bd6a8542337a88a16f7fb675d3cd4cbb942 (diff)
downloadplan9front-3487653524efc9c79e7173407446f6b83f8de81b.tar.xz
apic: fix lapic timer divider (fixes wrong lapic frequency on boot)
loading the divider before programming one shot mode *sometimes* gives the wrong frequency. (X200s got 192Mhz vs. 266Mhz, after 5 boot attempts) also reload the divider after programming periodic mode. (from http://wiki.osdev.org/APIC_timer)
-rw-r--r--sys/src/9/pc/apic.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/sys/src/9/pc/apic.c b/sys/src/9/pc/apic.c
index eada39531..4e006e8fb 100644
--- a/sys/src/9/pc/apic.c
+++ b/sys/src/9/pc/apic.c
@@ -124,6 +124,12 @@ lapiconline(void)
lapicw(LapicTICR, lapictimer.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(LapicTPR, 0);
}
@@ -134,8 +140,8 @@ static void
lapictimerinit(void)
{
Retry:
- lapicw(LapicTDCR, lapictdxtab[lapictimer.tdx]);
lapicw(LapicTIMER, ApicIMASK|LapicCLKIN|LapicONESHOT|(VectorPIC+IrqTIMER));
+ lapicw(LapicTDCR, lapictdxtab[lapictimer.tdx]);
if(lapictimer.hz == 0ULL){
uvlong x, v, hz;