From 3650a9839a127623ad63d75428fad0140e725ca6 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 16 Jul 1994 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1994-07-16 --- pc/clock.c | 89 +++++++++++++++++++++++++++--------------------------- pc/fns.h | 1 + pc/l.s | 21 ++++++++++++- 3 files changed, 65 insertions(+), 46 deletions(-) diff --git a/pc/clock.c b/pc/clock.c index 488a3c909f9a86dd47d1264e387759a51d32278f..a9a3dc9a98572d00d4aa413428e0ad9553a2868d 100644 --- a/pc/clock.c +++ b/pc/clock.c @@ -27,21 +27,9 @@ enum Freq= 1193182, /* Real clock frequency */ }; -static ulong delayloop = 1000; - -/* - * delay for l milliseconds more or less. delayloop is set by - * clockinit() to match the actual CPU speed. - */ -void -delay(int l) -{ - ulong i; - - while(l-- > 0) - for(i=0; i < delayloop; i++) - ; -} +static int cpufreq = 66; +static int cputype = 486; +static int loopconst = 100; static void clock(Ureg *ur, void *arg) @@ -95,43 +83,28 @@ clock(Ureg *ur, void *arg) splhi(); } + /* - * experimentally determined + * delay for l milliseconds more or less. delayloop is set by + * clockinit() to match the actual CPU speed. */ -enum +void +delay(int l) { - mul386= 380, - mul486= 121, - mul586= 121, -}; + aamloop(l*loopconst); +} void printcpufreq(void) { - ulong freq; - int cpu; - - switch(cpu = x86()){ - default: - case 586: - freq = mul586; - break; - case 486: - freq = mul486; - break; - case 386: - freq = mul386; - break; - } - freq *= delayloop; - freq /= 10000; - print("CPU is a %ud MHz %d\n", freq, cpu); + print("CPU is a %ud Hz %d\n", cpufreq, cputype); } void clockinit(void) { ulong x, y; /* change in counter */ + ulong cycles, loops; /* * set vector for clock interrupts @@ -146,21 +119,47 @@ clockinit(void) outb(T0cntr, (Freq/HZ)>>8); /* high byte */ /* - * measure time for delay(10) with current delayloop count + * measure time for the loop + * + * MOVL loops,CX + * aaml1: AAM + * LOOP aaml1 + * + * the time for the loop should be independent from external + * cache's and memory system since it fits in the execution + * prefetch buffer. + * */ + loops = 10000; outb(Tmode, Latch0); x = inb(T0cntr); x |= inb(T0cntr)<<8; - delay(10); + aamloop(loops); outb(Tmode, Latch0); y = inb(T0cntr); y |= inb(T0cntr)<<8; x -= y; /* - * fix count + * counter goes at twice the frequency, once per transition, + * i.e., twice per the square wave + */ + x >>= 1; + + /* + * figure out clock frequency and a loop multiplier for delay(). */ - delayloop = (delayloop*1193*10)/x; - if(delayloop == 0) - delayloop = 1; + switch(cputype = x86()){ + case 386: + cycles = 30; + break; + case 486: + cycles = 24; + break; + default: + cycles = 23; + break; + } + cpufreq = (cycles*loops) * (Freq/x); + loopconst = (cpufreq/1000)/cycles; /* AAM+LOOP's for 1 ms */ } diff --git a/pc/fns.h b/pc/fns.h index e645cb8a1a62f4cd327c18f8034c9a2c6bdd70be..e2ef8b1dc66b937582b199f2b8c28287c117f079 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -1,5 +1,6 @@ #include "../port/portfns.h" +void aamloop(int); void addconf(char*, char*); #define affinity(x) m void bbinit(void); diff --git a/pc/l.s b/pc/l.s index 4edc6485fa5cc42fc00d1d389e6945e61d67aebf..5e4fdeb0934703529325530352f8afd637763a2a 100644 --- a/pc/l.s +++ b/pc/l.s @@ -579,8 +579,16 @@ TEXT x86(SB),$0 MOVL AX, BX ANDL $0x40000,BX /* on 386 we can't change this bit */ JZ is386 - ANDL $0x200000,AX /* on 486 we can't change this bit */ + ANDL $0x200000,AX /* if we can't change this, there's no CPUID */ JZ is486 + MOVL $1,AX + /* CPUID */ + BYTE $0x0F + BYTE $0xA2 + SHLL $20,AX + SHRL $28,AX + CMPL AX, $4 + JEQ is486 MOVL $586,AX JMP done is486: @@ -593,6 +601,17 @@ done: POPFL RET +/* + * basic timing loop to determine CPU frequency + */ +TEXT aamloop(SB),$0 + + MOVL c+0(FP),CX +aaml1: + AAM + LOOP aaml1 + RET + /* * label consists of a stack pointer and a PC */