intel/common: use external stage cache for fsp_ramstage

The fsp_ramstage.c code was not taking advantage of the stage
cache which does all the accounting and calculation work for
the caller. Remove the open coded logic and use the provided
infrastructure. Using said infrastructure means there's no
need for the FSP_CACHE_SIZE Kconfig variable. Therefore, remove
it.

BUG=chrome-os-partner:43636
BRANCH=None
TEST=Built, booted, suspended, and resumed on glados.

Original-Change-Id: I4363823c825b4a700205769f109ff9cf0d78b897
Original-Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/290831
Original-Reviewed-by: Leroy P Leahy <leroy.p.leahy@intel.com>
Original-Reviewed-by: Duncan Laurie <dlaurie@chromium.org>

Change-Id: Ifd3cc4a538daac687949c5f4cab2c687368d6787
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/11196
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
Aaron Durbin 2015-08-05 12:26:56 -05:00
parent a0429b6f3c
commit abf87a25f2
2 changed files with 27 additions and 128 deletions

View File

@ -44,15 +44,6 @@ config DISPLAY_SMM_MEMORY_MAP
bool "SMM: Display the SMM memory map" bool "SMM: Display the SMM memory map"
default n default n
config FSP_CACHE_SIZE
hex "FSP Cache Size in bytes"
default 0
help
Size of the region in SMM used to cache the FSP binary. This region
size value is used to split the SMM_RESERVED_SIZE config value
into a region specifically for FSP. The remaining region is for
ramstage.
config SOC_INTEL_COMMON_FSP_RAM_INIT config SOC_INTEL_COMMON_FSP_RAM_INIT
bool "FSP: Use the common raminit.c module" bool "FSP: Use the common raminit.c module"
default n default n

View File

