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