|
@@ -64,6 +64,29 @@ void fpu__init_check_bugs(void)
|
|
|
check_fpu();
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * The earliest FPU detection code:
|
|
|
+ */
|
|
|
+static void fpu__init_system_early_generic(struct cpuinfo_x86 *c)
|
|
|
+{
|
|
|
+ unsigned long cr0;
|
|
|
+ u16 fsw, fcw;
|
|
|
+
|
|
|
+ fsw = fcw = 0xffff;
|
|
|
+
|
|
|
+ cr0 = read_cr0();
|
|
|
+ cr0 &= ~(X86_CR0_TS | X86_CR0_EM);
|
|
|
+ write_cr0(cr0);
|
|
|
+
|
|
|
+ asm volatile("fninit ; fnstsw %0 ; fnstcw %1"
|
|
|
+ : "+m" (fsw), "+m" (fcw));
|
|
|
+
|
|
|
+ if (fsw == 0 && (fcw & 0x103f) == 0x003f)
|
|
|
+ set_cpu_cap(c, X86_FEATURE_FPU);
|
|
|
+ else
|
|
|
+ clear_cpu_cap(c, X86_FEATURE_FPU);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Boot time FPU feature detection code:
|
|
|
*/
|
|
@@ -269,23 +292,7 @@ __setup("no387", no_387);
|
|
|
*/
|
|
|
void fpu__detect(struct cpuinfo_x86 *c)
|
|
|
{
|
|
|
- unsigned long cr0;
|
|
|
- u16 fsw, fcw;
|
|
|
-
|
|
|
- fsw = fcw = 0xffff;
|
|
|
-
|
|
|
- cr0 = read_cr0();
|
|
|
- cr0 &= ~(X86_CR0_TS | X86_CR0_EM);
|
|
|
- write_cr0(cr0);
|
|
|
-
|
|
|
- asm volatile("fninit ; fnstsw %0 ; fnstcw %1"
|
|
|
- : "+m" (fsw), "+m" (fcw));
|
|
|
-
|
|
|
- if (fsw == 0 && (fcw & 0x103f) == 0x003f)
|
|
|
- set_cpu_cap(c, X86_FEATURE_FPU);
|
|
|
- else
|
|
|
- clear_cpu_cap(c, X86_FEATURE_FPU);
|
|
|
-
|
|
|
+ fpu__init_system_early_generic(c);
|
|
|
fpu__init_system();
|
|
|
/* The final cr0 value is set later, in fpu_init() */
|
|
|
}
|