Re: Cyrix 6x86MX and Centaur C6 CPUs in 2.1.102

Trevor Johnson (trevor@jpj.net)
Tue, 19 May 1998 15:30:41 -0700 (PDT)


Linus Torvalds wrote:

> Another thing that would be good would be to have some names for the
> capabilities we currently use: using "x & 16" and just magically knowing
> that "16" is the bit value for X86_CAP_TSC is kind of obscure.
>
> Anybody want to do something like this?

Here's my attempt. This patch:

- moves the X86_FEATURE_ macros from arch/i386/mm/init.c to
include/asm-i386/processor.h
- defines X86_FEATURE_BADTSC, X86_FEATURE_FCMOV, X86_FEATURE_MMX,
X86_FEATURE_OSFXSR, X86_FEATURE_AMD3D, and several unused, numbered
capabilities
- adds a badtsc capability and tsc_bug bug to /proc/cpuinfo

Is it too much redundantly excessive duplication to have both?

The tsc_bug will show for all CPUs made by Centaur/IDT which say they have
a TSC. It will also show for CPUs made by Cyrix/IBM which say they have
both a TSC and MMX.

- capitalizes "CPU" in a few places :-)

- assumes the bad TSC is good enough for use in
drivers/net/hamradio/soundmodem/sm.c (changing its behavior) but
not arch/i386/kernel/time.c, drivers/char/hfmodem/refclock.c or
drivers/char/random.c (leaving them the same)

This patch is also available at
http://jpj.net/~trevor/linux/x86_capability-2.1.102.diff; any later
versions will have different names. It is untested.
___
Trevor Johnson

diff -ru linux/arch/i386/kernel/mtrr.c linux-2.1.102-local/arch/i386/kernel/mtrr.c
--- linux/arch/i386/kernel/mtrr.c Sun May 3 11:58:36 1998
+++ linux-2.1.102-local/arch/i386/kernel/mtrr.c Tue May 19 14:01:06 1998
@@ -148,8 +148,6 @@
#define TRUE 1
#define FALSE 0

-#define X86_FEATURE_MTRR 0x1000 /* memory type registers */
-
#define MTRRcap_MSR 0x0fe
#define MTRRdefType_MSR 0x2ff

diff -ru linux/arch/i386/kernel/setup.c linux-2.1.102-local/arch/i386/kernel/setup.c
--- linux/arch/i386/kernel/setup.c Wed May 13 11:47:26 1998
+++ linux-2.1.102-local/arch/i386/kernel/setup.c Tue May 19 14:01:14 1998
@@ -8,7 +8,7 @@
*/

/*
- * This file handles the architecture-dependent parts of initialization
+ * This file handles the architecture-dependent parts of initialization.
*/

#include <linux/errno.h>
@@ -32,19 +32,20 @@
#ifdef CONFIG_BLK_DEV_RAM
#include <linux/blk.h>
#endif
+#include <asm/processor.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/smp.h>

/*
- * Machine setup..
+ * Machine setup
*/

char ignore_irq13 = 0; /* set if exception 16 works */
struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };

