diff --git a/src/soc/intel/broadwell/romstage/raminit.c b/src/soc/intel/broadwell/romstage/raminit.c index e8fade4d74..870952f79a 100644 --- a/src/soc/intel/broadwell/romstage/raminit.c +++ b/src/soc/intel/broadwell/romstage/raminit.c @@ -17,147 +17,98 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include +#include #include #include -#include -#include #include -#include -#include +#include +#include #include -#include "raminit.h" -#include "pei_data.h" -#include "haswell.h" - -#if CONFIG_CHROMEOS -#include -#else -#define recovery_mode_enabled(x) 0 +#include +#if CONFIG_EC_GOOGLE_CHROMEEC +#include +#include #endif - -void save_mrc_data(struct pei_data *pei_data) -{ - struct mrc_data_container *mrcdata; - int output_len = ALIGN(pei_data->mrc_output_len, 16); - - /* Save the MRC S3 restore data to cbmem */ - mrcdata = cbmem_add - (CBMEM_ID_MRCDATA, - output_len + sizeof(struct mrc_data_container)); - - printk(BIOS_DEBUG, "Relocate MRC DATA from %p to %p (%u bytes)\n", - pei_data->mrc_output, mrcdata, output_len); - - mrcdata->mrc_signature = MRC_DATA_SIGNATURE; - mrcdata->mrc_data_size = output_len; - mrcdata->reserved = 0; - memcpy(mrcdata->mrc_data, pei_data->mrc_output, - pei_data->mrc_output_len); - - /* Zero the unused space in aligned buffer. */ - if (output_len > pei_data->mrc_output_len) - memset(mrcdata->mrc_data+pei_data->mrc_output_len, 0, - output_len - pei_data->mrc_output_len); - - mrcdata->mrc_checksum = compute_ip_checksum(mrcdata->mrc_data, - mrcdata->mrc_data_size); -} - -static void prepare_mrc_cache(struct pei_data *pei_data) -{ - struct mrc_data_container *mrc_cache; - - // preset just in case there is an error - pei_data->mrc_input = NULL; - pei_data->mrc_input_len = 0; - - if ((mrc_cache = find_current_mrc_cache()) == NULL) { - /* error message printed in find_current_mrc_cache */ - return; - } - - pei_data->mrc_input = mrc_cache->mrc_data; - pei_data->mrc_input_len = mrc_cache->mrc_data_size; - - printk(BIOS_DEBUG, "%s: at %p, size %x checksum %04x\n", - __func__, pei_data->mrc_input, - pei_data->mrc_input_len, mrc_cache->mrc_checksum); -} - -static const char* ecc_decoder[] = { - "inactive", - "active on IO", - "disabled on IO", - "active" -}; +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* * Find PEI executable in coreboot filesystem and execute it. - * - * @param pei_data: configuration data for UEFI PEI reference code */ -void sdram_initialize(struct pei_data *pei_data) +void raminit(struct pei_data *pei_data) { - unsigned long entry; + const struct mrc_saved_data *cache; + pei_wrapper_entry_t entry; + int ret; - printk(BIOS_DEBUG, "Starting UEFI PEI System Agent\n"); + broadwell_fill_pei_data(pei_data); - /* - * Do not pass MRC data in for recovery mode boot, - * Always pass it in for S3 resume. - */ - if (!recovery_mode_enabled() || pei_data->boot_mode == 2) - prepare_mrc_cache(pei_data); - - /* If MRC data is not found we cannot continue S3 resume. */ - if (pei_data->boot_mode == 2 && !pei_data->mrc_input) { + if (recovery_mode_enabled()) { + /* Recovery mode does not use MRC cache */ + printk(BIOS_DEBUG, "Recovery mode: not using MRC cache.\n"); + } else if (!mrc_cache_get_current(&cache)) { + /* MRC cache found */ + pei_data->saved_data_size = cache->size; + pei_data->saved_data = &cache->data[0]; + } else if (pei_data->boot_mode == SLEEP_STATE_S3) { + /* Waking from S3 and no cache. */ + printk(BIOS_DEBUG, "No MRC cache found in S3 resume path.\n"); post_code(POST_RESUME_FAILURE); - printk(BIOS_DEBUG, "Giving up in sdram_initialize: " - "No MRC data\n"); - outb(0x6, 0xcf9); - while(1) { - hlt(); - } - } - - /* Pass console handler in pei_data */ - pei_data->tx_byte = console_tx_byte; - - /* Locate and call UEFI System Agent binary. */ - entry = (unsigned long)cbfs_get_file_content( - CBFS_DEFAULT_MEDIA, "mrc.bin", 0xab); - if (entry) { - int rv; - asm volatile ( - "call *%%ecx\n\t" - :"=a" (rv) : "c" (entry), "a" (pei_data)); - if (rv) { - switch (rv) { - case -1: - printk(BIOS_ERR, "PEI version mismatch.\n"); - break; - case -2: - printk(BIOS_ERR, "Invalid memory frequency.\n"); - break; - default: - printk(BIOS_ERR, "MRC returned %x.\n", rv); - } - die("Nonzero MRC return value.\n"); - } + reset_system(); } else { - die("UEFI PEI System Agent not found.\n"); + printk(BIOS_DEBUG, "No MRC cache found.\n"); +#if CONFIG_EC_GOOGLE_CHROMEEC + if (pei_data->boot_mode == SLEEP_STATE_S0) { + /* Ensure EC is running RO firmware. */ + google_chromeec_check_ec_image(EC_IMAGE_RO); + } +#endif } - /* For reference print the System Agent version - * after executing the UEFI PEI stage. - */ - u32 version = MCHBAR32(0x5034); - printk(BIOS_DEBUG, "System Agent Version %d.%d.%d Build %d\n", + /* Determine if mrc.bin is in the cbfs. */ + entry = (pei_wrapper_entry_t)cbfs_get_file_content( + CBFS_DEFAULT_MEDIA, "mrc.bin", 0xab); + if (entry == NULL) { + printk(BIOS_DEBUG, "Couldn't find mrc.bin\n"); + return; + } + + printk(BIOS_DEBUG, "Starting Memory Reference Code\n"); + + ret = entry(pei_data); + if (ret < 0) + die("pei_data version mismatch\n"); + + /* Print the MRC version after executing the UEFI PEI stage. */ + u32 version = MCHBAR32(MCHBAR_PEI_VERSION); + printk(BIOS_DEBUG, "MRC Version %d.%d.%d Build %d\n", version >> 24 , (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff); report_memory_config(); -} + if (pei_data->boot_mode != SLEEP_STATE_S3) { + cbmem_initialize_empty(); + } else if (cbmem_initialize()) { +#if CONFIG_HAVE_ACPI_RESUME + printk(BIOS_DEBUG, "Failed to recover CBMEM in S3 resume.\n"); + /* Failed S3 resume, reset to come up cleanly */ + reset_system(); +#endif + } + + printk(BIOS_DEBUG, "MRC data at %p %d bytes\n", pei_data->data_to_save, + pei_data->data_to_save_size); + + if (pei_data->data_to_save != NULL && pei_data->data_to_save_size > 0) + mrc_cache_stash_data(pei_data->data_to_save, + pei_data->data_to_save_size); +}