summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86/car.ld1
-rw-r--r--src/include/memlayout.h10
-rw-r--r--src/include/symbols.h1
-rw-r--r--src/lib/Makefile.inc7
-rw-r--r--src/lib/cbfs.c6
-rw-r--r--src/lib/fmap.c119
-rw-r--r--src/soc/mediatek/mt8173/include/soc/memlayout.ld3
-rw-r--r--src/soc/mediatek/mt8183/include/soc/memlayout.ld3
-rw-r--r--src/soc/nvidia/tegra124/include/soc/memlayout.ld3
-rw-r--r--src/soc/nvidia/tegra210/include/soc/memlayout.ld3
-rw-r--r--src/soc/qualcomm/ipq40xx/include/soc/memlayout.ld3
-rw-r--r--src/soc/qualcomm/ipq806x/include/soc/memlayout.ld3
-rw-r--r--src/soc/qualcomm/qcs405/include/soc/memlayout.ld3
-rw-r--r--src/soc/qualcomm/sc7180/include/soc/memlayout.ld1
-rw-r--r--src/soc/rockchip/rk3399/include/soc/memlayout.ld3
-rw-r--r--src/soc/samsung/exynos5250/include/soc/memlayout.ld3
-rw-r--r--src/soc/samsung/exynos5420/include/soc/memlayout.ld3
17 files changed, 125 insertions, 50 deletions
diff --git a/src/arch/x86/car.ld b/src/arch/x86/car.ld
index 74fc74b58e..972cb5234b 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 0100e270c6..56dfb6a785 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 56df8d5734..eec47010e4 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 3b7d57c76a..dc0c46d460 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 1601f201fe..27a1592e2b 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 f3ff071766..4b4179c769 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 adda86e11b..2358c3940c 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 82e404f790..a8f464a3d8 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 7e2f9ec2af..7e2cc7ad58 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 1134da6111..b7268d114b 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 f1a7bc59d2..6ff1018272 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 25db17587c..595d939d0b 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 68642d67a2..dd013b5e8f 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 b2ee3b20a0..3f43419d14 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 293057a091..4e46e2d764 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 0bd319e45d..7e052f0f31 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 bc5d0669da..ff781d2228 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? */