[U-Boot] [RESUBMIT PATCH v3 3/8] armv8: Add SMC calls infrastructure

Sergey Temerkhanov
2015-08-13T16:51:23Z

This commit adds functions issuing calls to firmware. This allows
to use services such as PSCI provided by firmware, e.g. 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>

---

Changes in v3:
- Fixed clobber lists (thanks to Corey)

Changes in v2: None

arch/arm/cpu/armv8/Makefile | 1 +
arch/arm/cpu/armv8/fwcall.c | 77 +++++++++++++++++++++++++++++++++++++++++++
arch/arm/include/asm/system.h | 8 +++++
3 files changed, 86 insertions(+)
create mode 100644 arch/arm/cpu/armv8/fwcall.c

diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile
index 6466ebb..39a6ce7 100644
--- a/arch/arm/cpu/armv8/Makefile
+++ b/arch/arm/cpu/armv8/Makefile
@@ -14,6 +14,7 @@ obj-y += exceptions.o
obj-y += cache.o
obj-y += tlb.o
obj-y += transition.o
+obj-y += fwcall.o

obj-$(CONFIG_FSL_LSCH3) += fsl-lsch3/
obj-$(CONFIG_ARCH_ZYNQMP) += zynqmp/
diff --git a/arch/arm/cpu/armv8/fwcall.c b/arch/arm/cpu/armv8/fwcall.c
new file mode 100644
index 0000000..ff0caba
--- /dev/null
+++ b/arch/arm/cpu/armv8/fwcall.c
@@ -0,0 +1,77 @@
+/**
+ * (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>
+
+#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
+
+/*
+ * void hvc_call(arg0, arg1...arg7)
+ *
+ * issue the hypervisor call
+ *
+ * x0~x7: argument list
+ */
+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: argument list
+ */
+
+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");
+}
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 9288541..a4cefda 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -1,6 +1,9 @@
#ifndef __ASM_ARM_SYSTEM_H
#define __ASM_ARM_SYSTEM_H

+#include <common.h>
+#include <linux/compiler.h>
+
#ifdef CONFIG_ARM64

/*
@@ -104,6 +107,11 @@ void smp_kick_all_cpus(void);

void flush_l3_cache(void);

+#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
+
+void hvc_call(struct pt_regs *args);
+void smc_call(struct pt_regs *args);
+
#endif /* __ASSEMBLY__ */

#else /* CONFIG_ARM64 */
--
2.2.0