diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/x86/Kconfig | 7 | ||||
-rw-r--r-- | src/arch/x86/cbmem.c | 44 | ||||
-rw-r--r-- | src/include/cbmem.h | 9 |
3 files changed, 33 insertions, 27 deletions
diff --git a/src/arch/x86/Kconfig b/src/arch/x86/Kconfig index 0c8b97d2f3..e18d6d05dd 100644 --- a/src/arch/x86/Kconfig +++ b/src/arch/x86/Kconfig @@ -111,8 +111,15 @@ config ROMCC bool default n +config CBMEM_TOP_BACKUP + def_bool n + help + Platform implements non-volatile storage to cache cbmem_top() + over stage transitions and optionally also over S3 suspend. + config LATE_CBMEM_INIT def_bool n + select CBMEM_TOP_BACKUP help Enable this in chipset's Kconfig if northbridge does not implement early get_top_of_ram() call for romstage. CBMEM tables will be diff --git a/src/arch/x86/cbmem.c b/src/arch/x86/cbmem.c index 578bb8a4ed..e35d43cecb 100644 --- a/src/arch/x86/cbmem.c +++ b/src/arch/x86/cbmem.c @@ -18,49 +18,47 @@ #if IS_ENABLED(CONFIG_LATE_CBMEM_INIT) -#if !defined(__PRE_RAM__) void __attribute__((weak)) backup_top_of_ram(uint64_t ramtop) { /* Do nothing. Chipset may have implementation to save ramtop in NVRAM. */ } -static void *ramtop_pointer; - -void set_top_of_ram(uint64_t ramtop) +unsigned long __attribute__((weak)) get_top_of_ram(void) { - backup_top_of_ram(ramtop); - ramtop_pointer = (void *)(uintptr_t)ramtop; + return 0; } -static inline void *saved_ramtop(void) -{ - return ramtop_pointer; -} -#else -static inline void *saved_ramtop(void) -{ - return NULL; -} -#endif /* !__PRE_RAM__ */ +#endif /* LATE_CBMEM_INIT */ -unsigned long __attribute__((weak)) get_top_of_ram(void) +#if IS_ENABLED(CONFIG_CBMEM_TOP_BACKUP) + +static void *ramtop_pointer; + +void set_top_of_ram(uint64_t ramtop) { - return 0; + backup_top_of_ram(ramtop); + if (ENV_RAMSTAGE) + ramtop_pointer = (void *)(uintptr_t)ramtop; } void *cbmem_top(void) { /* Top of cbmem is at lowest usable DRAM address below 4GiB. */ - void *ptr = saved_ramtop(); + uintptr_t ramtop; + + if (ENV_RAMSTAGE && ramtop_pointer != NULL) + return ramtop_pointer; - if (ptr != NULL) - return ptr; + ramtop = get_top_of_ram(); - return (void *)get_top_of_ram(); + if (ENV_RAMSTAGE) + ramtop_pointer = (void *)ramtop; + + return (void *)ramtop; } -#endif /* LATE_CBMEM_INIT */ +#endif /* CBMEM_TOP_BACKUP */ /* Something went wrong, our high memory area got wiped */ void cbmem_fail_resume(void) diff --git a/src/include/cbmem.h b/src/include/cbmem.h index 0fe25c1741..21ca0975f9 100644 --- a/src/include/cbmem.h +++ b/src/include/cbmem.h @@ -145,11 +145,12 @@ void cbmem_add_records_to_cbtable(struct lb_header *header); #endif /* ENV_RAMSTAGE */ -/* These are for compatibility with old boards only. Any new chipset and board - * must implement cbmem_top() for both romstage and ramstage to support - * early features like COLLECT_TIMESTAMPS and CBMEM_CONSOLE. +/* Any new chipset and board must implement cbmem_top() for both + * romstage and ramstage to support early features like COLLECT_TIMESTAMPS + * and CBMEM_CONSOLE. Sometimes it is necessary to have cbmem_top() + * value stored in nvram to enable early recovery on S3 path. */ -#if IS_ENABLED(CONFIG_ARCH_X86) && IS_ENABLED(CONFIG_LATE_CBMEM_INIT) +#if IS_ENABLED(CONFIG_ARCH_X86) /* Note that many of the current providers of get_top_of_ram() conditionally * return 0 when the sleep type is non S3. i.e. cold and warm boots would * return 0 from get_top_of_ram(). */ |