feat(qemu-sbsa): configure RMM manifest based on system RAM

The RMM manifest needs to reflect the amount of RAM available on the
system.  Since system RAM is based on user input and reflected in the
device tree, get the information from there rather than using hard coded
values.

Change-Id: I63f090c1c04d9addfcd7a349450735728fa88ed0
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c
index 3521330..0bfb126 100644
--- a/plat/qemu/common/qemu_common.c
+++ b/plat/qemu/common/qemu_common.c
@@ -16,6 +16,9 @@
 #if ENABLE_RME
 #include <services/rmm_core_manifest.h>
 #endif
+#ifdef PLAT_qemu_sbsa
+#include <sbsa_platform.h>
+#endif
 
 #include <plat/common/platform.h>
 #include "qemu_private.h"
@@ -223,13 +226,43 @@
 
 	return (size_t)RMM_SHARED_SIZE;
 }
+
+#ifdef PLAT_qemu
+static uint32_t plat_get_num_memnodes(void)
+{
+	return 1;
+}
+
+static void plat_get_memory_node(int index, struct ns_dram_bank *bank_ptr)
+{
+	(void) index;
+	bank_ptr->base = NS_DRAM0_BASE;
+	bank_ptr->size = NS_DRAM0_SIZE;
+}
+#elif PLAT_qemu_sbsa
+static uint32_t plat_get_num_memnodes(void)
+{
+	return sbsa_platform_num_memnodes();
+}
+
+static void plat_get_memory_node(int index, struct ns_dram_bank *bank_ptr)
+{
+	struct platform_memory_data data = {0, 0, 0};
+
+	if (index < sbsa_platform_num_memnodes()) {
+		data = sbsa_platform_memory_node(index);
+	}
+
+	bank_ptr->base = data.addr_base;
+	bank_ptr->size = data.addr_size;
+}
+#endif /* PLAT_qemu */
 
 int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
 {
+	int i, last;
 	uint64_t checksum;
-	uintptr_t base;
-	uint64_t size;
-	size_t num_banks = 1;
+	size_t num_banks = plat_get_num_memnodes();
 	size_t num_consoles = 1;
 	struct ns_dram_bank *bank_ptr;
 	struct console_info *console_ptr;
@@ -300,11 +333,28 @@
 	/* Calculate checksum of plat_dram structure */
 	checksum = num_banks + (uint64_t)bank_ptr;
 
-	base = NS_DRAM0_BASE;
-	size = NS_DRAM0_SIZE;
-	bank_ptr[0].base = base;
-	bank_ptr[0].size = size;
-	checksum += base + size;
+	/*
+	 * In the TF-A, NUMA nodes (if present) are stored in descending
+	 * order, i.e:
+	 *
+	 * INFO:    RAM 0: node-id: 1, address: 0x10080000000 - 0x101ffffffff
+	 * INFO:    RAM 1: node-id: 0, address: 0x10043000000 - 0x1007fffffff
+	 *
+	 * The RMM expects the memory banks to be presented in ascending order:
+	 *
+	 * INFO:    RAM 1: node-id: 0, address: 0x10043000000 - 0x1007fffffff
+	 * INFO:    RAM 0: node-id: 1, address: 0x10080000000 - 0x101ffffffff
+	 *
+	 * As such, go through the NUMA nodes one by one and fill out
+	 * @bank_ptr[] starting from the end.  When NUMA nodes are not present
+	 * there is only one memory bank and none of the above matters.
+	 */
+	last = num_banks - 1;
+	for (i = 0; i < num_banks; i++) {
+		plat_get_memory_node(i, &bank_ptr[last]);
+		checksum += bank_ptr[last].base + bank_ptr[last].size;
+		last--;
+	}
 
 	/* Checksum must be 0 */
 	manifest->plat_dram.checksum = ~checksum + 1UL;