diff options
author | Jens Wiklander <jens.wiklander@linaro.org> | 2016-01-04 09:42:55 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2016-01-04 11:24:34 -0500 |
commit | b329f95d70f3f955093e9a2b18ac1ed3587a8f73 (patch) | |
tree | 08bd06d020ea58714eb914eeffce2dc2bf6619da | |
parent | 98dd64f34f47ce19b388d9015f767f48393a81eb (diff) |
ARM: 8479/2: add implementation for arm-smccc
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.
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>
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/kernel/armksyms.c | 6 | ||||
-rw-r--r-- | arch/arm/kernel/smccc-call.S | 62 |
4 files changed, 71 insertions, 0 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 6e644fd68ad2..54a8974222c9 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -37,6 +37,7 @@ config ARM | |||
37 | select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU | 37 | select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU |
38 | select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT) | 38 | select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT) |
39 | select HAVE_ARCH_TRACEHOOK | 39 | select HAVE_ARCH_TRACEHOOK |
40 | select HAVE_ARM_SMCCC if CPU_V7 | ||
40 | select HAVE_BPF_JIT | 41 | select HAVE_BPF_JIT |
41 | select HAVE_CC_STACKPROTECTOR | 42 | select HAVE_CC_STACKPROTECTOR |
42 | select HAVE_CONTEXT_TRACKING | 43 | select HAVE_CONTEXT_TRACKING |
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 3c789496297f..599c950468fc 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
@@ -91,4 +91,6 @@ obj-y += psci-call.o | |||
91 | obj-$(CONFIG_SMP) += psci_smp.o | 91 | obj-$(CONFIG_SMP) += psci_smp.o |
92 | endif | 92 | endif |
93 | 93 | ||
94 | obj-$(CONFIG_HAVE_ARM_SMCCC) += smccc-call.o | ||
95 | |||
94 | extra-y := $(head-y) vmlinux.lds | 96 | extra-y := $(head-y) vmlinux.lds |
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index f89811fb9a55..7e45f69a0ddc 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/syscalls.h> | 16 | #include <linux/syscalls.h> |
17 | #include <linux/uaccess.h> | 17 | #include <linux/uaccess.h> |
18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | #include <linux/arm-smccc.h> | ||
19 | 20 | ||
20 | #include <asm/checksum.h> | 21 | #include <asm/checksum.h> |
21 | #include <asm/ftrace.h> | 22 | #include <asm/ftrace.h> |
@@ -175,3 +176,8 @@ EXPORT_SYMBOL(__gnu_mcount_nc); | |||
175 | EXPORT_SYMBOL(__pv_phys_pfn_offset); | 176 | EXPORT_SYMBOL(__pv_phys_pfn_offset); |
176 | EXPORT_SYMBOL(__pv_offset); | 177 | EXPORT_SYMBOL(__pv_offset); |
177 | #endif | 178 | #endif |
179 | |||
180 | #ifdef CONFIG_HAVE_ARM_SMCCC | ||
181 | EXPORT_SYMBOL(arm_smccc_smc); | ||
182 | EXPORT_SYMBOL(arm_smccc_hvc); | ||
183 | #endif | ||
diff --git a/arch/arm/kernel/smccc-call.S b/arch/arm/kernel/smccc-call.S new file mode 100644 index 000000000000..2e48b674aab1 --- /dev/null +++ b/arch/arm/kernel/smccc-call.S | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2015, Linaro Limited | ||
3 | * | ||
4 | * This software is licensed under the terms of the GNU General Public | ||
5 | * License version 2, as published by the Free Software Foundation, and | ||
6 | * may be copied, distributed, and modified under those terms. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | */ | ||
14 | #include <linux/linkage.h> | ||
15 | |||
16 | #include <asm/opcodes-sec.h> | ||
17 | #include <asm/opcodes-virt.h> | ||
18 | #include <asm/unwind.h> | ||
19 | |||
20 | /* | ||
21 | * Wrap c macros in asm macros to delay expansion until after the | ||
22 | * SMCCC asm macro is expanded. | ||
23 | */ | ||
24 | .macro SMCCC_SMC | ||
25 | __SMC(0) | ||
26 | .endm | ||
27 | |||
28 | .macro SMCCC_HVC | ||
29 | __HVC(0) | ||
30 | .endm | ||
31 | |||
32 | .macro SMCCC instr | ||
33 | UNWIND( .fnstart) | ||
34 | mov r12, sp | ||
35 | push {r4-r7} | ||
36 | UNWIND( .save {r4-r7}) | ||
37 | ldm r12, {r4-r7} | ||
38 | \instr | ||
39 | pop {r4-r7} | ||
40 | ldr r12, [sp, #(4 * 4)] | ||
41 | stm r12, {r0-r3} | ||
42 | bx lr | ||
43 | UNWIND( .fnend) | ||
44 | .endm | ||
45 | |||
46 | /* | ||
47 | * void smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2, | ||
48 | * unsigned long a3, unsigned long a4, unsigned long a5, | ||
49 | * unsigned long a6, unsigned long a7, struct arm_smccc_res *res) | ||
50 | */ | ||
51 | ENTRY(arm_smccc_smc) | ||
52 | SMCCC SMCCC_SMC | ||
53 | ENDPROC(arm_smccc_smc) | ||
54 | |||
55 | /* | ||
56 | * void smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2, | ||
57 | * unsigned long a3, unsigned long a4, unsigned long a5, | ||
58 | * unsigned long a6, unsigned long a7, struct arm_smccc_res *res) | ||
59 | */ | ||
60 | ENTRY(arm_smccc_hvc) | ||
61 | SMCCC SMCCC_HVC | ||
62 | ENDPROC(arm_smccc_hvc) | ||