Initial tests for the primary VM interface.

The tests are kept platform independent and shutdown the system when
they are done. Shutting down results in QEMU being exited when we are in
emulation.

Change-Id: I1b5b0dd6c23ba2ab1e2b1a9d193b65d812f5a5ec
diff --git a/src/api.c b/src/api.c
index 39c90ad..2b7b5d9 100644
--- a/src/api.c
+++ b/src/api.c
@@ -2,7 +2,7 @@
 
 #include "std.h"
 #include "vm.h"
-#include "vmapi/hf/hvc.h"
+#include "vmapi/hf/call.h"
 
 struct vm secondary_vm[MAX_VMS];
 uint32_t secondary_vm_count;
diff --git a/src/arch/aarch64/BUILD.gn b/src/arch/aarch64/BUILD.gn
index 6426f40..1db1e37 100644
--- a/src/arch/aarch64/BUILD.gn
+++ b/src/arch/aarch64/BUILD.gn
@@ -6,6 +6,7 @@
   sources = [
     "exceptions.S",
     "hypervisor_entry.S",
+    "smc.S",
   ]
 
   sources += [
diff --git a/src/arch/aarch64/handler.c b/src/arch/aarch64/handler.c
index 06a8394..7088216 100644
--- a/src/arch/aarch64/handler.c
+++ b/src/arch/aarch64/handler.c
@@ -3,7 +3,7 @@
 #include "dlog.h"
 #include "psci.h"
 #include "vm.h"
-#include "vmapi/hf/hvc.h"
+#include "vmapi/hf/call.h"
 
 #include "msr.h"
 
diff --git a/src/arch/aarch64/hypervisor_entry.S b/src/arch/aarch64/hypervisor_entry.S
index 7d0396a..07747bd 100644
--- a/src/arch/aarch64/hypervisor_entry.S
+++ b/src/arch/aarch64/hypervisor_entry.S
@@ -37,14 +37,8 @@
 	bl cpu_main
 
 	/* Run the vcpu returned by cpu_main. */
-	b vcpu_restore_all_and_run
+	bl vcpu_restore_all_and_run
 
 	/* Loop forever waiting for interrupts. */
-5:	wfi
-	b 5b
-
-/* TODO: Move this elsewhere. */
-.globl smc
-smc:
-	SMC #0
-	ret
+0:	wfi
+	b 0b
diff --git a/src/arch/aarch64/inc/vm/shutdown.h b/src/arch/aarch64/inc/vm/shutdown.h
new file mode 100644
index 0000000..da9e553
--- /dev/null
+++ b/src/arch/aarch64/inc/vm/shutdown.h
@@ -0,0 +1,8 @@
+#ifndef _ARCH_VM_SHUTDOWN_H
+#define _ARCH_VM_SHUTDOWN_H
+
+#include <stdnoreturn.h>
+
+noreturn void shutdown(void);
+
+#endif /* _ARCH_VM_SHUTDOWN_H */
diff --git a/src/arch/aarch64/smc.S b/src/arch/aarch64/smc.S
new file mode 100644
index 0000000..8c817c9
--- /dev/null
+++ b/src/arch/aarch64/smc.S
@@ -0,0 +1,6 @@
+.text
+
+.globl smc
+smc:
+	smc #0
+	ret
diff --git a/src/arch/aarch64/vm/BUILD.gn b/src/arch/aarch64/vm/BUILD.gn
new file mode 100644
index 0000000..53ed1de
--- /dev/null
+++ b/src/arch/aarch64/vm/BUILD.gn
@@ -0,0 +1,19 @@
+# These components are only used by VMs for aarch64 specific actions.
+
+# Make a call to the hypervisor from a VM.
+source_set("hf_call") {
+  sources = [
+    "hf_call.S",
+  ]
+}
+
+# Shutdown the system or exit emulation.
+source_set("shutdown") {
+  sources = [
+    "shutdown.c",
+  ]
+
+  deps = [
+    ":hf_call",
+  ]
+}
diff --git a/src/arch/aarch64/vm/hf_call.S b/src/arch/aarch64/vm/hf_call.S
new file mode 100644
index 0000000..07743ca
--- /dev/null
+++ b/src/arch/aarch64/vm/hf_call.S
@@ -0,0 +1,6 @@
+.text
+
+.global hf_call
+hf_call:
+	hvc #0
+	ret
diff --git a/src/arch/aarch64/vm/shutdown.c b/src/arch/aarch64/vm/shutdown.c
new file mode 100644
index 0000000..8175cdf
--- /dev/null
+++ b/src/arch/aarch64/vm/shutdown.c
@@ -0,0 +1,15 @@
+#include "vm/shutdown.h"
+
+#include "psci.h"
+#include "vmapi/hf/call.h"
+
+/*
+ * Shutdown the system or exit emulation.
+ */
+noreturn void shutdown(void)
+{
+	hf_call(PSCI_SYSTEM_OFF, 0, 0, 0);
+	for (;;) {
+		/* This should never be reached. */
+	}
+}