summaryrefslogtreecommitdiff
path: root/sys/arch/i386
diff options
context:
space:
mode:
authorJason Downs <downsj@cvs.openbsd.org>1997-12-17 08:54:52 +0000
committerJason Downs <downsj@cvs.openbsd.org>1997-12-17 08:54:52 +0000
commitffed5272586c29a3919800adfa0b003f444c7fec (patch)
treeebcafcaa27d56a515c4a77e663ef296175b4f33a /sys/arch/i386
parent286718b01f4f5f3294c108d99ff58707f550dc95 (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/GENERIC3
-rw-r--r--sys/arch/i386/conf/INST3
-rw-r--r--sys/arch/i386/conf/RAMDISK3
-rw-r--r--sys/arch/i386/conf/THREADWAY7
-rw-r--r--sys/arch/i386/i386/locore.s102
-rw-r--r--sys/arch/i386/i386/machdep.c354
-rw-r--r--sys/arch/i386/i386/microtime.s6
-rw-r--r--sys/arch/i386/include/cpu.h34
-rw-r--r--sys/arch/i386/include/cputypes.h36
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) */