SPCI: SPCI_YIELD.

Adapted hf_vcpu_yield to conform with the spci_yield specification.

Change-Id: I7ad11e83f068a09a19fd930dcead787b5a22e498
diff --git a/inc/hf/api.h b/inc/hf/api.h
index c63f95c..75a85e2 100644
--- a/inc/hf/api.h
+++ b/inc/hf/api.h
@@ -40,7 +40,6 @@
 
 struct vcpu *api_preempt(struct vcpu *current);
 struct vcpu *api_wait_for_interrupt(struct vcpu *current);
-struct vcpu *api_yield(struct vcpu *current);
 struct vcpu *api_abort(struct vcpu *current);
 
 int64_t api_interrupt_enable(uint32_t intid, bool enable, struct vcpu *current);
@@ -53,3 +52,4 @@
 			  struct vcpu **next);
 int32_t api_spci_msg_recv(uint32_t attributes, struct vcpu *current,
 			  struct vcpu **next);
+int32_t api_spci_yield(struct vcpu *current, struct vcpu **next);
diff --git a/inc/vmapi/hf/call.h b/inc/vmapi/hf/call.h
index 6d36d54..aaa2fa7 100644
--- a/inc/vmapi/hf/call.h
+++ b/inc/vmapi/hf/call.h
@@ -28,7 +28,6 @@
 #define HF_VM_GET_COUNT         0xff01
 #define HF_VCPU_GET_COUNT       0xff02
 #define HF_VCPU_RUN             0xff03
-#define HF_VCPU_YIELD           0xff04
 #define HF_VM_CONFIGURE         0xff05
 #define HF_MAILBOX_CLEAR        0xff08
 #define HF_MAILBOX_WRITABLE_GET 0xff09
@@ -84,10 +83,11 @@
 
 /**
  * Hints that the vcpu is willing to yield its current use of the physical CPU.
+ * This call always returns SPCI_SUCCESS.
  */
-static inline void hf_vcpu_yield(void)
+static inline int64_t spci_yield(void)
 {
-	hf_call(HF_VCPU_YIELD, 0, 0, 0);
+	return hf_call(SPCI_YIELD_32, 0, 0, 0);
 }
 
 /**
diff --git a/src/api.c b/src/api.c
index 60954c3..ecc45b3 100644
--- a/src/api.c
+++ b/src/api.c
@@ -128,9 +128,9 @@
 /**
  * Returns to the primary vm to allow this cpu to be used for other tasks as the
  * vcpu does not have work to do at this moment. The current vcpu is marked as
- * ready to be scheduled again.
+ * ready to be scheduled again. This SPCI function always returns SPCI_SUCCESS.
  */
-struct vcpu *api_yield(struct vcpu *current)
+int32_t api_spci_yield(struct vcpu *current, struct vcpu **next)
 {
 	struct hf_vcpu_run_return ret = {
 		.code = HF_VCPU_RUN_YIELD,
@@ -138,10 +138,13 @@
 
 	if (current->vm->id == HF_PRIMARY_VM_ID) {
 		/* Noop on the primary as it makes the scheduling decisions. */
-		return NULL;
+		return SPCI_SUCCESS;
 	}
 
-	return api_switch_to_primary(current, ret, VCPU_STATE_READY);
+	*next = api_switch_to_primary(current, ret, VCPU_STATE_READY);
+
+	/* SPCI_YIELD always returns SPCI_SUCCESS. */
+	return SPCI_SUCCESS;
 }
 
 /**
diff --git a/src/arch/aarch64/handler.c b/src/arch/aarch64/handler.c
index 7aa3a3e..9402fe5 100644
--- a/src/arch/aarch64/handler.c
+++ b/src/arch/aarch64/handler.c
@@ -410,9 +410,8 @@
 			api_vcpu_run(arg1, arg2, current(), &ret.new));
 		break;
 
-	case HF_VCPU_YIELD:
-		ret.user_ret = 0;
-		ret.new = api_yield(current());
+	case SPCI_YIELD_32:
+		ret.user_ret = api_spci_yield(current(), &ret.new);
 		break;
 
 	case HF_VM_CONFIGURE:
@@ -544,6 +543,7 @@
 {
 	struct vcpu *vcpu = current();
 	struct vcpu_fault_info info;
+	struct vcpu *new_vcpu;
 
 	switch (esr >> 26) {
 	case 0x01: /* EC = 000001, WFI or WFE. */
@@ -556,7 +556,8 @@
 			 * TODO: consider giving the scheduler more context,
 			 * somehow.
 			 */
-			return api_yield(vcpu);
+			api_spci_yield(vcpu, &new_vcpu);
+			return new_vcpu;
 		}
 		/* WFI */
 		return api_wait_for_interrupt(vcpu);
