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

Linux Cross Reference
Linux/include/asm-mips/system.h

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* $Id: system.h,v 1.20 1999/12/06 23:13:21 ralf Exp $
  2  *
  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.
  6  *
  7  * Copyright (C) 1994 - 1999 by Ralf Baechle
  8  * Copyright (C) 1996 by Paul M. Antoine
  9  * Copyright (C) 1994 - 1999 by Ralf Baechle
 10  */
 11 #ifndef _ASM_SYSTEM_H
 12 #define _ASM_SYSTEM_H
 13 
 14 #include <linux/config.h>
 15 #include <asm/sgidefs.h>
 16 #include <asm/ptrace.h>
 17 #include <linux/kernel.h>
 18 
 19 extern __inline__ void
 20 __sti(void)
 21 {
 22         __asm__ __volatile__(
 23                 ".set\tpush\n\t"
 24                 ".set\treorder\n\t"
 25                 ".set\tnoat\n\t"
 26                 "mfc0\t$1,$12\n\t"
 27                 "ori\t$1,0x1f\n\t"
 28                 "xori\t$1,0x1e\n\t"
 29                 "mtc0\t$1,$12\n\t"
 30                 ".set\tpop\n\t"
 31                 : /* no outputs */
 32                 : /* no inputs */
 33                 : "$1", "memory");
 34 }
 35 
 36 /*
 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.
 42  */
 43 extern __inline__ void
 44 __cli(void)
 45 {
 46         __asm__ __volatile__(
 47                 ".set\tpush\n\t"
 48                 ".set\treorder\n\t"
 49                 ".set\tnoat\n\t"
 50                 "mfc0\t$1,$12\n\t"
 51                 "ori\t$1,1\n\t"
 52                 "xori\t$1,1\n\t"
 53                 ".set\tnoreorder\n\t"
 54                 "mtc0\t$1,$12\n\t"
 55                 "nop\n\t"
 56                 "nop\n\t"
 57                 "nop\n\t"
 58                 ".set\tpop\n\t"
 59                 : /* no outputs */
 60                 : /* no inputs */
 61                 : "$1", "memory");
 62 }
 63 
 64 #define __save_flags(x)                  \
 65 __asm__ __volatile__(                    \
 66         ".set\tpush\n\t"                 \
 67         ".set\treorder\n\t"              \
 68         "mfc0\t%0,$12\n\t"               \
 69         ".set\tpop\n\t"                      \
 70         : "=r" (x)                       \
 71         : /* no inputs */                \
 72         : "memory")
 73 
 74 #define __save_and_cli(x)                \
 75 __asm__ __volatile__(                    \
 76         ".set\tpush\n\t"                 \
 77         ".set\treorder\n\t"              \
 78         ".set\tnoat\n\t"                 \
 79         "mfc0\t%0,$12\n\t"               \
 80         "ori\t$1,%0,1\n\t"               \
 81         "xori\t$1,1\n\t"                 \
 82         ".set\tnoreorder\n\t"            \
 83         "mtc0\t$1,$12\n\t"               \
 84         "nop\n\t"                        \
 85         "nop\n\t"                        \
 86         "nop\n\t"                        \
 87         ".set\tpop\n\t"                  \
 88         : "=r" (x)                       \
 89         : /* no inputs */                \
 90         : "$1", "memory")
 91 
 92 extern void __inline__
 93 __restore_flags(int flags)
 94 {
 95         __asm__ __volatile__(
 96                 ".set\tpush\n\t"
 97                 ".set\treorder\n\t"
 98                 "mfc0\t$8,$12\n\t"
 99                 "li\t$9,0xff00\n\t"
100                 "and\t$8,$9\n\t"
101                 "nor\t$9,$0,$9\n\t"
102                 "and\t%0,$9\n\t"
103                 "or\t%0,$8\n\t"
104                 ".set\tnoreorder\n\t"
105                 "mtc0\t%0,$12\n\t"
106                 "nop\n\t"
107                 "nop\n\t"
108                 "nop\n\t"
109                 ".set\tpop\n\t"
110                 :
111                 : "r" (flags)
112                 : "$8", "$9", "memory");
113 }
114 
115 /*
116  * Non-SMP versions ...
117  */
118 #define sti() __sti()
119 #define cli() __cli()
120 #define save_flags(x) __save_flags(x)
121 #define save_and_cli(x) __save_and_cli(x)
122 #define restore_flags(x) __restore_flags(x)
123 
124 /* For spinlocks etc */
125 #define local_irq_save(x)       __save_and_cli(x);
126 #define local_irq_restore(x)    __restore_flags(x);
127 #define local_irq_disable()     __cli();
128 #define local_irq_enable()      __sti();
129 
130 /*
131  * These are probably defined overly paranoid ...
132  */
133 #ifdef CONFIG_CPU_HAS_WB
134 #include <asm/wbflush.h>
135 #define rmb()
136 #define wmb() wbflush()
137 #define mb() wbflush()
138 #else
139 #define mb()                                            \
140 __asm__ __volatile__(                                   \
141         "# prevent instructions being moved around\n\t" \
142         ".set\tnoreorder\n\t"                           \
143         "# 8 nops to fool the R4400 pipeline\n\t"       \
144         "nop;nop;nop;nop;nop;nop;nop;nop\n\t"           \
145         ".set\treorder"                                 \
146         : /* no output */                               \
147         : /* no input */                                \
148         : "memory")
149 #define rmb() mb()
150 #define wmb() mb()
151 #endif
152 
153 #define set_mb(var, value) \
154 do { var = value; mb(); } while (0)
155 
156 #define set_wmb(var, value) \
157 do { var = value; wmb(); } while (0)
158 
159 #if !defined (_LANGUAGE_ASSEMBLY)
160 /*
161  * switch_to(n) should switch tasks to task nr n, first
162  * checking that n isn't the current task, in which case it does nothing.
163  */
164 extern asmlinkage void *resume(void *last, void *next);
165 #endif /* !defined (_LANGUAGE_ASSEMBLY) */
166 
167 #define prepare_to_switch()     do { } while(0)
168 #define switch_to(prev,next,last) \
169 do { \
170         (last) = resume(prev, next); \
171 } while(0)
172 
173 /*
174  * For 32 and 64 bit operands we can take advantage of ll and sc.
175  * FIXME: This doesn't work for R3000 machines.
176  */
177 extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val)
178 {
179 #if defined(CONFIG_CPU_HAS_LLSC)
180         unsigned long dummy;
181 
182         __asm__ __volatile__(
183                 ".set\tnoreorder\n\t"
184                 ".set\tnoat\n\t"
185                 "ll\t%0,(%1)\n"
186                 "1:\tmove\t$1,%2\n\t"
187                 "sc\t$1,(%1)\n\t"
188                 "beqzl\t$1,1b\n\t"
189                 "ll\t%0,(%1)\n\t"
190                 ".set\tat\n\t"
191                 ".set\treorder"
192                 : "=r" (val), "=r" (m), "=r" (dummy)
193                 : "1" (m), "2" (val)
194                 : "memory");
195 
196         return val;
197 #else
198         unsigned long flags, retval;
199 
200         save_flags(flags);
201         cli();
202         retval = *m;
203         *m = val;
204         restore_flags(flags);
205         return retval;
206 
207 #endif /* Processor-dependent optimization */
208 }
209 
210 /*
211  * Only used for 64 bit kernel.
212  */
213 extern __inline__ unsigned long xchg_u64(volatile long * m, unsigned long val)
214 {
215         unsigned long dummy;
216 
217         __asm__ __volatile__(
218                 ".set\tnoreorder\n\t"
219                 ".set\tnoat\n\t"
220                 "lld\t%0,(%1)\n"
221                 "1:\tmove\t$1,%2\n\t"
222                 "scd\t$1,(%1)\n\t"
223                 "beqzl\t$1,1b\n\t"
224                 "lld\t%0,(%1)\n\t"
225                 ".set\tat\n\t"
226                 ".set\treorder"
227                 : "=r" (val), "=r" (m), "=r" (dummy)
228                 : "1" (m), "2" (val)
229                 : "memory");
230 
231         return val;
232 }
233 
234 #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
235 #define tas(ptr) (xchg((ptr),1))
236 
237 /*
238  * This function doesn't exist, so you'll get a linker error
239  * if something tries to do an invalid xchg().
240  *
241  * This only works if the compiler isn't horribly bad at optimizing.
242  * gcc-2.5.8 reportedly can't handle this, but I define that one to
243  * be dead anyway.
244  */
245 extern void __xchg_called_with_bad_pointer(void);
246 
247 static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
248 {
249         switch (size) {
250                 case 4:
251                         return xchg_u32(ptr, x);
252 #if defined(__mips64)
253                 case 8:
254                         return xchg_u64(ptr, x);
255 #endif
256         }
257         __xchg_called_with_bad_pointer();
258         return x;
259 }
260 
261 extern void set_except_vector(int n, void *addr);
262 
263 extern void __die(const char *, struct pt_regs *, const char *where,
264         unsigned long line) __attribute__((noreturn));
265 extern void __die_if_kernel(const char *, struct pt_regs *, const char *where,
266         unsigned long line);
267 extern int abs(int);
268 
269 #define die(msg, regs)                                                  \
270         __die(msg, regs, __FILE__ ":"__FUNCTION__, __LINE__)
271 #define die_if_kernel(msg, regs)                                        \
272         __die_if_kernel(msg, regs, __FILE__ ":"__FUNCTION__, __LINE__)
273 
274 #endif /* _ASM_SYSTEM_H */
275 

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

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.