diff options
author | Marshall Dawson <marshalldawson3rd@gmail.com> | 2018-01-29 18:08:16 -0700 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2018-02-07 16:24:55 +0000 |
commit | f3c57a7c28a3c66d2ade3e2b3108fd58b60c2a7c (patch) | |
tree | 61525ac36d3d5044860b7e18f2b48b9ea9d32e67 /src/soc/amd/stoneyridge/ramtop.c | |
parent | 8d6e0e0a72ed81d44ba61add0c2aab55bb217412 (diff) |
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 <marshalldawson3rd@gmail.com>
Reviewed-on: https://review.coreboot.org/23519
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/soc/amd/stoneyridge/ramtop.c')
-rw-r--r-- | src/soc/amd/stoneyridge/ramtop.c | 34 |
1 files changed, 34 insertions, 0 deletions
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 <arch/io.h> #include <cpu/x86/msr.h> #include <cpu/amd/mtrr.h> +#include <cpu/amd/amdfam15.h> #include <cbmem.h> +#include <stage_cache.h> #include <soc/northbridge.h> #include <soc/southbridge.h> @@ -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; |