add automatic detection of fence instructions

This commit is contained in:
Stefan Lankes 2012-07-17 22:33:29 +02:00
parent c32a30726a
commit f83f29abb7
3 changed files with 34 additions and 12 deletions

View file

@ -68,11 +68,16 @@ inline static uint32_t has_fxsr(void)
return (cpu_info.feature1 & CPU_FEATURE_FXSR); 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); 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) inline static uint32_t has_avx(void)
{ {
return (cpu_info.feature2 & CPU_FEATURE_AVX); return (cpu_info.feature2 & CPU_FEATURE_AVX);
@ -124,15 +129,11 @@ inline static int get_return_value(void) {
} }
/* Force strict CPU ordering */ /* Force strict CPU ordering */
#ifdef CONFIG_ROCKCREEK typedef void (*func_memory_barrier)(void);
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"); } extern func_memory_barrier mb;
inline static void wmb(void) { asm volatile ("lock; addl $0,0(%%esp)" ::: "memory", "cc"); } extern func_memory_barrier rmb;
#else extern func_memory_barrier wmb;
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
/** @brief Read out CPU ID /** @brief Read out CPU ID
* *

View file

@ -172,7 +172,7 @@ static void fpu_init(union fpu_state* fpu)
memset(fx, 0x00, sizeof(i387_fxsave_t)); memset(fx, 0x00, sizeof(i387_fxsave_t));
fx->cwd = 0x37f; fx->cwd = 0x37f;
if (has_xmm()) if (has_sse())
fx->mxcsr = 0x1f80; fx->mxcsr = 0x1f80;
} else { } else {
i387_fsave_t *fp = &fpu->fsave; i387_fsave_t *fp = &fpu->fsave;

View file

@ -26,6 +26,16 @@
#include <asm/RCCE_lib.h> #include <asm/RCCE_lib.h>
#endif #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 }; cpu_info_t cpu_info = { 0, 0 };
static uint32_t cpu_freq = 0; static uint32_t cpu_freq = 0;
@ -39,10 +49,21 @@ int cpu_detection(void)
cr4 = read_cr4(); cr4 = read_cr4();
if (has_fxsr()) if (has_fxsr())
cr4 |= 0x200; // set the OSFXSR bit cr4 |= 0x200; // set the OSFXSR bit
if (has_xmm()) if (has_sse())
cr4 |= 0x400; // set the OSXMMEXCPT bit cr4 |= 0x400; // set the OSXMMEXCPT bit
write_cr4(cr4); 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()) if (has_avx())
kprintf("The CPU owns the Advanced Vector Extensions (AVX). However, MetalSVM doesn't support AVX!\n"); kprintf("The CPU owns the Advanced Vector Extensions (AVX). However, MetalSVM doesn't support AVX!\n");