static void elog_add_boot_reason(void *unused) { int rec = vboot_recovery_mode_enabled(); int dev = vboot_developer_mode_enabled(); if (!rec && !dev) return; if (rec) { u8 reason = vboot_check_recovery_request(); elog_add_event_byte(ELOG_TYPE_CROS_RECOVERY_MODE, reason); printk(BIOS_DEBUG, "%s: Logged recovery mode boot%s, " "reason: 0x%02x\n", __func__, dev ? " (Dev-switch on)" : "", reason); } if (dev) { int log_event = 1; #if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME) /* Skip logging developer mode in ACPI resume path */ if (acpi_is_wakeup()) log_event = 0; #endif if (log_event) { elog_add_event(ELOG_TYPE_CROS_DEVELOPER_MODE); printk(BIOS_DEBUG, "%s: Logged dev mode boot\n", __func__); } } }
void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, {-1, ACTIVE_HIGH, vboot_recovery_mode_enabled(), "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, }; lb_add_gpios(gpios, chromeos_gpios, ARRAY_SIZE(chromeos_gpios)); }
/** * 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) { unsigned long entry; printk(BIOS_DEBUG, "Starting UEFI PEI System Agent\n"); /* * Do not pass MRC data in for recovery mode boot, * Always pass it in for S3 resume. */ if (!vboot_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) { post_code(POST_RESUME_FAILURE); printk(BIOS_DEBUG, "Giving up in sdram_initialize: " "No MRC data\n"); outb(0x6, 0xcf9); halt(); } /* Pass console handler in pei_data */ pei_data->tx_byte = do_putchar; /* Locate and call UEFI System Agent binary. */ entry = (unsigned long)cbfs_boot_map_with_leak("mrc.bin", CBFS_TYPE_MRC, NULL); 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"); } } else {
static void mainboard_init(device_t dev) { gpio_output(GPIO_RESET, 0); configure_usb(); configure_emmc(); configure_codec(); configure_3g(); /* No video. */ /* If recovery mode is detected, reduce frequency and voltage to reduce * heat in case machine is left unattended. chrome-os-partner:41201. */ if (vboot_recovery_mode_enabled()) { printk(BIOS_DEBUG, "Reducing APLL freq for recovery mode.\n"); rkclk_configure_cpu(APLL_600_MHZ); rk808_configure_buck(1, 900); } }
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)); }
/** * 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) { struct sys_info sysinfo; int (*entry) (struct pei_data *pei_data) __attribute__ ((regparm(1))); report_platform_info(); /* Wait for ME to be ready */ intel_early_me_init(); intel_early_me_uma_size(); printk(BIOS_DEBUG, "Starting UEFI PEI System Agent\n"); memset(&sysinfo, 0, sizeof(sysinfo)); sysinfo.boot_path = pei_data->boot_mode; /* * Do not pass MRC data in for recovery mode boot, * Always pass it in for S3 resume. */ if (!vboot_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) { printk(BIOS_DEBUG, "Giving up in sdram_initialize: No MRC data\n"); outb(0x6, 0xcf9); halt(); } /* Pass console handler in pei_data */ pei_data->tx_byte = do_putchar; /* Locate and call UEFI System Agent binary. */ entry = cbfs_boot_map_with_leak("mrc.bin", CBFS_TYPE_MRC, NULL); if (entry) { int rv; rv = entry (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"); } } else { die("UEFI PEI System Agent not found.\n"); } #if CONFIG_USBDEBUG_IN_ROMSTAGE /* mrc.bin reconfigures USB, so reinit it to have debug */ usbdebug_init(); #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", version >> 24 , (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff); /* Send ME init done for SandyBridge here. This is done * inside the SystemAgent binary on IvyBridge. */ if (BASE_REV_SNB == (pci_read_config16(PCI_CPU_DEVICE, PCI_DEVICE_ID) & BASE_REV_MASK)) intel_early_me_init_done(ME_INIT_STATUS_SUCCESS); else intel_early_me_status(); report_memory_config(); }
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); }
/* Entry from the mainboard. */ void romstage_common(struct romstage_params *params) { const struct mrc_saved_data *cache; struct romstage_handoff *handoff; struct pei_data *pei_data; post_code(0x32); timestamp_add_now(TS_BEFORE_INITRAM); pei_data = params->pei_data; pei_data->boot_mode = params->power_state->prev_sleep_state; #if IS_ENABLED(CONFIG_ELOG_BOOT_COUNT) if (params->power_state->prev_sleep_state != ACPI_S3) boot_count_increment(); #endif /* Perform remaining SOC initialization */ soc_pre_ram_init(params); post_code(0x33); /* Check recovery and MRC cache */ params->pei_data->saved_data_size = 0; params->pei_data->saved_data = NULL; if (!params->pei_data->disable_saved_data) { if (vboot_recovery_mode_enabled()) { /* Recovery mode does not use MRC cache */ printk(BIOS_DEBUG, "Recovery mode: not using MRC cache.\n"); } else if (IS_ENABLED(CONFIG_CACHE_MRC_SETTINGS) && (!mrc_cache_get_current_with_version(&cache, params->fsp_version))) { /* MRC cache found */ params->pei_data->saved_data_size = cache->size; params->pei_data->saved_data = &cache->data[0]; } else if (params->pei_data->boot_mode == ACPI_S3) { /* Waking from S3 and no cache. */ printk(BIOS_DEBUG, "No MRC cache found in S3 resume path.\n"); post_code(POST_RESUME_FAILURE); hard_reset(); } else { printk(BIOS_DEBUG, "No MRC cache found.\n"); mainboard_check_ec_image(params); } } /* Initialize RAM */ raminit(params); timestamp_add_now(TS_AFTER_INITRAM); /* Save MRC output */ if (IS_ENABLED(CONFIG_CACHE_MRC_SETTINGS)) { printk(BIOS_DEBUG, "MRC data at %p %d bytes\n", pei_data->data_to_save, pei_data->data_to_save_size); if ((params->pei_data->boot_mode != ACPI_S3) && (params->pei_data->data_to_save_size != 0) && (params->pei_data->data_to_save != NULL)) mrc_cache_stash_data_with_version( params->pei_data->data_to_save, params->pei_data->data_to_save_size, params->fsp_version); } /* Save DIMM information */ mainboard_save_dimm_info(params); /* Create romstage handof information */ handoff = romstage_handoff_find_or_add(); if (handoff != NULL) handoff->s3_resume = (params->power_state->prev_sleep_state == ACPI_S3); else { printk(BIOS_DEBUG, "Romstage handoff structure not added!\n"); hard_reset(); } /* * Initialize the TPM, unless the TPM was already initialized * in verstage and used to verify romstage. */ if (IS_ENABLED(CONFIG_LPC_TPM) && !IS_ENABLED(CONFIG_RESUME_PATH_SAME_AS_BOOT) && !IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) init_tpm(params->power_state->prev_sleep_state == ACPI_S3); }