GNU Linux-libre 4.19.264-gnu1
[releases.git] / arch / arm / kernel / smccc-call.S
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 #include <linux/arm-smccc.h>
16
17 #include <asm/asm-offsets.h>
18 #include <asm/opcodes-sec.h>
19 #include <asm/opcodes-virt.h>
20 #include <asm/unwind.h>
21
22         /*
23          * Wrap c macros in asm macros to delay expansion until after the
24          * SMCCC asm macro is expanded.
25          */
26         .macro SMCCC_SMC
27         __SMC(0)
28         .endm
29
30         .macro SMCCC_HVC
31         __HVC(0)
32         .endm
33
34         .macro SMCCC instr
35 UNWIND( .fnstart)
36         mov     r12, sp
37         push    {r4-r7}
38 UNWIND( .save   {r4-r7})
39         ldm     r12, {r4-r7}
40         \instr
41         ldr     r4, [sp, #36]
42         cmp     r4, #0
43         beq     1f                      // No quirk structure
44         ldr     r5, [r4, #ARM_SMCCC_QUIRK_ID_OFFS]
45         cmp     r5, #ARM_SMCCC_QUIRK_QCOM_A6
46         bne     1f                      // No quirk present
47         str     r6, [r4, #ARM_SMCCC_QUIRK_STATE_OFFS]
48 1:      pop     {r4-r7}
49         ldr     r12, [sp, #(4 * 4)]
50         stm     r12, {r0-r3}
51         bx      lr
52 UNWIND( .fnend)
53         .endm
54
55 /*
56  * void smccc_smc(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  *                struct arm_smccc_quirk *quirk)
60  */
61 ENTRY(__arm_smccc_smc)
62         SMCCC SMCCC_SMC
63 ENDPROC(__arm_smccc_smc)
64
65 /*
66  * void smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2,
67  *                unsigned long a3, unsigned long a4, unsigned long a5,
68  *                unsigned long a6, unsigned long a7, struct arm_smccc_res *res,
69  *                struct arm_smccc_quirk *quirk)
70  */
71 ENTRY(__arm_smccc_hvc)
72         SMCCC SMCCC_HVC
73 ENDPROC(__arm_smccc_hvc)