From b1ec3ceb0d8ef6460723416c08f4eba8ecd0704f Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Mon, 31 Oct 1994 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1994-10-31 --- pc/clock.c | 158 +++++++++++++++++++++++++++++++++++------------------ pc/fns.h | 1 + pc/l.s | 19 +++---- pc/main.c | 3 +- 4 files changed, 115 insertions(+), 66 deletions(-) diff --git a/pc/clock.c b/pc/clock.c index 68877c361b5f6f7f6fd4557e31dc307edd588503..b90df8e2784a64e7f8c0718da22b0b8eed58f26f 100644 --- a/pc/clock.c +++ b/pc/clock.c @@ -29,9 +29,8 @@ enum static int cpufreq = 66000000; static int cpumhz = 66; -static int cputype = 486; static int loopconst = 100; -ulong cpuidax, cpuiddx; +static int cpuidax, cpuiddx; static void clock(Ureg *ur, void *arg) @@ -72,6 +71,49 @@ clock(Ureg *ur, void *arg) mouseclock(); } +#define STEPPING(x) ((x)&0xf) +#define MODEL(x) (((x)>>4)&0xf) +#define FAMILY(x) (((x)>>8)&0xf) + +enum +{ + /* flags */ + CpuidFPU = 0x001, /* on-chip floating point unit */ + CpuidMCE = 0x080, /* machine check exception */ + CpuidCX8 = 0x100, /* CMPXCHG8B instruction */ +}; + +typedef struct +{ + int family; + int model; + int aalcycles; + char *name; +} X86type; + +X86type x86type[] = +{ + /* from the cpuid instruction */ + { 4, 0, 22, "Intel486DX", }, + { 4, 1, 22, "Intel486DX", }, + { 4, 2, 22, "Intel486SX", }, + { 4, 4, 22, "Intel486DX2", }, + { 4, 5, 22, "Intel486SL", }, + { 4, 8, 22, "IntelDX4", }, + { 5, 1, 23, "Pentium510", }, + { 5, 2, 23, "Pentium735", }, + + /* family defaults */ + { 3, -1, 32, "Intel386", }, + { 4, -1, 22, "Intel486", }, + { 5, -1, 23, "Pentium", }, + + /* total default */ + { -1, -1, 23, "unknown", }, +}; + +static X86type *cputype; + /* * delay for l milliseconds more or less. delayloop is set by * clockinit() to match the actual CPU speed. @@ -89,32 +131,37 @@ printcpufreq(void) cpufreq, cputype, cpuidax, cpuiddx); } +int +x86(void) +{ + return cputype->family; +} + void clockinit(void) { - ulong x, y; /* change in counter */ - ulong cycles, loops; - - switch(cputype = x86()){ - case 386: - loops = 10000; - cycles = 32; - break; - case 486: - loops = 10000; - cycles = 22; - break; - default: - loops = 30000; - cycles = 23; - break; - } + int x, y; /* change in counter */ + int family, model, loops; + X86type *t; /* * set vector for clock interrupts */ setvec(Clockvec, clock, 0); + /* + * figure out what we are + */ + x86cpuid(&cpuidax, &cpuiddx); + family = FAMILY(cpuidax); + model = MODEL(cpuidax); + for(t = x86type; t->name; t++) + if((t->family == family && t->model == model) + || (t->family == family && t->model == -1) + || (t->family == -1)) + break; + cputype = t; + /* * set clock for 1/HZ seconds */ @@ -122,39 +169,46 @@ clockinit(void) outb(T0cntr, (Freq/HZ)); /* low byte */ outb(T0cntr, (Freq/HZ)>>8); /* high byte */ - - /* - * 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. - * - */ - outb(Tmode, Latch0); - x = inb(T0cntr); - x |= inb(T0cntr)<<8; - aamloop(loops); - outb(Tmode, Latch0); - y = inb(T0cntr); - y |= inb(T0cntr)<<8; - x -= y; - - /* - * counter goes at twice the frequency, once per transition, - * i.e., twice per square wave - */ - x >>= 1; - - /* - * figure out clock frequency and a loop multiplier for delay(). - */ - cpufreq = loops*((cycles*Freq)/x); - loopconst = (cpufreq/1000)/cycles; /* AAM+LOOP's for 1 ms */ + /* use biggest loop that works */ + for(loops = 10000; ; loops += 5000) { + /* + * measure time for the loop + * + * MOVL loops,CX + * aaml1: AAM + * LOOP aaml1 + * + * the time for the loop should be independent of external + * cache and memory system since it fits in the execution + * prefetch buffer. + * + */ + outb(Tmode, Latch0); + x = inb(T0cntr); + x |= inb(T0cntr)<<8; + aamloop(loops); + outb(Tmode, Latch0); + y = inb(T0cntr); + y |= inb(T0cntr)<<8; + x -= y; + + if(x < 0) + x += 2^16; + if(x > (2^15)) + break; + + /* + * counter goes at twice the frequency, once per transition, + * i.e., twice per square wave + */ + x >>= 1; + + /* + * figure out clock frequency and a loop multiplier for delay(). + */ + cpufreq = loops*((t->aalcycles*Freq)/x); + loopconst = (cpufreq/1000)/t->aalcycles; /* AAM+LOOP's for 1 ms */ + } while(x > 0); /* * add in possible .1% error and convert to MHz diff --git a/pc/fns.h b/pc/fns.h index 883170e9df76efb398ba6c13a7797f0152868def..f671b703f0cf1e39100a45664eea4d26a7e56fa8 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -91,6 +91,7 @@ void vgainit(void); void vgasavecrash(uchar*, int); void vgarestorecrash(uchar*, int); int x86(void); +int x86cpuid(int*, int*); #define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1])) #define kmapperm(x) kmap(x) diff --git a/pc/l.s b/pc/l.s index c92e0b8ccfa7c3b994878cf9c3d41686345e4dd7..8fd75f7b7f690176dd1aabe141430bb44fd0d912 100644 --- a/pc/l.s +++ b/pc/l.s @@ -572,7 +572,7 @@ TEXT getstatus(SB),$0 /* * return cpu type (586 == pentium or better) */ -TEXT x86(SB),$0 +TEXT x86cpuid(SB),$0 PUSHFL MOVL 0(SP),AX @@ -591,22 +591,17 @@ TEXT x86(SB),$0 /* CPUID */ BYTE $0x0F BYTE $0xA2 - - MOVL AX, cpuidax(SB) - MOVL DX, cpuiddx(SB) - - SHLL $20,AX - SHRL $28,AX - CMPL AX, $4 - JEQ is486 - MOVL $586,AX JMP done is486: - MOVL $486,AX + MOVL $(4<<8),AX + MOVL $0,DX JMP done is386: - MOVL $386,AX + MOVL $(3<<8),AX + MOVL $0,DX done: + MOVL AX, a+0(FP) + MOVL DX, d+4(FP) POPL BX POPFL RET diff --git a/pc/main.c b/pc/main.c index 60d2038a75fe7be1cbbb1191e8d1a07caedcd42c..8c0b30ec938125651e54b57cdb58b9bf736b723b 100644 --- a/pc/main.c +++ b/pc/main.c @@ -448,11 +448,10 @@ confinit(void) conf.nswap = conf.nproc*80; conf.nimage = 50; switch(x86()){ - case 386: + case 3: conf.copymode = 1; /* copy on reference */ break; default: - case 486: conf.copymode = 0; /* copy on write */ break; }