summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drivers/intel/fsp2_0/include/fsp/api.h12
-rw-r--r--src/drivers/intel/fsp2_0/memory_init.c101
-rw-r--r--src/soc/intel/apollolake/romstage.c83
3 files changed, 101 insertions, 95 deletions
diff --git a/src/drivers/intel/fsp2_0/include/fsp/api.h b/src/drivers/intel/fsp2_0/include/fsp/api.h
index aa45d97876..9f8aae7f80 100644
--- a/src/drivers/intel/fsp2_0/include/fsp/api.h
+++ b/src/drivers/intel/fsp2_0/include/fsp/api.h
@@ -58,7 +58,7 @@ enum fsp_notify_phase {
/* Main FSP stages */
-enum fsp_status fsp_memory_init(void **hob_list, struct range_entry *r);
+enum fsp_status fsp_memory_init(struct range_entry *r, bool s3wake);
enum fsp_status fsp_silicon_init(struct range_entry *r);
enum fsp_status fsp_notify(enum fsp_notify_phase phase);
@@ -74,24 +74,18 @@ void platform_fsp_silicon_init_params_cb(struct FSPS_UPD *supd);
* points and map 1:1 to the FSP entry points of the same name.
*
* ### fsp_memory_init():
- * - hob_list: retuns a pointer to the HOB storage area created by FSP
* - r: memory range that the binary is allowed to be loaded into
+ * - s3wake: boolean indicating if the system is waking from resume
*
* This function is responsible for loading and executing the memory
* initialization code from the FSP-M binary. It expects this binary to reside
* in cbfs as FSP_M_FILE.
*
- * The function takes one parameter, which is described below, but does not
+ * The function takes two parameters, which are described above, but does not
* take in memory parameters as an argument. The memory parameters can be filled
* in with platform_fsp_memory_init_params_cb(). This is a callback symbol
* that fsp_memory_init() will call. The platform must provide this symbol.
*
- * FSP returns information about the memory layout in a series of structures
- * called hand-off-blocks (HOB). The "hob_list" output parameter will point to
- * the start of the HOB list. The fsp reserved region will also be described by
- * one of the HOBs. For more information on parsing these structures, see
- * fsp/util.h
- *
*
* ### fsp_silicon_init():
* - r: memory range that the binary is allowed to be loaded into
diff --git a/src/drivers/intel/fsp2_0/memory_init.c b/src/drivers/intel/fsp2_0/memory_init.c
index 5363fdd380..700d40fa7f 100644
--- a/src/drivers/intel/fsp2_0/memory_init.c
+++ b/src/drivers/intel/fsp2_0/memory_init.c
@@ -13,23 +13,103 @@
#include <arch/io.h>
#include <arch/cpu.h>
+#include <arch/symbols.h>
#include <cbmem.h>
#include <console/console.h>
#include <fsp/api.h>
#include <fsp/util.h>
#include <memrange.h>
+#include <reset.h>
+#include <romstage_handoff.h>
+#include <soc/intel/common/mrc_cache.h>
#include <string.h>
#include <timestamp.h>
typedef asmlinkage enum fsp_status (*fsp_memory_init_fn)
(void *raminit_upd, void **hob_list);
-static enum fsp_status do_fsp_memory_init(void **hob_list_ptr,
- struct fsp_header *hdr)
+static enum fsp_status do_fsp_post_memory_init(void *hob_list_ptr, bool s3wake)
+{
+ struct range_entry fsp_mem;
+ size_t mrc_data_size;
+ const void *mrc_data;
+ struct romstage_handoff *handoff;
+
+ fsp_find_reserved_memory(&fsp_mem, hob_list_ptr);
+
+ /* initialize cbmem by adding FSP reserved memory first thing */
+ if (!s3wake) {
+ cbmem_initialize_empty_id_size(CBMEM_ID_FSP_RESERVED_MEMORY,
+ range_entry_size(&fsp_mem));
+ } else if (cbmem_initialize_id_size(CBMEM_ID_FSP_RESERVED_MEMORY,
+ range_entry_size(&fsp_mem))) {
+ if (IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)) {
+ printk(BIOS_DEBUG, "Failed to recover CBMEM in S3 resume.\n");
+ /* Failed S3 resume, reset to come up cleanly */
+ hard_reset();
+ }
+ }
+
+ /* make sure FSP memory is reserved in cbmem */
+ if (range_entry_base(&fsp_mem) !=
+ (uintptr_t)cbmem_find(CBMEM_ID_FSP_RESERVED_MEMORY))
+ die("Failed to accommodate FSP reserved memory request");
+
+ /* Now that CBMEM is up, save the list so ramstage can use it */
+ fsp_save_hob_list(hob_list_ptr);
+
+ /* Save MRC Data to CBMEM */
+ if (IS_ENABLED(CONFIG_CACHE_MRC_SETTINGS) && !s3wake) {
+ mrc_data = fsp_find_nv_storage_data(&mrc_data_size);
+ if (mrc_data && mrc_cache_stash_data(mrc_data, mrc_data_size) < 0)
+ printk(BIOS_ERR, "Failed to stash MRC data\n");
+ }
+
+ /* Create romstage handof information */
+ handoff = romstage_handoff_find_or_add();
+ if (handoff != NULL)
+ handoff->s3_resume = s3wake;
+ else
+ printk(BIOS_DEBUG, "Romstage handoff structure not added!\n");
+
+ return FSP_SUCCESS;
+}
+
+static void fsp_fill_common_arch_params(struct FSPM_ARCH_UPD *arch_upd,
+ bool s3wake)
+{
+ const struct mrc_saved_data *mrc_cache;
+
+ /*
+ * FSPM_UPD passed here is populated with default values provided by
+ * the blob itself. We let FSPM use top of CAR region of the size it
+ * requests.
+ * TODO: add checks to avoid overlap/conflict of CAR usage.
+ */
+ arch_upd->StackBase = _car_region_end - arch_upd->StackSize;
+
+ arch_upd->BootMode = FSP_BOOT_WITH_FULL_CONFIGURATION;
+
+ if (IS_ENABLED(CONFIG_CACHE_MRC_SETTINGS)) {
+ if (!mrc_cache_get_current_with_version(&mrc_cache, 0)) {
+ /* MRC cache found */
+ arch_upd->NvsBufferPtr = (void *)mrc_cache->data;
+ arch_upd->BootMode = s3wake ?
+ FSP_BOOT_ON_S3_RESUME:
+ FSP_BOOT_ASSUMING_NO_CONFIGURATION_CHANGES;
+ printk(BIOS_DEBUG, "MRC cache found, size %x bootmode:%d\n",
+ mrc_cache->size, arch_upd->BootMode);
+ } else
+ printk(BIOS_DEBUG, "MRC cache was not found\n");
+ }
+}
+
+static enum fsp_status do_fsp_memory_init(struct fsp_header *hdr, bool s3wake)
{
enum fsp_status status;
fsp_memory_init_fn fsp_raminit;
struct FSPM_UPD fspm_upd, *upd;
+ void *hob_list_ptr;
post_code(0x34);
@@ -46,6 +126,9 @@ static enum fsp_status do_fsp_memory_init(void **hob_list_ptr,
/* Reserve enough memory under TOLUD to save CBMEM header */
fspm_upd.FspmArchUpd.BootLoaderTolumSize = cbmem_overhead_size();
+ /* Fill common settings on behalf of chipset. */
+ fsp_fill_common_arch_params(&fspm_upd.FspmArchUpd, s3wake);
+
/* Give SoC and mainboard a chance to update the UPD */
platform_fsp_memory_init_params_cb(&fspm_upd);
@@ -53,25 +136,29 @@ static enum fsp_status do_fsp_memory_init(void **hob_list_ptr,
fsp_raminit = (void *)(hdr->image_base + hdr->memory_init_entry_offset);
printk(BIOS_DEBUG, "Calling FspMemoryInit: 0x%p\n", fsp_raminit);
printk(BIOS_SPEW, "\t%p: raminit_upd\n", &fspm_upd);
- printk(BIOS_SPEW, "\t%p: hob_list ptr\n", hob_list_ptr);
+ printk(BIOS_SPEW, "\t%p: hob_list ptr\n", &hob_list_ptr);
post_code(POST_FSP_MEMORY_INIT);
timestamp_add_now(TS_FSP_MEMORY_INIT_START);
- status = fsp_raminit(&fspm_upd, hob_list_ptr);
+ status = fsp_raminit(&fspm_upd, &hob_list_ptr);
post_code(POST_FSP_MEMORY_INIT);
timestamp_add_now(TS_FSP_MEMORY_INIT_END);
printk(BIOS_DEBUG, "FspMemoryInit returned 0x%08x\n", status);
- return status;
+ /* TODO: Is this the only thing that can happen? */
+ if (status != FSP_SUCCESS)
+ return status;
+
+ return do_fsp_post_memory_init(hob_list_ptr, s3wake);
}
-enum fsp_status fsp_memory_init(void **hob_list, struct range_entry *range)
+enum fsp_status fsp_memory_init(struct range_entry *range, bool s3wake)
{
struct fsp_header hdr;
if (fsp_load_binary(&hdr, CONFIG_FSP_M_CBFS, range) != CB_SUCCESS)
return FSP_NOT_FOUND;
- return do_fsp_memory_init(hob_list, &hdr);
+ return do_fsp_memory_init(&hdr, s3wake);
}
diff --git a/src/soc/intel/apollolake/romstage.c b/src/soc/intel/apollolake/romstage.c
index ddbfaa4b39..464d5b8f84 100644
--- a/src/soc/intel/apollolake/romstage.c
+++ b/src/soc/intel/apollolake/romstage.c
@@ -30,9 +30,6 @@
#include <device/resource.h>
#include <fsp/api.h>
#include <fsp/util.h>
-#include <reset.h>
-#include <romstage_handoff.h>
-#include <soc/intel/common/mrc_cache.h>
#include <soc/iomap.h>
#include <soc/northbridge.h>
#include <soc/pci_devs.h>
@@ -104,14 +101,10 @@ ROMSTAGE_CBMEM_INIT_HOOK(migrate_power_state);
asmlinkage void car_stage_entry(void)
{
- void *hob_list_ptr;
- const void *mrc_data;
- struct range_entry fsp_mem, reg_car;
+ struct range_entry reg_car;
struct postcar_frame pcf;
- size_t mrc_data_size;
uintptr_t top_of_ram;
- int prev_sleep_state;
- struct romstage_handoff *handoff;
+ bool s3wake;
struct chipset_power_state *ps = car_get_var_ptr(&power_state);
timestamp_add_now(TS_START_ROMSTAGE);
@@ -121,55 +114,16 @@ asmlinkage void car_stage_entry(void)
console_init();
- prev_sleep_state = fill_power_state(ps);
+ s3wake = fill_power_state(ps) == ACPI_S3;
/* Make sure the blob does not override our data in CAR */
range_entry_init(&reg_car, (uintptr_t)_car_relocatable_data_end,
(uintptr_t)_car_region_end, 0);
- if (fsp_memory_init(&hob_list_ptr, &reg_car) != FSP_SUCCESS) {
+ if (fsp_memory_init(&reg_car, s3wake) != FSP_SUCCESS) {
die("FSP memory init failed. Giving up.");
}
- fsp_find_reserved_memory(&fsp_mem, hob_list_ptr);
-
- /* initialize cbmem by adding FSP reserved memory first thing */
- if (prev_sleep_state != ACPI_S3) {
- cbmem_initialize_empty_id_size(CBMEM_ID_FSP_RESERVED_MEMORY,
- range_entry_size(&fsp_mem));
- } else if (cbmem_initialize_id_size(CBMEM_ID_FSP_RESERVED_MEMORY,
- range_entry_size(&fsp_mem))) {
- if (IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)) {
- printk(BIOS_DEBUG, "Failed to recover CBMEM in S3 resume.\n");
- /* Failed S3 resume, reset to come up cleanly */
- hard_reset();
- }
- }
-
- /* make sure FSP memory is reserved in cbmem */
- if (range_entry_base(&fsp_mem) !=
- (uintptr_t)cbmem_find(CBMEM_ID_FSP_RESERVED_MEMORY))
- die("Failed to accommodate FSP reserved memory request");
-
- /* Now that CBMEM is up, save the list so ramstage can use it */
- fsp_save_hob_list(hob_list_ptr);
-
- /* Save MRC Data to CBMEM */
- if (IS_ENABLED(CONFIG_CACHE_MRC_SETTINGS) &&
- (prev_sleep_state != ACPI_S3))
- {
- mrc_data = fsp_find_nv_storage_data(&mrc_data_size);
- if (mrc_data && mrc_cache_stash_data(mrc_data, mrc_data_size) < 0)
- printk(BIOS_ERR, "Failed to stash MRC data\n");
- }
-
- /* Create romstage handof information */
- handoff = romstage_handoff_find_or_add();
- if (handoff != NULL)
- handoff->s3_resume = (prev_sleep_state == ACPI_S3);
- else
- printk(BIOS_DEBUG, "Romstage handoff structure not added!\n");
-
if (postcar_frame_init(&pcf, 1*KiB))
die("Unable to initialize postcar frame.\n");
@@ -203,40 +157,11 @@ static void fill_console_params(struct FSPM_UPD *mupd)
void platform_fsp_memory_init_params_cb(struct FSPM_UPD *mupd)
{
- const struct mrc_saved_data *mrc_cache;
- struct FSPM_ARCH_UPD *arch_upd = &mupd->FspmArchUpd;
- struct chipset_power_state *ps = car_get_var_ptr(&power_state);
- int prev_sleep_state = chipset_prev_sleep_state(ps);
-
fill_console_params(mupd);
mainboard_memory_init_params(mupd);
/* Do NOT let FSP do any GPIO pad configuration */
mupd->FspmConfig.PreMemGpioTablePtr = (uintptr_t) NULL;
- /*
- * FSPM_UPD passed here is populated with default values provided by
- * the blob itself. We let FSPM use top of CAR region of the size it
- * requests.
- * TODO: add checks to avoid overlap/conflict of CAR usage.
- */
- mupd->FspmArchUpd.StackBase = _car_region_end -
- mupd->FspmArchUpd.StackSize;
-
- arch_upd->BootMode = FSP_BOOT_WITH_FULL_CONFIGURATION;
-
- if (IS_ENABLED(CONFIG_CACHE_MRC_SETTINGS)) {
- if (!mrc_cache_get_current_with_version(&mrc_cache, 0)) {
- /* MRC cache found */
- arch_upd->NvsBufferPtr = (void *)mrc_cache->data;
- arch_upd->BootMode =
- prev_sleep_state == ACPI_S3 ?
- FSP_BOOT_ON_S3_RESUME:
- FSP_BOOT_ASSUMING_NO_CONFIGURATION_CHANGES;
- printk(BIOS_DEBUG, "MRC cache found, size %x bootmode:%d\n",
- mrc_cache->size, arch_upd->BootMode);
- } else
- printk(BIOS_DEBUG, "MRC cache was not found\n");
- }
/*
* Tell CSE we do not need to use Ring Buffer Protocol (RBP) to fetch