test(realm): allocate memory for multiple planes

- Update realm create helpers to allocate memory
  and copy multiple plane images.
- Also allocate memory for multiple Aux RTTs.
- Increase realm heap by 2 MB.

Signed-off-by: Shruti Gupta <shruti.gupta@arm.com>
Change-Id: Ic71af8d0b156ad60d8cb8c5bafe6f9b7df8280c7
diff --git a/include/runtime_services/host_realm_managment/host_realm_mem_layout.h b/include/runtime_services/host_realm_managment/host_realm_mem_layout.h
index 7458146..1bef986 100644
--- a/include/runtime_services/host_realm_managment/host_realm_mem_layout.h
+++ b/include/runtime_services/host_realm_managment/host_realm_mem_layout.h
@@ -41,8 +41,8 @@
 #ifdef ENABLE_REALM_PAYLOAD_TESTS
  /* 1MB for shared buffer between Realm and Host */
  #define NS_REALM_SHARED_MEM_SIZE	U(0x100000)
- /* 8MB of memory used as a pool for realm's objects creation */
- #define PAGE_POOL_MAX_SIZE		U(0x800000)
+ /* 10MB of memory used as a pool for realm's objects creation */
+ #define PAGE_POOL_MAX_SIZE		U(0xA00000)
 #else
  #define NS_REALM_SHARED_MEM_SIZE       U(0x0)
  #define PAGE_POOL_MAX_SIZE             U(0x0)
diff --git a/include/runtime_services/host_realm_managment/host_realm_rmi.h b/include/runtime_services/host_realm_managment/host_realm_rmi.h
index 1c0a621..0534ca2 100644
--- a/include/runtime_services/host_realm_managment/host_realm_rmi.h
+++ b/include/runtime_services/host_realm_managment/host_realm_rmi.h
@@ -1011,6 +1011,8 @@
 	unsigned short   vmid;
 	enum realm_state state;
 	long start_level;
+	u_register_t     aux_rtt_addr[MAX_AUX_PLANE_COUNT];
+	unsigned short   aux_vmid[MAX_AUX_PLANE_COUNT];
 };
 
 /* RMI/SMC */
diff --git a/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c b/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c
index a810617..1255fc6 100644
--- a/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c
+++ b/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c
@@ -392,7 +392,7 @@
 	u_register_t phys = target_pa;
 	u_register_t map_addr = target_pa;
 
-	if (!IS_ALIGNED(map_addr, map_size)) {
+	if (!IS_ALIGNED(map_addr, PAGE_SIZE)) {
 		return REALM_ERROR;
 	}
 
@@ -704,7 +704,7 @@
 {
 	struct rmi_realm_params *params;
 	u_register_t ret;
-	unsigned int count;
+	unsigned int count, rtt_page_count = 0U;
 
 	realm->par_size = REALM_MAX_LOAD_IMG_SIZE;
 
@@ -724,11 +724,16 @@
 		}
 	}
 
+	assert(realm->num_aux_planes <= MAX_AUX_PLANE_COUNT);
+
 	/*
-	 * Allocate memory for PAR - Realm image. Granule delegation
+	 * Allocate memory for PAR - Realm image for each Plane.
+	 * Granule delegation
 	 * of PAR will be performed during rtt creation.
 	 */
