/* Check for recovery mode and ensure EC is in RO */ void google_chromeec_early_init(void) { /* If in recovery ensure EC is running RO firmware. */ if (recovery_mode_enabled()) { google_chromeec_check_ec_image(EC_IMAGE_RO); } }
/* Check for recovery mode and ensure EC is in RO */ void google_chromeec_early_init(void) { struct chromeec_command cec_cmd; struct ec_response_get_version cec_resp = {{0}}; cec_cmd.cmd_code = EC_CMD_GET_VERSION; cec_cmd.cmd_version = 0; cec_cmd.cmd_data_out = &cec_resp; cec_cmd.cmd_size_in = 0; cec_cmd.cmd_size_out = sizeof(cec_resp); google_chromeec_command(&cec_cmd); if (cec_cmd.cmd_code || (recovery_mode_enabled() && (cec_resp.current_image != EC_IMAGE_RO))) { struct ec_params_reboot_ec reboot_ec; /* Reboot the EC and make it come back in RO mode */ reboot_ec.cmd = EC_REBOOT_COLD; reboot_ec.flags = 0; cec_cmd.cmd_code = EC_CMD_REBOOT_EC; cec_cmd.cmd_version = 0; cec_cmd.cmd_data_in = &reboot_ec; cec_cmd.cmd_size_in = sizeof(reboot_ec); cec_cmd.cmd_size_out = 0; /* ignore response, if any */ printk(BIOS_DEBUG, "Rebooting with EC in RO mode:\n"); google_chromeec_command(&cec_cmd); udelay(1000); hard_reset(); hlt(); } }
/* UPD parameters to be initialized before MemoryInit */ void soc_memory_init_params(struct romstage_params *params, MEMORY_INIT_UPD *upd) { const struct device *dev; const struct soc_intel_skylake_config *config; /* Set the parameters for MemoryInit */ dev = dev_find_slot(0, PCI_DEVFN(PCH_DEV_SLOT_LPC, 0)); config = dev->chip_info; upd->MmioSize = 0x800; /* 2GB in MB */ upd->TsegSize = CONFIG_SMM_TSEG_SIZE; upd->IedSize = CONFIG_IED_REGION_SIZE; upd->ProbelessTrace = config->ProbelessTrace; upd->EnableTraceHub = config->EnableTraceHub; if (recovery_mode_enabled()) upd->SaGv = 0; /* Disable SaGv in recovery mode. */ else upd->SaGv = config->SaGv; upd->RMT = config->Rmt; upd->DdrFreqLimit = config->DdrFreqLimit; if (IS_ENABLED(CONFIG_SKIP_FSP_CAR)) { upd->FspCarBase = CONFIG_DCACHE_RAM_BASE; upd->FspCarSize = CONFIG_DCACHE_RAM_SIZE_TOTAL; } }
void elog_add_boot_reason(void) { if (developer_mode_enabled()) { elog_add_event(ELOG_TYPE_CROS_DEVELOPER_MODE); printk(BIOS_DEBUG, "%s: Logged dev mode boot\n", __func__); } else if (recovery_mode_enabled()) { u8 reason = 0; #if CONFIG_VBOOT_VERIFY_FIRMWARE struct vboot_handoff *vbho = cbmem_find(CBMEM_ID_VBOOT_HANDOFF); reason = get_recovery_mode_from_vbnv(); if (vbho && !reason) { VbSharedDataHeader *sd = (VbSharedDataHeader *) vbho->shared_data; reason = sd->recovery_reason; } #endif elog_add_event_byte(ELOG_TYPE_CROS_RECOVERY_MODE, reason ? reason : ELOG_CROS_RECOVERY_MODE_BUTTON); printk(BIOS_DEBUG, "%s: Logged recovery mode boot, " "reason: 0x%02x\n", __func__, reason); } else { printk(BIOS_DEBUG, "%s: Normal mode boot, nothing " "interesting to log\n", __func__); } }
/* Check for recovery mode and ensure EC is in RO */ void google_chromeec_early_init(void) { if (IS_ENABLED(CONFIG_CHROMEOS)) { /* Check USB PD chip state first */ if (IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC_PD)) google_chromeec_early_pd_init(); /* If in recovery ensure EC is running RO firmware. */ if (recovery_mode_enabled()) google_chromeec_check_ec_image(EC_IMAGE_RO); } }
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, recovery_mode_enabled(), "recovery"}, {-1, ACTIVE_HIGH, get_developer_mode_switch(), "developer"}, {-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)); }
void google_chromeec_init(void) { struct chromeec_command cec_cmd; struct ec_response_get_version cec_resp = {{0}}; printk(BIOS_DEBUG, "Google Chrome EC: Initializing keyboard.\n"); google_chromeec_hello(); cec_cmd.cmd_code = EC_CMD_GET_VERSION; cec_cmd.cmd_version = 0; cec_cmd.cmd_data_out = &cec_resp; cec_cmd.cmd_size_in = 0; cec_cmd.cmd_size_out = sizeof(cec_resp); cec_cmd.cmd_dev_index = 0; google_chromeec_command(&cec_cmd); if (cec_cmd.cmd_code) { printk(BIOS_DEBUG, "Google Chrome EC: version command failed!\n"); } else { printk(BIOS_DEBUG, "Google Chrome EC: version:\n"); printk(BIOS_DEBUG, " ro: %s\n", cec_resp.version_string_ro); printk(BIOS_DEBUG, " rw: %s\n", cec_resp.version_string_rw); printk(BIOS_DEBUG, " running image: %d\n", cec_resp.current_image); ec_image_type = cec_resp.current_image; } if (cec_cmd.cmd_code || (recovery_mode_enabled() && (cec_resp.current_image != EC_IMAGE_RO))) { struct ec_params_reboot_ec reboot_ec; /* Reboot the EC and make it come back in RO mode */ reboot_ec.cmd = EC_REBOOT_COLD; reboot_ec.flags = 0; cec_cmd.cmd_code = EC_CMD_REBOOT_EC; cec_cmd.cmd_version = 0; cec_cmd.cmd_data_in = &reboot_ec; cec_cmd.cmd_size_in = sizeof(reboot_ec); cec_cmd.cmd_size_out = 0; /* ignore response, if any */ cec_cmd.cmd_dev_index = 0; printk(BIOS_DEBUG, "Rebooting with EC in RO mode:\n"); post_code(0); /* clear current post code */ google_chromeec_command(&cec_cmd); udelay(1000); hard_reset(); halt(); } }
/** * 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 (!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_get_file_content( CBFS_DEFAULT_MEDIA, "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 {
void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio *gpio; gpios->size = sizeof(*gpios) + (GPIO_COUNT * sizeof(struct lb_gpio)); gpios->count = GPIO_COUNT; gpio = gpios->gpios; fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "write protect", get_write_protect_state()); fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "recovery", recovery_mode_enabled()); fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "developer", get_developer_mode_switch()); fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "lid", get_lid_switch()); fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "power", 0); fill_lb_gpio(gpio++, -1, ACTIVE_HIGH, "oprom", gfx_get_init_done()); }
static void igd_init(struct device *dev) { if (IS_ENABLED(CONFIG_GOP_SUPPORT)) return; /* IGD needs to be Bus Master */ u32 reg32 = pci_read_config32(dev, PCI_COMMAND); reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO; pci_write_config32(dev, PCI_COMMAND, reg32); gtt_res = find_resource(dev, PCI_BASE_ADDRESS_0); if (!gtt_res || !gtt_res->base) return; /* Wait for any configured pre-graphics delay */ if (!acpi_is_wakeup_s3()) { #if IS_ENABLED(CONFIG_CHROMEOS) if (developer_mode_enabled() || recovery_mode_enabled() || vboot_wants_oprom()) mdelay(CONFIG_PRE_GRAPHICS_DELAY); #else mdelay(CONFIG_PRE_GRAPHICS_DELAY); #endif } /* Initialize PCI device, load/execute BIOS Option ROM */ pci_dev_init(dev); #if IS_ENABLED(CONFIG_CHROMEOS) if (!gfx_get_init_done() && !acpi_is_wakeup_s3()) { /* * Enable DDI-A if the Option ROM did not execute: * * bit 0: Display detected (RO) * bit 4: DDI A supports 4 lanes and DDI E is not used * bit 7: DDI buffer is idle */ gtt_write(DDI_BUF_CTL_A, DDI_BUF_IS_IDLE | DDI_A_4_LANES | DDI_INIT_DISPLAY_DETECTED); } #endif }
static void mainboard_init(device_t dev) { gpio_output(GPIO_RESET, 0); configure_usb(); configure_emmc(); configure_codec(); configure_3g(); /* No video. */ elog_init(); elog_add_watchdog_reset(); elog_add_boot_reason(); /* If recovery mode is detected, reduce frequency and voltage to reduce * heat in case machine is left unattended. chrome-os-partner:41201. */ if (recovery_mode_enabled()) { printk(BIOS_DEBUG, "Reducing APLL freq for recovery mode.\n"); rkclk_configure_cpu(APLL_600_MHZ); rk808_configure_buck(1, 900); } }
/** * 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 (!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_get_file_content( CBFS_DEFAULT_MEDIA, "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(); post_system_agent_init(pei_data); report_memory_config(); }
/** * Find the PEI executable in the ROM and execute it. * * @param pei_data: configuration data for UEFI PEI reference code */ int sdram_initialise(struct pei_data *pei_data) { unsigned version; const char *data; uint16_t done; int ret; report_platform_info(); /* Wait for ME to be ready */ ret = intel_early_me_init(); if (ret) return ret; ret = intel_early_me_uma_size(); if (ret < 0) return ret; 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 (!recovery_mode_enabled() || pei_data->boot_mode == PEI_BOOT_RESUME) { ret = prepare_mrc_cache(pei_data); if (ret) debug("prepare_mrc_cache failed: %d\n", ret); } /* If MRC data is not found we cannot continue S3 resume. */ if (pei_data->boot_mode == PEI_BOOT_RESUME && !pei_data->mrc_input) { debug("Giving up in sdram_initialize: No MRC data\n"); reset_cpu(0); } /* Pass console handler in pei_data */ pei_data->tx_byte = console_tx_byte; debug("PEI data at %p, size %x:\n", pei_data, sizeof(*pei_data)); data = (char *)CONFIG_X86_MRC_ADDR; if (data) { int rv; int (*func)(struct pei_data *); debug("Calling MRC at %p\n", data); post_code(POST_PRE_MRC); func = (int (*)(struct pei_data *))data; rv = func(pei_data); post_code(POST_MRC); if (rv) { switch (rv) { case -1: printf("PEI version mismatch.\n"); break; case -2: printf("Invalid memory frequency.\n"); break; default: printf("MRC returned %x.\n", rv); } printf("Nonzero MRC return value.\n"); return -EFAULT; } } else { printf("UEFI PEI System Agent not found.\n"); return -ENOSYS; } #if CONFIG_USBDEBUG /* mrc.bin reconfigures USB, so reinit it to have debug */ early_usbdebug_init(); #endif version = readl(MCHBAR_REG(0x5034)); debug("System Agent Version %d.%d.%d Build %d\n", version >> 24 , (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff); debug("MCR output data length %#x at %p\n", pei_data->mrc_output_len, pei_data->mrc_output); /* * Send ME init done for SandyBridge here. This is done inside the * SystemAgent binary on IvyBridge */ done = x86_pci_read_config32(PCH_DEV, PCI_DEVICE_ID); done &= BASE_REV_MASK; if (BASE_REV_SNB == done) intel_early_me_init_done(ME_INIT_STATUS_SUCCESS); else intel_early_me_status(); post_system_agent_init(pei_data); report_memory_config(); /* S3 resume: don't save scrambler seed or MRC data */ if (pei_data->boot_mode != PEI_BOOT_RESUME) { /* * This will be copied to SDRAM in reserve_arch(), then written * to SPI flash in sdram_save_mrc_data() */ gd->arch.mrc_output = (char *)pei_data->mrc_output; gd->arch.mrc_output_len = pei_data->mrc_output_len; ret = write_seeds_to_cmos(pei_data); if (ret) debug("Failed to write seeds to CMOS: %d\n", ret); } return 0; }
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 (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); }