Merge with Linux 2.4.0-test6-pre2.
[linux-2.6/linux-mips.git] / include / asm-mips64 / system.h
blob4b9d9f551a9aeebc3120ff5ca17fcfcb27bd2166
1 /* $Id: system.h,v 1.5 2000/01/27 07:48:08 kanoj Exp $
3 * This file is subject to the terms and conditions of the GNU General Public
4 * License. See the file "COPYING" in the main directory of this archive
5 * for more details.
7 * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 by Ralf Baechle
8 * Modified further for R[236]000 by Paul M. Antoine, 1996
9 * Copyright (C) 1999 Silicon Graphics
11 #ifndef _ASM_SYSTEM_H
12 #define _ASM_SYSTEM_H
14 #include <linux/config.h>
16 #include <asm/sgidefs.h>
17 #include <linux/kernel.h>
19 extern __inline__ void
20 __sti(void)
22 __asm__ __volatile__(
23 ".set\tnoreorder\n\t"
24 ".set\tnoat\n\t"
25 "mfc0\t$1,$12\n\t"
26 "ori\t$1,0x1f\n\t"
27 "xori\t$1,0x1e\n\t"
28 "mtc0\t$1,$12\n\t"
29 ".set\tat\n\t"
30 ".set\treorder"
31 : /* no outputs */
32 : /* no inputs */
33 : "$1", "memory");
37 * For cli() we have to insert nops to make shure that the new value
38 * has actually arrived in the status register before the end of this
39 * macro.
40 * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
41 * no nops at all.
43 extern __inline__ void
44 __cli(void)
46 __asm__ __volatile__(
47 ".set\tnoreorder\n\t"
48 ".set\tnoat\n\t"
49 "mfc0\t$1,$12\n\t"
50 "ori\t$1,1\n\t"
51 "xori\t$1,1\n\t"
52 "mtc0\t$1,$12\n\t"
53 "nop\n\t"
54 "nop\n\t"
55 "nop\n\t"
56 ".set\tat\n\t"
57 ".set\treorder"
58 : /* no outputs */
59 : /* no inputs */
60 : "$1", "memory");
63 #define __save_flags(x) \
64 __asm__ __volatile__( \
65 ".set\tnoreorder\n\t" \
66 "mfc0\t%0,$12\n\t" \
67 ".set\treorder" \
68 : "=r" (x) \
69 : /* no inputs */ \
70 : "memory")
72 #define __save_and_cli(x) \
73 __asm__ __volatile__( \
74 ".set\tnoreorder\n\t" \
75 ".set\tnoat\n\t" \
76 "mfc0\t%0,$12\n\t" \
77 "ori\t$1,%0,1\n\t" \
78 "xori\t$1,1\n\t" \
79 "mtc0\t$1,$12\n\t" \
80 "nop\n\t" \
81 "nop\n\t" \
82 "nop\n\t" \
83 ".set\tat\n\t" \
84 ".set\treorder" \
85 : "=r" (x) \
86 : /* no inputs */ \
87 : "$1", "memory")
89 extern void __inline__
90 __restore_flags(int flags)
92 __asm__ __volatile__(
93 ".set\tnoreorder\n\t"
94 "mfc0\t$8,$12\n\t"
95 "li\t$9,0xff00\n\t"
96 "and\t$8,$9\n\t"
97 "nor\t$9,$0,$9\n\t"
98 "and\t%0,$9\n\t"
99 "or\t%0,$8\n\t"
100 "mtc0\t%0,$12\n\t"
101 "nop\n\t"
102 "nop\n\t"
103 "nop\n\t"
104 ".set\treorder"
105 : /* no output */
106 : "r" (flags)
107 : "$8", "$9", "memory");
110 #ifdef CONFIG_SMP
112 extern void __global_cli(void);
113 extern void __global_sti(void);
114 extern unsigned long __global_save_flags(void);
115 extern void __global_restore_flags(unsigned long);
116 #define cli() __global_cli()
117 #define sti() __global_sti()
118 #define save_flags(x) ((x)=__global_save_flags())
119 #define restore_flags(x) __global_restore_flags(x)
120 #define save_and_cli(x) do { save_flags(x); cli(); } while(0)
122 #else
124 #define cli() __cli()
125 #define sti() __sti()
126 #define save_flags(x) __save_flags(x)
127 #define restore_flags(x) __restore_flags(x)
128 #define save_and_cli(x) __save_and_cli(x)
130 #endif /* CONFIG_SMP */
132 /* For spinlocks etc */
133 #define local_irq_save(x) __save_and_cli(x);
134 #define local_irq_restore(x) __restore_flags(x);
135 #define local_irq_disable() __cli();
136 #define local_irq_enable() __sti();
139 * These are probably defined overly paranoid ...
141 #define mb() \
142 __asm__ __volatile__( \
143 "# prevent instructions being moved around\n\t" \
144 ".set\tnoreorder\n\t" \
145 "# 8 nops to fool the R4400 pipeline\n\t" \
146 "nop;nop;nop;nop;nop;nop;nop;nop\n\t" \
147 ".set\treorder" \
148 : /* no output */ \
149 : /* no input */ \
150 : "memory")
151 #define rmb() mb()
152 #define wmb() mb()
154 #define set_mb(var, value) \
155 do { var = value; mb(); } while (0)
157 #define set_wmb(var, value) \
158 do { var = value; wmb(); } while (0)
160 #if !defined (_LANGUAGE_ASSEMBLY)
162 * switch_to(n) should switch tasks to task nr n, first
163 * checking that n isn't the current task, in which case it does nothing.
165 extern asmlinkage void *resume(void *last, void *next);
166 #endif /* !defined (_LANGUAGE_ASSEMBLY) */
168 #define prepare_to_switch() do { } while(0)
170 extern asmlinkage void lazy_fpu_switch(void *, void *);
171 extern asmlinkage void init_fpu(void);
172 extern asmlinkage void save_fp(void *);
174 #ifdef CONFIG_SMP
175 #define SWITCH_DO_LAZY_FPU \
176 if (prev->flags & PF_USEDFPU) { \
177 lazy_fpu_switch(prev, 0); \
178 set_cp0_status(ST0_CU1, ~ST0_CU1); \
179 prev->flags &= ~PF_USEDFPU; \
181 #else /* CONFIG_SMP */
182 #define SWITCH_DO_LAZY_FPU do { } while(0)
183 #endif /* CONFIG_SMP */
185 #define switch_to(prev,next,last) \
186 do { \
187 SWITCH_DO_LAZY_FPU; \
188 (last) = resume(prev, next); \
189 } while(0)
191 extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val)
193 unsigned long dummy;
195 __asm__ __volatile__(
196 ".set\tnoreorder\n\t"
197 ".set\tnoat\n\t"
198 "ll\t%0,(%1)\n"
199 "1:\tmove\t$1,%2\n\t"
200 "sc\t$1,(%1)\n\t"
201 "beqzl\t$1,1b\n\t"
202 "lld\t%0,(%1)\n\t"
203 ".set\tat\n\t"
204 ".set\treorder"
205 : "=r" (val), "=r" (m), "=r" (dummy)
206 : "1" (m), "2" (val)
207 : "memory");
209 return val;
213 * Only used for 64 bit kernel.
215 extern __inline__ unsigned long xchg_u64(volatile long * m, unsigned long val)
217 unsigned long dummy;
219 __asm__ __volatile__(
220 ".set\tnoreorder\n\t"
221 ".set\tnoat\n\t"
222 "lld\t%0,(%1)\n"
223 "1:\tmove\t$1,%2\n\t"
224 "scd\t$1,(%1)\n\t"
225 "beqzl\t$1,1b\n\t"
226 "lld\t%0,(%1)\n\t"
227 ".set\tat\n\t"
228 ".set\treorder"
229 : "=r" (val), "=r" (m), "=r" (dummy)
230 : "1" (m), "2" (val)
231 : "memory");
233 return val;
236 #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
237 #define tas(ptr) (xchg((ptr),1))
239 /* This function doesn't exist, so you'll get a linker error if something
240 tries to do an invalid xchg(). */
241 extern void __xchg_called_with_bad_pointer(void);
243 static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
245 switch (size) {
246 case 4:
247 return xchg_u32(ptr, x);
248 case 8:
249 return xchg_u64(ptr, x);
251 __xchg_called_with_bad_pointer();
252 return x;
255 extern void set_except_vector(int n, void *addr);
257 #endif /* _ASM_SYSTEM_H */