GNU Linux-libre 4.4.297-gnu1
[releases.git] / arch / arm64 / include / asm / assembler.h
1 /*
2  * Based on arch/arm/include/asm/assembler.h
3  *
4  * Copyright (C) 1996-2000 Russell King
5  * Copyright (C) 2012 ARM Ltd.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 #ifndef __ASSEMBLY__
20 #error "Only include this from assembly code"
21 #endif
22
23 #ifndef __ASM_ASSEMBLER_H
24 #define __ASM_ASSEMBLER_H
25
26 #include <asm/cputype.h>
27 #include <asm/ptrace.h>
28 #include <asm/thread_info.h>
29
30 /*
31  * Stack pushing/popping (register pairs only). Equivalent to store decrement
32  * before, load increment after.
33  */
34         .macro  push, xreg1, xreg2
35         stp     \xreg1, \xreg2, [sp, #-16]!
36         .endm
37
38         .macro  pop, xreg1, xreg2
39         ldp     \xreg1, \xreg2, [sp], #16
40         .endm
41
42 /*
43  * Enable and disable interrupts.
44  */
45         .macro  disable_irq
46         msr     daifset, #2
47         .endm
48
49         .macro  enable_irq
50         msr     daifclr, #2
51         .endm
52
53 /*
54  * Enable and disable debug exceptions.
55  */
56         .macro  disable_dbg
57         msr     daifset, #8
58         .endm
59
60         .macro  enable_dbg
61         msr     daifclr, #8
62         .endm
63
64         .macro  disable_step_tsk, flgs, tmp
65         tbz     \flgs, #TIF_SINGLESTEP, 9990f
66         mrs     \tmp, mdscr_el1
67         bic     \tmp, \tmp, #1
68         msr     mdscr_el1, \tmp
69         isb     // Synchronise with enable_dbg
70 9990:
71         .endm
72
73         .macro  enable_step_tsk, flgs, tmp
74         tbz     \flgs, #TIF_SINGLESTEP, 9990f
75         disable_dbg
76         mrs     \tmp, mdscr_el1
77         orr     \tmp, \tmp, #1
78         msr     mdscr_el1, \tmp
79 9990:
80         .endm
81
82 /*
83  * Enable both debug exceptions and interrupts. This is likely to be
84  * faster than two daifclr operations, since writes to this register
85  * are self-synchronising.
86  */
87         .macro  enable_dbg_and_irq
88         msr     daifclr, #(8 | 2)
89         .endm
90
91 /*
92  * SMP data memory barrier
93  */
94         .macro  smp_dmb, opt
95         dmb     \opt
96         .endm
97
98 #define USER(l, x...)                           \
99 9999:   x;                                      \
100         .section __ex_table,"a";                \
101         .align  3;                              \
102         .quad   9999b,l;                        \
103         .previous
104
105 /*
106  * Register aliases.
107  */
108 lr      .req    x30             // link register
109
110 /*
111  * Vector entry
112  */
113          .macro ventry  label
114         .align  7
115         b       \label
116         .endm
117
118 /*
119  * Select code when configured for BE.
120  */
121 #ifdef CONFIG_CPU_BIG_ENDIAN
122 #define CPU_BE(code...) code
123 #else
124 #define CPU_BE(code...)
125 #endif
126
127 /*
128  * Select code when configured for LE.
129  */
130 #ifdef CONFIG_CPU_BIG_ENDIAN
131 #define CPU_LE(code...)
132 #else
133 #define CPU_LE(code...) code
134 #endif
135
136 /*
137  * Define a macro that constructs a 64-bit value by concatenating two
138  * 32-bit registers. Note that on big endian systems the order of the
139  * registers is swapped.
140  */
141 #ifndef CONFIG_CPU_BIG_ENDIAN
142         .macro  regs_to_64, rd, lbits, hbits
143 #else
144         .macro  regs_to_64, rd, hbits, lbits
145 #endif
146         orr     \rd, \lbits, \hbits, lsl #32
147         .endm
148
149 /*
150  * Pseudo-ops for PC-relative adr/ldr/str <reg>, <symbol> where
151  * <symbol> is within the range +/- 4 GB of the PC when running
152  * in core kernel context. In module context, a movz/movk sequence
153  * is used, since modules may be loaded far away from the kernel
154  * when KASLR is in effect.
155  */
156         /*
157          * @dst: destination register (64 bit wide)
158          * @sym: name of the symbol
159          */
160         .macro  adr_l, dst, sym
161 #ifndef MODULE
162         adrp    \dst, \sym
163         add     \dst, \dst, :lo12:\sym
164 #else
165         movz    \dst, #:abs_g3:\sym
166         movk    \dst, #:abs_g2_nc:\sym
167         movk    \dst, #:abs_g1_nc:\sym
168         movk    \dst, #:abs_g0_nc:\sym
169 #endif
170         .endm
171
172         /*
173          * @dst: destination register (32 or 64 bit wide)
174          * @sym: name of the symbol
175          * @tmp: optional 64-bit scratch register to be used if <dst> is a
176          *       32-bit wide register, in which case it cannot be used to hold
177          *       the address
178          */
179         .macro  ldr_l, dst, sym, tmp=
180 #ifndef MODULE
181         .ifb    \tmp
182         adrp    \dst, \sym
183         ldr     \dst, [\dst, :lo12:\sym]
184         .else
185         adrp    \tmp, \sym
186         ldr     \dst, [\tmp, :lo12:\sym]
187         .endif
188 #else
189         .ifb    \tmp
190         adr_l   \dst, \sym
191         ldr     \dst, [\dst]
192         .else
193         adr_l   \tmp, \sym
194         ldr     \dst, [\tmp]
195         .endif
196 #endif
197         .endm
198
199         /*
200          * @src: source register (32 or 64 bit wide)
201          * @sym: name of the symbol
202          * @tmp: mandatory 64-bit scratch register to calculate the address
203          *       while <src> needs to be preserved.
204          */
205         .macro  str_l, src, sym, tmp
206 #ifndef MODULE
207         adrp    \tmp, \sym
208         str     \src, [\tmp, :lo12:\sym]
209 #else
210         adr_l   \tmp, \sym
211         str     \src, [\tmp]
212 #endif
213         .endm
214
215 /*
216  * Annotate a function as position independent, i.e., safe to be called before
217  * the kernel virtual mapping is activated.
218  */
219 #define ENDPIPROC(x)                    \
220         .globl  __pi_##x;               \
221         .type   __pi_##x, %function;    \
222         .set    __pi_##x, x;            \
223         .size   __pi_##x, . - x;        \
224         ENDPROC(x)
225
226         /*
227          * mov_q - move an immediate constant into a 64-bit register using
228          *         between 2 and 4 movz/movk instructions (depending on the
229          *         magnitude and sign of the operand)
230          */
231         .macro  mov_q, reg, val
232         .if (((\val) >> 31) == 0 || ((\val) >> 31) == 0x1ffffffff)
233         movz    \reg, :abs_g1_s:\val
234         .else
235         .if (((\val) >> 47) == 0 || ((\val) >> 47) == 0x1ffff)
236         movz    \reg, :abs_g2_s:\val
237         .else
238         movz    \reg, :abs_g3:\val
239         movk    \reg, :abs_g2_nc:\val
240         .endif
241         movk    \reg, :abs_g1_nc:\val
242         .endif
243         movk    \reg, :abs_g0_nc:\val
244         .endm
245
246 /*
247  * Check the MIDR_EL1 of the current CPU for a given model and a range of
248  * variant/revision. See asm/cputype.h for the macros used below.
249  *
250  *      model:          MIDR_CPU_PART of CPU
251  *      rv_min:         Minimum of MIDR_CPU_VAR_REV()
252  *      rv_max:         Maximum of MIDR_CPU_VAR_REV()
253  *      res:            Result register.
254  *      tmp1, tmp2, tmp3: Temporary registers
255  *
256  * Corrupts: res, tmp1, tmp2, tmp3
257  * Returns:  0, if the CPU id doesn't match. Non-zero otherwise
258  */
259         .macro  cpu_midr_match model, rv_min, rv_max, res, tmp1, tmp2, tmp3
260         mrs             \res, midr_el1
261         mov_q           \tmp1, (MIDR_REVISION_MASK | MIDR_VARIANT_MASK)
262         mov_q           \tmp2, MIDR_CPU_PART_MASK
263         and             \tmp3, \res, \tmp2      // Extract model
264         and             \tmp1, \res, \tmp1      // rev & variant
265         mov_q           \tmp2, \model
266         cmp             \tmp3, \tmp2
267         cset            \res, eq
268         cbz             \res, .Ldone\@          // Model matches ?
269
270         .if (\rv_min != 0)                      // Skip min check if rv_min == 0
271         mov_q           \tmp3, \rv_min
272         cmp             \tmp1, \tmp3
273         cset            \res, ge
274         .endif                                  // \rv_min != 0
275         /* Skip rv_max check if rv_min == rv_max && rv_min != 0 */
276         .if ((\rv_min != \rv_max) || \rv_min == 0)
277         mov_q           \tmp2, \rv_max
278         cmp             \tmp1, \tmp2
279         cset            \tmp2, le
280         and             \res, \res, \tmp2
281         .endif
282 .Ldone\@:
283         .endm
284
285 #endif  /* __ASM_ASSEMBLER_H */