Move non-trivial SPCI helper functions to a source file.

Also stop manually copying hf_call.c to kernel module, instead
copying as part of build.

Change-Id: I646ac994b5dc3de0bb4ce501323ea36a8a6fe009
diff --git a/driver/linux b/driver/linux
index 06046ea..4cc539b 160000
--- a/driver/linux
+++ b/driver/linux
@@ -1 +1 @@
-Subproject commit 06046eac25b06e5c2a81672acffb64b81ea1eca1
+Subproject commit 4cc539b162643dc512fe997d748c54cfa0296d6f
diff --git a/inc/vmapi/hf/spci.h b/inc/vmapi/hf/spci.h
index b00fb46..30feb0e 100644
--- a/inc/vmapi/hf/spci.h
+++ b/inc/vmapi/hf/spci.h
@@ -18,14 +18,6 @@
 
 #include "hf/types.h"
 
-/*
- * Copied from hf/arch/std.h because we can't include Hafnium internal headers
- * here.
- */
-#ifndef align_up
-#define align_up(v, a) (((uintptr_t)(v) + (a - 1)) & ~(a - 1))
-#endif
-
 /* clang-format off */
 
 #define SPCI_LOW_32_ID  0x84000060
@@ -310,8 +302,6 @@
 	struct spci_memory_region_attributes attributes[];
 };
 
-/* TODO: Move all the functions below this line to a support library. */
-
 /**
  * Gets the constituent array for an `spci_memory_region`.
  */
@@ -323,20 +313,7 @@
 			   memory_region->constituent_offset);
 }
 
-/**
- * Helper method to fill in the information about the architected message.
- */
-static inline void spci_architected_message_init(void *message,
-						 enum spci_memory_share type)
-{
-	/* Fill the architected header. */
-	struct spci_architected_message_header *architected_header =
-		(struct spci_architected_message_header *)message;
-	architected_header->type = type;
-	architected_header->reserved[0] = 0;
-	architected_header->reserved[1] = 0;
-	architected_header->reserved[2] = 0;
-}
+void spci_architected_message_init(void *message, enum spci_memory_share type);
 
 /** Gets the spci_memory_region within an architected message. */
 static inline struct spci_memory_region *spci_get_memory_region(void *message)
@@ -346,92 +323,21 @@
 	return (struct spci_memory_region *)architected_header->payload;
 }
 
-/**
- * Initialises the given `spci_memory_region` and copies the constituent
- * information to it. Returns the length in bytes occupied by the data copied to
- * `memory_region` (attributes, constituents and memory region header size).
- */
-static inline uint32_t spci_memory_region_init(
+uint32_t spci_memory_region_init(
 	struct spci_memory_region *memory_region, spci_vm_id_t receiver,
 	const struct spci_memory_region_constituent constituents[],
 	uint32_t constituent_count, uint32_t tag,
 	enum spci_memory_access access, enum spci_memory_type type,
 	enum spci_memory_cacheability cacheability,
-	enum spci_memory_shareability shareability)
-{
-	uint32_t constituents_length =
-		constituent_count *
-		sizeof(struct spci_memory_region_constituent);
-	uint32_t index;
-	struct spci_memory_region_constituent *region_constituents;
-	uint16_t attributes = 0;
+	enum spci_memory_shareability shareability);
 
-	/* Set memory region's page attributes. */
-	spci_set_memory_access_attr(&attributes, access);
-	spci_set_memory_type_attr(&attributes, type);
-	spci_set_memory_cacheability_attr(&attributes, cacheability);
-	spci_set_memory_shareability_attr(&attributes, shareability);
-
-	memory_region->tag = tag;
-	memory_region->flags = 0;
-	memory_region->page_count = 0;
-	memory_region->constituent_count = constituent_count;
-	memory_region->attribute_count = 1;
-	memory_region->attributes[0].receiver = receiver;
-	memory_region->attributes[0].memory_attributes = attributes;
-
-	/*
-	 * Constituent offset must be aligned to a 64-bit boundary so that
-	 * 64-bit addresses can be copied without alignment faults.
-	 */
-	memory_region->constituent_offset = align_up(
-		sizeof(struct spci_memory_region) +
-			memory_region->attribute_count *
-				sizeof(struct spci_memory_region_attributes),
-		8);
-	region_constituents =
-		spci_memory_region_get_constituents(memory_region);
-
-	for (index = 0; index < constituent_count; index++) {
-		region_constituents[index] = constituents[index];
-		region_constituents[index].reserved = 0;
-		memory_region->page_count += constituents[index].page_count;
-	}
-
-	/*
-	 * TODO: Add assert ensuring that the specified message
-	 * length is not greater than SPCI_MSG_PAYLOAD_MAX.
-	 */
-
-	return memory_region->constituent_offset + constituents_length;
-}
-
-/**
- * Constructs an 'architected message' for SPCI memory sharing of the given
- * type.
- */
-static inline uint32_t spci_memory_init(
+uint32_t spci_memory_init(
 	void *message, enum spci_memory_share share_type, spci_vm_id_t receiver,
 	struct spci_memory_region_constituent *region_constituents,
 	uint32_t constituent_count, uint32_t tag,
 	enum spci_memory_access access, enum spci_memory_type type,
 	enum spci_memory_cacheability cacheability,
-	enum spci_memory_shareability shareability)
-{
-	uint32_t message_length =
-		sizeof(struct spci_architected_message_header);
-	struct spci_memory_region *memory_region =
-		spci_get_memory_region(message);
-
-	/* Fill in the details on the common message header. */
-	spci_architected_message_init(message, share_type);
-
-	/* Fill in memory region. */
-	message_length += spci_memory_region_init(
-		memory_region, receiver, region_constituents, constituent_count,
-		tag, access, type, cacheability, shareability);
-	return message_length;
-}
+	enum spci_memory_shareability shareability);
 
 /** Constructs an SPCI donate memory region message. */
 static inline uint32_t spci_memory_donate_init(
diff --git a/src/arch/aarch64/hftest/BUILD.gn b/src/arch/aarch64/hftest/BUILD.gn
index 044c874..a06ef24 100644
--- a/src/arch/aarch64/hftest/BUILD.gn
+++ b/src/arch/aarch64/hftest/BUILD.gn
@@ -21,13 +21,6 @@
   ]
 }
 
