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