UPSTREAM: ARM: 8479/2: add implementation for arm-smccc
authorJens Wiklander <jens.wiklander@linaro.org>
Mon, 4 Jan 2016 14:42:55 +0000 (15:42 +0100)
committerHuang, Tao <huangtao@rock-chips.com>
Wed, 10 Aug 2016 10:19:57 +0000 (18:19 +0800)
Adds implementation for arm-smccc and enables CONFIG_HAVE_SMCCC for
architectures that may support arm-smccc. It's the responsibility of the
caller to know if the SMC instruction is supported by the platform.

Change-Id: Ic7fd73fb040a900cfaa783f70c29b1d984da558b
Reviewed-by: Lars Persson <lars.persson@axis.com>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
(cherry picked from commit b329f95d70f3f955093e9a2b18ac1ed3587a8f73)

arch/arm/Kconfig
arch/arm/kernel/Makefile
arch/arm/kernel/armksyms.c
arch/arm/kernel/smccc-call.S [new file with mode: 0644]

index dcc4339b6928a5c0650c0bb6fdecda68af64cddc..4c3c400410f2221077ef53235c47faefac11c3b2 100644 (file)
@@ -38,6 +38,7 @@ config ARM
        select HAVE_ARCH_MMAP_RND_BITS if MMU
        select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT)
        select HAVE_ARCH_TRACEHOOK
+       select HAVE_ARM_SMCCC if CPU_V7
        select HAVE_BPF_JIT
        select HAVE_CC_STACKPROTECTOR
        select HAVE_CONTEXT_TRACKING
index af9e59bf3831b9fd648d095c2070209b1e97677d..d2d00424f044bf44cd21d4d0a91ef449d135d853 100644 (file)
@@ -92,4 +92,6 @@ obj-y                         += psci-call.o
 obj-$(CONFIG_SMP)              += psci_smp.o
 endif
 
+obj-$(CONFIG_HAVE_ARM_SMCCC)   += smccc-call.o
+
 extra-y := $(head-y) vmlinux.lds
index f89811fb9a55f3a490c3633ef99ef52745c58129..7e45f69a0ddc9d0ef3b04c145195cf1b4ad7d84b 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/syscalls.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
+#include <linux/arm-smccc.h>
 
 #include <asm/checksum.h>
 #include <asm/ftrace.h>
@@ -175,3 +176,8 @@ EXPORT_SYMBOL(__gnu_mcount_nc);
 EXPORT_SYMBOL(__pv_phys_pfn_offset);
 EXPORT_SYMBOL(__pv_offset);
 #endif
+
+#ifdef CONFIG_HAVE_ARM_SMCCC
+EXPORT_SYMBOL(arm_smccc_smc);
+EXPORT_SYMBOL(arm_smccc_hvc);
+#endif
diff --git a/arch/arm/kernel/smccc-call.S b/arch/arm/kernel/smccc-call.S
new file mode 100644 (file)
index 0000000..2e48b67
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/linkage.h>
+
+#include <asm/opcodes-sec.h>
+#include <asm/opcodes-virt.h>
+#include <asm/unwind.h>
+
+       /*
+        * Wrap c macros in asm macros to delay expansion until after the
+        * SMCCC asm macro is expanded.
+        */
+       .macro SMCCC_SMC
+       __SMC(0)
+       .endm
+
+       .macro SMCCC_HVC
+       __HVC(0)
+       .endm
+
+       .macro SMCCC instr
+UNWIND(        .fnstart)
+       mov     r12, sp
+       push    {r4-r7}
+UNWIND(        .save   {r4-r7})
+       ldm     r12, {r4-r7}
+       \instr
+       pop     {r4-r7}
+       ldr     r12, [sp, #(4 * 4)]
+       stm     r12, {r0-r3}
+       bx      lr
+UNWIND(        .fnend)
+       .endm
+
+/*
+ * void smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2,
+ *               unsigned long a3, unsigned long a4, unsigned long a5,
+ *               unsigned long a6, unsigned long a7, struct arm_smccc_res *res)
+ */
+ENTRY(arm_smccc_smc)
+       SMCCC SMCCC_SMC
+ENDPROC(arm_smccc_smc)
+
+/*
+ * void smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2,
+ *               unsigned long a3, unsigned long a4, unsigned long a5,
+ *               unsigned long a6, unsigned long a7, struct arm_smccc_res *res)
+ */
+ENTRY(arm_smccc_hvc)
+       SMCCC SMCCC_HVC
+ENDPROC(arm_smccc_hvc)