-# Make a call to the hypervisor from a VM.
-source_set("hf_call") {
-  sources = [
-    "hf_call.c",
-  ]
-}
-
 # Shutdown the system or exit emulation, start/stop CPUs.
 source_set("power_mgmt") {
   testonly = true
@@ -85,7 +78,7 @@
   ]
 
   deps = [
-    "//src/arch/aarch64/hftest:hf_call",
+    "//vmlib/aarch64:call",
   ]
 }
 
diff --git a/test/hftest/BUILD.gn b/test/hftest/BUILD.gn
index e23e817..81525a2 100644
--- a/test/hftest/BUILD.gn
+++ b/test/hftest/BUILD.gn
@@ -26,7 +26,7 @@
 
   deps = [
     ":hftest_standalone",
-    "//src/arch/${plat_arch}/hftest:hf_call",
+    "//vmlib/${plat_arch}:call",
   ]
 }
 
@@ -50,8 +50,8 @@
     "//src:std",
     "//src/arch/${plat_arch}:entry",
     "//src/arch/${plat_arch}/hftest:entry",
-    "//src/arch/${plat_arch}/hftest:hf_call",
     "//src/arch/${plat_arch}/hftest:power_mgmt",
+    "//vmlib/${plat_arch}:call",
   ]
 }
 
diff --git a/test/vmapi/primary_with_secondaries/BUILD.gn b/test/vmapi/primary_with_secondaries/BUILD.gn
index 801d8b6..54501f7 100644
--- a/test/vmapi/primary_with_secondaries/BUILD.gn
+++ b/test/vmapi/primary_with_secondaries/BUILD.gn
@@ -42,6 +42,7 @@
     ":util",
     "//src/arch/aarch64/hftest:registers",
     "//test/hftest:hftest_primary_vm",
+    "//vmlib",
   ]
 }
 
