~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/m32r/include/asm/cmpxchg.h

Version: ~ [ linux-5.11-rc3 ] ~ [ linux-5.10.7 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.89 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.167 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.215 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.251 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.251 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #ifndef _ASM_M32R_CMPXCHG_H
  2 #define _ASM_M32R_CMPXCHG_H
  3 
  4 /*
  5  *  M32R version:
  6  *    Copyright (C) 2001, 2002  Hitoshi Yamamoto
  7  *    Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.org>
  8  */
  9 
 10 #include <linux/irqflags.h>
 11 #include <asm/assembler.h>
 12 #include <asm/dcache_clear.h>
 13 
 14 extern void  __xchg_called_with_bad_pointer(void);
 15 
 16 static __always_inline unsigned long
 17 __xchg(unsigned long x, volatile void *ptr, int size)
 18 {
 19         unsigned long flags;
 20         unsigned long tmp = 0;
 21 
 22         local_irq_save(flags);
 23 
 24         switch (size) {
 25 #ifndef CONFIG_SMP
 26         case 1:
 27                 __asm__ __volatile__ (
 28                         "ldb    %0, @%2 \n\t"
 29                         "stb    %1, @%2 \n\t"
 30                         : "=&r" (tmp) : "r" (x), "r" (ptr) : "memory");
 31                 break;
 32         case 2:
 33                 __asm__ __volatile__ (
 34                         "ldh    %0, @%2 \n\t"
 35                         "sth    %1, @%2 \n\t"
 36                         : "=&r" (tmp) : "r" (x), "r" (ptr) : "memory");
 37                 break;
 38         case 4:
 39                 __asm__ __volatile__ (
 40                         "ld     %0, @%2 \n\t"
 41                         "st     %1, @%2 \n\t"
 42                         : "=&r" (tmp) : "r" (x), "r" (ptr) : "memory");
 43                 break;
 44 #else  /* CONFIG_SMP */
 45         case 4:
 46                 __asm__ __volatile__ (
 47                         DCACHE_CLEAR("%0", "r4", "%2")
 48                         "lock   %0, @%2;        \n\t"
 49                         "unlock %1, @%2;        \n\t"
 50                         : "=&r" (tmp) : "r" (x), "r" (ptr)
 51                         : "memory"
 52 #ifdef CONFIG_CHIP_M32700_TS1
 53                         , "r4"
 54 #endif  /* CONFIG_CHIP_M32700_TS1 */
 55                 );
 56                 break;
 57 #endif  /* CONFIG_SMP */
 58         default:
 59                 __xchg_called_with_bad_pointer();
 60         }
 61 
 62         local_irq_restore(flags);
 63 
 64         return (tmp);
 65 }
 66 
 67 #define xchg(ptr, x)                                                    \
 68         ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
 69 
 70 static __always_inline unsigned long
 71 __xchg_local(unsigned long x, volatile void *ptr, int size)
 72 {
 73         unsigned long flags;
 74         unsigned long tmp = 0;
 75 
 76         local_irq_save(flags);
 77 
 78         switch (size) {
 79         case 1:
 80                 __asm__ __volatile__ (
 81                         "ldb    %0, @%2 \n\t"
 82                         "stb    %1, @%2 \n\t"
 83                         : "=&r" (tmp) : "r" (x), "r" (ptr) : "memory");
 84                 break;
 85         case 2:
 86                 __asm__ __volatile__ (
 87                         "ldh    %0, @%2 \n\t"
 88                         "sth    %1, @%2 \n\t"
 89                         : "=&r" (tmp) : "r" (x), "r" (ptr) : "memory");
 90                 break;
 91         case 4:
 92                 __asm__ __volatile__ (
 93                         "ld     %0, @%2 \n\t"
 94                         "st     %1, @%2 \n\t"
 95                         : "=&r" (tmp) : "r" (x), "r" (ptr) : "memory");
 96                 break;
 97         default:
 98                 __xchg_called_with_bad_pointer();
 99         }
100 
101         local_irq_restore(flags);
102 
103         return (tmp);
104 }
105 
106 #define xchg_local(ptr, x)                                              \
107         ((__typeof__(*(ptr)))__xchg_local((unsigned long)(x), (ptr),    \
108                         sizeof(*(ptr))))
109 
110 #define __HAVE_ARCH_CMPXCHG     1
111 
112 static inline unsigned long
113 __cmpxchg_u32(volatile unsigned int *p, unsigned int old, unsigned int new)
114 {
115         unsigned long flags;
116         unsigned int retval;
117 
118         local_irq_save(flags);
119         __asm__ __volatile__ (
120                         DCACHE_CLEAR("%0", "r4", "%1")
121                         M32R_LOCK" %0, @%1;     \n"
122                 "       bne     %0, %2, 1f;     \n"
123                         M32R_UNLOCK" %3, @%1;   \n"
124                 "       bra     2f;             \n"
125                 "       .fillinsn               \n"
126                 "1:"
127                         M32R_UNLOCK" %0, @%1;   \n"
128                 "       .fillinsn               \n"
129                 "2:"
130                         : "=&r" (retval)
131                         : "r" (p), "r" (old), "r" (new)
132                         : "cbit", "memory"
133 #ifdef CONFIG_CHIP_M32700_TS1
134                         , "r4"
135 #endif  /* CONFIG_CHIP_M32700_TS1 */
136                 );
137         local_irq_restore(flags);
138 
139         return retval;
140 }
141 
142 static inline unsigned long
143 __cmpxchg_local_u32(volatile unsigned int *p, unsigned int old,
144                         unsigned int new)
145 {
146         unsigned long flags;
147         unsigned int retval;
148 
149         local_irq_save(flags);
150         __asm__ __volatile__ (
151                         DCACHE_CLEAR("%0", "r4", "%1")
152                         "ld %0, @%1;            \n"
153                 "       bne     %0, %2, 1f;     \n"
154                         "st %3, @%1;            \n"
155                 "       bra     2f;             \n"
156                 "       .fillinsn               \n"
157                 "1:"
158                         "st %0, @%1;            \n"
159                 "       .fillinsn               \n"
160                 "2:"
161                         : "=&r" (retval)
162                         : "r" (p), "r" (old), "r" (new)
163                         : "cbit", "memory"
164 #ifdef CONFIG_CHIP_M32700_TS1
165                         , "r4"
166 #endif  /* CONFIG_CHIP_M32700_TS1 */
167                 );
168         local_irq_restore(flags);
169 
170         return retval;
171 }
172 
173 /* This function doesn't exist, so you'll get a linker error
174    if something tries to do an invalid cmpxchg().  */
175 extern void __cmpxchg_called_with_bad_pointer(void);
176 
177 static inline unsigned long
178 __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
179 {
180         switch (size) {
181         case 4:
182                 return __cmpxchg_u32(ptr, old, new);
183 #if 0   /* we don't have __cmpxchg_u64 */
184         case 8:
185                 return __cmpxchg_u64(ptr, old, new);
186 #endif /* 0 */
187         }
188         __cmpxchg_called_with_bad_pointer();
189         return old;
190 }
191 
192 #define cmpxchg(ptr, o, n)                                               \
193         ((__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)(o),       \
194                         (unsigned long)(n), sizeof(*(ptr))))
195 
196 #include <asm-generic/cmpxchg-local.h>
197 
198 static inline unsigned long __cmpxchg_local(volatile void *ptr,
199                                       unsigned long old,
200                                       unsigned long new, int size)
201 {
202         switch (size) {
203         case 4:
204                 return __cmpxchg_local_u32(ptr, old, new);
205         default:
206                 return __cmpxchg_local_generic(ptr, old, new, size);
207         }
208 
209         return old;
210 }
211 
212 /*
213  * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
214  * them available.
215  */
216 #define cmpxchg_local(ptr, o, n)                                            \
217         ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o),     \
218                         (unsigned long)(n), sizeof(*(ptr))))
219 #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
220 
221 #endif /* _ASM_M32R_CMPXCHG_H */
222 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp