From a0ec31775356309e217a11845ce08577449a54a4 Mon Sep 17 00:00:00 2001 From: Adrian-Ken Rueegsegger Date: Tue, 21 Apr 2015 23:09:01 +0200 Subject: [PATCH] hw_x86_64: Explicitly set all FPU-related CR flags Perform all FPU-related setup in the Cpu class' init_fpu function instead of the general system bring-up assembly code. Set all required control register 0 and 4 flags according to Intel SDM Vol. 3A, sections 9.2 and 9.6 instead of only enabling FPU error reporting and OSFXSR. --- .../src/core/include/spec/x86/cpu_support.h | 21 ++++++++++++++++--- .../src/core/spec/x86_64/kernel/crt0.s | 6 ++---- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/repos/base-hw/src/core/include/spec/x86/cpu_support.h b/repos/base-hw/src/core/include/spec/x86/cpu_support.h index cb1a2511c5..d5e58cf29b 100644 --- a/repos/base-hw/src/core/include/spec/x86/cpu_support.h +++ b/repos/base-hw/src/core/include/spec/x86/cpu_support.h @@ -256,10 +256,25 @@ class Genode::Cpu static void _enable_fpu() { asm volatile ("clts"); } /** - * Initialize FPU without checking for pending unmasked floating-point - * exceptions. + * Initialize FPU with SSE extensions by setting required CR0 and CR4 + * bits to configure the FPU environment according to Intel SDM Vol. + * 3A, sections 9.2 and 9.6. */ - static void _init_fpu() { asm volatile ("fninit"); } + static void _init_fpu() + { + Cr0::access_t cr0_value = Cr0::read(); + Cr4::access_t cr4_value = Cr4::read(); + + Cr0::Mp::set(cr0_value); + Cr0::Em::clear(cr0_value); + Cr0::Ts::set(cr0_value); + Cr0::Ne::set(cr0_value); + Cr0::write(cr0_value); + + Cr4::Osfxsr::set(cr4_value); + Cr4::Osxmmexcpt::set(cr4_value); + Cr4::write(cr4_value); + } /** * Returns True if the FPU is enabled. diff --git a/repos/base-hw/src/core/spec/x86_64/kernel/crt0.s b/repos/base-hw/src/core/spec/x86_64/kernel/crt0.s index 8cbeb2a069..5dffb5add4 100644 --- a/repos/base-hw/src/core/spec/x86_64/kernel/crt0.s +++ b/repos/base-hw/src/core/spec/x86_64/kernel/crt0.s @@ -41,10 +41,9 @@ xor %eax, %eax rep stosl - /* Enable PAE (prerequisite for IA-32e mode) and OSFXSR */ + /* Enable PAE (prerequisite for IA-32e mode) */ movl %cr4, %eax btsl $5, %eax - btsl $9, %eax movl %eax, %cr4 /* Load initial pagetables */ @@ -58,9 +57,8 @@ btsl $11, %eax wrmsr - /* Enable paging, write protection, caching and FPU error reporting */ + /* Enable paging, write protection and caching */ movl %cr0, %eax - btsl $5, %eax btsl $16, %eax btrl $29, %eax btrl $30, %eax