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>
This commit is contained in:
Marshall Dawson 2018-01-29 18:08:16 -07:00 committed by Martin Roth
parent 8d6e0e0a72
commit f3c57a7c28
2 changed files with 36 additions and 1 deletions

View File

@ -55,6 +55,7 @@ config CPU_SPECIFIC_OPTIONS
select BOOTBLOCK_CONSOLE select BOOTBLOCK_CONSOLE
select BOOT_DEVICE_SUPPORTS_WRITES if BOOT_DEVICE_SPI_FLASH select BOOT_DEVICE_SUPPORTS_WRITES if BOOT_DEVICE_SPI_FLASH
select RELOCATABLE_MODULES select RELOCATABLE_MODULES
select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM
select PARALLEL_MP select PARALLEL_MP
select PARALLEL_MP_AP_WORK select PARALLEL_MP_AP_WORK
select HAVE_SMI_HANDLER select HAVE_SMI_HANDLER
@ -295,7 +296,7 @@ config SMM_TSEG_SIZE
config SMM_RESERVED_SIZE config SMM_RESERVED_SIZE
hex hex
default 0x100000 default 0x140000
config ACPI_CPU_STRING config ACPI_CPU_STRING
string string

View File

@ -20,7 +20,9 @@
#include <arch/io.h> #include <arch/io.h>
#include <cpu/x86/msr.h> #include <cpu/x86/msr.h>
#include <cpu/amd/mtrr.h> #include <cpu/amd/mtrr.h>
#include <cpu/amd/amdfam15.h>
#include <cbmem.h> #include <cbmem.h>
#include <stage_cache.h>
#include <soc/northbridge.h> #include <soc/northbridge.h>
#include <soc/southbridge.h> #include <soc/southbridge.h>
@ -56,12 +58,43 @@ static size_t smm_region_size(void)
return CONFIG_SMM_TSEG_SIZE; 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) void smm_region_info(void **start, size_t *size)
{ {
*start = (void *)smm_region_start(); *start = (void *)smm_region_start();
*size = smm_region_size(); *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) int smm_subregion(int sub, void **start, size_t *size)
{ {
uintptr_t sub_base; 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. */ /* External cache is in the middle of TSEG. */
sub_base += sub_size - cache_size; sub_base += sub_size - cache_size;
sub_size = cache_size; sub_size = cache_size;
clear_tvalid();
break; break;
default: default:
return -1; return -1;