summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cpu/x86/cache/cache.c12
-rw-r--r--src/cpu/x86/mp_init.c11
-rw-r--r--src/include/cpu/x86/cache.h2
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