diff mbox

[U-Boot,2/7] armv8:Add SMC calls infrastructure

Message ID 1429226111-29823-3-git-send-email-s.temerkhanov@gmail.com
State Changes Requested
Delegated to: Albert ARIBAUD
Headers show

Commit Message

Sergey Temerkhanov April 16, 2015, 11:15 p.m. UTC
This commit adds functions issuing calls to firmware. This allows
to use services such as PSCI provided by firmware, e.g. ATF

Signed-off-by: Sergey Temerkhanov <s.temerkhanov@gmail.com>
Signed-off-by: Radha Mohan Chintakuntla <rchintakuntla@cavium.com>
---
 arch/arm/cpu/armv8/Makefile   |  1 +
 arch/arm/cpu/armv8/fwcall.c   | 79 +++++++++++++++++++++++++++++++++++++++++++
 arch/arm/include/asm/system.h |  8 +++++
 3 files changed, 88 insertions(+)
 create mode 100644 arch/arm/cpu/armv8/fwcall.c
diff mbox

Patch

diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile
index dee5e25..208d012 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_TARGET_XILINX_ZYNQMP) += zynqmp/
diff --git a/arch/arm/cpu/armv8/fwcall.c b/arch/arm/cpu/armv8/fwcall.c
new file mode 100644
index 0000000..fde3c06
--- /dev/null
+++ b/arch/arm/cpu/armv8/fwcall.c
@@ -0,0 +1,79 @@ 
+/**
+ * (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[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");
+}
+
+/*
+ * 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"
+		"ldr x7, %7\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[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");
+}
+
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index b778a6c..aac15cc 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
 
 /*
@@ -85,6 +88,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 */