aboutsummaryrefslogtreecommitdiff log msg author committer range
path: root/arch/arm64/include/asm/assembler.h
blob: 12eff928ef8b38dd18ae3bd157b12eb918f797a6 (plain)
 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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207  /* * Based on arch/arm/include/asm/assembler.h * * Copyright (C) 1996-2000 Russell King * Copyright (C) 2012 ARM Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef __ASSEMBLY__ #error "Only include this from assembly code" #endif #ifndef __ASM_ASSEMBLER_H #define __ASM_ASSEMBLER_H #include #include /* * Stack pushing/popping (register pairs only). Equivalent to store decrement * before, load increment after. */ .macro push, xreg1, xreg2 stp \xreg1, \xreg2, [sp, #-16]! .endm .macro pop, xreg1, xreg2 ldp \xreg1, \xreg2, [sp], #16 .endm /* * Enable and disable interrupts. */ .macro disable_irq msr daifset, #2 .endm .macro enable_irq msr daifclr, #2 .endm /* * Enable and disable debug exceptions. */ .macro disable_dbg msr daifset, #8 .endm .macro enable_dbg msr daifclr, #8 .endm .macro disable_step_tsk, flgs, tmp tbz \flgs, #TIF_SINGLESTEP, 9990f mrs \tmp, mdscr_el1 bic \tmp, \tmp, #1 msr mdscr_el1, \tmp isb // Synchronise with enable_dbg 9990: .endm .macro enable_step_tsk, flgs, tmp tbz \flgs, #TIF_SINGLESTEP, 9990f disable_dbg mrs \tmp, mdscr_el1 orr \tmp, \tmp, #1 msr mdscr_el1, \tmp 9990: .endm /* * Enable both debug exceptions and interrupts. This is likely to be * faster than two daifclr operations, since writes to this register * are self-synchronising. */ .macro enable_dbg_and_irq msr daifclr, #(8 | 2) .endm /* * SMP data memory barrier */ .macro smp_dmb, opt dmb \opt .endm #define USER(l, x...) \ 9999: x; \ .section __ex_table,"a"; \ .align 3; \ .quad 9999b,l; \ .previous /* * Register aliases. */ lr .req x30 // link register /* * Vector entry */ .macro ventry label .align 7 b \label .endm /* * Select code when configured for BE. */ #ifdef CONFIG_CPU_BIG_ENDIAN #define CPU_BE(code...) code #else #define CPU_BE(code...) #endif /* * Select code when configured for LE. */ #ifdef CONFIG_CPU_BIG_ENDIAN #define CPU_LE(code...) #else #define CPU_LE(code...) code #endif /* * Define a macro that constructs a 64-bit value by concatenating two * 32-bit registers. Note that on big endian systems the order of the * registers is swapped. */ #ifndef CONFIG_CPU_BIG_ENDIAN .macro regs_to_64, rd, lbits, hbits #else .macro regs_to_64, rd, hbits, lbits #endif orr \rd, \lbits, \hbits, lsl #32 .endm /* * Pseudo-ops for PC-relative adr/ldr/str , where * is within the range +/- 4 GB of the PC. */ /* * @dst: destination register (64 bit wide) * @sym: name of the symbol * @tmp: optional scratch register to be used if == sp, which * is not allowed in an adrp instruction */ .macro adr_l, dst, sym, tmp= .ifb \tmp adrp \dst, \sym add \dst, \dst, :lo12:\sym .else adrp \tmp, \sym add \dst, \tmp, :lo12:\sym .endif .endm /* * @dst: destination register (32 or 64 bit wide) * @sym: name of the symbol * @tmp: optional 64-bit scratch register to be used if is a * 32-bit wide register, in which case it cannot be used to hold * the address */ .macro ldr_l, dst, sym, tmp= .ifb \tmp adrp \dst, \sym ldr \dst, [\dst, :lo12:\sym] .else adrp \tmp, \sym ldr \dst, [\tmp, :lo12:\sym] .endif .endm /* * @src: source register (32 or 64 bit wide) * @sym: name of the symbol * @tmp: mandatory 64-bit scratch register to calculate the address * while needs to be preserved. */ .macro str_l, src, sym, tmp adrp \tmp, \sym str \src, [\tmp, :lo12:\sym] .endm /* * Annotate a function as position independent, i.e., safe to be called before * the kernel virtual mapping is activated. */ #define ENDPIPROC(x) \ .globl __pi_##x; \ .type __pi_##x, %function; \ .set __pi_##x, x; \ .size __pi_##x, . - x; \ ENDPROC(x) #endif /* __ASM_ASSEMBLER_H */