-	realm->par_base = (u_register_t)page_alloc(realm->par_size);
+	realm->par_base = (u_register_t)page_alloc((realm->par_size) *
+			(realm->num_aux_planes + 1U));
+
 	if (realm->par_base == HEAP_NULL_PTR) {
 		ERROR("page_alloc failed, base=0x%lx, size=0x%lx\n",
 			  realm->par_base, realm->par_size);
@@ -737,6 +742,15 @@
 
 	INFO("Realm start adr=0x%lx\n", realm->par_base);
 
+	/* Allocate memory for params */
+	params = (struct rmi_realm_params *)page_alloc(PAGE_SIZE);
+	if (params == NULL) {
+		ERROR("Failed to allocate memory for params\n");
+		goto pool_reset;
+	}
+
+	memset(params, 0, PAGE_SIZE);
+
 	/* Allocate and delegate RD */
 	realm->rd = (u_register_t)page_alloc(PAGE_SIZE);
 	if (realm->rd == HEAP_NULL_PTR) {
@@ -752,28 +766,41 @@
 	}
 
 	/* Allocate and delegate RTT */
-	realm->rtt_addr = (u_register_t)page_alloc(PAGE_SIZE);
+	if (realm->rtt_tree_single) {
+		rtt_page_count = 1U;
+	} else {
+		/* Primary + AUX RTT Tree */
+		rtt_page_count = (realm->num_aux_planes + 1U);
+	}
+
+	realm->rtt_addr = (u_register_t)page_alloc(rtt_page_count * PAGE_SIZE);
+
 	if (realm->rtt_addr == HEAP_NULL_PTR) {
 		ERROR("Failed to allocate memory for rtt_addr\n");
 		goto err_undelegate_rd;
 	} else {
-		ret = host_rmi_granule_delegate(realm->rtt_addr);
-		if (ret != RMI_SUCCESS) {
-			ERROR("%s() failed, rtt_addr=0x%lx ret=0x%lx\n",
+		for (unsigned int i = 0U; i < rtt_page_count; i++) {
+			ret = host_rmi_granule_delegate(realm->rtt_addr + (i * PAGE_SIZE));
+
+			if (ret != RMI_SUCCESS) {
+				ERROR("%s() failed, rtt_addr=0x%lx ret=0x%lx\n",
 				"host_rmi_granule_delegate", realm->rtt_addr, ret);
-			goto err_free_rtt;
+
+				for (unsigned int j = 0U; j < i; j++) {
+					host_rmi_granule_undelegate(realm->rtt_addr
+							+ (i * PAGE_SIZE));
+				}
+
+				goto err_free_rtt;
+			}
+
+			if (i > 0U && !realm->rtt_tree_single) {
+				realm->aux_rtt_addr[i - 1] = realm->rtt_addr + (i * PAGE_SIZE);
+				params->aux_rtt_base[i - 1] = realm->rtt_addr + (i * PAGE_SIZE);
+			}
 		}
 	}
 
-	/* Allocate memory for params */
-	params = (struct rmi_realm_params *)page_alloc(PAGE_SIZE);
-	if (params == NULL) {
-		ERROR("Failed to allocate memory for params\n");
-		goto err_undelegate_rtt;
-	}
-
-	memset((char *)params, 0U, PAGE_SIZE);
-
 	/* Populate params */
 	params->s2sz = EXTRACT(RMI_FEATURE_REGISTER_0_S2SZ,
 				realm->rmm_feat_reg0);
@@ -813,12 +840,18 @@
 	}
 	params->num_aux_planes = realm->num_aux_planes;
 
+	/* Allocate VMID for all planes */
+	for (unsigned int i = 0U; i < realm->num_aux_planes; i++) {
+		params->aux_vmid[i] = (unsigned short)(vmid++);
+		realm->aux_vmid[i] = params->aux_vmid[i];
+	}
+
 	/* Create Realm */
 	ret = host_rmi_realm_create(realm->rd, (u_register_t)params);
 	if (ret != RMI_SUCCESS) {
 		ERROR("%s() failed, rd=0x%lx ret=0x%lx\n",
 			"host_rmi_realm_create", realm->rd, ret);
-		goto err_free_params;
+		goto err_free_vmid;
 	}
 
 	realm->vmid = params->vmid;
@@ -827,7 +860,7 @@
 		ERROR("%s() failed, rd=0x%lx ret=0x%lx\n",
 			"host_rmi_rec_aux_count", realm->rd, ret);
 		host_rmi_realm_destroy(realm->rd);
-		goto err_free_params;
+		goto err_free_vmid;
 	}
 
 	realm->state = REALM_STATE_NEW;
@@ -836,14 +869,10 @@
 	page_free((u_register_t)params);
 	return REALM_SUCCESS;
 
-err_free_params:
-	page_free((u_register_t)params);
-
-err_undelegate_rtt:
-	ret = host_rmi_granule_undelegate(realm->rtt_addr);
-	if (ret != RMI_SUCCESS) {
-		WARN("%s() failed, rtt_addr=0x%lx ret=0x%lx\n",
-			"host_rmi_granule_undelegate", realm->rtt_addr, ret);
+err_free_vmid:
+	/* Free VMID */
+	for (unsigned int i = 0U; i <= realm->num_aux_planes; i++) {
+		vmid--;
 	}
 
 err_free_rtt:
@@ -855,9 +884,20 @@
 		WARN("%s() failed, rd=0x%lx ret=0x%lx\n",
 			"host_rmi_granule_undelegate", realm->rd, ret);
 	}
+
 err_free_rd:
 	page_free(realm->rd);
 
+	page_free((u_register_t)params);
+
+	for (unsigned int i = 0U; i < rtt_page_count; i++) {
+		ret = host_rmi_granule_undelegate(realm->rtt_addr + (i * PAGE_SIZE));
+		if (ret != RMI_SUCCESS) {
+			WARN("%s() failed, rtt_addr=0x%lx ret=0x%lx\n",
+			"host_rmi_granule_undelegate", realm->rtt_addr + (i * PAGE_SIZE), ret);
+		}
+	}
+
 err_free_par:
 	page_free(realm->par_base);
 
@@ -880,22 +920,23 @@
 					  u_register_t realm_payload_adr)
 {
 	u_register_t src_pa = realm_payload_adr;
-	u_register_t i = 0UL;
 	u_register_t ret;
 
 	/* MAP image regions */
-	while (i < (realm->par_size / PAGE_SIZE)) {
+	/* Copy Plane 0-N Images */
+
+	for (unsigned int j = 0U; j <= realm->num_aux_planes; j++) {
 		ret = host_realm_delegate_map_protected_data(false, realm,
-						realm->par_base + i * PAGE_SIZE,
-						PAGE_SIZE,
-						src_pa + i * PAGE_SIZE);
+					realm->par_base + (j * realm->par_size),
+					realm->par_size,
+					src_pa);
+
 		if (ret != RMI_SUCCESS) {
-			ERROR("%s() failed, par_base=0x%lx ret=0x%lx\n",
-				"host_realm_delegate_map_protected_data",
-				realm->par_base, ret);
+			ERROR("%s() failed par_base=0x%lx size=0x%lx j=%u ret=0x%lx\n",
+			"host_realm_delegate_map_protected_data",
+			realm->par_base, realm->par_size, j, ret);
 			return REALM_ERROR;
 		}
-		i++;
 	}
 
 	return REALM_SUCCESS;
@@ -1136,6 +1177,7 @@
 u_register_t host_realm_destroy(struct realm *realm)
 {
 	u_register_t ret;
+	unsigned int rtt_page_count;
 	long rtt_start_level = realm->start_level;
 
 	if (realm->state == REALM_STATE_NULL) {
@@ -1214,11 +1256,24 @@
 		return REALM_ERROR;
 	}
 
-	ret = host_rmi_granule_undelegate(realm->rtt_addr);
-	if (ret != RMI_SUCCESS) {
-		ERROR("%s() failed, rtt_addr=0x%lx ret=0x%lx\n",
-			"host_rmi_granule_undelegate", realm->rtt_addr, ret);
-		return REALM_ERROR;
+	if (realm->rtt_tree_single) {
+		rtt_page_count = 1U;
+	} else {
+		rtt_page_count = realm->num_aux_planes + 1U;
+	}
+
+	for (unsigned int i = 0U; i < rtt_page_count; i++) {
+		ret = host_rmi_granule_undelegate(realm->rtt_addr + (i * PAGE_SIZE));
+		if (ret != RMI_SUCCESS) {
+			ERROR("%s() failed, rtt_addr=0x%lx ret=0x%lx\n",
+			"host_rmi_granule_undelegate", realm->rtt_addr + (i * PAGE_SIZE), ret);
+			return REALM_ERROR;
+		}
+	}
+
+	/* Free VMID */
+	for (unsigned int i = 0U; i <= realm->num_aux_planes; i++) {
+		vmid--;
 	}
 
 	page_free(realm->rd);