diff --git a/arch/x86/core/Kconfig.ia32 b/arch/x86/core/Kconfig.ia32 index b408ec43068..8532535f2d6 100644 --- a/arch/x86/core/Kconfig.ia32 +++ b/arch/x86/core/Kconfig.ia32 @@ -170,4 +170,12 @@ config X86_USE_THREAD_LOCAL_STORAGE help Internal config to enable thread local storage. +config X86_MFENCE_INSTRUCTION_SUPPORTED + bool "X86 MFENCE instruction supported" + default y + depends on CACHE_MANAGEMENT + help + Set n to disable the use of MFENCE instruction in arch_dcache_flush() + for X86 CPUs have CLFLUSH instruction but no MFENCE + endif # !X86_64 diff --git a/arch/x86/core/cache.c b/arch/x86/core/cache.c index ca049504288..0d6322247cb 100644 --- a/arch/x86/core/cache.c +++ b/arch/x86/core/cache.c @@ -33,20 +33,24 @@ static void arch_dcache_flush(void *start_addr, size_t size) { size_t line_size = sys_cache_data_line_size_get(); uintptr_t start = (uintptr_t)start_addr; - uintptr_t end; + uintptr_t end = start + size; if (line_size == 0U) { return; } - size = ROUND_UP(size, line_size); - end = start + size; + end = ROUND_UP(end, line_size); for (; start < end; start += line_size) { - __asm__ volatile("clflush %0;\n\t" : : "m"(start)); + __asm__ volatile("clflush %0;\n\t" : + "+m"(*(volatile char *)start)); } - __asm__ volatile("mfence;\n\t"); +#if defined(CONFIG_X86_MFENCE_INSTRUCTION_SUPPORTED) + __asm__ volatile("mfence;\n\t":::"memory"); +#else + __asm__ volatile("lock; addl $0,-4(%%esp);\n\t":::"memory", "cc"); +#endif } int arch_dcache_range(void *addr, size_t size, int op)