diff --git a/test/hftest/hftest_service.c b/test/hftest/hftest_service.c
index 1278617..5b9fafb 100644
--- a/test/hftest/hftest_service.c
+++ b/test/hftest/hftest_service.c
@@ -114,7 +114,7 @@
 	ctx->memory_size = memory_size;
 
 	/* Pause so the next time cycles are given the service will be run. */
-	hf_vcpu_yield();
+	spci_yield();
 
 	/* Let the service run. */
 	service();
diff --git a/test/vmapi/primary_only/primary_only.c b/test/vmapi/primary_only/primary_only.c
index df19d32..6cb8f46 100644
--- a/test/vmapi/primary_only/primary_only.c
+++ b/test/vmapi/primary_only/primary_only.c
@@ -91,9 +91,9 @@
 /**
  * Yielding from the primary is a noop.
  */
-TEST(hf_vcpu_yield, yield_is_noop_for_primary)
+TEST(spci_yield, yield_is_noop_for_primary)
 {
-	hf_vcpu_yield();
+	EXPECT_EQ(spci_yield(), SPCI_SUCCESS);
 }
 
 /**
diff --git a/test/vmapi/primary_with_secondaries/services/boot.c b/test/vmapi/primary_with_secondaries/services/boot.c
index 965c5bb..4ca4390 100644
--- a/test/vmapi/primary_with_secondaries/services/boot.c
+++ b/test/vmapi/primary_with_secondaries/services/boot.c
@@ -47,7 +47,7 @@
 	ASSERT_NE(checksum, 0);
 	dlog("Checksum of all memory is %d\n", checksum);
 
-	hf_vcpu_yield();
+	spci_yield();
 }
 
 TEST_SERVICE(boot_memory_underrun)
diff --git a/test/vmapi/primary_with_secondaries/services/floating_point.c b/test/vmapi/primary_with_secondaries/services/floating_point.c
index 2ba57c9..d98fdb9 100644
--- a/test/vmapi/primary_with_secondaries/services/floating_point.c
+++ b/test/vmapi/primary_with_secondaries/services/floating_point.c
@@ -27,8 +27,8 @@
 {
 	const double value = 0.75;
 	fill_fp_registers(value);
-	hf_vcpu_yield();
+	EXPECT_EQ(spci_yield(), SPCI_SUCCESS);
 
 	ASSERT_TRUE(check_fp_register(value));
-	hf_vcpu_yield();
+	spci_yield();
 }
diff --git a/test/vmapi/primary_with_secondaries/services/interruptible_echo.c b/test/vmapi/primary_with_secondaries/services/interruptible_echo.c
index 760998c..296065f 100644
--- a/test/vmapi/primary_with_secondaries/services/interruptible_echo.c
+++ b/test/vmapi/primary_with_secondaries/services/interruptible_echo.c
@@ -44,7 +44,7 @@
 
 		/* Retry if interrupted but made visible with the yield. */
 		while (res == SPCI_INTERRUPTED) {
-			hf_vcpu_yield();
+			spci_yield();
 			res = spci_msg_recv(SPCI_MSG_RECV_BLOCK);
 		}
 
diff --git a/test/vmapi/primary_with_secondaries/services/memory.c b/test/vmapi/primary_with_secondaries/services/memory.c
index 0175577..f17932c 100644
--- a/test/vmapi/primary_with_secondaries/services/memory.c
+++ b/test/vmapi/primary_with_secondaries/services/memory.c
@@ -42,7 +42,7 @@
 		}
 
 		/* Allow the memory to be populated. */
-		hf_vcpu_yield();
+		EXPECT_EQ(spci_yield(), SPCI_SUCCESS);
 
 		/* Increment each byte of memory. */
 		for (i = 0; i < PAGE_SIZE; ++i) {
diff --git a/test/vmapi/primary_with_secondaries/services/spci_check.c b/test/vmapi/primary_with_secondaries/services/spci_check.c
index 4f4ce6e..d44da6a 100644
--- a/test/vmapi/primary_with_secondaries/services/spci_check.c
+++ b/test/vmapi/primary_with_secondaries/services/spci_check.c
@@ -61,7 +61,7 @@
 	/* Ensure that the payload was correctly transmitted. */
 	EXPECT_EQ(memcmp(recv_buf->payload, message, sizeof(message)), 0);
 
-	hf_vcpu_yield();
+	spci_yield();
 }
 
 TEST_SERVICE(spci_length)
@@ -79,7 +79,7 @@
 	EXPECT_NE(memcmp(recv_buf->payload, message, sizeof(message)), 0);
 	EXPECT_EQ(memcmp(recv_buf->payload, message, recv_buf->length), 0);
 
-	hf_vcpu_yield();
+	spci_yield();
 }
 
 TEST_SERVICE(spci_recv_non_blocking)
@@ -87,5 +87,5 @@
 	/* Wait for single message to be sent by the primary VM. */
 	EXPECT_EQ(spci_msg_recv(0), SPCI_RETRY);
 
-	hf_vcpu_yield();
+	spci_yield();
 }