[haiku-commits] haiku: hrev43673 - src/system/kernel/arch/x86 headers/private/kernel/arch/x86

  • From: kallisti5@xxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 20 Jan 2012 22:05:23 +0100 (CET)

hrev43673 adds 1 changeset to branch 'master'
old head: 67f45bfdf214750c67eca956df9289a2044e4984
new head: 8dd1e875c1d3735627166c6639078ae4419e7918

----------------------------------------------------------------------------

8dd1e87: kernel: Fix FPU SSE + MMX instruction usage.
  
  * Rename init_sse to init_fpu and handle FPU setup.
  * Stop trying to set up FPU before VM init.
    We tried to set up the FPU before VM init, then
    set it up again after VM init with SSE extensions,
    this caused SSE and MMX applications to crash.
  * Be more logical in FPU setup by detecting CPU flag prior
    to enabling FPU. (it's unlikely Haiku will run on
    a processor without a fpu... but lets be consistant)
  * SSE2 gcc code now runs (faster even) without GPF
  * tqh confirms his previously crashing mmx code now works
  * The non-SSE FPU enable after VM init needs tested!

                          [ Alexander von Gluck IV <kallisti5@xxxxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev43673
Commit:      8dd1e875c1d3735627166c6639078ae4419e7918
URL:         http://cgit.haiku-os.org/haiku/commit/?id=8dd1e87
Author:      Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Date:        Fri Jan 20 21:06:01 2012 UTC

----------------------------------------------------------------------------

4 files changed, 27 insertions(+), 8 deletions(-)
headers/private/kernel/arch/x86/arch_cpu.h |    1 +
src/system/kernel/arch/x86/arch_cpu.cpp    |   23 +++++++++++++++++------
src/system/kernel/arch/x86/arch_smp.cpp    |    5 +++--
src/system/kernel/arch/x86/arch_x86.S      |    6 ++++++

----------------------------------------------------------------------------

diff --git a/headers/private/kernel/arch/x86/arch_cpu.h 
b/headers/private/kernel/arch/x86/arch_cpu.h
index c88ea9b..df9f693 100644
--- a/headers/private/kernel/arch/x86/arch_cpu.h
+++ b/headers/private/kernel/arch/x86/arch_cpu.h
@@ -334,6 +334,7 @@ void i386_fnsave(void* fpuState);
 void i386_fxsave(void* fpuState);
 void i386_frstor(const void* fpuState);
 void i386_fxrstor(const void* fpuState);
+void i386_noop_swap(void* oldFpuState, const void* newFpuState);
 void i386_fnsave_swap(void* oldFpuState, const void* newFpuState);
 void i386_fxsave_swap(void* oldFpuState, const void* newFpuState);
 uint32 x86_read_ebp();
diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp 
b/src/system/kernel/arch/x86/arch_cpu.cpp
index 035c352..e508513 100644
--- a/src/system/kernel/arch/x86/arch_cpu.cpp
+++ b/src/system/kernel/arch/x86/arch_cpu.cpp
@@ -300,13 +300,24 @@ x86_set_mtrrs(uint8 defaultType, const x86_mtrr_info* 
infos, uint32 count)
 
 
 extern "C" void
-init_sse(void)
+init_fpu(void)
 {
+       if (!x86_check_feature(IA32_FEATURE_FPU, FEATURE_COMMON)) {
+               // No FPU... time to install one in your 386?
+               dprintf("Warning: CPU has no reported FPU.\n");
+               gX86SwapFPUFunc = i386_noop_swap;
+               return;
+       }
+
        if (!x86_check_feature(IA32_FEATURE_SSE, FEATURE_COMMON)
                || !x86_check_feature(IA32_FEATURE_FXSR, FEATURE_COMMON)) {
-               // we don't have proper SSE support
+               dprintf("CPU has no SSE... just enabling FPU.\n");
+               // we don't have proper SSE support, just enable FPU
+               x86_write_cr0(x86_read_cr0() & ~(CR0_FPU_EMULATION | 
CR0_MONITOR_FPU));
+               gX86SwapFPUFunc = i386_fnsave_swap;
                return;
        }
+       dprintf("CPU has SSE... enabling FXSR and XMM.\n");
 
        // enable OS support for SSE
        x86_write_cr4(x86_read_cr4() | CR4_OS_FXSR | CR4_OS_XMM_EXCEPTION);
@@ -658,8 +669,8 @@ x86_double_fault_get_cpu(void)
 status_t
 arch_cpu_preboot_init_percpu(kernel_args *args, int cpu)
 {
-       x86_write_cr0(x86_read_cr0() & ~(CR0_FPU_EMULATION | CR0_MONITOR_FPU));
-       gX86SwapFPUFunc = i386_fnsave_swap;
+       // A simple nop FPU call until init_fpu
+       gX86SwapFPUFunc = i386_noop_swap;
 
        // On SMP system we want to synchronize the CPUs' TSCs, so system_time()
        // will return consistent values.
@@ -791,8 +802,8 @@ arch_cpu_init_post_vm(kernel_args *args)
                        DT_DATA_WRITEABLE, DPL_USER);
        }
 
-       // setup SSE2/3 support
-       init_sse();
+       // setup FPU and SSE if supported
+       init_fpu();
 
        return B_OK;
 }
diff --git a/src/system/kernel/arch/x86/arch_smp.cpp 
b/src/system/kernel/arch/x86/arch_smp.cpp
index dd67bea..4f4e53a 100644
--- a/src/system/kernel/arch/x86/arch_smp.cpp
+++ b/src/system/kernel/arch/x86/arch_smp.cpp
@@ -36,7 +36,7 @@
 static uint32 sCPUAPICIds[B_MAX_CPU_COUNT];
 static uint32 sAPICVersions[B_MAX_CPU_COUNT];
 
-extern "C" void init_sse(void);
+extern "C" void init_fpu(void);
 
 
 static int32
@@ -107,7 +107,8 @@ arch_smp_per_cpu_init(kernel_args *args, int32 cpu)
        TRACE(("arch_smp_init_percpu: setting up the apic on cpu %ld\n", cpu));
        apic_per_cpu_init(args, cpu);
 
-       init_sse();
+       // setup FPU and SSE if supported
+       init_fpu();
 
        return B_OK;
 }
diff --git a/src/system/kernel/arch/x86/arch_x86.S 
b/src/system/kernel/arch/x86/arch_x86.S
index a0c60ff..28611fe 100644
--- a/src/system/kernel/arch/x86/arch_x86.S
+++ b/src/system/kernel/arch/x86/arch_x86.S
@@ -55,6 +55,12 @@ FUNCTION(i386_fxrstor):
        ret
 FUNCTION_END(i386_fxrstor)
 
+/* void i386_noop_swap(void *old_fpu_state, const void *new_fpu_state); */
+FUNCTION(i386_noop_swap):
+       nop
+       ret
+FUNCTION_END(i386_noop_swap)
+
 /* void i386_fsave_swap(void *old_fpu_state, const void *new_fpu_state); */
 FUNCTION(i386_fnsave_swap):
        movl    4(%esp),%eax


Other related posts:

  • » [haiku-commits] haiku: hrev43673 - src/system/kernel/arch/x86 headers/private/kernel/arch/x86 - kallisti5