diff options
Diffstat (limited to 'arch/arm/include/asm/assembler.h')
-rw-r--r-- | arch/arm/include/asm/assembler.h | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 4e84d09c9c1b..bc2d2d75f706 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h | |||
@@ -158,16 +158,24 @@ | |||
158 | #ifdef CONFIG_SMP | 158 | #ifdef CONFIG_SMP |
159 | #define ALT_SMP(instr...) \ | 159 | #define ALT_SMP(instr...) \ |
160 | 9998: instr | 160 | 9998: instr |
161 | /* | ||
162 | * Note: if you get assembler errors from ALT_UP() when building with | ||
163 | * CONFIG_THUMB2_KERNEL, you almost certainly need to use | ||
164 | * ALT_SMP( W(instr) ... ) | ||
165 | */ | ||
161 | #define ALT_UP(instr...) \ | 166 | #define ALT_UP(instr...) \ |
162 | .pushsection ".alt.smp.init", "a" ;\ | 167 | .pushsection ".alt.smp.init", "a" ;\ |
163 | .long 9998b ;\ | 168 | .long 9998b ;\ |
164 | instr ;\ | 169 | 9997: instr ;\ |
170 | .if . - 9997b != 4 ;\ | ||
171 | .error "ALT_UP() content must assemble to exactly 4 bytes";\ | ||
172 | .endif ;\ | ||
165 | .popsection | 173 | .popsection |
166 | #define ALT_UP_B(label) \ | 174 | #define ALT_UP_B(label) \ |
167 | .equ up_b_offset, label - 9998b ;\ | 175 | .equ up_b_offset, label - 9998b ;\ |
168 | .pushsection ".alt.smp.init", "a" ;\ | 176 | .pushsection ".alt.smp.init", "a" ;\ |
169 | .long 9998b ;\ | 177 | .long 9998b ;\ |
170 | b . + up_b_offset ;\ | 178 | W(b) . + up_b_offset ;\ |
171 | .popsection | 179 | .popsection |
172 | #else | 180 | #else |
173 | #define ALT_SMP(instr...) | 181 | #define ALT_SMP(instr...) |
@@ -178,16 +186,24 @@ | |||
178 | /* | 186 | /* |
179 | * SMP data memory barrier | 187 | * SMP data memory barrier |
180 | */ | 188 | */ |
181 | .macro smp_dmb | 189 | .macro smp_dmb mode |
182 | #ifdef CONFIG_SMP | 190 | #ifdef CONFIG_SMP |
183 | #if __LINUX_ARM_ARCH__ >= 7 | 191 | #if __LINUX_ARM_ARCH__ >= 7 |
192 | .ifeqs "\mode","arm" | ||
184 | ALT_SMP(dmb) | 193 | ALT_SMP(dmb) |
194 | .else | ||
195 | ALT_SMP(W(dmb)) | ||
196 | .endif | ||
185 | #elif __LINUX_ARM_ARCH__ == 6 | 197 | #elif __LINUX_ARM_ARCH__ == 6 |
186 | ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb | 198 | ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb |
187 | #else | 199 | #else |
188 | #error Incompatible SMP platform | 200 | #error Incompatible SMP platform |
189 | #endif | 201 | #endif |
202 | .ifeqs "\mode","arm" | ||
190 | ALT_UP(nop) | 203 | ALT_UP(nop) |
204 | .else | ||
205 | ALT_UP(W(nop)) | ||
206 | .endif | ||
191 | #endif | 207 | #endif |
192 | .endm | 208 | .endm |
193 | 209 | ||
@@ -239,7 +255,7 @@ | |||
239 | @ Slightly optimised to avoid incrementing the pointer twice | 255 | @ Slightly optimised to avoid incrementing the pointer twice |
240 | usraccoff \instr, \reg, \ptr, \inc, 0, \cond, \abort | 256 | usraccoff \instr, \reg, \ptr, \inc, 0, \cond, \abort |
241 | .if \rept == 2 | 257 | .if \rept == 2 |
242 | usraccoff \instr, \reg, \ptr, \inc, 4, \cond, \abort | 258 | usraccoff \instr, \reg, \ptr, \inc, \inc, \cond, \abort |
243 | .endif | 259 | .endif |
244 | 260 | ||
245 | add\cond \ptr, #\rept * \inc | 261 | add\cond \ptr, #\rept * \inc |