int board_init(void) { struct fdt_memory mem_config; /* Record the time we spent before SPL */ bootstage_add_record(BOOTSTAGE_ID_START_SPL, "spl_start", 0, CONFIG_SPL_TIME_US); bootstage_mark_name(BOOTSTAGE_ID_BOARD_INIT, "board_init"); if (fdtdec_decode_memory(gd->fdt_blob, &mem_config)) { debug("%s: Failed to decode memory\n", __func__); return -1; } gd->bd->bi_boot_params = mem_config.start + 0x100UL; #ifdef CONFIG_OF_CONTROL gd->bd->bi_arch_number = fdtdec_get_config_int(gd->fdt_blob, "machine-arch-id", -1); if (gd->bd->bi_arch_number == -1U) debug("Warning: No /config/machine-arch-id defined in fdt\n"); #endif #ifdef CONFIG_EXYNOS_SPI spi_init(); #endif if (board_i2c_arb_init(gd->fdt_blob)) return -1; board_i2c_init(gd->fdt_blob); #ifdef CONFIG_TPS65090_POWER tps65090_init(); /* * If we just reset, disable the backlight and lcd fets before * [re-]initializing the lcd. This ensures we are always in the same * state during lcd init. We've seen some oddities with these fets, so * this removes a bit of uncertainty. */ if (board_is_processor_reset()) { tps65090_fet_disable(1); tps65090_fet_disable(6); } #endif exynos_lcd_check_next_stage(gd->fdt_blob, 0); if (max77686_enable_32khz_cp()) { debug("%s: Failed to enable max77686 32khz coprocessor clock\n", __func__); return -1; } #if defined CONFIG_EXYNOS_CPUFREQ if (exynos5250_cpufreq_init(gd->fdt_blob)) { debug("%s: Failed to init CPU frequency scaling\n", __func__); return -1; } #endif #if defined CONFIG_EXYNOS_TMU if (tmu_init(gd->fdt_blob)) { debug("%s: Failed to init TMU\n", __func__); return -1; } #endif /* Clock Gating all the unused IP's to save power */ clock_gate(); /* Disable USB3.0 PLL to save 250mW of power */ disable_usb30_pll(); if (board_init_mkbp_devices(gd->fdt_blob)) return -1; board_configure_analogix(); board_enable_audio_codec(); exynos_lcd_check_next_stage(gd->fdt_blob, 0); bootstage_mark_name(BOOTSTAGE_ID_BOARD_INIT_DONE, "board_init_done"); return 0; }
static int twostop_init(struct twostop_fmap *fmap, firmware_storage_t *file, void **gbbp, size_t gbb_size, crossystem_data_t *cdata, void *vb_shared_data) { struct vboot_flag_details wpsw, recsw, devsw, oprom; GoogleBinaryBlockHeader *gbbh; uint8_t hardware_id[ID_LEN]; #ifndef CONFIG_HARDWARE_MAPPED_SPI uint8_t readonly_firmware_id[ID_LEN]; #else uint8_t *readonly_firmware_id; #endif int oprom_matters = 0; int ret = -1; void *gbb; bootstage_mark_name(BOOTSTAGE_VBOOT_TWOSTOP_INIT, "twostop_init"); if (vboot_flag_fetch(VBOOT_FLAG_WRITE_PROTECT, &wpsw) || vboot_flag_fetch(VBOOT_FLAG_RECOVERY, &recsw) || vboot_flag_fetch(VBOOT_FLAG_DEVELOPER, &devsw) || vboot_flag_fetch(VBOOT_FLAG_OPROM_LOADED, &oprom)) { VBDEBUG("failed to fetch gpio\n"); return -1; } vboot_flag_dump(VBOOT_FLAG_WRITE_PROTECT, &wpsw); vboot_flag_dump(VBOOT_FLAG_RECOVERY, &recsw); vboot_flag_dump(VBOOT_FLAG_DEVELOPER, &devsw); vboot_flag_dump(VBOOT_FLAG_OPROM_LOADED, &oprom); if (cros_fdtdec_config_has_prop(gd->fdt_blob, "oprom-matters")) { VBDEBUG("FDT says oprom-matters\n"); oprom_matters = 1; } if (!fmap->readonly.fmap.length && cros_fdtdec_flashmap(gd->fdt_blob, fmap)) { VBDEBUG("failed to decode fmap\n"); return -1; } dump_fmap(fmap); /* We revert the decision of using firmware_storage_open_twostop() */ if (firmware_storage_open_spi(file)) { VBDEBUG("failed to open firmware storage\n"); return -1; } /* Read read-only firmware ID */ if (file->read(file, fmap->readonly.firmware_id.offset, MIN(sizeof(readonly_firmware_id), fmap->readonly.firmware_id.length), BT_EXTRA readonly_firmware_id)) { VBDEBUG("failed to read firmware ID\n"); readonly_firmware_id[0] = '\0'; } VBDEBUG("read-only firmware id: \"%s\"\n", readonly_firmware_id); /* Load basic parts of gbb blob */ #ifdef CONFIG_HARDWARE_MAPPED_SPI if (gbb_init(gbbp, file, fmap->readonly.gbb.offset, gbb_size)) { VBDEBUG("failed to read gbb\n"); goto out; } gbb = *gbbp; #else gbb = *gbbp; if (gbb_init(gbb, file, fmap->readonly.gbb.offset, gbb_size)) { VBDEBUG("failed to read gbb\n"); goto out; } #endif gbbh = (GoogleBinaryBlockHeader *)gbb; memcpy(hardware_id, gbb + gbbh->hwid_offset, MIN(sizeof(hardware_id), gbbh->hwid_size)); VBDEBUG("hardware id: \"%s\"\n", hardware_id); /* Initialize crossystem data */ /* * TODO There is no readwrite EC firmware on our current ARM boards. But * we should have a mechanism to probe (or acquire this information from * the device tree) whether the active EC firmware is R/O or R/W. */ if (crossystem_data_init(cdata, &wpsw, &recsw, &devsw, &oprom, oprom_matters, fmap->readonly.fmap.offset, ACTIVE_EC_FIRMWARE_RO, hardware_id, readonly_firmware_id)) { VBDEBUG("failed to init crossystem data\n"); goto out; } ret = 0; #ifdef CONFIG_VIDEO_TEGRA tegra_lcd_check_next_stage(gd->fdt_blob, 0); #endif #ifdef CONFIG_EXYNOS_DISPLAYPORT exynos_lcd_check_next_stage(gd->fdt_blob, 0); #endif out: if (ret) file->close(file); return ret; }
static uint32_t twostop_main_firmware(struct twostop_fmap *fmap, void *gbb, crossystem_data_t *cdata, void *vb_shared_data) { VbError_t err; VbSelectAndLoadKernelParams kparams; VbCommonParams cparams; size_t size = 0; #ifdef CONFIG_BOOTSTAGE_STASH bootstage_unstash((void *)CONFIG_BOOTSTAGE_STASH, CONFIG_BOOTSTAGE_STASH_SIZE); #endif bootstage_mark_name(BOOTSTAGE_VBOOT_TWOSTOP_MAIN_FIRMWARE, "twostop_main_firmware"); if (twostop_init_cparams(fmap, gbb, vb_shared_data, &cparams)) { VBDEBUG("failed to init cparams\n"); return TWOSTOP_SELECT_ERROR; } /* * Note that in case "kernel" is not found in the device tree, the * "size" value is going to remain unchanged. */ kparams.kernel_buffer = cros_fdtdec_alloc_region(gd->fdt_blob, "kernel", &size); kparams.kernel_buffer_size = size; VBDEBUG("kparams:\n"); VBDEBUG("- kernel_buffer: : %p\n", kparams.kernel_buffer); VBDEBUG("- kernel_buffer_size: : %08x\n", kparams.kernel_buffer_size); #ifdef CONFIG_EXYNOS_DISPLAYPORT /* * Make sure the LCD is up before we load the kernel. Partly this * is because VbSelectAndLoadKernel may do a software sync. */ exynos_lcd_check_next_stage(gd->fdt_blob, 1); #endif if ((err = VbSelectAndLoadKernel(&cparams, &kparams))) { VBDEBUG("VbSelectAndLoadKernel: %d\n", err); switch (err) { case VBERROR_SHUTDOWN_REQUESTED: return TWOSTOP_SELECT_POWER_OFF; case VBERROR_BIOS_SHELL_REQUESTED: return TWOSTOP_SELECT_COMMAND_LINE; case VBERROR_EC_REBOOT_TO_RO_REQUIRED: request_ec_reboot_to_ro(); return TWOSTOP_SELECT_POWER_OFF; } return TWOSTOP_SELECT_ERROR; } VBDEBUG("kparams:\n"); VBDEBUG("- kernel_buffer: : %p\n", kparams.kernel_buffer); VBDEBUG("- kernel_buffer_size: : %08x\n", kparams.kernel_buffer_size); VBDEBUG("- disk_handle: : %p\n", kparams.disk_handle); VBDEBUG("- partition_number: : %08x\n", kparams.partition_number); VBDEBUG("- bootloader_address: : %08llx\n", kparams.bootloader_address); VBDEBUG("- bootloader_size: : %08x\n", kparams.bootloader_size); VBDEBUG("- partition_guid: :"); #ifdef VBOOT_DEBUG int i; for (i = 0; i < 16; i++) VbExDebug(" %02x", kparams.partition_guid[i]); VbExDebug("\n"); #endif /* VBOOT_DEBUG */ /* EC might jump between RO and RW during software sync. We need to * update active EC copy in cdata. */ set_active_ec_firmware(cdata); crossystem_data_dump(cdata); #if defined(CONFIG_SANDBOX) return TWOSTOP_SELECT_COMMAND_LINE; #else boot_kernel(&kparams, cdata); /* It is an error if boot_kenel returns */ return TWOSTOP_SELECT_ERROR; #endif }
static VbError_t twostop_init_vboot_library(firmware_storage_t *file, void *gbb, uint32_t gbb_offset, size_t gbb_size, crossystem_data_t *cdata, VbCommonParams *cparams) { VbError_t err; VbInitParams iparams; int virtual_dev_switch = cros_fdtdec_config_has_prop(gd->fdt_blob, "virtual-dev-switch"); #ifdef CONFIG_MKBP struct mkbp_dev *mdev = board_get_mkbp_dev(); #endif memset(&iparams, 0, sizeof(iparams)); iparams.flags = check_ro_normal_support(); #ifdef CONFIG_MKBP if (mdev) { uint32_t ec_events = 0; const uint32_t kb_rec_mask = EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY); /* Read keyboard recovery flag from EC, then clear it */ if (mkbp_get_host_events(mdev, &ec_events)) { /* * TODO: what can we do if that fails? Request * recovery? We don't simply want to fail, because * that'll prevent us from going into recovery mode. * We don't want to go into recovery mode * automatically, because that'll break snow. */ VBDEBUG("VbInit: unable to read EC events\n"); ec_events = 0; } if (ec_events & kb_rec_mask) { iparams.flags |= VB_INIT_FLAG_REC_BUTTON_PRESSED; if (mkbp_clear_host_events(mdev, kb_rec_mask)) VBDEBUG("VbInit: unable to clear " "EC KB recovery event\n"); } } #endif if (cdata->boot_write_protect_switch) iparams.flags |= VB_INIT_FLAG_WP_ENABLED; if (cdata->boot_recovery_switch) iparams.flags |= VB_INIT_FLAG_REC_BUTTON_PRESSED; if (cdata->boot_developer_switch) iparams.flags |= VB_INIT_FLAG_DEV_SWITCH_ON; if (cdata->boot_oprom_loaded) iparams.flags |= VB_INIT_FLAG_OPROM_LOADED; if (cdata->oprom_matters) iparams.flags |= VB_INIT_FLAG_OPROM_MATTERS; if (virtual_dev_switch) iparams.flags |= VB_INIT_FLAG_VIRTUAL_DEV_SWITCH; if (cros_fdtdec_config_has_prop(gd->fdt_blob, "ec-software-sync")) iparams.flags |= VB_INIT_FLAG_EC_SOFTWARE_SYNC; if (cros_fdtdec_config_has_prop(gd->fdt_blob, "ec-slow-update")) iparams.flags |= VB_INIT_FLAG_EC_SLOW_UPDATE; if (flash_sw_wp_is_enabled(file)) iparams.flags |= VB_INIT_FLAG_SW_WP_ENABLED; VBDEBUG("iparams.flags: %08x\n", iparams.flags); if ((err = VbInit(cparams, &iparams))) { VBDEBUG("VbInit: %u\n", err); /* * If vboot wants EC to reboot to RO, make request now, * because there isn't a clear path to pass this request * through to do_vboot_twostop(). */ if (err == VBERROR_EC_REBOOT_TO_RO_REQUIRED) request_ec_reboot_to_ro(); return err; } #ifdef CONFIG_VIDEO_TEGRA tegra_lcd_check_next_stage(gd->fdt_blob, 0); #endif #ifdef CONFIG_EXYNOS_DISPLAYPORT exynos_lcd_check_next_stage(gd->fdt_blob, 0); #endif VBDEBUG("iparams.out_flags: %08x\n", iparams.out_flags); if (virtual_dev_switch) { cdata->boot_developer_switch = (iparams.out_flags & VB_INIT_OUT_ENABLE_DEVELOPER) ? 1 : 0; VBDEBUG("cdata->boot_developer_switch=%d\n", cdata->boot_developer_switch); } if (iparams.out_flags & VB_INIT_OUT_CLEAR_RAM) wipe_unused_memory(cdata, cparams); /* Load required information of GBB */ if (iparams.out_flags & VB_INIT_OUT_ENABLE_DISPLAY) { if (gbb_read_bmp_block(gbb, file, gbb_offset, gbb_size)) return VBERROR_INVALID_GBB; have_read_gbb_bmp_block = 1; } if (cdata->boot_developer_switch || iparams.out_flags & VB_INIT_OUT_ENABLE_RECOVERY) { if (gbb_read_recovery_key(gbb, file, gbb_offset, gbb_size)) return VBERROR_INVALID_GBB; } return VBERROR_SUCCESS; }