summaryrefslogtreecommitdiffstats
path: root/include/asm-i386/bugs.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-i386/bugs.h')
-rw-r--r--include/asm-i386/bugs.h58
1 files changed, 56 insertions, 2 deletions
diff --git a/include/asm-i386/bugs.h b/include/asm-i386/bugs.h
index c9ca53c66..ebd9a4f1a 100644
--- a/include/asm-i386/bugs.h
+++ b/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 @@ __initfunc(static void no_halt(char *s, int *ints))
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 @@ __initfunc(static void check_fpu(void))
#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 @@ __initfunc(static void check_amd_k6(void))
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 @@ __initfunc(static void check_cx686_cpuid(void))
((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 @@ __initfunc(static void check_cx686_cpuid(void))
/* 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 @@ __initfunc(static void check_cyrix_cpu(void))
}
/*
+ * 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 @@ __initfunc(static void check_bugs(void))
check_popad();
check_amd_k6();
check_pentium_f00f();
+ check_cyrix_coma();
system_utsname.machine[1] = '0' + boot_cpu_data.x86;
}