aboutsummaryrefslogtreecommitdiff
path: root/src/lib/imd_cbmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/imd_cbmem.c')
-rw-r--r--src/lib/imd_cbmem.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/src/lib/imd_cbmem.c b/src/lib/imd_cbmem.c
index 3e3e2b0637..d72f0b034a 100644
--- a/src/lib/imd_cbmem.c
+++ b/src/lib/imd_cbmem.c
@@ -26,10 +26,23 @@
#include <arch/acpi.h>
#endif
+/*
+ * 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.
+ */
+#define CAN_USE_GLOBALS (!IS_ENABLED(CONFIG_ARCH_X86) || ENV_RAMSTAGE)
+
static inline struct imd *cbmem_get_imd(void)
{
- /* Only supply a backing store for imd in ramstage. */
- if (ENV_RAMSTAGE) {
+ if (CAN_USE_GLOBALS) {
static struct imd imd_cbmem;
return &imd_cbmem;
}
@@ -77,11 +90,10 @@ static struct imd *imd_init_backing_with_recover(struct imd *backing)
struct imd *imd;
imd = imd_init_backing(backing);
- if (!ENV_RAMSTAGE) {
+ if (!CAN_USE_GLOBALS) {
+ /* Always partially recover if we can't keep track of whether
+ * we have already initialized CBMEM in this stage. */
imd_handle_init(imd, cbmem_top());
-
- /* Need to partially recover all the time outside of ramstage
- * because there's object storage outside of the stack. */
imd_handle_init_partial_recovery(imd);
}