diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/imd_cbmem.c | 24 |
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); } |