static uint8_t *read_gbb_from_firmware(void) { void *fdt_ptr = (void *)gd->fdt_blob; firmware_storage_t file; struct twostop_fmap fmap; void *gbb; size_t gbb_size; #ifndef CONFIG_HARDWARE_MAPPED_SPI gbb = cros_fdtdec_alloc_region(gd->fdt_blob, "google-binary-block", &gbb_size); if (!gbb) { VbExDebug("Failed to find gbb region!\n"); return NULL; } #endif if (cros_fdtdec_flashmap(fdt_ptr, &fmap)) { VbExDebug("Failed to load fmap config from fdt!\n"); return NULL; } /* Open firmware storage device. */ if (firmware_storage_open_spi(&file)) { VbExDebug("Failed to open firmware device!\n"); return NULL; } #ifdef CONFIG_HARDWARE_MAPPED_SPI { void *gbbp; if (gbb_init(&gbbp, &file, fmap.readonly.gbb.offset, 0)) { VbExDebug("Failed to read GBB!\n"); return NULL; } gbb = gbbp; gbb_size = fmap.readonly.gbb.length; } #else if (gbb_init(gbb, &file, fmap.readonly.gbb.offset, gbb_size)) { VbExDebug("Failed to read GBB!\n"); return NULL; } #endif if (gbb_read_bmp_block(gbb, &file, fmap.readonly.gbb.offset, gbb_size)) { VbExDebug("Failed to load BMP Block in GBB!\n"); return NULL; } if (file.close(&file)) { VbExDebug("Failed to close firmware device!\n"); } return gbb; }
int common_params_init(int clear_shared_data) { uint32_t save_gbb_size = cparams.gbb_size; void *save_gbb_data = cparams.gbb_data; // Set up the common param structure. memset(&cparams, 0, sizeof(cparams)); cparams_initialized = 1; // Restore GBB size/data if it was already initialized. if (gbb_initialized) { cparams.gbb_size = save_gbb_size; cparams.gbb_data = save_gbb_data; } else { if (gbb_init()) return 1; } void *blob; int size; if (find_common_params(&blob, &size)) return 1; cparams.shared_data_blob = blob; cparams.shared_data_size = size; if (clear_shared_data) memset(blob, 0, size); return 0; }
uint32_t gbb_get_flags(void) { GoogleBinaryBlockHeader *header; if (gbb_init() != 0) return 0; header = cparams.gbb_data; return header->flags; }
int gbb_clear_flags(void) { /* If WP is enabled, cannot write to RO-GBB. */ if (flash_is_wp_enabled() != 0) return 1; if (gbb_init() != 0) return 1; FmapArea area; if (fmap_find_area("GBB", &area)) { printf("Couldn't find the GBB.\n"); return 1; } GoogleBinaryBlockHeader *header = cparams.gbb_data; header->flags = 0; gbb_copy_out(area.offset, 0, sizeof(*header)); 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; }