| Catalin Marinas | 0be7320 | 2012-03-05 11:49:26 +0000 | [diff] [blame] | 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 |  | 
| Marc Zyngier | f3e3927 | 2015-02-20 13:53:13 +0000 | [diff] [blame] | 23 | #ifndef __ASM_ASSEMBLER_H | 
|  | 24 | #define __ASM_ASSEMBLER_H | 
|  | 25 |  | 
| Catalin Marinas | 0be7320 | 2012-03-05 11:49:26 +0000 | [diff] [blame] | 26 | #include <asm/ptrace.h> | 
| Will Deacon | 2a28307 | 2014-04-29 19:04:06 +0100 | [diff] [blame] | 27 | #include <asm/thread_info.h> | 
| Catalin Marinas | 0be7320 | 2012-03-05 11:49:26 +0000 | [diff] [blame] | 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 |  | 
| Will Deacon | 2a28307 | 2014-04-29 19:04:06 +0100 | [diff] [blame] | 75 | .macro	disable_step_tsk, flgs, tmp | 
|  | 76 | tbz	\flgs, #TIF_SINGLESTEP, 9990f | 
| Catalin Marinas | 0be7320 | 2012-03-05 11:49:26 +0000 | [diff] [blame] | 77 | mrs	\tmp, mdscr_el1 | 
|  | 78 | bic	\tmp, \tmp, #1 | 
|  | 79 | msr	mdscr_el1, \tmp | 
| Will Deacon | 2a28307 | 2014-04-29 19:04:06 +0100 | [diff] [blame] | 80 | isb	// Synchronise with enable_dbg | 
|  | 81 | 9990: | 
| Catalin Marinas | 0be7320 | 2012-03-05 11:49:26 +0000 | [diff] [blame] | 82 | .endm | 
|  | 83 |  | 
| Will Deacon | 2a28307 | 2014-04-29 19:04:06 +0100 | [diff] [blame] | 84 | .macro	enable_step_tsk, flgs, tmp | 
|  | 85 | tbz	\flgs, #TIF_SINGLESTEP, 9990f | 
|  | 86 | disable_dbg | 
| Catalin Marinas | 0be7320 | 2012-03-05 11:49:26 +0000 | [diff] [blame] | 87 | mrs	\tmp, mdscr_el1 | 
|  | 88 | orr	\tmp, \tmp, #1 | 
|  | 89 | msr	mdscr_el1, \tmp | 
| Will Deacon | 2a28307 | 2014-04-29 19:04:06 +0100 | [diff] [blame] | 90 | 9990: | 
| Catalin Marinas | 0be7320 | 2012-03-05 11:49:26 +0000 | [diff] [blame] | 91 | .endm | 
|  | 92 |  | 
| Will Deacon | 2a28307 | 2014-04-29 19:04:06 +0100 | [diff] [blame] | 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) | 
| Catalin Marinas | 0be7320 | 2012-03-05 11:49:26 +0000 | [diff] [blame] | 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 | 
| Marc Zyngier | dc637f1 | 2012-10-19 17:37:35 +0100 | [diff] [blame] | 122 |  | 
|  | 123 | /* | 
|  | 124 | * Vector entry | 
|  | 125 | */ | 
|  | 126 | .macro	ventry	label | 
|  | 127 | .align	7 | 
|  | 128 | b	\label | 
|  | 129 | .endm | 
| Matthew Leach | e68beda | 2013-10-11 14:52:15 +0100 | [diff] [blame] | 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 |  | 
| Matthew Leach | 55b8954 | 2013-10-11 14:52:13 +0100 | [diff] [blame] | 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 | 
| Marc Zyngier | f3e3927 | 2015-02-20 13:53:13 +0000 | [diff] [blame] | 161 |  | 
| Ard Biesheuvel | b784a5d | 2015-03-04 19:45:38 +0100 | [diff] [blame^] | 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 |  | 
| Marc Zyngier | f3e3927 | 2015-02-20 13:53:13 +0000 | [diff] [blame] | 210 | #endif	/* __ASM_ASSEMBLER_H */ |