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(register) \
35 __asm__("movl %0,%%edx\n\t" \
36 "movl %%edx,%%db" #register "\n\t" \
37 : \
38 :"m" (current->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(tsk) do { \
69 cli();\
70 if(current->flags&PF_USEDFPU) \
71 { \
72 __asm__ __volatile__("fnsave %0":"=m" (current->tss.i387.hard)); \
73 __asm__ __volatile__("fwait"); \
74 current->flags&=~PF_USEDFPU; \
75 } \
76 current->lock_depth=syscall_count; \
77 kernel_counter+=next->lock_depth-current->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 "xchgl %%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 *)&tsk->tss.tr)-4)), \
90 "c" (tsk) \
91 :"cx"); \
92 \
93 if(current->debugreg[7]){ \
94 loaddebug(0); \
95 loaddebug(1); \
96 loaddebug(2); \
97 loaddebug(3); \
98 loaddebug(6); \
99 } \
100 } while (0)
101
102 #else
103 #define switch_to(tsk) do { \
104 __asm__("cli\n\t" \
105 "xchgl %%ecx,"SYMBOL_NAME_STR(current_set)"\n\t" \
106 "ljmp %0\n\t" \
107 "sti\n\t" \
108 "cmpl %%ecx,"SYMBOL_NAME_STR(last_task_used_math)"\n\t" \
109 "jne 1f\n\t" \
110 "clts\n" \
111 "1:" \
112 : \
113 :"m" (*(((char *)&tsk->tss.tr)-4)), \
114 "c" (tsk) \
115 :"cx"); \
116 \
117 if(current->debugreg[7]){ \
118 loaddebug(0); \
119 loaddebug(1); \
120 loaddebug(2); \
121 loaddebug(3); \
122 loaddebug(6); \
123 } \
124 } while (0)
125 #endif
126
127 #define _set_base(addr,base) \
128 __asm__("movw %%dx,%0\n\t" \
129 "rorl $16,%%edx\n\t" \
130 "movb %%dl,%1\n\t" \
131 "movb %%dh,%2" \
132 : \
133 :"m" (*((addr)+2)), \
134 "m" (*((addr)+4)), \
135 "m" (*((addr)+7)), \
136 "d" (base) \
137 :"dx")
138
139 #define _set_limit(addr,limit) \
140 __asm__("movw %%dx,%0\n\t" \
141 "rorl $16,%%edx\n\t" \
142 "movb %1,%%dh\n\t" \
143 "andb $0xf0,%%dh\n\t" \
144 "orb %%dh,%%dl\n\t" \
145 "movb %%dl,%1" \
146 : \
147 :"m" (*(addr)), \
148 "m" (*((addr)+6)), \
149 "d" (limit) \
150 :"dx")
151
152 #define set_base(ldt,base) _set_base( ((char *)&(ldt)) , base )
153 #define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , (limit-1)>>12 )
154
155 static inline unsigned long _get_base(char * addr)
156 {
157 unsigned long __base;
158 __asm__("movb %3,%%dh\n\t"
159 "movb %2,%%dl\n\t"
160 "shll $16,%%edx\n\t"
161 "movw %1,%%dx"
162 :"=&d" (__base)
163 :"m" (*((addr)+2)),
164 "m" (*((addr)+4)),
165 "m" (*((addr)+7)));
166 return __base;
167 }
168
169 #define get_base(ldt) _get_base( ((char *)&(ldt)) )
170
171 static inline unsigned long get_limit(unsigned long segment)
172 {
173 unsigned long __limit;
174 __asm__("lsll %1,%0"
175 :"=r" (__limit):"r" (segment));
176 return __limit+1;
177 }
178
179 #define nop() __asm__ __volatile__ ("nop")
180
181
182
183
184 #define clts() __asm__ __volatile__ ("clts")
185 #define stts() \
186 __asm__ __volatile__ ( \
187 "movl %%cr0,%%eax\n\t" \
188 "orl $8,%%eax\n\t" \
189 "movl %%eax,%%cr0" \
190 : \
191 : \
192 :"ax")
193
194
195 #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
196 #define tas(ptr) (xchg((ptr),1))
197
198 struct __xchg_dummy { unsigned long a[100]; };
199 #define __xg(x) ((volatile struct __xchg_dummy *)(x))
200
201 static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
202 {
203 switch (size) {
204 case 1:
205 __asm__("xchgb %b0,%1"
206 :"=q" (x), "=m" (*__xg(ptr))
207 :"0" (x), "m" (*__xg(ptr)));
208 break;
209 case 2:
210 __asm__("xchgw %w0,%1"
211 :"=r" (x), "=m" (*__xg(ptr))
212 :"0" (x), "m" (*__xg(ptr)));
213 break;
214 case 4:
215 __asm__("xchgl %0,%1"
216 :"=r" (x), "=m" (*__xg(ptr))
217 :"0" (x), "m" (*__xg(ptr)));
218 break;
219 }
220 return x;
221 }
222
223 #define mb() __asm__ __volatile__ ("" : : :"memory")
224 #define sti() __asm__ __volatile__ ("sti": : :"memory")
225 #define cli() __asm__ __volatile__ ("cli": : :"memory")
226
227 #define save_flags(x) \
228 __asm__ __volatile__("pushfl ; popl %0":"=r" (x): :"memory")
229
230 #define restore_flags(x) \
231 __asm__ __volatile__("pushl %0 ; popfl": :"r" (x):"memory")
232
233 #define iret() __asm__ __volatile__ ("iret": : :"memory")
234
235 #define _set_gate(gate_addr,type,dpl,addr) \
236 __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
237 "movw %2,%%dx\n\t" \
238 "movl %%eax,%0\n\t" \
239 "movl %%edx,%1" \
240 :"=m" (*((long *) (gate_addr))), \
241 "=m" (*(1+(long *) (gate_addr))) \
242 :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
243 "d" ((char *) (addr)),"a" (KERNEL_CS << 16) \
244 :"ax","dx")
245
246 #define set_intr_gate(n,addr) \
247 _set_gate(&idt[n],14,0,addr)
248
249 #define set_trap_gate(n,addr) \
250 _set_gate(&idt[n],15,0,addr)
251
252 #define set_system_gate(n,addr) \
253 _set_gate(&idt[n],15,3,addr)
254
255 #define set_call_gate(a,addr) \
256 _set_gate(a,12,3,addr)
257
258 #define _set_seg_desc(gate_addr,type,dpl,base,limit) {\
259 *((gate_addr)+1) = ((base) & 0xff000000) | \
260 (((base) & 0x00ff0000)>>16) | \
261 ((limit) & 0xf0000) | \
262 ((dpl)<<13) | \
263 (0x00408000) | \
264 ((type)<<8); \
265 *(gate_addr) = (((base) & 0x0000ffff)<<16) | \
266 ((limit) & 0x0ffff); }
267
268 #define _set_tssldt_desc(n,addr,limit,type) \
269 __asm__ __volatile__ ("movw $" #limit ",%1\n\t" \
270 "movw %%ax,%2\n\t" \
271 "rorl $16,%%eax\n\t" \
272 "movb %%al,%3\n\t" \
273 "movb $" type ",%4\n\t" \
274 "movb $0x00,%5\n\t" \
275 "movb %%ah,%6\n\t" \
276 "rorl $16,%%eax" \
277 : \
278 :"a" (addr+0xc0000000), "m" (*(n)), "m" (*(n+2)), "m" (*(n+4)), \
279 "m" (*(n+5)), "m" (*(n+6)), "m" (*(n+7)) \
280 )
281
282 #define set_tss_desc(n,addr) _set_tssldt_desc(((char *) (n)),((int)(addr)),235,"0x89")
283 #define set_ldt_desc(n,addr,size) \
284 _set_tssldt_desc(((char *) (n)),((int)(addr)),((size << 3) - 1),"0x82")
285
286
287
288
289
290 extern struct desc_struct default_ldt;
291
292
293
294
295 #define HAVE_DISABLE_HLT
296 void disable_hlt(void);
297 void enable_hlt(void);
298
299 #endif