示例#1
0
文件: smbios.c 项目: jpl888/coreboot
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;
}
示例#2
0
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;
}
示例#3
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;
}
示例#4
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;
}
示例#5
0
/* 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;
}