feat(ff-a): add managed exit field in the manifest

Moving setting to enable/disable managed exit support from messaging
method field to a separate field in partition manifest. As of DEN0077A
FF-A v1.1 Beta0 section 5.2, managed exit support is moved out of
messaging-method field and is described in a separate field.

Signed-off-by: Maksims Svecovs <maksims.svecovs@arm.com>
Change-Id: I87506d7213b88d5a18073bea7357c381605d8b33
diff --git a/src/api.c b/src/api.c
index 8a90a27..82619e0 100644
--- a/src/api.c
+++ b/src/api.c
@@ -228,7 +228,7 @@
  */
 static bool api_ffa_is_managed_exit_ongoing(struct vcpu_locked vcpu_locked)
 {
-	return (vm_managed_exit_supported(vcpu_locked.vcpu->vm) &&
+	return (plat_ffa_vm_managed_exit_supported(vcpu_locked.vcpu->vm) &&
 		vcpu_locked.vcpu->processing_managed_exit);
 }
 
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
index 0b4550d..c5bdacd 100644
--- a/src/arch/aarch64/hypervisor/handler.c
+++ b/src/arch/aarch64/hypervisor/handler.c
@@ -11,6 +11,7 @@
 #include "hf/arch/barriers.h"
 #include "hf/arch/init.h"
 #include "hf/arch/mmu.h"
+#include "hf/arch/plat/ffa.h"
 #include "hf/arch/plat/smc.h"
 
 #include "hf/api.h"
@@ -929,7 +930,7 @@
 	struct vcpu *current_vcpu = current();
 	int ret;
 
-	if (vm_managed_exit_supported(current_vcpu->vm)) {
+	if (plat_ffa_vm_managed_exit_supported(current_vcpu->vm)) {
 		/* Mask all interrupts */
 		plat_interrupts_set_priority_mask(0x0);
 
diff --git a/src/arch/aarch64/plat/ffa/hypervisor.c b/src/arch/aarch64/plat/ffa/hypervisor.c
index 22ea258..dc786ae 100644
--- a/src/arch/aarch64/plat/ffa/hypervisor.c
+++ b/src/arch/aarch64/plat/ffa/hypervisor.c
@@ -161,8 +161,7 @@
 ffa_partition_properties_t plat_ffa_partition_properties(
 	ffa_vm_id_t vm_id, const struct vm *target)
 {
-	ffa_partition_properties_t result =
-		target->messaging_method | ~FFA_PARTITION_MANAGED_EXIT;
+	ffa_partition_properties_t result = target->messaging_method;
 	/*
 	 * VMs support indirect messaging only in the Normal World.
 	 * Primary VM cannot receive direct requests.
@@ -178,3 +177,10 @@
 	}
 	return result;
 }
+
+bool plat_ffa_vm_managed_exit_supported(struct vm *vm)
+{
+	(void)vm;
+
+	return false;
+}
diff --git a/src/arch/aarch64/plat/ffa/spmc.c b/src/arch/aarch64/plat/ffa/spmc.c
index 10f7b54..7ddf6e8 100644
--- a/src/arch/aarch64/plat/ffa/spmc.c
+++ b/src/arch/aarch64/plat/ffa/spmc.c
@@ -107,8 +107,7 @@
 ffa_partition_properties_t plat_ffa_partition_properties(
 	ffa_vm_id_t vm_id, const struct vm *target)
 {
-	ffa_partition_properties_t result =
-		(target->messaging_method | ~(FFA_PARTITION_MANAGED_EXIT));
+	ffa_partition_properties_t result = target->messaging_method;
 	/*
 	 * SPs support full direct messaging communication with other SPs,
 	 * and are allowed to only receive direct requests from the other world.
@@ -120,3 +119,8 @@
 	}
 	return result & FFA_PARTITION_DIRECT_REQ_RECV;
 }
+
+bool plat_ffa_vm_managed_exit_supported(struct vm *vm)
+{
+	return vm->managed_exit;
+}
diff --git a/src/arch/fake/hypervisor/ffa.c b/src/arch/fake/hypervisor/ffa.c
index 5cf3d28..288b256 100644
--- a/src/arch/fake/hypervisor/ffa.c
+++ b/src/arch/fake/hypervisor/ffa.c
@@ -70,3 +70,9 @@
 	(void)target;
 	return 0;
 }
+
+bool plat_ffa_vm_managed_exit_supported(struct vm *vm)
+{
+	(void)vm;
+	return false;
+}
diff --git a/src/load.c b/src/load.c
index b700c59..0e4f9dd 100644
--- a/src/load.c
+++ b/src/load.c
@@ -152,6 +152,8 @@
 		vm_locked.vm->messaging_method =
 			manifest_vm->sp.messaging_method;
 
+		vm_locked.vm->managed_exit = manifest_vm->sp.managed_exit;
+
 		vm_locked.vm->boot_order = manifest_vm->sp.boot_order;
 		/* Updating boot list according to boot_order */
 		vm_update_boot(vm_locked.vm);
diff --git a/src/manifest.c b/src/manifest.c
index e8619b9..6110765 100644
--- a/src/manifest.c
+++ b/src/manifest.c
@@ -606,6 +606,8 @@
 		       (uint8_t *)&vm->sp.messaging_method));
 	dlog_verbose("  Messaging method %u\n", vm->sp.messaging_method);
 
+	TRY(read_bool(&root, "managed-exit", &vm->sp.managed_exit));
+
 	/* Parse memory-regions */
 	ffa_node = root;
 	if (fdt_find_child(&ffa_node, &mem_region_node_name)) {
@@ -669,8 +671,7 @@
 
 	if ((vm->sp.messaging_method &
 	     ~(FFA_PARTITION_DIRECT_REQ_RECV | FFA_PARTITION_DIRECT_REQ_SEND |
-	       FFA_PARTITION_INDIRECT_MSG | FFA_PARTITION_MANAGED_EXIT)) !=
-	    0U) {
+	       FFA_PARTITION_INDIRECT_MSG)) != 0U) {
 		dlog_error("Messaging method %s: %x\n", error_string,
 			   vm->sp.messaging_method);
 		ret_code = MANIFEST_ERROR_NOT_COMPATIBLE;
diff --git a/src/manifest_test.cc b/src/manifest_test.cc
index c73f843..89d5de6 100644
--- a/src/manifest_test.cc
+++ b/src/manifest_test.cc
@@ -236,6 +236,7 @@
 		Property("xlat-granule", "<0>");
 		Property("boot-order", "<0>");
 		Property("messaging-method", "<4>");
+		BooleanProperty("managed-exit");
 		return *this;
 	}
 
@@ -1057,6 +1058,7 @@
 	ASSERT_EQ(m.vm[0].sp.xlat_granule, PAGE_4KB);
 	ASSERT_EQ(m.vm[0].sp.boot_order, 0);
 	ASSERT_EQ(m.vm[0].sp.messaging_method, FFA_PARTITION_INDIRECT_MSG);
+	ASSERT_EQ(m.vm[0].sp.managed_exit, true);
 	ASSERT_EQ(m.vm[0].sp.mem_regions[0].base_address, 0x7100000);
 	ASSERT_EQ(m.vm[0].sp.mem_regions[0].page_count, 4);
 	ASSERT_EQ(m.vm[0].sp.mem_regions[0].attributes, 7);
diff --git a/src/vm.c b/src/vm.c
index cb7873f..e575d35 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -334,11 +334,3 @@
 
 	vm->next_boot = current;
 }
-
-/**
- * Returns true if VM supports a managed exit.
- */
-bool vm_managed_exit_supported(struct vm *vm)
-{
-	return (vm->messaging_method & FFA_PARTITION_MANAGED_EXIT) != 0U;
-}