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);
}
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
*

View file

@ -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;

View file

@ -26,6 +26,16 @@
#include <asm/RCCE_lib.h>
#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");