aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/x86/Kconfig7
-rw-r--r--src/arch/x86/cbmem.c44
-rw-r--r--src/include/cbmem.h9
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(). */