diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/x86/car.ld | 1 | ||||
-rw-r--r-- | src/include/memlayout.h | 10 | ||||
-rw-r--r-- | src/include/symbols.h | 1 | ||||
-rw-r--r-- | src/lib/Makefile.inc | 7 | ||||
-rw-r--r-- | src/lib/cbfs.c | 6 | ||||
-rw-r--r-- | src/lib/fmap.c | 119 | ||||
-rw-r--r-- | src/soc/mediatek/mt8173/include/soc/memlayout.ld | 3 | ||||
-rw-r--r-- | src/soc/mediatek/mt8183/include/soc/memlayout.ld | 3 | ||||
-rw-r--r-- | src/soc/nvidia/tegra124/include/soc/memlayout.ld | 3 | ||||
-rw-r--r-- | src/soc/nvidia/tegra210/include/soc/memlayout.ld | 3 | ||||
-rw-r--r-- | src/soc/qualcomm/ipq40xx/include/soc/memlayout.ld | 3 | ||||
-rw-r--r-- | src/soc/qualcomm/ipq806x/include/soc/memlayout.ld | 3 | ||||
-rw-r--r-- | src/soc/qualcomm/qcs405/include/soc/memlayout.ld | 3 | ||||
-rw-r--r-- | src/soc/qualcomm/sc7180/include/soc/memlayout.ld | 1 | ||||
-rw-r--r-- | src/soc/rockchip/rk3399/include/soc/memlayout.ld | 3 | ||||
-rw-r--r-- | src/soc/samsung/exynos5250/include/soc/memlayout.ld | 3 | ||||
-rw-r--r-- | src/soc/samsung/exynos5420/include/soc/memlayout.ld | 3 |
17 files changed, 125 insertions, 50 deletions
diff --git a/src/arch/x86/car.ld b/src/arch/x86/car.ld index 74fc74b58e53..972cb5234be9 100644 --- a/src/arch/x86/car.ld +++ b/src/arch/x86/car.ld @@ -58,6 +58,7 @@ #endif TIMESTAMP(., 0x200) + FMAP_CACHE(., FMAP_SIZE) _car_ehci_dbg_info = .; /* Reserve sizeof(struct ehci_dbg_info). */ diff --git a/src/include/memlayout.h b/src/include/memlayout.h index 0100e270c630..56dfb6a7850c 100644 --- a/src/include/memlayout.h +++ b/src/include/memlayout.h @@ -21,6 +21,8 @@ #include <arch/memlayout.h> #include <vb2_constants.h> +#include "fmap_config.h" + /* Macros that the architecture can override. */ #ifndef ARCH_POINTER_ALIGN_SIZE #define ARCH_POINTER_ALIGN_SIZE 8 @@ -30,7 +32,8 @@ #define ARCH_CACHELINE_ALIGN_SIZE 64 #endif -#define STR(x) #x +#define STR(x) XSTR(x) +#define XSTR(x) #x #define ALIGN_COUNTER(align) \ . = ALIGN(align); @@ -73,6 +76,11 @@ ALIAS_REGION(cbfs_cache, preram_cbfs_cache) \ ALIAS_REGION(cbfs_cache, postram_cbfs_cache) +#define FMAP_CACHE(addr, sz) \ + REGION(fmap_cache, addr, sz, 4) \ + _ = ASSERT(sz == 0 || sz >= FMAP_SIZE, \ + STR(FMAP does not fit in FMAP_CACHE! (sz < FMAP_SIZE))); + #if ENV_ROMSTAGE_OR_BEFORE #define PRERAM_CBFS_CACHE(addr, size) \ REGION(preram_cbfs_cache, addr, size, 4) \ diff --git a/src/include/symbols.h b/src/include/symbols.h index 56df8d573423..eec47010e456 100644 --- a/src/include/symbols.h +++ b/src/include/symbols.h @@ -34,6 +34,7 @@ DECLARE_REGION(stack) DECLARE_REGION(preram_cbfs_cache) DECLARE_REGION(postram_cbfs_cache) DECLARE_REGION(cbfs_cache) +DECLARE_REGION(fmap_cache) DECLARE_REGION(payload) /* "program" always refers to the current execution unit. */ diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc index 3b7d57c76ad3..dc0c46d46022 100644 --- a/src/lib/Makefile.inc +++ b/src/lib/Makefile.inc @@ -208,13 +208,6 @@ $(call src-to-obj,smm,$(dir)/version.c) : $(obj)/build.h $(call src-to-obj,verstage,$(dir)/version.c) : $(obj)/build.h $(call src-to-obj,postcar,$(dir)/version.c) : $(obj)/build.h -$(call src-to-obj,bootblock,$(dir)/cbfs.c) : $(obj)/fmap_config.h -$(call src-to-obj,romstage,$(dir)/cbfs.c) : $(obj)/fmap_config.h -$(call src-to-obj,ramstage,$(dir)/cbfs.c) : $(obj)/fmap_config.h -$(call src-to-obj,smm,$(dir)/cbfs.c) : $(obj)/fmap_config.h -$(call src-to-obj,verstage,$(dir)/cbfs.c) : $(obj)/fmap_config.h -$(call src-to-obj,postcar,$(dir)/cbfs.c) : $(obj)/fmap_config.h - $(call src-to-obj,bootblock,$(dir)/fmap.c) : $(obj)/fmap_config.h $(call src-to-obj,romstage,$(dir)/fmap.c) : $(obj)/fmap_config.h $(call src-to-obj,ramstage,$(dir)/fmap.c) : $(obj)/fmap_config.h diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c index 1601f201fe46..27a1592e2b34 100644 --- a/src/lib/cbfs.c +++ b/src/lib/cbfs.c @@ -26,7 +26,6 @@ #include <symbols.h> #include <timestamp.h> #include <fmap.h> -#include "fmap_config.h" #include <security/vboot/vboot_crtm.h> #define ERROR(x...) printk(BIOS_ERR, "CBFS: " x) @@ -310,7 +309,10 @@ int cbfs_master_header_props(struct cbfs_props *props) if (bdev == NULL) return -1; - size_t fmap_top = ___FMAP__COREBOOT_BASE + ___FMAP__COREBOOT_SIZE; + struct region fmap_region; + if (fmap_locate_area("COREBOOT", &fmap_region)) + return -1; + size_t fmap_top = region_end(&fmap_region); /* Find location of header using signed 32-bit offset from * end of CBFS region. */ diff --git a/src/lib/fmap.c b/src/lib/fmap.c index f3ff0717667b..4b4179c7698d 100644 --- a/src/lib/fmap.c +++ b/src/lib/fmap.c @@ -15,12 +15,13 @@ #include <arch/early_variables.h> #include <boot_device.h> +#include <cbmem.h> #include <console/console.h> #include <fmap.h> #include <commonlib/fmap_serialized.h> #include <stddef.h> #include <string.h> -#include <cbmem.h> +#include <symbols.h> #include "fmap_config.h" @@ -31,26 +32,94 @@ static int fmap_print_once CAR_GLOBAL; static struct mem_region_device fmap_cache CAR_GLOBAL; +#define print_once(...) do { \ + if (!car_get_var(fmap_print_once)) \ + printk(__VA_ARGS__); \ + } while (0) + +DECLARE_OPTIONAL_REGION(fmap_cache); + uint64_t get_fmap_flash_offset(void) { return FMAP_OFFSET; } +static int check_signature(const struct fmap *fmap) +{ + return memcmp(fmap->signature, FMAP_SIGNATURE, sizeof(fmap->signature)); +} + +static void report(const struct fmap *fmap) +{ + print_once(BIOS_DEBUG, "FMAP: Found \"%s\" version %d.%d at %#x.\n", + fmap->name, fmap->ver_major, fmap->ver_minor, FMAP_OFFSET); + print_once(BIOS_DEBUG, "FMAP: base = %#llx size = %#x #areas = %d\n", + (long long)fmap->base, fmap->size, fmap->nareas); + car_set_var(fmap_print_once, 1); +} + +static void setup_preram_cache(struct mem_region_device *cache_mrdev) +{ + if (!ENV_ROMSTAGE_OR_BEFORE) { + /* We get here if ramstage makes an FMAP access before calling + cbmem_initialize(). We should avoid letting it come to that, + so print a warning. */ + print_once(BIOS_WARNING, + "WARNING: Post-RAM FMAP access too early for cache!\n"); + return; + } + + if (REGION_SIZE(fmap_cache) == 0) { + /* If you see this you really want to add an FMAP_CACHE to your + memlayout, unless you absolutely can't affort the 2K. */ + print_once(BIOS_NOTICE, + "NOTE: Running without FMAP_CACHE, should add it!\n"); + return; + } + + struct fmap *fmap = (struct fmap *)_fmap_cache; + if (!ENV_BOOTBLOCK) { + /* NOTE: This assumes that for all platforms running this code, + the bootblock is the first stage and the bootblock will make + at least one FMAP access (usually from finding CBFS). */ + if (!check_signature(fmap)) + goto register_cache; + + printk(BIOS_ERR, "ERROR: FMAP cache corrupted?!\n"); + } + + /* In case we fail below, make sure the cache is invalid. */ + memset(fmap->signature, 0, sizeof(fmap->signature)); + + boot_device_init(); + const struct region_device *boot_rdev = boot_device_ro(); + if (!boot_rdev) + return; + + /* memlayout statically guarantees that the FMAP_CACHE is big enough. */ + if (rdev_readat(boot_rdev, fmap, FMAP_OFFSET, FMAP_SIZE) != FMAP_SIZE) + return; + if (check_signature(fmap)) + return; + report(fmap); + +register_cache: + mem_region_device_ro_init(cache_mrdev, fmap, FMAP_SIZE); +} + static int find_fmap_directory(struct region_device *fmrd) { const struct region_device *boot; struct fmap *fmap; - size_t fmap_size; + struct mem_region_device *cache; size_t offset = FMAP_OFFSET; - if (cbmem_possibly_online() && !ENV_SMM) { - /* Try FMAP cache first */ - const struct mem_region_device *cache; - - cache = car_get_var_ptr(&fmap_cache); - if (region_device_sz(&cache->rdev)) - return rdev_chain_full(fmrd, &cache->rdev); - } + /* Try FMAP cache first */ + cache = car_get_var_ptr(&fmap_cache); + if (!region_device_sz(&cache->rdev)) + setup_preram_cache(cache); + if (region_device_sz(&cache->rdev)) + return rdev_chain_full(fmrd, &cache->rdev); boot_device_init(); boot = boot_device_ro(); @@ -58,32 +127,22 @@ static int find_fmap_directory(struct region_device *fmrd) if (boot == NULL) return -1; - fmap_size = sizeof(struct fmap); - - fmap = rdev_mmap(boot, offset, fmap_size); + fmap = rdev_mmap(boot, offset, sizeof(struct fmap)); if (fmap == NULL) return -1; - if (memcmp(fmap->signature, FMAP_SIGNATURE, sizeof(fmap->signature))) { + if (check_signature(fmap)) { printk(BIOS_DEBUG, "No FMAP found at %zx offset.\n", offset); rdev_munmap(boot, fmap); return -1; } - if (!car_get_var(fmap_print_once)) { - printk(BIOS_DEBUG, "FMAP: Found \"%s\" version %d.%d at %zx.\n", - fmap->name, fmap->ver_major, fmap->ver_minor, offset); - printk(BIOS_DEBUG, "FMAP: base = %llx size = %x #areas = %d\n", - (long long)fmap->base, fmap->size, fmap->nareas); - car_set_var(fmap_print_once, 1); - } - - fmap_size += fmap->nareas * sizeof(struct fmap_area); + report(fmap); rdev_munmap(boot, fmap); - return rdev_chain(fmrd, boot, offset, fmap_size); + return rdev_chain(fmrd, boot, offset, FMAP_SIZE); } int fmap_locate_area_as_rdev(const char *name, struct region_device *area) @@ -212,7 +271,7 @@ ssize_t fmap_overwrite_area(const char *name, const void *buffer, size_t size) return rdev_writeat(&rdev, buffer, 0, size); } -static void fmap_register_cache(int unused) +static void fmap_register_cbmem_cache(int unused) { const struct cbmem_entry *e; struct mem_region_device *mdev; @@ -232,7 +291,7 @@ static void fmap_register_cache(int unused) * The main reason to copy the FMAP into CBMEM is to make it available to the * OS on every architecture. As side effect use the CBMEM copy as cache. */ -static void fmap_setup_cache(int unused) +static void fmap_setup_cbmem_cache(int unused) { struct region_device fmrd; @@ -255,9 +314,9 @@ static void fmap_setup_cache(int unused) } /* Finally advertise the cache for the current stage */ - fmap_register_cache(unused); + fmap_register_cbmem_cache(unused); } -ROMSTAGE_CBMEM_INIT_HOOK(fmap_setup_cache) -RAMSTAGE_CBMEM_INIT_HOOK(fmap_register_cache) -POSTCAR_CBMEM_INIT_HOOK(fmap_register_cache) +ROMSTAGE_CBMEM_INIT_HOOK(fmap_setup_cbmem_cache) +RAMSTAGE_CBMEM_INIT_HOOK(fmap_register_cbmem_cache) +POSTCAR_CBMEM_INIT_HOOK(fmap_register_cbmem_cache) diff --git a/src/soc/mediatek/mt8173/include/soc/memlayout.ld b/src/soc/mediatek/mt8173/include/soc/memlayout.ld index adda86e11b2c..2358c3940cda 100644 --- a/src/soc/mediatek/mt8173/include/soc/memlayout.ld +++ b/src/soc/mediatek/mt8173/include/soc/memlayout.ld @@ -40,7 +40,8 @@ SECTIONS SRAM_START(0x00100000) VBOOT2_WORK(0x00100000, 12K) VBOOT2_TPM_LOG(0x00103000, 2K) - PRERAM_CBMEM_CONSOLE(0x00103800, 14K) + FMAP_CACHE(0x00103800, 2K) + PRERAM_CBMEM_CONSOLE(0x00104000, 12K) WATCHDOG_TOMBSTONE(0x00107000, 4) PRERAM_CBFS_CACHE(0x00107004, 16K - 4) TIMESTAMP(0x0010B000, 4K) diff --git a/src/soc/mediatek/mt8183/include/soc/memlayout.ld b/src/soc/mediatek/mt8183/include/soc/memlayout.ld index 82e404f790c9..a8f464a3d80c 100644 --- a/src/soc/mediatek/mt8183/include/soc/memlayout.ld +++ b/src/soc/mediatek/mt8183/include/soc/memlayout.ld @@ -34,7 +34,8 @@ SECTIONS VBOOT2_TPM_LOG(0x00103000, 2K) PRERAM_CBMEM_CONSOLE(0x00103800, 14K) WATCHDOG_TOMBSTONE(0x00107000, 4) - PRERAM_CBFS_CACHE(0x00107004, 48K - 4) + PRERAM_CBFS_CACHE(0x00107004, 46K - 4) + FMAP_CACHE(0x00112800, 2K) TIMESTAMP(0x00113000, 4K) STACK(0x00114000, 16K) TTB(0x00118000, 28K) diff --git a/src/soc/nvidia/tegra124/include/soc/memlayout.ld b/src/soc/nvidia/tegra124/include/soc/memlayout.ld index 7e2f9ec2af7b..7e2cc7ad5873 100644 --- a/src/soc/nvidia/tegra124/include/soc/memlayout.ld +++ b/src/soc/nvidia/tegra124/include/soc/memlayout.ld @@ -28,7 +28,8 @@ SECTIONS SRAM_START(0x40000000) TTB(0x40000000, 16K + 32) PRERAM_CBMEM_CONSOLE(0x40004020, 6K - 32) - PRERAM_CBFS_CACHE(0x40005800, 16K) + FMAP_CACHE(0x40005800, 2K) + PRERAM_CBFS_CACHE(0x40006000, 14K) VBOOT2_WORK(0x40009800, 12K) VBOOT2_TPM_LOG(0x4000D800, 2K) STACK(0x4000E000, 8K) diff --git a/src/soc/nvidia/tegra210/include/soc/memlayout.ld b/src/soc/nvidia/tegra210/include/soc/memlayout.ld index 1134da6111cb..b7268d114b1f 100644 --- a/src/soc/nvidia/tegra210/include/soc/memlayout.ld +++ b/src/soc/nvidia/tegra210/include/soc/memlayout.ld @@ -29,7 +29,8 @@ SECTIONS { SRAM_START(0x40000000) PRERAM_CBMEM_CONSOLE(0x40000000, 2K) - PRERAM_CBFS_CACHE(0x40000800, 30K) + FMAP_CACHE(0x40000800, 2K) + PRERAM_CBFS_CACHE(0x40001000, 28K) VBOOT2_WORK(0x40008000, 12K) VBOOT2_TPM_LOG(0x4000B000, 2K) #if ENV_ARM64 diff --git a/src/soc/qualcomm/ipq40xx/include/soc/memlayout.ld b/src/soc/qualcomm/ipq40xx/include/soc/memlayout.ld index f1a7bc59d2f8..6ff101827240 100644 --- a/src/soc/qualcomm/ipq40xx/include/soc/memlayout.ld +++ b/src/soc/qualcomm/ipq40xx/include/soc/memlayout.ld @@ -34,7 +34,8 @@ SECTIONS /* This includes bootblock image, can be reused after bootblock starts */ /* UBER_SBL(0x0A0C0000, 48K) */ - PRERAM_CBFS_CACHE(0x0A0C0000, 93K) + PRERAM_CBFS_CACHE(0x0A0C0000, 92K) + FMAP_CACHE(0x0A0EF800, 2K) TTB(0x0A0F0000, 16K) TTB_SUBTABLES(0x0A0F4000, 4K) diff --git a/src/soc/qualcomm/ipq806x/include/soc/memlayout.ld b/src/soc/qualcomm/ipq806x/include/soc/memlayout.ld index 25db17587c73..595d939d0bf4 100644 --- a/src/soc/qualcomm/ipq806x/include/soc/memlayout.ld +++ b/src/soc/qualcomm/ipq806x/include/soc/memlayout.ld @@ -38,7 +38,8 @@ SECTIONS QCA_SHARED_RAM(2A03F000, 4K) */ STACK(0x2A040000, 16K) - PRERAM_CBFS_CACHE(0x2A044000, 93K) + PRERAM_CBFS_CACHE(0x2A044000, 91K) + FMAP_CACHE(0x2A05B000, 2K) TTB_SUBTABLES(0x2A05B800, 2K) TTB(0x2A05C000, 16K) SRAM_END(0x2A060000) diff --git a/src/soc/qualcomm/qcs405/include/soc/memlayout.ld b/src/soc/qualcomm/qcs405/include/soc/memlayout.ld index 68642d67a222..dd013b5e8f5d 100644 --- a/src/soc/qualcomm/qcs405/include/soc/memlayout.ld +++ b/src/soc/qualcomm/qcs405/include/soc/memlayout.ld @@ -39,7 +39,8 @@ SECTIONS TIMESTAMP(0x8C4F000, 1K) PRERAM_CBMEM_CONSOLE(0x8C4F400, 32K) PRERAM_CBFS_CACHE(0x8C57400, 70K) - REGION(bsram_unused, 0x8C68C00, 0xA2400, 0x100) + FMAP_CACHE(0x8C68C00, 2K) + REGION(bsram_unused, 0x8C69400, 0xA1C00, 0x100) BSRAM_END(0x8D80000) DRAM_START(0x80000000) diff --git a/src/soc/qualcomm/sc7180/include/soc/memlayout.ld b/src/soc/qualcomm/sc7180/include/soc/memlayout.ld index b2ee3b20a06d..3f43419d1477 100644 --- a/src/soc/qualcomm/sc7180/include/soc/memlayout.ld +++ b/src/soc/qualcomm/sc7180/include/soc/memlayout.ld @@ -43,6 +43,7 @@ SECTIONS REGION(ddr_training, 0x14850000, 8K, 4K) REGION(qclib_serial_log, 0x14852000, 4K, 4K) REGION(ddr_information, 0x14853000, 1K, 1K) + FMAP_CACHE(0x14853400, 2K) REGION(dcb, 0x14870000, 16K, 4K) REGION(pmic, 0x14874000, 44K, 4K) REGION(limits_cfg, 0x1487F000, 4K, 4K) diff --git a/src/soc/rockchip/rk3399/include/soc/memlayout.ld b/src/soc/rockchip/rk3399/include/soc/memlayout.ld index 293057a091bd..4e46e2d76444 100644 --- a/src/soc/rockchip/rk3399/include/soc/memlayout.ld +++ b/src/soc/rockchip/rk3399/include/soc/memlayout.ld @@ -33,7 +33,8 @@ SECTIONS #if ENV_RAMSTAGE REGION(bl31_sram, 0xFF8C0000, 64K, 1) #else - PRERAM_CBFS_CACHE(0xFF8C0000, 7K) + PRERAM_CBFS_CACHE(0xFF8C0000, 5K) + FMAP_CACHE(0xFF8C1400, 2K) TIMESTAMP(0xFF8C1C00, 1K) /* 0xFF8C2004 is the entry point address the masked ROM will jump to. */ OVERLAP_DECOMPRESSOR_VERSTAGE_ROMSTAGE(0xFF8C2004, 88K - 4) diff --git a/src/soc/samsung/exynos5250/include/soc/memlayout.ld b/src/soc/samsung/exynos5250/include/soc/memlayout.ld index 0bd319e45db0..7e052f0f3172 100644 --- a/src/soc/samsung/exynos5250/include/soc/memlayout.ld +++ b/src/soc/samsung/exynos5250/include/soc/memlayout.ld @@ -31,7 +31,8 @@ SECTIONS ROMSTAGE(0x2030000, 128K) /* 32K hole */ TTB(0x2058000, 16K) - PRERAM_CBFS_CACHE(0x205C000, 78K) + PRERAM_CBFS_CACHE(0x205C000, 76K) + FMAP_CACHE(0x206F000, 2K) VBOOT2_TPM_LOG(0x206F800, 2K) VBOOT2_WORK(0x2070000, 12K) STACK(0x2074000, 16K) diff --git a/src/soc/samsung/exynos5420/include/soc/memlayout.ld b/src/soc/samsung/exynos5420/include/soc/memlayout.ld index bc5d0669da94..ff781d2228a2 100644 --- a/src/soc/samsung/exynos5420/include/soc/memlayout.ld +++ b/src/soc/samsung/exynos5420/include/soc/memlayout.ld @@ -32,7 +32,8 @@ SECTIONS ROMSTAGE(0x2030000, 128K) /* 32K hole */ TTB(0x2058000, 16K) - PRERAM_CBFS_CACHE(0x205C000, 76K) + PRERAM_CBFS_CACHE(0x205C000, 74K) + FMAP_CACHE(0x206E800, 2K) STACK(0x206F000, 16K) /* 1K hole for weird kernel-shared CPU/SMP state structure that doesn't * seem to be implemented right now? */ |