CBMEM: Support DYNAMIC_CBMEM with LATE_CBMEM_INIT

We can now create CBMEM with dynamic allocation even if CBMEM
location is resolved late in ramstage.

Change-Id: I8529ccbcd4a0e567ebe0a46232ac5d16476e81a8
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: http://review.coreboot.org/7861
Reviewed-by: Aaron Durbin <adurbin@google.com>
Tested-by: build bot (Jenkins)
diff --git a/src/lib/cbmem_console.c b/src/lib/cbmem_console.c
index 6783b30..0c2722c 100644
--- a/src/lib/cbmem_console.c
+++ b/src/lib/cbmem_console.c
@@ -58,7 +58,7 @@
  * during the ROM stage, once CBMEM becomes available at RAM stage.
  */
 
-#if CONFIG_DYNAMIC_CBMEM
+#if IS_ENABLED(CONFIG_EARLY_CBMEM_INIT)
 #define STATIC_CONSOLE_SIZE 1024
 #else
 #define STATIC_CONSOLE_SIZE CONFIG_CONSOLE_CBMEM_BUFFER_SIZE
diff --git a/src/lib/dynamic_cbmem.c b/src/lib/dynamic_cbmem.c
index 1b46745..6ec56c7 100644
--- a/src/lib/dynamic_cbmem.c
+++ b/src/lib/dynamic_cbmem.c
@@ -24,10 +24,9 @@
 #include <string.h>
 #include <stdlib.h>
 #include <arch/early_variables.h>
-#if CONFIG_HAVE_ACPI_RESUME && !defined(__PRE_RAM__)
+#if IS_ENABLED(CONFIG_ARCH_X86) && !IS_ENABLED(CONFIG_EARLY_CBMEM_INIT)
 #include <arch/acpi.h>
 #endif
-
 #ifndef UINT_MAX
 #define UINT_MAX 4294967295U
 #endif
@@ -69,11 +68,18 @@
 } __attribute__((packed));
 
 
+#if !defined(__PRE_RAM__)
+static void *cached_cbmem_top;
+
+void cbmem_set_top(void * ramtop)
+{
+	cached_cbmem_top = ramtop;
+}
+#endif
+
 static inline void *cbmem_top_cached(void)
 {
 #if !defined(__PRE_RAM__)
-	static void *cached_cbmem_top;
-
 	if (cached_cbmem_top == NULL)
 		cached_cbmem_top = cbmem_top();
 
@@ -100,6 +106,9 @@
 	struct cbmem_root_pointer *pointer;
 
 	pointer_addr = get_top_aligned();
+	if (pointer_addr == 0)
+		return NULL;
+
 	pointer_addr -= sizeof(struct cbmem_root_pointer);
 
 	pointer = (void *)pointer_addr;
@@ -146,6 +155,9 @@
 	 * DYN_CBMEM_ALIGN_SIZE. The pointer falls just below the
 	 * address returned by get_top_aligned(). */
 	pointer_addr = get_top_aligned();
+	if (pointer_addr == 0)
+		return;
+
 	root_addr = pointer_addr - ROOT_MIN_SIZE;
 	root_addr &= ~(DYN_CBMEM_ALIGN_SIZE - 1);
 	pointer_addr -= sizeof(struct cbmem_root_pointer);
@@ -413,6 +425,8 @@
 
 
 #if !defined(__PRE_RAM__)
+
+#if IS_ENABLED(CONFIG_EARLY_CBMEM_INIT)
 /* selected cbmem can be initialized early in ramstage. Additionally, that
  * means cbmem console can be reinitialized early as well. The post_device
  * function is empty since cbmem was initialized early in ramstage. */
@@ -426,6 +440,22 @@
 	                      init_cbmem_pre_device, NULL),
 };
 
+#else
+
+static void init_cbmem_post_device(void *unused)
+{
+	if (acpi_is_wakeup())
+		cbmem_initialize();
+	else
+		cbmem_initialize_empty();
+}
+
+BOOT_STATE_INIT_ENTRIES(cbmem_bscb) = {
+	BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_ENTRY,
+	                      init_cbmem_post_device, NULL),
+};
+#endif
+
 void cbmem_add_bootmem(void)
 {
 	uintptr_t base;