summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv8/fwcall.c
diff options
context:
space:
mode:
authorSergey Temerkhanov <s.temerkhanov@gmail.com>2015-10-14 09:55:46 -0700
committerTom Rini <trini@konsulko.com>2016-01-19 22:25:36 +0000
commita5b9fa30cebd91082f9fea93d7ef33812910da6a (patch)
tree7b3078e6a1328148acd2e5361bb4b73fb8bafa40 /arch/arm/cpu/armv8/fwcall.c
parent94f7ff36e521674a02145a3ff04b659c40122ba3 (diff)
downloadu-boot-imx-a5b9fa30cebd91082f9fea93d7ef33812910da6a.zip
u-boot-imx-a5b9fa30cebd91082f9fea93d7ef33812910da6a.tar.gz
u-boot-imx-a5b9fa30cebd91082f9fea93d7ef33812910da6a.tar.bz2
armv8: Add Secure Monitor/Hypervisor Call (SMC/HVC) infrastructure
This commit adds functions issuing calls to secure monitor or hypervisore. This allows using services such as Power State Coordination Interface (PSCI) provided by firmware, e.g. ARM Trusted Firmware (ATF) The SMC call can destroy all registers declared temporary by the calling conventions. The clobber list is "x0..x17" because of this Signed-off-by: Sergey Temerkhanov <s.temerkhanov@gmail.com> Signed-off-by: Corey Minyard <cminyard@mvista.com> Signed-off-by: Radha Mohan Chintakuntla <rchintakuntla@cavium.com> Reviewed-by: Simon Glass <sjg@chromium.org> Tested-by: Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
Diffstat (limited to 'arch/arm/cpu/armv8/fwcall.c')
-rw-r--r--arch/arm/cpu/armv8/fwcall.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv8/fwcall.c b/arch/arm/cpu/armv8/fwcall.c
new file mode 100644
index 0000000..9efcc5a
--- /dev/null
+++ b/arch/arm/cpu/armv8/fwcall.c
@@ -0,0 +1,75 @@
+/**
+ * (C) Copyright 2014, Cavium Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+**/
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <version.h>
+#include <asm/macro.h>
+#include <asm/system.h>
+
+/*
+ * Issue the hypervisor call
+ *
+ * x0~x7: input arguments
+ * x0~x3: output arguments
+ */
+void hvc_call(struct pt_regs *args)
+{
+ asm volatile(
+ "ldr x0, %0\n"
+ "ldr x1, %1\n"
+ "ldr x2, %2\n"
+ "ldr x3, %3\n"
+ "ldr x4, %4\n"
+ "ldr x5, %5\n"
+ "ldr x6, %6\n"
+ "ldr x7, %7\n"
+ "hvc #0\n"
+ "str x0, %0\n"
+ "str x1, %1\n"
+ "str x2, %2\n"
+ "str x3, %3\n"
+ : "+m" (args->regs[0]), "+m" (args->regs[1]),
+ "+m" (args->regs[2]), "+m" (args->regs[3])
+ : "m" (args->regs[4]), "m" (args->regs[5]),
+ "m" (args->regs[6]), "m" (args->regs[7])
+ : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
+ "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
+ "x16", "x17");
+}
+
+/*
+ * void smc_call(arg0, arg1...arg7)
+ *
+ * issue the secure monitor call
+ *
+ * x0~x7: input arguments
+ * x0~x3: output arguments
+ */
+
+void smc_call(struct pt_regs *args)
+{
+ asm volatile(
+ "ldr x0, %0\n"
+ "ldr x1, %1\n"
+ "ldr x2, %2\n"
+ "ldr x3, %3\n"
+ "ldr x4, %4\n"
+ "ldr x5, %5\n"
+ "ldr x6, %6\n"
+ "smc #0\n"
+ "str x0, %0\n"
+ "str x1, %1\n"
+ "str x2, %2\n"
+ "str x3, %3\n"
+ : "+m" (args->regs[0]), "+m" (args->regs[1]),
+ "+m" (args->regs[2]), "+m" (args->regs[3])
+ : "m" (args->regs[4]), "m" (args->regs[5]),
+ "m" (args->regs[6])
+ : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
+ "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
+ "x16", "x17");
+}