diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index dcc0d698..808e3857 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -68,11 +68,16 @@ inline static uint32_t has_fxsr(void) return (cpu_info.feature1 & CPU_FEATURE_FXSR); } -inline static uint32_t has_xmm(void) +inline static uint32_t has_sse(void) { return (cpu_info.feature1 & CPU_FEATURE_SSE); } +inline static uint32_t has_sse2(void) +{ + return (cpu_info.feature1 & CPU_FEATURE_SSE2); +} + inline static uint32_t has_avx(void) { return (cpu_info.feature2 & CPU_FEATURE_AVX); @@ -124,15 +129,11 @@ inline static int get_return_value(void) { } /* Force strict CPU ordering */ -#ifdef CONFIG_ROCKCREEK -inline static void mb(void) { asm volatile ("lock; addl $0,0(%%esp)" ::: "memory", "cc"); } -inline static void rmb(void) { asm volatile ("lock; addl $0,0(%%esp)" ::: "memory", "cc"); } -inline static void wmb(void) { asm volatile ("lock; addl $0,0(%%esp)" ::: "memory", "cc"); } -#else -inline static void mb(void) { asm volatile("mfence" ::: "memory"); } -inline static void rmb(void) { asm volatile("lfence" ::: "memory"); } -inline static void wmb(void) { asm volatile("sfence" ::: "memory"); } -#endif +typedef void (*func_memory_barrier)(void); + +extern func_memory_barrier mb; +extern func_memory_barrier rmb; +extern func_memory_barrier wmb; /** @brief Read out CPU ID * diff --git a/arch/x86/kernel/isrs.c b/arch/x86/kernel/isrs.c index 5d61321a..69c59c79 100644 --- a/arch/x86/kernel/isrs.c +++ b/arch/x86/kernel/isrs.c @@ -172,7 +172,7 @@ static void fpu_init(union fpu_state* fpu) memset(fx, 0x00, sizeof(i387_fxsave_t)); fx->cwd = 0x37f; - if (has_xmm()) + if (has_sse()) fx->mxcsr = 0x1f80; } else { i387_fsave_t *fp = &fpu->fsave; diff --git a/arch/x86/kernel/processor.c b/arch/x86/kernel/processor.c index 5a0a86c0..c2c90106 100644 --- a/arch/x86/kernel/processor.c +++ b/arch/x86/kernel/processor.c @@ -26,6 +26,16 @@ #include #endif +static void default_mb(void) { asm volatile ("lock; addl $0,0(%%esp)" ::: "memory", "cc"); } + +func_memory_barrier mb = default_mb; +func_memory_barrier rmb = default_mb; +func_memory_barrier wmb = default_mb; + +static void mfence(void) { asm volatile("mfence" ::: "memory"); } +static void lfence(void) { asm volatile("lfence" ::: "memory"); } +static void sfence(void) { asm volatile("sfence" ::: "memory"); } + cpu_info_t cpu_info = { 0, 0 }; static uint32_t cpu_freq = 0; @@ -39,10 +49,21 @@ int cpu_detection(void) cr4 = read_cr4(); if (has_fxsr()) cr4 |= 0x200; // set the OSFXSR bit - if (has_xmm()) + if (has_sse()) cr4 |= 0x400; // set the OSXMMEXCPT bit write_cr4(cr4); + if (has_sse()) { + kprintf("Enable the usage of sfence\n"); + wmb = sfence; + } + + if (has_sse2()) { + kprintf("Enable the usage of lfence and mfence\n"); + rmb = lfence; + mb = mfence; + } + if (has_avx()) kprintf("The CPU owns the Advanced Vector Extensions (AVX). However, MetalSVM doesn't support AVX!\n");