ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / include / asm-arm26 / system.h
1 #ifndef __ASM_ARM_SYSTEM_H
2 #define __ASM_ARM_SYSTEM_H
3
4 #ifdef __KERNEL__
5
6 #include <linux/config.h>
7 #include <linux/kernel.h>
8 #include <asm/proc-fns.h>
9
10 #define vectors_base()  (0)
11
12 static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
13 {
14         extern void __bad_xchg(volatile void *, int);
15
16         switch (size) {
17                 case 1: return cpu_xchg_1(x, ptr);
18                 case 4: return cpu_xchg_4(x, ptr);
19                 default: __bad_xchg(ptr, size);
20         }
21         return 0;
22 }
23
24 /*
25  * We need to turn the caches off before calling the reset vector - RiscOS
26  * messes up if we don't
27  */
28 #define proc_hard_reset()       cpu_proc_fin()
29
30 /*
31  * A couple of speedups for the ARM
32  */
33
34 /*
35  * Enable IRQs  (sti)
36  */
37 #define local_irq_enable()                                      \
38         do {                                    \
39           unsigned long temp;                   \
40           __asm__ __volatile__(                 \
41 "       mov     %0, pc          @ sti\n"        \
42 "       bic     %0, %0, #0x08000000\n"          \
43 "       teqp    %0, #0\n"                       \
44           : "=r" (temp)                         \
45           :                                     \
46           : "memory");                          \
47         } while(0)
48
49 /*
50  * Disable IRQs (cli)
51  */
52 #define local_irq_disable()                                     \
53         do {                                    \
54           unsigned long temp;                   \
55           __asm__ __volatile__(                 \
56 "       mov     %0, pc          @ cli\n"        \
57 "       orr     %0, %0, #0x08000000\n"          \
58 "       teqp    %0, #0\n"                       \
59           : "=r" (temp)                         \
60           :                                     \
61           : "memory");                          \
62         } while(0)
63
64 /* Disable FIQs  (clf) */
65
66 #define __clf() do {                            \
67         unsigned long temp;                     \
68         __asm__ __volatile__(                   \
69 "       mov     %0, pc          @ clf\n"        \
70 "       orr     %0, %0, #0x04000000\n"          \
71 "       teqp    %0, #0\n"                       \
72         : "=r" (temp));                         \
73     } while(0)
74
75 /* Enable FIQs (stf) */
76
77 #define __stf() do {                            \
78         unsigned long temp;                     \
79         __asm__ __volatile__(                   \
80 "       mov     %0, pc          @ stf\n"        \
81 "       bic     %0, %0, #0x04000000\n"          \
82 "       teqp    %0, #0\n"                       \
83         : "=r" (temp));                         \
84     } while(0)
85
86 /*
87  * save current IRQ & FIQ state
88  */
89 #define local_save_flags(x)                             \
90         do {                                    \
91           __asm__ __volatile__(                 \
92 "       mov     %0, pc          @ save_flags\n" \
93 "       and     %0, %0, #0x0c000000\n"          \
94           : "=r" (x));                          \
95         } while (0)
96
97 /*
98  * Save the current interrupt enable state & disable IRQs
99  */
100 #define local_irq_save(x)                               \
101         do {                                            \
102           unsigned long temp;                           \
103           __asm__ __volatile__(                         \
104 "       mov     %0, pc          @ save_flags_cli\n"     \
105 "       orr     %1, %0, #0x08000000\n"                  \
106 "       and     %0, %0, #0x0c000000\n"                  \
107 "       teqp    %1, #0\n"                               \
108           : "=r" (x), "=r" (temp)                       \
109           :                                             \
110           : "memory");                                  \
111         } while (0)
112
113 /*
114  * restore saved IRQ & FIQ state
115  */
116 #define local_irq_restore(x)                            \
117         do {                                            \
118           unsigned long temp;                           \
119           __asm__ __volatile__(                         \
120 "       mov     %0, pc          @ restore_flags\n"      \
121 "       bic     %0, %0, #0x0c000000\n"                  \
122 "       orr     %0, %0, %1\n"                           \
123 "       teqp    %0, #0\n"                               \
124           : "=&r" (temp)                                \
125           : "r" (x)                                     \
126           : "memory");                                  \
127         } while (0)
128
129
130 struct thread_info;
131
132 /* information about the system we're running on */
133 extern unsigned int system_rev;
134 extern unsigned int system_serial_low;
135 extern unsigned int system_serial_high;
136
137 struct pt_regs;
138
139 void die(const char *msg, struct pt_regs *regs, int err)
140                 __attribute__((noreturn));
141
142 void die_if_kernel(const char *str, struct pt_regs *regs, int err);
143
144 void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
145                                        struct pt_regs *),
146                      int sig, const char *name);
147
148 #define xchg(ptr,x) \
149         ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
150
151 #define tas(ptr) (xchg((ptr),1))
152
153 extern asmlinkage void __backtrace(void);
154
155 /*
156  * Include processor dependent parts
157  */
158
159 #define mb() __asm__ __volatile__ ("" : : : "memory")
160 #define rmb() mb()
161 #define wmb() mb()
162 #define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
163
164 #define prepare_to_switch()    do { } while(0)
165
166 /*
167  * switch_to(prev, next) should switch from task `prev' to `next'
168  * `prev' will never be the same as `next'.
169  * The `mb' is to tell GCC not to cache `current' across this call.
170  */
171 struct thread_info;
172
173 extern struct task_struct *__switch_to(struct thread_info *, struct thread_info *);
174
175 #define switch_to(prev,next,last)                                       \
176         do {                                                            \
177                 __switch_to(prev->thread_info,next->thread_info);       \
178                 mb();                                                   \
179         } while (0)
180
181
182 #ifdef CONFIG_SMP
183 #error SMP not supported
184 #endif /* CONFIG_SMP */
185
186 #define irqs_disabled()                 \
187 ({                                      \
188         unsigned long flags;            \
189         local_save_flags(flags);        \
190         flags & PSR_I_BIT;              \
191 })
192
193 #define set_mb(var, value)  do { var = value; mb(); } while (0)
194 #define smp_mb()                barrier()
195 #define smp_rmb()               barrier()
196 #define smp_wmb()               barrier()
197 #define smp_read_barrier_depends()              do { } while(0)
198
199 #define clf()                   __clf()
200 #define stf()                   __stf()
201
202 #endif /* __KERNEL__ */
203
204 #endif