xref: /linux/arch/arm64/include/asm/assembler.h (revision 3932b9ca55b0be314a36d3e84faff3e823c081f5)
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 #include <asm/ptrace.h>
24 #include <asm/thread_info.h>
25 
26 /*
27  * Stack pushing/popping (register pairs only). Equivalent to store decrement
28  * before, load increment after.
29  */
30 	.macro	push, xreg1, xreg2
31 	stp	\xreg1, \xreg2, [sp, #-16]!
32 	.endm
33 
34 	.macro	pop, xreg1, xreg2
35 	ldp	\xreg1, \xreg2, [sp], #16
36 	.endm
37 
38 /*
39  * Enable and disable interrupts.
40  */
41 	.macro	disable_irq
42 	msr	daifset, #2
43 	.endm
44 
45 	.macro	enable_irq
46 	msr	daifclr, #2
47 	.endm
48 
49 /*
50  * Save/disable and restore interrupts.
51  */
52 	.macro	save_and_disable_irqs, olddaif
53 	mrs	\olddaif, daif
54 	disable_irq
55 	.endm
56 
57 	.macro	restore_irqs, olddaif
58 	msr	daif, \olddaif
59 	.endm
60 
61 /*
62  * Enable and disable debug exceptions.
63  */
64 	.macro	disable_dbg
65 	msr	daifset, #8
66 	.endm
67 
68 	.macro	enable_dbg
69 	msr	daifclr, #8
70 	.endm
71 
72 	.macro	disable_step_tsk, flgs, tmp
73 	tbz	\flgs, #TIF_SINGLESTEP, 9990f
74 	mrs	\tmp, mdscr_el1
75 	bic	\tmp, \tmp, #1
76 	msr	mdscr_el1, \tmp
77 	isb	// Synchronise with enable_dbg
78 9990:
79 	.endm
80 
81 	.macro	enable_step_tsk, flgs, tmp
82 	tbz	\flgs, #TIF_SINGLESTEP, 9990f
83 	disable_dbg
84 	mrs	\tmp, mdscr_el1
85 	orr	\tmp, \tmp, #1
86 	msr	mdscr_el1, \tmp
87 9990:
88 	.endm
89 
90 /*
91  * Enable both debug exceptions and interrupts. This is likely to be
92  * faster than two daifclr operations, since writes to this register
93  * are self-synchronising.
94  */
95 	.macro	enable_dbg_and_irq
96 	msr	daifclr, #(8 | 2)
97 	.endm
98 
99 /*
100  * SMP data memory barrier
101  */
102 	.macro	smp_dmb, opt
103 #ifdef CONFIG_SMP
104 	dmb	\opt
105 #endif
106 	.endm
107 
108 #define USER(l, x...)				\
109 9999:	x;					\
110 	.section __ex_table,"a";		\
111 	.align	3;				\
112 	.quad	9999b,l;			\
113 	.previous
114 
115 /*
116  * Register aliases.
117  */
118 lr	.req	x30		// link register
119 
120 /*
121  * Vector entry
122  */
123 	 .macro	ventry	label
124 	.align	7
125 	b	\label
126 	.endm
127 
128 /*
129  * Select code when configured for BE.
130  */
131 #ifdef CONFIG_CPU_BIG_ENDIAN
132 #define CPU_BE(code...) code
133 #else
134 #define CPU_BE(code...)
135 #endif
136 
137 /*
138  * Select code when configured for LE.
139  */
140 #ifdef CONFIG_CPU_BIG_ENDIAN
141 #define CPU_LE(code...)
142 #else
143 #define CPU_LE(code...) code
144 #endif
145 
146 /*
147  * Define a macro that constructs a 64-bit value by concatenating two
148  * 32-bit registers. Note that on big endian systems the order of the
149  * registers is swapped.
150  */
151 #ifndef CONFIG_CPU_BIG_ENDIAN
152 	.macro	regs_to_64, rd, lbits, hbits
153 #else
154 	.macro	regs_to_64, rd, hbits, lbits
155 #endif
156 	orr	\rd, \lbits, \hbits, lsl #32
157 	.endm
158