1*199767f8SToomas Soome /*- 2*199767f8SToomas Soome * Copyright (c) 1993 The Regents of the University of California. 3*199767f8SToomas Soome * All rights reserved. 4*199767f8SToomas Soome * 5*199767f8SToomas Soome * Redistribution and use in source and binary forms, with or without 6*199767f8SToomas Soome * modification, are permitted provided that the following conditions 7*199767f8SToomas Soome * are met: 8*199767f8SToomas Soome * 1. Redistributions of source code must retain the above copyright 9*199767f8SToomas Soome * notice, this list of conditions and the following disclaimer. 10*199767f8SToomas Soome * 2. Redistributions in binary form must reproduce the above copyright 11*199767f8SToomas Soome * notice, this list of conditions and the following disclaimer in the 12*199767f8SToomas Soome * documentation and/or other materials provided with the distribution. 13*199767f8SToomas Soome * 4. Neither the name of the University nor the names of its contributors 14*199767f8SToomas Soome * may be used to endorse or promote products derived from this software 15*199767f8SToomas Soome * without specific prior written permission. 16*199767f8SToomas Soome * 17*199767f8SToomas Soome * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18*199767f8SToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19*199767f8SToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20*199767f8SToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21*199767f8SToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22*199767f8SToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23*199767f8SToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24*199767f8SToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25*199767f8SToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26*199767f8SToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27*199767f8SToomas Soome * SUCH DAMAGE. 28*199767f8SToomas Soome * 29*199767f8SToomas Soome * $FreeBSD$ 30*199767f8SToomas Soome */ 31*199767f8SToomas Soome 32*199767f8SToomas Soome /* 33*199767f8SToomas Soome * Functions to provide access to special i386 instructions. 34*199767f8SToomas Soome * This in included in sys/systm.h, and that file should be 35*199767f8SToomas Soome * used in preference to this. 36*199767f8SToomas Soome */ 37*199767f8SToomas Soome 38*199767f8SToomas Soome #ifndef _MACHINE_CPUFUNC_H_ 39*199767f8SToomas Soome #define _MACHINE_CPUFUNC_H_ 40*199767f8SToomas Soome 41*199767f8SToomas Soome #ifndef _SYS_CDEFS_H_ 42*199767f8SToomas Soome #error this file needs sys/cdefs.h as a prerequisite 43*199767f8SToomas Soome #endif 44*199767f8SToomas Soome 45*199767f8SToomas Soome struct region_descriptor; 46*199767f8SToomas Soome 47*199767f8SToomas Soome #define readb(va) (*(volatile uint8_t *) (va)) 48*199767f8SToomas Soome #define readw(va) (*(volatile uint16_t *) (va)) 49*199767f8SToomas Soome #define readl(va) (*(volatile uint32_t *) (va)) 50*199767f8SToomas Soome 51*199767f8SToomas Soome #define writeb(va, d) (*(volatile uint8_t *) (va) = (d)) 52*199767f8SToomas Soome #define writew(va, d) (*(volatile uint16_t *) (va) = (d)) 53*199767f8SToomas Soome #define writel(va, d) (*(volatile uint32_t *) (va) = (d)) 54*199767f8SToomas Soome 55*199767f8SToomas Soome #if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE) 56*199767f8SToomas Soome 57*199767f8SToomas Soome static __inline void 58*199767f8SToomas Soome breakpoint(void) 59*199767f8SToomas Soome { 60*199767f8SToomas Soome __asm __volatile("int $3"); 61*199767f8SToomas Soome } 62*199767f8SToomas Soome 63*199767f8SToomas Soome static __inline u_int 64*199767f8SToomas Soome bsfl(u_int mask) 65*199767f8SToomas Soome { 66*199767f8SToomas Soome u_int result; 67*199767f8SToomas Soome 68*199767f8SToomas Soome __asm("bsfl %1,%0" : "=r" (result) : "rm" (mask) : "cc"); 69*199767f8SToomas Soome return (result); 70*199767f8SToomas Soome } 71*199767f8SToomas Soome 72*199767f8SToomas Soome static __inline u_int 73*199767f8SToomas Soome bsrl(u_int mask) 74*199767f8SToomas Soome { 75*199767f8SToomas Soome u_int result; 76*199767f8SToomas Soome 77*199767f8SToomas Soome __asm("bsrl %1,%0" : "=r" (result) : "rm" (mask) : "cc"); 78*199767f8SToomas Soome return (result); 79*199767f8SToomas Soome } 80*199767f8SToomas Soome 81*199767f8SToomas Soome static __inline void 82*199767f8SToomas Soome clflush(u_long addr) 83*199767f8SToomas Soome { 84*199767f8SToomas Soome 85*199767f8SToomas Soome __asm __volatile("clflush %0" : : "m" (*(char *)addr)); 86*199767f8SToomas Soome } 87*199767f8SToomas Soome 88*199767f8SToomas Soome static __inline void 89*199767f8SToomas Soome clflushopt(u_long addr) 90*199767f8SToomas Soome { 91*199767f8SToomas Soome 92*199767f8SToomas Soome __asm __volatile(".byte 0x66;clflush %0" : : "m" (*(char *)addr)); 93*199767f8SToomas Soome } 94*199767f8SToomas Soome 95*199767f8SToomas Soome static __inline void 96*199767f8SToomas Soome clts(void) 97*199767f8SToomas Soome { 98*199767f8SToomas Soome 99*199767f8SToomas Soome __asm __volatile("clts"); 100*199767f8SToomas Soome } 101*199767f8SToomas Soome 102*199767f8SToomas Soome static __inline void 103*199767f8SToomas Soome disable_intr(void) 104*199767f8SToomas Soome { 105*199767f8SToomas Soome 106*199767f8SToomas Soome __asm __volatile("cli" : : : "memory"); 107*199767f8SToomas Soome } 108*199767f8SToomas Soome 109*199767f8SToomas Soome static __inline void 110*199767f8SToomas Soome do_cpuid(u_int ax, u_int *p) 111*199767f8SToomas Soome { 112*199767f8SToomas Soome __asm __volatile("cpuid" 113*199767f8SToomas Soome : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) 114*199767f8SToomas Soome : "0" (ax)); 115*199767f8SToomas Soome } 116*199767f8SToomas Soome 117*199767f8SToomas Soome static __inline void 118*199767f8SToomas Soome cpuid_count(u_int ax, u_int cx, u_int *p) 119*199767f8SToomas Soome { 120*199767f8SToomas Soome __asm __volatile("cpuid" 121*199767f8SToomas Soome : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) 122*199767f8SToomas Soome : "0" (ax), "c" (cx)); 123*199767f8SToomas Soome } 124*199767f8SToomas Soome 125*199767f8SToomas Soome static __inline void 126*199767f8SToomas Soome enable_intr(void) 127*199767f8SToomas Soome { 128*199767f8SToomas Soome 129*199767f8SToomas Soome __asm __volatile("sti"); 130*199767f8SToomas Soome } 131*199767f8SToomas Soome 132*199767f8SToomas Soome static __inline void 133*199767f8SToomas Soome cpu_monitor(const void *addr, u_long extensions, u_int hints) 134*199767f8SToomas Soome { 135*199767f8SToomas Soome 136*199767f8SToomas Soome __asm __volatile("monitor" 137*199767f8SToomas Soome : : "a" (addr), "c" (extensions), "d" (hints)); 138*199767f8SToomas Soome } 139*199767f8SToomas Soome 140*199767f8SToomas Soome static __inline void 141*199767f8SToomas Soome cpu_mwait(u_long extensions, u_int hints) 142*199767f8SToomas Soome { 143*199767f8SToomas Soome 144*199767f8SToomas Soome __asm __volatile("mwait" : : "a" (hints), "c" (extensions)); 145*199767f8SToomas Soome } 146*199767f8SToomas Soome 147*199767f8SToomas Soome static __inline void 148*199767f8SToomas Soome lfence(void) 149*199767f8SToomas Soome { 150*199767f8SToomas Soome 151*199767f8SToomas Soome __asm __volatile("lfence" : : : "memory"); 152*199767f8SToomas Soome } 153*199767f8SToomas Soome 154*199767f8SToomas Soome static __inline void 155*199767f8SToomas Soome mfence(void) 156*199767f8SToomas Soome { 157*199767f8SToomas Soome 158*199767f8SToomas Soome __asm __volatile("mfence" : : : "memory"); 159*199767f8SToomas Soome } 160*199767f8SToomas Soome 161*199767f8SToomas Soome #ifdef _KERNEL 162*199767f8SToomas Soome 163*199767f8SToomas Soome #define HAVE_INLINE_FFS 164*199767f8SToomas Soome 165*199767f8SToomas Soome static __inline int 166*199767f8SToomas Soome ffs(int mask) 167*199767f8SToomas Soome { 168*199767f8SToomas Soome /* 169*199767f8SToomas Soome * Note that gcc-2's builtin ffs would be used if we didn't declare 170*199767f8SToomas Soome * this inline or turn off the builtin. The builtin is faster but 171*199767f8SToomas Soome * broken in gcc-2.4.5 and slower but working in gcc-2.5 and later 172*199767f8SToomas Soome * versions. 173*199767f8SToomas Soome */ 174*199767f8SToomas Soome return (mask == 0 ? mask : (int)bsfl((u_int)mask) + 1); 175*199767f8SToomas Soome } 176*199767f8SToomas Soome 177*199767f8SToomas Soome #define HAVE_INLINE_FFSL 178*199767f8SToomas Soome 179*199767f8SToomas Soome static __inline int 180*199767f8SToomas Soome ffsl(long mask) 181*199767f8SToomas Soome { 182*199767f8SToomas Soome return (ffs((int)mask)); 183*199767f8SToomas Soome } 184*199767f8SToomas Soome 185*199767f8SToomas Soome #define HAVE_INLINE_FLS 186*199767f8SToomas Soome 187*199767f8SToomas Soome static __inline int 188*199767f8SToomas Soome fls(int mask) 189*199767f8SToomas Soome { 190*199767f8SToomas Soome return (mask == 0 ? mask : (int)bsrl((u_int)mask) + 1); 191*199767f8SToomas Soome } 192*199767f8SToomas Soome 193*199767f8SToomas Soome #define HAVE_INLINE_FLSL 194*199767f8SToomas Soome 195*199767f8SToomas Soome static __inline int 196*199767f8SToomas Soome flsl(long mask) 197*199767f8SToomas Soome { 198*199767f8SToomas Soome return (fls((int)mask)); 199*199767f8SToomas Soome } 200*199767f8SToomas Soome 201*199767f8SToomas Soome #endif /* _KERNEL */ 202*199767f8SToomas Soome 203*199767f8SToomas Soome static __inline void 204*199767f8SToomas Soome halt(void) 205*199767f8SToomas Soome { 206*199767f8SToomas Soome __asm __volatile("hlt"); 207*199767f8SToomas Soome } 208*199767f8SToomas Soome 209*199767f8SToomas Soome static __inline u_char 210*199767f8SToomas Soome inb(u_int port) 211*199767f8SToomas Soome { 212*199767f8SToomas Soome u_char data; 213*199767f8SToomas Soome 214*199767f8SToomas Soome __asm __volatile("inb %w1, %0" : "=a" (data) : "Nd" (port)); 215*199767f8SToomas Soome return (data); 216*199767f8SToomas Soome } 217*199767f8SToomas Soome 218*199767f8SToomas Soome static __inline u_int 219*199767f8SToomas Soome inl(u_int port) 220*199767f8SToomas Soome { 221*199767f8SToomas Soome u_int data; 222*199767f8SToomas Soome 223*199767f8SToomas Soome __asm __volatile("inl %w1, %0" : "=a" (data) : "Nd" (port)); 224*199767f8SToomas Soome return (data); 225*199767f8SToomas Soome } 226*199767f8SToomas Soome 227*199767f8SToomas Soome static __inline void 228*199767f8SToomas Soome insb(u_int port, void *addr, size_t count) 229*199767f8SToomas Soome { 230*199767f8SToomas Soome __asm __volatile("cld; rep; insb" 231*199767f8SToomas Soome : "+D" (addr), "+c" (count) 232*199767f8SToomas Soome : "d" (port) 233*199767f8SToomas Soome : "memory"); 234*199767f8SToomas Soome } 235*199767f8SToomas Soome 236*199767f8SToomas Soome static __inline void 237*199767f8SToomas Soome insw(u_int port, void *addr, size_t count) 238*199767f8SToomas Soome { 239*199767f8SToomas Soome __asm __volatile("cld; rep; insw" 240*199767f8SToomas Soome : "+D" (addr), "+c" (count) 241*199767f8SToomas Soome : "d" (port) 242*199767f8SToomas Soome : "memory"); 243*199767f8SToomas Soome } 244*199767f8SToomas Soome 245*199767f8SToomas Soome static __inline void 246*199767f8SToomas Soome insl(u_int port, void *addr, size_t count) 247*199767f8SToomas Soome { 248*199767f8SToomas Soome __asm __volatile("cld; rep; insl" 249*199767f8SToomas Soome : "+D" (addr), "+c" (count) 250*199767f8SToomas Soome : "d" (port) 251*199767f8SToomas Soome : "memory"); 252*199767f8SToomas Soome } 253*199767f8SToomas Soome 254*199767f8SToomas Soome static __inline void 255*199767f8SToomas Soome invd(void) 256*199767f8SToomas Soome { 257*199767f8SToomas Soome __asm __volatile("invd"); 258*199767f8SToomas Soome } 259*199767f8SToomas Soome 260*199767f8SToomas Soome static __inline u_short 261*199767f8SToomas Soome inw(u_int port) 262*199767f8SToomas Soome { 263*199767f8SToomas Soome u_short data; 264*199767f8SToomas Soome 265*199767f8SToomas Soome __asm __volatile("inw %w1, %0" : "=a" (data) : "Nd" (port)); 266*199767f8SToomas Soome return (data); 267*199767f8SToomas Soome } 268*199767f8SToomas Soome 269*199767f8SToomas Soome static __inline void 270*199767f8SToomas Soome outb(u_int port, u_char data) 271*199767f8SToomas Soome { 272*199767f8SToomas Soome __asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port)); 273*199767f8SToomas Soome } 274*199767f8SToomas Soome 275*199767f8SToomas Soome static __inline void 276*199767f8SToomas Soome outl(u_int port, u_int data) 277*199767f8SToomas Soome { 278*199767f8SToomas Soome __asm __volatile("outl %0, %w1" : : "a" (data), "Nd" (port)); 279*199767f8SToomas Soome } 280*199767f8SToomas Soome 281*199767f8SToomas Soome static __inline void 282*199767f8SToomas Soome outsb(u_int port, const void *addr, size_t count) 283*199767f8SToomas Soome { 284*199767f8SToomas Soome __asm __volatile("cld; rep; outsb" 285*199767f8SToomas Soome : "+S" (addr), "+c" (count) 286*199767f8SToomas Soome : "d" (port)); 287*199767f8SToomas Soome } 288*199767f8SToomas Soome 289*199767f8SToomas Soome static __inline void 290*199767f8SToomas Soome outsw(u_int port, const void *addr, size_t count) 291*199767f8SToomas Soome { 292*199767f8SToomas Soome __asm __volatile("cld; rep; outsw" 293*199767f8SToomas Soome : "+S" (addr), "+c" (count) 294*199767f8SToomas Soome : "d" (port)); 295*199767f8SToomas Soome } 296*199767f8SToomas Soome 297*199767f8SToomas Soome static __inline void 298*199767f8SToomas Soome outsl(u_int port, const void *addr, size_t count) 299*199767f8SToomas Soome { 300*199767f8SToomas Soome __asm __volatile("cld; rep; outsl" 301*199767f8SToomas Soome : "+S" (addr), "+c" (count) 302*199767f8SToomas Soome : "d" (port)); 303*199767f8SToomas Soome } 304*199767f8SToomas Soome 305*199767f8SToomas Soome static __inline void 306*199767f8SToomas Soome outw(u_int port, u_short data) 307*199767f8SToomas Soome { 308*199767f8SToomas Soome __asm __volatile("outw %0, %w1" : : "a" (data), "Nd" (port)); 309*199767f8SToomas Soome } 310*199767f8SToomas Soome 311*199767f8SToomas Soome static __inline void 312*199767f8SToomas Soome ia32_pause(void) 313*199767f8SToomas Soome { 314*199767f8SToomas Soome __asm __volatile("pause"); 315*199767f8SToomas Soome } 316*199767f8SToomas Soome 317*199767f8SToomas Soome static __inline u_int 318*199767f8SToomas Soome read_eflags(void) 319*199767f8SToomas Soome { 320*199767f8SToomas Soome u_int ef; 321*199767f8SToomas Soome 322*199767f8SToomas Soome __asm __volatile("pushfl; popl %0" : "=r" (ef)); 323*199767f8SToomas Soome return (ef); 324*199767f8SToomas Soome } 325*199767f8SToomas Soome 326*199767f8SToomas Soome static __inline uint64_t 327*199767f8SToomas Soome rdmsr(u_int msr) 328*199767f8SToomas Soome { 329*199767f8SToomas Soome uint64_t rv; 330*199767f8SToomas Soome 331*199767f8SToomas Soome __asm __volatile("rdmsr" : "=A" (rv) : "c" (msr)); 332*199767f8SToomas Soome return (rv); 333*199767f8SToomas Soome } 334*199767f8SToomas Soome 335*199767f8SToomas Soome static __inline uint32_t 336*199767f8SToomas Soome rdmsr32(u_int msr) 337*199767f8SToomas Soome { 338*199767f8SToomas Soome uint32_t low; 339*199767f8SToomas Soome 340*199767f8SToomas Soome __asm __volatile("rdmsr" : "=a" (low) : "c" (msr) : "edx"); 341*199767f8SToomas Soome return (low); 342*199767f8SToomas Soome } 343*199767f8SToomas Soome 344*199767f8SToomas Soome static __inline uint64_t 345*199767f8SToomas Soome rdpmc(u_int pmc) 346*199767f8SToomas Soome { 347*199767f8SToomas Soome uint64_t rv; 348*199767f8SToomas Soome 349*199767f8SToomas Soome __asm __volatile("rdpmc" : "=A" (rv) : "c" (pmc)); 350*199767f8SToomas Soome return (rv); 351*199767f8SToomas Soome } 352*199767f8SToomas Soome 353*199767f8SToomas Soome static __inline uint64_t 354*199767f8SToomas Soome rdtsc(void) 355*199767f8SToomas Soome { 356*199767f8SToomas Soome uint64_t rv; 357*199767f8SToomas Soome 358*199767f8SToomas Soome __asm __volatile("rdtsc" : "=A" (rv)); 359*199767f8SToomas Soome return (rv); 360*199767f8SToomas Soome } 361*199767f8SToomas Soome 362*199767f8SToomas Soome static __inline uint32_t 363*199767f8SToomas Soome rdtsc32(void) 364*199767f8SToomas Soome { 365*199767f8SToomas Soome uint32_t rv; 366*199767f8SToomas Soome 367*199767f8SToomas Soome __asm __volatile("rdtsc" : "=a" (rv) : : "edx"); 368*199767f8SToomas Soome return (rv); 369*199767f8SToomas Soome } 370*199767f8SToomas Soome 371*199767f8SToomas Soome static __inline void 372*199767f8SToomas Soome wbinvd(void) 373*199767f8SToomas Soome { 374*199767f8SToomas Soome __asm __volatile("wbinvd"); 375*199767f8SToomas Soome } 376*199767f8SToomas Soome 377*199767f8SToomas Soome static __inline void 378*199767f8SToomas Soome write_eflags(u_int ef) 379*199767f8SToomas Soome { 380*199767f8SToomas Soome __asm __volatile("pushl %0; popfl" : : "r" (ef)); 381*199767f8SToomas Soome } 382*199767f8SToomas Soome 383*199767f8SToomas Soome static __inline void 384*199767f8SToomas Soome wrmsr(u_int msr, uint64_t newval) 385*199767f8SToomas Soome { 386*199767f8SToomas Soome __asm __volatile("wrmsr" : : "A" (newval), "c" (msr)); 387*199767f8SToomas Soome } 388*199767f8SToomas Soome 389*199767f8SToomas Soome static __inline void 390*199767f8SToomas Soome load_cr0(u_int data) 391*199767f8SToomas Soome { 392*199767f8SToomas Soome 393*199767f8SToomas Soome __asm __volatile("movl %0,%%cr0" : : "r" (data)); 394*199767f8SToomas Soome } 395*199767f8SToomas Soome 396*199767f8SToomas Soome static __inline u_int 397*199767f8SToomas Soome rcr0(void) 398*199767f8SToomas Soome { 399*199767f8SToomas Soome u_int data; 400*199767f8SToomas Soome 401*199767f8SToomas Soome __asm __volatile("movl %%cr0,%0" : "=r" (data)); 402*199767f8SToomas Soome return (data); 403*199767f8SToomas Soome } 404*199767f8SToomas Soome 405*199767f8SToomas Soome static __inline u_int 406*199767f8SToomas Soome rcr2(void) 407*199767f8SToomas Soome { 408*199767f8SToomas Soome u_int data; 409*199767f8SToomas Soome 410*199767f8SToomas Soome __asm __volatile("movl %%cr2,%0" : "=r" (data)); 411*199767f8SToomas Soome return (data); 412*199767f8SToomas Soome } 413*199767f8SToomas Soome 414*199767f8SToomas Soome static __inline void 415*199767f8SToomas Soome load_cr3(u_int data) 416*199767f8SToomas Soome { 417*199767f8SToomas Soome 418*199767f8SToomas Soome __asm __volatile("movl %0,%%cr3" : : "r" (data) : "memory"); 419*199767f8SToomas Soome } 420*199767f8SToomas Soome 421*199767f8SToomas Soome static __inline u_int 422*199767f8SToomas Soome rcr3(void) 423*199767f8SToomas Soome { 424*199767f8SToomas Soome u_int data; 425*199767f8SToomas Soome 426*199767f8SToomas Soome __asm __volatile("movl %%cr3,%0" : "=r" (data)); 427*199767f8SToomas Soome return (data); 428*199767f8SToomas Soome } 429*199767f8SToomas Soome 430*199767f8SToomas Soome static __inline void 431*199767f8SToomas Soome load_cr4(u_int data) 432*199767f8SToomas Soome { 433*199767f8SToomas Soome __asm __volatile("movl %0,%%cr4" : : "r" (data)); 434*199767f8SToomas Soome } 435*199767f8SToomas Soome 436*199767f8SToomas Soome static __inline u_int 437*199767f8SToomas Soome rcr4(void) 438*199767f8SToomas Soome { 439*199767f8SToomas Soome u_int data; 440*199767f8SToomas Soome 441*199767f8SToomas Soome __asm __volatile("movl %%cr4,%0" : "=r" (data)); 442*199767f8SToomas Soome return (data); 443*199767f8SToomas Soome } 444*199767f8SToomas Soome 445*199767f8SToomas Soome static __inline uint64_t 446*199767f8SToomas Soome rxcr(u_int reg) 447*199767f8SToomas Soome { 448*199767f8SToomas Soome u_int low, high; 449*199767f8SToomas Soome 450*199767f8SToomas Soome __asm __volatile("xgetbv" : "=a" (low), "=d" (high) : "c" (reg)); 451*199767f8SToomas Soome return (low | ((uint64_t)high << 32)); 452*199767f8SToomas Soome } 453*199767f8SToomas Soome 454*199767f8SToomas Soome static __inline void 455*199767f8SToomas Soome load_xcr(u_int reg, uint64_t val) 456*199767f8SToomas Soome { 457*199767f8SToomas Soome u_int low, high; 458*199767f8SToomas Soome 459*199767f8SToomas Soome low = val; 460*199767f8SToomas Soome high = val >> 32; 461*199767f8SToomas Soome __asm __volatile("xsetbv" : : "c" (reg), "a" (low), "d" (high)); 462*199767f8SToomas Soome } 463*199767f8SToomas Soome 464*199767f8SToomas Soome /* 465*199767f8SToomas Soome * Global TLB flush (except for thise for pages marked PG_G) 466*199767f8SToomas Soome */ 467*199767f8SToomas Soome static __inline void 468*199767f8SToomas Soome invltlb(void) 469*199767f8SToomas Soome { 470*199767f8SToomas Soome 471*199767f8SToomas Soome load_cr3(rcr3()); 472*199767f8SToomas Soome } 473*199767f8SToomas Soome 474*199767f8SToomas Soome /* 475*199767f8SToomas Soome * TLB flush for an individual page (even if it has PG_G). 476*199767f8SToomas Soome * Only works on 486+ CPUs (i386 does not have PG_G). 477*199767f8SToomas Soome */ 478*199767f8SToomas Soome static __inline void 479*199767f8SToomas Soome invlpg(u_int addr) 480*199767f8SToomas Soome { 481*199767f8SToomas Soome 482*199767f8SToomas Soome __asm __volatile("invlpg %0" : : "m" (*(char *)addr) : "memory"); 483*199767f8SToomas Soome } 484*199767f8SToomas Soome 485*199767f8SToomas Soome static __inline u_short 486*199767f8SToomas Soome rfs(void) 487*199767f8SToomas Soome { 488*199767f8SToomas Soome u_short sel; 489*199767f8SToomas Soome __asm __volatile("movw %%fs,%0" : "=rm" (sel)); 490*199767f8SToomas Soome return (sel); 491*199767f8SToomas Soome } 492*199767f8SToomas Soome 493*199767f8SToomas Soome static __inline uint64_t 494*199767f8SToomas Soome rgdt(void) 495*199767f8SToomas Soome { 496*199767f8SToomas Soome uint64_t gdtr; 497*199767f8SToomas Soome __asm __volatile("sgdt %0" : "=m" (gdtr)); 498*199767f8SToomas Soome return (gdtr); 499*199767f8SToomas Soome } 500*199767f8SToomas Soome 501*199767f8SToomas Soome static __inline u_short 502*199767f8SToomas Soome rgs(void) 503*199767f8SToomas Soome { 504*199767f8SToomas Soome u_short sel; 505*199767f8SToomas Soome __asm __volatile("movw %%gs,%0" : "=rm" (sel)); 506*199767f8SToomas Soome return (sel); 507*199767f8SToomas Soome } 508*199767f8SToomas Soome 509*199767f8SToomas Soome static __inline uint64_t 510*199767f8SToomas Soome ridt(void) 511*199767f8SToomas Soome { 512*199767f8SToomas Soome uint64_t idtr; 513*199767f8SToomas Soome __asm __volatile("sidt %0" : "=m" (idtr)); 514*199767f8SToomas Soome return (idtr); 515*199767f8SToomas Soome } 516*199767f8SToomas Soome 517*199767f8SToomas Soome static __inline u_short 518*199767f8SToomas Soome rldt(void) 519*199767f8SToomas Soome { 520*199767f8SToomas Soome u_short ldtr; 521*199767f8SToomas Soome __asm __volatile("sldt %0" : "=g" (ldtr)); 522*199767f8SToomas Soome return (ldtr); 523*199767f8SToomas Soome } 524*199767f8SToomas Soome 525*199767f8SToomas Soome static __inline u_short 526*199767f8SToomas Soome rss(void) 527*199767f8SToomas Soome { 528*199767f8SToomas Soome u_short sel; 529*199767f8SToomas Soome __asm __volatile("movw %%ss,%0" : "=rm" (sel)); 530*199767f8SToomas Soome return (sel); 531*199767f8SToomas Soome } 532*199767f8SToomas Soome 533*199767f8SToomas Soome static __inline u_short 534*199767f8SToomas Soome rtr(void) 535*199767f8SToomas Soome { 536*199767f8SToomas Soome u_short tr; 537*199767f8SToomas Soome __asm __volatile("str %0" : "=g" (tr)); 538*199767f8SToomas Soome return (tr); 539*199767f8SToomas Soome } 540*199767f8SToomas Soome 541*199767f8SToomas Soome static __inline void 542*199767f8SToomas Soome load_fs(u_short sel) 543*199767f8SToomas Soome { 544*199767f8SToomas Soome __asm __volatile("movw %0,%%fs" : : "rm" (sel)); 545*199767f8SToomas Soome } 546*199767f8SToomas Soome 547*199767f8SToomas Soome static __inline void 548*199767f8SToomas Soome load_gs(u_short sel) 549*199767f8SToomas Soome { 550*199767f8SToomas Soome __asm __volatile("movw %0,%%gs" : : "rm" (sel)); 551*199767f8SToomas Soome } 552*199767f8SToomas Soome 553*199767f8SToomas Soome static __inline void 554*199767f8SToomas Soome lidt(struct region_descriptor *addr) 555*199767f8SToomas Soome { 556*199767f8SToomas Soome __asm __volatile("lidt (%0)" : : "r" (addr)); 557*199767f8SToomas Soome } 558*199767f8SToomas Soome 559*199767f8SToomas Soome static __inline void 560*199767f8SToomas Soome lldt(u_short sel) 561*199767f8SToomas Soome { 562*199767f8SToomas Soome __asm __volatile("lldt %0" : : "r" (sel)); 563*199767f8SToomas Soome } 564*199767f8SToomas Soome 565*199767f8SToomas Soome static __inline void 566*199767f8SToomas Soome ltr(u_short sel) 567*199767f8SToomas Soome { 568*199767f8SToomas Soome __asm __volatile("ltr %0" : : "r" (sel)); 569*199767f8SToomas Soome } 570*199767f8SToomas Soome 571*199767f8SToomas Soome static __inline u_int 572*199767f8SToomas Soome rdr0(void) 573*199767f8SToomas Soome { 574*199767f8SToomas Soome u_int data; 575*199767f8SToomas Soome __asm __volatile("movl %%dr0,%0" : "=r" (data)); 576*199767f8SToomas Soome return (data); 577*199767f8SToomas Soome } 578*199767f8SToomas Soome 579*199767f8SToomas Soome static __inline void 580*199767f8SToomas Soome load_dr0(u_int dr0) 581*199767f8SToomas Soome { 582*199767f8SToomas Soome __asm __volatile("movl %0,%%dr0" : : "r" (dr0)); 583*199767f8SToomas Soome } 584*199767f8SToomas Soome 585*199767f8SToomas Soome static __inline u_int 586*199767f8SToomas Soome rdr1(void) 587*199767f8SToomas Soome { 588*199767f8SToomas Soome u_int data; 589*199767f8SToomas Soome __asm __volatile("movl %%dr1,%0" : "=r" (data)); 590*199767f8SToomas Soome return (data); 591*199767f8SToomas Soome } 592*199767f8SToomas Soome 593*199767f8SToomas Soome static __inline void 594*199767f8SToomas Soome load_dr1(u_int dr1) 595*199767f8SToomas Soome { 596*199767f8SToomas Soome __asm __volatile("movl %0,%%dr1" : : "r" (dr1)); 597*199767f8SToomas Soome } 598*199767f8SToomas Soome 599*199767f8SToomas Soome static __inline u_int 600*199767f8SToomas Soome rdr2(void) 601*199767f8SToomas Soome { 602*199767f8SToomas Soome u_int data; 603*199767f8SToomas Soome __asm __volatile("movl %%dr2,%0" : "=r" (data)); 604*199767f8SToomas Soome return (data); 605*199767f8SToomas Soome } 606*199767f8SToomas Soome 607*199767f8SToomas Soome static __inline void 608*199767f8SToomas Soome load_dr2(u_int dr2) 609*199767f8SToomas Soome { 610*199767f8SToomas Soome __asm __volatile("movl %0,%%dr2" : : "r" (dr2)); 611*199767f8SToomas Soome } 612*199767f8SToomas Soome 613*199767f8SToomas Soome static __inline u_int 614*199767f8SToomas Soome rdr3(void) 615*199767f8SToomas Soome { 616*199767f8SToomas Soome u_int data; 617*199767f8SToomas Soome __asm __volatile("movl %%dr3,%0" : "=r" (data)); 618*199767f8SToomas Soome return (data); 619*199767f8SToomas Soome } 620*199767f8SToomas Soome 621*199767f8SToomas Soome static __inline void 622*199767f8SToomas Soome load_dr3(u_int dr3) 623*199767f8SToomas Soome { 624*199767f8SToomas Soome __asm __volatile("movl %0,%%dr3" : : "r" (dr3)); 625*199767f8SToomas Soome } 626*199767f8SToomas Soome 627*199767f8SToomas Soome static __inline u_int 628*199767f8SToomas Soome rdr4(void) 629*199767f8SToomas Soome { 630*199767f8SToomas Soome u_int data; 631*199767f8SToomas Soome __asm __volatile("movl %%dr4,%0" : "=r" (data)); 632*199767f8SToomas Soome return (data); 633*199767f8SToomas Soome } 634*199767f8SToomas Soome 635*199767f8SToomas Soome static __inline void 636*199767f8SToomas Soome load_dr4(u_int dr4) 637*199767f8SToomas Soome { 638*199767f8SToomas Soome __asm __volatile("movl %0,%%dr4" : : "r" (dr4)); 639*199767f8SToomas Soome } 640*199767f8SToomas Soome 641*199767f8SToomas Soome static __inline u_int 642*199767f8SToomas Soome rdr5(void) 643*199767f8SToomas Soome { 644*199767f8SToomas Soome u_int data; 645*199767f8SToomas Soome __asm __volatile("movl %%dr5,%0" : "=r" (data)); 646*199767f8SToomas Soome return (data); 647*199767f8SToomas Soome } 648*199767f8SToomas Soome 649*199767f8SToomas Soome static __inline void 650*199767f8SToomas Soome load_dr5(u_int dr5) 651*199767f8SToomas Soome { 652*199767f8SToomas Soome __asm __volatile("movl %0,%%dr5" : : "r" (dr5)); 653*199767f8SToomas Soome } 654*199767f8SToomas Soome 655*199767f8SToomas Soome static __inline u_int 656*199767f8SToomas Soome rdr6(void) 657*199767f8SToomas Soome { 658*199767f8SToomas Soome u_int data; 659*199767f8SToomas Soome __asm __volatile("movl %%dr6,%0" : "=r" (data)); 660*199767f8SToomas Soome return (data); 661*199767f8SToomas Soome } 662*199767f8SToomas Soome 663*199767f8SToomas Soome static __inline void 664*199767f8SToomas Soome load_dr6(u_int dr6) 665*199767f8SToomas Soome { 666*199767f8SToomas Soome __asm __volatile("movl %0,%%dr6" : : "r" (dr6)); 667*199767f8SToomas Soome } 668*199767f8SToomas Soome 669*199767f8SToomas Soome static __inline u_int 670*199767f8SToomas Soome rdr7(void) 671*199767f8SToomas Soome { 672*199767f8SToomas Soome u_int data; 673*199767f8SToomas Soome __asm __volatile("movl %%dr7,%0" : "=r" (data)); 674*199767f8SToomas Soome return (data); 675*199767f8SToomas Soome } 676*199767f8SToomas Soome 677*199767f8SToomas Soome static __inline void 678*199767f8SToomas Soome load_dr7(u_int dr7) 679*199767f8SToomas Soome { 680*199767f8SToomas Soome __asm __volatile("movl %0,%%dr7" : : "r" (dr7)); 681*199767f8SToomas Soome } 682*199767f8SToomas Soome 683*199767f8SToomas Soome static __inline u_char 684*199767f8SToomas Soome read_cyrix_reg(u_char reg) 685*199767f8SToomas Soome { 686*199767f8SToomas Soome outb(0x22, reg); 687*199767f8SToomas Soome return inb(0x23); 688*199767f8SToomas Soome } 689*199767f8SToomas Soome 690*199767f8SToomas Soome static __inline void 691*199767f8SToomas Soome write_cyrix_reg(u_char reg, u_char data) 692*199767f8SToomas Soome { 693*199767f8SToomas Soome outb(0x22, reg); 694*199767f8SToomas Soome outb(0x23, data); 695*199767f8SToomas Soome } 696*199767f8SToomas Soome 697*199767f8SToomas Soome static __inline register_t 698*199767f8SToomas Soome intr_disable(void) 699*199767f8SToomas Soome { 700*199767f8SToomas Soome register_t eflags; 701*199767f8SToomas Soome 702*199767f8SToomas Soome eflags = read_eflags(); 703*199767f8SToomas Soome disable_intr(); 704*199767f8SToomas Soome return (eflags); 705*199767f8SToomas Soome } 706*199767f8SToomas Soome 707*199767f8SToomas Soome static __inline void 708*199767f8SToomas Soome intr_restore(register_t eflags) 709*199767f8SToomas Soome { 710*199767f8SToomas Soome write_eflags(eflags); 711*199767f8SToomas Soome } 712*199767f8SToomas Soome 713*199767f8SToomas Soome #else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */ 714*199767f8SToomas Soome 715*199767f8SToomas Soome int breakpoint(void); 716*199767f8SToomas Soome u_int bsfl(u_int mask); 717*199767f8SToomas Soome u_int bsrl(u_int mask); 718*199767f8SToomas Soome void clflush(u_long addr); 719*199767f8SToomas Soome void clts(void); 720*199767f8SToomas Soome void cpuid_count(u_int ax, u_int cx, u_int *p); 721*199767f8SToomas Soome void disable_intr(void); 722*199767f8SToomas Soome void do_cpuid(u_int ax, u_int *p); 723*199767f8SToomas Soome void enable_intr(void); 724*199767f8SToomas Soome void halt(void); 725*199767f8SToomas Soome void ia32_pause(void); 726*199767f8SToomas Soome u_char inb(u_int port); 727*199767f8SToomas Soome u_int inl(u_int port); 728*199767f8SToomas Soome void insb(u_int port, void *addr, size_t count); 729*199767f8SToomas Soome void insl(u_int port, void *addr, size_t count); 730*199767f8SToomas Soome void insw(u_int port, void *addr, size_t count); 731*199767f8SToomas Soome register_t intr_disable(void); 732*199767f8SToomas Soome void intr_restore(register_t ef); 733*199767f8SToomas Soome void invd(void); 734*199767f8SToomas Soome void invlpg(u_int addr); 735*199767f8SToomas Soome void invltlb(void); 736*199767f8SToomas Soome u_short inw(u_int port); 737*199767f8SToomas Soome void lidt(struct region_descriptor *addr); 738*199767f8SToomas Soome void lldt(u_short sel); 739*199767f8SToomas Soome void load_cr0(u_int cr0); 740*199767f8SToomas Soome void load_cr3(u_int cr3); 741*199767f8SToomas Soome void load_cr4(u_int cr4); 742*199767f8SToomas Soome void load_dr0(u_int dr0); 743*199767f8SToomas Soome void load_dr1(u_int dr1); 744*199767f8SToomas Soome void load_dr2(u_int dr2); 745*199767f8SToomas Soome void load_dr3(u_int dr3); 746*199767f8SToomas Soome void load_dr4(u_int dr4); 747*199767f8SToomas Soome void load_dr5(u_int dr5); 748*199767f8SToomas Soome void load_dr6(u_int dr6); 749*199767f8SToomas Soome void load_dr7(u_int dr7); 750*199767f8SToomas Soome void load_fs(u_short sel); 751*199767f8SToomas Soome void load_gs(u_short sel); 752*199767f8SToomas Soome void ltr(u_short sel); 753*199767f8SToomas Soome void outb(u_int port, u_char data); 754*199767f8SToomas Soome void outl(u_int port, u_int data); 755*199767f8SToomas Soome void outsb(u_int port, const void *addr, size_t count); 756*199767f8SToomas Soome void outsl(u_int port, const void *addr, size_t count); 757*199767f8SToomas Soome void outsw(u_int port, const void *addr, size_t count); 758*199767f8SToomas Soome void outw(u_int port, u_short data); 759*199767f8SToomas Soome u_int rcr0(void); 760*199767f8SToomas Soome u_int rcr2(void); 761*199767f8SToomas Soome u_int rcr3(void); 762*199767f8SToomas Soome u_int rcr4(void); 763*199767f8SToomas Soome uint64_t rdmsr(u_int msr); 764*199767f8SToomas Soome uint64_t rdpmc(u_int pmc); 765*199767f8SToomas Soome u_int rdr0(void); 766*199767f8SToomas Soome u_int rdr1(void); 767*199767f8SToomas Soome u_int rdr2(void); 768*199767f8SToomas Soome u_int rdr3(void); 769*199767f8SToomas Soome u_int rdr4(void); 770*199767f8SToomas Soome u_int rdr5(void); 771*199767f8SToomas Soome u_int rdr6(void); 772*199767f8SToomas Soome u_int rdr7(void); 773*199767f8SToomas Soome uint64_t rdtsc(void); 774*199767f8SToomas Soome u_char read_cyrix_reg(u_char reg); 775*199767f8SToomas Soome u_int read_eflags(void); 776*199767f8SToomas Soome u_int rfs(void); 777*199767f8SToomas Soome uint64_t rgdt(void); 778*199767f8SToomas Soome u_int rgs(void); 779*199767f8SToomas Soome uint64_t ridt(void); 780*199767f8SToomas Soome u_short rldt(void); 781*199767f8SToomas Soome u_short rtr(void); 782*199767f8SToomas Soome void wbinvd(void); 783*199767f8SToomas Soome void write_cyrix_reg(u_char reg, u_char data); 784*199767f8SToomas Soome void write_eflags(u_int ef); 785*199767f8SToomas Soome void wrmsr(u_int msr, uint64_t newval); 786*199767f8SToomas Soome 787*199767f8SToomas Soome #endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */ 788*199767f8SToomas Soome 789*199767f8SToomas Soome void reset_dbregs(void); 790*199767f8SToomas Soome 791*199767f8SToomas Soome #ifdef _KERNEL 792*199767f8SToomas Soome int rdmsr_safe(u_int msr, uint64_t *val); 793*199767f8SToomas Soome int wrmsr_safe(u_int msr, uint64_t newval); 794*199767f8SToomas Soome #endif 795*199767f8SToomas Soome 796*199767f8SToomas Soome #endif /* !_MACHINE_CPUFUNC_H_ */ 797