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/ptrace.h> 27 #include <asm/thread_info.h> 28 29 /* 30 * Stack pushing/popping (register pairs only). Equivalent to store decrement 31 * before, load increment after. 32 */ 33 .macro push, xreg1, xreg2 34 stp \xreg1, \xreg2, [sp, #-16]! 35 .endm 36 37 .macro pop, xreg1, xreg2 38 ldp \xreg1, \xreg2, [sp], #16 39 .endm 40 41 /* 42 * Enable and disable interrupts. 43 */ 44 .macro disable_irq 45 msr daifset, #2 46 .endm 47 48 .macro enable_irq 49 msr daifclr, #2 50 .endm 51 52 /* 53 * Save/disable and restore interrupts. 54 */ 55 .macro save_and_disable_irqs, olddaif 56 mrs \olddaif, daif 57 disable_irq 58 .endm 59 60 .macro restore_irqs, olddaif 61 msr daif, \olddaif 62 .endm 63 64 /* 65 * Enable and disable debug exceptions. 66 */ 67 .macro disable_dbg 68 msr daifset, #8 69 .endm 70 71 .macro enable_dbg 72 msr daifclr, #8 73 .endm 74 75 .macro disable_step_tsk, flgs, tmp 76 tbz \flgs, #TIF_SINGLESTEP, 9990f 77 mrs \tmp, mdscr_el1 78 bic \tmp, \tmp, #1 79 msr mdscr_el1, \tmp 80 isb // Synchronise with enable_dbg 81 9990: 82 .endm 83 84 .macro enable_step_tsk, flgs, tmp 85 tbz \flgs, #TIF_SINGLESTEP, 9990f 86 disable_dbg 87 mrs \tmp, mdscr_el1 88 orr \tmp, \tmp, #1 89 msr mdscr_el1, \tmp 90 9990: 91 .endm 92 93 /* 94 * Enable both debug exceptions and interrupts. This is likely to be 95 * faster than two daifclr operations, since writes to this register 96 * are self-synchronising. 97 */ 98 .macro enable_dbg_and_irq 99 msr daifclr, #(8 | 2) 100 .endm 101 102 /* 103 * SMP data memory barrier 104 */ 105 .macro smp_dmb, opt 106 #ifdef CONFIG_SMP 107 dmb \opt 108 #endif 109 .endm 110 111 #define USER(l, x...) \ 112 9999: x; \ 113 .section __ex_table,"a"; \ 114 .align 3; \ 115 .quad 9999b,l; \ 116 .previous 117 118 /* 119 * Register aliases. 120 */ 121 lr .req x30 // link register 122 123 /* 124 * Vector entry 125 */ 126 .macro ventry label 127 .align 7 128 b \label 129 .endm 130 131 /* 132 * Select code when configured for BE. 133 */ 134 #ifdef CONFIG_CPU_BIG_ENDIAN 135 #define CPU_BE(code...) code 136 #else 137 #define CPU_BE(code...) 138 #endif 139 140 /* 141 * Select code when configured for LE. 142 */ 143 #ifdef CONFIG_CPU_BIG_ENDIAN 144 #define CPU_LE(code...) 145 #else 146 #define CPU_LE(code...) code 147 #endif 148 149 /* 150 * Define a macro that constructs a 64-bit value by concatenating two 151 * 32-bit registers. Note that on big endian systems the order of the 152 * registers is swapped. 153 */ 154 #ifndef CONFIG_CPU_BIG_ENDIAN 155 .macro regs_to_64, rd, lbits, hbits 156 #else 157 .macro regs_to_64, rd, hbits, lbits 158 #endif 159 orr \rd, \lbits, \hbits, lsl #32 160 .endm 161 162 /* 163 * Pseudo-ops for PC-relative adr/ldr/str <reg>, <symbol> where 164 * <symbol> is within the range +/- 4 GB of the PC. 165 */ 166 /* 167 * @dst: destination register (64 bit wide) 168 * @sym: name of the symbol 169 * @tmp: optional scratch register to be used if <dst> == sp, which 170 * is not allowed in an adrp instruction 171 */ 172 .macro adr_l, dst, sym, tmp= 173 .ifb \tmp 174 adrp \dst, \sym 175 add \dst, \dst, :lo12:\sym 176 .else 177 adrp \tmp, \sym 178 add \dst, \tmp, :lo12:\sym 179 .endif 180 .endm 181 182 /* 183 * @dst: destination register (32 or 64 bit wide) 184 * @sym: name of the symbol 185 * @tmp: optional 64-bit scratch register to be used if <dst> is a 186 * 32-bit wide register, in which case it cannot be used to hold 187 * the address 188 */ 189 .macro ldr_l, dst, sym, tmp= 190 .ifb \tmp 191 adrp \dst, \sym 192 ldr \dst, [\dst, :lo12:\sym] 193 .else 194 adrp \tmp, \sym 195 ldr \dst, [\tmp, :lo12:\sym] 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 adrp \tmp, \sym 207 str \src, [\tmp, :lo12:\sym] 208 .endm 209 210 #endif /* __ASM_ASSEMBLER_H */ 211