X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=include%2Fasm-mips%2Fsystem.h;h=a944eda4faf5ef5f1f3e6ff53932056cf4ce7e4f;hb=ac9d463afb1ca2434335351f3b7d9e4c8f8470e9;hp=357251f42518bdb51e7c402ae720140880425007;hpb=532df780a2012ad75b3f078647f229c4dabd99d1;p=linux-2.6 diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index 357251f425..a944eda4fa 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -61,17 +62,21 @@ do { \ #define __mips_mt_fpaff_switch_to(prev) do { (void) (prev); } while (0) #endif -#define switch_to(prev,next,last) \ +#define switch_to(prev, next, last) \ do { \ __mips_mt_fpaff_switch_to(prev); \ if (cpu_has_dsp) \ __save_dsp(prev); \ (last) = resume(prev, next, task_thread_info(next)); \ +} while (0) + +#define finish_arch_switch(prev) \ +do { \ if (cpu_has_dsp) \ __restore_dsp(current); \ if (cpu_has_userlocal) \ - write_c0_userlocal(task_thread_info(current)->tp_value);\ -} while(0) + write_c0_userlocal(current_thread_info()->tp_value); \ +} while (0) static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) { @@ -192,280 +197,18 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz return x; } -#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) - -#define __HAVE_ARCH_CMPXCHG 1 - -static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old, - unsigned long new) -{ - __u32 retval; - - if (cpu_has_llsc && R10000_LLSC_WAR) { - __asm__ __volatile__( - " .set push \n" - " .set noat \n" - " .set mips3 \n" - "1: ll %0, %2 # __cmpxchg_u32 \n" - " bne %0, %z3, 2f \n" - " .set mips0 \n" - " move $1, %z4 \n" - " .set mips3 \n" - " sc $1, %1 \n" - " beqzl $1, 1b \n" - "2: \n" - " .set pop \n" - : "=&r" (retval), "=R" (*m) - : "R" (*m), "Jr" (old), "Jr" (new) - : "memory"); - } else if (cpu_has_llsc) { - __asm__ __volatile__( - " .set push \n" - " .set noat \n" - " .set mips3 \n" - "1: ll %0, %2 # __cmpxchg_u32 \n" - " bne %0, %z3, 2f \n" - " .set mips0 \n" - " move $1, %z4 \n" - " .set mips3 \n" - " sc $1, %1 \n" - " beqz $1, 3f \n" - "2: \n" - " .subsection 2 \n" - "3: b 1b \n" - " .previous \n" - " .set pop \n" - : "=&r" (retval), "=R" (*m) - : "R" (*m), "Jr" (old), "Jr" (new) - : "memory"); - } else { - unsigned long flags; - - raw_local_irq_save(flags); - retval = *m; - if (retval == old) - *m = new; - raw_local_irq_restore(flags); /* implies memory barrier */ - } - - smp_llsc_mb(); - - return retval; -} - -static inline unsigned long __cmpxchg_u32_local(volatile int * m, - unsigned long old, unsigned long new) -{ - __u32 retval; - - if (cpu_has_llsc && R10000_LLSC_WAR) { - __asm__ __volatile__( - " .set push \n" - " .set noat \n" - " .set mips3 \n" - "1: ll %0, %2 # __cmpxchg_u32 \n" - " bne %0, %z3, 2f \n" - " .set mips0 \n" - " move $1, %z4 \n" - " .set mips3 \n" - " sc $1, %1 \n" - " beqzl $1, 1b \n" - "2: \n" - " .set pop \n" - : "=&r" (retval), "=R" (*m) - : "R" (*m), "Jr" (old), "Jr" (new) - : "memory"); - } else if (cpu_has_llsc) { - __asm__ __volatile__( - " .set push \n" - " .set noat \n" - " .set mips3 \n" - "1: ll %0, %2 # __cmpxchg_u32 \n" - " bne %0, %z3, 2f \n" - " .set mips0 \n" - " move $1, %z4 \n" - " .set mips3 \n" - " sc $1, %1 \n" - " beqz $1, 1b \n" - "2: \n" - " .set pop \n" - : "=&r" (retval), "=R" (*m) - : "R" (*m), "Jr" (old), "Jr" (new) - : "memory"); - } else { - unsigned long flags; - - local_irq_save(flags); - retval = *m; - if (retval == old) - *m = new; - local_irq_restore(flags); /* implies memory barrier */ - } - - return retval; -} +#define xchg(ptr, x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))) -#ifdef CONFIG_64BIT -static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old, - unsigned long new) -{ - __u64 retval; - - if (cpu_has_llsc && R10000_LLSC_WAR) { - __asm__ __volatile__( - " .set push \n" - " .set noat \n" - " .set mips3 \n" - "1: lld %0, %2 # __cmpxchg_u64 \n" - " bne %0, %z3, 2f \n" - " move $1, %z4 \n" - " scd $1, %1 \n" - " beqzl $1, 1b \n" - "2: \n" - " .set pop \n" - : "=&r" (retval), "=R" (*m) - : "R" (*m), "Jr" (old), "Jr" (new) - : "memory"); - } else if (cpu_has_llsc) { - __asm__ __volatile__( - " .set push \n" - " .set noat \n" - " .set mips3 \n" - "1: lld %0, %2 # __cmpxchg_u64 \n" - " bne %0, %z3, 2f \n" - " move $1, %z4 \n" - " scd $1, %1 \n" - " beqz $1, 3f \n" - "2: \n" - " .subsection 2 \n" - "3: b 1b \n" - " .previous \n" - " .set pop \n" - : "=&r" (retval), "=R" (*m) - : "R" (*m), "Jr" (old), "Jr" (new) - : "memory"); - } else { - unsigned long flags; - - raw_local_irq_save(flags); - retval = *m; - if (retval == old) - *m = new; - raw_local_irq_restore(flags); /* implies memory barrier */ - } - - smp_llsc_mb(); - - return retval; -} - -static inline unsigned long __cmpxchg_u64_local(volatile int * m, - unsigned long old, unsigned long new) -{ - __u64 retval; - - if (cpu_has_llsc && R10000_LLSC_WAR) { - __asm__ __volatile__( - " .set push \n" - " .set noat \n" - " .set mips3 \n" - "1: lld %0, %2 # __cmpxchg_u64 \n" - " bne %0, %z3, 2f \n" - " move $1, %z4 \n" - " scd $1, %1 \n" - " beqzl $1, 1b \n" - "2: \n" - " .set pop \n" - : "=&r" (retval), "=R" (*m) - : "R" (*m), "Jr" (old), "Jr" (new) - : "memory"); - } else if (cpu_has_llsc) { - __asm__ __volatile__( - " .set push \n" - " .set noat \n" - " .set mips3 \n" - "1: lld %0, %2 # __cmpxchg_u64 \n" - " bne %0, %z3, 2f \n" - " move $1, %z4 \n" - " scd $1, %1 \n" - " beqz $1, 1b \n" - "2: \n" - " .set pop \n" - : "=&r" (retval), "=R" (*m) - : "R" (*m), "Jr" (old), "Jr" (new) - : "memory"); - } else { - unsigned long flags; - - local_irq_save(flags); - retval = *m; - if (retval == old) - *m = new; - local_irq_restore(flags); /* implies memory barrier */ - } - - return retval; -} - -#else -extern unsigned long __cmpxchg_u64_unsupported_on_32bit_kernels( - volatile int * m, unsigned long old, unsigned long new); -#define __cmpxchg_u64 __cmpxchg_u64_unsupported_on_32bit_kernels -extern unsigned long __cmpxchg_u64_local_unsupported_on_32bit_kernels( - volatile int * m, unsigned long old, unsigned long new); -#define __cmpxchg_u64_local __cmpxchg_u64_local_unsupported_on_32bit_kernels -#endif - -/* This function doesn't exist, so you'll get a linker error - if something tries to do an invalid cmpxchg(). */ -extern void __cmpxchg_called_with_bad_pointer(void); - -static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old, - unsigned long new, int size) -{ - switch (size) { - case 4: - return __cmpxchg_u32(ptr, old, new); - case 8: - return __cmpxchg_u64(ptr, old, new); - } - __cmpxchg_called_with_bad_pointer(); - return old; -} - -static inline unsigned long __cmpxchg_local(volatile void * ptr, - unsigned long old, unsigned long new, int size) -{ - switch (size) { - case 4: - return __cmpxchg_u32_local(ptr, old, new); - case 8: - return __cmpxchg_u64_local(ptr, old, new); - } - __cmpxchg_called_with_bad_pointer(); - return old; -} - -#define cmpxchg(ptr,old,new) \ - ((__typeof__(*(ptr)))__cmpxchg((ptr), \ - (unsigned long)(old), (unsigned long)(new),sizeof(*(ptr)))) - -#define cmpxchg_local(ptr,old,new) \ - ((__typeof__(*(ptr)))__cmpxchg_local((ptr), \ - (unsigned long)(old), (unsigned long)(new),sizeof(*(ptr)))) - -extern void set_handler (unsigned long offset, void *addr, unsigned long len); -extern void set_uncached_handler (unsigned long offset, void *addr, unsigned long len); +extern void set_handler(unsigned long offset, void *addr, unsigned long len); +extern void set_uncached_handler(unsigned long offset, void *addr, unsigned long len); typedef void (*vi_handler_t)(void); -extern void *set_vi_handler (int n, vi_handler_t addr); +extern void *set_vi_handler(int n, vi_handler_t addr); extern void *set_except_vector(int n, void *addr); extern unsigned long ebase; extern void per_cpu_trap_init(void); -extern int stop_a_enabled; - /* * See include/asm-ia64/system.h; prevents deadlock on SMP * systems.