1#ifndef __ASM_SYSTEM_H
2#define __ASM_SYSTEM_H
3
4#include <linux/kernel.h>
5#include <asm/segment.h>
6#include <asm/cpufeature.h>
7#include <asm/cmpxchg.h>
8
9#ifdef __KERNEL__
10
11struct task_struct;
12extern struct task_struct * FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next));
13
14
15
16
17
18#define switch_to(prev,next,last) do { \
19 unsigned long esi,edi; \
20 asm volatile("pushfl\n\t" \
21 "pushl %%ebp\n\t" \
22 "movl %%esp,%0\n\t" \
23 "movl %5,%%esp\n\t" \
24 "movl $1f,%1\n\t" \
25 "pushl %6\n\t" \
26 "jmp __switch_to\n" \
27 "1:\t" \
28 "popl %%ebp\n\t" \
29 "popfl" \
30 :"=m" (prev->thread.esp),"=m" (prev->thread.eip), \
31 "=a" (last),"=S" (esi),"=D" (edi) \
32 :"m" (next->thread.esp),"m" (next->thread.eip), \
33 "2" (prev), "d" (next)); \
34} while (0)
35
36#define _set_base(addr,base) do { unsigned long __pr; \
37__asm__ __volatile__ ("movw %%dx,%1\n\t" \
38 "rorl $16,%%edx\n\t" \
39 "movb %%dl,%2\n\t" \
40 "movb %%dh,%3" \
41 :"=&d" (__pr) \
42 :"m" (*((addr)+2)), \
43 "m" (*((addr)+4)), \
44 "m" (*((addr)+7)), \
45 "0" (base) \
46 ); } while(0)
47
48#define _set_limit(addr,limit) do { unsigned long __lr; \
49__asm__ __volatile__ ("movw %%dx,%1\n\t" \
50 "rorl $16,%%edx\n\t" \
51 "movb %2,%%dh\n\t" \
52 "andb $0xf0,%%dh\n\t" \
53 "orb %%dh,%%dl\n\t" \
54 "movb %%dl,%2" \
55 :"=&d" (__lr) \
56 :"m" (*(addr)), \
57 "m" (*((addr)+6)), \
58 "0" (limit) \
59 ); } while(0)
60
61#define set_base(ldt,base) _set_base( ((char *)&(ldt)) , (base) )
62#define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , ((limit)-1) )
63
64
65
66
67
68#define loadsegment(seg,value) \
69 asm volatile("\n" \
70 "1:\t" \
71 "mov %0,%%" #seg "\n" \
72 "2:\n" \
73 ".section .fixup,\"ax\"\n" \
74 "3:\t" \
75 "pushl $0\n\t" \
76 "popl %%" #seg "\n\t" \
77 "jmp 2b\n" \
78 ".previous\n" \
79 ".section __ex_table,\"a\"\n\t" \
80 ".align 4\n\t" \
81 ".long 1b,3b\n" \
82 ".previous" \
83 : :"rm" (value))
84
85
86
87
88#define savesegment(seg, value) \
89 asm volatile("mov %%" #seg ",%0":"=rm" (value))
90
91
92static inline void native_clts(void)
93{
94 asm volatile ("clts");
95}
96
97static inline unsigned long native_read_cr0(void)
98{
99 unsigned long val;
100 asm volatile("movl %%cr0,%0\n\t" :"=r" (val));
101 return val;
102}
103
104static inline void native_write_cr0(unsigned long val)
105{
106 asm volatile("movl %0,%%cr0": :"r" (val));
107}
108
109static inline unsigned long native_read_cr2(void)
110{
111 unsigned long val;
112 asm volatile("movl %%cr2,%0\n\t" :"=r" (val));
113 return val;
114}
115
116static inline void native_write_cr2(unsigned long val)
117{
118 asm volatile("movl %0,%%cr2": :"r" (val));
119}
120
121static inline unsigned long native_read_cr3(void)
122{
123 unsigned long val;
124 asm volatile("movl %%cr3,%0\n\t" :"=r" (val));
125 return val;
126}
127
128static inline void native_write_cr3(unsigned long val)
129{
130 asm volatile("movl %0,%%cr3": :"r" (val));
131}
132
133static inline unsigned long native_read_cr4(void)
134{
135 unsigned long val;
136 asm volatile("movl %%cr4,%0\n\t" :"=r" (val));
137 return val;
138}
139
140static inline unsigned long native_read_cr4_safe(void)
141{
142 unsigned long val;
143
144 asm("1: movl %%cr4, %0 \n"
145 "2: \n"
146 ".section __ex_table,\"a\" \n"
147 ".long 1b,2b \n"
148 ".previous \n"
149 : "=r" (val): "0" (0));
150 return val;
151}
152
153static inline void native_write_cr4(unsigned long val)
154{
155 asm volatile("movl %0,%%cr4": :"r" (val));
156}
157
158static inline void native_wbinvd(void)
159{
160 asm volatile("wbinvd": : :"memory");
161}
162
163
164#ifdef CONFIG_PARAVIRT
165#include <asm/paravirt.h>
166#else
167#define read_cr0() (native_read_cr0())
168#define write_cr0(x) (native_write_cr0(x))
169#define read_cr2() (native_read_cr2())
170#define write_cr2(x) (native_write_cr2(x))
171#define read_cr3() (native_read_cr3())
172#define write_cr3(x) (native_write_cr3(x))
173#define read_cr4() (native_read_cr4())
174#define read_cr4_safe() (native_read_cr4_safe())
175#define write_cr4(x) (native_write_cr4(x))
176#define wbinvd() (native_wbinvd())
177
178
179#define clts() (native_clts())
180
181#endif
182
183
184#define stts() write_cr0(8 | read_cr0())
185
186#endif
187
188static inline unsigned long get_limit(unsigned long segment)
189{
190 unsigned long __limit;
191 __asm__("lsll %1,%0"
192 :"=r" (__limit):"r" (segment));
193 return __limit+1;
194}
195
196#define nop() __asm__ __volatile__ ("nop")
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
223#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277#define read_barrier_depends() do { } while(0)
278
279#ifdef CONFIG_X86_OOSTORE
280
281
282#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)
283#else
284#define wmb() __asm__ __volatile__ ("": : :"memory")
285#endif
286
287#ifdef CONFIG_SMP
288#define smp_mb() mb()
289#define smp_rmb() rmb()
290#define smp_wmb() wmb()
291#define smp_read_barrier_depends() read_barrier_depends()
292#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
293#else
294#define smp_mb() barrier()
295#define smp_rmb() barrier()
296#define smp_wmb() barrier()
297#define smp_read_barrier_depends() do { } while(0)
298#define set_mb(var, value) do { var = value; barrier(); } while (0)
299#endif
300
301#include <linux/irqflags.h>
302
303
304
305
306#define HAVE_DISABLE_HLT
307void disable_hlt(void);
308void enable_hlt(void);
309
310extern int es7000_plat;
311void cpu_idle_wait(void);
312
313
314
315
316
317static inline void sched_cacheflush(void)
318{
319 wbinvd();
320}
321
322extern unsigned long arch_align_stack(unsigned long sp);
323extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
324
325void default_idle(void);
326
327#endif
328