Implement hf_call with assembly inline rather than entire function.

This should allow the compiler to inline and better optimise it.

Bug: 132429380
Change-Id: I4adf5adbc59ebd71bb2b8effecb07ce16bca49cc
diff --git a/driver/linux b/driver/linux
index 3e669bc..474c439 160000
--- a/driver/linux
+++ b/driver/linux
@@ -1 +1 @@
-Subproject commit 3e669bc98235cbaf0addc3176711ad28b62a17eb
+Subproject commit 474c4396e72c33692b0cd40eeb0f3ac7c76fe0f7
diff --git a/inc/vmapi/hf/call.h b/inc/vmapi/hf/call.h
index d04b914..67c8e35 100644
--- a/inc/vmapi/hf/call.h
+++ b/inc/vmapi/hf/call.h
@@ -46,7 +46,7 @@
  * This function must be implemented to trigger the architecture specific
  * mechanism to call to the hypervisor.
  */
-int64_t hf_call(size_t arg0, size_t arg1, size_t arg2, size_t arg3);
+int64_t hf_call(uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3);
 
 /**
  * Returns the VM's own ID.
diff --git a/src/arch/aarch64/hftest/BUILD.gn b/src/arch/aarch64/hftest/BUILD.gn
index e5bcedc..78d89c7 100644
--- a/src/arch/aarch64/hftest/BUILD.gn
+++ b/src/arch/aarch64/hftest/BUILD.gn
@@ -24,7 +24,7 @@
 # Make a call to the hypervisor from a VM.
 source_set("hf_call") {
   sources = [
-    "hf_call.S",
+    "hf_call.c",
   ]
 }
 
diff --git a/src/arch/aarch64/hftest/hf_call.S b/src/arch/aarch64/hftest/hf_call.S
deleted file mode 100644
index 86dd7a6..0000000
--- a/src/arch/aarch64/hftest/hf_call.S
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-.section .text.hf_call, "ax"
-.global hf_call
-hf_call:
-	hvc #0
-	ret
diff --git a/src/arch/aarch64/hftest/hf_call.c b/src/arch/aarch64/hftest/hf_call.c
new file mode 100644
index 0000000..3085ff1
--- /dev/null
+++ b/src/arch/aarch64/hftest/hf_call.c
@@ -0,0 +1,42 @@
+/*
+ * 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/call.h"
+#include "hf/types.h"
+
+int64_t hf_call(uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3)
+{
+	register uint64_t r0 __asm__("x0") = arg0;
+	register uint64_t r1 __asm__("x1") = arg1;
+	register uint64_t r2 __asm__("x2") = arg2;
+	register uint64_t r3 __asm__("x3") = arg3;
+
+	/*
+	 * We currently implement SMCCC 1.0, which specifies that the callee can
+	 * use x4–x17 as scratch registers. If we move to SMCCC 1.1 then this
+	 * will change.
+	 */
+	__asm__ volatile(
+		"hvc #0"
+		: /* Output registers, also used as inputs ('+' constraint). */
+		"+r"(r0), "+r"(r1), "+r"(r2), "+r"(r3)
+		:
+		: /* Clobber registers. */
+		"x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13",
+		"x14", "x15", "x16", "x17");
+
+	return r0;
+}