This source file includes following definitions.
- _get_base
- get_limit
- __xchg
1 #ifndef __ASM_SYSTEM_H
2 #define __ASM_SYSTEM_H
3
4 #include <asm/segment.h>
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #define FIRST_TSS_ENTRY 8
20 #define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY+1)
21 #define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3))
22 #define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3))
23 #define load_TR(n) __asm__("ltr %%ax": :"a" (_TSS(n)))
24 #define load_ldt(n) __asm__("lldt %%ax": :"a" (_LDT(n)))
25 #define store_TR(n) \
26 __asm__("str %%ax\n\t" \
27 "subl %2,%%eax\n\t" \
28 "shrl $4,%%eax" \
29 :"=a" (n) \
30 :"0" (0),"i" (FIRST_TSS_ENTRY<<3))
31
32
33
34 #define loaddebug(tsk,register) \
35 __asm__("movl %0,%%edx\n\t" \
36 "movl %%edx,%%db" #register "\n\t" \
37 : \
38 :"m" (tsk->debugreg[register]) \
39 :"dx");
40
41
42
43
44
45
46
47
48
49
50
51
52 #ifdef __SMP__
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 #define switch_to(prev,next) do { \
69 cli();\
70 if(prev->flags&PF_USEDFPU) \
71 { \
72 __asm__ __volatile__("fnsave %0":"=m" (prev->tss.i387.hard)); \
73 __asm__ __volatile__("fwait"); \
74 prev->flags&=~PF_USEDFPU; \
75 } \
76 prev->lock_depth=syscall_count; \
77 kernel_counter+=next->lock_depth-prev->lock_depth; \
78 syscall_count=next->lock_depth; \
79 __asm__("pushl %%edx\n\t" \
80 "movl "SYMBOL_NAME_STR(apic_reg)",%%edx\n\t" \
81 "movl 0x20(%%edx), %%edx\n\t" \
82 "shrl $22,%%edx\n\t" \
83 "and $0x3C,%%edx\n\t" \
84 "movl %%ecx,"SYMBOL_NAME_STR(current_set)"(,%%edx)\n\t" \
85 "popl %%edx\n\t" \
86 "ljmp %0\n\t" \
87 "sti\n\t" \
88 : \
89 :"m" (*(((char *)&next->tss.tr)-4)), \
90 "c" (next)); \
91 \
92 if(prev->debugreg[7]){ \
93 loaddebug(prev,0); \
94 loaddebug(prev,1); \
95 loaddebug(prev,2); \
96 loaddebug(prev,3); \
97 loaddebug(prev,6); \
98 } \
99 } while (0)
100
101 #else
102 #define switch_to(prev,next) do { \
103 __asm__("movl %2,"SYMBOL_NAME_STR(current_set)"\n\t" \
104 "ljmp %0\n\t" \
105 "cmpl %1,"SYMBOL_NAME_STR(last_task_used_math)"\n\t" \
106 "jne 1f\n\t" \
107 "clts\n" \
108 "1:" \
109 : \
110 :"m" (*(((char *)&next->tss.tr)-4)), \
111 "r" (prev), "r" (next)); \
112 \
113 if(prev->debugreg[7]){ \
114 loaddebug(prev,0); \
115 loaddebug(prev,1); \
116 loaddebug(prev,2); \
117 loaddebug(prev,3); \
118 loaddebug(prev,6); \
119 } \
120 } while (0)
121 #endif
122
123 #define _set_base(addr,base) \
124 __asm__("movw %%dx,%0\n\t" \
125 "rorl $16,%%edx\n\t" \
126 "movb %%dl,%1\n\t" \
127 "movb %%dh,%2" \
128 : \
129 :"m" (*((addr)+2)), \
130 "m" (*((addr)+4)), \
131 "m" (*((addr)+7)), \
132 "d" (base) \
133 :"dx")
134
135 #define _set_limit(addr,limit) \
136 __asm__("movw %%dx,%0\n\t" \
137 "rorl $16,%%edx\n\t" \
138 "movb %1,%%dh\n\t" \
139 "andb $0xf0,%%dh\n\t" \
140 "orb %%dh,%%dl\n\t" \
141 "movb %%dl,%1" \
142 : \
143 :"m" (*(addr)), \
144 "m" (*((addr)+6)), \
145 "d" (limit) \
146 :"dx")
147
148 #define set_base(ldt,base) _set_base( ((char *)&(ldt)) , base )
149 #define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , (limit-1)>>12 )
150
151 static inline unsigned long _get_base(char * addr)
152 {
153 unsigned long __base;
154 __asm__("movb %3,%%dh\n\t"
155 "movb %2,%%dl\n\t"
156 "shll $16,%%edx\n\t"
157 "movw %1,%%dx"
158 :"=&d" (__base)
159 :"m" (*((addr)+2)),
160 "m" (*((addr)+4)),
161 "m" (*((addr)+7)));
162 return __base;
163 }
164
165 #define get_base(ldt) _get_base( ((char *)&(ldt)) )
166
167 static inline unsigned long get_limit(unsigned long segment)
168 {
169 unsigned long __limit;
170 __asm__("lsll %1,%0"
171 :"=r" (__limit):"r" (segment));
172 return __limit+1;
173 }
174
175 #define nop() __asm__ __volatile__ ("nop")
176
177
178
179
180 #define clts() __asm__ __volatile__ ("clts")
181 #define stts() \
182 __asm__ __volatile__ ( \
183 "movl %%cr0,%%eax\n\t" \
184 "orl $8,%%eax\n\t" \
185 "movl %%eax,%%cr0" \
186 : \
187 : \
188 :"ax")
189
190
191 #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
192 #define tas(ptr) (xchg((ptr),1))
193
194 struct __xchg_dummy { unsigned long a[100]; };
195 #define __xg(x) ((volatile struct __xchg_dummy *)(x))
196
197 static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
198 {
199 switch (size) {
200 case 1:
201 __asm__("xchgb %b0,%1"
202 :"=q" (x), "=m" (*__xg(ptr))
203 :"0" (x), "m" (*__xg(ptr)));
204 break;
205 case 2:
206 __asm__("xchgw %w0,%1"
207 :"=r" (x), "=m" (*__xg(ptr))
208 :"0" (x), "m" (*__xg(ptr)));
209 break;
210 case 4:
211 __asm__("xchgl %0,%1"
212 :"=r" (x), "=m" (*__xg(ptr))
213 :"0" (x), "m" (*__xg(ptr)));
214 break;
215 }
216 return x;
217 }
218
219 #define mb() __asm__ __volatile__ ("" : : :"memory")
220 #define sti() __asm__ __volatile__ ("sti": : :"memory")
221 #define cli() __asm__ __volatile__ ("cli": : :"memory")
222
223 #define save_flags(x) \
224 __asm__ __volatile__("pushfl ; popl %0":"=r" (x): :"memory")
225
226 #define restore_flags(x) \
227 __asm__ __volatile__("pushl %0 ; popfl": :"r" (x):"memory")
228
229 #define iret() __asm__ __volatile__ ("iret": : :"memory")
230
231 #define _set_gate(gate_addr,type,dpl,addr) \
232 __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
233 "movw %2,%%dx\n\t" \
234 "movl %%eax,%0\n\t" \
235 "movl %%edx,%1" \
236 :"=m" (*((long *) (gate_addr))), \
237 "=m" (*(1+(long *) (gate_addr))) \
238 :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
239 "d" ((char *) (addr)),"a" (KERNEL_CS << 16) \
240 :"ax","dx")
241
242 #define set_intr_gate(n,addr) \
243 _set_gate(&idt[n],14,0,addr)
244
245 #define set_trap_gate(n,addr) \
246 _set_gate(&idt[n],15,0,addr)
247
248 #define set_system_gate(n,addr) \
249 _set_gate(&idt[n],15,3,addr)
250
251 #define set_call_gate(a,addr) \
252 _set_gate(a,12,3,addr)
253
254 #define _set_seg_desc(gate_addr,type,dpl,base,limit) {\
255 *((gate_addr)+1) = ((base) & 0xff000000) | \
256 (((base) & 0x00ff0000)>>16) | \
257 ((limit) & 0xf0000) | \
258 ((dpl)<<13) | \
259 (0x00408000) | \
260 ((type)<<8); \
261 *(gate_addr) = (((base) & 0x0000ffff)<<16) | \
262 ((limit) & 0x0ffff); }
263
264 #define _set_tssldt_desc(n,addr,limit,type) \
265 __asm__ __volatile__ ("movw $" #limit ",%1\n\t" \
266 "movw %%ax,%2\n\t" \
267 "rorl $16,%%eax\n\t" \
268 "movb %%al,%3\n\t" \
269 "movb $" type ",%4\n\t" \
270 "movb $0x00,%5\n\t" \
271 "movb %%ah,%6\n\t" \
272 "rorl $16,%%eax" \
273 : \
274 :"a" (addr+0xc0000000), "m" (*(n)), "m" (*(n+2)), "m" (*(n+4)), \
275 "m" (*(n+5)), "m" (*(n+6)), "m" (*(n+7)) \
276 )
277
278 #define set_tss_desc(n,addr) _set_tssldt_desc(((char *) (n)),((int)(addr)),235,"0x89")
279 #define set_ldt_desc(n,addr,size) \
280 _set_tssldt_desc(((char *) (n)),((int)(addr)),((size << 3) - 1),"0x82")
281
282
283
284
285
286 extern struct desc_struct default_ldt;
287
288
289
290
291 #define HAVE_DISABLE_HLT
292 void disable_hlt(void);
293 void enable_hlt(void);
294
295 #endif