aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-mips/system.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-mips/system.h')
-rw-r--r--include/asm-mips/system.h71
1 files changed, 47 insertions, 24 deletions
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index 6663efd49b27..330c4e497af3 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -17,6 +17,7 @@
17 17
18#include <asm/addrspace.h> 18#include <asm/addrspace.h>
19#include <asm/cpu-features.h> 19#include <asm/cpu-features.h>
20#include <asm/dsp.h>
20#include <asm/ptrace.h> 21#include <asm/ptrace.h>
21#include <asm/war.h> 22#include <asm/war.h>
22#include <asm/interrupt.h> 23#include <asm/interrupt.h>
@@ -70,7 +71,7 @@
70 * does not enforce ordering, since there is no data dependency between 71 * does not enforce ordering, since there is no data dependency between
71 * the read of "a" and the read of "b". Therefore, on some CPUs, such 72 * the read of "a" and the read of "b". Therefore, on some CPUs, such
72 * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() 73 * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb()
73 * in cases like thiswhere there are no data dependencies. 74 * in cases like this where there are no data dependencies.
74 */ 75 */
75 76
76#define read_barrier_depends() do { } while(0) 77#define read_barrier_depends() do { } while(0)
@@ -154,15 +155,15 @@ extern asmlinkage void *resume(void *last, void *next, void *next_ti);
154 155
155struct task_struct; 156struct task_struct;
156 157
157#define switch_to(prev,next,last) \ 158#define switch_to(prev,next,last) \
158do { \ 159do { \
159 (last) = resume(prev, next, next->thread_info); \ 160 if (cpu_has_dsp) \
161 __save_dsp(prev); \
162 (last) = resume(prev, next, next->thread_info); \
163 if (cpu_has_dsp) \
164 __restore_dsp(current); \
160} while(0) 165} while(0)
161 166
162#define ROT_IN_PIECES \
163 " .set noreorder \n" \
164 " .set reorder \n"
165
166static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) 167static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
167{ 168{
168 __u32 retval; 169 __u32 retval;
@@ -171,14 +172,17 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
171 unsigned long dummy; 172 unsigned long dummy;
172 173
173 __asm__ __volatile__( 174 __asm__ __volatile__(
175 " .set mips3 \n"
174 "1: ll %0, %3 # xchg_u32 \n" 176 "1: ll %0, %3 # xchg_u32 \n"
177 " .set mips0 \n"
175 " move %2, %z4 \n" 178 " move %2, %z4 \n"
179 " .set mips3 \n"
176 " sc %2, %1 \n" 180 " sc %2, %1 \n"
177 " beqzl %2, 1b \n" 181 " beqzl %2, 1b \n"
178 ROT_IN_PIECES
179#ifdef CONFIG_SMP 182#ifdef CONFIG_SMP
180 " sync \n" 183 " sync \n"
181#endif 184#endif
185 " .set mips0 \n"
182 : "=&r" (retval), "=m" (*m), "=&r" (dummy) 186 : "=&r" (retval), "=m" (*m), "=&r" (dummy)
183 : "R" (*m), "Jr" (val) 187 : "R" (*m), "Jr" (val)
184 : "memory"); 188 : "memory");
@@ -186,13 +190,17 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
186 unsigned long dummy; 190 unsigned long dummy;
187 191
188 __asm__ __volatile__( 192 __asm__ __volatile__(
193 " .set mips3 \n"
189 "1: ll %0, %3 # xchg_u32 \n" 194 "1: ll %0, %3 # xchg_u32 \n"
195 " .set mips0 \n"
190 " move %2, %z4 \n" 196 " move %2, %z4 \n"
197 " .set mips3 \n"
191 " sc %2, %1 \n" 198 " sc %2, %1 \n"
192 " beqz %2, 1b \n" 199 " beqz %2, 1b \n"
193#ifdef CONFIG_SMP 200#ifdef CONFIG_SMP
194 " sync \n" 201 " sync \n"
195#endif 202#endif
203 " .set mips0 \n"
196 : "=&r" (retval), "=m" (*m), "=&r" (dummy) 204 : "=&r" (retval), "=m" (*m), "=&r" (dummy)
197 : "R" (*m), "Jr" (val) 205 : "R" (*m), "Jr" (val)
198 : "memory"); 206 : "memory");
@@ -217,14 +225,15 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
217 unsigned long dummy; 225 unsigned long dummy;
218 226
219 __asm__ __volatile__( 227 __asm__ __volatile__(
228 " .set mips3 \n"
220 "1: lld %0, %3 # xchg_u64 \n" 229 "1: lld %0, %3 # xchg_u64 \n"
221 " move %2, %z4 \n" 230 " move %2, %z4 \n"
222 " scd %2, %1 \n" 231 " scd %2, %1 \n"
223 " beqzl %2, 1b \n" 232 " beqzl %2, 1b \n"
224 ROT_IN_PIECES
225#ifdef CONFIG_SMP 233#ifdef CONFIG_SMP
226 " sync \n" 234 " sync \n"
227#endif 235#endif
236 " .set mips0 \n"
228 : "=&r" (retval), "=m" (*m), "=&r" (dummy) 237 : "=&r" (retval), "=m" (*m), "=&r" (dummy)
229 : "R" (*m), "Jr" (val) 238 : "R" (*m), "Jr" (val)
230 : "memory"); 239 : "memory");
@@ -232,6 +241,7 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
232 unsigned long dummy; 241 unsigned long dummy;
233 242
234 __asm__ __volatile__( 243 __asm__ __volatile__(
244 " .set mips3 \n"
235 "1: lld %0, %3 # xchg_u64 \n" 245 "1: lld %0, %3 # xchg_u64 \n"
236 " move %2, %z4 \n" 246 " move %2, %z4 \n"
237 " scd %2, %1 \n" 247 " scd %2, %1 \n"
@@ -239,6 +249,7 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
239#ifdef CONFIG_SMP 249#ifdef CONFIG_SMP
240 " sync \n" 250 " sync \n"
241#endif 251#endif
252 " .set mips0 \n"
242 : "=&r" (retval), "=m" (*m), "=&r" (dummy) 253 : "=&r" (retval), "=m" (*m), "=&r" (dummy)
243 : "R" (*m), "Jr" (val) 254 : "R" (*m), "Jr" (val)
244 : "memory"); 255 : "memory");
@@ -286,34 +297,41 @@ static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old,
286 297
287 if (cpu_has_llsc && R10000_LLSC_WAR) { 298 if (cpu_has_llsc && R10000_LLSC_WAR) {
288 __asm__ __volatile__( 299 __asm__ __volatile__(
300 " .set push \n"
289 " .set noat \n" 301 " .set noat \n"
302 " .set mips3 \n"
290 "1: ll %0, %2 # __cmpxchg_u32 \n" 303 "1: ll %0, %2 # __cmpxchg_u32 \n"
291 " bne %0, %z3, 2f \n" 304 " bne %0, %z3, 2f \n"
305 " .set mips0 \n"
292 " move $1, %z4 \n" 306 " move $1, %z4 \n"
307 " .set mips3 \n"
293 " sc $1, %1 \n" 308 " sc $1, %1 \n"
294 " beqzl $1, 1b \n" 309 " beqzl $1, 1b \n"
295 ROT_IN_PIECES
296#ifdef CONFIG_SMP 310#ifdef CONFIG_SMP
297 " sync \n" 311 " sync \n"
298#endif 312#endif
299 "2: \n" 313 "2: \n"
300 " .set at \n" 314 " .set pop \n"
301 : "=&r" (retval), "=m" (*m) 315 : "=&r" (retval), "=m" (*m)
302 : "R" (*m), "Jr" (old), "Jr" (new) 316 : "R" (*m), "Jr" (old), "Jr" (new)
303 : "memory"); 317 : "memory");
304 } else if (cpu_has_llsc) { 318 } else if (cpu_has_llsc) {
305 __asm__ __volatile__( 319 __asm__ __volatile__(
320 " .set push \n"
306 " .set noat \n" 321 " .set noat \n"
322 " .set mips3 \n"
307 "1: ll %0, %2 # __cmpxchg_u32 \n" 323 "1: ll %0, %2 # __cmpxchg_u32 \n"
308 " bne %0, %z3, 2f \n" 324 " bne %0, %z3, 2f \n"
325 " .set mips0 \n"
309 " move $1, %z4 \n" 326 " move $1, %z4 \n"
327 " .set mips3 \n"
310 " sc $1, %1 \n" 328 " sc $1, %1 \n"
311 " beqz $1, 1b \n" 329 " beqz $1, 1b \n"
312#ifdef CONFIG_SMP 330#ifdef CONFIG_SMP
313 " sync \n" 331 " sync \n"
314#endif 332#endif
315 "2: \n" 333 "2: \n"
316 " .set at \n" 334 " .set pop \n"
317 : "=&r" (retval), "=m" (*m) 335 : "=&r" (retval), "=m" (*m)
318 : "R" (*m), "Jr" (old), "Jr" (new) 336 : "R" (*m), "Jr" (old), "Jr" (new)
319 : "memory"); 337 : "memory");
@@ -338,24 +356,27 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
338 356
339 if (cpu_has_llsc) { 357 if (cpu_has_llsc) {
340 __asm__ __volatile__( 358 __asm__ __volatile__(
359 " .set push \n"
341 " .set noat \n" 360 " .set noat \n"
361 " .set mips3 \n"
342 "1: lld %0, %2 # __cmpxchg_u64 \n" 362 "1: lld %0, %2 # __cmpxchg_u64 \n"
343 " bne %0, %z3, 2f \n" 363 " bne %0, %z3, 2f \n"
344 " move $1, %z4 \n" 364 " move $1, %z4 \n"
345 " scd $1, %1 \n" 365 " scd $1, %1 \n"
346 " beqzl $1, 1b \n" 366 " beqzl $1, 1b \n"
347 ROT_IN_PIECES
348#ifdef CONFIG_SMP 367#ifdef CONFIG_SMP
349 " sync \n" 368 " sync \n"
350#endif 369#endif
351 "2: \n" 370 "2: \n"
352 " .set at \n" 371 " .set pop \n"
353 : "=&r" (retval), "=m" (*m) 372 : "=&r" (retval), "=m" (*m)
354 : "R" (*m), "Jr" (old), "Jr" (new) 373 : "R" (*m), "Jr" (old), "Jr" (new)
355 : "memory"); 374 : "memory");
356 } else if (cpu_has_llsc) { 375 } else if (cpu_has_llsc) {
357 __asm__ __volatile__( 376 __asm__ __volatile__(
377 " .set push \n"
358 " .set noat \n" 378 " .set noat \n"
379 " .set mips3 \n"
359 "1: lld %0, %2 # __cmpxchg_u64 \n" 380 "1: lld %0, %2 # __cmpxchg_u64 \n"
360 " bne %0, %z3, 2f \n" 381 " bne %0, %z3, 2f \n"
361 " move $1, %z4 \n" 382 " move $1, %z4 \n"
@@ -365,7 +386,7 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
365 " sync \n" 386 " sync \n"
366#endif 387#endif
367 "2: \n" 388 "2: \n"
368 " .set at \n" 389 " .set pop \n"
369 : "=&r" (retval), "=m" (*m) 390 : "=&r" (retval), "=m" (*m)
370 : "R" (*m), "Jr" (old), "Jr" (new) 391 : "R" (*m), "Jr" (old), "Jr" (new)
371 : "memory"); 392 : "memory");
@@ -406,18 +427,20 @@ static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
406 427
407#define cmpxchg(ptr,old,new) ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(old), (unsigned long)(new),sizeof(*(ptr)))) 428#define cmpxchg(ptr,old,new) ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(old), (unsigned long)(new),sizeof(*(ptr))))
408 429
430extern void set_handler (unsigned long offset, void *addr, unsigned long len);
431extern void set_uncached_handler (unsigned long offset, void *addr, unsigned long len);
432extern void *set_vi_handler (int n, void *addr);
433extern void *set_vi_srs_handler (int n, void *addr, int regset);
409extern void *set_except_vector(int n, void *addr); 434extern void *set_except_vector(int n, void *addr);
410extern void per_cpu_trap_init(void); 435extern void per_cpu_trap_init(void);
411 436
412extern NORET_TYPE void __die(const char *, struct pt_regs *, const char *file, 437extern NORET_TYPE void die(const char *, struct pt_regs *);
413 const char *func, unsigned long line);
414extern void __die_if_kernel(const char *, struct pt_regs *, const char *file,
415 const char *func, unsigned long line);
416 438
417#define die(msg, regs) \ 439static inline void die_if_kernel(const char *str, struct pt_regs *regs)
418 __die(msg, regs, __FILE__ ":", __FUNCTION__, __LINE__) 440{
419#define die_if_kernel(msg, regs) \ 441 if (unlikely(!user_mode(regs)))
420 __die_if_kernel(msg, regs, __FILE__ ":", __FUNCTION__, __LINE__) 442 die(str, regs);
443}
421 444
422extern int stop_a_enabled; 445extern int stop_a_enabled;
423 446