00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef __PROGRAM_CPROTO__
00037
00038 #ifndef _I386_CPUFUNC_H_
00039 #define _I386_CPUFUNC_H_
00040 #include <sysinterf/types.h>
00041 #include <machdep/psl.h>
00042
00043
00044
00045
00046
00047 static __inline void
00048 invlpg(u_int addr)
00049 {
00050 __asm __volatile ("invlpg (%0)" : : "r" (addr) : "memory");
00051 }
00052
00053 static __inline void
00054 lidt(void * base, unsigned int limit)
00055 {
00056 unsigned int i[2];
00057
00058 i[0] = limit<<16;
00059 i[1] = (unsigned int) base;
00060
00061
00062
00063 __asm __volatile ("lidt (%0)": :"r" (((char *)i) + 2));
00064 }
00065
00066 static __inline void
00067 lgdt(void * base, unsigned int limit)
00068 {
00069 unsigned int i[2];
00070
00071 i[0] = limit<<16;
00072 i[1] = (unsigned int) base;
00073
00074 __asm __volatile ("lgdt (%0)": :"r" (((char *) i) + 2));
00075 }
00076
00077 static __inline void
00078 lcall(u_int selector)
00079 {
00080 u_int sel[2];
00081
00082 sel[0] = 0;
00083 sel[1] = selector;
00084
00085 __asm __volatile ("lcall *%0": :"m" (*sel));
00086 }
00087
00088 static __inline void
00089 lldt(u_short sel)
00090 {
00091 __asm __volatile ("lldt %0" : : "r" (sel));
00092 }
00093
00094 static __inline void
00095 lcr0(u_int val)
00096 {
00097 __asm __volatile ("movl %0,%%cr0" : : "r" (val));
00098 }
00099
00100 static __inline u_int
00101 rcr0(void)
00102 {
00103 u_int val;
00104 __asm __volatile ("movl %%cr0,%0" : "=r" (val));
00105 return val;
00106 }
00107
00108 static __inline u_int
00109 rcr2(void)
00110 {
00111 u_int val;
00112 __asm __volatile ("movl %%cr2,%0" : "=r" (val));
00113 return val;
00114 }
00115
00116 static __inline void
00117 lcr2(u_int val)
00118 {
00119 __asm __volatile ("movl %0,%%cr2" : : "r" (val));
00120 }
00121
00122
00123 static __inline void
00124 lcr3(u_int val)
00125 {
00126 __asm __volatile ("movl %0,%%cr3" : : "r" (val));
00127 }
00128
00129 static __inline u_int
00130 rcr3(void)
00131 {
00132 u_int val;
00133 __asm __volatile ("movl %%cr3,%0" : "=r" (val));
00134 return val;
00135 }
00136
00137 static __inline void
00138 lcr4(u_int val)
00139 {
00140 __asm __volatile ("movl %0,%%cr4" : : "r" (val));
00141 }
00142
00143 static __inline u_int
00144 rcr4(void)
00145 {
00146 u_int val;
00147 __asm __volatile ("movl %%cr4,%0" : "=r" (val));
00148 return val;
00149 }
00150
00151 static __inline void
00152 tlbflush(void)
00153 {
00154 u_int val;
00155 __asm __volatile ("movl %%cr3,%0" : "=r" (val));
00156 __asm __volatile ("movl %0,%%cr3" : : "r" (val));
00157 }
00158
00159 static __inline void
00160 leax(u_int val)
00161 {
00162 __asm __volatile ("movl %0,%%eax" : : "r" (val));
00163 }
00164
00165 static __inline void
00166 lebx(u_int val)
00167 {
00168 __asm __volatile ("movl %0,%%ebx" : : "r" (val));
00169 }
00170
00171 static __inline void
00172 lecx(u_int val)
00173 {
00174 __asm __volatile ("movl %0,%%ecx" : : "r" (val));
00175 }
00176
00177 static __inline u_int
00178 rebx(void)
00179 {
00180 u_int val;
00181 __asm __volatile ("movl %%ebx,%0" : "=r" (val));
00182 return val;
00183 }
00184
00185 static __inline u_int
00186 recx(void)
00187 {
00188 u_int val;
00189 __asm __volatile ("movl %%ecx,%0" : "=r" (val));
00190 return val;
00191 }
00192
00193 static __inline void
00194 ledx(u_int val)
00195 {
00196 __asm __volatile ("movl %0,%%edx" : : "r" (val));
00197 }
00198
00199 static __inline void
00200 cpu_hang()
00201 {
00202 __asm __volatile ("cli;hlt");
00203 }
00204
00205 static __inline void
00206 cpu_halt()
00207 {
00208 __asm __volatile ("hlt");
00209 }
00210
00211 static __inline void
00212 yield()
00213 {
00214 __asm __volatile ("iret");
00215 }
00216
00217 static __inline void
00218 disable_intr(void)
00219 {
00220 __asm __volatile ("cli");
00221 }
00222
00223 static __inline void
00224 enable_intr(void)
00225 {
00226 __asm __volatile ("sti");
00227 }
00228
00229 static __inline u_long
00230 read_eflags(void)
00231 {
00232 u_long ef;
00233
00234 __asm __volatile ("pushfl; popl %0" : "=r" (ef));
00235 return (ef);
00236 }
00237
00242 static __inline int
00243 interruptible()
00244 {
00245 return (read_eflags() & PSL_I);
00246 }
00247
00248 static __inline void
00249 write_eflags(u_long ef)
00250 {
00251 __asm __volatile ("pushl %0; popfl" : : "r" (ef));
00252 }
00253
00254 static __inline u_int64_t
00255 rdmsr(u_int msr)
00256 {
00257 u_int64_t rv;
00258
00259 __asm __volatile ("rdmsr" : "=A" (rv) : "c" (msr));
00260 return (rv);
00261 }
00262
00263 static __inline void
00264 wrmsr(u_int msr, u_int64_t newval)
00265 {
00266 __asm __volatile ("wrmsr" : : "A" (newval), "c" (msr));
00267 }
00268
00269 static __inline void
00270 wbinvd(void)
00271 {
00272 __asm __volatile ("wbinvd");
00273 }
00274
00275 static __inline u_int64_t
00276 rdtsc(void)
00277 {
00278 u_int64_t rv;
00279
00280 __asm __volatile ("rdtsc" : "=A" (rv));
00281 return (rv);
00282 }
00283
00284 static __inline u_int64_t
00285 rdpmc(u_int pmc)
00286 {
00287 u_int64_t rv;
00288
00289 __asm __volatile ("rdpmc" : "=A" (rv) : "c" (pmc));
00290 return (rv);
00291 }
00292
00293
00294
00295
00296 #define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
00297
00298 struct __xchg_dummy { unsigned long a[100]; };
00299 #define __xg(x) ((struct __xchg_dummy *)(x))
00300
00301
00302
00303
00304
00305
00306 static __inline unsigned long
00307 __xchg(unsigned long x, volatile void * ptr, int size)
00308 {
00309 switch (size) {
00310 case 1:
00311 __asm __volatile ("xchgb %b0,%1"
00312 :"=q" (x)
00313 :"m" (*__xg(ptr)), "0" (x)
00314 :"memory");
00315 break;
00316 case 2:
00317 __asm __volatile ("xchgw %w0,%1"
00318 :"=r" (x)
00319 :"m" (*__xg(ptr)), "0" (x)
00320 :"memory");
00321 break;
00322 case 4:
00323 __asm __volatile ("xchgl %0,%1"
00324 :"=r" (x)
00325 :"m" (*__xg(ptr)), "0" (x)
00326 :"memory");
00327 break;
00328 }
00329 return x;
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341 #ifdef __OPTIMIZE__
00342
00343 #define __use_immediate_port(port) \
00344 (__builtin_constant_p((port)) && (port) < 0x100)
00345
00346 #else
00347
00348 #define __use_immediate_port(port) 0
00349
00350 #endif
00351
00352
00353 #define inb(port) \
00354 (__use_immediate_port(port) ? __inbc(port) : __inb(port))
00355
00356 static __inline u_int8_t
00357 __inbc(int port)
00358 {
00359 u_int8_t data;
00360 __asm __volatile("inb %1,%0" : "=a" (data) : "id" (port));
00361 return data;
00362 }
00363
00364 static __inline u_int8_t
00365 __inb(int port)
00366 {
00367 u_int8_t data;
00368 __asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
00369 return data;
00370 }
00371
00372 static __inline void
00373 insb(int port, void *addr, int cnt)
00374 {
00375 void *dummy1;
00376 int dummy2;
00377 __asm __volatile("cld\n\trepne\n\tinsb" :
00378 "=D" (dummy1), "=c" (dummy2) :
00379 "d" (port), "0" (addr), "1" (cnt) :
00380 "memory");
00381 }
00382
00383 #define inw(port) \
00384 (__use_immediate_port(port) ? __inwc(port) : __inw(port))
00385
00386 static __inline u_int16_t
00387 __inwc(int port)
00388 {
00389 u_int16_t data;
00390 __asm __volatile("inw %1,%0" : "=a" (data) : "id" (port));
00391 return data;
00392 }
00393
00394 static __inline u_int16_t
00395 __inw(int port)
00396 {
00397 u_int16_t data;
00398 __asm __volatile("inw %w1,%0" : "=a" (data) : "d" (port));
00399 return data;
00400 }
00401
00402 static __inline void
00403 insw(int port, void *addr, int cnt)
00404 {
00405 void *dummy1;
00406 int dummy2;
00407 __asm __volatile("cld\n\trepne\n\tinsw" :
00408 "=D" (dummy1), "=c" (dummy2) :
00409 "d" (port), "0" (addr), "1" (cnt) :
00410 "memory");
00411 }
00412
00413 #define inl(port) \
00414 (__use_immediate_port(port) ? __inlc(port) : __inl(port))
00415
00416 static __inline u_int32_t
00417 __inlc(int port)
00418 {
00419 u_int32_t data;
00420 __asm __volatile("inl %1,%0" : "=a" (data) : "id" (port));
00421 return data;
00422 }
00423
00424 static __inline u_int32_t
00425 __inl(int port)
00426 {
00427 u_int32_t data;
00428 __asm __volatile("inl %w1,%0" : "=a" (data) : "d" (port));
00429 return data;
00430 }
00431
00432 static __inline void
00433 insl(int port, void *addr, int cnt)
00434 {
00435 void *dummy1;
00436 int dummy2;
00437 __asm __volatile("cld\n\trepne\n\tinsl" :
00438 "=D" (dummy1), "=c" (dummy2) :
00439 "d" (port), "0" (addr), "1" (cnt) :
00440 "memory");
00441 }
00442
00443 #define outb(port, data) \
00444 (__use_immediate_port(port) ? __outbc(port, data) : __outb(port, data))
00445
00446 static __inline void
00447 __outbc(int port, u_int8_t data)
00448 {
00449 __asm __volatile("outb %0,%1" : : "a" (data), "id" (port));
00450 }
00451
00452 static __inline void
00453 __outb(int port, u_int8_t data)
00454 {
00455 __asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
00456 }
00457
00458 static __inline void
00459 outsb(int port, void *addr, int cnt)
00460 {
00461 void *dummy1;
00462 int dummy2;
00463 __asm __volatile("cld\n\trepne\n\toutsb" :
00464 "=S" (dummy1), "=c" (dummy2) :
00465 "d" (port), "0" (addr), "1" (cnt));
00466 }
00467
00468 #define outw(port, data) \
00469 (__use_immediate_port(port) ? __outwc(port, data) : __outw(port, data))
00470
00471 static __inline void
00472 __outwc(int port, u_int16_t data)
00473 {
00474 __asm __volatile("outw %0,%1" : : "a" (data), "id" (port));
00475 }
00476
00477 static __inline void
00478 __outw(int port, u_int16_t data)
00479 {
00480 __asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));
00481 }
00482
00483 static __inline void
00484 outsw(int port, void *addr, int cnt)
00485 {
00486 void *dummy1;
00487 int dummy2;
00488 __asm __volatile("cld\n\trepne\n\toutsw" :
00489 "=S" (dummy1), "=c" (dummy2) :
00490 "d" (port), "0" (addr), "1" (cnt));
00491 }
00492
00493 #define outl(port, data) \
00494 (__use_immediate_port(port) ? __outlc(port, data) : __outl(port, data))
00495
00496 static __inline void
00497 __outlc(int port, u_int32_t data)
00498 {
00499 __asm __volatile("outl %0,%1" : : "a" (data), "id" (port));
00500 }
00501
00502 static __inline void
00503 __outl(int port, u_int32_t data)
00504 {
00505 __asm __volatile("outl %0,%w1" : : "a" (data), "d" (port));
00506 }
00507
00508 static __inline void
00509 outsl(int port, void *addr, int cnt)
00510 {
00511 void *dummy1;
00512 int dummy2;
00513 __asm __volatile("cld\n\trepne\n\toutsl" :
00514 "=S" (dummy1), "=c" (dummy2) :
00515 "d" (port), "0" (addr), "1" (cnt));
00516 }
00517
00518
00519
00520
00521
00522 static __inline void
00523 waitch(u_int8_t waited)
00524 {
00525 static u_int8_t prev_code = 0xff;
00526 u_int8_t code;
00527
00528 while (1)
00529 {
00530 code = inb(0x60);
00531 if (code == waited && prev_code != waited)
00532 {
00533 prev_code = code;
00534 return ;
00535 }
00536 prev_code = code;
00537 }
00538 }
00539
00540 #endif
00541 #endif