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:
parent
8d6e0e0a72
commit
f3c57a7c28
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue