Build api.c against the fake arch.

In order to have unit test, it at least needs to build so and the arch
interfaces and implement enough of the fake arch to make that happen.

Change-Id: I180885cedeef9e0323065cbe949f3d4161af3345
diff --git a/src/BUILD.gn b/src/BUILD.gn
index cad0a06..4a730b4 100644
--- a/src/BUILD.gn
+++ b/src/BUILD.gn
@@ -15,20 +15,41 @@
 # Hypervisor specific code.
 source_set("src") {
   sources = [
-    "api.c",
     "cpio.c",
-    "cpu.c",
     "load.c",
     "main.c",
+  ]
+
+  deps = [
+    ":common",
+    ":fdt",
+    ":memiter",
+    ":src_testable",
+  ]
+
+  if (is_debug) {
+    deps += [ ":dlog" ]
+  }
+}
+
+# One day, this will contain all the hypervisor's source but only once it can
+# all be built against the fake arch for unit tests. Utilities that are shared
+# e.g. with VM used in the VM tests have their own targets to facilitate
+# sharing.
+source_set("src_testable") {
+  sources = [
+    "alloc.c",
+    "api.c",
+    "cpu.c",
+    "fdt_handler.c",
+    "mm.c",
     "vm.c",
   ]
 
   deps = [
     ":common",
     ":fdt",
-    ":fdt_handler",
     ":memiter",
-    ":mm",
   ]
 
   if (is_debug) {
@@ -55,6 +76,7 @@
   ]
 }
 
+# Flattened Device Tree (FDT) utilities.
 source_set("fdt") {
   sources = [
     "fdt.c",
@@ -69,44 +91,17 @@
   }
 }
 
-source_set("fdt_handler") {
-  sources = [
-    "fdt_handler.c",
-  ]
-
-  deps = [
-    ":common",
-    ":fdt",
-  ]
-
-  if (is_debug) {
-    deps += [ ":dlog" ]
-  }
-}
-
 source_set("memiter") {
   sources = [
     "memiter.c",
   ]
 }
 
-source_set("mm") {
-  sources = [
-    "alloc.c",
-    "mm.c",
-  ]
-
-  deps = []
-
-  if (is_debug) {
-    deps += [ ":dlog" ]
-  }
-}
-
 executable("unit_tests") {
   testonly = true
   sources = [
     "abi_test.cc",
+    "api_test.cc",
     "fdt_handler_test.cc",
     "fdt_test.cc",
     "mm_test.cc",
@@ -132,9 +127,7 @@
     "-defsym=bin_end=600",
   ]
   deps = [
-    ":fdt",
-    ":fdt_handler",
-    ":mm",
+    ":src_testable",
     "//third_party:gtest_main",
   ]
 }
diff --git a/src/api_test.cc b/src/api_test.cc
new file mode 100644
index 0000000..fb6b8cb
--- /dev/null
+++ b/src/api_test.cc
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+extern "C" {
+#include "hf/api.h"
+}
+
+#include <gmock/gmock.h>
+
+namespace
+{
+using ::testing::Eq;
+
+TEST(api, vm_get_count)
+{
+	EXPECT_THAT(api_vm_get_count(), Eq(0));
+}
+
+} /* namespace */
diff --git a/src/arch/aarch64/inc/hf/arch/cpu.h b/src/arch/aarch64/inc/hf/arch/cpu.h
index d2c1a12..28061a6 100644
--- a/src/arch/aarch64/inc/hf/arch/cpu.h
+++ b/src/arch/aarch64/inc/hf/arch/cpu.h
@@ -116,6 +116,11 @@
 	r->r[0] = arg;
 }
 
+static inline void arch_regs_set_vcpu_index(struct arch_regs *r, uint32_t index)
+{
+	r->lazy.vmpidr_el2 = index;
+}
+
 static inline void arch_regs_set_retval(struct arch_regs *r, size_t v)
 {
 	r->r[0] = v;
diff --git a/src/arch/fake/inc/hf/arch/cpu.h b/src/arch/fake/inc/hf/arch/cpu.h
index 501c303..421a7f7 100644
--- a/src/arch/fake/inc/hf/arch/cpu.h
+++ b/src/arch/fake/inc/hf/arch/cpu.h
@@ -18,8 +18,11 @@
 
 #include <stdint.h>
 
+#include "hf/addr.h"
+
 struct arch_regs {
-	uint32_t r[5];
+	uint64_t r[5];
+	uint16_t vcpu_index;
 };
 
 static inline struct cpu *cpu(void)
@@ -37,3 +40,25 @@
 {
 	/* TODO */
 }
+
+static inline void arch_cpu_update(bool is_primary)
+{
+	/* TODO */
+	(void)is_primary;
+}
+
+static inline void arch_regs_init(struct arch_regs *r, ipaddr_t pc, size_t arg)
+{
+	/* TODO */
+	(void)pc;
+	r->r[0] = arg;
+}
+static inline void arch_regs_set_vcpu_index(struct arch_regs *r, uint16_t index)
+{
+	r->vcpu_index = index;
+}
+
+static inline void arch_regs_set_retval(struct arch_regs *r, size_t v)
+{
+	r->r[0] = v;
+}
diff --git a/src/arch/fake/inc/hf/arch/mm.h b/src/arch/fake/inc/hf/arch/mm.h
index 9c16cb7..053eafa 100644
--- a/src/arch/fake/inc/hf/arch/mm.h
+++ b/src/arch/fake/inc/hf/arch/mm.h
@@ -204,4 +204,9 @@
 	return true;
 }
 
-void arch_mm_set_vm(uint64_t vmid, paddr_t table);
+static inline void arch_mm_set_vm(uint64_t vmid, paddr_t table)
+{
+	/* TODO */
+	(void)vmid;
+	(void)table;
+}
diff --git a/src/cpu.c b/src/cpu.c
index 03b92e1..739fdcc 100644
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -133,8 +133,7 @@
 	sl_init(&vcpu->lock);
 	vcpu->vm = vm;
 	vcpu->state = vcpu_state_off;
-	/* TODO: This needs to be moved to arch-dependent code. */
-	vcpu->regs.lazy.vmpidr_el2 = vcpu - vm->vcpus;
+	arch_regs_set_vcpu_index(&vcpu->regs, vcpu - vm->vcpus);
 }
 
 void vcpu_on(struct vcpu *vcpu)