Revert last change. Bug noticed by Linus.
[linux-2.6/linux-mips.git] / include / asm-m68k / system.h
blob7b6ae7d16f32273a4065bbed0e492e7b307100ad
1 #ifndef _M68K_SYSTEM_H
2 #define _M68K_SYSTEM_H
4 #include <linux/config.h> /* get configuration macros */
5 #include <linux/linkage.h>
6 #include <asm/segment.h>
7 #include <asm/entry.h>
9 #define prepare_to_switch() do { } while(0)
12 * switch_to(n) should switch tasks to task ptr, first checking that
13 * ptr isn't the current task, in which case it does nothing. This
14 * also clears the TS-flag if the task we switched to has used the
15 * math co-processor latest.
18 * switch_to() saves the extra registers, that are not saved
19 * automatically by SAVE_SWITCH_STACK in resume(), ie. d0-d5 and
20 * a0-a1. Some of these are used by schedule() and its predecessors
21 * and so we might get see unexpected behaviors when a task returns
22 * with unexpected register values.
24 * syscall stores these registers itself and none of them are used
25 * by syscall after the function in the syscall has been called.
27 * Beware that resume now expects *next to be in d1 and the offset of
28 * tss to be in a1. This saves a few instructions as we no longer have
29 * to push them onto the stack and read them back right after.
31 * 02/17/96 - Jes Sorensen (jds@kom.auc.dk)
33 * Changed 96/09/19 by Andreas Schwab
34 * pass prev in a0, next in a1, offset of tss in d1, and whether
35 * the mm structures are shared in d2 (to avoid atc flushing).
37 asmlinkage void resume(void);
38 #define switch_to(prev,next,last) { \
39 register void *_prev __asm__ ("a0") = (prev); \
40 register void *_next __asm__ ("a1") = (next); \
41 register void *_last __asm__ ("d1"); \
42 __asm__ __volatile__("jbsr " SYMBOL_NAME_STR(resume) \
43 : "=d" (_last) : "a" (_prev), "a" (_next) \
44 : "d0", "d1", "d2", "d3", "d4", "d5", "a0", "a1"); \
45 (last) = _last; \
49 /* interrupt control.. */
50 #if 0
51 #define __sti() asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory")
52 #else
53 #include <asm/hardirq.h>
54 #define __sti() ({ \
55 if (!local_irq_count[smp_processor_id()]) \
56 asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory"); \
58 #endif
59 #define __cli() asm volatile ("oriw #0x0700,%%sr": : : "memory")
60 #define __save_flags(x) asm volatile ("movew %%sr,%0":"=d" (x) : : "memory")
61 #define __restore_flags(x) asm volatile ("movew %0,%%sr": :"d" (x) : "memory")
63 /* For spinlocks etc */
64 #define local_irq_save(x) ({ __save_flags(x); __cli(); })
65 #define local_irq_restore(x) __restore_flags(x)
66 #define local_irq_disable() __cli()
67 #define local_irq_enable() __sti()
69 #define cli() __cli()
70 #define sti() __sti()
71 #define save_flags(x) __save_flags(x)
72 #define restore_flags(x) __restore_flags(x)
76 * Force strict CPU ordering.
77 * Not really required on m68k...
79 #define nop() asm volatile ("nop"::)
80 #define mb() asm volatile ("" : : :"memory")
81 #define rmb() asm volatile ("" : : :"memory")
82 #define wmb() asm volatile ("" : : :"memory")
83 #define set_rmb(var, value) do { xchg(&var, value); } while (0)
84 #define set_mb(var, value) set_rmb(var, value)
85 #define set_wmb(var, value) do { var = value; wmb(); } while (0)
88 #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
89 #define tas(ptr) (xchg((ptr),1))
91 struct __xchg_dummy { unsigned long a[100]; };
92 #define __xg(x) ((volatile struct __xchg_dummy *)(x))
94 #ifndef CONFIG_RMW_INSNS
95 static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
97 unsigned long tmp, flags;
99 save_flags(flags);
100 cli();
102 switch (size) {
103 case 1:
104 __asm__ __volatile__
105 ("moveb %2,%0\n\t"
106 "moveb %1,%2"
107 : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
108 break;
109 case 2:
110 __asm__ __volatile__
111 ("movew %2,%0\n\t"
112 "movew %1,%2"
113 : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
114 break;
115 case 4:
116 __asm__ __volatile__
117 ("movel %2,%0\n\t"
118 "movel %1,%2"
119 : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
120 break;
122 restore_flags(flags);
123 return tmp;
125 #else
126 static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
128 switch (size) {
129 case 1:
130 __asm__ __volatile__
131 ("moveb %2,%0\n\t"
132 "1:\n\t"
133 "casb %0,%1,%2\n\t"
134 "jne 1b"
135 : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory");
136 break;
137 case 2:
138 __asm__ __volatile__
139 ("movew %2,%0\n\t"
140 "1:\n\t"
141 "casw %0,%1,%2\n\t"
142 "jne 1b"
143 : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory");
144 break;
145 case 4:
146 __asm__ __volatile__
147 ("movel %2,%0\n\t"
148 "1:\n\t"
149 "casl %0,%1,%2\n\t"
150 "jne 1b"
151 : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory");
152 break;
154 return x;
156 #endif
158 #endif /* _M68K_SYSTEM_H */