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