feat(rmm-eac4): modify RMI_PSCI_COMPLETE command

This patch makes the following changes in
RMI_PSCI_COMPLETE command handler in according to
RMM Specification 1.0-eac3:
- added 'status' parameter passed in X3 register
- added 'status' failure condition.
PSCI and SMC return codes changed to comply with MISRA C
Rule 10.1 from UL(n) to (unsigned long)(n).

Signed-off-by: AlexeiFedorov <Alexei.Fedorov@arm.com>
Change-Id: Ib5ec506433a58f17591bef85a2b48663ac3969c0
diff --git a/runtime/rsi/psci.c b/runtime/rsi/psci.c
index a3752e5..b9cbd91 100644
--- a/runtime/rsi/psci.c
+++ b/runtime/rsi/psci.c
@@ -331,13 +331,22 @@
  */
 static unsigned long complete_psci_cpu_on(struct rec *target_rec,
 					  unsigned long entry_point_address,
-					  unsigned long caller_sctlr_el1)
+					  unsigned long caller_sctlr_el1,
+					  unsigned long status)
 {
 	if ((granule_refcount_read_acquire(target_rec->g_rec) != 0UL) ||
 		target_rec->runnable) {
 		return PSCI_RETURN_ALREADY_ON;
 	}
 
+	/*
+	 * Host is permitted to deny a PSCI_CPU_ON request,
+	 * if the target CPU is not already on.
+	 */
+	if (status == PSCI_RETURN_DENIED) {
+		return PSCI_RETURN_DENIED;
+	}
+
 	psci_reset_rec(target_rec, caller_sctlr_el1);
 	target_rec->pc = entry_point_address;
 	target_rec->runnable = true;
@@ -355,9 +364,10 @@
 }
 
 unsigned long psci_complete_request(struct rec *calling_rec,
-				    struct rec *target_rec)
+				    struct rec *target_rec, unsigned long status)
 {
-	unsigned long ret = PSCI_RETURN_NOT_SUPPORTED;
+	unsigned long ret = RMI_SUCCESS;
+	unsigned long rec_ret = PSCI_RETURN_NOT_SUPPORTED;
 	unsigned long mpidr = calling_rec->regs[1];
 
 	if (!calling_rec->psci_info.pending) {
@@ -375,23 +385,41 @@
 	switch (calling_rec->regs[0]) {
 	case SMC32_PSCI_CPU_ON:
 	case SMC64_PSCI_CPU_ON:
-		ret = complete_psci_cpu_on(target_rec,
-					   calling_rec->regs[2],
-					   calling_rec->sysregs.sctlr_el1);
+		if ((status != PSCI_RETURN_SUCCESS) &&
+		    (status != PSCI_RETURN_DENIED)) {
+			return RMI_ERROR_INPUT;
+		}
+
+		rec_ret = complete_psci_cpu_on(target_rec,
+						calling_rec->regs[2],
+						calling_rec->sysregs.sctlr_el1,
+						status);
+		/*
+		 * If the target CPU is already running and the Host has denied the
+		 * PSCI_CPU_ON request, then return error back to Host.
+		 */
+		if ((status == PSCI_RETURN_DENIED) &&
+		   (rec_ret == PSCI_RETURN_ALREADY_ON)) {
+			ret = RMI_ERROR_INPUT;
+		}
 		break;
 	case SMC32_PSCI_AFFINITY_INFO:
 	case SMC64_PSCI_AFFINITY_INFO:
-		ret = complete_psci_affinity_info(target_rec);
+		if (status != PSCI_RETURN_SUCCESS) {
+			return RMI_ERROR_INPUT;
+		}
+
+		rec_ret = complete_psci_affinity_info(target_rec);
 		break;
 	default:
 		assert(false);
 	}
 
-	calling_rec->regs[0] = ret;
+	calling_rec->regs[0] = rec_ret;
 	calling_rec->regs[1] = 0;
 	calling_rec->regs[2] = 0;
 	calling_rec->regs[3] = 0;
 	calling_rec->psci_info.pending = false;
 
-	return RMI_SUCCESS;
+	return ret;
 }