Implement minimal PSCI for secondary VMs to manage their vCPUs.

Bug: 132422393
Change-Id: I44643ec9eec722dfe0332b7ffefadcdd8dd98985
diff --git a/src/api.c b/src/api.c
index c1f337c..438f6da 100644
--- a/src/api.c
+++ b/src/api.c
@@ -126,6 +126,24 @@
 }
 
 /**
+ * Puts the current vCPU in off mode, and returns to the primary VM.
+ */
+struct vcpu *api_vcpu_off(struct vcpu *current)
+{
+	struct hf_vcpu_run_return ret = {
+		.code = HF_VCPU_RUN_WAIT_FOR_INTERRUPT,
+	};
+
+	/*
+	 * Disable the timer, so the scheduler doesn't get told to call back
+	 * based on it.
+	 */
+	arch_timer_disable_current();
+
+	return api_switch_to_primary(current, ret, VCPU_STATE_OFF);
+}
+
+/**
  * 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. This SPCI function always returns SPCI_SUCCESS.
@@ -148,6 +166,20 @@
 }
 
 /**
+ * Switches to the primary so that it can switch to the target, or kick it if it
+ * is already running on a different physical CPU.
+ */
+struct vcpu *api_wake_up(struct vcpu *current, struct vcpu *target_vcpu)
+{
+	struct hf_vcpu_run_return ret = {
+		.code = HF_VCPU_RUN_WAKE_UP,
+		.wake_up.vm_id = target_vcpu->vm->id,
+		.wake_up.vcpu = vcpu_index(target_vcpu),
+	};
+	return api_switch_to_primary(current, ret, VCPU_STATE_READY);
+}
+
+/**
  * Aborts the vCPU and triggers its VM to abort fully.
  */
 struct vcpu *api_abort(struct vcpu *current)
@@ -258,7 +290,6 @@
 					 uint32_t intid, struct vcpu *current,
 					 struct vcpu **next)
 {
-	struct vm *target_vm = target_vcpu->vm;
 	uint32_t intid_index = intid / INTERRUPT_REGISTER_BITS;
 	uint32_t intid_mask = 1u << (intid % INTERRUPT_REGISTER_BITS);
 	int64_t ret = 0;
@@ -297,16 +328,7 @@
 		 */
 		ret = 1;
 	} else if (current != target_vcpu && next != NULL) {
-		/*
-		 * Switch to the primary so that it can switch to the target, or
-		 * kick it if it is already running on a different physical CPU.
-		 */
-		struct hf_vcpu_run_return ret = {
-			.code = HF_VCPU_RUN_WAKE_UP,
-			.wake_up.vm_id = target_vm->id,
-			.wake_up.vcpu = target_vcpu - target_vm->vcpus,
-		};
-		*next = api_switch_to_primary(current, ret, VCPU_STATE_READY);
+		*next = api_wake_up(current, target_vcpu);
 	}
 
 out: