Support loading initrd from a fixed address under Android boot flow

This is useful when the initrd is not compiled into the Hafnium image,
but rather flashed to a different partition which gets loaded by the
firmware to a well-known address.

Change-Id: I49f657100c917cece5dbe6d935ae8b2a7bb886bc
diff --git a/project/reference b/project/reference
index e2a525d..c702a03 160000
--- a/project/reference
+++ b/project/reference
@@ -1 +1 @@
-Subproject commit e2a525d24927401f8b2d190f234af6ea24c85664
+Subproject commit c702a035abf38c1d4916dd015071bd942d3429f5
diff --git a/src/boot_flow/BUILD.gn b/src/boot_flow/BUILD.gn
index 9de339d..c8d768d 100644
--- a/src/boot_flow/BUILD.gn
+++ b/src/boot_flow/BUILD.gn
@@ -14,6 +14,11 @@
 
 import("//build/toolchain/platform.gni")
 
+declare_args() {
+  boot_flow_android_initrd_addr = 0
+  boot_flow_android_initrd_size = 0
+}
+
 source_set("common") {
   sources = [
     "common.c",
@@ -28,6 +33,10 @@
     ":common",
     "//src/arch/${plat_arch}/boot_flow:android",
   ]
+  defines = [
+    "INITRD_ADDR=${boot_flow_android_initrd_addr}",
+    "INITRD_SIZE=${boot_flow_android_initrd_size}",
+  ]
 }
 
 source_set("linux") {
diff --git a/src/boot_flow/android.c b/src/boot_flow/android.c
index 0221674..88939bc 100644
--- a/src/boot_flow/android.c
+++ b/src/boot_flow/android.c
@@ -35,15 +35,27 @@
 }
 
 /**
- * Initrd was compiled into Hafnium. Return range of the '.plat.initrd' section.
+ * Return the memory range of the RAM disk. This can be either:
+ * (a) the range of the '.plat.initrd' section, if it was compiled into the
+ *     Hafnium image (INITRD_ADDR and INITRD_SIZE are zero), or
+ * (b) a fixed address range known at build time (INITRD_ADDR and INITRD_SIZE
+ *     are not zero).
  */
 bool plat_boot_flow_get_initrd_range(const struct fdt_node *fdt_root,
 				     paddr_t *begin, paddr_t *end)
 {
 	(void)fdt_root;
 
-	*begin = layout_initrd_begin();
-	*end = layout_initrd_end();
+	uintpaddr_t initrd_addr = (uintpaddr_t)(INITRD_ADDR);
+	size_t initrd_size = (size_t)(INITRD_SIZE);
+
+	if (initrd_addr == 0 || initrd_size == 0) {
+		*begin = layout_initrd_begin();
+		*end = layout_initrd_end();
+	} else {
+		*begin = pa_init(initrd_addr);
+		*end = pa_add(*begin, initrd_size);
+	}
 	return true;
 }