@@ -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/
new file mode 100644
@@ -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");
+}
+
@@ -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 */