From 3f25c23dc58f85d2521916cd6edbe9deeeb8d523 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Fri, 2 May 2014 14:27:52 -0700 Subject: [PATCH] broadwell: Update raminit to follow baytrail layout Make the broadwell raminit function closely resemble the baytrail raminit function. The MRC cache related functions have been split into the common code at soc/intel/common so we can re-use those functions here. The PEI data structure is set up in pei_data.c so we do not need to do any additional configuration of the struct before starting memory training. BUG=chrome-os-partner:28234 TEST=Successfully execute mrc.bin on whitecap mountain 2 board to train memory. Change-Id: Ie1582d61180e9998d8bfe26758b925b0d4a80840 Signed-off-by: Duncan Laurie Reviewed-on: https://chromium-review.googlesource.com/199369 Reviewed-by: Aaron Durbin --- src/soc/intel/broadwell/romstage/raminit.c | 197 ++++++++------------- 1 file changed, 74 insertions(+), 123 deletions(-) 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); +}