From f3c57a7c28a3c66d2ade3e2b3108fd58b60c2a7c Mon Sep 17 00:00:00 2001 From: Marshall Dawson Date: Mon, 29 Jan 2018 18:08:16 -0700 Subject: amd/stoneyridge: Put stage cache into TSEG Add a function to allow an external region to be located in TSEG. Select the option to use memory outside of cbmem. Increase the size reserved in TSEG. Change-Id: Ic1073af04475d862753136c9e14e2b2dde31fe66 Signed-off-by: Marshall Dawson Reviewed-on: https://review.coreboot.org/23519 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin --- src/soc/amd/stoneyridge/Kconfig | 3 ++- src/soc/amd/stoneyridge/ramtop.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/soc/amd/stoneyridge/Kconfig b/src/soc/amd/stoneyridge/Kconfig index 148ca3ff04..79755239d8 100644 --- a/src/soc/amd/stoneyridge/Kconfig +++ b/src/soc/amd/stoneyridge/Kconfig @@ -55,6 +55,7 @@ config CPU_SPECIFIC_OPTIONS select BOOTBLOCK_CONSOLE select BOOT_DEVICE_SUPPORTS_WRITES if BOOT_DEVICE_SPI_FLASH select RELOCATABLE_MODULES + select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM select PARALLEL_MP select PARALLEL_MP_AP_WORK select HAVE_SMI_HANDLER @@ -295,7 +296,7 @@ config SMM_TSEG_SIZE config SMM_RESERVED_SIZE hex - default 0x100000 + default 0x140000 config ACPI_CPU_STRING string diff --git a/src/soc/amd/stoneyridge/ramtop.c b/src/soc/amd/stoneyridge/ramtop.c index e676465ce7..24386edba3 100644 --- a/src/soc/amd/stoneyridge/ramtop.c +++ b/src/soc/amd/stoneyridge/ramtop.c @@ -20,7 +20,9 @@ #include #include #include +#include #include +#include #include #include @@ -56,12 +58,43 @@ static size_t smm_region_size(void) return CONFIG_SMM_TSEG_SIZE; } +void stage_cache_external_region(void **base, size_t *size) +{ + if (smm_subregion(SMM_SUBREGION_CACHE, base, size)) { + printk(BIOS_ERR, "ERROR: No cache SMM subregion.\n"); + *base = NULL; + *size = 0; + } +} + void smm_region_info(void **start, size_t *size) { *start = (void *)smm_region_start(); *size = smm_region_size(); } +/* + * For data stored in TSEG, ensure TValid is clear so R/W access can reach + * the DRAM when not in SMM. + */ +static void clear_tvalid(void) +{ + msr_t hwcr = rdmsr(HWCR_MSR); + msr_t mask = rdmsr(MSR_SMM_MASK); + int tvalid = !!(mask.lo & SMM_TSEG_VALID); + + if (hwcr.lo & SMM_LOCK) { + if (!tvalid) /* not valid but locked means still accessible */ + return; + + printk(BIOS_ERR, "Error: can't clear TValid, already locked\n"); + return; + } + + mask.lo &= ~SMM_TSEG_VALID; + wrmsr(MSR_SMM_MASK, mask); +} + int smm_subregion(int sub, void **start, size_t *size) { uintptr_t sub_base; @@ -82,6 +115,7 @@ int smm_subregion(int sub, void **start, size_t *size) /* External cache is in the middle of TSEG. */ sub_base += sub_size - cache_size; sub_size = cache_size; + clear_tvalid(); break; default: return -1; -- cgit v1.2.3