void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) { struct region_device rdev; check_full_retrain(mupd); fill_console_params(mupd); if (CONFIG(SOC_INTEL_GLK)) soc_memory_init_params(mupd); mainboard_memory_init_params(mupd); parse_devicetree_setting(mupd); /* Do NOT let FSP do any GPIO pad configuration */ mupd->FspmConfig.PreMemGpioTablePtr = (uintptr_t) NULL; /* * Tell CSE we do not need to use Ring Buffer Protocol (RBP) to fetch * firmware for us if we are using memory-mapped SPI. This lets CSE * state machine transition to next boot state, so that it can function * as designed. */ mupd->FspmConfig.SkipCseRbp = CONFIG(BOOT_DEVICE_MEMORY_MAPPED); /* * Converged Security Engine (CSE) has secure storage functionality. * HECI2 device can be used to access that functionality. However, part * of S3 resume flow involves resetting HECI2 which takes 136ms. Since * coreboot does not use secure storage functionality, instruct FSP to * skip HECI2 reset. */ mupd->FspmConfig.EnableS3Heci2 = 0; /* * Apollolake splits MRC cache into two parts: constant and variable. * The constant part is not expected to change often and variable is. * Currently variable part consists of parameters that change on cold * boots such as scrambler seed and some memory controller registers. * Scrambler seed is vital for S3 resume case because attempt to use * wrong/missing key renders DRAM contents useless. */ if (mrc_cache_get_current(MRC_VARIABLE_DATA, version, &rdev) == 0) { /* Assume leaking is ok. */ assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED)); mupd->FspmConfig.VariableNvsBufferPtr = rdev_mmap_full(&rdev); } car_set_var(fsp_version, version); }
static void fsp_fill_mrc_cache(FSPM_ARCH_UPD *arch_upd, uint32_t fsp_version) { struct region_device rdev; void *data; arch_upd->NvsBufferPtr = NULL; if (!CONFIG(CACHE_MRC_SETTINGS)) return; /* * In recovery mode, force retraining: * 1. Recovery cache is not supported, or * 2. Memory retrain switch is set. */ if (vboot_recovery_mode_enabled()) { if (!CONFIG(HAS_RECOVERY_MRC_CACHE)) return; if (vboot_recovery_mode_memory_retrain()) return; } if (mrc_cache_get_current(MRC_TRAINING_DATA, fsp_version, &rdev) < 0) return; /* Assume boot device is memory mapped. */ assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED)); data = rdev_mmap_full(&rdev); if (data == NULL) return; if (CONFIG(FSP2_0_USES_TPM_MRC_HASH) && !mrc_cache_verify_hash(data, region_device_sz(&rdev))) return; /* MRC cache found */ arch_upd->NvsBufferPtr = data; printk(BIOS_SPEW, "MRC cache found, size %zx\n", region_device_sz(&rdev)); }
void raminit(struct mrc_params *mp, int prev_sleep_state) { int ret; mrc_wrapper_entry_t mrc_entry; const struct mrc_saved_data *cache; /* Fill in default entries. */ mp->version = MRC_PARAMS_VER; mp->console_out = &send_to_console; mp->prev_sleep_state = prev_sleep_state; if (!mrc_cache_get_current(&cache)) { mp->saved_data_size = cache->size; mp->saved_data = &cache->data[0]; } else { printk(BIOS_DEBUG, "No MRC cache found.\n"); } mrc_entry = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "mrc.bin", 0xab, NULL); if (mrc_entry == NULL) { printk(BIOS_DEBUG, "Couldn't find mrc.bin\n"); return; } if (mp->mainboard.dram_info_location == DRAM_INFO_SPD_SMBUS) enable_smbus(); ret = mrc_entry(mp); cbmem_initialize_empty(); printk(BIOS_DEBUG, "MRC Wrapper returned %d\n", ret); printk(BIOS_DEBUG, "MRC data at %p %d bytes\n", mp->data_to_save, mp->data_to_save_size); if (mp->data_to_save != NULL && mp->data_to_save_size > 0) mrc_cache_stash_data(mp->data_to_save, mp->data_to_save_size); }
void raminit(struct mrc_params *mp, int prev_sleep_state) { int ret; mrc_wrapper_entry_t mrc_entry; const struct mrc_saved_data *cache; /* Fill in default entries. */ mp->version = MRC_PARAMS_VER; mp->console_out = &send_to_console; mp->prev_sleep_state = prev_sleep_state; mp->rmt_enabled = IS_ENABLED(CONFIG_MRC_RMT); /* Default to 2GiB IO hole. */ if (!mp->io_hole_mb) mp->io_hole_mb = 2048; if (vboot_recovery_mode_enabled()) { printk(BIOS_DEBUG, "Recovery mode: not using MRC cache.\n"); } else if (!mrc_cache_get_current(&cache)) { mp->saved_data_size = cache->size; mp->saved_data = &cache->data[0]; } else if (prev_sleep_state == ACPI_S3) { /* If waking from S3 and no cache then. */ printk(BIOS_DEBUG, "No MRC cache found in S3 resume path.\n"); post_code(POST_RESUME_FAILURE); reset_system(); } else { printk(BIOS_DEBUG, "No MRC cache found.\n"); #if CONFIG_EC_GOOGLE_CHROMEEC if (prev_sleep_state == ACPI_S0) { /* Ensure EC is running RO firmware. */ google_chromeec_check_ec_image(EC_IMAGE_RO); } #endif } /* Determine if mrc.bin is in the cbfs. */ if (cbfs_boot_map_with_leak("mrc.bin", CBFS_TYPE_MRC, NULL) == NULL) { printk(BIOS_DEBUG, "Couldn't find mrc.bin\n"); return; } /* * The entry point is currently the first instruction. Handle the * case of an ELF file being put in the cbfs by setting the entry * to the CONFIG_MRC_BIN_ADDRESS. */ mrc_entry = (void *)(uintptr_t)CONFIG_MRC_BIN_ADDRESS; if (mp->mainboard.dram_info_location == DRAM_INFO_SPD_SMBUS) enable_smbus(); ret = mrc_entry(mp); print_dram_info(); if (prev_sleep_state != ACPI_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 Wrapper returned %d\n", ret); printk(BIOS_DEBUG, "MRC data at %p %d bytes\n", mp->data_to_save, mp->data_to_save_size); if (mp->data_to_save != NULL && mp->data_to_save_size > 0) mrc_cache_stash_data(mp->data_to_save, mp->data_to_save_size); }