diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cpu/x86/cache/cache.c | 12 | ||||
-rw-r--r-- | src/cpu/x86/mp_init.c | 11 | ||||
-rw-r--r-- | src/include/cpu/x86/cache.h | 2 |
3 files changed, 14 insertions, 11 deletions
diff --git a/src/cpu/x86/cache/cache.c b/src/cpu/x86/cache/cache.c index d02d6d4427..6413660b83 100644 --- a/src/cpu/x86/cache/cache.c +++ b/src/cpu/x86/cache/cache.c @@ -12,16 +12,11 @@ bool clflush_supported(void) return (cpuid_edx(1) >> CPUID_FEATURE_CLFLUSH_BIT) & 1; } -static void clflush_region(const uintptr_t start, const size_t size) +void clflush_region(const uintptr_t start, const size_t size) { uintptr_t addr; const size_t cl_size = ((cpuid_ebx(1) >> 8) & 0xff) * 8; - if (!clflush_supported()) { - printk(BIOS_DEBUG, "Not flushing cache to RAM, CLFLUSH not supported\n"); - return; - } - printk(BIOS_SPEW, "CLFLUSH [0x%lx, 0x%lx]\n", start, start + size); for (addr = ALIGN_DOWN(start, cl_size); addr < start + size; addr += cl_size) @@ -54,5 +49,8 @@ void arch_segment_loaded(uintptr_t start, size_t size, int flags) if (!cbmem_online()) return; - clflush_region(start, size); + if (clflush_supported()) + clflush_region(start, size); + else + printk(BIOS_DEBUG, "Not flushing cache to RAM, CLFLUSH not supported\n"); } diff --git a/src/cpu/x86/mp_init.c b/src/cpu/x86/mp_init.c index 28d6092d0d..6809f812d7 100644 --- a/src/cpu/x86/mp_init.c +++ b/src/cpu/x86/mp_init.c @@ -364,6 +364,13 @@ static atomic_t *load_sipi_vector(struct mp_params *mp_params) ap_count = &sp->ap_count; atomic_set(ap_count, 0); + /* Make sure SIPI data hits RAM so the APs that come up will see the + startup code even if the caches are disabled. */ + if (clflush_supported()) + clflush_region((uintptr_t)mod_loc, module_size); + else + wbinvd(); + return ap_count; } @@ -626,10 +633,6 @@ static enum cb_err mp_init(struct bus *cpu_bus, struct mp_params *p) if (ap_count == NULL) return CB_ERR; - /* Make sure SIPI data hits RAM so the APs that come up will see - * the startup code even if the caches are disabled. */ - wbinvd(); - /* Start the APs providing number of APs and the cpus_entered field. */ global_num_aps = p->num_cpus - 1; if (start_aps(cpu_bus, global_num_aps, ap_count) != CB_SUCCESS) { diff --git a/src/include/cpu/x86/cache.h b/src/include/cpu/x86/cache.h index 63703a7871..d35c4e7fd0 100644 --- a/src/include/cpu/x86/cache.h +++ b/src/include/cpu/x86/cache.h @@ -13,6 +13,7 @@ #if !defined(__ASSEMBLER__) #include <stdbool.h> +#include <stddef.h> static inline void wbinvd(void) { @@ -30,6 +31,7 @@ static inline void clflush(void *addr) } bool clflush_supported(void); +void clflush_region(const uintptr_t start, const size_t size); /* The following functions require the __always_inline due to AMD * function STOP_CAR_AND_CPU that disables cache as |