static int smbios_write_type0(unsigned long *current, int handle) { struct smbios_type0 *t = (struct smbios_type0 *)*current; int len = sizeof(struct smbios_type0); memset(t, 0, sizeof(struct smbios_type0)); t->type = SMBIOS_BIOS_INFORMATION; t->handle = handle; t->length = len - 2; t->vendor = smbios_add_string(t->eos, "coreboot"); #if !CONFIG_CHROMEOS t->bios_release_date = smbios_add_string(t->eos, COREBOOT_DMI_DATE); if (strlen(CONFIG_LOCALVERSION)) t->bios_version = smbios_add_string(t->eos, CONFIG_LOCALVERSION); else t->bios_version = smbios_add_string(t->eos, COREBOOT_VERSION); #else #define SPACES \ " " t->bios_release_date = smbios_add_string(t->eos, COREBOOT_DMI_DATE); u32 version_offset = (u32)smbios_string_table_len(t->eos); t->bios_version = smbios_add_string(t->eos, SPACES); /* SMBIOS offsets start at 1 rather than 0 */ vboot_data->vbt10 = (u32)t->eos + (version_offset - 1); #endif { const struct cbfs_header *header; u32 romsize = CONFIG_ROM_SIZE; header = cbfs_get_header(CBFS_DEFAULT_MEDIA); if (header != CBFS_HEADER_INVALID_ADDRESS) romsize = ntohl(header->romsize); t->bios_rom_size = (romsize / 65535) - 1; } t->system_bios_major_release = 4; t->bios_characteristics = BIOS_CHARACTERISTICS_PCI_SUPPORTED | #if CONFIG_CARDBUS_PLUGIN_SUPPORT BIOS_CHARACTERISTICS_PC_CARD | #endif BIOS_CHARACTERISTICS_SELECTABLE_BOOT | BIOS_CHARACTERISTICS_UPGRADEABLE; #if CONFIG_GENERATE_ACPI_TABLES t->bios_characteristics_ext1 = BIOS_EXT1_CHARACTERISTICS_ACPI; #endif t->bios_characteristics_ext2 = BIOS_EXT2_CHARACTERISTICS_TARGET; len = t->length + smbios_string_table_len(t->eos); *current += len; return len; }
static int get_cbfs_range(uint32_t *offset, uint32_t *cbfs_end, struct cbfs_media *media) { const struct cbfs_header *header; if (media == CBFS_DEFAULT_MEDIA && lib_sysinfo.cbfs_offset && lib_sysinfo.cbfs_size) { *offset = lib_sysinfo.cbfs_offset; *cbfs_end = *offset + lib_sysinfo.cbfs_size; return 0; } /* * If sysinfo doesn't have offset or size, we read them from * a master header. */ DEBUG("CBFS offset & size not found in sysinfo\n"); header = cbfs_get_header(media); if (header == CBFS_HEADER_INVALID_ADDRESS) return -1; // Logical offset (for source media) of first file. *offset = ntohl(header->offset); *cbfs_end = ntohl(header->romsize); #if IS_ENABLED(CONFIG_LP_ARCH_X86) // resolve actual length of ROM used for CBFS components // the bootblock size was not taken into account *cbfs_end -= ntohl(header->bootblocksize); // fine tune the length to handle alignment positioning. // using (bootblock size) % align, to derive the // number of bytes the bootblock is off from the alignment size. if ((ntohl(header->bootblocksize) % CBFS_ALIGNMENT)) *cbfs_end -= (CBFS_ALIGNMENT - (ntohl(header->bootblocksize) % CBFS_ALIGNMENT)); else *cbfs_end -= 1; #endif return 0; }
int cbfs_image_from_file(struct cbfs_image *image, const char *filename) { void *header_loc; if (buffer_from_file(&image->buffer, filename) != 0) return -1; DEBUG("read_cbfs_image: %s (%zd bytes)\n", image->buffer.name, image->buffer.size); header_loc = cbfs_find_header(image->buffer.data, image->buffer.size); if (!header_loc) { ERROR("%s does not have CBFS master header.\n", filename); cbfs_image_delete(image); return -1; } if ((image->header = malloc(sizeof(*image->header))) == NULL) return -1; cbfs_get_header(image->header, header_loc); cbfs_fix_legacy_size(image, header_loc); return 0; }
/* public API starts here*/ struct cbfs_file *cbfs_get_file(struct cbfs_media *media, const char *name) { const char *vardata; uint32_t offset, romsize, vardata_len; const struct cbfs_header *header; struct cbfs_file file, *file_ptr; struct cbfs_media default_media; if (media == CBFS_DEFAULT_MEDIA) { media = &default_media; if (init_default_cbfs_media(media) != 0) { ERROR("Failed to initialize default media.\n"); return NULL; } } if (CBFS_HEADER_INVALID_ADDRESS == (header = cbfs_get_header(media))) return NULL; // Logical offset (for source media) of first file. offset = ntohl(header->offset); romsize = ntohl(header->romsize); // TODO Add a "size" in CBFS header for a platform independent way to // determine the end of CBFS data. #if IS_ENABLED(CONFIG_LP_ARCH_X86) // resolve actual length of ROM used for CBFS components // the bootblock size was not taken into account romsize -= ntohl(header->bootblocksize); // fine tune the length to handle alignment positioning. // using (bootblock size) % align, to derive the // number of bytes the bootblock is off from the alignment size. if ((ntohl(header->bootblocksize) % CBFS_ALIGNMENT)) romsize -= (CBFS_ALIGNMENT - (ntohl(header->bootblocksize) % CBFS_ALIGNMENT)); else romsize -= 1; #endif DEBUG("CBFS location: 0x%x~0x%x\n", offset, romsize); DEBUG("Looking for '%s' starting from 0x%x.\n", name, offset); media->open(media); while (offset < romsize && media->read(media, &file, offset, sizeof(file)) == sizeof(file)) { if (memcmp(CBFS_FILE_MAGIC, file.magic, sizeof(file.magic)) != 0) { uint32_t new_align = CBFS_ALIGNMENT; if (offset % CBFS_ALIGNMENT) new_align += CBFS_ALIGNMENT - (offset % CBFS_ALIGNMENT); ERROR("ERROR: No file header found at 0x%xx - " "try next aligned address: 0x%x.\n", offset, offset + new_align); offset += new_align; continue; } vardata_len = ntohl(file.offset) - sizeof(file); DEBUG(" - load entry 0x%x variable data (%d bytes)...\n", offset, vardata_len); // load file name (arbitrary length). vardata = (const char*)media->map( media, offset + sizeof(file), vardata_len); if (vardata == CBFS_MEDIA_INVALID_MAP_ADDRESS) { ERROR("ERROR: Failed to get filename: 0x%x.\n", offset); } else if (strcmp(vardata, name) == 0) { int file_offset = ntohl(file.offset), file_len = ntohl(file.len); DEBUG("Found file (offset=0x%x, len=%d).\n", offset + file_offset, file_len); media->unmap(media, vardata); file_ptr = media->map(media, offset, file_offset + file_len); media->close(media); return file_ptr; } else { DEBUG(" (unmatched file @0x%x: %s)\n", offset, vardata); media->unmap(media, vardata); } // Move to next file. offset += ntohl(file.len) + ntohl(file.offset); if (offset % CBFS_ALIGNMENT) offset += CBFS_ALIGNMENT - (offset % CBFS_ALIGNMENT); } media->close(media); LOG("WARNING: '%s' not found.\n", name); return NULL; }
/* public API starts here*/ ssize_t cbfs_locate_file(struct cbfs_media *media, struct cbfs_file *file, const char *name) { const char *file_name; uint32_t offset, align, romsize, name_len; const struct cbfs_header *header; struct cbfs_media default_media; if (init_backing_media(&media, &default_media)) return -1; if (CBFS_HEADER_INVALID_ADDRESS == (header = cbfs_get_header(media))) return -1; // Logical offset (for source media) of first file. offset = ntohl(header->offset); align = ntohl(header->align); romsize = ntohl(header->romsize); // TODO Add a "size" in CBFS header for a platform independent way to // determine the end of CBFS data. #if defined(CONFIG_ARCH_X86) && CONFIG_ARCH_X86 // resolve actual length of ROM used for CBFS components // the bootblock size was not taken into account romsize -= ntohl(header->bootblocksize); // fine tune the length to handle alignment positioning. // using (bootblock size) % align, to derive the // number of bytes the bootblock is off from the alignment size. if ((ntohl(header->bootblocksize) % align)) romsize -= (align - (ntohl(header->bootblocksize) % align)); else romsize -= 1; #endif DEBUG("CBFS location: 0x%x~0x%x, align: %d\n", offset, romsize, align); DEBUG("Looking for '%s' starting from 0x%x.\n", name, offset); media->open(media); while (offset < romsize && media->read(media, file, offset, sizeof(*file)) == sizeof(*file)) { if (memcmp(CBFS_FILE_MAGIC, file->magic, sizeof(file->magic)) != 0) { uint32_t new_align = align; if (offset % align) new_align += align - (offset % align); LOG("WARNING: No file header found at 0x%x - " "try next aligned address: 0x%x.\n", offset, offset + new_align); offset += new_align; continue; } file->len = ntohl(file->len); file->type= ntohl(file->type); file->offset = ntohl(file->offset); name_len = file->offset - sizeof(*file); DEBUG(" - load entry 0x%x file name (%d bytes)...\n", offset, name_len); // load file name (arbitrary length). file_name = (const char *)media->map( media, offset + sizeof(*file), name_len); if (file_name == CBFS_MEDIA_INVALID_MAP_ADDRESS) { ERROR("ERROR: Failed to get filename: 0x%x.\n", offset); } else if (strcmp(file_name, name) == 0) { DEBUG("Found file (offset=0x%x, len=%d).\n", offset + file->offset, file->len); media->unmap(media, file_name); return offset + file->offset; } else { DEBUG(" (unmatched file @0x%x: %s)\n", offset, file_name); media->unmap(media, file_name); } // Move to next file. offset += file->len + file->offset; if (offset % align) offset += align - (offset % align); } media->close(media); LOG("WARNING: '%s' not found.\n", name); return -1; }