refactor: FF-A PSCI framework messages

This change is a slight refactoring of the spmd_handler in the way it
consumes FF-A power management messages conveyed by the SPMD to the SPMC
by a direct request and how the latter builds the direct response.
This follows the guidance from FF-A v1.1 REL0 section 18.3.4.

Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
Change-Id: I242f5f51e5a81fba859a2031fbc7746a814e0241
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
index 2b02f1b..e29117e 100644
--- a/src/arch/aarch64/hypervisor/handler.c
+++ b/src/arch/aarch64/hypervisor/handler.c
@@ -61,7 +61,8 @@
  */
 #define SPMD_FWK_MSG_BIT (UINT64_C(1) << 31)
 #define SPMD_FWK_MSG_FUNC_MASK UINT64_C(0xFF)
-#define SPMD_FWK_MSG_PSCI UINT8_C(0)
+#define SPMD_FWK_MSG_PSCI_REQ UINT8_C(0x0)
+#define SPMD_FWK_MSG_PSCI_RESP UINT8_C(0x2)
 #define SPMD_FWK_MSG_FFA_VERSION_REQ UINT8_C(0x8)
 #define SPMD_FWK_MSG_FFA_VERSION_RESP UINT8_C(0x9)
 
@@ -346,35 +347,48 @@
 		return false;
 	}
 
+	/*
+	 * The framework message is conveyed by EL3/SPMD to SPMC so the
+	 * current VM id must match to the other world VM id.
+	 */
+	CHECK(current->vm->id == HF_HYPERVISOR_VM_ID);
+
 	switch (fwk_msg_func_id) {
-	case SPMD_FWK_MSG_PSCI: {
+	case SPMD_FWK_MSG_PSCI_REQ: {
+		uint32_t psci_msg_response = PSCI_ERROR_NOT_SUPPORTED;
 		struct vcpu *boot_vcpu = vcpu_get_boot_vcpu();
 		struct vm *vm = boot_vcpu->vm;
 		struct vcpu *vcpu = vm_get_vcpu(vm, vcpu_index(current));
 
+		/*
+		 * TODO: the power management event reached the SPMC.
+		 * In a later iteration, the power management event can
+		 * be passed to the SP by resuming it.
+		 */
 		switch (args->arg3) {
 		case PSCI_CPU_OFF: {
-			/*
-			 * TODO: the PM event reached the SPMC. In a later
-			 * iteration, the PM event can be passed to the SP by
-			 * resuming it.
-			 */
-			*args = (struct ffa_value){
-				.func = FFA_MSG_SEND_DIRECT_RESP_32,
-				.arg1 = ((uint64_t)HF_SPMC_VM_ID << 16) |
-					HF_SPMD_VM_ID,
-				.arg2 = 0U};
+			dlog_verbose("cpu%u off notification!\n",
+				     vcpu_index(vcpu));
 
-			dlog_verbose("%s cpu off notification cpuid %#x\n",
-				     __func__, vcpu->cpu->id);
 			cpu_off(vcpu->cpu);
+			psci_msg_response = PSCI_RETURN_SUCCESS;
 			break;
 		}
 		default:
-			dlog_verbose("%s PSCI message not handled %#x\n",
-				     __func__, args->arg3);
-			return false;
+			dlog_error(
+				"FF-A PSCI framework message not handled "
+				"%#x %#x %#x %#x\n",
+				args->func, args->arg1, args->arg2, args->arg3);
+			psci_msg_response = PSCI_ERROR_NOT_SUPPORTED;
 		}
+
+		*args = (struct ffa_value){
+			.func = FFA_MSG_SEND_DIRECT_RESP_32,
+			.arg1 = ((uint64_t)HF_SPMC_VM_ID << 16) | HF_SPMD_VM_ID,
+			.arg2 = SPMD_FWK_MSG_BIT | SPMD_FWK_MSG_PSCI_RESP,
+			.arg3 = psci_msg_response};
+
+		return true;
 	}
 	case SPMD_FWK_MSG_FFA_VERSION_REQ: {
 		struct ffa_value ret = api_ffa_version(current, args->arg3);
@@ -385,18 +399,32 @@
 			.arg2 = SPMD_FWK_MSG_BIT |
 				SPMD_FWK_MSG_FFA_VERSION_RESP,
 			.arg3 = ret.func};
-		break;
+		return true;
 	}
 	default:
-		dlog_verbose("%s message not handled %#x\n", __func__, fwk_msg);
+		dlog_error("FF-A framework message not handled %#x\n",
+			   args->arg2);
+
+		/*
+		 * TODO: the framework message that was conveyed by a direct
+		 * request is not handled although we still want to complete
+		 * by a direct response. However, there is no defined error
+		 * response to state that the message couldn't be handled.
+		 * An alternative would be to return FFA_ERROR.
+		 */
 		*args = (struct ffa_value){
 			.func = FFA_MSG_SEND_DIRECT_RESP_32,
 			.arg1 = ((uint64_t)HF_SPMC_VM_ID << 16) | HF_SPMD_VM_ID,
 			/* Set bit 31 since this is a framework message. */
 			.arg2 = SPMD_FWK_MSG_BIT | fwk_msg_func_id};
+
+		return true;
 	}
 
-	return true;
+	/* Should not reach this point. */
+	assert(false);
+
+	return false;
 }
 
 #endif