/* * Verify if the mirrored elog structure is valid. * Returns 1 if the header is valid, 0 otherwise */ static int elog_is_header_valid(void) { struct elog_header *header; elog_debug("elog_is_header_valid()\n"); header = rdev_mmap(mirror_dev_get(), 0, sizeof(*header)); if (header == NULL) { printk(BIOS_ERR, "ELOG: could not map header.\n"); return 0; } if (header->magic != ELOG_SIGNATURE) { printk(BIOS_ERR, "ELOG: header magic 0x%X != 0x%X\n", header->magic, ELOG_SIGNATURE); return 0; } if (header->version != ELOG_VERSION) { printk(BIOS_ERR, "ELOG: header version %u != %u\n", header->version, ELOG_VERSION); return 0; } if (header->header_size != sizeof(*header)) { printk(BIOS_ERR, "ELOG: header size mismatch %u != %zu\n", header->header_size, sizeof(*header)); return 0; } return 1; }
void *locate_rmu_file(size_t *rmu_file_len) { struct cbfsf fh; size_t fsize; void *rmu_data; uint32_t type; /* Locate the rmu.bin file in the read-only region of the flash */ type = CBFS_TYPE_RAW; if (cbfs_locate_file_in_region(&fh, "COREBOOT", "rmu.bin", &type)) return NULL; /* Get the file size */ fsize = region_device_sz(&fh.data); if (rmu_file_len != NULL) *rmu_file_len = fsize; /* Get the data address */ rmu_data = rdev_mmap(&fh.data, 0, fsize); /* Since the SPI flash is directly mapped into memory, we do not need * the mapping provided by the rdev service. Unmap the file to prevent * a memory leak. Return/leak the SPI flash address for the rmu.bin * file data which will be directly accessed by FSP MemoryInit. */ rdev_munmap(&fh.data, rmu_data); return rmu_data; }
size_t cbfs_load_and_decompress(const struct region_device *rdev, size_t offset, size_t in_size, void *buffer, size_t buffer_size, uint32_t compression) { size_t out_size; switch (compression) { case CBFS_COMPRESS_NONE: if (buffer_size < in_size) return 0; if (rdev_readat(rdev, buffer, offset, in_size) != in_size) return 0; return in_size; case CBFS_COMPRESS_LZ4: if ((ENV_BOOTBLOCK || ENV_VERSTAGE) && !IS_ENABLED(CONFIG_COMPRESS_PRERAM_STAGES)) return 0; /* Load the compressed image to the end of the available memory * area for in-place decompression. It is the responsibility of * the caller to ensure that buffer_size is large enough * (see compression.h, guaranteed by cbfstool for stages). */ void *compr_start = buffer + buffer_size - in_size; if (rdev_readat(rdev, compr_start, offset, in_size) != in_size) return 0; timestamp_add_now(TS_START_ULZ4F); out_size = ulz4fn(compr_start, in_size, buffer, buffer_size); timestamp_add_now(TS_END_ULZ4F); return out_size; case CBFS_COMPRESS_LZMA: if (ENV_BOOTBLOCK || ENV_VERSTAGE) return 0; if ((ENV_ROMSTAGE || ENV_POSTCAR) && !IS_ENABLED(CONFIG_COMPRESS_RAMSTAGE)) return 0; void *map = rdev_mmap(rdev, offset, in_size); if (map == NULL) return 0; /* Note: timestamp not useful for memory-mapped media (x86) */ timestamp_add_now(TS_START_ULZMA); out_size = ulzman(map, in_size, buffer, buffer_size); timestamp_add_now(TS_END_ULZMA); rdev_munmap(rdev, map); return out_size; default: return 0; } }
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); }
static void *emu_rom_map(struct cbfs_media *media, size_t offset, size_t count) { const struct region_device *boot_dev; void *ptr; boot_dev = media->context; ptr = rdev_mmap(boot_dev, offset, count); if (ptr == NULL) return (void *)-1; return ptr; }
void *cbfs_boot_map_with_leak(const char *name, uint32_t type, size_t *size) { struct cbfsf fh; size_t fsize; if (cbfs_boot_locate(&fh, name, &type)) return NULL; fsize = region_device_sz(&fh.data); if (size != NULL) *size = fsize; return rdev_mmap(&fh.data, 0, fsize); }
/* * Check if mirrored buffer is filled with ELOG_TYPE_EOL byte from the * provided offset to the end of the mirrored buffer. */ static int elog_is_buffer_clear(size_t offset) { size_t i; const struct region_device *rdev = mirror_dev_get(); size_t size = region_device_sz(rdev) - offset; uint8_t *buffer = rdev_mmap(rdev, offset, size); int ret = 1; elog_debug("elog_is_buffer_clear(offset=%zu size=%zu)\n", offset, size); if (buffer == NULL) return 0; for (i = 0; i < size; i++) { if (buffer[i] != ELOG_TYPE_EOL) { ret = 0; break; } } rdev_munmap(rdev, buffer); return ret; }
/* * Write 'size' bytes of data from provided 'offset' in the mirrored elog to * the flash backing store. This will not erase the flash and it assumes the * flash area has been erased appropriately. */ static void elog_nv_write(size_t offset, size_t size) { void *address; const struct region_device *rdev = mirror_dev_get(); if (!size) return; address = rdev_mmap(rdev, offset, size); elog_debug("%s(address=0x%p offset=0x%08zx size=%zu)\n", __func__, address, offset, size); if (address == NULL) return; /* Write the data to flash */ if (rdev_writeat(&nv_dev, address, offset, size) != size) printk(BIOS_ERR, "ELOG: NV Write failed at 0x%zx, size 0x%zx\n", offset, size); rdev_munmap(rdev, address); }
static struct event_header *elog_get_event_buffer(size_t offset, size_t size) { return rdev_mmap(mirror_dev_get(), offset, size); }