Aaron Durbin (adurbin@chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9134
-gerrit
commit 5d0e851364eed6d3954a1954367963878ad9a862 Author: Aaron Durbin adurbin@chromium.org Date: Fri May 15 23:39:23 2015 -0500
cbfs: new API and better program loading
A new CBFS API is introduced to allow making CBFS access easier for providing multiple CBFS sources. That is achieved by decoupling the cbfs source from a CBFS file. A CBFS source is described by a descriptor. It contains the necessary properties for walking a CBFS to locate a file. The CBFS file is then decoupled from the CBFS descriptor in that it's no longer needed to access the contents of the file.
All of this is accomplished using the regions infrastructure by repsenting CBFS sources and files as region_devices. Because region_devices can be chained together forming subregions this allows one to decouple a CBFS source from a file. This also allows one to provide CBFS files that came from other sources for payload and/or stage loading.
The program loading takes advantage of those very properties by allowing multiple sources for locating a program. Because of this we can reduce the overhead of loading programs because it's all done in the common code paths. Only locating the program is per source.
Change-Id: I339b84fce95f03d1dbb63a0f54a26be5eb07f7c8 Signed-off-by: Aaron Durbin adurbin@chromium.org --- src/arch/arm/armv7/bootblock_simple.c | 3 - src/arch/arm64/arm_tf.c | 48 +-- src/arch/riscv/rom_media.c | 67 +---- src/arch/x86/boot/acpi.c | 3 +- src/arch/x86/lib/Makefile.inc | 3 - src/arch/x86/lib/mmap_boot.c | 44 +++ src/arch/x86/lib/rom_media.c | 97 ------ src/cpu/allwinner/a10/bootblock_media.c | 8 +- src/cpu/amd/microcode/microcode.c | 4 +- src/cpu/intel/microcode/microcode.c | 18 +- src/cpu/ti/am335x/bootblock_media.c | 71 +---- src/cpu/ti/am335x/nand.c | 8 +- src/cpu/via/nano/update_ucode.c | 5 +- src/device/dram/spd_cache.c | 4 +- src/device/oprom/realmode/x86.c | 9 +- src/device/oprom/yabel/vbe.c | 7 +- src/device/pci_rom.c | 8 +- src/drivers/intel/fsp1_0/fastboot_cache.c | 7 +- src/drivers/intel/fsp1_1/fastboot_cache.c | 3 +- src/drivers/intel/fsp1_1/fsp_gop.c | 10 +- src/drivers/pc80/mc146818rtc.c | 8 +- src/drivers/spi/spi_flash.c | 7 +- src/include/cbfs.h | 121 ++++---- src/include/cbfs_core.h | 128 -------- src/include/fallback.h | 2 +- src/include/memlayout.h | 2 - src/include/program_loading.h | 22 +- src/include/rmodule.h | 4 +- src/include/romstage_handoff.h | 10 - src/include/symbols.h | 1 - src/lib/Makefile.inc | 17 +- src/lib/cbfs.c | 334 ++++++++++++--------- src/lib/cbfs_boot_props.c | 66 ++++ src/lib/cbfs_core.c | 324 -------------------- src/lib/cbfs_core.h | 47 --- src/lib/cbfs_spi.c | 72 ----- src/lib/coreboot_table.c | 4 +- src/lib/hardwaremain.c | 2 - src/lib/loaders/Makefile.inc | 27 -- src/lib/loaders/cbfs_payload_loader.c | 43 --- src/lib/loaders/cbfs_ramstage_loader.c | 56 ---- src/lib/loaders/cbfs_romstage_loader.c | 31 -- src/lib/loaders/load_and_run_payload.c | 118 -------- src/lib/loaders/load_and_run_ramstage.c | 109 ------- src/lib/loaders/load_and_run_romstage.c | 85 ------ src/lib/prog_loaders.c | 247 +++++++++++++++ src/lib/rmodule.c | 54 ++-- src/lib/selfboot.c | 21 +- src/mainboard/emulation/qemu-armv7/media.c | 75 +---- src/mainboard/google/bolt/romstage.c | 4 +- src/mainboard/google/butterfly/mainboard.c | 5 +- src/mainboard/google/falco/romstage.c | 4 +- src/mainboard/google/link/romstage.c | 4 +- src/mainboard/google/panther/lan.c | 3 +- src/mainboard/google/peach_pit/romstage.c | 17 +- src/mainboard/google/peppy/romstage.c | 4 +- src/mainboard/google/rambi/romstage.c | 9 +- src/mainboard/google/samus/spd/spd.c | 13 +- src/mainboard/google/slippy/romstage.c | 4 +- src/mainboard/google/urara/boardid.c | 23 +- src/mainboard/samsung/lumpy/romstage.c | 4 +- src/mainboard/siemens/mc_tcu3/modhwinfo.c | 6 +- src/northbridge/amd/agesa/common/common.c | 3 +- src/northbridge/amd/agesa/def_callouts.c | 4 +- src/northbridge/amd/pi/agesawrapper.c | 11 +- src/northbridge/amd/pi/def_callouts.c | 4 +- src/northbridge/intel/haswell/mrccache.c | 3 +- src/northbridge/intel/haswell/raminit.c | 4 +- src/northbridge/intel/i82830/vga.c | 3 +- src/northbridge/intel/sandybridge/mrccache.c | 3 +- src/northbridge/intel/sandybridge/raminit.c | 3 +- src/soc/broadcom/cygnus/include/soc/memlayout.ld | 1 - src/soc/intel/baytrail/refcode.c | 67 +---- src/soc/intel/baytrail/romstage/raminit.c | 3 +- src/soc/intel/braswell/romstage/raminit.c | 3 +- src/soc/intel/broadwell/refcode.c | 69 +---- src/soc/intel/broadwell/romstage/raminit.c | 3 +- src/soc/nvidia/tegra124/spi.c | 75 ----- src/soc/nvidia/tegra132/ccplex.c | 15 +- src/soc/nvidia/tegra132/spi.c | 75 ----- src/soc/qualcomm/ipq806x/blobs_init.c | 12 +- src/soc/qualcomm/ipq806x/include/soc/memlayout.ld | 3 +- src/soc/samsung/exynos5250/alternate_cbfs.c | 64 ---- src/soc/samsung/exynos5420/alternate_cbfs.c | 64 ---- .../google/chromeos/vboot2/vboot_loader.c | 149 ++++----- 85 files changed, 892 insertions(+), 2313 deletions(-)
diff --git a/src/arch/arm/armv7/bootblock_simple.c b/src/arch/arm/armv7/bootblock_simple.c index 903c24d..4dc0975 100644 --- a/src/arch/arm/armv7/bootblock_simple.c +++ b/src/arch/arm/armv7/bootblock_simple.c @@ -21,7 +21,6 @@ #include <arch/exception.h> #include <arch/stages.h> #include <bootblock_common.h> -#include <cbfs.h> #include <console/console.h> #include <delay.h> #include <program_loading.h> @@ -45,8 +44,6 @@ void main(void) exception_init(); #endif
- cbfs_set_header_offset(0); - bootblock_soc_init(); bootblock_mainboard_init();
diff --git a/src/arch/arm64/arm_tf.c b/src/arch/arm64/arm_tf.c index c5d46e3..2ab0151 100644 --- a/src/arch/arm64/arm_tf.c +++ b/src/arch/arm64/arm_tf.c @@ -22,7 +22,7 @@ #include <assert.h> #include <cbfs.h> #include <cbmem.h> -#include <vendorcode/google/chromeos/vboot_handoff.h> +#include <program_loading.h>
/* * TODO: Many of these structures are currently unused. Better not fill them out @@ -37,47 +37,21 @@ static entry_point_info_t bl32_ep_info; static entry_point_info_t bl33_ep_info; static bl31_params_t bl31_params;
-/* TODO: Replace with glorious new CBFSv1 solution when it's available. */ -static void *vboot_get_bl31(void) -{ - void *bl31_entry; - struct cbfs_media *media; - struct firmware_component *component; - struct vboot_handoff *handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF); - - if (!handoff) - return NULL; - - assert(CONFIG_VBOOT_BL31_INDEX < MAX_PARSED_FW_COMPONENTS); - component = &handoff->components[CONFIG_VBOOT_BL31_INDEX]; - - /* components[] is zeroed out before filling, so size == 0 -> missing */ - if (!component->size) - return NULL; - - init_default_cbfs_media(media); - bl31_entry = cbfs_load_stage_by_offset(media, component->address); - if (bl31_entry == CBFS_LOAD_ERROR) - return NULL; - - printk(BIOS_INFO, "Loaded %u bytes verified BL31 from %#.8x to EP %p\n", - component->size, component->address, bl31_entry); - return bl31_entry; -} - void arm_tf_run_bl31(u64 payload_entry, u64 payload_arg0, u64 payload_spsr) { - const char *bl31_filename = CONFIG_CBFS_PREFIX"/bl31"; + struct prog bl31 = { + .type = PROG_BL31, + .name = CONFIG_CBFS_PREFIX"/bl31", + }; void (*bl31_entry)(bl31_params_t *params, void *plat_params) = NULL;
- if (IS_ENABLED(CONFIG_VBOOT2_VERIFY_FIRMWARE)) - bl31_entry = vboot_get_bl31(); + if (prog_locate(&bl31)) + die("BL31 not found"); + + if (cbfs_prog_stage_load(&bl31)) + die("BL31 load failed");
- if (!bl31_entry) { - bl31_entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA, bl31_filename); - if (bl31_entry == CBFS_LOAD_ERROR) - die("BL31 not found in CBFS"); - } + bl31_entry = prog_entry(&bl31);
SET_PARAM_HEAD(&bl31_params, PARAM_BL31, VERSION_1, 0); bl31_params.bl33_ep_info = &bl33_ep_info; diff --git a/src/arch/riscv/rom_media.c b/src/arch/riscv/rom_media.c index f18030c..dd57849 100644 --- a/src/arch/riscv/rom_media.c +++ b/src/arch/riscv/rom_media.c @@ -18,76 +18,13 @@ * Foundation, Inc. */ #include <boot_device.h> -#include <cbfs.h> -#include <console/console.h> -#include <string.h>
/* This assumes that the CBFS resides at 0x0, which is true for the default * configuration. */ -static const struct mem_region_device gboot_dev = +static const struct mem_region_device boot_dev = MEM_REGION_DEV_INIT(NULL, CONFIG_ROM_SIZE);
const struct region_device *boot_device_ro(void) { - return &gboot_dev.rdev; -} - -static int rom_media_open(struct cbfs_media *media) { - return 0; -} - -static void *rom_media_map(struct cbfs_media *media, size_t offset, size_t count) { - const struct region_device *boot_dev; - void *ptr; - - printk(BIOS_INFO, "%s: media %p, offset %lx, size %ld.\n", __func__, media, offset, count); - boot_dev = media->context; - - ptr = rdev_mmap(boot_dev, offset, count); - - if (ptr == NULL) - return (void *)-1; - - return ptr; -} - -static void *rom_media_unmap(struct cbfs_media *media, const void *address) { - const struct region_device *boot_dev; - - boot_dev = media->context; - - rdev_munmap(boot_dev, (void *)address); - - return NULL; -} - -static size_t rom_media_read(struct cbfs_media *media, void *dest, size_t offset, - size_t count) { - const struct region_device *boot_dev; - - boot_dev = media->context; - - if (rdev_readat(boot_dev, dest, offset, count) < 0) - return 0; - - return count; -} - -static int rom_media_close(struct cbfs_media *media) { - return 0; -} - -static int init_rom_media_cbfs(struct cbfs_media *media) { - boot_device_init(); - media->context = (void *)boot_device_ro(); - media->open = rom_media_open; - media->close = rom_media_close; - media->map = rom_media_map; - media->unmap = rom_media_unmap; - media->read = rom_media_read; - return 0; -} - -int init_default_cbfs_media(struct cbfs_media *media) { - return init_rom_media_cbfs(media); + return &boot_dev.rdev; } diff --git a/src/arch/x86/boot/acpi.c b/src/arch/x86/boot/acpi.c index bc2a0cc..6f6074e 100644 --- a/src/arch/x86/boot/acpi.c +++ b/src/arch/x86/boot/acpi.c @@ -707,8 +707,7 @@ unsigned long write_acpi_tables(unsigned long start) if (fw) return fw;
- slic_file = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, - CONFIG_CBFS_PREFIX "/slic", + slic_file = cbfs_boot_map_with_leak(CONFIG_CBFS_PREFIX "/slic", CBFS_TYPE_RAW, &slic_size); if (slic_file && (slic_file->length > slic_size || slic_file->length < sizeof (acpi_header_t))) { diff --git a/src/arch/x86/lib/Makefile.inc b/src/arch/x86/lib/Makefile.inc index e308be9..0d88a6d 100644 --- a/src/arch/x86/lib/Makefile.inc +++ b/src/arch/x86/lib/Makefile.inc @@ -5,7 +5,6 @@ romstage-y += cbfs_and_run.c romstage-y += memset.c romstage-y += memcpy.c romstage-y += memmove.c -romstage-y += rom_media.c romstage-y += mmap_boot.c
endif # CONFIG_ARCH_ROMSTAGE_X86_32 @@ -22,7 +21,6 @@ ramstage-y += memset.c ramstage-y += memcpy.c ramstage-y += memmove.c ramstage-y += ebda.c -ramstage-y += rom_media.c ramstage-y += mmap_boot.c ramstage-$(CONFIG_COOP_MULTITASKING) += thread.c ramstage-$(CONFIG_COOP_MULTITASKING) += thread_switch.S @@ -33,7 +31,6 @@ romstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c smm-y += memset.c smm-y += memcpy.c smm-y += memmove.c -smm-y += rom_media.c smm-y += mmap_boot.c
rmodules_x86_32-y += memset.c diff --git a/src/arch/x86/lib/mmap_boot.c b/src/arch/x86/lib/mmap_boot.c index eb7b23e..4dd269b 100644 --- a/src/arch/x86/lib/mmap_boot.c +++ b/src/arch/x86/lib/mmap_boot.c @@ -18,6 +18,10 @@ */
#include <boot_device.h> +#include <console/console.h> +#include <cbfs.h> +#include <endian.h> +#include <stdlib.h>
/* The ROM is memory mapped just below 4GiB. Form a pointer for the base. */ #define rom_base ((void *)(uintptr_t)(-(int32_t)CONFIG_ROM_SIZE)) @@ -29,3 +33,43 @@ const struct region_device *boot_device_ro(void) { return &boot_dev.rdev; } + +int cbfs_boot_region_properties(struct cbfs_props *props) +{ + struct cbfs_header header; + int32_t offset; + const struct region_device *bdev; + + bdev = boot_device_ro(); + + rdev_readat(bdev, &offset, CONFIG_ROM_SIZE - sizeof(offset), + sizeof(offset)); + + /* The offset is relative to the end of the media. */ + offset += CONFIG_ROM_SIZE; + + rdev_readat(bdev, &header , offset, sizeof(header)); + + header.magic = ntohl(header.magic); + header.romsize = ntohl(header.romsize); + header.bootblocksize = ntohl(header.bootblocksize); + header.align = ntohl(header.align); + header.offset = ntohl(header.offset); + + if (header.magic != CBFS_HEADER_MAGIC) + return -1; + + props->align = header.align; + props->offset = header.offset; + if (CONFIG_ROM_SIZE != header.romsize) + props->size = CONFIG_ROM_SIZE; + else + props->size = header.romsize; + props->size -= props->offset; + props->size -= header.bootblocksize; + props->size = ALIGN_DOWN(props->size, props->align); + + printk(BIOS_DEBUG, "CBFS @ %zx size %zx\n", props->offset, props->size); + + return 0; +} diff --git a/src/arch/x86/lib/rom_media.c b/src/arch/x86/lib/rom_media.c deleted file mode 100644 index d4663c7..0000000 --- a/src/arch/x86/lib/rom_media.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2013 The Chromium OS Authors. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2 of - * the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc. - */ - -#include <boot_device.h> -#include <cbfs.h> -#include <string.h> - -#ifdef LIBPAYLOAD -# define printk(x...) -# define init_default_cbfs_media libpayload_init_default_cbfs_media - extern int libpayload_init_default_cbfs_media(struct cbfs_media *media); -#else -# include <console/console.h> -#endif - -// Implementation of memory-mapped ROM media source on X86. - -static int x86_rom_open(struct cbfs_media *media) { - return 0; -} - -static void *x86_rom_map(struct cbfs_media *media, size_t offset, size_t count) { - void *ptr; - const struct region_device *boot_dev; - - boot_dev = media->context; - - /* Extremely large offsets are considered relative to end of region. */ - if ((uint32_t)offset > (uint32_t)0xf0000000) - offset += region_device_sz(boot_dev); - - ptr = rdev_mmap(boot_dev, offset, count); - - if (ptr == NULL) - return (void *)-1; - - return ptr; -} - -static void *x86_rom_unmap(struct cbfs_media *media, const void *address) { - return NULL; -} - -static size_t x86_rom_read(struct cbfs_media *media, void *dest, size_t offset, - size_t count) { - void *ptr; - - ptr = x86_rom_map(media, offset, count); - - if (ptr == (void *)-1) - return 0; - - memcpy(dest, ptr, count); - x86_rom_unmap(media, ptr); - return count; -} - -static int x86_rom_close(struct cbfs_media *media) { - return 0; -} - -static int init_x86rom_cbfs_media(struct cbfs_media *media) { - boot_device_init(); - - media->context = (void *)boot_device_ro(); - - if (media->context == NULL) - return -1; - - media->open = x86_rom_open; - media->close = x86_rom_close; - media->map = x86_rom_map; - media->unmap = x86_rom_unmap; - media->read = x86_rom_read; - return 0; -} - -int init_default_cbfs_media(struct cbfs_media *media) { - return init_x86rom_cbfs_media(media); -} diff --git a/src/cpu/allwinner/a10/bootblock_media.c b/src/cpu/allwinner/a10/bootblock_media.c index a585bca..17c6039 100644 --- a/src/cpu/allwinner/a10/bootblock_media.c +++ b/src/cpu/allwinner/a10/bootblock_media.c @@ -5,16 +5,10 @@ * Subject to the GNU GPL v2, or (at your option) any later version. */ #include <boot_device.h> -#include <cbfs.h> #include <console/console.h>
const struct region_device *boot_device_ro(void) { - return NULL; -} - -int init_default_cbfs_media(struct cbfs_media *media) -{ printk(BIOS_ERR, "Oh my! I don't know how to access CBFS yet."); - return -1; + return NULL; } diff --git a/src/cpu/amd/microcode/microcode.c b/src/cpu/amd/microcode/microcode.c index 8e3f4de..45e4bf0 100644 --- a/src/cpu/amd/microcode/microcode.c +++ b/src/cpu/amd/microcode/microcode.c @@ -105,8 +105,8 @@ void amd_update_microcode_from_cbfs(u32 equivalent_processor_rev_id) return; }
- ucode = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, MICROCODE_CBFS_FILE, - CBFS_TYPE_MICROCODE, &ucode_len); + ucode = cbfs_boot_map_with_leak(MICROCODE_CBFS_FILE, + CBFS_TYPE_MICROCODE, &ucode_len); if (!ucode) { UCODE_DEBUG("microcode file not found. Skipping updates.\n"); return; diff --git a/src/cpu/intel/microcode/microcode.c b/src/cpu/intel/microcode/microcode.c index 88435cc..3492bfd 100644 --- a/src/cpu/intel/microcode/microcode.c +++ b/src/cpu/intel/microcode/microcode.c @@ -109,25 +109,29 @@ void intel_microcode_load_unlocked(const void *microcode_patch)
const void *intel_microcode_find(void) { - struct cbfs_file *microcode_file; const struct microcode *ucode_updates; - u32 eax, microcode_len; + size_t microcode_len; + u32 eax; u32 pf, rev, sig, update_size; unsigned int x86_model, x86_family; msr_t msr;
#ifdef __PRE_RAM__ - microcode_file = walkcbfs_head((char *) MICROCODE_CBFS_FILE); -#else - microcode_file = cbfs_get_file(CBFS_DEFAULT_MEDIA, - MICROCODE_CBFS_FILE); -#endif + struct cbfs_file *microcode_file;
+ microcode_file = walkcbfs_head((char *) MICROCODE_CBFS_FILE); if (!microcode_file) return NULL;
ucode_updates = CBFS_SUBHEADER(microcode_file); microcode_len = ntohl(microcode_file->len); +#else + ucode_updates = cbfs_boot_map_with_leak(MICROCODE_CBFS_FILE, + CBFS_TYPE_MICROCODE, + µcode_len); + if (ucode_updates == NULL) + return NULL; +#endif
/* CPUID sets MSR 0x8B iff a microcode update has been loaded. */ msr.lo = 0; diff --git a/src/cpu/ti/am335x/bootblock_media.c b/src/cpu/ti/am335x/bootblock_media.c index 79724ee..0a8ccb6 100644 --- a/src/cpu/ti/am335x/bootblock_media.c +++ b/src/cpu/ti/am335x/bootblock_media.c @@ -18,80 +18,13 @@ */
#include <boot_device.h> -#include <cbfs.h> -#include <console/console.h> -#include <string.h> #include <symbols.h>
/* FIXME: No idea how big the internal SRAM actually is. */ -static const struct mem_region_device gboot_dev = +static const struct mem_region_device boot_dev = MEM_REGION_DEV_INIT(_dram, CONFIG_ROM_SIZE);
const struct region_device *boot_device_ro(void) { - return &gboot_dev.rdev; -} - -static int dummy_open(struct cbfs_media *media) -{ - return 0; -} - -static int dummy_close(struct cbfs_media *media) -{ - return 0; -} - -static void * on_chip_memory_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; -} - -static void * dummy_unmap(struct cbfs_media *media, const void *address) -{ - const struct region_device *boot_dev; - - boot_dev = media->context; - - rdev_munmap(boot_dev, (void *)address); - - return NULL; -} - -static size_t on_chip_memory_read(struct cbfs_media *media, void *dest, - size_t offset, size_t count) -{ - const struct region_device *boot_dev; - - boot_dev = media->context; - - if (rdev_readat(boot_dev, dest, offset, count) < 0) - return 0; - - return count; -} - -int init_default_cbfs_media(struct cbfs_media *media) -{ - boot_device_init(); - - media->context = (void *)boot_device_ro(); - media->open = dummy_open; - media->close = dummy_close; - media->map = on_chip_memory_map; - media->unmap = dummy_unmap; - media->read = on_chip_memory_read; - - return 0; + return &boot_dev.rdev; } diff --git a/src/cpu/ti/am335x/nand.c b/src/cpu/ti/am335x/nand.c index dd05fb6..4ac359d 100644 --- a/src/cpu/ti/am335x/nand.c +++ b/src/cpu/ti/am335x/nand.c @@ -18,15 +18,9 @@ */
#include <boot_device.h> -#include <cbfs.h>
const struct region_device *boot_device_ro(void) { - return NULL; -} - -int init_default_cbfs_media(struct cbfs_media *media) -{ /* FIXME: add support for reading coreboot from NAND */ - return -1; + return NULL; } diff --git a/src/cpu/via/nano/update_ucode.c b/src/cpu/via/nano/update_ucode.c index aa0adeb..a69a291 100644 --- a/src/cpu/via/nano/update_ucode.c +++ b/src/cpu/via/nano/update_ucode.c @@ -110,9 +110,8 @@ unsigned int nano_update_ucode(void) u32 *ucode_data; size_t ucode_len;
- ucode_data = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, - "cpu_microcode_blob.bin", - CBFS_TYPE_MICROCODE, &ucode_len); + ucode_data = cbfs_boot_map_with_leak("cpu_microcode_blob.bin", + CBFS_TYPE_MICROCODE, &ucode_len); /* Oops, did you forget to include the microcode ? */ if(ucode_data == NULL) { printk(BIOS_ALERT, "WARNING: No microcode file found in CBFS. " diff --git a/src/device/dram/spd_cache.c b/src/device/dram/spd_cache.c index 62e19a6..c8222de 100644 --- a/src/device/dram/spd_cache.c +++ b/src/device/dram/spd_cache.c @@ -36,8 +36,8 @@ int read_spd_from_cbfs(u8 *buf, int idx) size_t min_len = (idx + 1) * SPD_SIZE;
printk(BIOS_DEBUG, "read SPD\n"); - spd_file = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "spd.bin", - CBFS_TYPE_SPD, &spd_file_len); + spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, + &spd_file_len); if (!spd_file) printk(BIOS_EMERG, "file [spd.bin] not found in CBFS"); if (spd_file_len < min_len) diff --git a/src/device/oprom/realmode/x86.c b/src/device/oprom/realmode/x86.c index 4d8a3e4..485d1a4 100644 --- a/src/device/oprom/realmode/x86.c +++ b/src/device/oprom/realmode/x86.c @@ -273,10 +273,9 @@ void vbe_set_graphics(void) vbe_set_mode(&mode_info); #if CONFIG_BOOTSPLASH struct jpeg_decdata *decdata; - unsigned char *jpeg = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, - "bootsplash.jpg", - CBFS_TYPE_BOOTSPLASH, - NULL); + unsigned char *jpeg = cbfs_boot_map_with_leak("bootsplash.jpg", + CBFS_TYPE_BOOTSPLASH, + NULL); if (!jpeg) { printk(BIOS_DEBUG, "VBE: No bootsplash found.\n"); return; @@ -390,7 +389,7 @@ void do_vsmbios(void) /* Make sure the code is placed. */ setup_realmode_code();
- if ((unsigned int)cbfs_load_stage(CBFS_DEFAULT_MEDIA, "vsa") != + if ((uintptr_t)cbfs_boot_load_stage_by_name("vsa") != VSA2_ENTRY_POINT) { printk(BIOS_ERR, "Failed to load VSA.\n"); return; diff --git a/src/device/oprom/yabel/vbe.c b/src/device/oprom/yabel/vbe.c index ab92c0a..07eb1f3 100644 --- a/src/device/oprom/yabel/vbe.c +++ b/src/device/oprom/yabel/vbe.c @@ -724,10 +724,9 @@ void vbe_set_graphics(void) * cares. */ // int imagesize = 1024*768*2;
- unsigned char *jpeg = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, - "bootsplash.jpg", - CBFS_TYPE_BOOTSPLASH, - NULL); + unsigned char *jpeg = cbfs_boot_map_with_leak("bootsplash.jpg", + CBFS_TYPE_BOOTSPLASH, + NULL); if (!jpeg) { DEBUG_PRINTF_VBE("Could not find bootsplash.jpg\n"); return; diff --git a/src/device/pci_rom.c b/src/device/pci_rom.c index 04db05c..26cd6cf 100644 --- a/src/device/pci_rom.c +++ b/src/device/pci_rom.c @@ -38,8 +38,7 @@ struct rom_header *pci_rom_probe(struct device *dev) struct pci_data *rom_data;
/* If it's in FLASH, then don't check device for ROM. */ - rom_header = cbfs_load_optionrom(CBFS_DEFAULT_MEDIA, dev->vendor, - dev->device, NULL); + rom_header = cbfs_boot_map_optionrom(dev->vendor, dev->device);
u32 vendev = (dev->vendor << 16) | dev->device; u32 mapped_vendev = vendev; @@ -48,10 +47,9 @@ struct rom_header *pci_rom_probe(struct device *dev)
if (!rom_header) { if (vendev != mapped_vendev) { - rom_header = cbfs_load_optionrom( - CBFS_DEFAULT_MEDIA, + rom_header = cbfs_boot_map_optionrom( mapped_vendev >> 16, - mapped_vendev & 0xffff, NULL); + mapped_vendev & 0xffff); } }
diff --git a/src/drivers/intel/fsp1_0/fastboot_cache.c b/src/drivers/intel/fsp1_0/fastboot_cache.c index 306359e..5093810 100644 --- a/src/drivers/intel/fsp1_0/fastboot_cache.c +++ b/src/drivers/intel/fsp1_0/fastboot_cache.c @@ -63,10 +63,9 @@ static int is_mrc_cache(struct mrc_data_container *mrc_cache) static u32 get_mrc_cache_region(struct mrc_data_container **mrc_region_ptr) { size_t region_size; - *mrc_region_ptr = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, - "mrc.cache", - CBFS_TYPE_MRC_CACHE, - ®ion_size); + *mrc_region_ptr = cbfs_boot_map_with_leak("mrc.cache", + CBFS_TYPE_MRC_CACHE, + ®ion_size);
return region_size; } diff --git a/src/drivers/intel/fsp1_1/fastboot_cache.c b/src/drivers/intel/fsp1_1/fastboot_cache.c index a0d15c4..9aa8a64 100644 --- a/src/drivers/intel/fsp1_1/fastboot_cache.c +++ b/src/drivers/intel/fsp1_1/fastboot_cache.c @@ -62,8 +62,7 @@ static int is_mrc_cache(struct mrc_data_container *mrc_cache) static u32 get_mrc_cache_region(struct mrc_data_container **mrc_region_ptr) { size_t region_size; - *mrc_region_ptr = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, - "mrc.cache", + *mrc_region_ptr = cbfs_boot_map_with_leak("mrc.cache", CBFS_TYPE_MRC_CACHE, ®ion_size);
diff --git a/src/drivers/intel/fsp1_1/fsp_gop.c b/src/drivers/intel/fsp1_1/fsp_gop.c index cf781cd..b3160e5 100644 --- a/src/drivers/intel/fsp1_1/fsp_gop.c +++ b/src/drivers/intel/fsp1_1/fsp_gop.c @@ -25,28 +25,28 @@ /* Reading VBT table from flash */ const optionrom_vbt_t *fsp_get_vbt(uint32_t *vbt_len) { - struct cbfs_file *vbt_file; + size_t vbt_size; union { const optionrom_vbt_t *data; uint32_t *signature; } vbt;
/* Locate the vbt file in cbfs */ - vbt_file = cbfs_get_file(CBFS_DEFAULT_MEDIA, "vbt.bin"); - if (!vbt_file) { + vbt.data = cbfs_boot_map_with_leak("vbt.bin", CBFS_TYPE_OPTIONROM, + &vbt_size); + if (!vbt.data) { printk(BIOS_INFO, "FSP_INFO: VBT data file (vbt.bin) not found in CBFS"); return NULL; }
/* Validate the vbt file */ - vbt.data = CBFS_SUBHEADER(vbt_file); if (*vbt.signature != VBT_SIGNATURE) { printk(BIOS_WARNING, "FSP_WARNING: Invalid signature in VBT data file (vbt.bin)!\n"); return NULL; } - *vbt_len = ntohl(vbt_file->len); + *vbt_len = vbt_size; printk(BIOS_DEBUG, "FSP_INFO: VBT found at %p, 0x%08x bytes\n", vbt.data, *vbt_len);
diff --git a/src/drivers/pc80/mc146818rtc.c b/src/drivers/pc80/mc146818rtc.c index ff3be5b..07fc884 100644 --- a/src/drivers/pc80/mc146818rtc.c +++ b/src/drivers/pc80/mc146818rtc.c @@ -212,8 +212,8 @@ enum cb_err get_option(void *dest, const char *name) namelen = strnlen(name, CMOS_MAX_NAME_LENGTH);
/* find the requested entry record */ - ct = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "cmos_layout.bin", - CBFS_COMPONENT_CMOS_LAYOUT, NULL); + ct = cbfs_boot_map_with_leak("cmos_layout.bin", + CBFS_COMPONENT_CMOS_LAYOUT, NULL); if (!ct) { printk(BIOS_ERR, "RTC: cmos_layout.bin could not be found. " "Options are disabled\n"); @@ -295,8 +295,8 @@ enum cb_err set_option(const char *name, void *value) namelen = strnlen(name, CMOS_MAX_NAME_LENGTH);
/* find the requested entry record */ - ct = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "cmos_layout.bin", - CBFS_COMPONENT_CMOS_LAYOUT, NULL); + ct = cbfs_boot_map_with_leak("cmos_layout.bin", + CBFS_COMPONENT_CMOS_LAYOUT, NULL); if (!ct) { printk(BIOS_ERR, "cmos_layout.bin could not be found. " "Options are disabled\n"); diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c index d2a3c66..b95a0a2 100644 --- a/src/drivers/spi/spi_flash.c +++ b/src/drivers/spi/spi_flash.c @@ -7,6 +7,7 @@ * Licensed under the GPL-2 or later. */
+#include <boot_device.h> #include <cbfs.h> #include <cpu/x86/smm.h> #include <delay.h> @@ -407,10 +408,8 @@ void lb_spi_flash(struct lb_header *header) flash->size = sizeof(*flash);
/* Try to get the flash device if not loaded yet */ - if (!spi_flash_dev) { - struct cbfs_media media; - init_default_cbfs_media(&media); - } + if (!spi_flash_dev) + boot_device_init();
if (spi_flash_dev) { flash->flash_size = spi_flash_dev->size; diff --git a/src/include/cbfs.h b/src/include/cbfs.h index 8db87e3..00c43f2 100644 --- a/src/include/cbfs.h +++ b/src/include/cbfs.h @@ -1,14 +1,8 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2008 Jordan Crouse jordan@cosmicpenguin.net - * Copyright (C) 2013-2015 Google, Inc. + * Copyright 2015 Google Inc. * - * This file is dual-licensed. You can choose between: - * - The GNU GPL, version 2, as published by the Free Software Foundation - * - The revised BSD license (without advertising clause) - * - * --------------------------------------------------------------------------- * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. @@ -21,74 +15,71 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc. - * --------------------------------------------------------------------------- - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * --------------------------------------------------------------------------- */
#ifndef _CBFS_H_ #define _CBFS_H_
-#include <cbfs_core.h> +#include <cbfs_serialized.h> +#include <program_loading.h> +#include <region.h>
-int init_backing_media(struct cbfs_media **media, struct cbfs_media *backing); -void *cbfs_load_optionrom(struct cbfs_media *media, uint16_t vendor, - uint16_t device, void * dest); -void *cbfs_load_stage(struct cbfs_media *media, const char *name); -void *cbfs_load_stage_by_offset(struct cbfs_media *media, ssize_t offset); -/* Load a stage from a prog structure. Returns < 0 on error. 0 on success. */ -struct prog; -int cbfs_load_prog_stage(struct cbfs_media *media, struct prog *prog); -int cbfs_load_prog_stage_by_offset(struct cbfs_media *media, - struct prog *prog, ssize_t offset); +/* + * CBFS operations consist of the following concepts: + * - region_device for the boot media + * - cbfsd which is a descriptor for representing a cbfs instance + */
-/* Simple buffer for streaming media. */ -struct cbfs_simple_buffer { - char *buffer; - size_t allocated; - size_t size; - size_t last_allocate; -}; +/* Descriptor for cbfs lookup operations. */ +struct cbfsd;
-void *cbfs_simple_buffer_map(struct cbfs_simple_buffer *buffer, - struct cbfs_media *media, - size_t offset, size_t count); +/*********************************************** + * Perform CBFS operations on the boot device. * + ***********************************************/
-void *cbfs_simple_buffer_unmap(struct cbfs_simple_buffer *buffer, - const void *address); +/* Return mapping of option rom found in boot device. NULL on error. */ +void *cbfs_boot_map_optionrom(uint16_t vendor, uint16_t device); +/* Load stage by name into memory. Returns entry address on success. NULL on + * failure. */ +void *cbfs_boot_load_stage_by_name(const char *name); +/* Locate file by name and optional type. Return 0 on success. < 0 on error. */ +int cbfs_boot_locate(struct region_device *fh, const char *name, + uint32_t *type); +/* Map file into memory leaking the mapping. Only should be used when + * leaking mappings are a no-op. Returns NULL on error, else returns + * the mapping and sets the size of the file. */ +void *cbfs_boot_map_with_leak(const char *name, uint32_t type, size_t *size);
+/* Load stage into memory filling in prog. Return 0 on success. < 0 on error. */ +int cbfs_prog_stage_load(struct prog *prog);
-/* - * Defined in individual arch / board implementation. - * - * it returns 0 on success and non-zero on error. - */ -int init_default_cbfs_media(struct cbfs_media *media); +/* Locate file by name and optional type. Returns 0 on succcess else < 0 on + * error.*/ +int cbfs_locate(struct region_device *fh, const struct cbfsd *cbfs, + const char *name, uint32_t *type); + +/***************************************************************** + * Support structures and functions. Direct field access should * + * only be done by implementers of cbfs regions -- Not the above * + * API. * + *****************************************************************/ + +struct cbfsd { + const struct region_device *rdev; + size_t align; +}; + +/* The cbfs_props struct describes the properties associated with a CBFS. */ +struct cbfs_props { + /* Each file is aligned. */ + size_t align; + /* CBFS starts at the following offset within the boot region. */ + size_t offset; + /* CBFS size. */ + size_t size; +}; + +/* Return < 0 on error otherwise props are filled out accordingly. */ +int cbfs_boot_region_properties(struct cbfs_props *props);
-#if (IS_ENABLED(CONFIG_MULTIPLE_CBFS_INSTANCES)) -void cbfs_set_header_offset(size_t offset); -#else -static inline void cbfs_set_header_offset(size_t offset) {} -#endif #endif diff --git a/src/include/cbfs_core.h b/src/include/cbfs_core.h deleted file mode 100644 index f00a26c..0000000 --- a/src/include/cbfs_core.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2008 Jordan Crouse jordan@cosmicpenguin.net - * Copyright (C) 2012 Google, Inc. - * Copyright (C) 2013 The Chromium OS Authors. All rights reserved. - * - * This file is dual-licensed. You can choose between: - * - The GNU GPL, version 2, as published by the Free Software Foundation - * - The revised BSD license (without advertising clause) - * - * --------------------------------------------------------------------------- - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc. - * --------------------------------------------------------------------------- - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * --------------------------------------------------------------------------- - */ - -#ifndef _CBFS_CORE_H_ -#define _CBFS_CORE_H_ - -#include <endian.h> -#include <stddef.h> -#include <stdint.h> -#include <cbfs_serialized.h> - -#define CBFS_HEADER_INVALID_ADDRESS ((void*)(0xffffffff)) - -#define CBFS_NAME(_c) (((char *) (_c)) + sizeof(struct cbfs_file)) -#define CBFS_SUBHEADER(_p) ( (void *) ((((uint8_t *) (_p)) + ntohl((_p)->offset))) ) - -/* - * ROMCC does not understand uint64_t, so we hide future definitions as they are - * unlikely to be ever needed from ROMCC - */ -#ifndef __ROMCC__ - -#define CBFS_MEDIA_INVALID_MAP_ADDRESS ((void*)(0xffffffff)) -#define CBFS_DEFAULT_MEDIA ((void*)(0x0)) - -/* Media for CBFS to load files. */ -struct cbfs_media { - - /* implementation dependent context, to hold resource references */ - void *context; - - /* opens media and returns 0 on success, -1 on failure */ - int (*open)(struct cbfs_media *media); - - /* returns number of bytes read from media into dest, starting from - * offset for count of bytes */ - size_t (*read)(struct cbfs_media *media, void *dest, size_t offset, - size_t count); - - /* returns a pointer to memory with count of bytes from media source - * starting from offset, or CBFS_MEDIA_INVALID_MAP_ADDRESS on failure. - * Note: mapped data can't be free unless unmap is called, even if you - * do close first. */ - void * (*map)(struct cbfs_media *media, size_t offset, size_t count); - - /* returns NULL and releases the memory by address, which was allocated - * by map */ - void * (*unmap)(struct cbfs_media *media, const void *address); - - /* closes media and returns 0 on success, -1 on failure. */ - int (*close)(struct cbfs_media *media); -}; - -/* - * Locate file by name and fill in cbfs_file in host byte order. Returns - * < 0 on error, else the offset of the file data. - */ -ssize_t cbfs_locate_file(struct cbfs_media *media, struct cbfs_file *file, - const char *name); - -/* Read count bytes at offset into dest. Return number of bytes read. */ -size_t cbfs_read(struct cbfs_media *media, void *dest, size_t offset, - size_t count); - -/* returns pointer to a file entry inside CBFS or NULL */ -struct cbfs_file *cbfs_get_file(struct cbfs_media *media, const char *name); - -/* returns pointer to file content inside CBFS after if type is correct */ -void *cbfs_get_file_content(struct cbfs_media *media, const char *name, - int type, size_t *sz); - -/* returns decompressed size on success, 0 on failure */ -int cbfs_decompress(int algo, void *src, void *dst, int len); - -/* returns a pointer to CBFS master header, or CBFS_HEADER_INVALID_ADDRESS - * on failure */ -const struct cbfs_header *cbfs_get_header(struct cbfs_media *media); - -#endif /* __ROMCC__ */ - -#endif diff --git a/src/include/fallback.h b/src/include/fallback.h index 7f3c823..740f130 100644 --- a/src/include/fallback.h +++ b/src/include/fallback.h @@ -1,7 +1,7 @@ #ifndef FALLBACK_H #define FALLBACK_H
-#if !defined(__ASSEMBLER__) && !defined(__PRE_RAM__) +#if !defined(__ASSEMBLER__)
void boot_successful(void);
diff --git a/src/include/memlayout.h b/src/include/memlayout.h index 651e60d..2771f2f 100644 --- a/src/include/memlayout.h +++ b/src/include/memlayout.h @@ -102,6 +102,4 @@ . += sz; #endif
-#define CBFS_HEADER_OFFSET(addr) REGION(cbfs_header_offset, addr, 4, 4) - #endif /* __MEMLAYOUT_H */ diff --git a/src/include/program_loading.h b/src/include/program_loading.h index 981bd7b..eb99350 100644 --- a/src/include/program_loading.h +++ b/src/include/program_loading.h @@ -22,6 +22,7 @@
#include <stdint.h> #include <stddef.h> +#include <region.h>
enum { /* Last segment of program. Can be used to take different actions for @@ -42,17 +43,22 @@ enum prog_type { PROG_VERSTAGE, PROG_ROMSTAGE, PROG_RAMSTAGE, + PROG_REFCODE, PROG_PAYLOAD, + PROG_BL31, };
/* Representation of a program. */ struct prog { enum prog_type type; const char *name; + /* Source of program content to load. */ + struct region_device rdev; /* The area can mean different things depending on what type the - * program is. e.g. a payload prog uses this field for the backing - * store of the payload_segments and data. After loading the segments - * area is updated to reflect the bounce buffer used. */ + * program is. A stage after being loaded reflects the memory occupied + * by the program, Since payloads are multi-segment one can't express + * the memory layout with one range. Instead this field is updated + * to reflect the bounce buffer used. */ struct buffer_area area; /* Entry to program with optional argument. It's up to the architecture * to decide if argument is passed. */ @@ -92,6 +98,8 @@ static inline void prog_set_entry(struct prog *prog, void *e, void *arg) prog->arg = arg; }
+/* Locate the identified program to run. Return 0 on success. < 0 on error. */ +int prog_locate(struct prog *prog); /* Run the program described by prog. */ void prog_run(struct prog *prog); /* Per architecture implementation running a program. */ @@ -107,10 +115,10 @@ struct prog_loader_ops { /* Determine if the loader is the active one. If so returns 1 else 0 * or < 0 on error. */ int (*is_loader_active)(struct prog *prog); - /* Returns < 0 on error or 0 on success. This function needs to do - * different things depending on the prog type. See definition - * of struct prog above. */ - int (*prepare)(struct prog *prog); + /* Returns < 0 on error or 0 on success. This function locates + * the rdev representing the file data associated with the passed in + * prog. */ + int (*locate)(struct prog *prog); };
/************************ diff --git a/src/include/rmodule.h b/src/include/rmodule.h index c42614a..719c6a6 100644 --- a/src/include/rmodule.h +++ b/src/include/rmodule.h @@ -54,7 +54,6 @@ int rmodule_calc_region(unsigned int region_alignment, size_t rmodule_size, /* Support for loading rmodule stages. This API is only available when * using dynamic cbmem because it uses the dynamic cbmem API to obtain * the backing store region for the stage. */ -struct cbfs_stage; struct prog;
struct rmod_stage_load { @@ -63,8 +62,7 @@ struct rmod_stage_load { };
/* Both of the following functions return 0 on success, -1 on error. */ -int rmodule_stage_load(struct rmod_stage_load *rsl, struct cbfs_stage *stage); -int rmodule_stage_load_from_cbfs(struct rmod_stage_load *rsl); +int rmodule_stage_load(struct rmod_stage_load *rsl);
struct rmodule { void *location; diff --git a/src/include/romstage_handoff.h b/src/include/romstage_handoff.h index b92c884..3b0050b 100644 --- a/src/include/romstage_handoff.h +++ b/src/include/romstage_handoff.h @@ -38,8 +38,6 @@ struct romstage_handoff { uint8_t reserved[2]; };
-#if defined(__ROMSTAGE__) -#if CONFIG_EARLY_CBMEM_INIT /* The romstage_handoff_find_or_add() function provides the necessary logic * for initializing the romstage_handoff structure in cbmem. Different components * of the romstage may be responsible for setting up different fields. Therefore @@ -62,14 +60,6 @@ static inline struct romstage_handoff *romstage_handoff_find_or_add(void)
return handoff; } -#else /* CONFIG_EARLY_CBMEM_INIT */ -static inline struct romstage_handoff *romstage_handoff_find_or_add(void) -{ - return NULL; -} -#endif /* CONFIG_EARLY_CBMEM_INIT */ - -#endif /* defined(__PRE_RAM__) */
#endif /* ROMSTAGE_HANDOFF_H */
diff --git a/src/include/symbols.h b/src/include/symbols.h index b47c886..4a47de1 100644 --- a/src/include/symbols.h +++ b/src/include/symbols.h @@ -27,7 +27,6 @@ extern u8 _esram[]; #define _sram_size (_esram - _sram)
extern u8 _dram[]; -extern u32 _cbfs_header_offset[];
extern u8 _preram_cbmem_console[]; extern u8 _epreram_cbmem_console[]; diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc index 5ec9de7..ebb3076 100644 --- a/src/lib/Makefile.inc +++ b/src/lib/Makefile.inc @@ -18,8 +18,10 @@ # subdirs-y += loaders
+bootblock-y += prog_loaders.c bootblock-y += prog_ops.c -bootblock-y += cbfs.c cbfs_core.c +bootblock-y += cbfs.c +bootblock-y += cbfs_boot_props.c bootblock-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c bootblock-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c
@@ -34,12 +36,13 @@ bootblock-y += region.c bootblock-y += boot_device.c bootblock-y += fmap.c
+verstage-y += prog_loaders.c verstage-y += prog_ops.c verstage-y += delay.c verstage-y += cbfs.c -verstage-y += cbfs_core.c verstage-y += halt.c verstage-y += fmap.c +verstage-y += cbfs_boot_props.c verstage-y += memcmp.c verstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c verstage-y += region.c @@ -57,6 +60,7 @@ verstage-$(CONFIG_GENERIC_UDELAY) += timer.c verstage-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c verstage-y += mem_pool.c
+romstage-y += prog_loaders.c romstage-y += prog_ops.c romstage-y += memchr.c romstage-y += memcmp.c @@ -66,7 +70,8 @@ $(foreach arch,$(ARCH_SUPPORTED),\
romstage-y += fmap.c romstage-$(CONFIG_I2C_TPM) += delay.c -romstage-y += cbfs.c cbfs_core.c +romstage-y += cbfs.c +romstage-y += cbfs_boot_props.c romstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c romstage-$(CONFIG_COMPRESS_RAMSTAGE) += lzma.c lzmadecode.c romstage-$(CONFIG_PRIMITIVE_MEMTEST) += primitive_memtest.c @@ -87,6 +92,7 @@ endif
romstage-$(CONFIG_GENERIC_UDELAY) += timer.c
+ramstage-y += prog_loaders.c ramstage-y += prog_ops.c ramstage-y += hardwaremain.c ramstage-y += selfboot.c @@ -100,7 +106,8 @@ smm-$(CONFIG_SMM_TSEG) += malloc.c ramstage-y += delay.c ramstage-y += fallback_boot.c ramstage-y += compute_ip_checksum.c -ramstage-y += cbfs.c cbfs_core.c +ramstage-y += cbfs.c +ramstage-y += cbfs_boot_props.c ramstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c ramstage-y += lzma.c lzmadecode.c ramstage-y += stack.c @@ -153,7 +160,7 @@ ramstage-y += boot_device.c smm-y += region.c smm-y += boot_device.c smm-y += fmap.c -smm-y += cbfs.c cbfs_core.c memcmp.c +smm-y += cbfs.c memcmp.c smm-$(CONFIG_COMPILER_GCC) += gcc.c
bootblock-y += version.c diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c index 00071f8..23dfee7 100644 --- a/src/lib/cbfs.c +++ b/src/lib/cbfs.c @@ -1,8 +1,8 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2008, Jordan Crouse jordan@cosmicpenguin.net - * Copyright (C) 2013 The Chromium OS Authors. All rights reserved. + * Copyright (C) 2011 secunet Security Networks AG + * Copyright 2015 Google Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,192 +18,238 @@ * Foundation, Inc. */
+#include <assert.h> +#include <string.h> +#include <stdlib.h> +#include <boot_device.h> +#include <cbfs.h> +#include <endian.h> +#include <lib.h> +#include <symbols.h> + +#define ERROR(x...) printk(BIOS_ERR, "CBFS: " x) +#define LOG(x...) printk(BIOS_INFO, "CBFS: " x) +#if IS_ENABLED(CONFIG_DEBUG_CBFS) +#define DEBUG(x...) printk(BIOS_SPEW, "CBFS: " x) +#else +#define DEBUG(x...) +#endif
-#include <program_loading.h> -#include "cbfs_core.h" - -#ifndef __SMM__ -static inline int tohex4(unsigned int c) +int cbfs_boot_locate(struct region_device *fh, const char *name, uint32_t *type) { - return (c <= 9) ? (c + '0') : (c - 10 + 'a'); -} + struct cbfsd cbfs; + struct region_device rdev; + const struct region_device *boot_dev; + struct cbfs_props props;
-static void tohex16(unsigned int val, char* dest) -{ - dest[0] = tohex4(val>>12); - dest[1] = tohex4((val>>8) & 0xf); - dest[2] = tohex4((val>>4) & 0xf); - dest[3] = tohex4(val & 0xf); -} + boot_device_init();
-void *cbfs_load_optionrom(struct cbfs_media *media, uint16_t vendor, - uint16_t device, void *dest) -{ - char name[17] = "pciXXXX,XXXX.rom"; - struct cbfs_optionrom *orom; - uint8_t *src; + if (cbfs_boot_region_properties(&props)) + return -1;
- tohex16(vendor, name+3); - tohex16(device, name+8); + /* All boot CBFS operations are performed using the RO devie. */ + boot_dev = boot_device_ro();
- orom = (struct cbfs_optionrom *) - cbfs_get_file_content(media, name, CBFS_TYPE_OPTIONROM, NULL); + if (boot_dev == NULL) + return -1;
- if (orom == NULL) - return NULL; + if (rdev_chain(&rdev, boot_dev, props.offset, props.size)) + return -1;
- /* They might have specified a dest address. If so, we can decompress. - * If not, there's not much hope of decompressing or relocating the rom. - * in the common case, the expansion rom is uncompressed, we - * pass 0 in for the dest, and all we have to do is find the rom and - * return a pointer to it. - */ + cbfs.rdev = &rdev; + cbfs.align = props.align;
- /* BUG: the cbfstool is (not yet) including a cbfs_optionrom header */ - src = (uint8_t *)orom; // + sizeof(struct cbfs_optionrom); + return cbfs_locate(fh, &cbfs, name, type); +}
- if (! dest) - return src; +void *cbfs_boot_map_with_leak(const char *name, uint32_t type, size_t *size) +{ + struct region_device fh; + size_t fsize;
- if (!cbfs_decompress(ntohl(orom->compression), - src, - dest, - ntohl(orom->len))) + if (cbfs_boot_locate(&fh, name, &type)) return NULL;
- return dest; + fsize = region_device_sz(&fh); + + if (size != NULL) + *size = fsize; + + return rdev_mmap(&fh, 0, fsize); }
-int cbfs_load_prog_stage_by_offset(struct cbfs_media *media, - struct prog *prog, ssize_t offset) +int cbfs_locate(struct region_device *fh, const struct cbfsd *cbfs, + const char *name, uint32_t *type) { - struct cbfs_stage stage; - struct cbfs_media backing_store; + size_t offset; + const struct region_device *rd; + size_t align; + + offset = 0; + rd = cbfs->rdev; + align = cbfs->align; + + LOG("Locating '%s'\n", name); + + /* Try to scan the entire cbfs region looking for file name. */ + while (1) { + struct cbfs_file file; + const size_t fsz = sizeof(file); + char *fname; + int name_match; + size_t datasz; + + DEBUG("Checking offset %zx\n", offset); + + /* Can't read file. Nothing else to do but bail out. */ + if (rdev_readat(rd, &file, offset, fsz) != fsz) + break; + + if (memcmp(file.magic, CBFS_FILE_MAGIC, sizeof(file.magic))) { + offset++; + offset = ALIGN_UP(offset, align); + continue; + }
- if (init_backing_media(&media, &backing_store)) - return -1; + file.len = ntohl(file.len); + file.type = ntohl(file.type); + file.offset = ntohl(file.offset);
- if (cbfs_read(media, &stage, offset, sizeof(stage)) != sizeof(stage)) { - ERROR("ERROR: failed to read stage header\n"); - return -1; - } + /* See if names match. */ + fname = rdev_mmap(rd, offset + fsz, file.offset - fsz);
- LOG("loading stage from %#zx @ 0x%llx (%d bytes), entry @ 0x%llx\n", - offset, stage.load, stage.memlen, stage.entry); + if (fname == NULL) + break;
- /* Stages rely the below clearing so that the bss is initialized. */ - memset((void *)(uintptr_t)stage.load, 0, stage.memlen); + name_match = !strcmp(fname, name); + rdev_munmap(rd, fname);
- if (stage.compression == CBFS_COMPRESS_NONE) { - if (cbfs_read(media, (void *)(uintptr_t)stage.load, - offset + sizeof(stage), stage.len) != stage.len) { - ERROR("ERROR: Reading stage failed.\n"); - return -1; + if (!name_match) { + DEBUG(" Unmatched '%s' at %zx\n", fname, offset); + offset += file.offset + file.len; + offset = ALIGN_UP(offset, align); + continue; } - } else { - void *data = media->map(media, offset + sizeof(stage), - stage.len); - if (data == CBFS_MEDIA_INVALID_MAP_ADDRESS) { - ERROR("ERROR: Mapping stage failed.\n"); - return -1; + + if (type != NULL && *type != file.type) { + DEBUG(" Unmatched type %x at %zx\n", file.type, offset); + offset += file.offset + file.len; + offset = ALIGN_UP(offset, align); + continue; } - if (!cbfs_decompress(stage.compression, data, - (void *)(uintptr_t)stage.load, stage.len)) - return -1; - media->unmap(media, data); - }
- arch_segment_loaded(stage.load, stage.memlen, SEG_FINAL); - DEBUG("stage loaded\n"); + LOG("Found @ offset %zx size %x\n", offset, file.len); + /* File and type match. Create a chained region_device to + * represent the cbfs file. */ + offset += file.offset; + datasz = file.len; + if (rdev_chain(fh, rd, offset, datasz)) + break;
- prog_set_area(prog, (void *)(uintptr_t)stage.load, stage.memlen); - prog_set_entry(prog, (void *)(uintptr_t)stage.entry, NULL); + /* Success. */ + return 0; + }
- return 0; + LOG("'%s' not found.\n", name); + return -1; }
-int cbfs_load_prog_stage(struct cbfs_media *media, struct prog *prog) +static size_t inflate(void *src, void *dst) { - struct cbfs_file file; - ssize_t offset; - struct cbfs_media backing_store; - - if (init_backing_media(&media, &backing_store)) - return -1; - - offset = cbfs_locate_file(media, &file, prog->name); - if (offset < 0 || file.type != CBFS_TYPE_STAGE) - return -1; + if (ENV_BOOTBLOCK || ENV_VERSTAGE) + return 0; + if (ENV_ROMSTAGE && !IS_ENABLED(CONFIG_COMPRESS_RAMSTAGE)) + return 0; + return ulzma(src, dst); +}
- if (cbfs_load_prog_stage_by_offset(media, prog, offset) < 0) - return -1; +static inline int tohex4(unsigned int c) +{ + return (c <= 9) ? (c + '0') : (c - 10 + 'a'); +}
- return 0; +static void tohex16(unsigned int val, char* dest) +{ + dest[0] = tohex4(val>>12); + dest[1] = tohex4((val>>8) & 0xf); + dest[2] = tohex4((val>>4) & 0xf); + dest[3] = tohex4(val & 0xf); }
-void *cbfs_load_stage_by_offset(struct cbfs_media *media, ssize_t offset) +void *cbfs_boot_map_optionrom(uint16_t vendor, uint16_t device) { - struct prog prog = { - .name = NULL, - }; + char name[17] = "pciXXXX,XXXX.rom";
- if (cbfs_load_prog_stage_by_offset(media, &prog, offset) < 0) - return (void *)-1; + tohex16(vendor, name+3); + tohex16(device, name+8);
- return prog_entry(&prog); + return cbfs_boot_map_with_leak(name, CBFS_TYPE_OPTIONROM, NULL); }
-void *cbfs_load_stage(struct cbfs_media *media, const char *name) +void *cbfs_boot_load_stage_by_name(const char *name) { - struct prog prog = { + struct prog stage = { .name = name, }; + uint32_t type = CBFS_TYPE_STAGE;
- if (cbfs_load_prog_stage(media, &prog) < 0) - return (void *)-1; + if (cbfs_boot_locate(&stage.rdev, name, &type)) + return NULL;
- return prog_entry(&prog); -} + if (cbfs_prog_stage_load(&stage)) + return NULL;
-/* Simple buffer */ - -void *cbfs_simple_buffer_map(struct cbfs_simple_buffer *buffer, - struct cbfs_media *media, - size_t offset, size_t count) { - void *address = buffer->buffer + buffer->allocated; - DEBUG("simple_buffer_map(offset=%zd, count=%zd): " - "allocated=%zd, size=%zd, last_allocate=%zd\n", - offset, count, buffer->allocated, buffer->size, - buffer->last_allocate); - if (buffer->allocated + count > buffer->size) { - ERROR("simple_buffer: no room to map %zd bytes from %#zx\n", - count, offset); - return CBFS_MEDIA_INVALID_MAP_ADDRESS; - } - if (media->read(media, address, offset, count) != count) { - ERROR("simple_buffer: fail to read %zd bytes from 0x%zx\n", - count, offset); - return CBFS_MEDIA_INVALID_MAP_ADDRESS; - } - buffer->allocated += count; - buffer->last_allocate = count; - return address; + return prog_entry(&stage); }
-void *cbfs_simple_buffer_unmap(struct cbfs_simple_buffer *buffer, - const void *address) { - // TODO Add simple buffer management so we can free more than last - // allocated one. - DEBUG("simple_buffer_unmap(address=0x%p): " - "allocated=%zd, size=%zd, last_allocate=%zd\n", - address, buffer->allocated, buffer->size, - buffer->last_allocate); - if ((buffer->buffer + buffer->allocated - buffer->last_allocate) == - address) { - buffer->allocated -= buffer->last_allocate; - buffer->last_allocate = 0; - } - return NULL; -} +int cbfs_prog_stage_load(struct prog *pstage) +{ + struct cbfs_stage stage; + uint8_t *load; + void *entry; + size_t fsize; + size_t foffset; + const struct region_device *fh = &pstage->rdev;
-#endif + if (rdev_readat(fh, &stage, 0, sizeof(stage)) != sizeof(stage)) + return 0; + + fsize = region_device_sz(fh); + fsize -= sizeof(stage); + foffset = 0; + foffset += sizeof(stage); + + assert(fsize == stage.len); + + /* Note: cbfs_stage fields are currently in the endianness of the + * running processor. */ + load = (void *)(uintptr_t)stage.load; + entry = (void *)(uintptr_t)stage.entry; + + if (stage.compression == CBFS_COMPRESS_NONE) { + if (rdev_readat(fh, load, foffset, fsize) != fsize) + return -1; + } else if (stage.compression == CBFS_COMPRESS_LZMA) { + void *map = rdev_mmap(fh, foffset, fsize); + + if (map == NULL) + return -1; + + fsize = inflate(map, load); + + rdev_munmap(fh, map); + + if (!fsize) + return -1; + } else + return -1; + + /* Clear area not covered by file. */ + memset(&load[fsize], 0, stage.memlen - fsize); + + arch_segment_loaded((uintptr_t)load, stage.memlen, SEG_FINAL); + prog_set_area(pstage, load, stage.memlen); + prog_set_entry(pstage, entry, NULL); + + return 0; +} diff --git a/src/lib/cbfs_boot_props.c b/src/lib/cbfs_boot_props.c new file mode 100644 index 0000000..21e64d3 --- /dev/null +++ b/src/lib/cbfs_boot_props.c @@ -0,0 +1,66 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2015 Google Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc. + */ + +#include <boot_device.h> +#include <cbfs.h> +#include <console/console.h> +#include <endian.h> +#include <region.h> + +/* This function is marked as weak to allow a particular platform to + * override the logic. This implementation should work for most devices. */ +int __attribute__((weak)) cbfs_boot_region_properties(struct cbfs_props *props) +{ + struct cbfs_header header; + const struct region_device *bdev; + int32_t rel_offset; + size_t offset; + + bdev = boot_device_ro(); + + if (bdev == NULL) + return -1; + + /* Find location of header using signed 32-bit offset from + * end of CBFS region. */ + offset = CONFIG_CBFS_SIZE - sizeof(int32_t); + if (rdev_readat(bdev, &rel_offset, offset, sizeof(int32_t)) < 0) + return -1; + + offset = CONFIG_CBFS_SIZE + rel_offset; + if (rdev_readat(bdev, &header, offset, sizeof(header)) < 0) + return -1; + + header.magic = ntohl(header.magic); + header.romsize = ntohl(header.romsize); + header.align = ntohl(header.align); + header.offset = ntohl(header.offset); + + if (header.magic != CBFS_HEADER_MAGIC) + return -1; + + props->align = header.align; + props->offset = header.offset; + props->size = header.romsize; + props->size -= props->offset; + + printk(BIOS_SPEW, "CBFS @ %zx size %zx\n", props->offset, props->size); + + return 0; +} diff --git a/src/lib/cbfs_core.c b/src/lib/cbfs_core.c deleted file mode 100644 index 9f45b3c..0000000 --- a/src/lib/cbfs_core.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2011 secunet Security Networks AG - * Copyright (C) 2013 The Chromium OS Authors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* The CBFS core requires a couple of #defines or functions to adapt it to the - * target environment: - * - * CBFS_CORE_WITH_LZMA (must be #define) - * if defined, ulzma() must exist for decompression of data streams - * - * ERROR(x...) - * print an error message x (in printf format) - * - * LOG(x...) - * print a message x (in printf format) - * - * DEBUG(x...) - * print a debug message x (in printf format) - * - */ - -#include <cbfs.h> -#include <string.h> -#include <symbols.h> - -#if IS_ENABLED(CONFIG_MULTIPLE_CBFS_INSTANCES) -void cbfs_set_header_offset(size_t offset) -{ - _cbfs_header_offset[0] = offset; - LOG("header set to: %#zx\n", offset); -} - -static size_t get_header_offset(void) -{ - return _cbfs_header_offset[0]; -} -#else -static size_t get_header_offset(void) -{ - return 0; -} -#endif - -#include "cbfs_core.h" - -/* returns a pointer to CBFS master header, or CBFS_HEADER_INVALID_ADDRESS - * on failure */ -const struct cbfs_header *cbfs_get_header(struct cbfs_media *media) -{ - size_t offset; - const struct cbfs_header *header; - 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 CBFS_HEADER_INVALID_ADDRESS; - } - } - media->open(media); - - /* TODO: allow negative offsets from the end of the CBFS image at media - * layer (like libpayload) so we can combine these two cases. */ - if (IS_ENABLED(CONFIG_ARCH_X86)) { - offset = *(int32_t *)(uintptr_t)0xfffffffc; - header = media->map(media, offset, sizeof(*header)); - } else { - - offset = get_header_offset(); - - if (!offset) { - int32_t rel_offset; - size_t cbfs_top = CONFIG_CBFS_SIZE; - DEBUG("CBFS top at offset: 0x%zx\n", cbfs_top); - if (!media->read(media, &rel_offset, cbfs_top - - sizeof(int32_t), - sizeof(int32_t))) { - ERROR("Could not read master header offset!\n"); - media->close(media); - return CBFS_HEADER_INVALID_ADDRESS; - } - offset = cbfs_top + rel_offset; - } - header = media->map(media, offset, sizeof(*header)); - } - DEBUG("CBFS header offset: 0x%zx/0x%x\n", offset, CONFIG_ROM_SIZE); - media->close(media); - - if (header == CBFS_MEDIA_INVALID_MAP_ADDRESS) { - ERROR("Failed to load CBFS header from 0x%zx\n", offset); - return CBFS_HEADER_INVALID_ADDRESS; - } - - if (CBFS_HEADER_MAGIC != ntohl(header->magic)) { - ERROR("Could not find valid CBFS master header at %#zx: " - "magic %#.8x vs %#.8x.\n", offset, CBFS_HEADER_MAGIC, - ntohl(header->magic)); - if (header->magic == 0xffffffff) { - ERROR("Maybe ROM is not mapped properly?\n"); - } - return CBFS_HEADER_INVALID_ADDRESS; - } - return header; -} - - -int init_backing_media(struct cbfs_media **media, struct cbfs_media *backing) -{ - if (*media == CBFS_DEFAULT_MEDIA) { - *media = backing; - if (init_default_cbfs_media(*media) != 0) { - ERROR("Failed to initialize default media.\n"); - return -1; - } - } - return 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; -} - -size_t cbfs_read(struct cbfs_media *media, void *dest, size_t offset, - size_t count) -{ - struct cbfs_media default_media; - size_t nread; - - if (init_backing_media(&media, &default_media)) - return 0; - - media->open(media); - nread = media->read(media, dest, offset, count); - media->close(media); - - return nread; -} - -struct cbfs_file *cbfs_get_file(struct cbfs_media *media, const char *name) -{ - struct cbfs_media default_media; - struct cbfs_file file, *file_ptr; - ssize_t offset; - - if (init_backing_media(&media, &default_media)) - return NULL; - - offset = cbfs_locate_file(media, &file, name); - if (offset < 0) - return NULL; - - /* Map both the metadata and the file contents. */ - media->open(media); - offset -= file.offset; - file_ptr = media->map(media, offset, file.offset + file.len); - media->close(media); - - if (file_ptr == CBFS_MEDIA_INVALID_MAP_ADDRESS) { - ERROR("ERROR: Mapping %s failed.\n", name); - return NULL; - } - - return file_ptr; -} - -void *cbfs_get_file_content(struct cbfs_media *media, const char *name, - int type, size_t *sz) -{ - struct cbfs_file *file = cbfs_get_file(media, name); - - if (sz) - *sz = 0; - - if (file == NULL) { - ERROR("Could not find file '%s'.\n", name); - return NULL; - } - - if (ntohl(file->type) != type) { - ERROR("File '%s' is of type %x, but we requested %x.\n", name, - ntohl(file->type), type); - return NULL; - } - - if (sz) - *sz = ntohl(file->len); - - return (void *)CBFS_SUBHEADER(file); -} - -int cbfs_decompress(int algo, void *src, void *dst, int len) -{ - switch (algo) { - case CBFS_COMPRESS_NONE: - /* Reads need to be aligned at 4 bytes to avoid - poor flash performance. */ - while (len && ((uintptr_t)src & 3)) { - *(u8*)dst++ = *(u8*)src++; - len--; - } - memmove(dst, src, len); - return len; -#ifdef CBFS_CORE_WITH_LZMA - case CBFS_COMPRESS_LZMA: - return ulzma(src, dst); -#endif - default: - ERROR("tried to decompress %d bytes with algorithm #%x," - "but that algorithm id is unsupported.\n", len, - algo); - return 0; - } -} diff --git a/src/lib/cbfs_core.h b/src/lib/cbfs_core.h deleted file mode 100644 index f9aeaa8..0000000 --- a/src/lib/cbfs_core.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef __LIB_CBFS_CORE -#define __LIB_CBFS_CORE - -#include <cbfs.h> -#include <string.h> - -#ifdef LIBPAYLOAD -# include <libpayload-config.h> -# ifdef CONFIG_LZMA -# include <lzma.h> -# define CBFS_CORE_WITH_LZMA -# endif -# define CBFS_MINI_BUILD -#elif defined(__SMM__) -# define CBFS_MINI_BUILD -#elif defined(__BOOTBLOCK__) - /* No LZMA in boot block. */ -#elif defined(__VERSTAGE__) - /* No LZMA in verstage. */ -#elif defined(__PRE_RAM__) && !CONFIG_COMPRESS_RAMSTAGE - /* No LZMA in romstage if ramstage is not compressed. */ -#else -# define CBFS_CORE_WITH_LZMA -# include <lib.h> -#endif - -#include <cbfs.h> -#include <string.h> -#include <cbmem.h> - -#ifdef LIBPAYLOAD -# include <stdio.h> -# define DEBUG(x...) -# define LOG(x...) printf(x) -# define ERROR(x...) printf(x) -#else -# include <console/console.h> -# define ERROR(x...) printk(BIOS_ERR, "CBFS: " x) -# define LOG(x...) printk(BIOS_INFO, "CBFS: " x) -# if CONFIG_DEBUG_CBFS -# define DEBUG(x...) printk(BIOS_SPEW, "CBFS: " x) -# else -# define DEBUG(x...) -# endif -#endif - -#endif /* __LIB_CBFS_CORE */ diff --git a/src/lib/cbfs_spi.c b/src/lib/cbfs_spi.c index 6758220..5b5aaff 100644 --- a/src/lib/cbfs_spi.c +++ b/src/lib/cbfs_spi.c @@ -24,8 +24,6 @@ */
#include <boot_device.h> -#include <cbfs.h> -#include <region.h> #include <spi_flash.h> #include <symbols.h>
@@ -69,73 +67,3 @@ const struct region_device *boot_device_ro(void)
return &mdev.rdev; } - -static int cbfs_media_open(struct cbfs_media *media) -{ - return 0; -} - -static int cbfs_media_close(struct cbfs_media *media) -{ - return 0; -} - -static size_t cbfs_media_read(struct cbfs_media *media, - void *dest, size_t offset, - size_t count) -{ - const struct region_device *boot_dev; - - boot_dev = media->context; - - if (rdev_readat(boot_dev, dest, offset, count) < 0) - return 0; - - return count; -} - -static void *cbfs_media_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; -} - -static void *cbfs_media_unmap(struct cbfs_media *media, - const void *address) -{ - const struct region_device *boot_dev; - - boot_dev = media->context; - - rdev_munmap(boot_dev, (void *)address); - - return NULL; -} - -int init_default_cbfs_media(struct cbfs_media *media) -{ - boot_device_init(); - - media->context = (void *)boot_device_ro(); - - if (media->context == NULL) - return -1; - - media->open = cbfs_media_open; - media->close = cbfs_media_close; - media->read = cbfs_media_read; - media->map = cbfs_media_map; - media->unmap = cbfs_media_unmap; - - return 0; -} diff --git a/src/lib/coreboot_table.c b/src/lib/coreboot_table.c index b1fbef6..f7fb2bb 100644 --- a/src/lib/coreboot_table.c +++ b/src/lib/coreboot_table.c @@ -396,8 +396,8 @@ unsigned long write_coreboot_table(
#if CONFIG_USE_OPTION_TABLE { - struct cmos_option_table *option_table = cbfs_get_file_content( - CBFS_DEFAULT_MEDIA, "cmos_layout.bin", + struct cmos_option_table *option_table = + cbfs_boot_map_with_leak("cmos_layout.bin", CBFS_COMPONENT_CMOS_LAYOUT, NULL); if (option_table) { struct lb_record *rec_dest = lb_new_record(head); diff --git a/src/lib/hardwaremain.c b/src/lib/hardwaremain.c index 80f6776..56f3f29 100644 --- a/src/lib/hardwaremain.c +++ b/src/lib/hardwaremain.c @@ -228,8 +228,6 @@ static boot_state_t bs_write_tables(void *arg)
static boot_state_t bs_payload_load(void *arg) { - timestamp_add_now(TS_LOAD_PAYLOAD); - payload_load();
return BS_PAYLOAD_BOOT; diff --git a/src/lib/loaders/Makefile.inc b/src/lib/loaders/Makefile.inc deleted file mode 100644 index ef5af6a..0000000 --- a/src/lib/loaders/Makefile.inc +++ /dev/null @@ -1,27 +0,0 @@ -# -# This file is part of the coreboot project. -# -# Copyright (C) 2014 Google Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc. -# - -bootblock-y += load_and_run_romstage.c -bootblock-y += cbfs_romstage_loader.c -romstage-y += cbfs_ramstage_loader.c -romstage-y += load_and_run_ramstage.c -ramstage-y += cbfs_payload_loader.c -ramstage-y += load_and_run_payload.c -verstage-y += cbfs_romstage_loader.c -verstage-y += load_and_run_romstage.c diff --git a/src/lib/loaders/cbfs_payload_loader.c b/src/lib/loaders/cbfs_payload_loader.c deleted file mode 100644 index 8e790a2..0000000 --- a/src/lib/loaders/cbfs_payload_loader.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc. - */ - -#include <cbfs.h> -#include <program_loading.h> - -static int cbfs_locate_payload(struct prog *payload) -{ - void *buffer; - size_t size; - const int type = CBFS_TYPE_PAYLOAD; - - buffer = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, payload->name, - type, &size); - - if (buffer == NULL) - return -1; - - prog_set_area(payload, buffer, size); - - return 0; -} - -const struct prog_loader_ops cbfs_payload_loader = { - .name = "CBFS", - .prepare = cbfs_locate_payload, -}; diff --git a/src/lib/loaders/cbfs_ramstage_loader.c b/src/lib/loaders/cbfs_ramstage_loader.c deleted file mode 100644 index acbc6c0..0000000 --- a/src/lib/loaders/cbfs_ramstage_loader.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2008-2009 coresystems GmbH - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc. - */ -#include <console/console.h> -#include <cbfs.h> -#include <program_loading.h> - -#if CONFIG_RELOCATABLE_RAMSTAGE -#include <rmodule.h> -#include <cbmem.h> - -static int cbfs_load_ramstage(struct prog *ramstage) -{ - struct rmod_stage_load rmod_ram = { - .cbmem_id = CBMEM_ID_RAMSTAGE, - .prog = ramstage, - }; - - if (rmodule_stage_load_from_cbfs(&rmod_ram)) { - printk(BIOS_DEBUG, "Could not load ramstage.\n"); - return -1; - } - - return 0; -} - -#else /* CONFIG_RELOCATABLE_RAMSTAGE */ - -static int cbfs_load_ramstage(struct prog *ramstage) -{ - return cbfs_load_prog_stage(CBFS_DEFAULT_MEDIA, ramstage); - -} - -#endif /* CONFIG_RELOCATABLE_RAMSTAGE */ - -const struct prog_loader_ops cbfs_ramstage_loader = { - .name = "CBFS", - .prepare = cbfs_load_ramstage, -}; diff --git a/src/lib/loaders/cbfs_romstage_loader.c b/src/lib/loaders/cbfs_romstage_loader.c deleted file mode 100644 index e5b4215..0000000 --- a/src/lib/loaders/cbfs_romstage_loader.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2015 Google Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc. - */ - -#include <cbfs.h> -#include <program_loading.h> - -static int cbfs_load_romstage(struct prog *romstage) -{ - return cbfs_load_prog_stage(CBFS_DEFAULT_MEDIA, romstage); -} - -const struct prog_loader_ops cbfs_romstage_loader = { - .name = "CBFS", - .prepare = cbfs_load_romstage, -}; diff --git a/src/lib/loaders/load_and_run_payload.c b/src/lib/loaders/load_and_run_payload.c deleted file mode 100644 index 6616110..0000000 --- a/src/lib/loaders/load_and_run_payload.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc. - */ - -#include <stdint.h> -#include <stdlib.h> -#include <cbmem.h> -#include <console/console.h> -#include <fallback.h> -#include <lib.h> -#include <program_loading.h> -#include <symbols.h> -#include <timestamp.h> - -extern const struct prog_loader_ops vboot_loader; -extern const struct prog_loader_ops cbfs_payload_loader; - -static const struct prog_loader_ops *payload_ops[] = { -#if CONFIG_VBOOT_VERIFY_FIRMWARE - &vboot_loader, -#endif - &cbfs_payload_loader, -}; - -static struct prog global_payload = { - .name = CONFIG_CBFS_PREFIX "/payload", - .type = PROG_PAYLOAD, -}; - -void __attribute__((weak)) mirror_payload(struct prog *payload) -{ - return; -} - -void payload_load(void) -{ - int i; - const struct prog_loader_ops *ops; - struct prog *payload = &global_payload; - - for (i = 0; i < ARRAY_SIZE(payload_ops); i++) { - /* Default loader state is active. */ - int ret = 1; - - ops = payload_ops[i]; - - if (ops->is_loader_active != NULL) - ret = ops->is_loader_active(payload); - - if (ret == 0) { - printk(BIOS_DEBUG, "%s payload loader inactive.\n", - ops->name); - continue; - } else if (ret < 0) { - printk(BIOS_DEBUG, "%s payload loader failure.\n", - ops->name); - continue; - } - - if (ops->prepare(payload) < 0) { - printk(BIOS_DEBUG, "%s: could not locate payload.\n", - ops->name); - continue; - } - printk(BIOS_DEBUG, "%s: located payload @ %p, %zu bytes.\n", - ops->name, prog_start(payload), prog_size(payload)); - break; - } - - if (i == ARRAY_SIZE(payload_ops)) - goto out; - - mirror_payload(payload); - - /* Pass cbtables to payload if architecture desires it. */ - prog_set_entry(payload, selfload(payload), - cbmem_find(CBMEM_ID_CBTABLE)); - -out: - if (prog_entry(payload) == NULL) - die("Payload not loaded.\n"); -} - -void payload_run(void) -{ - struct prog *payload = &global_payload; - - /* Reset to booting from this image as late as possible */ - boot_successful(); - - printk(BIOS_DEBUG, "Jumping to boot code at %p(%p)\n", - prog_entry(payload), prog_entry_arg(payload)); - post_code(POST_ENTER_ELF_BOOT); - - timestamp_add_now(TS_SELFBOOT_JUMP); - - /* Before we go off to run the payload, see if - * we stayed within our bounds. - */ - checkstack(_estack, 0); - - prog_run(payload); -} diff --git a/src/lib/loaders/load_and_run_ramstage.c b/src/lib/loaders/load_and_run_ramstage.c deleted file mode 100644 index 47637b8..0000000 --- a/src/lib/loaders/load_and_run_ramstage.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc. - */ - -#include <stdlib.h> -#include <console/console.h> -#include <arch/stages.h> -#include <cbfs.h> -#include <program_loading.h> -#include <romstage_handoff.h> -#include <stage_cache.h> -#include <timestamp.h> - -extern const struct prog_loader_ops cbfs_ramstage_loader; -extern const struct prog_loader_ops vboot_loader; - -static const struct prog_loader_ops *loaders[] = { -#if CONFIG_VBOOT_VERIFY_FIRMWARE - &vboot_loader, -#endif - &cbfs_ramstage_loader, -}; - -void __attribute__((weak)) stage_cache_add(int stage_id, struct prog *stage) {} -void __attribute__((weak)) stage_cache_load_stage(int stage_id, - struct prog *stage) {} -void __attribute__((weak)) ramstage_cache_invalid(void) {} - -static void load_ramstage(const struct prog_loader_ops *ops, - struct prog *ramstage) -{ - timestamp_add_now(TS_START_COPYRAM); - - if (ops->prepare(ramstage)) - return; - - stage_cache_add(STAGE_RAMSTAGE, ramstage); - - timestamp_add_now(TS_END_COPYRAM); - - prog_run(ramstage); -} - -static void run_ramstage_from_resume(struct romstage_handoff *handoff, - struct prog *ramstage) -{ - if (handoff != NULL && handoff->s3_resume) { - /* Load the cached ramstage to runtime location. */ - stage_cache_load_stage(STAGE_RAMSTAGE, ramstage); - - if (prog_entry(ramstage) != NULL) { - printk(BIOS_DEBUG, "Jumping to image.\n"); - prog_run(ramstage); - } - ramstage_cache_invalid(); - } -} - -void run_ramstage(void) -{ - const struct prog_loader_ops *ops; - int i; - struct prog ramstage = { - .name = CONFIG_CBFS_PREFIX "/ramstage", - .type = PROG_RAMSTAGE, - }; - - run_ramstage_from_resume(romstage_handoff_find_or_add(), &ramstage); - - for (i = 0; i < ARRAY_SIZE(loaders); i++) { - /* Default loader state is active. */ - int ret = 1; - - ops = loaders[i]; - - if (ops->is_loader_active != NULL) - ret = ops->is_loader_active(&ramstage); - - if (ret == 0) { - printk(BIOS_DEBUG, "%s ramstage loader inactive.\n", - ops->name); - continue; - } else if (ret < 0) { - printk(BIOS_DEBUG, "%s ramstage loader failure.\n", - ops->name); - continue; - } - - printk(BIOS_DEBUG, "%s ramstage loader active.\n", ops->name); - load_ramstage(ops, &ramstage); - } - - die("Ramstage was not loaded!\n"); -} diff --git a/src/lib/loaders/load_and_run_romstage.c b/src/lib/loaders/load_and_run_romstage.c deleted file mode 100644 index dfcb859..0000000 --- a/src/lib/loaders/load_and_run_romstage.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2015 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc. - */ - - -#include <stdlib.h> -#include <console/console.h> -#include <arch/stages.h> -#include <cbfs.h> -#include <halt.h> -#include <program_loading.h> -#include <rules.h> -#include <timestamp.h> - -extern const struct prog_loader_ops cbfs_romstage_loader; -extern const struct prog_loader_ops vboot_loader; - -static const struct prog_loader_ops *loaders[] = { -#if CONFIG_VBOOT_VERIFY_FIRMWARE - &vboot_loader, -#endif -#if !ENV_VERSTAGE || (ENV_VERSTAGE && !CONFIG_RETURN_FROM_VERSTAGE) - &cbfs_romstage_loader, -#endif -}; - -void run_romstage(void) -{ - int i; - struct prog romstage = { - .name = CONFIG_CBFS_PREFIX "/romstage", - .type = PROG_ROMSTAGE, - }; - - for (i = 0; i < ARRAY_SIZE(loaders); i++) { - /* Default loader state is active. */ - int ret = 1; - const struct prog_loader_ops *ops; - - ops = loaders[i]; - - if (ops->is_loader_active != NULL) - ret = ops->is_loader_active(&romstage); - - if (ret == 0) { - printk(BIOS_DEBUG, "%s romstage loader inactive.\n", - ops->name); - continue; - } else if (ret < 0) { - printk(BIOS_DEBUG, "%s romstage loader failure.\n", - ops->name); - continue; - } - - printk(BIOS_DEBUG, "%s romstage loader active.\n", ops->name); - - timestamp_add_now(TS_START_COPYROM); - - if (ops->prepare(&romstage)) - continue; - - timestamp_add_now(TS_END_COPYROM); - - prog_run(&romstage); - } - - if (IS_ENABLED(CONFIG_BOOTBLOCK_CONSOLE)) - die("Couldn't load romstage.\n"); - halt(); -} diff --git a/src/lib/prog_loaders.c b/src/lib/prog_loaders.c new file mode 100644 index 0000000..881cd99 --- /dev/null +++ b/src/lib/prog_loaders.c @@ -0,0 +1,247 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2015 Google Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc. + */ + + +#include <stdlib.h> +#include <arch/stages.h> +#include <boot_device.h> +#include <cbfs.h> +#include <cbmem.h> +#include <console/console.h> +#include <fallback.h> +#include <halt.h> +#include <lib.h> +#include <program_loading.h> +#include <romstage_handoff.h> +#include <rmodule.h> +#include <rules.h> +#include <stage_cache.h> +#include <symbols.h> +#include <timestamp.h> + +#define DEFAULT_CBFS_LOADER_PRESENT \ + (!ENV_VERSTAGE || (ENV_VERSTAGE && !CONFIG_RETURN_FROM_VERSTAGE)) + +#if DEFAULT_CBFS_LOADER_PRESENT +static int cbfs_boot_prog_locate(struct prog *prog) +{ + return cbfs_boot_locate(&prog->rdev, prog->name, NULL); +} + +static const struct prog_loader_ops cbfs_default_loader = { + .locate = cbfs_boot_prog_locate, +}; +#endif + +extern const struct prog_loader_ops vboot_loader; + +static const struct prog_loader_ops *loaders[] = { +#if CONFIG_VBOOT_VERIFY_FIRMWARE + &vboot_loader, +#endif +#if DEFAULT_CBFS_LOADER_PRESENT + &cbfs_default_loader, +#endif +}; + +int prog_locate(struct prog *prog) +{ + int i; + + boot_device_init(); + + for (i = 0; i < ARRAY_SIZE(loaders); i++) { + /* Default loader state is active. */ + int ret = 1; + const struct prog_loader_ops *ops; + + ops = loaders[i]; + + if (ops->is_loader_active != NULL) + ret = ops->is_loader_active(prog); + + if (ret == 0) { + printk(BIOS_DEBUG, "%s loader inactive.\n", + ops->name); + continue; + } else if (ret < 0) { + printk(BIOS_DEBUG, "%s loader failure.\n", + ops->name); + continue; + } + + printk(BIOS_DEBUG, "%s loader active.\n", ops->name); + + if (ops->locate(prog)) + continue; + + printk(BIOS_DEBUG, "'%s' located at offset: %zx size: %zx\n", + prog->name, region_device_offset(&prog->rdev), + region_device_sz(&prog->rdev)); + + return 0; + } + + return -1; +} + +void run_romstage(void) +{ + struct prog romstage = { + .name = CONFIG_CBFS_PREFIX "/romstage", + .type = PROG_ROMSTAGE, + }; + + /* The only time the default CBFS loader isn't present is during + * VERSTAGE in which it returns back to the calling stage. */ + if (!DEFAULT_CBFS_LOADER_PRESENT) + return; + + if (prog_locate(&romstage)) + goto fail; + + timestamp_add_now(TS_START_COPYROM); + + if (cbfs_prog_stage_load(&romstage)) + goto fail; + + timestamp_add_now(TS_END_COPYROM); + + prog_run(&romstage); + +fail: + if (IS_ENABLED(CONFIG_BOOTBLOCK_CONSOLE)) + die("Couldn't load romstage.\n"); + halt(); +} + +void __attribute__((weak)) stage_cache_add(int stage_id, struct prog *stage) {} +void __attribute__((weak)) stage_cache_load_stage(int stage_id, + struct prog *stage) {} +void __attribute__((weak)) ramstage_cache_invalid(void) {} + +static void run_ramstage_from_resume(struct romstage_handoff *handoff, + struct prog *ramstage) +{ + if (handoff != NULL && handoff->s3_resume) { + /* Load the cached ramstage to runtime location. */ + stage_cache_load_stage(STAGE_RAMSTAGE, ramstage); + + if (prog_entry(ramstage) != NULL) { + printk(BIOS_DEBUG, "Jumping to image.\n"); + prog_run(ramstage); + } + ramstage_cache_invalid(); + } +} + +static int load_relocatable_ramstage(struct prog *ramstage) +{ + struct rmod_stage_load rmod_ram = { + .cbmem_id = CBMEM_ID_RAMSTAGE, + .prog = ramstage, + }; + + return rmodule_stage_load(&rmod_ram); +} + +void run_ramstage(void) +{ + struct prog ramstage = { + .name = CONFIG_CBFS_PREFIX "/ramstage", + .type = PROG_RAMSTAGE, + }; + + /* Only x86 systems currently take the same firmware path on resume. */ + if (IS_ENABLED(CONFIG_ARCH_X86) && IS_ENABLED(CONFIG_EARLY_CBMEM_INIT)) + run_ramstage_from_resume(romstage_handoff_find_or_add(), + &ramstage); + + if (prog_locate(&ramstage)) + goto fail; + + timestamp_add_now(TS_START_COPYRAM); + + if (IS_ENABLED(CONFIG_RELOCATABLE_RAMSTAGE)) { + if (load_relocatable_ramstage(&ramstage)) + goto fail; + } else if (cbfs_prog_stage_load(&ramstage)) + goto fail; + + stage_cache_add(STAGE_RAMSTAGE, &ramstage); + + timestamp_add_now(TS_END_COPYRAM); + + prog_run(&ramstage); + +fail: + die("Ramstage was not loaded!\n"); +} + +static struct prog global_payload = { + .name = CONFIG_CBFS_PREFIX "/payload", + .type = PROG_PAYLOAD, +}; + +void __attribute__((weak)) mirror_payload(struct prog *payload) +{ + return; +} + +void payload_load(void) +{ + struct prog *payload = &global_payload; + + timestamp_add_now(TS_LOAD_PAYLOAD); + + if (prog_locate(payload)) + goto out; + + mirror_payload(payload); + + /* Pass cbtables to payload if architecture desires it. */ + prog_set_entry(payload, selfload(payload), + cbmem_find(CBMEM_ID_CBTABLE)); + +out: + if (prog_entry(payload) == NULL) + die("Payload not loaded.\n"); +} + +void payload_run(void) +{ + struct prog *payload = &global_payload; + + /* Reset to booting from this image as late as possible */ + boot_successful(); + + printk(BIOS_DEBUG, "Jumping to boot code at %p(%p)\n", + prog_entry(payload), prog_entry_arg(payload)); + + post_code(POST_ENTER_ELF_BOOT); + + timestamp_add_now(TS_SELFBOOT_JUMP); + + /* Before we go off to run the payload, see if + * we stayed within our bounds. + */ + checkstack(_estack, 0); + + prog_run(payload); +} diff --git a/src/lib/rmodule.c b/src/lib/rmodule.c index 359272f..35893d9 100644 --- a/src/lib/rmodule.c +++ b/src/lib/rmodule.c @@ -22,6 +22,7 @@ #include <stdint.h> #include <stdlib.h> #include <string.h> +#include <lib.h> #include <console/console.h> #include <program_loading.h> #include <rmodule.h> @@ -252,34 +253,60 @@ int rmodule_calc_region(unsigned int region_alignment, size_t rmodule_size, return region_alignment - sizeof(struct rmodule_header); }
-int rmodule_stage_load(struct rmod_stage_load *rsl, struct cbfs_stage *stage) +int rmodule_stage_load(struct rmod_stage_load *rsl) { struct rmodule rmod_stage; size_t region_size; char *stage_region; int rmodule_offset; int load_offset; + struct cbfs_stage stage; + void *rmod_loc; + struct region_device *fh;
- if (stage == NULL || rsl->prog == NULL || rsl->prog->name == NULL) + if (rsl->prog == NULL || rsl->prog->name == NULL) + return -1; + + fh = &rsl->prog->rdev; + + if (rdev_readat(fh, &stage, 0, sizeof(stage)) != sizeof(stage)) return -1;
rmodule_offset = rmodule_calc_region(DYN_CBMEM_ALIGN_SIZE, - stage->memlen, ®ion_size, &load_offset); + stage.memlen, ®ion_size, &load_offset);
stage_region = cbmem_add(rsl->cbmem_id, region_size);
if (stage_region == NULL) return -1;
+ rmod_loc = &stage_region[rmodule_offset]; + printk(BIOS_INFO, "Decompressing stage %s @ 0x%p (%d bytes)\n", - rsl->prog->name, &stage_region[rmodule_offset], stage->memlen); + rsl->prog->name, rmod_loc, stage.memlen); + + if (stage.compression == CBFS_COMPRESS_NONE) { + if (rdev_readat(fh, rmod_loc, sizeof(stage), stage.len) != + stage.len) + return -1; + } else if (stage.compression == CBFS_COMPRESS_LZMA) { + size_t fsize; + void *map = rdev_mmap(fh, sizeof(stage), stage.len); + + if (map == NULL) + return -1; + + fsize = ulzma(map, rmod_loc); + + rdev_munmap(fh, map);
- if (!cbfs_decompress(stage->compression, &stage[1], - &stage_region[rmodule_offset], stage->len)) + if (!fsize) + return -1; + } else return -1;
- if (rmodule_parse(&stage_region[rmodule_offset], &rmod_stage)) + if (rmodule_parse(rmod_loc, &rmod_stage)) return -1;
if (rmodule_load(&stage_region[load_offset], &rmod_stage)) @@ -291,16 +318,3 @@ int rmodule_stage_load(struct rmod_stage_load *rsl, struct cbfs_stage *stage)
return 0; } - -int rmodule_stage_load_from_cbfs(struct rmod_stage_load *rsl) -{ - struct cbfs_stage *stage; - - stage = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, - rsl->prog->name, CBFS_TYPE_STAGE, NULL); - - if (stage == NULL) - return -1; - - return rmodule_stage_load(rsl, stage); -} diff --git a/src/lib/selfboot.c b/src/lib/selfboot.c index 06c0f60..3f8cc6f 100644 --- a/src/lib/selfboot.c +++ b/src/lib/selfboot.c @@ -211,13 +211,11 @@ static int relocate_segment(unsigned long buffer, struct segment *seg)
static int build_self_segment_list( struct segment *head, - struct prog *payload, uintptr_t *entry) + struct cbfs_payload *cbfs_payload, uintptr_t *entry) { struct segment *new; struct segment *ptr; struct cbfs_payload_segment *segment, *first_segment; - struct cbfs_payload *cbfs_payload; - cbfs_payload = prog_start(payload); memset(head, 0, sizeof(*head)); head->next = head->prev = head; first_segment = segment = &cbfs_payload->segments; @@ -447,9 +445,6 @@ static int load_self_segments( } }
- /* Update the payload's area with the bounce buffer information. */ - prog_set_area(payload, (void *)(uintptr_t)bounce_buffer, bounce_size); - return 1; }
@@ -457,9 +452,15 @@ void *selfload(struct prog *payload) { uintptr_t entry = 0; struct segment head; + void *data; + + data = rdev_mmap_full(&payload->rdev); + + if (data == NULL) + return NULL;
/* Preprocess the self segments */ - if (!build_self_segment_list(&head, payload, &entry)) + if (!build_self_segment_list(&head, data, &entry)) goto out;
/* Load the segments */ @@ -468,8 +469,14 @@ void *selfload(struct prog *payload)
printk(BIOS_SPEW, "Loaded segments\n");
+ rdev_munmap(&payload->rdev, data); + + /* Update the payload's area with the bounce buffer information. */ + prog_set_area(payload, (void *)(uintptr_t)bounce_buffer, bounce_size); + return (void *)entry;
out: + rdev_munmap(&payload->rdev, data); return NULL; } diff --git a/src/mainboard/emulation/qemu-armv7/media.c b/src/mainboard/emulation/qemu-armv7/media.c index e0f2251..cb0b275 100644 --- a/src/mainboard/emulation/qemu-armv7/media.c +++ b/src/mainboard/emulation/qemu-armv7/media.c @@ -13,83 +13,12 @@ * GNU General Public License for more details. */ #include <boot_device.h> -#include <cbfs.h> -#include <string.h> -#include <symbols.h> -#include <console/console.h>
/* Maps directly to qemu memory mapped space of 0x10000 up to rom size. */ -static const struct mem_region_device gboot_dev = +static const struct mem_region_device boot_dev = MEM_REGION_DEV_INIT((void *)0x10000, CONFIG_ROM_SIZE);
const struct region_device *boot_device_ro(void) { - return &gboot_dev.rdev; -} - -static int emu_rom_open(struct cbfs_media *media) -{ - return 0; -} - -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; -} - -static void *emu_rom_unmap(struct cbfs_media *media, const void *address) -{ - const struct region_device *boot_dev; - - boot_dev = media->context; - - rdev_munmap(boot_dev, (void *)address); - - return NULL; -} - -static size_t emu_rom_read(struct cbfs_media *media, void *dest, size_t offset, - size_t count) -{ - const struct region_device *boot_dev; - - boot_dev = media->context; - - if (rdev_readat(boot_dev, dest, offset, count) < 0) - return 0; - - return count; -} - -static int emu_rom_close(struct cbfs_media *media) -{ - return 0; -} - -static int init_emu_rom_cbfs_media(struct cbfs_media *media) -{ - boot_device_init(); - - media->context = (void *)boot_device_ro(); - media->open = emu_rom_open; - media->close = emu_rom_close; - media->map = emu_rom_map; - media->unmap = emu_rom_unmap; - media->read = emu_rom_read; - return 0; -} - -int init_default_cbfs_media(struct cbfs_media *media) -{ - return init_emu_rom_cbfs_media(media); + return &boot_dev.rdev; } diff --git a/src/mainboard/google/bolt/romstage.c b/src/mainboard/google/bolt/romstage.c index 62549f5..f721a70 100644 --- a/src/mainboard/google/bolt/romstage.c +++ b/src/mainboard/google/bolt/romstage.c @@ -78,8 +78,8 @@ static void copy_spd(struct pei_data *peid) int spd_index = 0; /* No GPIO selection, force index 0 for now */
printk(BIOS_DEBUG, "SPD index %d\n", spd_index); - spd_file = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "spd.bin", - CBFS_TYPE_SPD, &spd_file_len); + spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, + &spd_file_len); if (!spd_file) die("SPD data not found.");
diff --git a/src/mainboard/google/butterfly/mainboard.c b/src/mainboard/google/butterfly/mainboard.c index e09336d..629e90f 100644 --- a/src/mainboard/google/butterfly/mainboard.c +++ b/src/mainboard/google/butterfly/mainboard.c @@ -211,9 +211,8 @@ static void mainboard_init(device_t dev) } } } else { - vpd_file = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, - "vpd.bin", CBFS_TYPE_RAW, - &search_length); + vpd_file = cbfs_boot_map_with_leak("vpd.bin", CBFS_TYPE_RAW, + &search_length); if (vpd_file) { search_address = (unsigned long)vpd_file; } else { diff --git a/src/mainboard/google/falco/romstage.c b/src/mainboard/google/falco/romstage.c index edbf371..7282c1e 100644 --- a/src/mainboard/google/falco/romstage.c +++ b/src/mainboard/google/falco/romstage.c @@ -79,8 +79,8 @@ static void copy_spd(struct pei_data *peid) size_t spd_file_len;
printk(BIOS_DEBUG, "SPD index %d\n", spd_index); - spd_file = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "spd.bin", - CBFS_TYPE_SPD, &spd_file_len); + spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, + &spd_file_len); if (!spd_file) die("SPD data not found.");
diff --git a/src/mainboard/google/link/romstage.c b/src/mainboard/google/link/romstage.c index ca8c2bd..7ad9210 100644 --- a/src/mainboard/google/link/romstage.c +++ b/src/mainboard/google/link/romstage.c @@ -94,8 +94,8 @@ static void copy_spd(struct pei_data *peid) int spd_index = get_gpios(gpio_vector);
printk(BIOS_DEBUG, "spd index %d\n", spd_index); - spd_file = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "spd.bin", - CBFS_TYPE_SPD, &spd_file_len); + spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, + &spd_file_len); if (!spd_file) die("SPD data not found.");
diff --git a/src/mainboard/google/panther/lan.c b/src/mainboard/google/panther/lan.c index 8a648cb..4b34c06 100644 --- a/src/mainboard/google/panther/lan.c +++ b/src/mainboard/google/panther/lan.c @@ -127,8 +127,7 @@ static void program_mac_address(u16 io_base) search_length = region_device_sz(&rdev); } } else { - search_address = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, - "vpd.bin", + search_address = cbfs_boot_map_with_leak("vpd.bin", CBFS_TYPE_RAW, &search_length); } diff --git a/src/mainboard/google/peach_pit/romstage.c b/src/mainboard/google/peach_pit/romstage.c index 6734b77..35cf906 100644 --- a/src/mainboard/google/peach_pit/romstage.c +++ b/src/mainboard/google/peach_pit/romstage.c @@ -21,12 +21,14 @@ #include <arch/exception.h> #include <arch/stages.h> #include <armv7.h> +#include <boot_device.h> #include <cbfs.h> #include <cbmem.h> #include <console/console.h> #include <device/i2c.h> #include <drivers/maxim/max77802/max77802.h> #include <program_loading.h> +#include <region.h> #include <soc/clk.h> #include <soc/cpu.h> #include <soc/dmc.h> @@ -176,29 +178,28 @@ static unsigned long primitive_mem_test(void) /* here is a simple SPI debug test, known to fid trouble */ static void simple_spi_test(void) { - struct cbfs_media default_media, *media; + const struct region_device *boot_dev; int i, amt = 4 * MiB, errors = 0; //u32 *data = (void *)0x40000000; u32 data[1024]; u32 in;
+ boot_device_init(); + boot_dev = boot_device_ro(); amt = sizeof(data); - media = &default_media; - if (init_default_cbfs_media(media) != 0) { + if (boot_dev == NULL) { printk(BIOS_SPEW, "Failed to initialize default media.\n"); return; }
- - media->open(media); - if (media->read(media, data, (size_t) 0, amt) < amt){ + if (rdev_readat(boot_dev, data, 0, amt) < amt) { printk(BIOS_SPEW, "simple_spi_test fails\n"); return; }
for(i = 0; i < amt; i += 4){ - if (media->read(media, &in, (size_t) i, 4) < 1){ + if (rdev_readat(boot_dev, &in, i, 4) < 4) { printk(BIOS_SPEW, "simple_spi_test fails at %d\n", i); return; } @@ -207,7 +208,7 @@ static void simple_spi_test(void) printk(BIOS_SPEW, "BAD at %d(%p):\nRAM %08lx\nSPI %08lx\n", i, &data[i/4], (unsigned long)data[i/4], (unsigned long)in); /* reread it to see which is wrong. */ - if (media->read(media, &in, (size_t) i, 4) < 1){ + if (rdev_readat(boot_dev, &in, i, 4) < 4) { printk(BIOS_SPEW, "simple_spi_test fails at %d\n", i); return; } diff --git a/src/mainboard/google/peppy/romstage.c b/src/mainboard/google/peppy/romstage.c index bd4ce3d..6957783 100644 --- a/src/mainboard/google/peppy/romstage.c +++ b/src/mainboard/google/peppy/romstage.c @@ -82,8 +82,8 @@ static void copy_spd(struct pei_data *peid) size_t spd_file_len;
printk(BIOS_DEBUG, "SPD index %d\n", spd_index); - spd_file = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "spd.bin", - CBFS_TYPE_SPD, &spd_file_len); + spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, + &spd_file_len); if (!spd_file) die("SPD data not found.");
diff --git a/src/mainboard/google/rambi/romstage.c b/src/mainboard/google/rambi/romstage.c index 1fd03bd..adbdffb 100644 --- a/src/mainboard/google/rambi/romstage.c +++ b/src/mainboard/google/rambi/romstage.c @@ -71,9 +71,10 @@ static void *get_spd_pointer(char *spd_file_content, int total_spds, int *dual)
void mainboard_romstage_entry(struct romstage_params *rp) { - struct cbfs_file *spd_file; void *spd_content; int dual_channel = 0; + void *spd_file; + size_t spd_fsize;
struct mrc_params mp = { .mainboard = { @@ -83,12 +84,12 @@ void mainboard_romstage_entry(struct romstage_params *rp) }, };
- spd_file = cbfs_get_file(CBFS_DEFAULT_MEDIA, "spd.bin"); + spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, + &spd_fsize); if (!spd_file) die("SPD data not found.");
- spd_content = get_spd_pointer(CBFS_SUBHEADER(spd_file), - ntohl(spd_file->len) / SPD_SIZE, + spd_content = get_spd_pointer(spd_file, spd_fsize / SPD_SIZE, &dual_channel); mp.mainboard.dram_data[0] = spd_content; if (dual_channel) diff --git a/src/mainboard/google/samus/spd/spd.c b/src/mainboard/google/samus/spd/spd.c index f8b0bf2..1979f8c 100644 --- a/src/mainboard/google/samus/spd/spd.c +++ b/src/mainboard/google/samus/spd/spd.c @@ -90,8 +90,8 @@ void mainboard_fill_spd_data(struct pei_data *pei_data) }; int spd_gpio[4]; int spd_index; - int spd_file_len; - struct cbfs_file *spd_file; + size_t spd_file_len; + char *spd_file;
spd_gpio[0] = get_gpio(spd_bits[0]); spd_gpio[1] = get_gpio(spd_bits[1]); @@ -106,10 +106,9 @@ void mainboard_fill_spd_data(struct pei_data *pei_data) spd_bits[3], spd_gpio[3], spd_bits[2], spd_gpio[2], spd_bits[1], spd_gpio[1], spd_bits[0], spd_gpio[0]);
- spd_file = cbfs_get_file(CBFS_DEFAULT_MEDIA, "spd.bin"); + spd_file = cbfs_boot_map_with_leak("spd.bin", 0xab, &spd_file_len); if (!spd_file) die("SPD data not found."); - spd_file_len = ntohl(spd_file->len);
if (spd_file_len < ((spd_index + 1) * SPD_LEN)) { printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n"); @@ -121,10 +120,8 @@ void mainboard_fill_spd_data(struct pei_data *pei_data)
/* Assume same memory in both channels */ spd_index *= SPD_LEN; - memcpy(pei_data->spd_data[0][0], - ((char*)CBFS_SUBHEADER(spd_file)) + spd_index, SPD_LEN); - memcpy(pei_data->spd_data[1][0], - ((char*)CBFS_SUBHEADER(spd_file)) + spd_index, SPD_LEN); + memcpy(pei_data->spd_data[0][0], spd_file + spd_index, SPD_LEN); + memcpy(pei_data->spd_data[1][0], spd_file + spd_index, SPD_LEN);
/* Make sure a valid SPD was found */ if (pei_data->spd_data[0][0][0] == 0) diff --git a/src/mainboard/google/slippy/romstage.c b/src/mainboard/google/slippy/romstage.c index 036cbe9..6948756 100644 --- a/src/mainboard/google/slippy/romstage.c +++ b/src/mainboard/google/slippy/romstage.c @@ -80,8 +80,8 @@ static void copy_spd(struct pei_data *peid) size_t spd_file_len;
printk(BIOS_DEBUG, "SPD index %d\n", spd_index); - spd_file = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "spd.bin", - CBFS_TYPE_SPD, &spd_file_len); + spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, + &spd_file_len); if (!spd_file) die("SPD data not found.");
diff --git a/src/mainboard/google/urara/boardid.c b/src/mainboard/google/urara/boardid.c index 8fcb565..1d21102 100644 --- a/src/mainboard/google/urara/boardid.c +++ b/src/mainboard/google/urara/boardid.c @@ -22,7 +22,7 @@ #include <string.h>
#include <boardid.h> -#include <cbfs_core.h> +#include <cbfs.h> #include <console/console.h>
#include "mainboard/google/urara/urara_boardid.h" @@ -47,28 +47,17 @@ static int cached_board_id = -1;
static uint8_t retrieve_board_id(void) { - struct cbfs_file *board_id_file; const char *board_id_file_name = CBFS_BOARD_ID_FILE_NAME; char *file_contents; int i; - unsigned length; + size_t length;
- board_id_file = cbfs_get_file(CBFS_DEFAULT_MEDIA, board_id_file_name); - if (!board_id_file) { - printk(BIOS_WARNING, - "board_id: failed to locate file '%s'\n", - board_id_file_name); - return 0; - } - - length = be32_to_cpu(board_id_file->len); - - file_contents = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, - board_id_file_name, - CBFS_TYPE_RAW, NULL); + file_contents = cbfs_boot_map_with_leak(board_id_file_name, + CBFS_TYPE_RAW, &length);
if (!file_contents) { - printk(BIOS_WARNING, "board_id: failed to read file '%s'\n", + printk(BIOS_WARNING, + "board_id: failed to locate file '%s'\n", board_id_file_name); return 0; } diff --git a/src/mainboard/samsung/lumpy/romstage.c b/src/mainboard/samsung/lumpy/romstage.c index 9b1a023..c551fdc 100644 --- a/src/mainboard/samsung/lumpy/romstage.c +++ b/src/mainboard/samsung/lumpy/romstage.c @@ -236,8 +236,8 @@ void main(unsigned long bist) break; }
- spd_data = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "spd.bin", - CBFS_TYPE_SPD, &spd_file_len); + spd_data = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, + &spd_file_len); if (!spd_data) die("SPD data not found."); if (spd_file_len < (spd_index + 1) * 256) diff --git a/src/mainboard/siemens/mc_tcu3/modhwinfo.c b/src/mainboard/siemens/mc_tcu3/modhwinfo.c index a2796b8..a024095 100644 --- a/src/mainboard/siemens/mc_tcu3/modhwinfo.c +++ b/src/mainboard/siemens/mc_tcu3/modhwinfo.c @@ -31,8 +31,7 @@ u8* get_first_linked_block(char *filename, u8 **file_offset) { u8* block_ptr = NULL;
- block_ptr = (cbfs_get_file_content(CBFS_DEFAULT_MEDIA, filename, - 0x50, NULL)); + block_ptr = cbfs_boot_map_with_leak(filename, 0x50, NULL); if (!block_ptr) return NULL; if (!strncmp((char*)block_ptr, "H1W2M3I4", LEN_MAGIC_NUM)) { @@ -57,8 +56,7 @@ struct hwinfo* get_hwinfo(char *filename) { struct hwinfo* main_hwinfo;
- main_hwinfo = (struct hwinfo*)(cbfs_get_file_content(CBFS_DEFAULT_MEDIA, - filename, 0x50, NULL)); + main_hwinfo = cbfs_boot_map_with_leak(filename, 0x50, NULL); if ((main_hwinfo) && (!strncmp(main_hwinfo->magicNumber, "H1W2M3I4", LEN_MAGIC_NUM)) && (main_hwinfo->length == LEN_MAIN_HWINFO)) diff --git a/src/northbridge/amd/agesa/common/common.c b/src/northbridge/amd/agesa/common/common.c index a77aea7..cc08ac1 100644 --- a/src/northbridge/amd/agesa/common/common.c +++ b/src/northbridge/amd/agesa/common/common.c @@ -38,7 +38,8 @@ AGESA_STATUS common_ReadCbfsSpd (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
char *spd_file;
- spd_file = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "spd.bin", CBFS_TYPE_SPD_BIN, &spd_file_length); + spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD_BIN, + &spd_file_length); if (!spd_file) die("file [spd.bin] not found in CBFS");
diff --git a/src/northbridge/amd/agesa/def_callouts.c b/src/northbridge/amd/agesa/def_callouts.c index fd3ceee..c07c063 100644 --- a/src/northbridge/amd/agesa/def_callouts.c +++ b/src/northbridge/amd/agesa/def_callouts.c @@ -117,8 +117,8 @@ AGESA_STATUS agesa_RunFuncOnAp (UINT32 Func, UINT32 Data, VOID *ConfigPtr) AGESA_STATUS agesa_GfxGetVbiosImage(UINT32 Func, UINT32 FchData, VOID *ConfigPrt) { GFX_VBIOS_IMAGE_INFO *pVbiosImageInfo = (GFX_VBIOS_IMAGE_INFO *)ConfigPrt; - pVbiosImageInfo->ImagePtr = cbfs_get_file_content( - CBFS_DEFAULT_MEDIA, "pci"CONFIG_VGA_BIOS_ID".rom", + pVbiosImageInfo->ImagePtr = cbfs_boot_map_with_leak( + "pci"CONFIG_VGA_BIOS_ID".rom", CBFS_TYPE_OPTIONROM, NULL); /* printk(BIOS_DEBUG, "IMGptr=%x\n", pVbiosImageInfo->ImagePtr); */ return pVbiosImageInfo->ImagePtr == NULL ? AGESA_WARNING : AGESA_SUCCESS; diff --git a/src/northbridge/amd/pi/agesawrapper.c b/src/northbridge/amd/pi/agesawrapper.c index 247a38f..1236932 100644 --- a/src/northbridge/amd/pi/agesawrapper.c +++ b/src/northbridge/amd/pi/agesawrapper.c @@ -593,20 +593,13 @@ AGESA_STATUS agesawrapper_amdreadeventlog (UINT8 HeapStatus)
const void *agesawrapper_locate_module (const CHAR8 name[8]) { - struct cbfs_media media; - struct cbfs_file* file; const void* agesa; const AMD_IMAGE_HEADER* image; const AMD_MODULE_HEADER* module; size_t file_size;
- if (init_default_cbfs_media(&media)) - return NULL; - file = cbfs_get_file(&media, (const char*)CONFIG_CBFS_AGESA_NAME); - if (!file) - return NULL; - agesa = cbfs_get_file_content(&media, (const char*)CONFIG_CBFS_AGESA_NAME, - ntohl(file->type), &file_size); + agesa = cbfs_boot_map_with_leak((const char *)CONFIG_CBFS_AGESA_NAME, + CBFS_TYPE_RAW, &file_size); if (!agesa) return NULL; image = LibAmdLocateImage(agesa, agesa + file_size - 1, 4096, name); diff --git a/src/northbridge/amd/pi/def_callouts.c b/src/northbridge/amd/pi/def_callouts.c index 0ff7f45..8a4472c 100644 --- a/src/northbridge/amd/pi/def_callouts.c +++ b/src/northbridge/amd/pi/def_callouts.c @@ -107,8 +107,8 @@ AGESA_STATUS agesa_RunFuncOnAp (UINT32 Func, UINT32 Data, VOID *ConfigPtr) AGESA_STATUS agesa_GfxGetVbiosImage(UINT32 Func, UINT32 FchData, VOID *ConfigPrt) { GFX_VBIOS_IMAGE_INFO *pVbiosImageInfo = (GFX_VBIOS_IMAGE_INFO *)ConfigPrt; - pVbiosImageInfo->ImagePtr = cbfs_get_file_content( - CBFS_DEFAULT_MEDIA, "pci"CONFIG_VGA_BIOS_ID".rom", + pVbiosImageInfo->ImagePtr = cbfs_boot_map_with_leak( + "pci"CONFIG_VGA_BIOS_ID".rom", CBFS_TYPE_OPTIONROM, NULL); printk(BIOS_DEBUG, "agesa_GfxGetVbiosImage: IMGptr=%p\n", pVbiosImageInfo->ImagePtr); return (pVbiosImageInfo->ImagePtr ? AGESA_SUCCESS : AGESA_WARNING); diff --git a/src/northbridge/intel/haswell/mrccache.c b/src/northbridge/intel/haswell/mrccache.c index d72c2c3..481110f 100644 --- a/src/northbridge/intel/haswell/mrccache.c +++ b/src/northbridge/intel/haswell/mrccache.c @@ -74,8 +74,7 @@ static u32 get_mrc_cache_region(struct mrc_data_container **mrc_region_ptr) *mrc_region_ptr = rdev_mmap_full(&rdev); } } else { - *mrc_region_ptr = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, - "mrc.cache", + *mrc_region_ptr = cbfs_boot_map_with_leak("mrc.cache", CBFS_TYPE_MRC_CACHE, ®ion_size); } diff --git a/src/northbridge/intel/haswell/raminit.c b/src/northbridge/intel/haswell/raminit.c index 9bb1d8a..86205ab 100644 --- a/src/northbridge/intel/haswell/raminit.c +++ b/src/northbridge/intel/haswell/raminit.c @@ -162,8 +162,8 @@ void sdram_initialize(struct pei_data *pei_data) pei_data->tx_byte = do_putchar;
/* Locate and call UEFI System Agent binary. */ - entry = (unsigned long)cbfs_get_file_content( - CBFS_DEFAULT_MEDIA, "mrc.bin", CBFS_TYPE_MRC, NULL); + entry = (unsigned long)cbfs_boot_map_with_leak("mrc.bin", + CBFS_TYPE_MRC, NULL); if (entry) { int rv; asm volatile ( diff --git a/src/northbridge/intel/i82830/vga.c b/src/northbridge/intel/i82830/vga.c index 0fd197b..7a79d13 100644 --- a/src/northbridge/intel/i82830/vga.c +++ b/src/northbridge/intel/i82830/vga.c @@ -31,8 +31,7 @@ static void vga_init(device_t dev) { printk(BIOS_INFO, "Starting Graphics Initialization\n"); size_t mbi_len; - void *mbi = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "mbi.bin", - CBFS_TYPE_MBI, &mbi_len); + void *mbi = cbfs_boot_map_with_leak("mbi.bin", CBFS_TYPE_MBI, &mbi_len);
if (mbi && mbi_len) { /* The GDT or coreboot table is going to live here. But diff --git a/src/northbridge/intel/sandybridge/mrccache.c b/src/northbridge/intel/sandybridge/mrccache.c index e17c54b..94a7c39 100644 --- a/src/northbridge/intel/sandybridge/mrccache.c +++ b/src/northbridge/intel/sandybridge/mrccache.c @@ -74,8 +74,7 @@ static u32 get_mrc_cache_region(struct mrc_data_container **mrc_region_ptr) *mrc_region_ptr = rdev_mmap_full(&rdev); } } else { - *mrc_region_ptr = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, - "mrc.cache", + *mrc_region_ptr = cbfs_boot_map_with_leak("mrc.cache", CBFS_TYPE_MRC_CACHE, ®ion_size); } diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c index 3cf0726..053a487 100644 --- a/src/northbridge/intel/sandybridge/raminit.c +++ b/src/northbridge/intel/sandybridge/raminit.c @@ -246,8 +246,7 @@ void sdram_initialize(struct pei_data *pei_data) pei_data->tx_byte = do_putchar;
/* Locate and call UEFI System Agent binary. */ - entry = cbfs_get_file_content( - CBFS_DEFAULT_MEDIA, "mrc.bin", CBFS_TYPE_MRC, NULL); + entry = cbfs_boot_map_with_leak("mrc.bin", CBFS_TYPE_MRC, NULL); if (entry) { int rv; rv = entry (pei_data); diff --git a/src/soc/broadcom/cygnus/include/soc/memlayout.ld b/src/soc/broadcom/cygnus/include/soc/memlayout.ld index 874fae8..3f6e8d8 100644 --- a/src/soc/broadcom/cygnus/include/soc/memlayout.ld +++ b/src/soc/broadcom/cygnus/include/soc/memlayout.ld @@ -34,7 +34,6 @@ SECTIONS VBOOT2_WORK(0x02010000, 16K) OVERLAP_VERSTAGE_ROMSTAGE(0x02014000, 120K) PRERAM_CBFS_CACHE(0x02032000, 1K) - CBFS_HEADER_OFFSET(0x02032800) STACK(0x02033000, 12K) REGION(reserved_for_secure_service_api, 0x0203F000, 4K, 4) SRAM_END(0x02040000) diff --git a/src/soc/intel/baytrail/refcode.c b/src/soc/intel/baytrail/refcode.c index 53da81d..0c49a80 100644 --- a/src/soc/intel/baytrail/refcode.c +++ b/src/soc/intel/baytrail/refcode.c @@ -26,9 +26,6 @@ #include <program_loading.h> #include <rmodule.h> #include <stage_cache.h> -#if IS_ENABLED(CONFIG_CHROMEOS) -#include <vendorcode/google/chromeos/vboot_handoff.h> -#endif
#include <soc/ramstage.h> #include <soc/efi_wrapper.h> @@ -49,58 +46,10 @@ static efi_wrapper_entry_t load_refcode_from_cache(void) return (efi_wrapper_entry_t)prog_entry(&refcode); }
-static void cache_refcode(const struct rmod_stage_load *rsl) -{ - stage_cache_add(STAGE_REFCODE, rsl->prog); -} - -#if IS_ENABLED(CONFIG_CHROMEOS) -static int load_refcode_from_vboot(struct rmod_stage_load *refcode) -{ - struct vboot_handoff *vboot_handoff; - const struct firmware_component *fwc; - struct cbfs_stage *stage; - - vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF); - fwc = &vboot_handoff->components[CONFIG_VBOOT_REFCODE_INDEX]; - - if (vboot_handoff == NULL || - vboot_handoff->selected_firmware == VB_SELECT_FIRMWARE_READONLY || - CONFIG_VBOOT_REFCODE_INDEX >= MAX_PARSED_FW_COMPONENTS || - fwc->size == 0 || fwc->address == 0) - return -1; - - printk(BIOS_DEBUG, "refcode loading from vboot rw area.\n"); - stage = (void *)(uintptr_t)fwc->address; - - if (rmodule_stage_load(refcode, stage)) { - printk(BIOS_DEBUG, "Error loading reference code.\n"); - return -1; - } - return 0; -} -#else -static int load_refcode_from_vboot(struct rmod_stage_load *refcode) -{ - return -1; -} -#endif - -static int load_refcode_from_cbfs(struct rmod_stage_load *refcode) -{ - printk(BIOS_DEBUG, "refcode loading from cbfs.\n"); - - if (rmodule_stage_load_from_cbfs(refcode)) { - printk(BIOS_DEBUG, "Error loading reference code.\n"); - return -1; - } - - return 0; -} - static efi_wrapper_entry_t load_reference_code(void) { struct prog prog = { + .type = PROG_REFCODE, .name = CONFIG_CBFS_PREFIX "/refcode", }; struct rmod_stage_load refcode = { @@ -112,12 +61,18 @@ static efi_wrapper_entry_t load_reference_code(void) return load_refcode_from_cache(); }
- if (load_refcode_from_vboot(&refcode) && - load_refcode_from_cbfs(&refcode)) - return NULL; + if (prog_locate(&prog)) { + printk(BIOS_DEBUG, "Couldn't locate reference code.\n"); + return NULL; + } + + if (rmodule_stage_load(&refcode)) { + printk(BIOS_DEBUG, "Error loading reference code.\n"); + return NULL; + }
/* Cache loaded reference code. */ - cache_refcode(&refcode); + stage_cache_add(STAGE_REFCODE, &prog);
return prog_entry(&prog); } diff --git a/src/soc/intel/baytrail/romstage/raminit.c b/src/soc/intel/baytrail/romstage/raminit.c index 7bbd671..191821a 100644 --- a/src/soc/intel/baytrail/romstage/raminit.c +++ b/src/soc/intel/baytrail/romstage/raminit.c @@ -148,8 +148,7 @@ void raminit(struct mrc_params *mp, int prev_sleep_state) }
/* Determine if mrc.bin is in the cbfs. */ - if (cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "mrc.bin", CBFS_TYPE_MRC, - NULL) == NULL) { + if (cbfs_boot_map_with_leak("mrc.bin", CBFS_TYPE_MRC, NULL) == NULL) { printk(BIOS_DEBUG, "Couldn't find mrc.bin\n"); return; } diff --git a/src/soc/intel/braswell/romstage/raminit.c b/src/soc/intel/braswell/romstage/raminit.c index 61c122c..8611d70 100644 --- a/src/soc/intel/braswell/romstage/raminit.c +++ b/src/soc/intel/braswell/romstage/raminit.c @@ -148,8 +148,7 @@ void raminit(struct mrc_params *mp, int prev_sleep_state) }
/* Determine if mrc.bin is in the cbfs. */ - if (cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "mrc.bin", CBFS_TYPE_MRC, - NULL) == NULL) { + if (cbfs_boot_map_with_leak("mrc.bin", CBFS_TYPE_MRC, NULL) == NULL) { printk(BIOS_DEBUG, "Couldn't find mrc.bin\n"); return; } diff --git a/src/soc/intel/broadwell/refcode.c b/src/soc/intel/broadwell/refcode.c index 2fb365d..45fd8e2 100644 --- a/src/soc/intel/broadwell/refcode.c +++ b/src/soc/intel/broadwell/refcode.c @@ -27,9 +27,6 @@ #include <rmodule.h> #include <stage_cache.h> #include <string.h> -#if IS_ENABLED(CONFIG_CHROMEOS) -#include <vendorcode/google/chromeos/vboot_handoff.h> -#endif #include <soc/pei_data.h> #include <soc/pei_wrapper.h> #include <soc/ramstage.h> @@ -45,58 +42,10 @@ static pei_wrapper_entry_t load_refcode_from_cache(void) return (pei_wrapper_entry_t)prog_entry(&refcode); }
-static void cache_refcode(const struct rmod_stage_load *rsl) -{ - stage_cache_add(STAGE_REFCODE, rsl->prog); -} - -#if IS_ENABLED(CONFIG_CHROMEOS) -static int load_refcode_from_vboot(struct rmod_stage_load *refcode) -{ - struct vboot_handoff *vboot_handoff; - const struct firmware_component *fwc; - struct cbfs_stage *stage; - - vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF); - fwc = &vboot_handoff->components[CONFIG_VBOOT_REFCODE_INDEX]; - - if (vboot_handoff == NULL || - vboot_handoff->selected_firmware == VB_SELECT_FIRMWARE_READONLY || - CONFIG_VBOOT_REFCODE_INDEX >= MAX_PARSED_FW_COMPONENTS || - fwc->size == 0 || fwc->address == 0) - return -1; - - printk(BIOS_DEBUG, "refcode loading from vboot rw area.\n"); - stage = (void *)(uintptr_t)fwc->address; - - if (rmodule_stage_load(refcode, stage)) { - printk(BIOS_DEBUG, "Error loading reference code.\n"); - return -1; - } - return 0; -} -#else -static int load_refcode_from_vboot(struct rmod_stage_load *refcode) -{ - return -1; -} -#endif - -static int load_refcode_from_cbfs(struct rmod_stage_load *refcode) -{ - printk(BIOS_DEBUG, "refcode loading from cbfs.\n"); - - if (rmodule_stage_load_from_cbfs(refcode)) { - printk(BIOS_DEBUG, "Error loading reference code.\n"); - return -1; - } - - return 0; -} - -static pei_wrapper_entry_t load_reference_code(void) +static efi_wrapper_entry_t load_reference_code(void) { struct prog prog = { + .type = PROG_REFCODE, .name = CONFIG_CBFS_PREFIX "/refcode", }; struct rmod_stage_load refcode = { @@ -108,12 +57,18 @@ static pei_wrapper_entry_t load_reference_code(void) return load_refcode_from_cache(); }
- if (load_refcode_from_vboot(&refcode) && - load_refcode_from_cbfs(&refcode)) - return NULL; + if (prog_locate(&prog)) { + printk(BIOS_DEBUG, "Couldn't locate reference code.\n"); + return NULL; + } + + if (rmodule_stage_load(&refcode)) { + printk(BIOS_DEBUG, "Error loading reference code.\n"); + return NULL; + }
/* Cache loaded reference code. */ - cache_refcode(&refcode); + stage_cache_add(STAGE_REFCODE, &prog);
return prog_entry(&prog); } diff --git a/src/soc/intel/broadwell/romstage/raminit.c b/src/soc/intel/broadwell/romstage/raminit.c index 8d37306..edc8790 100644 --- a/src/soc/intel/broadwell/romstage/raminit.c +++ b/src/soc/intel/broadwell/romstage/raminit.c @@ -86,8 +86,7 @@ void raminit(struct pei_data *pei_data) }
/* Determine if mrc.bin is in the cbfs. */ - entry = (pei_wrapper_entry_t)cbfs_get_file_content( - CBFS_DEFAULT_MEDIA, "mrc.bin", CBFS_TYPE_MRC, NULL); + entry = cbfs_boot_map_with_leak("mrc.bin", CBFS_TYPE_MRC, NULL); if (entry == NULL) { printk(BIOS_DEBUG, "Couldn't find mrc.bin\n"); return; diff --git a/src/soc/nvidia/tegra124/spi.c b/src/soc/nvidia/tegra124/spi.c index 0cf5495..7cc74c2 100644 --- a/src/soc/nvidia/tegra124/spi.c +++ b/src/soc/nvidia/tegra124/spi.c @@ -802,18 +802,6 @@ int spi_xfer(struct spi_slave *slave, const void *dout, return ret; }
-static int tegra_spi_cbfs_open(struct cbfs_media *media) -{ - DEBUG_SPI("tegra_spi_cbfs_open\n"); - return 0; -} - -static int tegra_spi_cbfs_close(struct cbfs_media *media) -{ - DEBUG_SPI("tegra_spi_cbfs_close\n"); - return 0; -} - #define JEDEC_READ 0x03 #define JEDEC_READ_OUTSIZE 0x04 #define JEDEC_FAST_READ_DUAL 0x3b @@ -877,69 +865,6 @@ tegra_spi_cbfs_read_exit: return ret; }
-static size_t tegra_spi_cbfs_read(struct cbfs_media *media, void *dest, - size_t offset, size_t count) -{ - const struct region_device *boot_dev; - - boot_dev = media->context; - - printk(BIOS_ERR, "%s: reading %zx bytes from %zx\n", - __func__, count, offset); - if (rdev_readat(boot_dev, dest, offset, count) < 0) - return 0; - - return count; -} - -static void *tegra_spi_cbfs_map(struct cbfs_media *media, size_t offset, - size_t count) -{ - const struct region_device *boot_dev; - void *map; - - DEBUG_SPI("tegra_spi_cbfs_map\n"); - - boot_dev = media->context; - - map = rdev_mmap(boot_dev, offset, count); - - if (map == NULL) - map = (void *)-1; - - return map; -} - -static void *tegra_spi_cbfs_unmap(struct cbfs_media *media, - const void *address) -{ - const struct region_device *boot_dev; - - DEBUG_SPI("tegra_spi_cbfs_unmap\n"); - - boot_dev = media->context; - - rdev_munmap(boot_dev, (void *)address); - - return NULL; -} - -int init_default_cbfs_media(struct cbfs_media *media) -{ - DEBUG_SPI("Initializing CBFS media on SPI\n"); - - boot_device_init(); - - media->context = (void *)boot_device_ro(); - media->open = tegra_spi_cbfs_open; - media->close = tegra_spi_cbfs_close; - media->read = tegra_spi_cbfs_read; - media->map = tegra_spi_cbfs_map; - media->unmap = tegra_spi_cbfs_unmap; - - return 0; -} - struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) { struct tegra_spi_channel *channel = to_tegra_spi(bus); diff --git a/src/soc/nvidia/tegra132/ccplex.c b/src/soc/nvidia/tegra132/ccplex.c index 7ab752f..e133b48 100644 --- a/src/soc/nvidia/tegra132/ccplex.c +++ b/src/soc/nvidia/tegra132/ccplex.c @@ -75,10 +75,9 @@ static int ccplex_start(void)
int ccplex_load_mts(void) { - struct cbfs_file file; - ssize_t offset; - size_t nread; + ssize_t nread; struct stopwatch sw; + struct region_device fh;
/* * MTS location is hard coded to this magic address. The hardware will @@ -86,21 +85,19 @@ int ccplex_load_mts(void) * place in the carveout region. */ void * const mts = (void *)(uintptr_t)MTS_LOAD_ADDRESS; - struct cbfs_media *media = CBFS_DEFAULT_MEDIA;
stopwatch_init(&sw); - offset = cbfs_locate_file(media, &file, MTS_FILE_NAME); - if (offset < 0) { + if (cbfs_boot_locate(&fh, MTS_FILE_NAME, NULL)) { printk(BIOS_DEBUG, "MTS file not found: %s\n", MTS_FILE_NAME); return -1; }
/* Read MTS file into the carveout region. */ - nread = cbfs_read(media, mts, offset, file.len); + nread = rdev_readat(&fh, mts, 0, region_device_sz(&fh));
- if (nread != file.len) { + if (nread != region_device_sz(&fh)) { printk(BIOS_DEBUG, "MTS bytes read (%zu) != file length(%u)!\n", - nread, file.len); + nread, region_device_sz(&fh)); return -1; }
diff --git a/src/soc/nvidia/tegra132/spi.c b/src/soc/nvidia/tegra132/spi.c index 1650057..efe4334 100644 --- a/src/soc/nvidia/tegra132/spi.c +++ b/src/soc/nvidia/tegra132/spi.c @@ -817,18 +817,6 @@ int spi_xfer(struct spi_slave *slave, const void *dout, return ret; }
-static int tegra_spi_cbfs_open(struct cbfs_media *media) -{ - DEBUG_SPI("tegra_spi_cbfs_open\n"); - return 0; -} - -static int tegra_spi_cbfs_close(struct cbfs_media *media) -{ - DEBUG_SPI("tegra_spi_cbfs_close\n"); - return 0; -} - #define JEDEC_READ 0x03 #define JEDEC_READ_OUTSIZE 0x04 #define JEDEC_FAST_READ_DUAL 0x3b @@ -892,69 +880,6 @@ tegra_spi_cbfs_read_exit: return ret; }
-static size_t tegra_spi_cbfs_read(struct cbfs_media *media, void *dest, - size_t offset, size_t count) -{ - const struct region_device *boot_dev; - - boot_dev = media->context; - - DEBUG_SPI("%s: reading %zx bytes from %zx\n", __func__, count, offset); - - if (rdev_readat(boot_dev, dest, offset, count) < 0) - return 0; - - return count; -} - -static void *tegra_spi_cbfs_map(struct cbfs_media *media, size_t offset, - size_t count) -{ - const struct region_device *boot_dev; - void *map; - - DEBUG_SPI("tegra_spi_cbfs_map\n"); - - boot_dev = media->context; - - map = rdev_mmap(boot_dev, offset, count); - - if (map == NULL) - map = (void *)-1; - - return map; -} - -static void *tegra_spi_cbfs_unmap(struct cbfs_media *media, - const void *address) -{ - const struct region_device *boot_dev; - - DEBUG_SPI("tegra_spi_cbfs_unmap\n"); - - boot_dev = media->context; - - rdev_munmap(boot_dev, (void *)address); - - return NULL; -} - -int init_default_cbfs_media(struct cbfs_media *media) -{ - DEBUG_SPI("Initializing CBFS media on SPI\n"); - - boot_device_init(); - - media->context = (void *)boot_device_ro(); - media->open = tegra_spi_cbfs_open; - media->close = tegra_spi_cbfs_close; - media->read = tegra_spi_cbfs_read; - media->map = tegra_spi_cbfs_map; - media->unmap = tegra_spi_cbfs_unmap; - - return 0; -} - struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) { struct tegra_spi_channel *channel = to_tegra_spi(bus); diff --git a/src/soc/qualcomm/ipq806x/blobs_init.c b/src/soc/qualcomm/ipq806x/blobs_init.c index dc52200..16179db 100644 --- a/src/soc/qualcomm/ipq806x/blobs_init.c +++ b/src/soc/qualcomm/ipq806x/blobs_init.c @@ -32,20 +32,18 @@
static void *load_ipq_blob(const char *file_name) { - struct cbfs_file *blob_file; struct mbn_header *blob_mbn; void *blob_dest; + size_t blob_size;
- blob_file = cbfs_get_file(CBFS_DEFAULT_MEDIA, file_name); - if (!blob_file) + blob_mbn = cbfs_boot_map_with_leak(file_name, CBFS_TYPE_RAW, + &blob_size); + if (!blob_mbn) return NULL;
- blob_mbn = (struct mbn_header *)((uintptr_t)blob_file + - ntohl(blob_file->offset)); - /* some sanity checks on the headers */ if ((blob_mbn->mbn_version != 3) || - (blob_mbn->mbn_total_size > ntohl(blob_file->len))) + (blob_mbn->mbn_total_size > blob_size)) return NULL;
blob_dest = (void *) blob_mbn->mbn_destination; diff --git a/src/soc/qualcomm/ipq806x/include/soc/memlayout.ld b/src/soc/qualcomm/ipq806x/include/soc/memlayout.ld index 62d755e..426d35b 100644 --- a/src/soc/qualcomm/ipq806x/include/soc/memlayout.ld +++ b/src/soc/qualcomm/ipq806x/include/soc/memlayout.ld @@ -34,9 +34,8 @@ SECTIONS OVERLAP_VERSTAGE_ROMSTAGE(0x2A012000, 64K) VBOOT2_WORK(0x2A022000, 16K) PRERAM_CBMEM_CONSOLE(0x2A026000, 32K) - CBFS_HEADER_OFFSET(0x2A02E400)
-/* 0x2e404..0x3F000 4 bytes shy of 67KB free */ +/* 0x2e400..0x3F000 67KB free */
/* Keep the below area reserved at all times, it is used by various QCA components as shared data diff --git a/src/soc/samsung/exynos5250/alternate_cbfs.c b/src/soc/samsung/exynos5250/alternate_cbfs.c index 546018a..cb69921 100644 --- a/src/soc/samsung/exynos5250/alternate_cbfs.c +++ b/src/soc/samsung/exynos5250/alternate_cbfs.c @@ -112,70 +112,6 @@ static int sdmmc_cbfs_open(void) return 0; }
-static int exynos_cbfs_open(struct cbfs_media *media) { - return 0; -} - -static int exynos_cbfs_close(struct cbfs_media *media) { - return 0; -} - -static size_t exynos_cbfs_read(struct cbfs_media *media, void *dest, - size_t offset, size_t count) { - const struct region_device *boot_dev; - - boot_dev = media->context; - - if (rdev_readat(boot_dev, dest, offset, count) < 0) - return 0; - - return count; -} - -static void *exynos_cbfs_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; -} - -static void *exynos_cbfs_unmap(struct cbfs_media *media, - const void *address) { - const struct region_device *boot_dev; - - boot_dev = media->context; - - rdev_munmap(boot_dev, (void *)address); - - return NULL; -} - -int init_default_cbfs_media(struct cbfs_media *media) -{ - boot_device_init(); - - media->context = (void *)boot_device_ro(); - - if (media->context == NULL) - return -1; - - media->open = exynos_cbfs_open; - media->close = exynos_cbfs_close; - media->read = exynos_cbfs_read; - media->map = exynos_cbfs_map; - media->unmap = exynos_cbfs_unmap; - - return 0; -} - static struct mem_region_device alternate_rdev = MEM_REGION_DEV_INIT(NULL, 0);
const struct region_device *boot_device_ro(void) diff --git a/src/soc/samsung/exynos5420/alternate_cbfs.c b/src/soc/samsung/exynos5420/alternate_cbfs.c index 9bba748..f3e7504 100644 --- a/src/soc/samsung/exynos5420/alternate_cbfs.c +++ b/src/soc/samsung/exynos5420/alternate_cbfs.c @@ -119,70 +119,6 @@ static int sdmmc_cbfs_open(void) return 0; }
-static int exynos_cbfs_open(struct cbfs_media *media) { - return 0; -} - -static int exynos_cbfs_close(struct cbfs_media *media) { - return 0; -} - -static size_t exynos_cbfs_read(struct cbfs_media *media, void *dest, - size_t offset, size_t count) { - const struct region_device *boot_dev; - - boot_dev = media->context; - - if (rdev_readat(boot_dev, dest, offset, count) < 0) - return 0; - - return count; -} - -static void *exynos_cbfs_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; -} - -static void *exynos_cbfs_unmap(struct cbfs_media *media, - const void *address) { - const struct region_device *boot_dev; - - boot_dev = media->context; - - rdev_munmap(boot_dev, (void *)address); - - return NULL; -} - -int init_default_cbfs_media(struct cbfs_media *media) -{ - boot_device_init(); - - media->context = (void *)boot_device_ro(); - - if (media->context == NULL) - return -1; - - media->open = exynos_cbfs_open; - media->close = exynos_cbfs_close; - media->read = exynos_cbfs_read; - media->map = exynos_cbfs_map; - media->unmap = exynos_cbfs_unmap; - - return 0; -} - static struct mem_region_device alternate_rdev = MEM_REGION_DEV_INIT(NULL, 0);
const struct region_device *boot_device_ro(void) diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_loader.c b/src/vendorcode/google/chromeos/vboot2/vboot_loader.c index 226578b..5248305 100644 --- a/src/vendorcode/google/chromeos/vboot2/vboot_loader.c +++ b/src/vendorcode/google/chromeos/vboot2/vboot_loader.c @@ -98,7 +98,8 @@ static int vboot_loader_active(struct prog *prog) printk(BIOS_DEBUG, "VBOOT: Loading verstage.\n");
/* load verstage from RO */ - if (cbfs_load_prog_stage(CBFS_DEFAULT_MEDIA, &verstage)) + if (cbfs_boot_locate(&verstage.rdev, verstage.name, NULL) || + cbfs_prog_stage_load(&verstage)) die("failed to load verstage");
/* verify and select a slot */ @@ -118,29 +119,34 @@ static int vboot_loader_active(struct prog *prog)
wd = vboot_get_working_data();
- if (vboot_is_slot_selected(wd)) { - if (IS_ENABLED(CONFIG_MULTIPLE_CBFS_INSTANCES) && - run_verification) { - /* RW A or B */ - struct region_device fw_main; - - if (vb2_get_selected_region(wd, &fw_main)) - die("failed to reference selected region\n"); - cbfs_set_header_offset(region_device_offset(&fw_main)); - } + if (vboot_is_slot_selected(wd)) return 1; - }
return 0; }
-static int vboot_fw_region(int fw_index, const struct region_device *fw_main, - struct region_device *fw) +static int vboot_locate_by_components(const struct region_device *fw_main, + struct prog *prog) { struct vboot_components *fw_info; size_t metadata_sz; size_t offset; size_t size; + struct region_device *fw = &prog->rdev; + int fw_index = 0; + + if (prog->type == PROG_ROMSTAGE) + fw_index = CONFIG_VBOOT_ROMSTAGE_INDEX; + else if (prog->type == PROG_RAMSTAGE) + fw_index = CONFIG_VBOOT_RAMSTAGE_INDEX; + else if (prog->type == PROG_PAYLOAD) + fw_index = CONFIG_VBOOT_BOOT_LOADER_INDEX; + else if (prog->type == PROG_REFCODE) + fw_index = CONFIG_VBOOT_REFCODE_INDEX; + else if (prog->type == PROG_BL31) + fw_index = CONFIG_VBOOT_BL31_INDEX; + else + die("Invalid program type for vboot.");
metadata_sz = sizeof(*fw_info); metadata_sz += MAX_PARSED_FW_COMPONENTS * sizeof(fw_info->entries[0]); @@ -153,7 +159,7 @@ static int vboot_fw_region(int fw_index, const struct region_device *fw_main, }
if (fw_index >= fw_info->num_components) { - printk(BIOS_INFO, "invalid stage index: %d\n", fw_index); + printk(BIOS_INFO, "invalid index: %d\n", fw_index); rdev_munmap(fw_main, fw_info); return -1; } @@ -163,16 +169,44 @@ static int vboot_fw_region(int fw_index, const struct region_device *fw_main, rdev_munmap(fw_main, fw_info);
if (rdev_chain(fw, fw_main, offset, size)) { - printk(BIOS_INFO, "invalid stage address or size\n"); + printk(BIOS_INFO, "invalid offset or size\n"); return -1; }
return 0; }
+static int vboot_locate_by_multi_cbfs(const struct region_device *fw_main, + struct prog *prog) +{ + struct cbfsd cbfs; + struct region_device rdev; + struct cbfs_props props; + + if (cbfs_boot_region_properties(&props)) + return -1; + + if (rdev_chain(&rdev, fw_main, props.offset, props.size)) + return -1; + + cbfs.rdev = &rdev; + cbfs.align = props.align; + + return cbfs_locate(&prog->rdev, &cbfs, prog->name, NULL); +} + +static int vboot_prog_locate(const struct region_device *fw_main, + struct prog *prog) +{ + if (IS_ENABLED(CONFIG_MULTIPLE_CBFS_INSTANCES)) + return vboot_locate_by_multi_cbfs(fw_main, prog); + else + return vboot_locate_by_components(fw_main, prog); +} + /* This function is only called when vboot_loader_active() returns 1. That * means we are taking vboot paths. */ -static int vboot_prepare(struct prog *prog) +static int vboot_locate(struct prog *prog) { struct vb2_working_data *wd; struct region_device fw_main; @@ -183,92 +217,15 @@ static int vboot_prepare(struct prog *prog) if (verstage_should_load() && !IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE)) return 0;
- /* In the multi cbfs case the cbfs offset pointer has already been - * updated after firmware verification. */ - if (IS_ENABLED(CONFIG_MULTIPLE_CBFS_INSTANCES)) { - if (!ENV_RAMSTAGE && - cbfs_load_prog_stage(CBFS_DEFAULT_MEDIA, prog) != 0) - return -1; - - /* Need to load payload. */ - if (ENV_RAMSTAGE) { - void *payload; - size_t size; - - payload = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, - prog->name, - CBFS_TYPE_PAYLOAD, - &size); - - if (payload == NULL) - die("Couldn't load payload\n"); - - prog_set_area(prog, payload, size); - } - return 0; - } - wd = vboot_get_working_data(); if (vb2_get_selected_region(wd, &fw_main)) die("failed to reference selected region\n");
- /* Load payload in ramstage. */ - if (ENV_RAMSTAGE) { - struct region_device payload; - void *payload_ptr; - - if (vboot_fw_region(CONFIG_VBOOT_BOOT_LOADER_INDEX, - &fw_main, &payload)) - die("Couldn't load payload."); - - payload_ptr = rdev_mmap_full(&payload); - - if (payload_ptr == NULL) - die("Couldn't load payload."); - - prog_set_area(prog, payload_ptr, region_device_sz(&payload)); - } else { - struct region_device stage; - int stage_index = 0; - - if (prog->type == PROG_ROMSTAGE) - stage_index = CONFIG_VBOOT_ROMSTAGE_INDEX; - else if (prog->type == PROG_RAMSTAGE) - stage_index = CONFIG_VBOOT_RAMSTAGE_INDEX; - else - die("Invalid program type for vboot."); - - if (vboot_fw_region(stage_index, &fw_main, &stage)) - die("Vboot stage load failed."); - - if (ENV_ROMSTAGE && IS_ENABLED(CONFIG_RELOCATABLE_RAMSTAGE)) { - void *stage_ptr; - struct rmod_stage_load rmod_ram = { - .cbmem_id = CBMEM_ID_RAMSTAGE, - .prog = prog, - }; - - stage_ptr = rdev_mmap_full(&stage); - - if (stage_ptr == NULL) - die("Vboot couldn't load stage."); - - if (rmodule_stage_load(&rmod_ram, stage_ptr)) - die("Vboot couldn't load stage"); - } else { - size_t offset = region_device_offset(&stage); - - if (cbfs_load_prog_stage_by_offset(CBFS_DEFAULT_MEDIA, - prog, offset)) - die("Vboot couldn't load stage"); - } - } - - return 0; + return vboot_prog_locate(&fw_main, prog); }
const struct prog_loader_ops vboot_loader = { .name = "VBOOT", .is_loader_active = vboot_loader_active, - .prepare = vboot_prepare, + .locate = vboot_locate, };