1 /*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 by Ralf Baechle
7 * Modified further for R[236]000 by Paul M. Antoine, 1996
8 * Copyright (C) 1999 Silicon Graphics
9 */
10 #ifndef _ASM_SYSTEM_H
11 #define _ASM_SYSTEM_H
12
13 #include <linux/config.h>
14
15 #include <asm/sgidefs.h>
16 #include <linux/kernel.h>
17
18 extern __inline__ void
19 __sti(void)
20 {
21 __asm__ __volatile__(
22 ".set\tnoreorder\n\t"
23 ".set\tnoat\n\t"
24 "mfc0\t$1,$12\n\t"
25 "ori\t$1,0x1f\n\t"
26 "xori\t$1,0x1e\n\t"
27 "mtc0\t$1,$12\n\t"
28 ".set\tat\n\t"
29 ".set\treorder"
30 : /* no outputs */
31 : /* no inputs */
32 : "$1", "memory");
33 }
34
35 /*
36 * For cli() we have to insert nops to make shure that the new value
37 * has actually arrived in the status register before the end of this
38 * macro.
39 * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
40 * no nops at all.
41 */
42 extern __inline__ void
43 __cli(void)
44 {
45 __asm__ __volatile__(
46 ".set\tnoreorder\n\t"
47 ".set\tnoat\n\t"
48 "mfc0\t$1,$12\n\t"
49 "ori\t$1,1\n\t"
50 "xori\t$1,1\n\t"
51 "mtc0\t$1,$12\n\t"
52 "nop\n\t"
53 "nop\n\t"
54 "nop\n\t"
55 ".set\tat\n\t"
56 ".set\treorder"
57 : /* no outputs */
58 : /* no inputs */
59 : "$1", "memory");
60 }
61
62 #define __save_flags(x) \
63 __asm__ __volatile__( \
64 ".set\tnoreorder\n\t" \
65 "mfc0\t%0,$12\n\t" \
66 ".set\treorder" \
67 : "=r" (x))
68
69 #define __save_and_cli(x) \
70 __asm__ __volatile__( \
71 ".set\tnoreorder\n\t" \
72 ".set\tnoat\n\t" \
73 "mfc0\t%0,$12\n\t" \
74 "ori\t$1,%0,1\n\t" \
75 "xori\t$1,1\n\t" \
76 "mtc0\t$1,$12\n\t" \
77 "nop\n\t" \
78 "nop\n\t" \
79 "nop\n\t" \
80 ".set\tat\n\t" \
81 ".set\treorder" \
82 : "=r" (x) \
83 : /* no inputs */ \
84 : "$1", "memory")
85
86 #define __restore_flags(flags) \
87 do { \
88 unsigned long __tmp1; \
89 \
90 __asm__ __volatile__( \
91 ".set\tnoreorder\t\t\t# __restore_flags\n\t" \
92 ".set\tnoat\n\t" \
93 "mfc0\t$1, $12\n\t" \
94 "andi\t%0, 1\n\t" \
95 "ori\t$1, 1\n\t" \
96 "xori\t$1, 1\n\t" \
97 "or\t%0, $1\n\t" \
98 "mtc0\t%0, $12\n\t" \
99 "nop\n\t" \
100 "nop\n\t" \
101 "nop\n\t" \
102 ".set\tat\n\t" \
103 ".set\treorder" \
104 : "=r" (__tmp1) \
105 : "" (flags) \
106 : "$1", "memory"); \
107 } while(0)
108
109 #ifdef CONFIG_SMP
110
111 extern void __global_cli(void);
112 extern void __global_sti(void);
113 extern unsigned long __global_save_flags(void);
114 extern void __global_restore_flags(unsigned long);
115 #define cli() __global_cli()
116 #define sti() __global_sti()
117 #define save_flags(x) ((x)=__global_save_flags())
118 #define restore_flags(x) __global_restore_flags(x)
119 #define save_and_cli(x) do { save_flags(x); cli(); } while(0)
120
121 #else
122
123 #define cli() __cli()
124 #define sti() __sti()
125 #define save_flags(x) __save_flags(x)
126 #define restore_flags(x) __restore_flags(x)
127 #define save_and_cli(x) __save_and_cli(x)
128
129 #endif /* CONFIG_SMP */
130
131 /* For spinlocks etc */
132 #define local_irq_save(x) __save_and_cli(x);
133 #define local_irq_restore(x) __restore_flags(x);
134 #define local_irq_disable() __cli();
135 #define local_irq_enable() __sti();
136
137 /*
138 * These are probably defined overly paranoid ...
139 */
140 #define mb() \
141 __asm__ __volatile__( \
142 "# prevent instructions being moved around\n\t" \
143 ".set\tnoreorder\n\t" \
144 "sync\n\t" \
145 ".set\treorder" \
146 : /* no output */ \
147 : /* no input */ \
148 : "memory")
149 #define rmb() mb()
150 #define wmb() mb()
151
152 #ifdef CONFIG_SMP
153 #define smp_mb() mb()
154 #define smp_rmb() rmb()
155 #define smp_wmb() wmb()
156 #else
157 #define smp_mb() barrier()
158 #define smp_rmb() barrier()
159 #define smp_wmb() barrier()
160 #endif
161
162 #define set_mb(var, value) \
163 do { var = value; mb(); } while (0)
164
165 #define set_wmb(var, value) \
166 do { var = value; wmb(); } while (0)
167
168 #if !defined (_LANGUAGE_ASSEMBLY)
169 /*
170 * switch_to(n) should switch tasks to task nr n, first
171 * checking that n isn't the current task, in which case it does nothing.
172 */
173 extern asmlinkage void *resume(void *last, void *next);
174 #endif /* !defined (_LANGUAGE_ASSEMBLY) */
175
176 #define prepare_to_switch() do { } while(0)
177
178 extern asmlinkage void lazy_fpu_switch(void *, void *);
179 extern asmlinkage void init_fpu(void);
180 extern asmlinkage void save_fp(void *);
181
182 #ifdef CONFIG_SMP
183 #define SWITCH_DO_LAZY_FPU \
184 if (prev->flags & PF_USEDFPU) { \
185 lazy_fpu_switch(prev, 0); \
186 set_cp0_status(ST0_CU1, ~ST0_CU1); \
187 prev->flags &= ~PF_USEDFPU; \
188 }
189 #else /* CONFIG_SMP */
190 #define SWITCH_DO_LAZY_FPU do { } while(0)
191 #endif /* CONFIG_SMP */
192
193 #define switch_to(prev,next,last) \
194 do { \
195 SWITCH_DO_LAZY_FPU; \
196 (last) = resume(prev, next); \
197 } while(0)
198
199 extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val)
200 {
201 unsigned long dummy;
202
203 __asm__ __volatile__(
204 ".set\tnoreorder\t\t\t# xchg_u32\n\t"
205 ".set\tnoat\n\t"
206 "ll\t%0, %3\n"
207 "1:\tmove\t$1, %2\n\t"
208 "sc\t$1, %1\n\t"
209 "beqzl\t$1, 1b\n\t"
210 " ll\t%0, %3\n\t"
211 ".set\tat\n\t"
212 ".set\treorder"
213 : "=r" (val), "=o" (*m), "=r" (dummy)
214 : "o" (*m), "2" (val)
215 : "memory");
216
217 return val;
218 }
219
220 extern __inline__ unsigned long xchg_u64(volatile long * m, unsigned long val)
221 {
222 unsigned long dummy;
223
224 __asm__ __volatile__(
225 ".set\tnoreorder\t\t\t# xchg_u64\n\t"
226 ".set\tnoat\n\t"
227 "lld\t%0, %3\n"
228 "1:\tmove\t$1, %2\n\t"
229 "scd\t$1, %1\n\t"
230 "beqzl\t$1, 1b\n\t"
231 " lld\t%0, %3\n\t"
232 ".set\tat\n\t"
233 ".set\treorder"
234 : "=r" (val), "=o" (*m), "=r" (dummy)
235 : "o" (*m), "2" (val)
236 : "memory");
237
238 return val;
239 }
240
241 #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
242 #define tas(ptr) (xchg((ptr),1))
243
244
245 static __inline__ unsigned long
246 __xchg(unsigned long x, volatile void * ptr, int size)
247 {
248 switch (size) {
249 case 4:
250 return xchg_u32(ptr, x);
251 case 8:
252 return xchg_u64(ptr, x);
253 }
254 return x;
255 }
256
257 extern void set_except_vector(int n, void *addr);
258
259 #endif /* _ASM_SYSTEM_H */
260
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.