diff --git a/test/vmapi/primary_with_secondaries/services/BUILD.gn b/test/vmapi/primary_with_secondaries/services/BUILD.gn
index 732a655..dc395c0 100644
--- a/test/vmapi/primary_with_secondaries/services/BUILD.gn
+++ b/test/vmapi/primary_with_secondaries/services/BUILD.gn
@@ -95,6 +95,7 @@
   ]
   deps = [
     "//test/vmapi/primary_with_secondaries:util",
+    "//vmlib",
   ]
 
   sources = [
diff --git a/vmlib/BUILD.gn b/vmlib/BUILD.gn
new file mode 100644
index 0000000..9ba8c3d
--- /dev/null
+++ b/vmlib/BUILD.gn
@@ -0,0 +1,21 @@
+# Copyright 2019 The Hafnium Authors.
+#
+# 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.
+
+import("//build/toolchain/platform.gni")
+
+source_set("vmlib") {
+  sources = [
+    "spci.c",
+  ]
+}
diff --git a/vmlib/aarch64/BUILD.gn b/vmlib/aarch64/BUILD.gn
new file mode 100644
index 0000000..4ddd659
--- /dev/null
+++ b/vmlib/aarch64/BUILD.gn
@@ -0,0 +1,21 @@
+# Copyright 2019 The Hafnium Authors.
+#
+# 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.
+
+import("//build/toolchain/platform.gni")
+
+source_set("call") {
+  sources = [
+    "call.c",
+  ]
+}
diff --git a/src/arch/aarch64/hftest/hf_call.c b/vmlib/aarch64/call.c
similarity index 99%
rename from src/arch/aarch64/hftest/hf_call.c
rename to vmlib/aarch64/call.c
index a48a797..0c1a078 100644
--- a/src/arch/aarch64/hftest/hf_call.c
+++ b/vmlib/aarch64/call.c
@@ -15,6 +15,7 @@
  */
 
 #include "hf/call.h"
+
 #include "hf/spci.h"
 #include "hf/types.h"
 
diff --git a/vmlib/spci.c b/vmlib/spci.c
new file mode 100644
index 0000000..93fe88d
--- /dev/null
+++ b/vmlib/spci.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2019 The Hafnium Authors.
+ *
+ * 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.
+ */
+
+#include "hf/spci.h"
+
+#include "hf/types.h"
+
+/*
+ * Copied from hf/arch/std.h because we can't include Hafnium internal headers
+ * here.
+ */
+#ifndef align_up
+#define align_up(v, a) (((uintptr_t)(v) + ((a)-1)) & ~((a)-1))
+#endif
+
+/**
+ * Helper method to fill in the information about the architected message.
+ */
+void spci_architected_message_init(void *message, enum spci_memory_share type)
+{
+	/* Fill the architected header. */
+	struct spci_architected_message_header *architected_header =
+		(struct spci_architected_message_header *)message;
+	architected_header->type = type;
+	architected_header->reserved[0] = 0;
+	architected_header->reserved[1] = 0;
+	architected_header->reserved[2] = 0;
+}
+
+/**
+ * Initialises the given `spci_memory_region` and copies the constituent
+ * information to it. Returns the length in bytes occupied by the data copied to
+ * `memory_region` (attributes, constituents and memory region header size).
+ */
+uint32_t spci_memory_region_init(
+	struct spci_memory_region *memory_region, spci_vm_id_t receiver,
+	const struct spci_memory_region_constituent constituents[],
+	uint32_t constituent_count, uint32_t tag,
+	enum spci_memory_access access, enum spci_memory_type type,
+	enum spci_memory_cacheability cacheability,
+	enum spci_memory_shareability shareability)
+{
+	uint32_t constituents_length =
+		constituent_count *
+		sizeof(struct spci_memory_region_constituent);
+	uint32_t index;
+	struct spci_memory_region_constituent *region_constituents;
+	uint16_t attributes = 0;
+
+	/* Set memory region's page attributes. */
+	spci_set_memory_access_attr(&attributes, access);
+	spci_set_memory_type_attr(&attributes, type);
+	spci_set_memory_cacheability_attr(&attributes, cacheability);
+	spci_set_memory_shareability_attr(&attributes, shareability);
+
+	memory_region->tag = tag;
+	memory_region->flags = 0;
+	memory_region->page_count = 0;
+	memory_region->constituent_count = constituent_count;
+	memory_region->attribute_count = 1;
+	memory_region->attributes[0].receiver = receiver;
+	memory_region->attributes[0].memory_attributes = attributes;
+
+	/*
+	 * Constituent offset must be aligned to a 64-bit boundary so that
+	 * 64-bit addresses can be copied without alignment faults.
+	 */
+	memory_region->constituent_offset = align_up(
+		sizeof(struct spci_memory_region) +
+			memory_region->attribute_count *
+				sizeof(struct spci_memory_region_attributes),
+		8);
+	region_constituents =
+		spci_memory_region_get_constituents(memory_region);
+
+	for (index = 0; index < constituent_count; index++) {
+		region_constituents[index] = constituents[index];
+		region_constituents[index].reserved = 0;
+		memory_region->page_count += constituents[index].page_count;
+	}
+
+	/*
+	 * TODO: Add assert ensuring that the specified message
+	 * length is not greater than SPCI_MSG_PAYLOAD_MAX.
+	 */
+
+	return memory_region->constituent_offset + constituents_length;
+}
+
+/**
+ * Constructs an 'architected message' for SPCI memory sharing of the given
+ * type.
+ */
+uint32_t spci_memory_init(
+	void *message, enum spci_memory_share share_type, spci_vm_id_t receiver,
+	struct spci_memory_region_constituent *region_constituents,
+	uint32_t constituent_count, uint32_t tag,
+	enum spci_memory_access access, enum spci_memory_type type,
+	enum spci_memory_cacheability cacheability,
+	enum spci_memory_shareability shareability)
+{
+	uint32_t message_length =
+		sizeof(struct spci_architected_message_header);
+	struct spci_memory_region *memory_region =
+		spci_get_memory_region(message);
+
+	/* Fill in the details on the common message header. */
+	spci_architected_message_init(message, share_type);
+
+	/* Fill in memory region. */
+	message_length += spci_memory_region_init(
+		memory_region, receiver, region_constituents, constituent_count,
+		tag, access, type, cacheability, shareability);
+	return message_length;
+}