
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 --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 */