diff options
-rw-r--r-- | src/drivers/intel/fsp2_0/include/fsp/api.h | 12 | ||||
-rw-r--r-- | src/drivers/intel/fsp2_0/memory_init.c | 101 | ||||
-rw-r--r-- | src/soc/intel/apollolake/romstage.c | 83 |
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(®_car, (uintptr_t)_car_relocatable_data_end, (uintptr_t)_car_region_end, 0); - if (fsp_memory_init(&hob_list_ptr, ®_car) != FSP_SUCCESS) { + if (fsp_memory_init(®_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 |