xref: /OK3568_Linux_fs/kernel/arch/arm64/include/asm/assembler.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Based on arch/arm/include/asm/assembler.h, arch/arm/mm/proc-macros.S
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 1996-2000 Russell King
6*4882a593Smuzhiyun  * Copyright (C) 2012 ARM Ltd.
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun #ifndef __ASSEMBLY__
9*4882a593Smuzhiyun #error "Only include this from assembly code"
10*4882a593Smuzhiyun #endif
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #ifndef __ASM_ASSEMBLER_H
13*4882a593Smuzhiyun #define __ASM_ASSEMBLER_H
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun #include <asm-generic/export.h>
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #include <asm/asm-offsets.h>
18*4882a593Smuzhiyun #include <asm/asm-bug.h>
19*4882a593Smuzhiyun #include <asm/alternative.h>
20*4882a593Smuzhiyun #include <asm/cpufeature.h>
21*4882a593Smuzhiyun #include <asm/cputype.h>
22*4882a593Smuzhiyun #include <asm/debug-monitors.h>
23*4882a593Smuzhiyun #include <asm/page.h>
24*4882a593Smuzhiyun #include <asm/pgtable-hwdef.h>
25*4882a593Smuzhiyun #include <asm/ptrace.h>
26*4882a593Smuzhiyun #include <asm/thread_info.h>
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun 	/*
29*4882a593Smuzhiyun 	 * Provide a wxN alias for each wN register so what we can paste a xN
30*4882a593Smuzhiyun 	 * reference after a 'w' to obtain the 32-bit version.
31*4882a593Smuzhiyun 	 */
32*4882a593Smuzhiyun 	.irp	n,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
33*4882a593Smuzhiyun 	wx\n	.req	w\n
34*4882a593Smuzhiyun 	.endr
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun 	.macro save_and_disable_daif, flags
37*4882a593Smuzhiyun 	mrs	\flags, daif
38*4882a593Smuzhiyun 	msr	daifset, #0xf
39*4882a593Smuzhiyun 	.endm
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun 	.macro disable_daif
42*4882a593Smuzhiyun 	msr	daifset, #0xf
43*4882a593Smuzhiyun 	.endm
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun 	.macro enable_daif
46*4882a593Smuzhiyun 	msr	daifclr, #0xf
47*4882a593Smuzhiyun 	.endm
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 	.macro	restore_daif, flags:req
50*4882a593Smuzhiyun 	msr	daif, \flags
51*4882a593Smuzhiyun 	.endm
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun 	/* IRQ is the lowest priority flag, unconditionally unmask the rest. */
54*4882a593Smuzhiyun 	.macro enable_da_f
55*4882a593Smuzhiyun 	msr	daifclr, #(8 | 4 | 1)
56*4882a593Smuzhiyun 	.endm
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun /*
59*4882a593Smuzhiyun  * Save/restore interrupts.
60*4882a593Smuzhiyun  */
61*4882a593Smuzhiyun 	.macro	save_and_disable_irq, flags
62*4882a593Smuzhiyun 	mrs	\flags, daif
63*4882a593Smuzhiyun 	msr	daifset, #2
64*4882a593Smuzhiyun 	.endm
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	.macro	restore_irq, flags
67*4882a593Smuzhiyun 	msr	daif, \flags
68*4882a593Smuzhiyun 	.endm
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun 	.macro	enable_dbg
71*4882a593Smuzhiyun 	msr	daifclr, #8
72*4882a593Smuzhiyun 	.endm
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	.macro	disable_step_tsk, flgs, tmp
75*4882a593Smuzhiyun 	tbz	\flgs, #TIF_SINGLESTEP, 9990f
76*4882a593Smuzhiyun 	mrs	\tmp, mdscr_el1
77*4882a593Smuzhiyun 	bic	\tmp, \tmp, #DBG_MDSCR_SS
78*4882a593Smuzhiyun 	msr	mdscr_el1, \tmp
79*4882a593Smuzhiyun 	isb	// Synchronise with enable_dbg
80*4882a593Smuzhiyun 9990:
81*4882a593Smuzhiyun 	.endm
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	/* call with daif masked */
84*4882a593Smuzhiyun 	.macro	enable_step_tsk, flgs, tmp
85*4882a593Smuzhiyun 	tbz	\flgs, #TIF_SINGLESTEP, 9990f
86*4882a593Smuzhiyun 	mrs	\tmp, mdscr_el1
87*4882a593Smuzhiyun 	orr	\tmp, \tmp, #DBG_MDSCR_SS
88*4882a593Smuzhiyun 	msr	mdscr_el1, \tmp
89*4882a593Smuzhiyun 9990:
90*4882a593Smuzhiyun 	.endm
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun /*
93*4882a593Smuzhiyun  * RAS Error Synchronization barrier
94*4882a593Smuzhiyun  */
95*4882a593Smuzhiyun 	.macro  esb
96*4882a593Smuzhiyun #ifdef CONFIG_ARM64_RAS_EXTN
97*4882a593Smuzhiyun 	hint    #16
98*4882a593Smuzhiyun #else
99*4882a593Smuzhiyun 	nop
100*4882a593Smuzhiyun #endif
101*4882a593Smuzhiyun 	.endm
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun /*
104*4882a593Smuzhiyun  * Value prediction barrier
105*4882a593Smuzhiyun  */
106*4882a593Smuzhiyun 	.macro	csdb
107*4882a593Smuzhiyun 	hint	#20
108*4882a593Smuzhiyun 	.endm
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun /*
111*4882a593Smuzhiyun  * Clear Branch History instruction
112*4882a593Smuzhiyun  */
113*4882a593Smuzhiyun 	.macro clearbhb
114*4882a593Smuzhiyun 	hint	#22
115*4882a593Smuzhiyun 	.endm
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun /*
118*4882a593Smuzhiyun  * Speculation barrier
119*4882a593Smuzhiyun  */
120*4882a593Smuzhiyun 	.macro	sb
121*4882a593Smuzhiyun alternative_if_not ARM64_HAS_SB
122*4882a593Smuzhiyun 	dsb	nsh
123*4882a593Smuzhiyun 	isb
124*4882a593Smuzhiyun alternative_else
125*4882a593Smuzhiyun 	SB_BARRIER_INSN
126*4882a593Smuzhiyun 	nop
127*4882a593Smuzhiyun alternative_endif
128*4882a593Smuzhiyun 	.endm
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun /*
131*4882a593Smuzhiyun  * NOP sequence
132*4882a593Smuzhiyun  */
133*4882a593Smuzhiyun 	.macro	nops, num
134*4882a593Smuzhiyun 	.rept	\num
135*4882a593Smuzhiyun 	nop
136*4882a593Smuzhiyun 	.endr
137*4882a593Smuzhiyun 	.endm
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun /*
140*4882a593Smuzhiyun  * Emit an entry into the exception table
141*4882a593Smuzhiyun  */
142*4882a593Smuzhiyun 	.macro		_asm_extable, from, to
143*4882a593Smuzhiyun 	.pushsection	__ex_table, "a"
144*4882a593Smuzhiyun 	.align		3
145*4882a593Smuzhiyun 	.long		(\from - .), (\to - .)
146*4882a593Smuzhiyun 	.popsection
147*4882a593Smuzhiyun 	.endm
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun #define USER(l, x...)				\
150*4882a593Smuzhiyun 9999:	x;					\
151*4882a593Smuzhiyun 	_asm_extable	9999b, l
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun /*
154*4882a593Smuzhiyun  * Register aliases.
155*4882a593Smuzhiyun  */
156*4882a593Smuzhiyun lr	.req	x30		// link register
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun /*
159*4882a593Smuzhiyun  * Vector entry
160*4882a593Smuzhiyun  */
161*4882a593Smuzhiyun 	 .macro	ventry	label
162*4882a593Smuzhiyun 	.align	7
163*4882a593Smuzhiyun 	b	\label
164*4882a593Smuzhiyun 	.endm
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun /*
167*4882a593Smuzhiyun  * Select code when configured for BE.
168*4882a593Smuzhiyun  */
169*4882a593Smuzhiyun #ifdef CONFIG_CPU_BIG_ENDIAN
170*4882a593Smuzhiyun #define CPU_BE(code...) code
171*4882a593Smuzhiyun #else
172*4882a593Smuzhiyun #define CPU_BE(code...)
173*4882a593Smuzhiyun #endif
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun /*
176*4882a593Smuzhiyun  * Select code when configured for LE.
177*4882a593Smuzhiyun  */
178*4882a593Smuzhiyun #ifdef CONFIG_CPU_BIG_ENDIAN
179*4882a593Smuzhiyun #define CPU_LE(code...)
180*4882a593Smuzhiyun #else
181*4882a593Smuzhiyun #define CPU_LE(code...) code
182*4882a593Smuzhiyun #endif
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun /*
185*4882a593Smuzhiyun  * Define a macro that constructs a 64-bit value by concatenating two
186*4882a593Smuzhiyun  * 32-bit registers. Note that on big endian systems the order of the
187*4882a593Smuzhiyun  * registers is swapped.
188*4882a593Smuzhiyun  */
189*4882a593Smuzhiyun #ifndef CONFIG_CPU_BIG_ENDIAN
190*4882a593Smuzhiyun 	.macro	regs_to_64, rd, lbits, hbits
191*4882a593Smuzhiyun #else
192*4882a593Smuzhiyun 	.macro	regs_to_64, rd, hbits, lbits
193*4882a593Smuzhiyun #endif
194*4882a593Smuzhiyun 	orr	\rd, \lbits, \hbits, lsl #32
195*4882a593Smuzhiyun 	.endm
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun /*
198*4882a593Smuzhiyun  * Pseudo-ops for PC-relative adr/ldr/str <reg>, <symbol> where
199*4882a593Smuzhiyun  * <symbol> is within the range +/- 4 GB of the PC.
200*4882a593Smuzhiyun  */
201*4882a593Smuzhiyun 	/*
202*4882a593Smuzhiyun 	 * @dst: destination register (64 bit wide)
203*4882a593Smuzhiyun 	 * @sym: name of the symbol
204*4882a593Smuzhiyun 	 */
205*4882a593Smuzhiyun 	.macro	adr_l, dst, sym
206*4882a593Smuzhiyun 	adrp	\dst, \sym
207*4882a593Smuzhiyun 	add	\dst, \dst, :lo12:\sym
208*4882a593Smuzhiyun 	.endm
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun 	/*
211*4882a593Smuzhiyun 	 * @dst: destination register (32 or 64 bit wide)
212*4882a593Smuzhiyun 	 * @sym: name of the symbol
213*4882a593Smuzhiyun 	 * @tmp: optional 64-bit scratch register to be used if <dst> is a
214*4882a593Smuzhiyun 	 *       32-bit wide register, in which case it cannot be used to hold
215*4882a593Smuzhiyun 	 *       the address
216*4882a593Smuzhiyun 	 */
217*4882a593Smuzhiyun 	.macro	ldr_l, dst, sym, tmp=
218*4882a593Smuzhiyun 	.ifb	\tmp
219*4882a593Smuzhiyun 	adrp	\dst, \sym
220*4882a593Smuzhiyun 	ldr	\dst, [\dst, :lo12:\sym]
221*4882a593Smuzhiyun 	.else
222*4882a593Smuzhiyun 	adrp	\tmp, \sym
223*4882a593Smuzhiyun 	ldr	\dst, [\tmp, :lo12:\sym]
224*4882a593Smuzhiyun 	.endif
225*4882a593Smuzhiyun 	.endm
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	/*
228*4882a593Smuzhiyun 	 * @src: source register (32 or 64 bit wide)
229*4882a593Smuzhiyun 	 * @sym: name of the symbol
230*4882a593Smuzhiyun 	 * @tmp: mandatory 64-bit scratch register to calculate the address
231*4882a593Smuzhiyun 	 *       while <src> needs to be preserved.
232*4882a593Smuzhiyun 	 */
233*4882a593Smuzhiyun 	.macro	str_l, src, sym, tmp
234*4882a593Smuzhiyun 	adrp	\tmp, \sym
235*4882a593Smuzhiyun 	str	\src, [\tmp, :lo12:\sym]
236*4882a593Smuzhiyun 	.endm
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 	/*
239*4882a593Smuzhiyun 	 * @dst: destination register
240*4882a593Smuzhiyun 	 */
241*4882a593Smuzhiyun #if defined(__KVM_NVHE_HYPERVISOR__) || defined(__KVM_VHE_HYPERVISOR__)
242*4882a593Smuzhiyun 	.macro	this_cpu_offset, dst
243*4882a593Smuzhiyun 	mrs	\dst, tpidr_el2
244*4882a593Smuzhiyun 	.endm
245*4882a593Smuzhiyun #else
246*4882a593Smuzhiyun 	.macro	this_cpu_offset, dst
247*4882a593Smuzhiyun alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
248*4882a593Smuzhiyun 	mrs	\dst, tpidr_el1
249*4882a593Smuzhiyun alternative_else
250*4882a593Smuzhiyun 	mrs	\dst, tpidr_el2
251*4882a593Smuzhiyun alternative_endif
252*4882a593Smuzhiyun 	.endm
253*4882a593Smuzhiyun #endif
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	/*
256*4882a593Smuzhiyun 	 * @dst: Result of per_cpu(sym, smp_processor_id()) (can be SP)
257*4882a593Smuzhiyun 	 * @sym: The name of the per-cpu variable
258*4882a593Smuzhiyun 	 * @tmp: scratch register
259*4882a593Smuzhiyun 	 */
260*4882a593Smuzhiyun 	.macro adr_this_cpu, dst, sym, tmp
261*4882a593Smuzhiyun 	adrp	\tmp, \sym
262*4882a593Smuzhiyun 	add	\dst, \tmp, #:lo12:\sym
263*4882a593Smuzhiyun 	this_cpu_offset \tmp
264*4882a593Smuzhiyun 	add	\dst, \dst, \tmp
265*4882a593Smuzhiyun 	.endm
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun 	/*
268*4882a593Smuzhiyun 	 * @dst: Result of READ_ONCE(per_cpu(sym, smp_processor_id()))
269*4882a593Smuzhiyun 	 * @sym: The name of the per-cpu variable
270*4882a593Smuzhiyun 	 * @tmp: scratch register
271*4882a593Smuzhiyun 	 */
272*4882a593Smuzhiyun 	.macro ldr_this_cpu dst, sym, tmp
273*4882a593Smuzhiyun 	adr_l	\dst, \sym
274*4882a593Smuzhiyun 	this_cpu_offset \tmp
275*4882a593Smuzhiyun 	ldr	\dst, [\dst, \tmp]
276*4882a593Smuzhiyun 	.endm
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun /*
279*4882a593Smuzhiyun  * vma_vm_mm - get mm pointer from vma pointer (vma->vm_mm)
280*4882a593Smuzhiyun  */
281*4882a593Smuzhiyun 	.macro	vma_vm_mm, rd, rn
282*4882a593Smuzhiyun 	ldr	\rd, [\rn, #VMA_VM_MM]
283*4882a593Smuzhiyun 	.endm
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun /*
286*4882a593Smuzhiyun  * read_ctr - read CTR_EL0. If the system has mismatched register fields,
287*4882a593Smuzhiyun  * provide the system wide safe value from arm64_ftr_reg_ctrel0.sys_val
288*4882a593Smuzhiyun  */
289*4882a593Smuzhiyun 	.macro	read_ctr, reg
290*4882a593Smuzhiyun #ifndef __KVM_NVHE_HYPERVISOR__
291*4882a593Smuzhiyun alternative_if_not ARM64_MISMATCHED_CACHE_TYPE
292*4882a593Smuzhiyun 	mrs	\reg, ctr_el0			// read CTR
293*4882a593Smuzhiyun 	nop
294*4882a593Smuzhiyun alternative_else
295*4882a593Smuzhiyun 	ldr_l	\reg, arm64_ftr_reg_ctrel0 + ARM64_FTR_SYSVAL
296*4882a593Smuzhiyun alternative_endif
297*4882a593Smuzhiyun #else
298*4882a593Smuzhiyun alternative_if_not ARM64_KVM_PROTECTED_MODE
299*4882a593Smuzhiyun 	ASM_BUG()
300*4882a593Smuzhiyun alternative_else_nop_endif
301*4882a593Smuzhiyun alternative_cb kvm_compute_final_ctr_el0
302*4882a593Smuzhiyun 	movz	\reg, #0
303*4882a593Smuzhiyun 	movk	\reg, #0, lsl #16
304*4882a593Smuzhiyun 	movk	\reg, #0, lsl #32
305*4882a593Smuzhiyun 	movk	\reg, #0, lsl #48
306*4882a593Smuzhiyun alternative_cb_end
307*4882a593Smuzhiyun #endif
308*4882a593Smuzhiyun 	.endm
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun /*
312*4882a593Smuzhiyun  * raw_dcache_line_size - get the minimum D-cache line size on this CPU
313*4882a593Smuzhiyun  * from the CTR register.
314*4882a593Smuzhiyun  */
315*4882a593Smuzhiyun 	.macro	raw_dcache_line_size, reg, tmp
316*4882a593Smuzhiyun 	mrs	\tmp, ctr_el0			// read CTR
317*4882a593Smuzhiyun 	ubfm	\tmp, \tmp, #16, #19		// cache line size encoding
318*4882a593Smuzhiyun 	mov	\reg, #4			// bytes per word
319*4882a593Smuzhiyun 	lsl	\reg, \reg, \tmp		// actual cache line size
320*4882a593Smuzhiyun 	.endm
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun /*
323*4882a593Smuzhiyun  * dcache_line_size - get the safe D-cache line size across all CPUs
324*4882a593Smuzhiyun  */
325*4882a593Smuzhiyun 	.macro	dcache_line_size, reg, tmp
326*4882a593Smuzhiyun 	read_ctr	\tmp
327*4882a593Smuzhiyun 	ubfm		\tmp, \tmp, #16, #19	// cache line size encoding
328*4882a593Smuzhiyun 	mov		\reg, #4		// bytes per word
329*4882a593Smuzhiyun 	lsl		\reg, \reg, \tmp	// actual cache line size
330*4882a593Smuzhiyun 	.endm
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun /*
333*4882a593Smuzhiyun  * raw_icache_line_size - get the minimum I-cache line size on this CPU
334*4882a593Smuzhiyun  * from the CTR register.
335*4882a593Smuzhiyun  */
336*4882a593Smuzhiyun 	.macro	raw_icache_line_size, reg, tmp
337*4882a593Smuzhiyun 	mrs	\tmp, ctr_el0			// read CTR
338*4882a593Smuzhiyun 	and	\tmp, \tmp, #0xf		// cache line size encoding
339*4882a593Smuzhiyun 	mov	\reg, #4			// bytes per word
340*4882a593Smuzhiyun 	lsl	\reg, \reg, \tmp		// actual cache line size
341*4882a593Smuzhiyun 	.endm
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun /*
344*4882a593Smuzhiyun  * icache_line_size - get the safe I-cache line size across all CPUs
345*4882a593Smuzhiyun  */
346*4882a593Smuzhiyun 	.macro	icache_line_size, reg, tmp
347*4882a593Smuzhiyun 	read_ctr	\tmp
348*4882a593Smuzhiyun 	and		\tmp, \tmp, #0xf	// cache line size encoding
349*4882a593Smuzhiyun 	mov		\reg, #4		// bytes per word
350*4882a593Smuzhiyun 	lsl		\reg, \reg, \tmp	// actual cache line size
351*4882a593Smuzhiyun 	.endm
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun /*
354*4882a593Smuzhiyun  * tcr_set_t0sz - update TCR.T0SZ so that we can load the ID map
355*4882a593Smuzhiyun  */
356*4882a593Smuzhiyun 	.macro	tcr_set_t0sz, valreg, t0sz
357*4882a593Smuzhiyun 	bfi	\valreg, \t0sz, #TCR_T0SZ_OFFSET, #TCR_TxSZ_WIDTH
358*4882a593Smuzhiyun 	.endm
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun /*
361*4882a593Smuzhiyun  * tcr_set_t1sz - update TCR.T1SZ
362*4882a593Smuzhiyun  */
363*4882a593Smuzhiyun 	.macro	tcr_set_t1sz, valreg, t1sz
364*4882a593Smuzhiyun 	bfi	\valreg, \t1sz, #TCR_T1SZ_OFFSET, #TCR_TxSZ_WIDTH
365*4882a593Smuzhiyun 	.endm
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun /*
368*4882a593Smuzhiyun  * tcr_compute_pa_size - set TCR.(I)PS to the highest supported
369*4882a593Smuzhiyun  * ID_AA64MMFR0_EL1.PARange value
370*4882a593Smuzhiyun  *
371*4882a593Smuzhiyun  *	tcr:		register with the TCR_ELx value to be updated
372*4882a593Smuzhiyun  *	pos:		IPS or PS bitfield position
373*4882a593Smuzhiyun  *	tmp{0,1}:	temporary registers
374*4882a593Smuzhiyun  */
375*4882a593Smuzhiyun 	.macro	tcr_compute_pa_size, tcr, pos, tmp0, tmp1
376*4882a593Smuzhiyun 	mrs	\tmp0, ID_AA64MMFR0_EL1
377*4882a593Smuzhiyun 	// Narrow PARange to fit the PS field in TCR_ELx
378*4882a593Smuzhiyun 	ubfx	\tmp0, \tmp0, #ID_AA64MMFR0_PARANGE_SHIFT, #3
379*4882a593Smuzhiyun 	mov	\tmp1, #ID_AA64MMFR0_PARANGE_MAX
380*4882a593Smuzhiyun 	cmp	\tmp0, \tmp1
381*4882a593Smuzhiyun 	csel	\tmp0, \tmp1, \tmp0, hi
382*4882a593Smuzhiyun 	bfi	\tcr, \tmp0, \pos, #3
383*4882a593Smuzhiyun 	.endm
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun /*
386*4882a593Smuzhiyun  * Macro to perform a data cache maintenance for the interval
387*4882a593Smuzhiyun  * [kaddr, kaddr + size)
388*4882a593Smuzhiyun  *
389*4882a593Smuzhiyun  * 	op:		operation passed to dc instruction
390*4882a593Smuzhiyun  * 	domain:		domain used in dsb instruciton
391*4882a593Smuzhiyun  * 	kaddr:		starting virtual address of the region
392*4882a593Smuzhiyun  * 	size:		size of the region
393*4882a593Smuzhiyun  * 	Corrupts:	kaddr, size, tmp1, tmp2
394*4882a593Smuzhiyun  */
395*4882a593Smuzhiyun 	.macro __dcache_op_workaround_clean_cache, op, kaddr
396*4882a593Smuzhiyun alternative_if_not ARM64_WORKAROUND_CLEAN_CACHE
397*4882a593Smuzhiyun 	dc	\op, \kaddr
398*4882a593Smuzhiyun alternative_else
399*4882a593Smuzhiyun 	dc	civac, \kaddr
400*4882a593Smuzhiyun alternative_endif
401*4882a593Smuzhiyun 	.endm
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 	.macro dcache_by_line_op op, domain, kaddr, size, tmp1, tmp2
404*4882a593Smuzhiyun 	dcache_line_size \tmp1, \tmp2
405*4882a593Smuzhiyun 	add	\size, \kaddr, \size
406*4882a593Smuzhiyun 	sub	\tmp2, \tmp1, #1
407*4882a593Smuzhiyun 	bic	\kaddr, \kaddr, \tmp2
408*4882a593Smuzhiyun 9998:
409*4882a593Smuzhiyun 	.ifc	\op, cvau
410*4882a593Smuzhiyun 	__dcache_op_workaround_clean_cache \op, \kaddr
411*4882a593Smuzhiyun 	.else
412*4882a593Smuzhiyun 	.ifc	\op, cvac
413*4882a593Smuzhiyun 	__dcache_op_workaround_clean_cache \op, \kaddr
414*4882a593Smuzhiyun 	.else
415*4882a593Smuzhiyun 	.ifc	\op, cvap
416*4882a593Smuzhiyun 	sys	3, c7, c12, 1, \kaddr	// dc cvap
417*4882a593Smuzhiyun 	.else
418*4882a593Smuzhiyun 	.ifc	\op, cvadp
419*4882a593Smuzhiyun 	sys	3, c7, c13, 1, \kaddr	// dc cvadp
420*4882a593Smuzhiyun 	.else
421*4882a593Smuzhiyun 	dc	\op, \kaddr
422*4882a593Smuzhiyun 	.endif
423*4882a593Smuzhiyun 	.endif
424*4882a593Smuzhiyun 	.endif
425*4882a593Smuzhiyun 	.endif
426*4882a593Smuzhiyun 	add	\kaddr, \kaddr, \tmp1
427*4882a593Smuzhiyun 	cmp	\kaddr, \size
428*4882a593Smuzhiyun 	b.lo	9998b
429*4882a593Smuzhiyun 	dsb	\domain
430*4882a593Smuzhiyun 	.endm
431*4882a593Smuzhiyun 
432*4882a593Smuzhiyun /*
433*4882a593Smuzhiyun  * Macro to perform an instruction cache maintenance for the interval
434*4882a593Smuzhiyun  * [start, end)
435*4882a593Smuzhiyun  *
436*4882a593Smuzhiyun  * 	start, end:	virtual addresses describing the region
437*4882a593Smuzhiyun  *	label:		A label to branch to on user fault.
438*4882a593Smuzhiyun  * 	Corrupts:	tmp1, tmp2
439*4882a593Smuzhiyun  */
440*4882a593Smuzhiyun 	.macro invalidate_icache_by_line start, end, tmp1, tmp2, label
441*4882a593Smuzhiyun 	icache_line_size \tmp1, \tmp2
442*4882a593Smuzhiyun 	sub	\tmp2, \tmp1, #1
443*4882a593Smuzhiyun 	bic	\tmp2, \start, \tmp2
444*4882a593Smuzhiyun 9997:
445*4882a593Smuzhiyun USER(\label, ic	ivau, \tmp2)			// invalidate I line PoU
446*4882a593Smuzhiyun 	add	\tmp2, \tmp2, \tmp1
447*4882a593Smuzhiyun 	cmp	\tmp2, \end
448*4882a593Smuzhiyun 	b.lo	9997b
449*4882a593Smuzhiyun 	dsb	ish
450*4882a593Smuzhiyun 	isb
451*4882a593Smuzhiyun 	.endm
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun /*
454*4882a593Smuzhiyun  * reset_pmuserenr_el0 - reset PMUSERENR_EL0 if PMUv3 present
455*4882a593Smuzhiyun  */
456*4882a593Smuzhiyun 	.macro	reset_pmuserenr_el0, tmpreg
457*4882a593Smuzhiyun 	mrs	\tmpreg, id_aa64dfr0_el1
458*4882a593Smuzhiyun 	sbfx	\tmpreg, \tmpreg, #ID_AA64DFR0_PMUVER_SHIFT, #4
459*4882a593Smuzhiyun 	cmp	\tmpreg, #1			// Skip if no PMU present
460*4882a593Smuzhiyun 	b.lt	9000f
461*4882a593Smuzhiyun 	msr	pmuserenr_el0, xzr		// Disable PMU access from EL0
462*4882a593Smuzhiyun 9000:
463*4882a593Smuzhiyun 	.endm
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun /*
466*4882a593Smuzhiyun  * reset_amuserenr_el0 - reset AMUSERENR_EL0 if AMUv1 present
467*4882a593Smuzhiyun  */
468*4882a593Smuzhiyun 	.macro	reset_amuserenr_el0, tmpreg
469*4882a593Smuzhiyun 	mrs	\tmpreg, id_aa64pfr0_el1	// Check ID_AA64PFR0_EL1
470*4882a593Smuzhiyun 	ubfx	\tmpreg, \tmpreg, #ID_AA64PFR0_AMU_SHIFT, #4
471*4882a593Smuzhiyun 	cbz	\tmpreg, .Lskip_\@		// Skip if no AMU present
472*4882a593Smuzhiyun 	msr_s	SYS_AMUSERENR_EL0, xzr		// Disable AMU access from EL0
473*4882a593Smuzhiyun .Lskip_\@:
474*4882a593Smuzhiyun 	.endm
475*4882a593Smuzhiyun /*
476*4882a593Smuzhiyun  * copy_page - copy src to dest using temp registers t1-t8
477*4882a593Smuzhiyun  */
478*4882a593Smuzhiyun 	.macro copy_page dest:req src:req t1:req t2:req t3:req t4:req t5:req t6:req t7:req t8:req
479*4882a593Smuzhiyun 9998:	ldp	\t1, \t2, [\src]
480*4882a593Smuzhiyun 	ldp	\t3, \t4, [\src, #16]
481*4882a593Smuzhiyun 	ldp	\t5, \t6, [\src, #32]
482*4882a593Smuzhiyun 	ldp	\t7, \t8, [\src, #48]
483*4882a593Smuzhiyun 	add	\src, \src, #64
484*4882a593Smuzhiyun 	stnp	\t1, \t2, [\dest]
485*4882a593Smuzhiyun 	stnp	\t3, \t4, [\dest, #16]
486*4882a593Smuzhiyun 	stnp	\t5, \t6, [\dest, #32]
487*4882a593Smuzhiyun 	stnp	\t7, \t8, [\dest, #48]
488*4882a593Smuzhiyun 	add	\dest, \dest, #64
489*4882a593Smuzhiyun 	tst	\src, #(PAGE_SIZE - 1)
490*4882a593Smuzhiyun 	b.ne	9998b
491*4882a593Smuzhiyun 	.endm
492*4882a593Smuzhiyun 
493*4882a593Smuzhiyun /*
494*4882a593Smuzhiyun  * Annotate a function as being unsuitable for kprobes.
495*4882a593Smuzhiyun  */
496*4882a593Smuzhiyun #ifdef CONFIG_KPROBES
497*4882a593Smuzhiyun #define NOKPROBE(x)				\
498*4882a593Smuzhiyun 	.pushsection "_kprobe_blacklist", "aw";	\
499*4882a593Smuzhiyun 	.quad	x;				\
500*4882a593Smuzhiyun 	.popsection;
501*4882a593Smuzhiyun #else
502*4882a593Smuzhiyun #define NOKPROBE(x)
503*4882a593Smuzhiyun #endif
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
506*4882a593Smuzhiyun #define EXPORT_SYMBOL_NOKASAN(name)
507*4882a593Smuzhiyun #else
508*4882a593Smuzhiyun #define EXPORT_SYMBOL_NOKASAN(name)	EXPORT_SYMBOL(name)
509*4882a593Smuzhiyun #endif
510*4882a593Smuzhiyun 
511*4882a593Smuzhiyun 	/*
512*4882a593Smuzhiyun 	 * Emit a 64-bit absolute little endian symbol reference in a way that
513*4882a593Smuzhiyun 	 * ensures that it will be resolved at build time, even when building a
514*4882a593Smuzhiyun 	 * PIE binary. This requires cooperation from the linker script, which
515*4882a593Smuzhiyun 	 * must emit the lo32/hi32 halves individually.
516*4882a593Smuzhiyun 	 */
517*4882a593Smuzhiyun 	.macro	le64sym, sym
518*4882a593Smuzhiyun 	.long	\sym\()_lo32
519*4882a593Smuzhiyun 	.long	\sym\()_hi32
520*4882a593Smuzhiyun 	.endm
521*4882a593Smuzhiyun 
522*4882a593Smuzhiyun 	/*
523*4882a593Smuzhiyun 	 * mov_q - move an immediate constant into a 64-bit register using
524*4882a593Smuzhiyun 	 *         between 2 and 4 movz/movk instructions (depending on the
525*4882a593Smuzhiyun 	 *         magnitude and sign of the operand)
526*4882a593Smuzhiyun 	 */
527*4882a593Smuzhiyun 	.macro	mov_q, reg, val
528*4882a593Smuzhiyun 	.if (((\val) >> 31) == 0 || ((\val) >> 31) == 0x1ffffffff)
529*4882a593Smuzhiyun 	movz	\reg, :abs_g1_s:\val
530*4882a593Smuzhiyun 	.else
531*4882a593Smuzhiyun 	.if (((\val) >> 47) == 0 || ((\val) >> 47) == 0x1ffff)
532*4882a593Smuzhiyun 	movz	\reg, :abs_g2_s:\val
533*4882a593Smuzhiyun 	.else
534*4882a593Smuzhiyun 	movz	\reg, :abs_g3:\val
535*4882a593Smuzhiyun 	movk	\reg, :abs_g2_nc:\val
536*4882a593Smuzhiyun 	.endif
537*4882a593Smuzhiyun 	movk	\reg, :abs_g1_nc:\val
538*4882a593Smuzhiyun 	.endif
539*4882a593Smuzhiyun 	movk	\reg, :abs_g0_nc:\val
540*4882a593Smuzhiyun 	.endm
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun /*
543*4882a593Smuzhiyun  * Return the current task_struct.
544*4882a593Smuzhiyun  */
545*4882a593Smuzhiyun 	.macro	get_current_task, rd
546*4882a593Smuzhiyun 	mrs	\rd, sp_el0
547*4882a593Smuzhiyun 	.endm
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun /*
550*4882a593Smuzhiyun  * Offset ttbr1 to allow for 48-bit kernel VAs set with 52-bit PTRS_PER_PGD.
551*4882a593Smuzhiyun  * orr is used as it can cover the immediate value (and is idempotent).
552*4882a593Smuzhiyun  * In future this may be nop'ed out when dealing with 52-bit kernel VAs.
553*4882a593Smuzhiyun  * 	ttbr: Value of ttbr to set, modified.
554*4882a593Smuzhiyun  */
555*4882a593Smuzhiyun 	.macro	offset_ttbr1, ttbr, tmp
556*4882a593Smuzhiyun #ifdef CONFIG_ARM64_VA_BITS_52
557*4882a593Smuzhiyun 	mrs_s	\tmp, SYS_ID_AA64MMFR2_EL1
558*4882a593Smuzhiyun 	and	\tmp, \tmp, #(0xf << ID_AA64MMFR2_LVA_SHIFT)
559*4882a593Smuzhiyun 	cbnz	\tmp, .Lskipoffs_\@
560*4882a593Smuzhiyun 	orr	\ttbr, \ttbr, #TTBR1_BADDR_4852_OFFSET
561*4882a593Smuzhiyun .Lskipoffs_\@ :
562*4882a593Smuzhiyun #endif
563*4882a593Smuzhiyun 	.endm
564*4882a593Smuzhiyun 
565*4882a593Smuzhiyun /*
566*4882a593Smuzhiyun  * Perform the reverse of offset_ttbr1.
567*4882a593Smuzhiyun  * bic is used as it can cover the immediate value and, in future, won't need
568*4882a593Smuzhiyun  * to be nop'ed out when dealing with 52-bit kernel VAs.
569*4882a593Smuzhiyun  */
570*4882a593Smuzhiyun 	.macro	restore_ttbr1, ttbr
571*4882a593Smuzhiyun #ifdef CONFIG_ARM64_VA_BITS_52
572*4882a593Smuzhiyun 	bic	\ttbr, \ttbr, #TTBR1_BADDR_4852_OFFSET
573*4882a593Smuzhiyun #endif
574*4882a593Smuzhiyun 	.endm
575*4882a593Smuzhiyun 
576*4882a593Smuzhiyun /*
577*4882a593Smuzhiyun  * Arrange a physical address in a TTBR register, taking care of 52-bit
578*4882a593Smuzhiyun  * addresses.
579*4882a593Smuzhiyun  *
580*4882a593Smuzhiyun  * 	phys:	physical address, preserved
581*4882a593Smuzhiyun  * 	ttbr:	returns the TTBR value
582*4882a593Smuzhiyun  */
583*4882a593Smuzhiyun 	.macro	phys_to_ttbr, ttbr, phys
584*4882a593Smuzhiyun #ifdef CONFIG_ARM64_PA_BITS_52
585*4882a593Smuzhiyun 	orr	\ttbr, \phys, \phys, lsr #46
586*4882a593Smuzhiyun 	and	\ttbr, \ttbr, #TTBR_BADDR_MASK_52
587*4882a593Smuzhiyun #else
588*4882a593Smuzhiyun 	mov	\ttbr, \phys
589*4882a593Smuzhiyun #endif
590*4882a593Smuzhiyun 	.endm
591*4882a593Smuzhiyun 
592*4882a593Smuzhiyun 	.macro	phys_to_pte, pte, phys
593*4882a593Smuzhiyun #ifdef CONFIG_ARM64_PA_BITS_52
594*4882a593Smuzhiyun 	/*
595*4882a593Smuzhiyun 	 * We assume \phys is 64K aligned and this is guaranteed by only
596*4882a593Smuzhiyun 	 * supporting this configuration with 64K pages.
597*4882a593Smuzhiyun 	 */
598*4882a593Smuzhiyun 	orr	\pte, \phys, \phys, lsr #36
599*4882a593Smuzhiyun 	and	\pte, \pte, #PTE_ADDR_MASK
600*4882a593Smuzhiyun #else
601*4882a593Smuzhiyun 	mov	\pte, \phys
602*4882a593Smuzhiyun #endif
603*4882a593Smuzhiyun 	.endm
604*4882a593Smuzhiyun 
605*4882a593Smuzhiyun 	.macro	pte_to_phys, phys, pte
606*4882a593Smuzhiyun #ifdef CONFIG_ARM64_PA_BITS_52
607*4882a593Smuzhiyun 	ubfiz	\phys, \pte, #(48 - 16 - 12), #16
608*4882a593Smuzhiyun 	bfxil	\phys, \pte, #16, #32
609*4882a593Smuzhiyun 	lsl	\phys, \phys, #16
610*4882a593Smuzhiyun #else
611*4882a593Smuzhiyun 	and	\phys, \pte, #PTE_ADDR_MASK
612*4882a593Smuzhiyun #endif
613*4882a593Smuzhiyun 	.endm
614*4882a593Smuzhiyun 
615*4882a593Smuzhiyun /*
616*4882a593Smuzhiyun  * tcr_clear_errata_bits - Clear TCR bits that trigger an errata on this CPU.
617*4882a593Smuzhiyun  */
618*4882a593Smuzhiyun 	.macro	tcr_clear_errata_bits, tcr, tmp1, tmp2
619*4882a593Smuzhiyun #ifdef CONFIG_FUJITSU_ERRATUM_010001
620*4882a593Smuzhiyun 	mrs	\tmp1, midr_el1
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun 	mov_q	\tmp2, MIDR_FUJITSU_ERRATUM_010001_MASK
623*4882a593Smuzhiyun 	and	\tmp1, \tmp1, \tmp2
624*4882a593Smuzhiyun 	mov_q	\tmp2, MIDR_FUJITSU_ERRATUM_010001
625*4882a593Smuzhiyun 	cmp	\tmp1, \tmp2
626*4882a593Smuzhiyun 	b.ne	10f
627*4882a593Smuzhiyun 
628*4882a593Smuzhiyun 	mov_q	\tmp2, TCR_CLEAR_FUJITSU_ERRATUM_010001
629*4882a593Smuzhiyun 	bic	\tcr, \tcr, \tmp2
630*4882a593Smuzhiyun 10:
631*4882a593Smuzhiyun #endif /* CONFIG_FUJITSU_ERRATUM_010001 */
632*4882a593Smuzhiyun 	.endm
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun /**
635*4882a593Smuzhiyun  * Errata workaround prior to disable MMU. Insert an ISB immediately prior
636*4882a593Smuzhiyun  * to executing the MSR that will change SCTLR_ELn[M] from a value of 1 to 0.
637*4882a593Smuzhiyun  */
638*4882a593Smuzhiyun 	.macro pre_disable_mmu_workaround
639*4882a593Smuzhiyun #ifdef CONFIG_QCOM_FALKOR_ERRATUM_E1041
640*4882a593Smuzhiyun 	isb
641*4882a593Smuzhiyun #endif
642*4882a593Smuzhiyun 	.endm
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun 	/*
645*4882a593Smuzhiyun 	 * frame_push - Push @regcount callee saved registers to the stack,
646*4882a593Smuzhiyun 	 *              starting at x19, as well as x29/x30, and set x29 to
647*4882a593Smuzhiyun 	 *              the new value of sp. Add @extra bytes of stack space
648*4882a593Smuzhiyun 	 *              for locals.
649*4882a593Smuzhiyun 	 */
650*4882a593Smuzhiyun 	.macro		frame_push, regcount:req, extra
651*4882a593Smuzhiyun 	__frame		st, \regcount, \extra
652*4882a593Smuzhiyun 	.endm
653*4882a593Smuzhiyun 
654*4882a593Smuzhiyun 	/*
655*4882a593Smuzhiyun 	 * frame_pop  - Pop the callee saved registers from the stack that were
656*4882a593Smuzhiyun 	 *              pushed in the most recent call to frame_push, as well
657*4882a593Smuzhiyun 	 *              as x29/x30 and any extra stack space that may have been
658*4882a593Smuzhiyun 	 *              allocated.
659*4882a593Smuzhiyun 	 */
660*4882a593Smuzhiyun 	.macro		frame_pop
661*4882a593Smuzhiyun 	__frame		ld
662*4882a593Smuzhiyun 	.endm
663*4882a593Smuzhiyun 
664*4882a593Smuzhiyun 	.macro		__frame_regs, reg1, reg2, op, num
665*4882a593Smuzhiyun 	.if		.Lframe_regcount == \num
666*4882a593Smuzhiyun 	\op\()r		\reg1, [sp, #(\num + 1) * 8]
667*4882a593Smuzhiyun 	.elseif		.Lframe_regcount > \num
668*4882a593Smuzhiyun 	\op\()p		\reg1, \reg2, [sp, #(\num + 1) * 8]
669*4882a593Smuzhiyun 	.endif
670*4882a593Smuzhiyun 	.endm
671*4882a593Smuzhiyun 
672*4882a593Smuzhiyun 	.macro		__frame, op, regcount, extra=0
673*4882a593Smuzhiyun 	.ifc		\op, st
674*4882a593Smuzhiyun 	.if		(\regcount) < 0 || (\regcount) > 10
675*4882a593Smuzhiyun 	.error		"regcount should be in the range [0 ... 10]"
676*4882a593Smuzhiyun 	.endif
677*4882a593Smuzhiyun 	.if		((\extra) % 16) != 0
678*4882a593Smuzhiyun 	.error		"extra should be a multiple of 16 bytes"
679*4882a593Smuzhiyun 	.endif
680*4882a593Smuzhiyun 	.ifdef		.Lframe_regcount
681*4882a593Smuzhiyun 	.if		.Lframe_regcount != -1
682*4882a593Smuzhiyun 	.error		"frame_push/frame_pop may not be nested"
683*4882a593Smuzhiyun 	.endif
684*4882a593Smuzhiyun 	.endif
685*4882a593Smuzhiyun 	.set		.Lframe_regcount, \regcount
686*4882a593Smuzhiyun 	.set		.Lframe_extra, \extra
687*4882a593Smuzhiyun 	.set		.Lframe_local_offset, ((\regcount + 3) / 2) * 16
688*4882a593Smuzhiyun 	stp		x29, x30, [sp, #-.Lframe_local_offset - .Lframe_extra]!
689*4882a593Smuzhiyun 	mov		x29, sp
690*4882a593Smuzhiyun 	.endif
691*4882a593Smuzhiyun 
692*4882a593Smuzhiyun 	__frame_regs	x19, x20, \op, 1
693*4882a593Smuzhiyun 	__frame_regs	x21, x22, \op, 3
694*4882a593Smuzhiyun 	__frame_regs	x23, x24, \op, 5
695*4882a593Smuzhiyun 	__frame_regs	x25, x26, \op, 7
696*4882a593Smuzhiyun 	__frame_regs	x27, x28, \op, 9
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun 	.ifc		\op, ld
699*4882a593Smuzhiyun 	.if		.Lframe_regcount == -1
700*4882a593Smuzhiyun 	.error		"frame_push/frame_pop may not be nested"
701*4882a593Smuzhiyun 	.endif
702*4882a593Smuzhiyun 	ldp		x29, x30, [sp], #.Lframe_local_offset + .Lframe_extra
703*4882a593Smuzhiyun 	.set		.Lframe_regcount, -1
704*4882a593Smuzhiyun 	.endif
705*4882a593Smuzhiyun 	.endm
706*4882a593Smuzhiyun 
707*4882a593Smuzhiyun /*
708*4882a593Smuzhiyun  * Set SCTLR_ELx to the @reg value, and invalidate the local icache
709*4882a593Smuzhiyun  * in the process. This is called when setting the MMU on.
710*4882a593Smuzhiyun  */
711*4882a593Smuzhiyun .macro set_sctlr, sreg, reg
712*4882a593Smuzhiyun 	msr	\sreg, \reg
713*4882a593Smuzhiyun 	isb
714*4882a593Smuzhiyun 	/*
715*4882a593Smuzhiyun 	 * Invalidate the local I-cache so that any instructions fetched
716*4882a593Smuzhiyun 	 * speculatively from the PoC are discarded, since they may have
717*4882a593Smuzhiyun 	 * been dynamically patched at the PoU.
718*4882a593Smuzhiyun 	 */
719*4882a593Smuzhiyun 	ic	iallu
720*4882a593Smuzhiyun 	dsb	nsh
721*4882a593Smuzhiyun 	isb
722*4882a593Smuzhiyun .endm
723*4882a593Smuzhiyun 
724*4882a593Smuzhiyun .macro set_sctlr_el1, reg
725*4882a593Smuzhiyun 	set_sctlr sctlr_el1, \reg
726*4882a593Smuzhiyun .endm
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun .macro set_sctlr_el2, reg
729*4882a593Smuzhiyun 	set_sctlr sctlr_el2, \reg
730*4882a593Smuzhiyun .endm
731*4882a593Smuzhiyun 
732*4882a593Smuzhiyun 	/*
733*4882a593Smuzhiyun 	 * Check whether preempt/bh-disabled asm code should yield as soon as
734*4882a593Smuzhiyun 	 * it is able. This is the case if we are currently running in task
735*4882a593Smuzhiyun 	 * context, and either a softirq is pending, or the TIF_NEED_RESCHED
736*4882a593Smuzhiyun 	 * flag is set and re-enabling preemption a single time would result in
737*4882a593Smuzhiyun 	 * a preempt count of zero. (Note that the TIF_NEED_RESCHED flag is
738*4882a593Smuzhiyun 	 * stored negated in the top word of the thread_info::preempt_count
739*4882a593Smuzhiyun 	 * field)
740*4882a593Smuzhiyun 	 */
741*4882a593Smuzhiyun 	.macro		cond_yield, lbl:req, tmp:req, tmp2:req
742*4882a593Smuzhiyun 	get_current_task \tmp
743*4882a593Smuzhiyun 	ldr		\tmp, [\tmp, #TSK_TI_PREEMPT]
744*4882a593Smuzhiyun 	/*
745*4882a593Smuzhiyun 	 * If we are serving a softirq, there is no point in yielding: the
746*4882a593Smuzhiyun 	 * softirq will not be preempted no matter what we do, so we should
747*4882a593Smuzhiyun 	 * run to completion as quickly as we can.
748*4882a593Smuzhiyun 	 */
749*4882a593Smuzhiyun 	tbnz		\tmp, #SOFTIRQ_SHIFT, .Lnoyield_\@
750*4882a593Smuzhiyun #ifdef CONFIG_PREEMPTION
751*4882a593Smuzhiyun 	sub		\tmp, \tmp, #PREEMPT_DISABLE_OFFSET
752*4882a593Smuzhiyun 	cbz		\tmp, \lbl
753*4882a593Smuzhiyun #endif
754*4882a593Smuzhiyun 	adr_l		\tmp, irq_stat + IRQ_CPUSTAT_SOFTIRQ_PENDING
755*4882a593Smuzhiyun 	this_cpu_offset	\tmp2
756*4882a593Smuzhiyun 	ldr		w\tmp, [\tmp, \tmp2]
757*4882a593Smuzhiyun 	cbnz		w\tmp, \lbl	// yield on pending softirq in task context
758*4882a593Smuzhiyun .Lnoyield_\@:
759*4882a593Smuzhiyun 	.endm
760*4882a593Smuzhiyun 
761*4882a593Smuzhiyun /*
762*4882a593Smuzhiyun  * This macro emits a program property note section identifying
763*4882a593Smuzhiyun  * architecture features which require special handling, mainly for
764*4882a593Smuzhiyun  * use in assembly files included in the VDSO.
765*4882a593Smuzhiyun  */
766*4882a593Smuzhiyun 
767*4882a593Smuzhiyun #define NT_GNU_PROPERTY_TYPE_0  5
768*4882a593Smuzhiyun #define GNU_PROPERTY_AARCH64_FEATURE_1_AND      0xc0000000
769*4882a593Smuzhiyun 
770*4882a593Smuzhiyun #define GNU_PROPERTY_AARCH64_FEATURE_1_BTI      (1U << 0)
771*4882a593Smuzhiyun #define GNU_PROPERTY_AARCH64_FEATURE_1_PAC      (1U << 1)
772*4882a593Smuzhiyun 
773*4882a593Smuzhiyun #ifdef CONFIG_ARM64_BTI_KERNEL
774*4882a593Smuzhiyun #define GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT		\
775*4882a593Smuzhiyun 		((GNU_PROPERTY_AARCH64_FEATURE_1_BTI |	\
776*4882a593Smuzhiyun 		  GNU_PROPERTY_AARCH64_FEATURE_1_PAC))
777*4882a593Smuzhiyun #endif
778*4882a593Smuzhiyun 
779*4882a593Smuzhiyun #ifdef GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT
780*4882a593Smuzhiyun .macro emit_aarch64_feature_1_and, feat=GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT
781*4882a593Smuzhiyun 	.pushsection .note.gnu.property, "a"
782*4882a593Smuzhiyun 	.align  3
783*4882a593Smuzhiyun 	.long   2f - 1f
784*4882a593Smuzhiyun 	.long   6f - 3f
785*4882a593Smuzhiyun 	.long   NT_GNU_PROPERTY_TYPE_0
786*4882a593Smuzhiyun 1:      .string "GNU"
787*4882a593Smuzhiyun 2:
788*4882a593Smuzhiyun 	.align  3
789*4882a593Smuzhiyun 3:      .long   GNU_PROPERTY_AARCH64_FEATURE_1_AND
790*4882a593Smuzhiyun 	.long   5f - 4f
791*4882a593Smuzhiyun 4:
792*4882a593Smuzhiyun 	/*
793*4882a593Smuzhiyun 	 * This is described with an array of char in the Linux API
794*4882a593Smuzhiyun 	 * spec but the text and all other usage (including binutils,
795*4882a593Smuzhiyun 	 * clang and GCC) treat this as a 32 bit value so no swizzling
796*4882a593Smuzhiyun 	 * is required for big endian.
797*4882a593Smuzhiyun 	 */
798*4882a593Smuzhiyun 	.long   \feat
799*4882a593Smuzhiyun 5:
800*4882a593Smuzhiyun 	.align  3
801*4882a593Smuzhiyun 6:
802*4882a593Smuzhiyun 	.popsection
803*4882a593Smuzhiyun .endm
804*4882a593Smuzhiyun 
805*4882a593Smuzhiyun #else
806*4882a593Smuzhiyun .macro emit_aarch64_feature_1_and, feat=0
807*4882a593Smuzhiyun .endm
808*4882a593Smuzhiyun 
809*4882a593Smuzhiyun #endif /* GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT */
810*4882a593Smuzhiyun 
811*4882a593Smuzhiyun 	.macro __mitigate_spectre_bhb_loop      tmp
812*4882a593Smuzhiyun #ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
813*4882a593Smuzhiyun alternative_cb  spectre_bhb_patch_loop_iter
814*4882a593Smuzhiyun 	mov	\tmp, #32		// Patched to correct the immediate
815*4882a593Smuzhiyun alternative_cb_end
816*4882a593Smuzhiyun .Lspectre_bhb_loop\@:
817*4882a593Smuzhiyun 	b	. + 4
818*4882a593Smuzhiyun 	subs	\tmp, \tmp, #1
819*4882a593Smuzhiyun 	b.ne	.Lspectre_bhb_loop\@
820*4882a593Smuzhiyun 	sb
821*4882a593Smuzhiyun #endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
822*4882a593Smuzhiyun 	.endm
823*4882a593Smuzhiyun 
824*4882a593Smuzhiyun 	.macro mitigate_spectre_bhb_loop	tmp
825*4882a593Smuzhiyun #ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
826*4882a593Smuzhiyun alternative_cb	spectre_bhb_patch_loop_mitigation_enable
827*4882a593Smuzhiyun 	b	.L_spectre_bhb_loop_done\@	// Patched to NOP
828*4882a593Smuzhiyun alternative_cb_end
829*4882a593Smuzhiyun 	__mitigate_spectre_bhb_loop	\tmp
830*4882a593Smuzhiyun .L_spectre_bhb_loop_done\@:
831*4882a593Smuzhiyun #endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
832*4882a593Smuzhiyun 	.endm
833*4882a593Smuzhiyun 
834*4882a593Smuzhiyun 	/* Save/restores x0-x3 to the stack */
835*4882a593Smuzhiyun 	.macro __mitigate_spectre_bhb_fw
836*4882a593Smuzhiyun #ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
837*4882a593Smuzhiyun 	stp	x0, x1, [sp, #-16]!
838*4882a593Smuzhiyun 	stp	x2, x3, [sp, #-16]!
839*4882a593Smuzhiyun 	mov	w0, #ARM_SMCCC_ARCH_WORKAROUND_3
840*4882a593Smuzhiyun alternative_cb	smccc_patch_fw_mitigation_conduit
841*4882a593Smuzhiyun 	nop					// Patched to SMC/HVC #0
842*4882a593Smuzhiyun alternative_cb_end
843*4882a593Smuzhiyun 	ldp	x2, x3, [sp], #16
844*4882a593Smuzhiyun 	ldp	x0, x1, [sp], #16
845*4882a593Smuzhiyun #endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
846*4882a593Smuzhiyun 	.endm
847*4882a593Smuzhiyun 
848*4882a593Smuzhiyun 	.macro mitigate_spectre_bhb_clear_insn
849*4882a593Smuzhiyun #ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
850*4882a593Smuzhiyun alternative_cb	spectre_bhb_patch_clearbhb
851*4882a593Smuzhiyun 	/* Patched to NOP when not supported */
852*4882a593Smuzhiyun 	clearbhb
853*4882a593Smuzhiyun 	isb
854*4882a593Smuzhiyun alternative_cb_end
855*4882a593Smuzhiyun #endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
856*4882a593Smuzhiyun 	.endm
857*4882a593Smuzhiyun #endif	/* __ASM_ASSEMBLER_H */
858