Arthur Heymans | 3134a81 | 2019-11-25 12:20:01 +0100 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | |
| 3 | #include <arch/cpu.h> |
| 4 | #include <cbmem.h> |
| 5 | #include <console/console.h> |
| 6 | #include <cpu/x86/cache.h> |
| 7 | #include <program_loading.h> |
| 8 | #include <types.h> |
| 9 | |
| 10 | bool clflush_supported(void) |
| 11 | { |
| 12 | return (cpuid_edx(1) >> CPUID_FEATURE_CLFLUSH_BIT) & 1; |
| 13 | } |
| 14 | |
Jeremy Compostella | 4a2ce02 | 2023-05-22 17:38:10 -0700 | [diff] [blame] | 15 | void clflush_region(const uintptr_t start, const size_t size) |
Arthur Heymans | 3134a81 | 2019-11-25 12:20:01 +0100 | [diff] [blame] | 16 | { |
| 17 | uintptr_t addr; |
| 18 | const size_t cl_size = ((cpuid_ebx(1) >> 8) & 0xff) * 8; |
| 19 | |
Arthur Heymans | 3134a81 | 2019-11-25 12:20:01 +0100 | [diff] [blame] | 20 | printk(BIOS_SPEW, "CLFLUSH [0x%lx, 0x%lx]\n", start, start + size); |
| 21 | |
| 22 | for (addr = ALIGN_DOWN(start, cl_size); addr < start + size; addr += cl_size) |
| 23 | clflush((void *)addr); |
| 24 | } |
| 25 | |
| 26 | /* |
| 27 | * For each segment of a program loaded this function is called |
| 28 | * to invalidate caches for the addresses of the loaded segment |
| 29 | */ |
| 30 | void arch_segment_loaded(uintptr_t start, size_t size, int flags) |
| 31 | { |
| 32 | /* INVD is only called in postcar stage so we only need |
| 33 | to make sure that our code hits dram during romstage. */ |
| 34 | if (!ENV_CACHE_AS_RAM) |
| 35 | return; |
Arthur Heymans | a2bc254 | 2021-05-29 08:10:49 +0200 | [diff] [blame^] | 36 | if (!ENV_RAMINIT) |
Arthur Heymans | 3134a81 | 2019-11-25 12:20:01 +0100 | [diff] [blame] | 37 | return; |
| 38 | if (!CONFIG(POSTCAR_STAGE)) |
| 39 | return; |
| 40 | if (!CONFIG(X86_CLFLUSH_CAR)) |
| 41 | return; |
| 42 | if (flags != SEG_FINAL) |
| 43 | return; |
| 44 | |
| 45 | /* |
| 46 | * The assumption is made here that DRAM is only ready after cbmem |
| 47 | * is initialized, to avoid flushing when loading earlier things (e.g. FSP, ...) |
| 48 | */ |
| 49 | if (!cbmem_online()) |
| 50 | return; |
| 51 | |
Jeremy Compostella | 4a2ce02 | 2023-05-22 17:38:10 -0700 | [diff] [blame] | 52 | if (clflush_supported()) |
| 53 | clflush_region(start, size); |
| 54 | else |
| 55 | printk(BIOS_DEBUG, "Not flushing cache to RAM, CLFLUSH not supported\n"); |
Arthur Heymans | 3134a81 | 2019-11-25 12:20:01 +0100 | [diff] [blame] | 56 | } |