diff options
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 903c24d819..4dc0975e22 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 1bdf522a2c..3e0892ec34 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,34 +37,6 @@ 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 __attribute__((weak)) *soc_get_bl31_plat_params(bl31_params_t *params) { /* Default weak implementation. */ @@ -73,17 +45,19 @@ void __attribute__((weak)) *soc_get_bl31_plat_params(bl31_params_t *params) 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 f18030c49f..dd57849db4 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 4ce5ed6036..bfdb18fbf8 100644 --- a/src/arch/x86/boot/acpi.c +++ b/src/arch/x86/boot/acpi.c @@ -759,8 +759,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 diff --git a/src/arch/x86/lib/Makefile.inc b/src/arch/x86/lib/Makefile.inc index e308be91bc..0d88a6daea 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 eb7b23e2b1..4dd269b772 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 d4663c7f60..0000000000 --- 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 a585bcaaa8..17c6039bb6 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 8e3f4de3e3..45e4bf0a52 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 88435cc9b5..3492bfd6c9 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 79724eea5d..0a8ccb696c 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 dd05fb6dee..4ac359da59 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 aa0adeb8dc..a69a29107b 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 62e19a6594..c8222decce 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 4d8a3e41c8..485d1a4e42 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 ab92c0ad26..07eb1f3abb 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 04db05c09f..26cd6cfb9c 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 306359eafc..50938108bf 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 a0d15c4769..9aa8a649e6 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 8a1c75f7c5..32a176f398 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 ff3be5b3ce..07fc884a21 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 b0558bb19a..91fd5d3d5f 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> @@ -390,10 +391,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 8db87e3885..00c43f2871 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 f00a26cc46..0000000000 --- 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 7f3c82310b..740f130dc2 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 651e60dc68..2771f2fe14 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 981bd7b557..eb9935020a 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 c42614a833..719c6a6b6b 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 b92c88492d..3b0050bba4 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 b47c88623c..4a47de1f41 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 5ec9de72ed..ebb3076e63 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 00071f8934..23dfee70c9 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 0000000000..21e64d37a5 --- /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 9f45b3cedc..0000000000 --- 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 f9aeaa8069..0000000000 --- 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 6758220dfd..5b5aaff053 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 b1fbef6026..f7fb2bb54a 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 80f677695c..56f3f29f97 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 ef5af6a7aa..0000000000 --- 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 8e790a2952..0000000000 --- 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 acbc6c0afe..0000000000 --- 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 e5b42158f8..0000000000 --- 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 6616110319..0000000000 --- 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 47637b85fc..0000000000 --- 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 dfcb8597dc..0000000000 --- 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 0000000000..881cd99794 --- /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 359272fc2b..35893d9d96 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 06c0f601b4..3f8cc6fb18 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 e0f22515cd..cb0b2757aa 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 62549f5cdc..f721a705e0 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 1c1814dcf7..6cacc9ae09 100644 --- a/src/mainboard/google/butterfly/mainboard.c +++ b/src/mainboard/google/butterfly/mainboard.c @@ -203,9 +203,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 edbf371009..7282c1ef10 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 b345d5ec3e..e9b4a09859 100644 --- a/src/mainboard/google/link/romstage.c +++ b/src/mainboard/google/link/romstage.c @@ -92,8 +92,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 8a648cb250..4b34c0678c 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 6734b77fd7..35cf906e16 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 bd4ce3d3ee..695778346e 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 1fd03bda5a..adbdffb9a0 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 f8b0bf2ea9..1979f8c2f8 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 036cbe9c59..6948756729 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 8fcb5650b6..1d211025fd 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 ce064bbe8b..015ae08096 100644 --- a/src/mainboard/samsung/lumpy/romstage.c +++ b/src/mainboard/samsung/lumpy/romstage.c @@ -234,8 +234,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 a2796b8ca2..a024095769 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 a77aea7d55..cc08ac1637 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 fd3ceee188..c07c063f00 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 247a38f716..1236932626 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 0ff7f457fe..8a4472ccc4 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 d72c2c3224..481110f2fe 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 9bb1d8af61..86205abc24 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 0fd197b7ff..7a79d13b81 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 e17c54b7cd..94a7c396fb 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 3cf0726d6a..053a4873cd 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 874fae82bf..3f6e8d8298 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 53da81dfc2..0c49a800a6 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 7bbd671b5f..191821ad5b 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 7bbd671b5f..191821ad5b 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 722669bf33..f1bc4cbb8d 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/pm.h> @@ -46,58 +43,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 = { @@ -109,12 +58,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 8d373062e3..edc87905d7 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 0cf54956d3..7cc74c2838 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 7ab752fbc4..e133b48482 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 1650057fab..efe43343ca 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 ae7e4d4b48..2821677465 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 62d755e8e1..426d35b844 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 546018a35a..cb6992199d 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 9bba748a84..f3e7504c5f 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 226578bc8c..5248305a04 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, }; |