blob: 9c291f5bcde97e924ea23af7f8c073483de842fc [file] [log] [blame]
Nicholas Flintham1e3d3112013-04-10 10:48:38 +01001/*
2 * arch/arm/include/asm/assembler.h
3 *
4 * Copyright (C) 1996-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This file contains arm architecture specific defines
11 * for the different processors.
12 *
13 * Do not include any C declarations in this file - it is included by
14 * assembler source.
15 */
16#ifndef __ASM_ASSEMBLER_H__
17#define __ASM_ASSEMBLER_H__
18
19#ifndef __ASSEMBLY__
20#error "Only include this from assembly code"
21#endif
22
23#include <asm/ptrace.h>
24#include <asm/domain.h>
25
26#define IOMEM(x) (x)
27
28#ifndef __ARMEB__
29#define pull lsr
30#define push lsl
31#define get_byte_0 lsl #0
32#define get_byte_1 lsr #8
33#define get_byte_2 lsr #16
34#define get_byte_3 lsr #24
35#define put_byte_0 lsl #0
36#define put_byte_1 lsl #8
37#define put_byte_2 lsl #16
38#define put_byte_3 lsl #24
39#else
40#define pull lsl
41#define push lsr
42#define get_byte_0 lsr #24
43#define get_byte_1 lsr #16
44#define get_byte_2 lsr #8
45#define get_byte_3 lsl #0
46#define put_byte_0 lsl #24
47#define put_byte_1 lsl #16
48#define put_byte_2 lsl #8
49#define put_byte_3 lsl #0
50#endif
51
52#if __LINUX_ARM_ARCH__ >= 5
53#define PLD(code...) code
54#else
55#define PLD(code...)
56#endif
57
58#ifdef CONFIG_CPU_FEROCEON
59#define CALGN(code...) code
60#else
61#define CALGN(code...)
62#endif
63
64#if __LINUX_ARM_ARCH__ >= 6
65 .macro disable_irq_notrace
66 cpsid i
67 .endm
68
69 .macro enable_irq_notrace
70 cpsie i
71 .endm
72#else
73 .macro disable_irq_notrace
74 msr cpsr_c, #PSR_I_BIT | SVC_MODE
75 .endm
76
77 .macro enable_irq_notrace
78 msr cpsr_c, #SVC_MODE
79 .endm
80#endif
81
82 .macro asm_trace_hardirqs_off
83#if defined(CONFIG_TRACE_IRQFLAGS)
84 stmdb sp!, {r0-r3, ip, lr}
85 bl trace_hardirqs_off
86 ldmia sp!, {r0-r3, ip, lr}
87#endif
88 .endm
89
90 .macro asm_trace_hardirqs_on_cond, cond
91#if defined(CONFIG_TRACE_IRQFLAGS)
92 stmdb sp!, {r0-r3, ip, lr}
93 bl\cond trace_hardirqs_on
94 ldmia sp!, {r0-r3, ip, lr}
95#endif
96 .endm
97
98 .macro asm_trace_hardirqs_on
99 asm_trace_hardirqs_on_cond al
100 .endm
101
102 .macro disable_irq
103 disable_irq_notrace
104 asm_trace_hardirqs_off
105 .endm
106
107 .macro enable_irq
108 asm_trace_hardirqs_on
109 enable_irq_notrace
110 .endm
111 .macro save_and_disable_irqs, oldcpsr
112 mrs \oldcpsr, cpsr
113 disable_irq
114 .endm
115
116 .macro save_and_disable_irqs_notrace, oldcpsr
117 mrs \oldcpsr, cpsr
118 disable_irq_notrace
119 .endm
120
121 .macro restore_irqs_notrace, oldcpsr
122 msr cpsr_c, \oldcpsr
123 .endm
124
125 .macro restore_irqs, oldcpsr
126 tst \oldcpsr, #PSR_I_BIT
127 asm_trace_hardirqs_on_cond eq
128 restore_irqs_notrace \oldcpsr
129 .endm
130
131#define USER(x...) \
1329999: x; \
133 .pushsection __ex_table,"a"; \
134 .align 3; \
135 .long 9999b,9001f; \
136 .popsection
137
138#ifdef CONFIG_SMP
139#define ALT_SMP(instr...) \
1409998: instr
141#define ALT_UP(instr...) \
142 .pushsection ".alt.smp.init", "a" ;\
143 .long 9998b ;\
1449997: instr ;\
145 .if . - 9997b != 4 ;\
146 .error "ALT_UP() content must assemble to exactly 4 bytes";\
147 .endif ;\
148 .popsection
149#define ALT_UP_B(label) \
150 .equ up_b_offset, label - 9998b ;\
151 .pushsection ".alt.smp.init", "a" ;\
152 .long 9998b ;\
153 W(b) . + up_b_offset ;\
154 .popsection
155#else
156#define ALT_SMP(instr...)
157#define ALT_UP(instr...) instr
158#define ALT_UP_B(label) b label
159#endif
160
161 .macro instr_sync
162#if __LINUX_ARM_ARCH__ >= 7
163 isb
164#elif __LINUX_ARM_ARCH__ == 6
165 mcr p15, 0, r0, c7, c5, 4
166#endif
167 .endm
168
169 .macro smp_dmb mode
170#ifdef CONFIG_SMP
171#if __LINUX_ARM_ARCH__ >= 7
172 .ifeqs "\mode","arm"
173 ALT_SMP(dmb)
174 .else
175 ALT_SMP(W(dmb))
176 .endif
177#elif __LINUX_ARM_ARCH__ == 6
178 ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb
179#else
180#error Incompatible SMP platform
181#endif
182 .ifeqs "\mode","arm"
183 ALT_UP(nop)
184 .else
185 ALT_UP(W(nop))
186 .endif
187#endif
188 .endm
189
190#ifdef CONFIG_THUMB2_KERNEL
191 .macro setmode, mode, reg
192 mov \reg, #\mode
193 msr cpsr_c, \reg
194 .endm
195#else
196 .macro setmode, mode, reg
197 msr cpsr_c, #\mode
198 .endm
199#endif
200
201#ifdef CONFIG_THUMB2_KERNEL
202
203 .macro usraccoff, instr, reg, ptr, inc, off, cond, abort, t=TUSER()
2049999:
205 .if \inc == 1
206 \instr\cond\()b\()\t\().w \reg, [\ptr, #\off]
207 .elseif \inc == 4
208 \instr\cond\()\t\().w \reg, [\ptr, #\off]
209 .else
210 .error "Unsupported inc macro argument"
211 .endif
212
213 .pushsection __ex_table,"a"
214 .align 3
215 .long 9999b, \abort
216 .popsection
217 .endm
218
219 .macro usracc, instr, reg, ptr, inc, cond, rept, abort
220 @ explicit IT instruction needed because of the label
221 @ introduced by the USER macro
222 .ifnc \cond,al
223 .if \rept == 1
224 itt \cond
225 .elseif \rept == 2
226 ittt \cond
227 .else
228 .error "Unsupported rept macro argument"
229 .endif
230 .endif
231
232 @ Slightly optimised to avoid incrementing the pointer twice
233 usraccoff \instr, \reg, \ptr, \inc, 0, \cond, \abort
234 .if \rept == 2
235 usraccoff \instr, \reg, \ptr, \inc, \inc, \cond, \abort
236 .endif
237
238 add\cond \ptr, #\rept * \inc
239 .endm
240
241#else
242
243 .macro usracc, instr, reg, ptr, inc, cond, rept, abort, t=TUSER()
244 .rept \rept
2459999:
246 .if \inc == 1
247 \instr\cond\()b\()\t \reg, [\ptr], #\inc
248 .elseif \inc == 4
249 \instr\cond\()\t \reg, [\ptr], #\inc
250 .else
251 .error "Unsupported inc macro argument"
252 .endif
253
254 .pushsection __ex_table,"a"
255 .align 3
256 .long 9999b, \abort
257 .popsection
258 .endr
259 .endm
260
261#endif
262
263 .macro strusr, reg, ptr, inc, cond=al, rept=1, abort=9001f
264 usracc str, \reg, \ptr, \inc, \cond, \rept, \abort
265 .endm
266
267 .macro ldrusr, reg, ptr, inc, cond=al, rept=1, abort=9001f
268 usracc ldr, \reg, \ptr, \inc, \cond, \rept, \abort
269 .endm
270
271 .macro string name:req, string
272 .type \name , #object
273\name:
274 .asciz "\string"
275 .size \name , . - \name
276 .endm
277
278#endif