/*
- * Bus types ..
+ * Bus types
*/
int EISA_bus = 0;
int MCA_bus = 0;
@@ -172,7 +173,7 @@
if (to != command_line) to--;
if (!memcmp(from+4, "nopentium", 9)) {
from += 9+4;
- boot_cpu_data.x86_capability &= ~8;
+ boot_cpu_data.x86_capability &= ~X86_FEATURE_PSE;
} else {
memory_end = simple_strtoul(from+4, &from, 0);
if ( *from == 'K' || *from == 'k' ) {
@@ -210,7 +211,7 @@
}
#endif

- /* request io space for devices used on all i[345]86 PC'S */
+ /* request I/O space for devices used on all i[345]86 PCs */
request_region(0x00,0x20,"dma1");
request_region(0x40,0x20,"timer");
request_region(0x80,0x10,"dma page reg");
@@ -238,8 +239,11 @@
int nr = c->x86_model;
char *buf = c->x86_model_id;

- /* Cyrix claims they have a TSC, but it is broken */
- c->x86_capability &= ~16;
+ /* Cyrix claims they have a TSC, but it is broken,
+ so set the badtsc flag instead. */
+
+ c->x86_capability &= ~X86_FEATURE_TSC;
+ c->x86_capability |= X86_FEATURE_BADTSC;

/* Note that some of the possibilities this decoding allows
* have never actually been manufactured - but those that
@@ -264,7 +268,7 @@
} else if (nr >= 0x20 && nr <= 0x4f) { /* 5x86, 6x86 or Gx86 */
char *s = "";
if (nr >= 0x30 && nr < 0x40) { /* 6x86 */
- if (c->x86 == 5 && (c->x86_capability & (1 << 8)))
+ if (c->x86 == 5 && (c->x86_capability & X86_FEATURE_CXS))
s = "L"; /* 6x86L */
else if (c->x86 == 6)
s = "MX"; /* 6x86MX */
@@ -441,12 +445,13 @@
int get_cpuinfo(char * buffer)
{
char *p = buffer;
- int sep_bug;
+ int sep_bug, tsc_bug;
static const char *x86_cap_flags[] = {
"fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
- "cx8", "apic", "10", "sep", "mtrr", "pge", "mca", "cmov",
- "fcmov", "17", "18", "19", "20", "21", "22", "mmx",
- "osfxsr", "25", "26", "27", "28", "29", "30", "amd3d"
+ "cx8", "apic", "badtsc", "sep", "mtrr", "pge", "mca",
+ "cmov", "fcmov", "17", "18", "19", "20", "21", "22",
+ "mmx", "osfxsr", "25", "26", "27", "28", "29", "30",
+ "amd3d"
};
struct cpuinfo_x86 *c = cpu_data;
int i, n;
@@ -477,14 +482,20 @@
sep_bug = c->x86_vendor == X86_VENDOR_INTEL &&
c->x86 == 0x06 &&
c->cpuid_level >= 0 &&
- (c->x86_capability & 0x800) &&
+ (c->x86_capability & X86_FEATURE_CMOV) &&
c->x86_model < 3 &&
c->x86_mask < 3;
+
+ tsc_bug = c->x86_capability & X86_FEATURE_TSC &&
+ ((c->x86_vendor == X86_VENDOR_CYRIX &&
+ c->x86_capability & X86_FEATURE_MMX ) ||
+ c->x86_vendor == X86_VENDOR_CENTAUR);

p += sprintf(p, "fdiv_bug\t: %s\n"
"hlt_bug\t\t: %s\n"
"sep_bug\t\t: %s\n"
"f00f_bug\t: %s\n"
+ "tsc_bug\t: %s\n"
"fpu\t\t: %s\n"
"fpu_exception\t: %s\n"
"cpuid level\t: %d\n"
@@ -494,6 +505,7 @@
c->hlt_works_ok ? "no" : "yes",
sep_bug ? "yes" : "no",
c->f00f_bug ? "yes" : "no",
+ tsc_bug ? "yes" : "no",
c->hard_math ? "yes" : "no",
(c->hard_math && ignore_irq13) ? "yes" : "no",
c->cpuid_level,
diff -ru linux/arch/i386/kernel/time.c linux-2.1.102-local/arch/i386/kernel/time.c
--- linux/arch/i386/kernel/time.c Wed May 13 13:23:13 1998
+++ linux-2.1.102-local/arch/i386/kernel/time.c Tue May 19 14:13:53 1998
@@ -25,6 +25,7 @@
#include <linux/init.h>
#include <linux/smp.h>

+#include <asm/processor.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -525,7 +526,7 @@
xtime.tv_usec = 0;

/* If we have the CPU hardware time counters, use them */
- if (boot_cpu_data.x86_capability & 16) {
+ if (boot_cpu_data.x86_capability & X86_FEATURE_TSC) {
do_gettimeoffset = do_fast_gettimeoffset;
do_get_fast_time = do_x86_get_fast_time;

diff -ru linux/arch/i386/mm/init.c linux-2.1.102-local/arch/i386/mm/init.c
--- linux/arch/i386/mm/init.c Tue Apr 28 13:04:00 1998
+++ linux-2.1.102-local/arch/i386/mm/init.c Tue May 19 14:01:11 1998
@@ -22,6 +22,7 @@
#include <linux/blk.h>
#endif

+#include <asm/processor.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -115,23 +116,6 @@
#define X86_CR4_MCE 0x0040 /* Machine check enable */
#define X86_CR4_PGE 0x0080 /* enable global pages */
#define X86_CR4_PCE 0x0100 /* enable performance counters at ipl 3 */
-
-#define X86_FEATURE_FPU 0x0001 /* internal FPU */
-#define X86_FEATURE_VME 0x0002 /* vm86 extensions */
-#define X86_FEATURE_DE 0x0004 /* debugging extensions */
-#define X86_FEATURE_PSE 0x0008 /* Page size extensions */
-#define X86_FEATURE_TSC 0x0010 /* Time stamp counter */
-#define X86_FEATURE_MSR 0x0020 /* RDMSR/WRMSR */
-#define X86_FEATURE_PAE 0x0040 /* Physical address extension */
-#define X86_FEATURE_MCE 0x0080 /* Machine check exception */
-#define X86_FEATURE_CXS 0x0100 /* cmpxchg8 available */
-#define X86_FEATURE_APIC 0x0200 /* internal APIC */
-#define X86_FEATURE_10 0x0400
-#define X86_FEATURE_11 0x0800
-#define X86_FEATURE_MTRR 0x1000 /* memory type registers */
-#define X86_FEATURE_PGE 0x2000 /* Global page */
-#define X86_FEATURE_MCA 0x4000 /* Machine Check Architecture */
-#define X86_FEATURE_CMOV 0x8000 /* Cmov/fcomi */

/*
* Save the cr4 feature set we're using (ie
diff -ru linux/drivers/char/hfmodem/refclock.c linux-2.1.102-local/drivers/char/hfmodem/refclock.c
--- linux/drivers/char/hfmodem/refclock.c Thu May 7 23:50:19 1998
+++ linux-2.1.102-local/drivers/char/hfmodem/refclock.c Tue May 19 14:17:31 1998
@@ -30,6 +30,7 @@
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/hfmodem.h>
+#include <asm/processor.h>

/* --------------------------------------------------------------------- */

@@ -67,10 +68,10 @@
#ifdef __i386__
__initfunc(static void i386_capability(void))
{
- if (boot_cpu_data.x86_capability & 0x10)
+ if (boot_cpu_data.x86_capability & X86_FEATURE_TSC))
rdtsc_ok = 1;
else
- printk(KERN_INFO "%s: cpu does not support the rdtsc instruction\n", hfmodem_drvname);
+ printk(KERN_INFO "%s: CPU does not support the rdtsc instruction\n", hfmodem_drvname);
}
#endif /* __i386__ */

diff -ru linux/drivers/char/random.c linux-2.1.102-local/drivers/char/random.c
--- linux/drivers/char/random.c Wed May 6 10:56:03 1998
+++ linux-2.1.102-local/drivers/char/random.c Tue May 19 14:17:28 1998
@@ -237,6 +237,7 @@
#include <linux/poll.h>
#include <linux/init.h>

+#include <asm/processor.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
@@ -585,7 +586,7 @@
begin_benchmark(&timer_benchmark);
#endif
#if defined (__i386__)
- if (boot_cpu_data.x86_capability & 16) {
+ if (boot_cpu_data.x86_capability & X86_FEATURE_TSC) {
unsigned long low, high;
__asm__(".byte 0x0f,0x31"
:"=a" (low), "=d" (high));
diff -ru linux/drivers/net/hamradio/soundmodem/sm.h linux-2.1.102-local/drivers/net/hamradio/soundmodem/sm.h
--- linux/drivers/net/hamradio/soundmodem/sm.h Mon Jun 16 16:35:56 1997
+++ linux-2.1.102-local/drivers/net/hamradio/soundmodem/sm.h Tue May 19 14:14:39 1998
@@ -32,6 +32,7 @@

#include <linux/hdlcdrv.h>
#include <linux/soundmodem.h>
+#include <asm/processor.h>

#define SM_DEBUG

@@ -293,7 +294,7 @@

extern int sm_x86_capability;

-#define HAS_RDTSC (sm_x86_capability & 0x10)
+#define HAS_RDTSC (sm_x86_capability & (X86_FEATURE_TSC | X86_FEATURE_BADTSC))

/*
* only do 32bit cycle counter arithmetic; we hope we won't overflow :-)
diff -ru linux/include/asm-i386/processor.h linux-2.1.102-local/include/asm-i386/processor.h
--- linux/include/asm-i386/processor.h Tue Apr 14 12:54:05 1998
+++ linux-2.1.102-local/include/asm-i386/processor.h Tue May 19 14:01:17 1998
@@ -44,6 +44,43 @@
#define X86_VENDOR_CENTAUR 5
#define X86_VENDOR_UNKNOWN 0xff

+/*
+ * capabilities of CPUs
+ */
+
+#define X86_FEATURE_FPU 0x1 /* internal FPU */
+#define X86_FEATURE_VME 0x2 /* vm86 extensions */
+#define X86_FEATURE_DE 0x4 /* debugging extensions */
+#define X86_FEATURE_PSE 0x8 /* Page size extensions */
+#define X86_FEATURE_TSC 0x10 /* Time stamp counter */
+#define X86_FEATURE_MSR 0x20 /* RDMSR/WRMSR */
+#define X86_FEATURE_PAE 0x40 /* Physical address extension */
+#define X86_FEATURE_MCE 0x80 /* Machine check exception */
+#define X86_FEATURE_CXS 0x100 /* cmpxchg8 available */
+#define X86_FEATURE_APIC 0x200 /* internal APIC */
+#define X86_FEATURE_BADTSC 0x400 /* buggy time stamp counter */
+#define X86_FEATURE_SEP 0x800
+#define X86_FEATURE_MTRR 0x1000 /* memory type registers */
+#define X86_FEATURE_PGE 0x2000 /* Global page */
+#define X86_FEATURE_MCA 0x4000 /* Machine Check Architecture */
+#define X86_FEATURE_CMOV 0x8000 /* Cmov/fcomi */
+#define X86_FEATURE_FCMOV 0x10000
+#define X86_FEATURE_17 0x20000
+#define X86_FEATURE_18 0x40000
+#define X86_FEATURE_19 0x80000
+#define X86_FEATURE_20 0x100000
+#define X86_FEATURE_21 0x200000
+#define X86_FEATURE_22 0x400000
+#define X86_FEATURE_MMX 0x800000 /* multimedia extensions */
+#define X86_FEATURE_OSFXSR 0x1000000
+#define X86_FEATURE_25 0x2000000
+#define X86_FEATURE_26 0x4000000
+#define X86_FEATURE_27 0x8000000
+#define X86_FEATURE_28 0x10000000
+#define X86_FEATURE_29 0x20000000
+#define X86_FEATURE_30 0x40000000
+#define X86_FEATURE_AMD3D 0x80000000
+
extern struct cpuinfo_x86 boot_cpu_data;

#ifdef __SMP__

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu