patch-2.2.8 linux/include/asm-i386/bugs.h

Next file: linux/include/asm-i386/irq.h
Previous file: linux/include/asm-arm/vga.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.7/linux/include/asm-i386/bugs.h linux/include/asm-i386/bugs.h
@@ -19,6 +19,7 @@
 
 #include <linux/config.h>
 #include <asm/processor.h>
+#include <asm/msr.h>
 
 #define CONFIG_BUGi386
 
@@ -27,6 +28,11 @@
 	boot_cpu_data.hlt_works_ok = 0;
 }
 
+__initfunc(static void mca_pentium(char *s, int *ints))
+{
+	mca_pentium_flag = 1;
+}
+
 __initfunc(static void no_387(char *s, int *ints))
 {
 	boot_cpu_data.hard_math = 0;
@@ -61,6 +67,31 @@
 #endif
 		return;
 	}
+	if (mca_pentium_flag) {
+		/* The IBM Model 95 machines with pentiums lock up on
+		 * fpu test, so we avoid it. All pentiums have inbuilt
+		 * FPU and thus should use exception 16. We still do
+		 * the FDIV test, although I doubt there where ever any
+		 * MCA boxes built with non-FDIV-bug cpus.
+		 */
+		__asm__("fninit\n\t"
+			"fldl %1\n\t"
+			"fdivl %2\n\t"
+			"fmull %2\n\t"
+			"fldl %1\n\t"
+			"fsubp %%st,%%st(1)\n\t"
+			"fistpl %0\n\t"
+			"fwait\n\t"
+			"fninit"
+			: "=m" (*&boot_cpu_data.fdiv_bug)
+			: "m" (*&x), "m" (*&y));
+		printk("mca-pentium specified, avoiding FPU coupling test... ");
+		if (!boot_cpu_data.fdiv_bug)
+			printk("??? No FDIV bug? Lucky you...\n");
+		else
+			printk("detected FDIV bug though.\n");
+		return;
+	}
 	/*
 	 * check if exception 16 works correctly.. This is truly evil
 	 * code: it disables the high 8 interrupts to make sure that
@@ -173,10 +204,10 @@
 
 		n = K6_BUG_LOOP;
 		f_vide = vide;
-		__asm__ ("rdtsc" : "=a" (d));
+		rdtscl(d);
 		while (n--) 
 			f_vide();
-		__asm__ ("rdtsc" : "=a" (d2));
+		rdtscl(d2);
 		d = d2-d;
 
 		/* Knock these two lines out if it debugs out ok */
@@ -246,6 +277,7 @@
 	    ((Cx86_dir0_msb == 5) || (Cx86_dir0_msb == 3))) {
 		int eax, dummy;
 		unsigned char ccr3, ccr4;
+		__u32 old_cap;
 
 		cli();
 		ccr3 = getCx86(CX86_CCR3);
@@ -257,8 +289,11 @@
 
 		/* we have up to level 1 available on the Cx6x86(L|MX) */
 		boot_cpu_data.cpuid_level = 1;
+		/*  Need to preserve some externally computed capabilities  */
+		old_cap = boot_cpu_data.x86_capability & X86_FEATURE_MTRR;
 		cpuid(1, &eax, &dummy, &dummy,
 		      &boot_cpu_data.x86_capability);
+		boot_cpu_data.x86_capability |= old_cap;
 
 		boot_cpu_data.x86 = (eax >> 8) & 15;
 		/*
@@ -314,6 +349,24 @@
 }
  
 /*
+ * In setup.c's cyrix_model() we have set the boot_cpu_data.coma_bug
+ * on certain processors that we know contain this bug and now we
+ * enable the workaround for it.
+ */
+
+__initfunc(static void check_cyrix_coma(void))
+{
+	if (boot_cpu_data.coma_bug) {
+		unsigned char ccr1;
+		cli();
+		ccr1 = getCx86 (CX86_CCR1);
+		setCx86 (CX86_CCR1, ccr1 | 0x10);
+		sti();
+		printk("Cyrix processor with \"coma bug\" found, workaround enabled\n");
+	}
+}
+ 
+/*
  * Check wether we are able to run this kernel safely on SMP.
  *
  * - In order to run on a i386, we need to be compiled for i386
@@ -371,5 +424,6 @@
 	check_popad();
 	check_amd_k6();
 	check_pentium_f00f();
+	check_cyrix_coma();
 	system_utsname.machine[1] = '0' + boot_cpu_data.x86;
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)