diff options
author | Jason Downs <downsj@cvs.openbsd.org> | 1997-12-17 08:54:52 +0000 |
---|---|---|
committer | Jason Downs <downsj@cvs.openbsd.org> | 1997-12-17 08:54:52 +0000 |
commit | ffed5272586c29a3919800adfa0b003f444c7fec (patch) | |
tree | ebcafcaa27d56a515c4a77e663ef296175b4f33a /sys/arch/i386 | |
parent | 286718b01f4f5f3294c108d99ff58707f550dc95 (diff) |
New CPU detection code, from NetBSD, with some machdep changes from myself.
Add I686_CPU to your configs if you have a PPro...
Diffstat (limited to 'sys/arch/i386')
-rw-r--r-- | sys/arch/i386/conf/GENERIC | 3 | ||||
-rw-r--r-- | sys/arch/i386/conf/INST | 3 | ||||
-rw-r--r-- | sys/arch/i386/conf/RAMDISK | 3 | ||||
-rw-r--r-- | sys/arch/i386/conf/THREADWAY | 7 | ||||
-rw-r--r-- | sys/arch/i386/i386/locore.s | 102 | ||||
-rw-r--r-- | sys/arch/i386/i386/machdep.c | 354 | ||||
-rw-r--r-- | sys/arch/i386/i386/microtime.s | 6 | ||||
-rw-r--r-- | sys/arch/i386/include/cpu.h | 34 | ||||
-rw-r--r-- | sys/arch/i386/include/cputypes.h | 36 |
9 files changed, 442 insertions, 106 deletions
diff --git a/sys/arch/i386/conf/GENERIC b/sys/arch/i386/conf/GENERIC index b9e7265d81b..5e09cab491a 100644 --- a/sys/arch/i386/conf/GENERIC +++ b/sys/arch/i386/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.54 1997/10/20 01:40:11 todd Exp $ +# $OpenBSD: GENERIC,v 1.55 1997/12/17 08:54:42 downsj Exp $ # $NetBSD: GENERIC,v 1.48 1996/05/20 18:17:23 mrg Exp $ # # GENERIC -- everything that's currently supported @@ -11,6 +11,7 @@ include "../../../conf/GENERIC" option I386_CPU # CPU classes; at least one is REQUIRED option I486_CPU option I586_CPU +option I686_CPU option GPL_MATH_EMULATE # floating point emulation #option VM86 # Virtual 8086 emulation diff --git a/sys/arch/i386/conf/INST b/sys/arch/i386/conf/INST index e0c900f9811..abdf5711557 100644 --- a/sys/arch/i386/conf/INST +++ b/sys/arch/i386/conf/INST @@ -1,4 +1,4 @@ -# $OpenBSD: INST,v 1.21 1997/10/07 05:53:52 mickey Exp $ +# $OpenBSD: INST,v 1.22 1997/12/17 08:54:43 downsj Exp $ # $NetBSD: INSTADP,v 1.17 1996/05/20 03:32:19 thorpej Exp $ # # Install kernels no longer support X. @@ -11,6 +11,7 @@ option INSTALL # support floppy install option I386_CPU # CPU classes; at least one is REQUIRED option I486_CPU option I586_CPU +option I686_CPU option GPL_MATH_EMULATE # floating point emulation # Some BIOSes don't get the size of extended memory right. If you diff --git a/sys/arch/i386/conf/RAMDISK b/sys/arch/i386/conf/RAMDISK index 2101f5558fd..aa18c48de1c 100644 --- a/sys/arch/i386/conf/RAMDISK +++ b/sys/arch/i386/conf/RAMDISK @@ -1,4 +1,4 @@ -# $OpenBSD: RAMDISK,v 1.20 1997/10/13 00:15:52 deraadt Exp $ +# $OpenBSD: RAMDISK,v 1.21 1997/12/17 08:54:44 downsj Exp $ # from: OpenBSD: INST,v 1.19 1996/11/05 03:49:13 tholo Exp # # Install kernels no longer support X. @@ -11,6 +11,7 @@ option SCSITERSE option I386_CPU # CPU classes; at least one is REQUIRED option I486_CPU option I586_CPU +option I686_CPU option GPL_MATH_EMULATE # floating point emulation # Some BIOSes don't get the size of extended memory right. If you diff --git a/sys/arch/i386/conf/THREADWAY b/sys/arch/i386/conf/THREADWAY index 0161bb08111..23c722bde31 100644 --- a/sys/arch/i386/conf/THREADWAY +++ b/sys/arch/i386/conf/THREADWAY @@ -1,16 +1,19 @@ # # THREADWAY: threadway.teeny.org # -# $OpenBSD: THREADWAY,v 1.22 1997/09/29 03:52:20 mickey Exp $ +# Cyrix 150Mhz ("PR200+") 6x86 +# +# $OpenBSD: THREADWAY,v 1.23 1997/12/17 08:54:45 downsj Exp $ # machine i386 option I586_CPU +option I486_CPU option XSERVER option PCVT_SCREENSAVER=1,PCVT_PRETTYSCRNS=0 option NMBCLUSTERS=512 -option APM_NOIDLE +option ATAPI_DEBUG_PROBE maxusers 32 option TIMEZONE=480 diff --git a/sys/arch/i386/i386/locore.s b/sys/arch/i386/i386/locore.s index 192fffb44f6..38bdbf128ef 100644 --- a/sys/arch/i386/i386/locore.s +++ b/sys/arch/i386/i386/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.37 1997/12/09 03:36:39 deraadt Exp $ */ +/* $OpenBSD: locore.s,v 1.38 1997/12/17 08:54:47 downsj Exp $ */ /* $NetBSD: locore.s,v 1.145 1996/05/03 19:41:19 christos Exp $ */ /*- @@ -151,12 +151,16 @@ */ .data - .globl _cpu,_cpu_vendor,_cold,_cnvmem,_extmem,_esym + .globl _cpu,_cpu_id,_cpu_vendor,_cpuid_level,_cpu_feature + .globl _cold,_cnvmem,_extmem,_esym .globl _boothowto,_bootdev,_atdevbase .globl _proc0paddr,_curpcb,_PTDpaddr,_dynamic_gdt .globl _bootapiver, _bootargc, _bootargv _cpu: .long 0 # are we 386, 386sx, 486, 586 or 686 +_cpu_id: .long 0 # saved from `cpuid' instruction +_cpu_feature: .long 0 # feature flags from 'cpuid' instruction +_cpuid_level: .long -1 # max. level accepted by 'cpuid' instruction _cpu_vendor: .space 16 # vendor string returned by `cpuid' instruction _cold: .long 1 # cold till we are not _esym: .long 0 # ptr to end of syms @@ -230,6 +234,27 @@ try386: /* Try to toggle alignment check flag; does not exist on 386. */ testl %eax,%eax jnz try486 + + /* + * Try the test of a NexGen CPU -- ZF will not change on a DIV + * instruction on a NexGen, it will on an i386. Documented in + * Nx586 Processor Recognition Application Note, NexGen, Inc. + */ + movl $0x5555,%eax + xorl %edx,%edx + movl $2,%ecx + divl %ecx + jnz is386 + +isnx586: + /* + * Don't try cpuid, as Nx586s reportedly don't support the + * PSL_ID bit. + */ + movl $CPU_NX586,RELOC(_cpu) + jmp 2f + +is386: movl $CPU_386,RELOC(_cpu) jmp 2f @@ -252,8 +277,27 @@ try486: /* Try to toggle identification flag; does not exist on early 486s. */ is486: movl $CPU_486,RELOC(_cpu) /* - * Check for Cyrix CPU by seeing if the flags change during a divide. - * This is documented in the Cx486SLC/e SMM Programmer's Guide. + * Check Cyrix CPU + * Cyrix CPUs do not change the undefined flags following + * execution of the divide instruction which divides 5 by 2. + * + * Note: CPUID is enabled on M2, so it passes another way. + */ + pushfl + movl $0x5555, %eax + xorl %edx, %edx + movl $2, %ecx + clc + divl %ecx + jnc trycyrix486 + popfl + jmp 2f +trycyrix486: + movl $CPU_6x86,RELOC(_cpu) # set CPU type + /* + * Check for Cyrix 486 CPU by seeing if the flags change during a + * divide. This is documented in the Cx486SLC/e SMM Programmer's + * Guide. */ xorl %edx,%edx cmpl %edx,%edx # set flags to known state @@ -267,10 +311,7 @@ is486: movl $CPU_486,RELOC(_cpu) xorl %ecx,%eax # are the flags different? testl $0x8d5,%eax # only check C|PF|AF|Z|N|V jne 2f # yes; must not be Cyrix CPU - movl $CPU_486DLC,RELOC(_cpu) # set CPU type - movl $0x69727943,RELOC(_cpu_vendor) # store vendor string - movb $0x78,RELOC(_cpu_vendor)+4 #ifndef CYRIX_CACHE_WORKS /* Disable caching of the ISA hole only. */ @@ -334,25 +375,16 @@ is486: movl $CPU_486,RELOC(_cpu) try586: /* Use the `cpuid' instruction. */ xorl %eax,%eax cpuid + movl %eax,RELOC(_cpuid_level) movl %ebx,RELOC(_cpu_vendor) # store vendor string movl %edx,RELOC(_cpu_vendor)+4 movl %ecx,RELOC(_cpu_vendor)+8 + movl $0, RELOC(_cpu_vendor)+12 movl $1,%eax cpuid - rorl $8,%eax # extract family type - andl $15,%eax - cmpl $5,%eax - jb is486 # less than a Pentium - movl $CPU_586,RELOC(_cpu) - je 3f # Pentium - movl $CPU_686,RELOC(_cpu) # else Pentium Pro -3: - - xorl %eax,%eax - xorl %edx,%edx - movl $0x10,%ecx - .byte 0xf, 0x30 # wrmsr (or trap on non-pentium :-) + movl %eax,RELOC(_cpu_id) # store cpu_id and features + movl %edx,RELOC(_cpu_feature) 2: /* @@ -828,10 +860,10 @@ ENTRY(copyout) ja _copy_fault #if defined(I386_CPU) -#if defined(I486_CPU) || defined(I586_CPU) +#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU) cmpl $CPUCLASS_386,_cpu_class jne 3f -#endif /* I486_CPU || I586_CPU */ +#endif /* I486_CPU || I586_CPU || I686_CPU */ testl %eax,%eax # anything to do? jz 3f @@ -968,10 +1000,10 @@ ENTRY(copyoutstr) movl 20(%esp),%edx # edx = maxlen #if defined(I386_CPU) -#if defined(I486_CPU) || defined(I586_CPU) +#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU) cmpl $CPUCLASS_386,_cpu_class jne 5f -#endif /* I486_CPU || I586_CPU */ +#endif /* I486_CPU || I586_CPU || I686_CPU */ /* Compute number of bytes in first page. */ movl %edi,%eax @@ -1033,7 +1065,7 @@ ENTRY(copyoutstr) jmp copystr_return #endif /* I386_CPU */ -#if defined(I486_CPU) || defined(I586_CPU) +#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU) 5: /* * Get min(%edx, VM_MAXUSER_ADDRESS-%edi). */ @@ -1064,7 +1096,7 @@ ENTRY(copyoutstr) jae _copystr_fault movl $ENAMETOOLONG,%eax jmp copystr_return -#endif /* I486_CPU || I586_CPU */ +#endif /* I486_CPU || I586_CPU || I686_CPU */ /* * copyinstr(caddr_t from, caddr_t to, size_t maxlen, size_t *lencopied); @@ -1269,10 +1301,10 @@ ENTRY(suword) movl $_fusufault,PCB_ONFAULT(%ecx) #if defined(I386_CPU) -#if defined(I486_CPU) || defined(I586_CPU) +#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU) cmpl $CPUCLASS_386,_cpu_class jne 2f -#endif /* I486_CPU || I586_CPU */ +#endif /* I486_CPU || I586_CPU || I686_CPU */ movl %edx,%eax shrl $PGSHIFT,%eax # calculate pte address @@ -1310,10 +1342,10 @@ ENTRY(susword) movl $_fusufault,PCB_ONFAULT(%ecx) #if defined(I386_CPU) -#if defined(I486_CPU) || defined(I586_CPU) +#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU) cmpl $CPUCLASS_386,_cpu_class jne 2f -#endif /* I486_CPU || I586_CPU */ +#endif /* I486_CPU || I586_CPU || I686_CPU */ movl %edx,%eax shrl $PGSHIFT,%eax # calculate pte address @@ -1352,10 +1384,10 @@ ENTRY(suswintr) movl $_fusubail,PCB_ONFAULT(%ecx) #if defined(I386_CPU) -#if defined(I486_CPU) || defined(I586_CPU) +#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU) cmpl $CPUCLASS_386,_cpu_class jne 2f -#endif /* I486_CPU || I586_CPU */ +#endif /* I486_CPU || I586_CPU || I686_CPU */ movl %edx,%eax shrl $PGSHIFT,%eax # calculate pte address @@ -1386,10 +1418,10 @@ ENTRY(subyte) movl $_fusufault,PCB_ONFAULT(%ecx) #if defined(I386_CPU) -#if defined(I486_CPU) || defined(I586_CPU) +#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU) cmpl $CPUCLASS_386,_cpu_class jne 2f -#endif /* I486_CPU || I586_CPU */ +#endif /* I486_CPU || I586_CPU || I686_CPU */ movl %edx,%eax shrl $PGSHIFT,%eax # calculate pte address @@ -2129,7 +2161,7 @@ ENTRY(bzero) stosb #if defined(I486_CPU) -#if defined(I386_CPU) || defined(I586_CPU) +#if defined(I386_CPU) || defined(I586_CPU) || defined(I686_CPU) cmpl $CPUCLASS_486,_cpu_class jne 8f #endif diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index 5494dc3d24c..539dc0406e9 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.67 1997/12/09 03:36:40 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.68 1997/12/17 08:54:48 downsj Exp $ */ /* $NetBSD: machdep.c,v 1.202 1996/05/18 15:54:59 christos Exp $ */ /*- @@ -189,6 +189,26 @@ int bus_mem_add_mapping __P((bus_addr_t, bus_size_t, extern u_int cnvmem; /* BIOS's conventional memory size */ extern u_int extmem; /* BIOS's extended memory size */ +void cyrix6x86_cpu_setup __P((const char *)); +void intel586_cpu_setup __P((const char *)); +void intel686_cpu_setup __P((const char *)); + +#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU) +static __inline u_char +cyrix_read_reg(u_char reg) +{ + outb(0x22, reg); + return inb(0x23); +} + +static __inline void +cyrix_write_reg(u_char reg, u_char data) +{ + outb(0x22, reg); + outb(0x23, data); +} +#endif + /* * Machine-dependent startup code */ @@ -438,74 +458,300 @@ allocsys(v) char cpu_model[120]; extern char version[]; -struct cpu_nameclass i386_cpus[] = { - { "i386SX", CPUCLASS_386 }, /* CPU_386SX */ - { "i386DX", CPUCLASS_386 }, /* CPU_386 */ - { "i486SX", CPUCLASS_486 }, /* CPU_486SX */ - { "i486DX", CPUCLASS_486 }, /* CPU_486 */ - { "Pentium", CPUCLASS_586 }, /* CPU_586 */ - { "Cx486DLC", CPUCLASS_486 }, /* CPU_486DLC (Cyrix) */ - { "Pentium Pro",CPUCLASS_686 }, /* CPU_686 */ +/* + * Note: these are just the ones that may not have a cpuid instruction. + * We deal with the rest in a different way. + */ +struct cpu_nocpuid_nameclass i386_nocpuid_cpus[] = { + { CPUVENDOR_INTEL, "Intel", "386SX", CPUCLASS_386, + NULL}, /* CPU_386SX */ + { CPUVENDOR_INTEL, "Intel", "386DX", CPUCLASS_386, + NULL}, /* CPU_386 */ + { CPUVENDOR_INTEL, "Intel", "486SX", CPUCLASS_486, + NULL}, /* CPU_486SX */ + { CPUVENDOR_INTEL, "Intel", "486DX", CPUCLASS_486, + NULL}, /* CPU_486 */ + { CPUVENDOR_CYRIX, "Cyrix", "486DLC", CPUCLASS_486, + NULL}, /* CPU_486DLC */ + { CPUVENDOR_CYRIX, "Cyrix", "6x86", CPUCLASS_486, + cyrix6x86_cpu_setup}, /* CPU_6x86 */ + { CPUVENDOR_NEXGEN,"NexGen","586", CPUCLASS_386, + NULL}, /* CPU_NX586 */ +}; + +const char *classnames[] = { + "386", + "486", + "586", + "686" +}; + +const char *modifiers[] = { + "", + "OverDrive ", + "Dual ", + "" }; +struct cpu_cpuid_nameclass i386_cpuid_cpus[] = { + { + "GenuineIntel", + CPUVENDOR_INTEL, + "Intel", + /* Family 4 */ + { { + CPUCLASS_486, + { + "486DX", "486DX", "486SX", "486DX2", "486SL", + "486SX2", 0, "486DX2 W/B Enhanced", + "486DX4", 0, 0, 0, 0, 0, 0, 0, + "486" /* Default */ + }, + NULL + }, + /* Family 5 */ + { + CPUCLASS_586, + { + 0, "Pentium", "Pentium (P54C)", + "Pentium (P24T)", "Pentium/MMX", "Pentium", 0, + "Pentium (P54C)", 0, 0, 0, 0, 0, 0, 0, 0, + "Pentium" /* Default */ + }, + intel586_cpu_setup + }, + /* Family 6 */ + { + CPUCLASS_686, + { + 0, "Pentium Pro", 0, "Pentium II", + "Pentium Pro", 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + "Pentium Pro" /* Default */ + }, + intel686_cpu_setup + } } + }, + { + "AuthenticAMD", + CPUVENDOR_AMD, + "AMD", + /* Family 4 */ + { { + CPUCLASS_486, + { + 0, 0, 0, "Am486DX2 W/T", + 0, 0, 0, "Am486DX2 W/B", + "Am486DX4 W/T or Am5x86 W/T 150", + "Am486DX4 W/B or Am5x86 W/B 150", 0, 0, + 0, 0, "Am5x86 W/T 133/160", + "Am5x86 W/B 133/160", + "Am486 or Am5x86" /* Default */ + }, + NULL + }, + /* Family 5 */ + { + CPUCLASS_586, + { + "K5", "K5", "K5", "K5", 0, 0, "K6", + 0, 0, 0, 0, 0, 0, 0, 0, 0, + "K5 or K6" /* Default */ + }, + NULL + }, + /* Family 6, not yet available from AMD */ + { + CPUCLASS_686, + { + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + "Pentium Pro compatible" /* Default */ + }, + NULL + } } + }, + { + "CyrixInstead", + CPUVENDOR_CYRIX, + "Cyrix", + /* Family 4 */ + { { + CPUCLASS_486, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "486" /* Default */ + }, + NULL + }, + /* Family 5 */ + { + CPUCLASS_586, + { + 0, 0, "6x86", 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + "6x86" /* Default */ + }, + cyrix6x86_cpu_setup + }, + /* Family 6, not yet available from Cyrix */ + { + CPUCLASS_686, + { + "M2", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "M2" /* Default */ + }, + NULL + } } + } +}; + +#define CPUDEBUG + +void +cyrix6x86_cpu_setup(cpu_device) + const char *cpu_device; +{ +#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU) + /* set up various cyrix registers */ + /* Enable suspend on halt */ + cyrix_write_reg(0xc2, cyrix_read_reg(0xc2) | 0x08); + /* enable access to ccr4/ccr5 */ + cyrix_write_reg(0xC3, cyrix_read_reg(0xC3) | 0x10); + /* cyrix's workaround for the "coma bug" */ + cyrix_write_reg(0x31, cyrix_read_reg(0x31) | 0xf8); + cyrix_write_reg(0x32, cyrix_read_reg(0x32) | 0x7f); + cyrix_write_reg(0x33, cyrix_read_reg(0x33) & ~0xff); + cyrix_write_reg(0x3c, cyrix_read_reg(0x3c) | 0x87); + /* disable access to ccr4/ccr5 */ + cyrix_write_reg(0xC3, cyrix_read_reg(0xC3) & ~0x10); + + printf("\n%s: Cyrix workaround performed\n", cpu_device); +#endif +} + +void +intel586_cpu_setup(cpu_device) + const char *cpu_device; +{ +#if defined(I586_CPU) || defined(I686_CPU) + calibrate_cyclecounter(); + printf(" %d MHz\n", pentium_mhz); + + fix_f00f(); + printf("%s: F00F bug workaround installed\n", cpu_device); +#endif +} + +void +intel686_cpu_setup(cpu_device) + const char *cpu_device; +{ +#if defined(I586_CPU) || defined(I686_CPU) + calibrate_cyclecounter(); + printf(" %d MHz\n", pentium_mhz); +#endif +} + void identifycpu() { extern char cpu_vendor[]; - - printf("CPU: "); + extern int cpu_id; + const char *name, *modifier, *vendorname; + const char *cpu_device = "cpu0"; + int class = CPUCLASS_386, vendor, i, max; + int family, model, step, modif; + struct cpu_cpuid_nameclass *cpup = NULL; + void (*cpu_setup) __P((const char *)); + + if (cpuid_level == -1) { #ifdef DIAGNOSTIC - if (cpu < 0 || cpu >= (sizeof i386_cpus/sizeof(struct cpu_nameclass))) - panic("unknown cpu type %d\n", cpu); + if (cpu < 0 || cpu >= + (sizeof i386_nocpuid_cpus/sizeof(struct cpu_nocpuid_nameclass))) + panic("unknown cpu type %d\n", cpu); +#endif + name = i386_nocpuid_cpus[cpu].cpu_name; + vendor = i386_nocpuid_cpus[cpu].cpu_vendor; + vendorname = i386_nocpuid_cpus[cpu].cpu_vendorname; + class = i386_nocpuid_cpus[cpu].cpu_class; + cpu_setup = i386_nocpuid_cpus[cpu].cpu_setup; + modifier = ""; + } else { + max = sizeof (i386_cpuid_cpus) / sizeof (i386_cpuid_cpus[0]); + modif = (cpu_id >> 12) & 3; + family = (cpu_id >> 8) & 15; + if (family < CPU_MINFAMILY) + panic("identifycpu: strange family value"); + model = (cpu_id >> 4) & 15; + step = cpu_id & 15; +#ifdef CPUDEBUG + printf("%s: family %x model %x step %x\n", cpu_device, family, + model, step); #endif - sprintf(cpu_model, "%s (", i386_cpus[cpu].cpu_name); - if (cpu_vendor[0] != '\0') { - strcat(cpu_model, cpu_vendor); - strcat(cpu_model, " "); - } - cpu_class = i386_cpus[cpu].cpu_class; - switch(cpu_class) { - case CPUCLASS_386: - strcat(cpu_model, "386"); - break; - case CPUCLASS_486: - strcat(cpu_model, "486"); - break; - case CPUCLASS_586: - strcat(cpu_model, "586"); - break; - case CPUCLASS_686: - strcat(cpu_model, "686"); - break; - default: - strcat(cpu_model, "unknown"); /* will panic below... */ - break; - } - strcat(cpu_model, "-class CPU)"); - printf("%s", cpu_model); -#if defined(I586_CPU) - if (cpu_class >= CPUCLASS_586) { - calibrate_cyclecounter(); - printf(" %d MHz", pentium_mhz); - } - if (!strcmp(cpu_model, "Pentium (GenuineIntel 586-class CPU)")) { - fix_f00f(); - printf("\nCPU: F00F bug workaround installed"); + for (i = 0; i < max; i++) { + if (!strncmp(cpu_vendor, + i386_cpuid_cpus[i].cpu_id, 12)) { + cpup = &i386_cpuid_cpus[i]; + break; + } + } + + if (cpup == NULL) { + vendor = CPUVENDOR_UNKNOWN; + if (cpu_vendor[0] != '\0') + vendorname = &cpu_vendor[0]; + else + vendorname = "Unknown"; + if (family > CPU_MAXFAMILY) + family = CPU_MAXFAMILY; + class = family - 3; + modifier = ""; + name = ""; + cpu_setup = NULL; + } else { + vendor = cpup->cpu_vendor; + vendorname = cpup->cpu_vendorname; + modifier = modifiers[modif]; + if (family > CPU_MAXFAMILY) { + family = CPU_MAXFAMILY; + model = CPU_DEFMODEL; + } else if (model > CPU_MAXMODEL) + model = CPU_DEFMODEL; + i = family - CPU_MINFAMILY; + name = cpup->cpu_family[i].cpu_models[model]; + if (name == NULL) + name = cpup->cpu_family[i].cpu_models[CPU_DEFMODEL]; + class = cpup->cpu_family[i].cpu_class; + cpu_setup = cpup->cpu_family[i].cpu_setup; + } } -#endif - printf("\n"); + + sprintf(cpu_model, "%s %s%s (%s-class)", vendorname, modifier, name, + classnames[class]); + printf("%s: %s", cpu_device, cpu_model); + + cpu_class = class; /* * Now that we have told the user what they have, * let them know if that machine type isn't configured. */ switch (cpu_class) { -#if !defined(I386_CPU) && !defined(I486_CPU) && !defined(I586_CPU) +#if !defined(I386_CPU) && !defined(I486_CPU) && !defined(I586_CPU) && !defined(I686_CPU) #error No CPU classes configured. #endif -#ifndef I586_CPU +#ifndef I686_CPU case CPUCLASS_686: + printf("NOTICE: this kernel does not support Pentium Pro CPU class\n"); +#ifdef I586_CPU + printf("NOTICE: lowering CPU class to i586\n"); + cpu_class = CPUCLASS_586; + break; +#endif +#endif +#ifndef I586_CPU case CPUCLASS_586: printf("NOTICE: this kernel does not support Pentium CPU class\n"); #ifdef I486_CPU @@ -532,6 +778,12 @@ identifycpu() break; } + /* configure the CPU if needed */ + if (cpu_setup != NULL) + cpu_setup(cpu_device); + else + printf("\n"); + if (cpu == CPU_486DLC) { #ifndef CYRIX_CACHE_WORKS printf("WARNING: CYRIX 486DLC CACHE UNCHANGED.\n"); @@ -544,7 +796,7 @@ identifycpu() #endif } -#if defined(I486_CPU) || defined(I586_CPU) +#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU) /* * On a 486 or above, enable ring 0 write protection. */ diff --git a/sys/arch/i386/i386/microtime.s b/sys/arch/i386/i386/microtime.s index 05cf6c53fde..8c342f0b53c 100644 --- a/sys/arch/i386/i386/microtime.s +++ b/sys/arch/i386/i386/microtime.s @@ -1,4 +1,4 @@ -/* $OpenBSD: microtime.s,v 1.8 1996/08/08 18:47:11 dm Exp $ */ +/* $OpenBSD: microtime.s,v 1.9 1997/12/17 08:54:49 downsj Exp $ */ /* $NetBSD: microtime.s,v 1.16 1995/04/17 12:06:47 cgd Exp $ */ /*- @@ -48,7 +48,7 @@ #ifndef HZ ENTRY(microtime) -#if defined(I586_CPU) && defined(NTP) +#if (defined(I586_CPU) || defined(I686_CPU)) && defined(NTP) movl _pentium_mhz, %ecx testl %ecx, %ecx jne pentium_microtime @@ -138,7 +138,7 @@ common_microtime: ret -#if defined(I586_CPU) +#if defined(I586_CPU) || defined(I686_CPU) .data .globl _pentium_base_tsc .comm _pentium_base_tsc,8 diff --git a/sys/arch/i386/include/cpu.h b/sys/arch/i386/include/cpu.h index 15506252a04..33527023919 100644 --- a/sys/arch/i386/include/cpu.h +++ b/sys/arch/i386/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.18 1997/12/09 03:36:41 deraadt Exp $ */ +/* $OpenBSD: cpu.h,v 1.19 1997/12/17 08:54:51 downsj Exp $ */ /* $NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $ */ /*- @@ -96,7 +96,7 @@ int want_resched; /* resched() was called */ #define DELAY(x) delay(x) void delay __P((int)); -#ifdef I586_CPU +#if defined(I586_CPU) || defined(I686_CPU) /* * High resolution clock support (Pentium only) */ @@ -129,18 +129,38 @@ void delay __P((int)); */ #include <machine/cputypes.h> -struct cpu_nameclass { - char *cpu_name; - int cpu_class; +struct cpu_nocpuid_nameclass { + int cpu_vendor; + const char *cpu_vendorname; + const char *cpu_name; + int cpu_class; + void (*cpu_setup) __P((const char *)); +}; + +struct cpu_cpuid_nameclass { + const char *cpu_id; + int cpu_vendor; + const char *cpu_vendorname; + struct cpu_cpuid_family { + int cpu_class; + const char *cpu_models[CPU_MAXMODEL+2]; + void (*cpu_setup) __P((const char *)); + } cpu_family[CPU_MAXFAMILY - CPU_MINFAMILY + 1]; }; #ifdef _KERNEL extern int cpu; extern int cpu_class; -extern struct cpu_nameclass i386_cpus[]; -#ifdef I586_CPU +extern int cpu_feature; +extern int cpuid_level; +extern struct cpu_nocpuid_nameclass i386_nocpuid_cpus[]; +extern struct cpu_cpuid_nameclass i386_cpuid_cpus[]; + +#if defined(I586_CPU) || defined(I686_CPU) extern int pentium_mhz; +#endif +#ifdef I586_CPU /* F00F bug fix stuff for pentium cpu */ extern int cpu_f00f_bug; void fix_f00f __P((void)); diff --git a/sys/arch/i386/include/cputypes.h b/sys/arch/i386/include/cputypes.h index fb8f3576ee9..fe434ab40de 100644 --- a/sys/arch/i386/include/cputypes.h +++ b/sys/arch/i386/include/cputypes.h @@ -1,4 +1,5 @@ -/* $NetBSD: cputypes.h,v 1.7 1994/10/27 04:16:01 cgd Exp $ */ +/* $OpenBSD: cputypes.h,v 1.3 1997/12/17 08:54:51 downsj Exp $ */ +/* $NetBSD: cputypes.h,v 1.10 1997/10/18 04:51:03 mikel Exp $ */ /* * Copyright (c) 1993 Christopher G. Demetriou @@ -37,13 +38,38 @@ #define CPUCLASS_686 3 /* - * Kinds of Processor + * Kinds of Processor. Only the first 7 are used, as they are processors + * that might not have a cpuid instruction. */ #define CPU_386SX 0 /* Intel 80386SX */ #define CPU_386 1 /* Intel 80386DX */ #define CPU_486SX 2 /* Intel 80486SX */ #define CPU_486 3 /* Intel 80486DX */ -#define CPU_586 4 /* Intel P.....m (I hate lawyers; it's TM) */ -#define CPU_486DLC 5 /* Cyrix 486DLC */ -#define CPU_686 6 /* Intel P.....m Pro */ +#define CPU_486DLC 4 /* Cyrix 486DLC */ +#define CPU_6x86 5 /* Cyrix/IBM 6x86 */ +#define CPU_NX586 6 /* NexGen 586 */ +#define CPU_586 7 /* Intel P.....m (I hate lawyers; it's TM) */ +#define CPU_AM586 8 /* AMD Am486 and Am5x86 */ +#define CPU_K5 9 /* AMD K5 */ +#define CPU_K6 10 /* NexGen 686 aka AMD K6 */ +#define CPU_686 11 /* Intel P.....m Pro */ + +/* + * CPU vendors + */ + +#define CPUVENDOR_UNKNOWN -1 +#define CPUVENDOR_INTEL 0 +#define CPUVENDOR_CYRIX 1 +#define CPUVENDOR_NEXGEN 2 +#define CPUVENDOR_AMD 3 + +/* + * Some other defines, dealing with values returned by cpuid. + */ + +#define CPU_MAXMODEL 15 /* Models within family range 0-15 */ +#define CPU_DEFMODEL 16 /* Value for unknown model -> default */ +#define CPU_MINFAMILY 4 /* Lowest that cpuid can return (486) */ +#define CPU_MAXFAMILY 6 /* Highest we know (686) */ |