@ -40,9 +40,9 @@ __attribute__((weak)) void soc_after_silicon_init(void)
* SMM Memory Map: * SMM Memory Map:
* *
* +--------------------------+ smm_region_size() ----. * +--------------------------+ smm_region_size() ----.
* | FSP Cache | CONFIG_FSP_CACHE_SIZE | * | FSP Cache | |
* +--------------------------+ | * +--------------------------+ |
* | SMM Ramstage Cache | + CONFIG_SMM_RESERVED_SIZE * | SMM Stage Cache | + CONFIG_SMM_RESERVED_SIZE
* +--------------------------+ ---------------------' * +--------------------------+ ---------------------'
* | SMM Code | * | SMM Code |
* +--------------------------+ smm_base * +--------------------------+ smm_base
@ -56,42 +56,27 @@ void stage_cache_external_region(void **base, size_t *size)
/* Determine the location of the ramstage cache */ /* Determine the location of the ramstage cache */
smm_region((void **)&cache_base, &cache_size); smm_region((void **)&cache_base, &cache_size);
*size = CONFIG_SMM_RESERVED_SIZE - CONFIG_FSP_CACHE_SIZE; *size = CONFIG_SMM_RESERVED_SIZE;
*base = &cache_base[cache_size - CONFIG_SMM_RESERVED_SIZE]; *base = &cache_base[cache_size - CONFIG_SMM_RESERVED_SIZE];
} }
static void *smm_fsp_cache_base(size_t *size)
{
size_t cache_size;
u8 *cache_base;
/* Determine the location of the FSP cache */
stage_cache_external_region((void **)&cache_base, &cache_size);
*size = CONFIG_FSP_CACHE_SIZE;
return &cache_base[cache_size];
}
/* Display SMM memory map */ /* Display SMM memory map */
static void smm_memory_map(void) static void smm_memory_map(void)
{ {
u8 *smm_base; u8 *smm_base;
size_t smm_bytes; size_t smm_bytes;
size_t smm_code_bytes; size_t smm_code_bytes;
u8 *fsp_cache; u8 *ext_cache;
size_t fsp_cache_bytes; size_t ext_cache_bytes;
u8 *ramstage_cache;
size_t ramstage_cache_bytes;
u8 *smm_reserved; u8 *smm_reserved;
size_t smm_reserved_bytes; size_t smm_reserved_bytes;
/* Locate the SMM regions */ /* Locate the SMM regions */
smm_region((void **)&smm_base, &smm_bytes); smm_region((void **)&smm_base, &smm_bytes);
fsp_cache = smm_fsp_cache_base(&fsp_cache_bytes); stage_cache_external_region((void **)&ext_cache, &ext_cache_bytes);
stage_cache_external_region((void **)&ramstage_cache, &ramstage_cache_bytes); smm_code_bytes = ext_cache - smm_base;
smm_code_bytes = ramstage_cache - smm_base; smm_reserved_bytes = smm_bytes - ext_cache_bytes - smm_code_bytes;
smm_reserved = fsp_cache + fsp_cache_bytes; smm_reserved = smm_base + smm_bytes - smm_reserved_bytes;
smm_reserved_bytes = smm_bytes - fsp_cache_bytes - ramstage_cache_bytes
- smm_code_bytes;
/* Display the SMM regions */ /* Display the SMM regions */
printk(BIOS_SPEW, "\nLocation SMM Memory Map Offset\n"); printk(BIOS_SPEW, "\nLocation SMM Memory Map Offset\n");
@ -102,79 +87,12 @@ static void smm_memory_map(void)
} }
printk(BIOS_SPEW, "0x%p +--------------------------+ 0x%08x\n", printk(BIOS_SPEW, "0x%p +--------------------------+ 0x%08x\n",
smm_reserved, (u32)(smm_reserved - smm_base)); smm_reserved, (u32)(smm_reserved - smm_base));
printk(BIOS_SPEW, " | FSP binary cache |\n"); printk(BIOS_SPEW, " | external cache |\n");
printk(BIOS_SPEW, "0x%p +--------------------------+ 0x%08x\n", printk(BIOS_SPEW, "0x%p +--------------------------+ 0x%08x\n",
fsp_cache, (u32)(fsp_cache - smm_base)); ext_cache, (u32)(ext_cache - smm_base));
printk(BIOS_SPEW, " | ramstage cache |\n");
printk(BIOS_SPEW, "0x%p +--------------------------+ 0x%08x\n",
ramstage_cache, (u32)(ramstage_cache - smm_base));
printk(BIOS_SPEW, " | SMM code |\n"); printk(BIOS_SPEW, " | SMM code |\n");
printk(BIOS_SPEW, "0x%p +--------------------------+ 0x%08x\n", printk(BIOS_SPEW, "0x%p +--------------------------+ 0x%08x\n",
smm_base, 0); smm_base, 0);
printk(BIOS_ERR, "\nCONFIG_FSP_CACHE_SIZE: 0x%08x bytes\n\n",
CONFIG_FSP_CACHE_SIZE);
}
struct smm_fsp_cache_header {
void *start;
size_t size;
FSP_INFO_HEADER *fih;
};
/* SoC implementation for caching support code. */
static void soc_save_support_code(void *start, size_t size,
FSP_INFO_HEADER *fih)
{
u8 *fsp_cache;
size_t fsp_cache_length;
struct smm_fsp_cache_header *header;
size_t smm_fsp_cache_length;
if (IS_ENABLED(CONFIG_DISPLAY_SMM_MEMORY_MAP))
smm_memory_map();
/* Locate the FSP cache in SMM */
fsp_cache = smm_fsp_cache_base(&smm_fsp_cache_length);
/* Initialize the FSP cache header */
header = (struct smm_fsp_cache_header *)fsp_cache;
fsp_cache += sizeof(*header);
header->start = start;
header->size = size;
header->fih = fih;
/* Validate the CONFIG_FSP_CACHE_SIZE value */
fsp_cache_length = sizeof(*header) + size;
if (smm_fsp_cache_length < fsp_cache_length) {
printk(BIOS_ERR, "CONFIG_FSP_CACHE_SIZE < 0x%08x bytes\n",
(u32)fsp_cache_length);
die("ERROR: Insufficent space to cache FSP binary!\n");
}
/* Copy the FSP binary into the SMM region for safe keeping */
memcpy(fsp_cache, start, size);
}
/* SoC implementation for restoring support code after S3 resume. Returns
* previously passed fih pointer from soc_save_support_code(). */
static FSP_INFO_HEADER *soc_restore_support_code(void)
{
u8 *fsp_cache;
struct smm_fsp_cache_header *header;
size_t smm_fsp_cache_length;
/* Locate the FSP cache in SMM */
fsp_cache = smm_fsp_cache_base(&smm_fsp_cache_length);
/* Get the FSP cache header */
header = (struct smm_fsp_cache_header *)fsp_cache;
fsp_cache += sizeof(*header);
/* Copy the FSP binary from the SMM region back into RAM */
memcpy(header->start, fsp_cache, header->size);
/* Return the FSP_INFO_HEADER address */
return header->fih;
} }
static void fsp_run_silicon_init(int is_s3_wakeup) static void fsp_run_silicon_init(int is_s3_wakeup)
@ -261,64 +179,54 @@ static void fsp_run_silicon_init(int is_s3_wakeup)
soc_after_silicon_init(); soc_after_silicon_init();
} }
static void fsp_cache_save(void) static void fsp_cache_save(struct prog *fsp)
{ {
const struct cbmem_entry *fsp_entry; if (IS_ENABLED(CONFIG_DISPLAY_SMM_MEMORY_MAP))
FSP_INFO_HEADER *fih; smm_memory_map();
fsp_entry = cbmem_entry_find(CBMEM_ID_REFCODE); if (prog_entry(fsp) == NULL) {
printk(BIOS_ERR, "ERROR: No FSP to save in cache.\n");
if (fsp_entry == NULL) {
printk(BIOS_ERR, "ERROR: FSP not found in CBMEM.\n");
return; return;
} }
fih = fsp_get_fih(); stage_cache_add(STAGE_REFCODE, fsp);
if (fih == NULL) {
printk(BIOS_ERR, "ERROR: No FIH found.\n");
return;
}
soc_save_support_code(cbmem_entry_start(fsp_entry),
cbmem_entry_size(fsp_entry), fih);
} }
static int fsp_find_and_relocate(void) static int fsp_find_and_relocate(struct prog *fsp)
{ {
struct prog fsp_prog = PROG_INIT(ASSET_REFCODE, "fsp.bin");
struct region_device fsp_rdev; struct region_device fsp_rdev;
uint32_t type = CBFS_TYPE_FSP; uint32_t type = CBFS_TYPE_FSP;
if (cbfs_boot_locate(&fsp_rdev, prog_name(&fsp_prog), &type)) { if (cbfs_boot_locate(&fsp_rdev, prog_name(fsp), &type)) {
printk(BIOS_ERR, "ERROR: Couldn't find fsp.bin in CBFS.\n"); printk(BIOS_ERR, "ERROR: Couldn't find fsp.bin in CBFS.\n");
return -1; return -1;
} }
if (fsp_relocate(&fsp_prog, &fsp_rdev)) { if (fsp_relocate(fsp, &fsp_rdev)) {
printk(BIOS_ERR, "ERROR: FSP relocation failed.\n"); printk(BIOS_ERR, "ERROR: FSP relocation failed.\n");
return -1; return -1;
} }
/* FSP_INFO_HEADER is set as the program entry. */
fsp_update_fih(prog_entry(&fsp_prog));
return 0; return 0;
} }
void intel_silicon_init(void) void intel_silicon_init(void)
{ {
struct prog fsp = PROG_INIT(ASSET_REFCODE, "fsp.bin");
int is_s3_wakeup = acpi_is_wakeup_s3(); int is_s3_wakeup = acpi_is_wakeup_s3();
if (is_s3_wakeup) { if (is_s3_wakeup) {
printk(BIOS_DEBUG, "FSP: Loading binary from cache\n"); printk(BIOS_DEBUG, "FSP: Loading binary from cache\n");
fsp_update_fih(soc_restore_support_code()); stage_cache_load_stage(STAGE_REFCODE, &fsp);
} else { } else {
fsp_find_and_relocate(); fsp_find_and_relocate(&fsp);
printk(BIOS_DEBUG, "FSP: Saving binary in cache\n"); printk(BIOS_DEBUG, "FSP: Saving binary in cache\n");
fsp_cache_save(); fsp_cache_save(&fsp);
} }
/* FSP_INFO_HEADER is set as the program entry. */
fsp_update_fih(prog_entry(&fsp));
fsp_run_silicon_init(is_s3_wakeup); fsp_run_silicon_init(is_s3_wakeup);
} }