Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/35993 )
Change subject: cpu/x86: Add a prog_run hook to set up caching of XIP stages ......................................................................
cpu/x86: Add a prog_run hook to set up caching of XIP stages
Some platforms lack a non-eviction mode and therefore caching the whole ROM to speed up XIP stages can be dangerous as it could result in eviction if too much of the ROM is being accessed. The solution is to only cache a region, about the size of the stage that the bootblock is about to load: verstage and/or romstage.
CR0.CD bits are not touched to do this, but this seems to work just fine on at least model_1067x and model_6ex.
Change-Id: I94d5771a57ffd74d53db3e35fe169d77d7fbb8cd Signed-off-by: Arthur Heymans arthur@aheymans.xyz --- M src/cpu/x86/Kconfig M src/cpu/x86/mtrr/Makefile.inc A src/cpu/x86/mtrr/xip_cache.c 3 files changed, 73 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/93/35993/1
diff --git a/src/cpu/x86/Kconfig b/src/cpu/x86/Kconfig index a8cf54d..b316c1f 100644 --- a/src/cpu/x86/Kconfig +++ b/src/cpu/x86/Kconfig @@ -78,6 +78,16 @@ depends on !NO_FIXED_XIP_ROM_SIZE default 0x10000
+config SETUP_XIP_CACHE + bool + depends on C_ENVIRONMENT_BOOTBLOCK + depends on !NO_XIP_EARLY_STAGES + help + Select this option to set up an MTRR to cache XIP stages loaded + from the bootblock. This is useful on platforms lacking a + non-eviction mode and therefore need to be careful to avoid + eviction. + config CPU_ADDR_BITS int default 36 diff --git a/src/cpu/x86/mtrr/Makefile.inc b/src/cpu/x86/mtrr/Makefile.inc index caa6e9c..dc914de 100644 --- a/src/cpu/x86/mtrr/Makefile.inc +++ b/src/cpu/x86/mtrr/Makefile.inc @@ -7,3 +7,5 @@ romstage-y += debug.c postcar-y += debug.c ramstage-y += debug.c + +bootblock-$(CONFIG_SETUP_XIP_CACHE) += xip_cache.c diff --git a/src/cpu/x86/mtrr/xip_cache.c b/src/cpu/x86/mtrr/xip_cache.c new file mode 100644 index 0000000..a45944b --- /dev/null +++ b/src/cpu/x86/mtrr/xip_cache.c @@ -0,0 +1,61 @@ +/* + * This file is part of the coreboot project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/cpu.h> +#include <program_loading.h> +#include <commonlib/region.h> +#include <console/console.h> +#include <cpu/x86/mtrr.h> + +#define MAX_ROM_CACHE_SIZE (256 * KiB) + +void platform_prog_run(struct prog *prog) +{ + uint32_t base = region_device_offset(&prog->rdev); + uint32_t size = region_device_sz(&prog->rdev); + uint32_t end = base + size; + int mtrr_num = get_free_var_mtrr(); + uint32_t mtrr_mask_size = 4 * KiB; + struct cpuinfo_x86 cpu_info; + + get_fms(&cpu_info, cpuid_eax(1)); + if (cpu_info.x86 == 0xf) { + printk(BIOS_DEBUG, + "PROG_RUN: CPU does not support caching ROM\n" + "The next stage will run slowly\n"); + return; + } + + if (mtrr_num == -1) { + printk(BIOS_NOTICE, + "PROG_RUN: No MTRR available to cache ROM!\n" + "The next stage will run slowly!\n"); + return; + } + + while (ALIGN_DOWN(base, mtrr_mask_size) + mtrr_mask_size < end) + mtrr_mask_size *= 2; + base = ALIGN_DOWN(base, mtrr_mask_size); + if (mtrr_mask_size > MAX_ROM_CACHE_SIZE) { + printk(BIOS_WARNING, + "PROG_RUN: %dKiB XIP cache requested but limiting to %dKiB!", + mtrr_mask_size, MAX_ROM_CACHE_SIZE); + mtrr_mask_size = MAX_ROM_CACHE_SIZE; + } + + printk(BIOS_DEBUG, + "PROG_RUN: Setting MTRR to cache XIP stage. base: 0x%08x, size: 0x%08x\n", + base, mtrr_mask_size); + + set_var_mtrr(mtrr_num, base, mtrr_mask_size, MTRR_TYPE_WRPROT); +}