smc wrapper function conformance

smc wrapper function accepts all arguments and returns all four result
registers.

Bug: 132421503
Change-Id: If3030df8ffe77f26a89d73959d9e05c3bd269c05
diff --git a/src/arch/aarch64/hftest/power_mgmt.c b/src/arch/aarch64/hftest/power_mgmt.c
index 7abe4d9..161c200 100644
--- a/src/arch/aarch64/hftest/power_mgmt.c
+++ b/src/arch/aarch64/hftest/power_mgmt.c
@@ -63,6 +63,7 @@
 {
 	void vm_cpu_entry_raw(uintptr_t arg);
 	struct cpu_start_state s;
+	smc_res_t smc_res;
 
 	/* Initialise the temporary state we'll hold on the stack. */
 	sl_init(&s.lock);
@@ -72,8 +73,9 @@
 	s.arg = arg;
 
 	/* Try to start the CPU. */
-	if (smc32(PSCI_CPU_ON, id, (size_t)&vm_cpu_entry_raw, (size_t)&s) !=
-	    PSCI_RETURN_SUCCESS) {
+	smc_res = smc32(PSCI_CPU_ON, id, (size_t)&vm_cpu_entry_raw, (size_t)&s,
+			0, 0, 0, 0);
+	if (smc_res.res0 != PSCI_RETURN_SUCCESS) {
 		return false;
 	}
 
@@ -91,7 +93,7 @@
  */
 noreturn void cpu_stop(void)
 {
-	smc32(PSCI_CPU_OFF, 0, 0, 0);
+	smc32(PSCI_CPU_OFF, 0, 0, 0, 0, 0, 0, 0);
 	for (;;) {
 		/* This should never be reached. */
 	}
@@ -110,13 +112,16 @@
 enum power_status cpu_status(cpu_id_t cpu_id)
 {
 	uint32_t lowest_affinity_level = 0;
+	smc_res_t smc_res;
 
 	/*
 	 * This works because the power_status enum values happen to be the same
 	 * as the PSCI_RETURN_* values. The static_asserts above validate that
 	 * this is the case.
 	 */
-	return smc32(PSCI_AFFINITY_INFO, cpu_id, lowest_affinity_level, 0);
+	smc_res = smc32(PSCI_AFFINITY_INFO, cpu_id, lowest_affinity_level, 0, 0,
+			0, 0, 0);
+	return smc_res.res0;
 }
 
 /**
@@ -124,7 +129,7 @@
  */
 noreturn void arch_power_off(void)
 {
-	smc32(PSCI_SYSTEM_OFF, 0, 0, 0);
+	smc32(PSCI_SYSTEM_OFF, 0, 0, 0, 0, 0, 0, 0);
 	for (;;) {
 		/* This should never be reached. */
 	}
diff --git a/src/arch/aarch64/hypervisor/psci_handler.c b/src/arch/aarch64/hypervisor/psci_handler.c
index 5f5f211..ad3447f 100644
--- a/src/arch/aarch64/hypervisor/psci_handler.c
+++ b/src/arch/aarch64/hypervisor/psci_handler.c
@@ -37,7 +37,9 @@
 /* Performs arch specific boot time initialisation. */
 void arch_one_time_init(void)
 {
-	el3_psci_version = smc32(PSCI_VERSION, 0, 0, 0);
+	smc_res_t smc_res = smc32(PSCI_VERSION, 0, 0, 0, 0, 0, 0, 0);
+
+	el3_psci_version = smc_res.res0;
 
 	/* Check there's nothing unexpected about PSCI. */
 	switch (el3_psci_version) {
@@ -69,6 +71,7 @@
 			     uintreg_t arg1, uintreg_t arg2, uintreg_t *ret)
 {
 	struct cpu *c;
+	smc_res_t smc_res;
 
 	/*
 	 * If there's a problem with the EL3 PSCI, block standard secure service
@@ -100,7 +103,8 @@
 				*ret = 0;
 			} else {
 				/* PSCI 1.x only defines two feature bits. */
-				*ret = smc32(func, arg0, 0, 0) & 0x3;
+				smc_res = smc32(func, arg0, 0, 0, 0, 0, 0, 0);
+				*ret = smc_res.res0 & 0x3;
 			}
 			break;
 
@@ -123,12 +127,12 @@
 		break;
 
 	case PSCI_SYSTEM_OFF:
-		smc32(PSCI_SYSTEM_OFF, 0, 0, 0);
+		smc32(PSCI_SYSTEM_OFF, 0, 0, 0, 0, 0, 0, 0);
 		panic("System off failed");
 		break;
 
 	case PSCI_SYSTEM_RESET:
-		smc32(PSCI_SYSTEM_RESET, 0, 0, 0);
+		smc32(PSCI_SYSTEM_RESET, 0, 0, 0, 0, 0, 0, 0);
 		panic("System reset failed");
 		break;
 
@@ -161,14 +165,15 @@
 		 * vcpu registers will be ignored.
 		 */
 		arch_regs_set_pc_arg(&vcpu->regs, ipa_init(arg1), arg2);
-		*ret = smc64(PSCI_CPU_SUSPEND, arg0, (uintreg_t)&cpu_entry,
-			     (uintreg_t)vcpu->cpu);
+		smc_res = smc64(PSCI_CPU_SUSPEND, arg0, (uintreg_t)&cpu_entry,
+				(uintreg_t)vcpu->cpu, 0, 0, 0, 0);
+		*ret = smc_res.res0;
 		break;
 	}
 
 	case PSCI_CPU_OFF:
 		cpu_off(vcpu->cpu);
-		smc32(PSCI_CPU_OFF, 0, 0, 0);
+		smc32(PSCI_CPU_OFF, 0, 0, 0, 0, 0, 0, 0);
 		panic("CPU off failed");
 		break;
 
@@ -191,8 +196,10 @@
 		 * itself off).
 		 */
 		do {
-			*ret = smc64(PSCI_CPU_ON, arg0, (uintreg_t)&cpu_entry,
-				     (uintreg_t)c);
+			smc_res =
+				smc64(PSCI_CPU_ON, arg0, (uintreg_t)&cpu_entry,
+				      (uintreg_t)c, 0, 0, 0, 0);
+			*ret = smc_res.res0;
 		} while (*ret == PSCI_ERROR_ALREADY_ON);
 
 		if (*ret != PSCI_RETURN_SUCCESS) {
diff --git a/src/arch/aarch64/smc.c b/src/arch/aarch64/smc.c
index 4a9d980..cb49389 100644
--- a/src/arch/aarch64/smc.c
+++ b/src/arch/aarch64/smc.c
@@ -18,10 +18,24 @@
 
 #include <stdint.h>
 
-uint64_t smc64_internal(uint64_t func, uint64_t arg0, uint64_t arg1,
-			uint64_t arg2);
+smc_res_t smc32_internal(uint32_t func, uint32_t arg0, uint32_t arg1,
+			 uint32_t arg2, uint32_t arg3, uint32_t arg4,
+			 uint32_t arg5, uint32_t caller_id);
 
-uint64_t smc64(uint32_t func, uint64_t arg0, uint64_t arg1, uint64_t arg2)
+smc_res_t smc32(uint32_t func, uint32_t arg0, uint32_t arg1, uint32_t arg2,
+		uint32_t arg3, uint32_t arg4, uint32_t arg5, uint32_t caller_id)
 {
-	return smc64_internal(func | SMCCC_64_BIT, arg0, arg1, arg2);
+	return smc32_internal(func | SMCCC_32_BIT, arg0, arg1, arg2, arg3, arg4,
+			      arg5, caller_id);
+}
+
+smc_res_t smc64_internal(uint32_t func, uint64_t arg0, uint64_t arg1,
+			 uint64_t arg2, uint64_t arg3, uint64_t arg4,
+			 uint64_t arg5, uint32_t caller_id);
+
+smc_res_t smc64(uint32_t func, uint64_t arg0, uint64_t arg1, uint64_t arg2,
+		uint64_t arg3, uint64_t arg4, uint64_t arg5, uint32_t caller_id)
+{
+	return smc64_internal(func | SMCCC_64_BIT, arg0, arg1, arg2, arg3, arg4,
+			      arg5, caller_id);
 }
diff --git a/src/arch/aarch64/smc.h b/src/arch/aarch64/smc.h
index 1cc5ba3..8c00a30 100644
--- a/src/arch/aarch64/smc.h
+++ b/src/arch/aarch64/smc.h
@@ -45,5 +45,17 @@
 
 /* clang-format on */
 
-uint32_t smc32(uint32_t func, uint32_t arg0, uint32_t arg1, uint32_t arg2);
-uint64_t smc64(uint32_t func, uint64_t arg0, uint64_t arg1, uint64_t arg2);
+typedef struct smc_res {
+	uint64_t res0;
+	uint64_t res1;
+	uint64_t res2;
+	uint64_t res3;
+} smc_res_t;
+
+smc_res_t smc32(uint32_t func, uint32_t arg0, uint32_t arg1, uint32_t arg2,
+		uint32_t arg3, uint32_t arg4, uint32_t arg5,
+		uint32_t caller_id);
+
+smc_res_t smc64(uint32_t func, uint64_t arg0, uint64_t arg1, uint64_t arg2,
+		uint64_t arg3, uint64_t arg4, uint64_t arg5,
+		uint32_t caller_id);
diff --git a/src/arch/aarch64/smc_internal.S b/src/arch/aarch64/smc_internal.S
index 9350fd1..de7879f 100644
--- a/src/arch/aarch64/smc_internal.S
+++ b/src/arch/aarch64/smc_internal.S
@@ -15,9 +15,14 @@
  */
 
 .section .text.smc, "ax"
-.global smc32
+.global smc32_internal
 .global smc64_internal
-smc32:
+
+smc32_internal:
 smc64_internal:
+	str x8, [sp, #-8] !
 	smc #0
+	ldr x8, [sp], #8
+        stp x0, x1, [x8]
+        stp x2, x3, [x8, #16]
 	ret