mm: remove ptep_test_and_clear_dirty and ptep_clear_flush_dirty
[safe/jmp/linux-2.6] / include / asm-m32r / system.h
1 #ifndef _ASM_M32R_SYSTEM_H
2 #define _ASM_M32R_SYSTEM_H
3
4 /*
5  * This file is subject to the terms and conditions of the GNU General Public
6  * License.  See the file "COPYING" in the main directory of this archive
7  * for more details.
8  *
9  * Copyright (C) 2001  Hiroyuki Kondo, Hirokazu Takata, and Hitoshi Yamamoto
10  * Copyright (C) 2004, 2006  Hirokazu Takata <takata at linux-m32r.org>
11  */
12
13 #include <linux/compiler.h>
14 #include <asm/assembler.h>
15
16 #ifdef __KERNEL__
17
18 /*
19  * switch_to(prev, next) should switch from task `prev' to `next'
20  * `prev' will never be the same as `next'.
21  *
22  * `next' and `prev' should be struct task_struct, but it isn't always defined
23  */
24
25 #if defined(CONFIG_FRAME_POINTER) || \
26         !defined(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER)
27 #define M32R_PUSH_FP "  push fp\n"
28 #define M32R_POP_FP  "  pop  fp\n"
29 #else
30 #define M32R_PUSH_FP ""
31 #define M32R_POP_FP  ""
32 #endif
33
34 #define switch_to(prev, next, last)  do { \
35         __asm__ __volatile__ ( \
36                 "       seth    lr, #high(1f)                           \n" \
37                 "       or3     lr, lr, #low(1f)                        \n" \
38                 "       st      lr, @%4  ; store old LR                 \n" \
39                 "       ld      lr, @%5  ; load new LR                  \n" \
40                         M32R_PUSH_FP \
41                 "       st      sp, @%2  ; store old SP                 \n" \
42                 "       ld      sp, @%3  ; load new SP                  \n" \
43                 "       push    %1  ; store `prev' on new stack         \n" \
44                 "       jmp     lr                                      \n" \
45                 "       .fillinsn                                       \n" \
46                 "1:                                                     \n" \
47                 "       pop     %0  ; restore `__last' from new stack   \n" \
48                         M32R_POP_FP \
49                 : "=r" (last) \
50                 : "0" (prev), \
51                   "r" (&(prev->thread.sp)), "r" (&(next->thread.sp)), \
52                   "r" (&(prev->thread.lr)), "r" (&(next->thread.lr)) \
53                 : "memory", "lr" \
54         ); \
55 } while(0)
56
57 /*
58  * On SMP systems, when the scheduler does migration-cost autodetection,
59  * it needs a way to flush as much of the CPU's caches as possible.
60  *
61  * TODO: fill this in!
62  */
63 static inline void sched_cacheflush(void)
64 {
65 }
66
67 /* Interrupt Control */
68 #if !defined(CONFIG_CHIP_M32102) && !defined(CONFIG_CHIP_M32104)
69 #define local_irq_enable() \
70         __asm__ __volatile__ ("setpsw #0x40 -> nop": : :"memory")
71 #define local_irq_disable() \
72         __asm__ __volatile__ ("clrpsw #0x40 -> nop": : :"memory")
73 #else   /* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
74 static inline void local_irq_enable(void)
75 {
76         unsigned long tmpreg;
77         __asm__ __volatile__(
78                 "mvfc   %0, psw;                \n\t"
79                 "or3    %0, %0, #0x0040;        \n\t"
80                 "mvtc   %0, psw;                \n\t"
81         : "=&r" (tmpreg) : : "cbit", "memory");
82 }
83
84 static inline void local_irq_disable(void)
85 {
86         unsigned long tmpreg0, tmpreg1;
87         __asm__ __volatile__(
88                 "ld24   %0, #0  ; Use 32-bit insn. \n\t"
89                 "mvfc   %1, psw ; No interrupt can be accepted here. \n\t"
90                 "mvtc   %0, psw \n\t"
91                 "and3   %0, %1, #0xffbf \n\t"
92                 "mvtc   %0, psw \n\t"
93         : "=&r" (tmpreg0), "=&r" (tmpreg1) : : "cbit", "memory");
94 }
95 #endif  /* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
96
97 #define local_save_flags(x) \
98         __asm__ __volatile__("mvfc %0,psw" : "=r"(x) : /* no input */)
99
100 #define local_irq_restore(x) \
101         __asm__ __volatile__("mvtc %0,psw" : /* no outputs */ \
102                 : "r" (x) : "cbit", "memory")
103
104 #if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
105 #define local_irq_save(x)                               \
106         __asm__ __volatile__(                           \
107                 "mvfc   %0, psw;                \n\t"   \
108                 "clrpsw #0x40 -> nop;           \n\t"   \
109                 : "=r" (x) : /* no input */ : "memory")
110 #else   /* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
111 #define local_irq_save(x)                               \
112         ({                                              \
113                 unsigned long tmpreg;                   \
114                 __asm__ __volatile__(                   \
115                         "ld24   %1, #0 \n\t"            \
116                         "mvfc   %0, psw \n\t"           \
117                         "mvtc   %1, psw \n\t"           \
118                         "and3   %1, %0, #0xffbf \n\t"   \
119                         "mvtc   %1, psw \n\t"           \
120                         : "=r" (x), "=&r" (tmpreg)      \
121                         : : "cbit", "memory");          \
122         })
123 #endif  /* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
124
125 #define irqs_disabled()                                 \
126         ({                                              \
127                 unsigned long flags;                    \
128                 local_save_flags(flags);                \
129                 !(flags & 0x40);                        \
130         })
131
132 #define nop()   __asm__ __volatile__ ("nop" : : )
133
134 #define xchg(ptr,x) \
135         ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
136
137 #ifdef CONFIG_SMP
138 extern void  __xchg_called_with_bad_pointer(void);
139 #endif
140
141 #ifdef CONFIG_CHIP_M32700_TS1
142 #define DCACHE_CLEAR(reg0, reg1, addr)                          \
143         "seth   "reg1", #high(dcache_dummy);            \n\t"   \
144         "or3    "reg1", "reg1", #low(dcache_dummy);     \n\t"   \
145         "lock   "reg0", @"reg1";                        \n\t"   \
146         "add3   "reg0", "addr", #0x1000;                \n\t"   \
147         "ld     "reg0", @"reg0";                        \n\t"   \
148         "add3   "reg0", "addr", #0x2000;                \n\t"   \
149         "ld     "reg0", @"reg0";                        \n\t"   \
150         "unlock "reg0", @"reg1";                        \n\t"
151         /* FIXME: This workaround code cannot handle kernel modules
152          * correctly under SMP environment.
153          */
154 #else   /* CONFIG_CHIP_M32700_TS1 */
155 #define DCACHE_CLEAR(reg0, reg1, addr)
156 #endif  /* CONFIG_CHIP_M32700_TS1 */
157
158 static __always_inline unsigned long
159 __xchg(unsigned long x, volatile void * ptr, int size)
160 {
161         unsigned long flags;
162         unsigned long tmp = 0;
163
164         local_irq_save(flags);
165
166         switch (size) {
167 #ifndef CONFIG_SMP
168         case 1:
169                 __asm__ __volatile__ (
170                         "ldb    %0, @%2 \n\t"
171                         "stb    %1, @%2 \n\t"
172                         : "=&r" (tmp) : "r" (x), "r" (ptr) : "memory");
173                 break;
174         case 2:
175                 __asm__ __volatile__ (
176                         "ldh    %0, @%2 \n\t"
177                         "sth    %1, @%2 \n\t"
178                         : "=&r" (tmp) : "r" (x), "r" (ptr) : "memory");
179                 break;
180         case 4:
181                 __asm__ __volatile__ (
182                         "ld     %0, @%2 \n\t"
183                         "st     %1, @%2 \n\t"
184                         : "=&r" (tmp) : "r" (x), "r" (ptr) : "memory");
185                 break;
186 #else  /* CONFIG_SMP */
187         case 4:
188                 __asm__ __volatile__ (
189                         DCACHE_CLEAR("%0", "r4", "%2")
190                         "lock   %0, @%2;        \n\t"
191                         "unlock %1, @%2;        \n\t"
192                         : "=&r" (tmp) : "r" (x), "r" (ptr)
193                         : "memory"
194 #ifdef CONFIG_CHIP_M32700_TS1
195                         , "r4"
196 #endif  /* CONFIG_CHIP_M32700_TS1 */
197                 );
198                 break;
199         default:
200                 __xchg_called_with_bad_pointer();
201 #endif  /* CONFIG_SMP */
202         }
203
204         local_irq_restore(flags);
205
206         return (tmp);
207 }
208
209 #define __HAVE_ARCH_CMPXCHG     1
210
211 static inline unsigned long
212 __cmpxchg_u32(volatile unsigned int *p, unsigned int old, unsigned int new)
213 {
214         unsigned long flags;
215         unsigned int retval;
216
217         local_irq_save(flags);
218         __asm__ __volatile__ (
219                         DCACHE_CLEAR("%0", "r4", "%1")
220                         M32R_LOCK" %0, @%1;     \n"
221                 "       bne     %0, %2, 1f;     \n"
222                         M32R_UNLOCK" %3, @%1;   \n"
223                 "       bra     2f;             \n"
224                 "       .fillinsn               \n"
225                 "1:"
226                         M32R_UNLOCK" %0, @%1;   \n"
227                 "       .fillinsn               \n"
228                 "2:"
229                         : "=&r" (retval)
230                         : "r" (p), "r" (old), "r" (new)
231                         : "cbit", "memory"
232 #ifdef CONFIG_CHIP_M32700_TS1
233                         , "r4"
234 #endif  /* CONFIG_CHIP_M32700_TS1 */
235                 );
236         local_irq_restore(flags);
237
238         return retval;
239 }
240
241 /* This function doesn't exist, so you'll get a linker error
242    if something tries to do an invalid cmpxchg().  */
243 extern void __cmpxchg_called_with_bad_pointer(void);
244
245 static inline unsigned long
246 __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
247 {
248         switch (size) {
249         case 4:
250                 return __cmpxchg_u32(ptr, old, new);
251 #if 0   /* we don't have __cmpxchg_u64 */
252         case 8:
253                 return __cmpxchg_u64(ptr, old, new);
254 #endif /* 0 */
255         }
256         __cmpxchg_called_with_bad_pointer();
257         return old;
258 }
259
260 #define cmpxchg(ptr,o,n)                                                 \
261   ({                                                                     \
262      __typeof__(*(ptr)) _o_ = (o);                                       \
263      __typeof__(*(ptr)) _n_ = (n);                                       \
264      (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,           \
265                                     (unsigned long)_n_, sizeof(*(ptr))); \
266   })
267
268 #endif  /* __KERNEL__ */
269
270 /*
271  * Memory barrier.
272  *
273  * mb() prevents loads and stores being reordered across this point.
274  * rmb() prevents loads being reordered across this point.
275  * wmb() prevents stores being reordered across this point.
276  */
277 #define mb()   barrier()
278 #define rmb()  mb()
279 #define wmb()  mb()
280
281 /**
282  * read_barrier_depends - Flush all pending reads that subsequents reads
283  * depend on.
284  *
285  * No data-dependent reads from memory-like regions are ever reordered
286  * over this barrier.  All reads preceding this primitive are guaranteed
287  * to access memory (but not necessarily other CPUs' caches) before any
288  * reads following this primitive that depend on the data return by
289  * any of the preceding reads.  This primitive is much lighter weight than
290  * rmb() on most CPUs, and is never heavier weight than is
291  * rmb().
292  *
293  * These ordering constraints are respected by both the local CPU
294  * and the compiler.
295  *
296  * Ordering is not guaranteed by anything other than these primitives,
297  * not even by data dependencies.  See the documentation for
298  * memory_barrier() for examples and URLs to more information.
299  *
300  * For example, the following code would force ordering (the initial
301  * value of "a" is zero, "b" is one, and "p" is "&a"):
302  *
303  * <programlisting>
304  *      CPU 0                           CPU 1
305  *
306  *      b = 2;
307  *      memory_barrier();
308  *      p = &b;                         q = p;
309  *                                      read_barrier_depends();
310  *                                      d = *q;
311  * </programlisting>
312  *
313  *
314  * because the read of "*q" depends on the read of "p" and these
315  * two reads are separated by a read_barrier_depends().  However,
316  * the following code, with the same initial values for "a" and "b":
317  *
318  * <programlisting>
319  *      CPU 0                           CPU 1
320  *
321  *      a = 2;
322  *      memory_barrier();
323  *      b = 3;                          y = b;
324  *                                      read_barrier_depends();
325  *                                      x = a;
326  * </programlisting>
327  *
328  * does not enforce ordering, since there is no data dependency between
329  * the read of "a" and the read of "b".  Therefore, on some CPUs, such
330  * as Alpha, "y" could be set to 3 and "x" to 0.  Use rmb()
331  * in cases like this where there are no data dependencies.
332  **/
333
334 #define read_barrier_depends()  do { } while (0)
335
336 #ifdef CONFIG_SMP
337 #define smp_mb()        mb()
338 #define smp_rmb()       rmb()
339 #define smp_wmb()       wmb()
340 #define smp_read_barrier_depends()      read_barrier_depends()
341 #define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
342 #else
343 #define smp_mb()        barrier()
344 #define smp_rmb()       barrier()
345 #define smp_wmb()       barrier()
346 #define smp_read_barrier_depends()      do { } while (0)
347 #define set_mb(var, value) do { var = value; barrier(); } while (0)
348 #endif
349
350 #define arch_align_stack(x) (x)
351
352 #endif /* _ASM_M32R_SYSTEM_H */