lib/cbmem: use globals for non CAR global migration platforms
For CAR platforms which don't migrate globals real globals can
be directly used. This alleviates the need to peform partial
recovery on every cbmem access which in turn acts like all non-CAR
platforms or any stages which execute entirely out of RAM.
Change-Id: I31c08dd6473324424d5d42fe6b56d42fe635929e
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: https://review.coreboot.org/20859
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
diff --git a/src/lib/imd_cbmem.c b/src/lib/imd_cbmem.c
index 4fb78ce..ba00c2e 100644
--- a/src/lib/imd_cbmem.c
+++ b/src/lib/imd_cbmem.c
@@ -24,24 +24,30 @@
#include <arch/early_variables.h>
/*
- * We need special handling on x86 before ramstage because we cannot use global
- * variables (we're executing in-place from flash so we don't have a writable
- * data segment, and we cannot use CAR_GLOBAL here since that mechanism itself
- * is dependent on CBMEM). Therefore, we have to always try to partially recover
- * CBMEM from cbmem_top() whenever we try to access it. In other environments
- * we're not so constrained and just keep the backing imd struct in a global.
- * This also means that we can easily tell whether CBMEM has explicitly been
- * initialized or recovered yet on those platforms, and don't need to put the
- * burden on board or chipset code to tell us by returning NULL from cbmem_top()
- * before that point.
+ * We need special handling on x86 where CAR global migration is employed. One
+ * cannot use true globals in that circumstance because CAR is where the globals
+ * are backed -- creating a circular dependency. For non CAR platforms globals
+ * are free to be used as well as any stages that are purely executing out of
+ * RAM. For CAR platforms that don't migrate globals the as-linked globals can
+ * be used, but they need special decoration using CAR_GLOBAL. That ensures
+ * proper object placement in conjunction with the linker.
+ *
+ * For the CAR global migration platforms we have to always try to partially
+ * recover CBMEM from cbmem_top() whenever we try to access it. In other
+ * environments we're not so constrained and just keep the backing imd struct
+ * in a global. This also means that we can easily tell whether CBMEM has
+ * explicitly been initialized or recovered yet on those platforms, and don't
+ * need to put the burden on board or chipset code to tell us by returning
+ * NULL from cbmem_top() before that point.
*/
#define CAN_USE_GLOBALS \
- (!IS_ENABLED(CONFIG_ARCH_X86) || ENV_RAMSTAGE || ENV_POSTCAR)
+ (!IS_ENABLED(CONFIG_ARCH_X86) || ENV_RAMSTAGE || ENV_POSTCAR || \
+ IS_ENABLED(CONFIG_NO_CAR_GLOBAL_MIGRATION))
static inline struct imd *cbmem_get_imd(void)
{
if (CAN_USE_GLOBALS) {
- static struct imd imd_cbmem;
+ static struct imd imd_cbmem CAR_GLOBAL;
return &imd_cbmem;
}
return NULL;