Implement SMC calls with inline assembly rather than a separate file.
This will let the compiler do better optimisation by inlining the call,
rather than having to put parameters on the stack.
Bug: 132429380
Change-Id: I51d57460d2826dc24b6f6b01ceebdf5f053c5c17
diff --git a/src/arch/aarch64/BUILD.gn b/src/arch/aarch64/BUILD.gn
index 8abc3d0..f9cbc5a 100644
--- a/src/arch/aarch64/BUILD.gn
+++ b/src/arch/aarch64/BUILD.gn
@@ -43,6 +43,5 @@
source_set("smc") {
sources = [
"smc.c",
- "smc_internal.S",
]
}
diff --git a/src/arch/aarch64/smc.c b/src/arch/aarch64/smc.c
index 7772fdf..d1c4bb8 100644
--- a/src/arch/aarch64/smc.c
+++ b/src/arch/aarch64/smc.c
@@ -18,9 +18,36 @@
#include <stdint.h>
-smc_res_t smc_internal(uint32_t func, uint64_t arg0, uint64_t arg1,
- uint64_t arg2, uint64_t arg3, uint64_t arg4,
- uint64_t arg5, uint32_t caller_id);
+static smc_res_t smc_internal(uint32_t func, uint64_t arg0, uint64_t arg1,
+ uint64_t arg2, uint64_t arg3, uint64_t arg4,
+ uint64_t arg5, uint32_t caller_id)
+{
+ register uint64_t r0 __asm__("x0") = func;
+ register uint64_t r1 __asm__("x1") = arg0;
+ register uint64_t r2 __asm__("x2") = arg1;
+ register uint64_t r3 __asm__("x3") = arg2;
+ register uint64_t r4 __asm__("x4") = arg3;
+ register uint64_t r5 __asm__("x5") = arg4;
+ register uint64_t r6 __asm__("x6") = arg5;
+ register uint64_t r7 __asm__("x7") = caller_id;
+
+ /*
+ * 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(
+ "smc #0"
+ : /* Output registers, also used as inputs ('+' constraint). */
+ "+r"(r0), "+r"(r1), "+r"(r2), "+r"(r3), "+r"(r4), "+r"(r5),
+ "+r"(r6), "+r"(r7)
+ :
+ : /* Clobber registers. */
+ "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16",
+ "x17");
+
+ return (smc_res_t){.res0 = r0, .res1 = r1, .res2 = r2, .res3 = r3};
+}
smc_res_t smc32(uint32_t func, uint32_t arg0, uint32_t arg1, uint32_t arg2,
uint32_t arg3, uint32_t arg4, uint32_t arg5, uint32_t caller_id)
diff --git a/src/arch/aarch64/smc_internal.S b/src/arch/aarch64/smc_internal.S
deleted file mode 100644
index 093fade..0000000
--- a/src/arch/aarch64/smc_internal.S
+++ /dev/null
@@ -1,26 +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.smc_internal, "ax"
-.global smc_internal
-
-smc_internal:
- str x8, [sp, #-16] ! /* AArch64 stack pointer alignment is 16 bytes */
- smc #0
- ldr x8, [sp], #16
- stp x0, x1, [x8]
- stp x2, x3, [x8, #16]
- ret