int vboot_is_slot_selected(void) { struct selected_region *reg = &vboot_get_working_data()->selected_region; assert(reg != NULL); return reg->size > 0; }
void vboot_set_selected_region(const struct region *region) { struct selected_region *reg = &vboot_get_working_data()->selected_region; assert(reg != NULL); reg->offset = region_offset(region); reg->size = region_sz(region); }
void vboot_finalize_work_context(struct vb2_context *ctx) { /* * Shrink buffer_size so that vboot_migrate_cbmem knows how * much of vboot_working_data needs to be copied into CBMEM * (if applicable), and so that downstream users know how much * of the workbuf is currently used. */ vboot_get_working_data()->buffer_size = ctx->workbuf_used; }
static void lb_vboot_workbuf(struct lb_header *header) { struct lb_range *vbwb; struct vboot_working_data *wd = vboot_get_working_data(); vbwb = (struct lb_range *)lb_new_record(header); vbwb->tag = LB_TAB_VBOOT_WORKBUF; vbwb->size = sizeof(*vbwb); vbwb->range_start = (uintptr_t)wd + wd->buffer_offset; vbwb->range_size = wd->buffer_size; }
static struct selected_region *vb2_selected_region(void) { struct selected_region *sel_reg = NULL; /* Ramstage and postcar always uses cbmem as a source of truth. */ if (ENV_RAMSTAGE || ENV_POSTCAR) sel_reg = cbmem_find(CBMEM_ID_VBOOT_SEL_REG); else if (ENV_ROMSTAGE) { /* Try cbmem first. Fall back on working data if not found. */ sel_reg = cbmem_find(CBMEM_ID_VBOOT_SEL_REG); if (sel_reg == NULL) { struct vb2_working_data *wd = vboot_get_working_data(); sel_reg = &wd->selected_region; } } else { /* Stages such as bootblock and verstage use working data. */ struct vb2_working_data *wd = vboot_get_working_data(); sel_reg = &wd->selected_region; } return sel_reg; }
void vboot_fill_handoff(void) { int i; struct vboot_handoff *vh; struct vb2_shared_data *sd; struct region_device fw_main; struct vboot_components *fw_info; size_t metadata_sz; struct vb2_working_data *wd = vboot_get_working_data(); sd = vboot_get_work_buffer(wd); sd->workbuf_hash_offset = 0; sd->workbuf_hash_size = 0; printk(BIOS_INFO, "creating vboot_handoff structure\n"); vh = cbmem_add(CBMEM_ID_VBOOT_HANDOFF, sizeof(*vh)); if (vh == NULL) /* we don't need to failover gracefully here because this * shouldn't happen with the image that has passed QA. */ die("failed to allocate vboot_handoff structure\n"); memset(vh, 0, sizeof(*vh)); /* needed until we finish transtion to vboot2 for kernel verification */ fill_vboot_handoff(vh, sd); /* Nothing left to do in readonly path. */ if (vboot_is_readonly_path(wd)) return; if (vb2_get_selected_region(wd, &fw_main)) die("No component metadata.\n"); metadata_sz = sizeof(*fw_info); metadata_sz += MAX_PARSED_FW_COMPONENTS * sizeof(fw_info->entries[0]); fw_info = rdev_mmap(&fw_main, 0, metadata_sz); if (fw_info == NULL) die("failed to locate firmware components\n"); /* these offset & size are used to load a rw boot loader */ for (i = 0; i < fw_info->num_components; i++) { vh->components[i].address = region_device_offset(&fw_main); vh->components[i].address += fw_info->entries[i].offset; vh->components[i].size = fw_info->entries[i].size; } rdev_munmap(&fw_main, fw_info); }
void vb2_store_selected_region(void) { const struct vb2_working_data *wd; struct selected_region *sel_reg; /* Always use the working data in this path since it's the object * which has the result.. */ wd = vboot_get_working_data(); sel_reg = cbmem_add(CBMEM_ID_VBOOT_SEL_REG, sizeof(*sel_reg)); assert(sel_reg != NULL); sel_reg->offset = wd->selected_region.offset; sel_reg->size = wd->selected_region.size; }
int vboot_get_selected_region(struct region *region) { const struct selected_region *reg = &vboot_get_working_data()->selected_region; if (reg == NULL) return -1; if (reg->offset == 0 && reg->size == 0) return -1; region->offset = reg->offset; region->size = reg->size; return 0; }
void vboot_init_work_context(struct vb2_context *ctx) { struct vboot_working_data *wd; /* First initialize the working data region. */ wd = vboot_get_working_data(); memset(wd, 0, VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE); /* * vboot prefers 16-byte alignment. This takes away 16 bytes * from the VBOOT2_WORK region, but the vboot devs said that's okay. */ wd->buffer_offset = ALIGN_UP(sizeof(*wd), 16); wd->buffer_size = VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE - wd->buffer_offset; /* Initialize the vb2_context. */ memset(ctx, 0, sizeof(*ctx)); ctx->workbuf = (void *)vboot_get_shared_data(); ctx->workbuf_size = wd->buffer_size; }
struct vb2_shared_data *vb2_get_shared_data(void) { struct vb2_working_data *wd = vboot_get_working_data(); return (void *)((uintptr_t)wd + wd->buffer_offset); }