13c4dd356SDavid Greenman /*- 2fcfe57d6SPeter Wemm * Copyright (c) 2003 Peter Wemm. 33c4dd356SDavid Greenman * Copyright (c) 1993 The Regents of the University of California. 43c4dd356SDavid Greenman * All rights reserved. 53c4dd356SDavid Greenman * 63c4dd356SDavid Greenman * Redistribution and use in source and binary forms, with or without 73c4dd356SDavid Greenman * modification, are permitted provided that the following conditions 83c4dd356SDavid Greenman * are met: 93c4dd356SDavid Greenman * 1. Redistributions of source code must retain the above copyright 103c4dd356SDavid Greenman * notice, this list of conditions and the following disclaimer. 113c4dd356SDavid Greenman * 2. Redistributions in binary form must reproduce the above copyright 123c4dd356SDavid Greenman * notice, this list of conditions and the following disclaimer in the 133c4dd356SDavid Greenman * documentation and/or other materials provided with the distribution. 14fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors 153c4dd356SDavid Greenman * may be used to endorse or promote products derived from this software 163c4dd356SDavid Greenman * without specific prior written permission. 173c4dd356SDavid Greenman * 183c4dd356SDavid Greenman * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 193c4dd356SDavid Greenman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 203c4dd356SDavid Greenman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 213c4dd356SDavid Greenman * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 223c4dd356SDavid Greenman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 233c4dd356SDavid Greenman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 243c4dd356SDavid Greenman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 253c4dd356SDavid Greenman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 263c4dd356SDavid Greenman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 273c4dd356SDavid Greenman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 283c4dd356SDavid Greenman * SUCH DAMAGE. 293c4dd356SDavid Greenman * 30c3aac50fSPeter Wemm * $FreeBSD$ 313c4dd356SDavid Greenman */ 323c4dd356SDavid Greenman 335b81b6b3SRodney W. Grimes /* 345b81b6b3SRodney W. Grimes * Functions to provide access to special i386 instructions. 35f5d9a10bSMark Murray * This in included in sys/systm.h, and that file should be 36f5d9a10bSMark Murray * used in preference to this. 375b81b6b3SRodney W. Grimes */ 385b81b6b3SRodney W. Grimes 396e393973SGarrett Wollman #ifndef _MACHINE_CPUFUNC_H_ 40004bedebSBruce Evans #define _MACHINE_CPUFUNC_H_ 416e393973SGarrett Wollman 42a5f50ef9SJoerg Wunsch #ifndef _SYS_CDEFS_H_ 43a5f50ef9SJoerg Wunsch #error this file needs sys/cdefs.h as a prerequisite 44a5f50ef9SJoerg Wunsch #endif 45a5f50ef9SJoerg Wunsch 46eb1443c8SPeter Wemm struct region_descriptor; 47d74ac681SMatthew Dillon 48f5ac47f4SJung-uk Kim #define readb(va) (*(volatile uint8_t *) (va)) 49f5ac47f4SJung-uk Kim #define readw(va) (*(volatile uint16_t *) (va)) 50f5ac47f4SJung-uk Kim #define readl(va) (*(volatile uint32_t *) (va)) 51f5ac47f4SJung-uk Kim #define readq(va) (*(volatile uint64_t *) (va)) 52e31fa854SDoug Rabson 53f5ac47f4SJung-uk Kim #define writeb(va, d) (*(volatile uint8_t *) (va) = (d)) 54f5ac47f4SJung-uk Kim #define writew(va, d) (*(volatile uint16_t *) (va) = (d)) 55f5ac47f4SJung-uk Kim #define writel(va, d) (*(volatile uint32_t *) (va) = (d)) 56f5ac47f4SJung-uk Kim #define writeq(va, d) (*(volatile uint64_t *) (va) = (d)) 57e31fa854SDoug Rabson 58a5f50ef9SJoerg Wunsch #if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE) 595b81b6b3SRodney W. Grimes 605dbd168eSBruce Evans static __inline void 615dbd168eSBruce Evans breakpoint(void) 62004bedebSBruce Evans { 63004bedebSBruce Evans __asm __volatile("int $3"); 645b81b6b3SRodney W. Grimes } 655b81b6b3SRodney W. Grimes 666f240e18SConrad Meyer static __inline __pure2 u_int 67c83b1328SBruce Evans bsfl(u_int mask) 68c83b1328SBruce Evans { 69c83b1328SBruce Evans u_int result; 70c83b1328SBruce Evans 713f9a462fSJohn Baldwin __asm __volatile("bsfl %1,%0" : "=r" (result) : "rm" (mask)); 72c83b1328SBruce Evans return (result); 73c83b1328SBruce Evans } 74c83b1328SBruce Evans 756f240e18SConrad Meyer static __inline __pure2 u_long 76176ce2b1SPeter Wemm bsfq(u_long mask) 77176ce2b1SPeter Wemm { 78176ce2b1SPeter Wemm u_long result; 79176ce2b1SPeter Wemm 80176ce2b1SPeter Wemm __asm __volatile("bsfq %1,%0" : "=r" (result) : "rm" (mask)); 81176ce2b1SPeter Wemm return (result); 82176ce2b1SPeter Wemm } 83176ce2b1SPeter Wemm 846f240e18SConrad Meyer static __inline __pure2 u_int 85c83b1328SBruce Evans bsrl(u_int mask) 86c83b1328SBruce Evans { 87c83b1328SBruce Evans u_int result; 88c83b1328SBruce Evans 893f9a462fSJohn Baldwin __asm __volatile("bsrl %1,%0" : "=r" (result) : "rm" (mask)); 90c83b1328SBruce Evans return (result); 91c83b1328SBruce Evans } 92c83b1328SBruce Evans 936f240e18SConrad Meyer static __inline __pure2 u_long 94176ce2b1SPeter Wemm bsrq(u_long mask) 95176ce2b1SPeter Wemm { 96176ce2b1SPeter Wemm u_long result; 97176ce2b1SPeter Wemm 98176ce2b1SPeter Wemm __asm __volatile("bsrq %1,%0" : "=r" (result) : "rm" (mask)); 99176ce2b1SPeter Wemm return (result); 100176ce2b1SPeter Wemm } 101176ce2b1SPeter Wemm 102004bedebSBruce Evans static __inline void 103206a3368SKonstantin Belousov clflush(u_long addr) 104206a3368SKonstantin Belousov { 105206a3368SKonstantin Belousov 106206a3368SKonstantin Belousov __asm __volatile("clflush %0" : : "m" (*(char *)addr)); 107206a3368SKonstantin Belousov } 108206a3368SKonstantin Belousov 109206a3368SKonstantin Belousov static __inline void 1103f8e0710SKonstantin Belousov clflushopt(u_long addr) 1113f8e0710SKonstantin Belousov { 1123f8e0710SKonstantin Belousov 1133f8e0710SKonstantin Belousov __asm __volatile(".byte 0x66;clflush %0" : : "m" (*(char *)addr)); 1143f8e0710SKonstantin Belousov } 1153f8e0710SKonstantin Belousov 1163f8e0710SKonstantin Belousov static __inline void 117d706ec29SJohn Baldwin clts(void) 118d706ec29SJohn Baldwin { 119d706ec29SJohn Baldwin 120d706ec29SJohn Baldwin __asm __volatile("clts"); 121d706ec29SJohn Baldwin } 122d706ec29SJohn Baldwin 123d706ec29SJohn Baldwin static __inline void 1245b81b6b3SRodney W. Grimes disable_intr(void) 1255b81b6b3SRodney W. Grimes { 1268966b85cSJohn Dyson __asm __volatile("cli" : : : "memory"); 1275b81b6b3SRodney W. Grimes } 1285b81b6b3SRodney W. Grimes 129004bedebSBruce Evans static __inline void 130a983fdfeSDavid Malone do_cpuid(u_int ax, u_int *p) 131a983fdfeSDavid Malone { 132a983fdfeSDavid Malone __asm __volatile("cpuid" 133a983fdfeSDavid Malone : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) 134a983fdfeSDavid Malone : "0" (ax)); 135a983fdfeSDavid Malone } 136a983fdfeSDavid Malone 137a983fdfeSDavid Malone static __inline void 138f6108b61SJacques Vidrine cpuid_count(u_int ax, u_int cx, u_int *p) 139f6108b61SJacques Vidrine { 140f6108b61SJacques Vidrine __asm __volatile("cpuid" 141f6108b61SJacques Vidrine : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) 142f6108b61SJacques Vidrine : "0" (ax), "c" (cx)); 143f6108b61SJacques Vidrine } 144f6108b61SJacques Vidrine 145f6108b61SJacques Vidrine static __inline void 1465b81b6b3SRodney W. Grimes enable_intr(void) 1475b81b6b3SRodney W. Grimes { 148fadc51bdSBruce Evans __asm __volatile("sti"); 1495b81b6b3SRodney W. Grimes } 1505b81b6b3SRodney W. Grimes 151a67ef0a7SBruce Evans #ifdef _KERNEL 152a67ef0a7SBruce Evans 153264c3d87SPeter Wemm #define HAVE_INLINE_FFS 154bc35f5dcSPaul Saab #define ffs(x) __builtin_ffs(x) 155176ce2b1SPeter Wemm 156176ce2b1SPeter Wemm #define HAVE_INLINE_FFSL 157176ce2b1SPeter Wemm 1586f240e18SConrad Meyer static __inline __pure2 int 159176ce2b1SPeter Wemm ffsl(long mask) 160176ce2b1SPeter Wemm { 161176ce2b1SPeter Wemm return (mask == 0 ? mask : (int)bsfq((u_long)mask) + 1); 162004bedebSBruce Evans } 163004bedebSBruce Evans 164f25e50cfSAndriy Gapon #define HAVE_INLINE_FFSLL 165f25e50cfSAndriy Gapon 1666f240e18SConrad Meyer static __inline __pure2 int 167f25e50cfSAndriy Gapon ffsll(long long mask) 168f25e50cfSAndriy Gapon { 169f25e50cfSAndriy Gapon return (ffsl((long)mask)); 170f25e50cfSAndriy Gapon } 171f25e50cfSAndriy Gapon 17213f588f8SGarrett Wollman #define HAVE_INLINE_FLS 17313f588f8SGarrett Wollman 1746f240e18SConrad Meyer static __inline __pure2 int 17513f588f8SGarrett Wollman fls(int mask) 17613f588f8SGarrett Wollman { 1777e622d3cSMark Murray return (mask == 0 ? mask : (int)bsrl((u_int)mask) + 1); 17813f588f8SGarrett Wollman } 17913f588f8SGarrett Wollman 180176ce2b1SPeter Wemm #define HAVE_INLINE_FLSL 181176ce2b1SPeter Wemm 1826f240e18SConrad Meyer static __inline __pure2 int 183176ce2b1SPeter Wemm flsl(long mask) 184176ce2b1SPeter Wemm { 185176ce2b1SPeter Wemm return (mask == 0 ? mask : (int)bsrq((u_long)mask) + 1); 186176ce2b1SPeter Wemm } 187176ce2b1SPeter Wemm 188f25e50cfSAndriy Gapon #define HAVE_INLINE_FLSLL 189f25e50cfSAndriy Gapon 1906f240e18SConrad Meyer static __inline __pure2 int 191f25e50cfSAndriy Gapon flsll(long long mask) 192f25e50cfSAndriy Gapon { 193f25e50cfSAndriy Gapon return (flsl((long)mask)); 194f25e50cfSAndriy Gapon } 195f25e50cfSAndriy Gapon 196a67ef0a7SBruce Evans #endif /* _KERNEL */ 197a67ef0a7SBruce Evans 198d7ee4425SMark Murray static __inline void 199d7ee4425SMark Murray halt(void) 200d7ee4425SMark Murray { 201d7ee4425SMark Murray __asm __volatile("hlt"); 202d7ee4425SMark Murray } 203d7ee4425SMark Murray 204004bedebSBruce Evans static __inline u_char 205e1048f76SEd Schouten inb(u_int port) 206004bedebSBruce Evans { 207004bedebSBruce Evans u_char data; 208004bedebSBruce Evans 2094854ae24SJung-uk Kim __asm __volatile("inb %w1, %0" : "=a" (data) : "Nd" (port)); 210004bedebSBruce Evans return (data); 211004bedebSBruce Evans } 212004bedebSBruce Evans 21300be8601SBruce Evans static __inline u_int 214004bedebSBruce Evans inl(u_int port) 215004bedebSBruce Evans { 21600be8601SBruce Evans u_int data; 217004bedebSBruce Evans 2184854ae24SJung-uk Kim __asm __volatile("inl %w1, %0" : "=a" (data) : "Nd" (port)); 219004bedebSBruce Evans return (data); 220004bedebSBruce Evans } 221004bedebSBruce Evans 222004bedebSBruce Evans static __inline void 22393d8be03SDavid E. O'Brien insb(u_int port, void *addr, size_t count) 224004bedebSBruce Evans { 225004bedebSBruce Evans __asm __volatile("cld; rep; insb" 22693d8be03SDavid E. O'Brien : "+D" (addr), "+c" (count) 2273f9a462fSJohn Baldwin : "d" (port) 228896763faSBruce Evans : "memory"); 229004bedebSBruce Evans } 230004bedebSBruce Evans 231004bedebSBruce Evans static __inline void 23293d8be03SDavid E. O'Brien insw(u_int port, void *addr, size_t count) 233004bedebSBruce Evans { 234004bedebSBruce Evans __asm __volatile("cld; rep; insw" 23593d8be03SDavid E. O'Brien : "+D" (addr), "+c" (count) 2363f9a462fSJohn Baldwin : "d" (port) 237896763faSBruce Evans : "memory"); 238004bedebSBruce Evans } 239004bedebSBruce Evans 240004bedebSBruce Evans static __inline void 24193d8be03SDavid E. O'Brien insl(u_int port, void *addr, size_t count) 242004bedebSBruce Evans { 243004bedebSBruce Evans __asm __volatile("cld; rep; insl" 24493d8be03SDavid E. O'Brien : "+D" (addr), "+c" (count) 2453f9a462fSJohn Baldwin : "d" (port) 246896763faSBruce Evans : "memory"); 247004bedebSBruce Evans } 248004bedebSBruce Evans 249ece15d78SBruce Evans static __inline void 2504c024bbdSKATO Takenori invd(void) 2514c024bbdSKATO Takenori { 2524c024bbdSKATO Takenori __asm __volatile("invd"); 2534c024bbdSKATO Takenori } 2544c024bbdSKATO Takenori 255004bedebSBruce Evans static __inline u_short 256004bedebSBruce Evans inw(u_int port) 257004bedebSBruce Evans { 258004bedebSBruce Evans u_short data; 259004bedebSBruce Evans 2604854ae24SJung-uk Kim __asm __volatile("inw %w1, %0" : "=a" (data) : "Nd" (port)); 261004bedebSBruce Evans return (data); 262004bedebSBruce Evans } 263004bedebSBruce Evans 264004bedebSBruce Evans static __inline void 265e1048f76SEd Schouten outb(u_int port, u_char data) 266004bedebSBruce Evans { 2674854ae24SJung-uk Kim __asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port)); 268004bedebSBruce Evans } 269004bedebSBruce Evans 270004bedebSBruce Evans static __inline void 27100be8601SBruce Evans outl(u_int port, u_int data) 272004bedebSBruce Evans { 2734854ae24SJung-uk Kim __asm __volatile("outl %0, %w1" : : "a" (data), "Nd" (port)); 274004bedebSBruce Evans } 275004bedebSBruce Evans 276004bedebSBruce Evans static __inline void 27793d8be03SDavid E. O'Brien outsb(u_int port, const void *addr, size_t count) 278004bedebSBruce Evans { 279004bedebSBruce Evans __asm __volatile("cld; rep; outsb" 28093d8be03SDavid E. O'Brien : "+S" (addr), "+c" (count) 2813f9a462fSJohn Baldwin : "d" (port)); 282004bedebSBruce Evans } 283004bedebSBruce Evans 284004bedebSBruce Evans static __inline void 28593d8be03SDavid E. O'Brien outsw(u_int port, const void *addr, size_t count) 286004bedebSBruce Evans { 287004bedebSBruce Evans __asm __volatile("cld; rep; outsw" 28893d8be03SDavid E. O'Brien : "+S" (addr), "+c" (count) 2893f9a462fSJohn Baldwin : "d" (port)); 290004bedebSBruce Evans } 291004bedebSBruce Evans 292004bedebSBruce Evans static __inline void 29393d8be03SDavid E. O'Brien outsl(u_int port, const void *addr, size_t count) 294004bedebSBruce Evans { 295004bedebSBruce Evans __asm __volatile("cld; rep; outsl" 29693d8be03SDavid E. O'Brien : "+S" (addr), "+c" (count) 2973f9a462fSJohn Baldwin : "d" (port)); 298004bedebSBruce Evans } 299004bedebSBruce Evans 300004bedebSBruce Evans static __inline void 301004bedebSBruce Evans outw(u_int port, u_short data) 302004bedebSBruce Evans { 3034854ae24SJung-uk Kim __asm __volatile("outw %0, %w1" : : "a" (data), "Nd" (port)); 304004bedebSBruce Evans } 305004bedebSBruce Evans 3062bde6e35SAlan Cox static __inline u_long 3072bde6e35SAlan Cox popcntq(u_long mask) 3082bde6e35SAlan Cox { 3092bde6e35SAlan Cox u_long result; 3102bde6e35SAlan Cox 3112bde6e35SAlan Cox __asm __volatile("popcntq %1,%0" : "=r" (result) : "rm" (mask)); 3122bde6e35SAlan Cox return (result); 3132bde6e35SAlan Cox } 3142bde6e35SAlan Cox 3152be69f32SJohn Baldwin static __inline void 3160220d04fSKonstantin Belousov lfence(void) 3170220d04fSKonstantin Belousov { 3180220d04fSKonstantin Belousov 3190220d04fSKonstantin Belousov __asm __volatile("lfence" : : : "memory"); 3200220d04fSKonstantin Belousov } 3210220d04fSKonstantin Belousov 3220220d04fSKonstantin Belousov static __inline void 323206a3368SKonstantin Belousov mfence(void) 324206a3368SKonstantin Belousov { 325206a3368SKonstantin Belousov 326beb2c1f3SAndriy Gapon __asm __volatile("mfence" : : : "memory"); 327206a3368SKonstantin Belousov } 328206a3368SKonstantin Belousov 329206a3368SKonstantin Belousov static __inline void 3305611aaa1SKonstantin Belousov sfence(void) 3315611aaa1SKonstantin Belousov { 3325611aaa1SKonstantin Belousov 3335611aaa1SKonstantin Belousov __asm __volatile("sfence" : : : "memory"); 3345611aaa1SKonstantin Belousov } 3355611aaa1SKonstantin Belousov 3365611aaa1SKonstantin Belousov static __inline void 3376b8c6989SJohn Baldwin ia32_pause(void) 3382be69f32SJohn Baldwin { 3392be69f32SJohn Baldwin __asm __volatile("pause"); 3402be69f32SJohn Baldwin } 3412be69f32SJohn Baldwin 342afa88623SPeter Wemm static __inline u_long 343afa88623SPeter Wemm read_rflags(void) 3445b81b6b3SRodney W. Grimes { 345afa88623SPeter Wemm u_long rf; 346004bedebSBruce Evans 347afa88623SPeter Wemm __asm __volatile("pushfq; popq %0" : "=r" (rf)); 348afa88623SPeter Wemm return (rf); 3495b81b6b3SRodney W. Grimes } 3505b81b6b3SRodney W. Grimes 351f5ac47f4SJung-uk Kim static __inline uint64_t 3525dbd168eSBruce Evans rdmsr(u_int msr) 3535dbd168eSBruce Evans { 354f5ac47f4SJung-uk Kim uint32_t low, high; 3555dbd168eSBruce Evans 356afa88623SPeter Wemm __asm __volatile("rdmsr" : "=a" (low), "=d" (high) : "c" (msr)); 357f5ac47f4SJung-uk Kim return (low | ((uint64_t)high << 32)); 3585dbd168eSBruce Evans } 3595dbd168eSBruce Evans 3604c918926SKonstantin Belousov static __inline uint32_t 3614c918926SKonstantin Belousov rdmsr32(u_int msr) 3624c918926SKonstantin Belousov { 3634c918926SKonstantin Belousov uint32_t low; 3644c918926SKonstantin Belousov 3654c918926SKonstantin Belousov __asm __volatile("rdmsr" : "=a" (low) : "c" (msr) : "rdx"); 3664c918926SKonstantin Belousov return (low); 3674c918926SKonstantin Belousov } 3684c918926SKonstantin Belousov 369f5ac47f4SJung-uk Kim static __inline uint64_t 3705dbd168eSBruce Evans rdpmc(u_int pmc) 3715dbd168eSBruce Evans { 372f5ac47f4SJung-uk Kim uint32_t low, high; 3735dbd168eSBruce Evans 374afa88623SPeter Wemm __asm __volatile("rdpmc" : "=a" (low), "=d" (high) : "c" (pmc)); 375f5ac47f4SJung-uk Kim return (low | ((uint64_t)high << 32)); 3765dbd168eSBruce Evans } 3775dbd168eSBruce Evans 378f5ac47f4SJung-uk Kim static __inline uint64_t 3795dbd168eSBruce Evans rdtsc(void) 3805dbd168eSBruce Evans { 381f5ac47f4SJung-uk Kim uint32_t low, high; 3825dbd168eSBruce Evans 383afa88623SPeter Wemm __asm __volatile("rdtsc" : "=a" (low), "=d" (high)); 384f5ac47f4SJung-uk Kim return (low | ((uint64_t)high << 32)); 3855dbd168eSBruce Evans } 3865dbd168eSBruce Evans 3870e727642SJung-uk Kim static __inline uint32_t 3880e727642SJung-uk Kim rdtsc32(void) 3890e727642SJung-uk Kim { 3900e727642SJung-uk Kim uint32_t rv; 3910e727642SJung-uk Kim 3920e727642SJung-uk Kim __asm __volatile("rdtsc" : "=a" (rv) : : "edx"); 3930e727642SJung-uk Kim return (rv); 3940e727642SJung-uk Kim } 3950e727642SJung-uk Kim 396004bedebSBruce Evans static __inline void 3974c024bbdSKATO Takenori wbinvd(void) 3984c024bbdSKATO Takenori { 3994c024bbdSKATO Takenori __asm __volatile("wbinvd"); 4004c024bbdSKATO Takenori } 4014c024bbdSKATO Takenori 4024c024bbdSKATO Takenori static __inline void 403afa88623SPeter Wemm write_rflags(u_long rf) 4045b81b6b3SRodney W. Grimes { 405afa88623SPeter Wemm __asm __volatile("pushq %0; popfq" : : "r" (rf)); 4065b81b6b3SRodney W. Grimes } 4075b81b6b3SRodney W. Grimes 408d69e8502SGarrett Wollman static __inline void 409f5ac47f4SJung-uk Kim wrmsr(u_int msr, uint64_t newval) 410d69e8502SGarrett Wollman { 411f5ac47f4SJung-uk Kim uint32_t low, high; 412afa88623SPeter Wemm 413afa88623SPeter Wemm low = newval; 414afa88623SPeter Wemm high = newval >> 32; 415afa88623SPeter Wemm __asm __volatile("wrmsr" : : "a" (low), "d" (high), "c" (msr)); 416d69e8502SGarrett Wollman } 417d69e8502SGarrett Wollman 418f1b665c8SPeter Wemm static __inline void 419afa88623SPeter Wemm load_cr0(u_long data) 420f1b665c8SPeter Wemm { 421f1b665c8SPeter Wemm 422afa88623SPeter Wemm __asm __volatile("movq %0,%%cr0" : : "r" (data)); 423f1b665c8SPeter Wemm } 424f1b665c8SPeter Wemm 425afa88623SPeter Wemm static __inline u_long 426f1b665c8SPeter Wemm rcr0(void) 427f1b665c8SPeter Wemm { 428afa88623SPeter Wemm u_long data; 429f1b665c8SPeter Wemm 430afa88623SPeter Wemm __asm __volatile("movq %%cr0,%0" : "=r" (data)); 431f1b665c8SPeter Wemm return (data); 432f1b665c8SPeter Wemm } 433f1b665c8SPeter Wemm 434afa88623SPeter Wemm static __inline u_long 435f1b665c8SPeter Wemm rcr2(void) 436f1b665c8SPeter Wemm { 437afa88623SPeter Wemm u_long data; 438f1b665c8SPeter Wemm 439afa88623SPeter Wemm __asm __volatile("movq %%cr2,%0" : "=r" (data)); 440f1b665c8SPeter Wemm return (data); 441f1b665c8SPeter Wemm } 442f1b665c8SPeter Wemm 443f1b665c8SPeter Wemm static __inline void 444afa88623SPeter Wemm load_cr3(u_long data) 445f1b665c8SPeter Wemm { 446f1b665c8SPeter Wemm 447afa88623SPeter Wemm __asm __volatile("movq %0,%%cr3" : : "r" (data) : "memory"); 448f1b665c8SPeter Wemm } 449f1b665c8SPeter Wemm 450afa88623SPeter Wemm static __inline u_long 451f1b665c8SPeter Wemm rcr3(void) 452f1b665c8SPeter Wemm { 453afa88623SPeter Wemm u_long data; 454f1b665c8SPeter Wemm 455afa88623SPeter Wemm __asm __volatile("movq %%cr3,%0" : "=r" (data)); 456f1b665c8SPeter Wemm return (data); 457f1b665c8SPeter Wemm } 458f1b665c8SPeter Wemm 459f1b665c8SPeter Wemm static __inline void 460afa88623SPeter Wemm load_cr4(u_long data) 461f1b665c8SPeter Wemm { 462afa88623SPeter Wemm __asm __volatile("movq %0,%%cr4" : : "r" (data)); 463f1b665c8SPeter Wemm } 464f1b665c8SPeter Wemm 465afa88623SPeter Wemm static __inline u_long 466f1b665c8SPeter Wemm rcr4(void) 467f1b665c8SPeter Wemm { 468afa88623SPeter Wemm u_long data; 469f1b665c8SPeter Wemm 470afa88623SPeter Wemm __asm __volatile("movq %%cr4,%0" : "=r" (data)); 471f1b665c8SPeter Wemm return (data); 472f1b665c8SPeter Wemm } 473f1b665c8SPeter Wemm 4747574a595SJohn Baldwin static __inline u_long 4757574a595SJohn Baldwin rxcr(u_int reg) 4767574a595SJohn Baldwin { 4777574a595SJohn Baldwin u_int low, high; 4787574a595SJohn Baldwin 4797574a595SJohn Baldwin __asm __volatile("xgetbv" : "=a" (low), "=d" (high) : "c" (reg)); 4807574a595SJohn Baldwin return (low | ((uint64_t)high << 32)); 4817574a595SJohn Baldwin } 4827574a595SJohn Baldwin 4837574a595SJohn Baldwin static __inline void 4847574a595SJohn Baldwin load_xcr(u_int reg, u_long val) 4857574a595SJohn Baldwin { 4867574a595SJohn Baldwin u_int low, high; 4877574a595SJohn Baldwin 4887574a595SJohn Baldwin low = val; 4897574a595SJohn Baldwin high = val >> 32; 4907574a595SJohn Baldwin __asm __volatile("xsetbv" : : "c" (reg), "a" (low), "d" (high)); 4917574a595SJohn Baldwin } 4927574a595SJohn Baldwin 493f1b665c8SPeter Wemm /* 494f1b665c8SPeter Wemm * Global TLB flush (except for thise for pages marked PG_G) 495f1b665c8SPeter Wemm */ 496f1b665c8SPeter Wemm static __inline void 497f1b665c8SPeter Wemm invltlb(void) 498f1b665c8SPeter Wemm { 499f1b665c8SPeter Wemm 500f1b665c8SPeter Wemm load_cr3(rcr3()); 501f1b665c8SPeter Wemm } 502f1b665c8SPeter Wemm 503e44af46eSJustin T. Gibbs #ifndef CR4_PGE 504e44af46eSJustin T. Gibbs #define CR4_PGE 0x00000080 /* Page global enable */ 505e44af46eSJustin T. Gibbs #endif 506e44af46eSJustin T. Gibbs 507e44af46eSJustin T. Gibbs /* 508e44af46eSJustin T. Gibbs * Perform the guaranteed invalidation of all TLB entries. This 509e44af46eSJustin T. Gibbs * includes the global entries, and entries in all PCIDs, not only the 510e44af46eSJustin T. Gibbs * current context. The function works both on non-PCID CPUs and CPUs 511e44af46eSJustin T. Gibbs * with the PCID turned off or on. See IA-32 SDM Vol. 3a 4.10.4.1 512e44af46eSJustin T. Gibbs * Operations that Invalidate TLBs and Paging-Structure Caches. 513e44af46eSJustin T. Gibbs */ 514e44af46eSJustin T. Gibbs static __inline void 51527691a24SKonstantin Belousov invltlb_glob(void) 516e44af46eSJustin T. Gibbs { 517e44af46eSJustin T. Gibbs uint64_t cr4; 518e44af46eSJustin T. Gibbs 519e44af46eSJustin T. Gibbs cr4 = rcr4(); 520e44af46eSJustin T. Gibbs load_cr4(cr4 & ~CR4_PGE); 521e44af46eSJustin T. Gibbs /* 522e44af46eSJustin T. Gibbs * Although preemption at this point could be detrimental to 523e44af46eSJustin T. Gibbs * performance, it would not lead to an error. PG_G is simply 524e44af46eSJustin T. Gibbs * ignored if CR4.PGE is clear. Moreover, in case this block 525e44af46eSJustin T. Gibbs * is re-entered, the load_cr4() either above or below will 526e44af46eSJustin T. Gibbs * modify CR4.PGE flushing the TLB. 527e44af46eSJustin T. Gibbs */ 528e44af46eSJustin T. Gibbs load_cr4(cr4 | CR4_PGE); 529e44af46eSJustin T. Gibbs } 530e44af46eSJustin T. Gibbs 531f1b665c8SPeter Wemm /* 532f1b665c8SPeter Wemm * TLB flush for an individual page (even if it has PG_G). 533f1b665c8SPeter Wemm * Only works on 486+ CPUs (i386 does not have PG_G). 534f1b665c8SPeter Wemm */ 535f1b665c8SPeter Wemm static __inline void 536afa88623SPeter Wemm invlpg(u_long addr) 537f1b665c8SPeter Wemm { 538f1b665c8SPeter Wemm 539f1b665c8SPeter Wemm __asm __volatile("invlpg %0" : : "m" (*(char *)addr) : "memory"); 540f1b665c8SPeter Wemm } 541f1b665c8SPeter Wemm 5425f5703efSKonstantin Belousov #define INVPCID_ADDR 0 5435f5703efSKonstantin Belousov #define INVPCID_CTX 1 5445f5703efSKonstantin Belousov #define INVPCID_CTXGLOB 2 5455f5703efSKonstantin Belousov #define INVPCID_ALLCTX 3 5465f5703efSKonstantin Belousov 5475f5703efSKonstantin Belousov struct invpcid_descr { 5485f5703efSKonstantin Belousov uint64_t pcid:12 __packed; 5495f5703efSKonstantin Belousov uint64_t pad:52 __packed; 5505f5703efSKonstantin Belousov uint64_t addr; 5515f5703efSKonstantin Belousov } __packed; 5525f5703efSKonstantin Belousov 5535f5703efSKonstantin Belousov static __inline void 5545f5703efSKonstantin Belousov invpcid(struct invpcid_descr *d, int type) 5555f5703efSKonstantin Belousov { 5565f5703efSKonstantin Belousov 557a546448bSKonstantin Belousov __asm __volatile("invpcid (%0),%1" 558a546448bSKonstantin Belousov : : "r" (d), "r" ((u_long)type) : "memory"); 5595f5703efSKonstantin Belousov } 5605f5703efSKonstantin Belousov 56127d4fea6SRoman Divacky static __inline u_short 5625206bca1SLuoqi Chen rfs(void) 5635206bca1SLuoqi Chen { 56427d4fea6SRoman Divacky u_short sel; 56527d4fea6SRoman Divacky __asm __volatile("movw %%fs,%0" : "=rm" (sel)); 5665206bca1SLuoqi Chen return (sel); 5675206bca1SLuoqi Chen } 5685206bca1SLuoqi Chen 56927d4fea6SRoman Divacky static __inline u_short 5705206bca1SLuoqi Chen rgs(void) 5715206bca1SLuoqi Chen { 57227d4fea6SRoman Divacky u_short sel; 57327d4fea6SRoman Divacky __asm __volatile("movw %%gs,%0" : "=rm" (sel)); 5745206bca1SLuoqi Chen return (sel); 5755206bca1SLuoqi Chen } 5765206bca1SLuoqi Chen 57727d4fea6SRoman Divacky static __inline u_short 578cd0149e3SPeter Wemm rss(void) 579cd0149e3SPeter Wemm { 58027d4fea6SRoman Divacky u_short sel; 58127d4fea6SRoman Divacky __asm __volatile("movw %%ss,%0" : "=rm" (sel)); 582cd0149e3SPeter Wemm return (sel); 583cd0149e3SPeter Wemm } 584cd0149e3SPeter Wemm 5855206bca1SLuoqi Chen static __inline void 58627d4fea6SRoman Divacky load_ds(u_short sel) 587d85631c4SPeter Wemm { 58827d4fea6SRoman Divacky __asm __volatile("movw %0,%%ds" : : "rm" (sel)); 589d85631c4SPeter Wemm } 590d85631c4SPeter Wemm 591d85631c4SPeter Wemm static __inline void 59227d4fea6SRoman Divacky load_es(u_short sel) 593d85631c4SPeter Wemm { 59427d4fea6SRoman Divacky __asm __volatile("movw %0,%%es" : : "rm" (sel)); 595d85631c4SPeter Wemm } 596d85631c4SPeter Wemm 597beb2c1f3SAndriy Gapon static __inline void 598f0b28f00SJung-uk Kim cpu_monitor(const void *addr, u_long extensions, u_int hints) 59966247efaSJeff Roberson { 600f0b28f00SJung-uk Kim 601f0b28f00SJung-uk Kim __asm __volatile("monitor" 60266247efaSJeff Roberson : : "a" (addr), "c" (extensions), "d" (hints)); 60366247efaSJeff Roberson } 60466247efaSJeff Roberson 605beb2c1f3SAndriy Gapon static __inline void 606f0b28f00SJung-uk Kim cpu_mwait(u_long extensions, u_int hints) 60766247efaSJeff Roberson { 608f0b28f00SJung-uk Kim 609f0b28f00SJung-uk Kim __asm __volatile("mwait" : : "a" (hints), "c" (extensions)); 61066247efaSJeff Roberson } 61166247efaSJeff Roberson 612c0a54ff6SPeter Wemm #ifdef _KERNEL 613c0a54ff6SPeter Wemm /* This is defined in <machine/specialreg.h> but is too painful to get to */ 614c0a54ff6SPeter Wemm #ifndef MSR_FSBASE 615c0a54ff6SPeter Wemm #define MSR_FSBASE 0xc0000100 616c0a54ff6SPeter Wemm #endif 617c0a54ff6SPeter Wemm static __inline void 61827d4fea6SRoman Divacky load_fs(u_short sel) 619c0a54ff6SPeter Wemm { 620c0a54ff6SPeter Wemm /* Preserve the fsbase value across the selector load */ 62127d4fea6SRoman Divacky __asm __volatile("rdmsr; movw %0,%%fs; wrmsr" 622db26a671SEd Schouten : : "rm" (sel), "c" (MSR_FSBASE) : "eax", "edx"); 623c0a54ff6SPeter Wemm } 624c0a54ff6SPeter Wemm 625c0a54ff6SPeter Wemm #ifndef MSR_GSBASE 626c0a54ff6SPeter Wemm #define MSR_GSBASE 0xc0000101 627c0a54ff6SPeter Wemm #endif 628c0a54ff6SPeter Wemm static __inline void 62927d4fea6SRoman Divacky load_gs(u_short sel) 630c0a54ff6SPeter Wemm { 631c0a54ff6SPeter Wemm /* 632c0a54ff6SPeter Wemm * Preserve the gsbase value across the selector load. 633c0a54ff6SPeter Wemm * Note that we have to disable interrupts because the gsbase 634c0a54ff6SPeter Wemm * being trashed happens to be the kernel gsbase at the time. 635c0a54ff6SPeter Wemm */ 63627d4fea6SRoman Divacky __asm __volatile("pushfq; cli; rdmsr; movw %0,%%gs; wrmsr; popfq" 637db26a671SEd Schouten : : "rm" (sel), "c" (MSR_GSBASE) : "eax", "edx"); 638c0a54ff6SPeter Wemm } 639c0a54ff6SPeter Wemm #else 640c0a54ff6SPeter Wemm /* Usable by userland */ 641d85631c4SPeter Wemm static __inline void 64227d4fea6SRoman Divacky load_fs(u_short sel) 6435206bca1SLuoqi Chen { 64427d4fea6SRoman Divacky __asm __volatile("movw %0,%%fs" : : "rm" (sel)); 6455206bca1SLuoqi Chen } 6465206bca1SLuoqi Chen 6475206bca1SLuoqi Chen static __inline void 64827d4fea6SRoman Divacky load_gs(u_short sel) 6495206bca1SLuoqi Chen { 65027d4fea6SRoman Divacky __asm __volatile("movw %0,%%gs" : : "rm" (sel)); 6515206bca1SLuoqi Chen } 652c0a54ff6SPeter Wemm #endif 6535206bca1SLuoqi Chen 654*0fd7ea1fSKonstantin Belousov static __inline uint64_t 655*0fd7ea1fSKonstantin Belousov rdfsbase(void) 656*0fd7ea1fSKonstantin Belousov { 657*0fd7ea1fSKonstantin Belousov uint64_t x; 658*0fd7ea1fSKonstantin Belousov 659*0fd7ea1fSKonstantin Belousov __asm __volatile("rdfsbase %0" : "=r" (x)); 660*0fd7ea1fSKonstantin Belousov return (x); 661*0fd7ea1fSKonstantin Belousov } 662*0fd7ea1fSKonstantin Belousov 663*0fd7ea1fSKonstantin Belousov static __inline void 664*0fd7ea1fSKonstantin Belousov wrfsbase(uint64_t x) 665*0fd7ea1fSKonstantin Belousov { 666*0fd7ea1fSKonstantin Belousov 667*0fd7ea1fSKonstantin Belousov __asm __volatile("wrfsbase %0" : : "r" (x)); 668*0fd7ea1fSKonstantin Belousov } 669*0fd7ea1fSKonstantin Belousov 670*0fd7ea1fSKonstantin Belousov static __inline uint64_t 671*0fd7ea1fSKonstantin Belousov rdgsbase(void) 672*0fd7ea1fSKonstantin Belousov { 673*0fd7ea1fSKonstantin Belousov uint64_t x; 674*0fd7ea1fSKonstantin Belousov 675*0fd7ea1fSKonstantin Belousov __asm __volatile("rdgsbase %0" : "=r" (x)); 676*0fd7ea1fSKonstantin Belousov return (x); 677*0fd7ea1fSKonstantin Belousov } 678*0fd7ea1fSKonstantin Belousov 679*0fd7ea1fSKonstantin Belousov static __inline void 680*0fd7ea1fSKonstantin Belousov wrgsbase(uint64_t x) 681*0fd7ea1fSKonstantin Belousov { 682*0fd7ea1fSKonstantin Belousov 683*0fd7ea1fSKonstantin Belousov __asm __volatile("wrgsbase %0" : : "r" (x)); 684*0fd7ea1fSKonstantin Belousov } 685*0fd7ea1fSKonstantin Belousov 686eb1443c8SPeter Wemm static __inline void 687c1538a13SKonstantin Belousov bare_lgdt(struct region_descriptor *addr) 688c1538a13SKonstantin Belousov { 689c1538a13SKonstantin Belousov __asm __volatile("lgdt (%0)" : : "r" (addr)); 690c1538a13SKonstantin Belousov } 691c1538a13SKonstantin Belousov 692c1538a13SKonstantin Belousov static __inline void 693c1538a13SKonstantin Belousov sgdt(struct region_descriptor *addr) 694c1538a13SKonstantin Belousov { 695c1538a13SKonstantin Belousov char *loc; 696c1538a13SKonstantin Belousov 697c1538a13SKonstantin Belousov loc = (char *)addr; 698c1538a13SKonstantin Belousov __asm __volatile("sgdt %0" : "=m" (*loc) : : "memory"); 699c1538a13SKonstantin Belousov } 700c1538a13SKonstantin Belousov 701c1538a13SKonstantin Belousov static __inline void 702eb1443c8SPeter Wemm lidt(struct region_descriptor *addr) 703eb1443c8SPeter Wemm { 704eb1443c8SPeter Wemm __asm __volatile("lidt (%0)" : : "r" (addr)); 705eb1443c8SPeter Wemm } 706eb1443c8SPeter Wemm 707eb1443c8SPeter Wemm static __inline void 708c1538a13SKonstantin Belousov sidt(struct region_descriptor *addr) 709c1538a13SKonstantin Belousov { 710c1538a13SKonstantin Belousov char *loc; 711c1538a13SKonstantin Belousov 712c1538a13SKonstantin Belousov loc = (char *)addr; 713c1538a13SKonstantin Belousov __asm __volatile("sidt %0" : "=m" (*loc) : : "memory"); 714c1538a13SKonstantin Belousov } 715c1538a13SKonstantin Belousov 716c1538a13SKonstantin Belousov static __inline void 717eb1443c8SPeter Wemm lldt(u_short sel) 718eb1443c8SPeter Wemm { 719eb1443c8SPeter Wemm __asm __volatile("lldt %0" : : "r" (sel)); 720eb1443c8SPeter Wemm } 721eb1443c8SPeter Wemm 722eb1443c8SPeter Wemm static __inline void 723eb1443c8SPeter Wemm ltr(u_short sel) 724eb1443c8SPeter Wemm { 725eb1443c8SPeter Wemm __asm __volatile("ltr %0" : : "r" (sel)); 726eb1443c8SPeter Wemm } 727eb1443c8SPeter Wemm 728c1538a13SKonstantin Belousov static __inline uint32_t 729c1538a13SKonstantin Belousov read_tr(void) 730c1538a13SKonstantin Belousov { 731c1538a13SKonstantin Belousov u_short sel; 732c1538a13SKonstantin Belousov 733c1538a13SKonstantin Belousov __asm __volatile("str %0" : "=r" (sel)); 734c1538a13SKonstantin Belousov return (sel); 735c1538a13SKonstantin Belousov } 736c1538a13SKonstantin Belousov 737f5ac47f4SJung-uk Kim static __inline uint64_t 7381182b177SPeter Wemm rdr0(void) 7391182b177SPeter Wemm { 740f5ac47f4SJung-uk Kim uint64_t data; 7411182b177SPeter Wemm __asm __volatile("movq %%dr0,%0" : "=r" (data)); 7421182b177SPeter Wemm return (data); 7431182b177SPeter Wemm } 7441182b177SPeter Wemm 7451182b177SPeter Wemm static __inline void 746f5ac47f4SJung-uk Kim load_dr0(uint64_t dr0) 7471182b177SPeter Wemm { 7481182b177SPeter Wemm __asm __volatile("movq %0,%%dr0" : : "r" (dr0)); 7491182b177SPeter Wemm } 7501182b177SPeter Wemm 751f5ac47f4SJung-uk Kim static __inline uint64_t 7521182b177SPeter Wemm rdr1(void) 7531182b177SPeter Wemm { 754f5ac47f4SJung-uk Kim uint64_t data; 7551182b177SPeter Wemm __asm __volatile("movq %%dr1,%0" : "=r" (data)); 7561182b177SPeter Wemm return (data); 7571182b177SPeter Wemm } 7581182b177SPeter Wemm 7591182b177SPeter Wemm static __inline void 760f5ac47f4SJung-uk Kim load_dr1(uint64_t dr1) 7611182b177SPeter Wemm { 7621182b177SPeter Wemm __asm __volatile("movq %0,%%dr1" : : "r" (dr1)); 7631182b177SPeter Wemm } 7641182b177SPeter Wemm 765f5ac47f4SJung-uk Kim static __inline uint64_t 7661182b177SPeter Wemm rdr2(void) 7671182b177SPeter Wemm { 768f5ac47f4SJung-uk Kim uint64_t data; 7691182b177SPeter Wemm __asm __volatile("movq %%dr2,%0" : "=r" (data)); 7701182b177SPeter Wemm return (data); 7711182b177SPeter Wemm } 7721182b177SPeter Wemm 7731182b177SPeter Wemm static __inline void 774f5ac47f4SJung-uk Kim load_dr2(uint64_t dr2) 7751182b177SPeter Wemm { 7761182b177SPeter Wemm __asm __volatile("movq %0,%%dr2" : : "r" (dr2)); 7771182b177SPeter Wemm } 7781182b177SPeter Wemm 779f5ac47f4SJung-uk Kim static __inline uint64_t 7801182b177SPeter Wemm rdr3(void) 7811182b177SPeter Wemm { 782f5ac47f4SJung-uk Kim uint64_t data; 7831182b177SPeter Wemm __asm __volatile("movq %%dr3,%0" : "=r" (data)); 7841182b177SPeter Wemm return (data); 7851182b177SPeter Wemm } 7861182b177SPeter Wemm 7871182b177SPeter Wemm static __inline void 788f5ac47f4SJung-uk Kim load_dr3(uint64_t dr3) 7891182b177SPeter Wemm { 7901182b177SPeter Wemm __asm __volatile("movq %0,%%dr3" : : "r" (dr3)); 7911182b177SPeter Wemm } 7921182b177SPeter Wemm 793f5ac47f4SJung-uk Kim static __inline uint64_t 7941182b177SPeter Wemm rdr6(void) 7951182b177SPeter Wemm { 796f5ac47f4SJung-uk Kim uint64_t data; 7971182b177SPeter Wemm __asm __volatile("movq %%dr6,%0" : "=r" (data)); 7981182b177SPeter Wemm return (data); 7991182b177SPeter Wemm } 8001182b177SPeter Wemm 8011182b177SPeter Wemm static __inline void 802f5ac47f4SJung-uk Kim load_dr6(uint64_t dr6) 8031182b177SPeter Wemm { 8041182b177SPeter Wemm __asm __volatile("movq %0,%%dr6" : : "r" (dr6)); 8051182b177SPeter Wemm } 8061182b177SPeter Wemm 807f5ac47f4SJung-uk Kim static __inline uint64_t 8081182b177SPeter Wemm rdr7(void) 8091182b177SPeter Wemm { 810f5ac47f4SJung-uk Kim uint64_t data; 8111182b177SPeter Wemm __asm __volatile("movq %%dr7,%0" : "=r" (data)); 8121182b177SPeter Wemm return (data); 8131182b177SPeter Wemm } 8141182b177SPeter Wemm 8151182b177SPeter Wemm static __inline void 816f5ac47f4SJung-uk Kim load_dr7(uint64_t dr7) 8171182b177SPeter Wemm { 8181182b177SPeter Wemm __asm __volatile("movq %0,%%dr7" : : "r" (dr7)); 8191182b177SPeter Wemm } 8201182b177SPeter Wemm 821ba74981eSWarner Losh static __inline register_t 822ba74981eSWarner Losh intr_disable(void) 823ba74981eSWarner Losh { 824afa88623SPeter Wemm register_t rflags; 825ba74981eSWarner Losh 826afa88623SPeter Wemm rflags = read_rflags(); 827ba74981eSWarner Losh disable_intr(); 828afa88623SPeter Wemm return (rflags); 829ba74981eSWarner Losh } 830ba74981eSWarner Losh 831ba74981eSWarner Losh static __inline void 832afa88623SPeter Wemm intr_restore(register_t rflags) 833ba74981eSWarner Losh { 834afa88623SPeter Wemm write_rflags(rflags); 835ba74981eSWarner Losh } 836ba74981eSWarner Losh 837a5f50ef9SJoerg Wunsch #else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */ 8385b81b6b3SRodney W. Grimes 839b63dc6adSAlfred Perlstein int breakpoint(void); 840b63dc6adSAlfred Perlstein u_int bsfl(u_int mask); 841b63dc6adSAlfred Perlstein u_int bsrl(u_int mask); 842d706ec29SJohn Baldwin void clflush(u_long addr); 843d706ec29SJohn Baldwin void clts(void); 844d706ec29SJohn Baldwin void cpuid_count(u_int ax, u_int cx, u_int *p); 845b63dc6adSAlfred Perlstein void disable_intr(void); 846b63dc6adSAlfred Perlstein void do_cpuid(u_int ax, u_int *p); 847b63dc6adSAlfred Perlstein void enable_intr(void); 848d7ee4425SMark Murray void halt(void); 8494f6c19e5SPeter Wemm void ia32_pause(void); 850b63dc6adSAlfred Perlstein u_char inb(u_int port); 851b63dc6adSAlfred Perlstein u_int inl(u_int port); 85293d8be03SDavid E. O'Brien void insb(u_int port, void *addr, size_t count); 85393d8be03SDavid E. O'Brien void insl(u_int port, void *addr, size_t count); 85493d8be03SDavid E. O'Brien void insw(u_int port, void *addr, size_t count); 8554f6c19e5SPeter Wemm register_t intr_disable(void); 8564f6c19e5SPeter Wemm void intr_restore(register_t rf); 857b63dc6adSAlfred Perlstein void invd(void); 858b63dc6adSAlfred Perlstein void invlpg(u_int addr); 859b63dc6adSAlfred Perlstein void invltlb(void); 860b63dc6adSAlfred Perlstein u_short inw(u_int port); 861eb1443c8SPeter Wemm void lidt(struct region_descriptor *addr); 862eb1443c8SPeter Wemm void lldt(u_short sel); 8634f6c19e5SPeter Wemm void load_cr0(u_long cr0); 8644f6c19e5SPeter Wemm void load_cr3(u_long cr3); 8654f6c19e5SPeter Wemm void load_cr4(u_long cr4); 866f5ac47f4SJung-uk Kim void load_dr0(uint64_t dr0); 867f5ac47f4SJung-uk Kim void load_dr1(uint64_t dr1); 868f5ac47f4SJung-uk Kim void load_dr2(uint64_t dr2); 869f5ac47f4SJung-uk Kim void load_dr3(uint64_t dr3); 870f5ac47f4SJung-uk Kim void load_dr6(uint64_t dr6); 871f5ac47f4SJung-uk Kim void load_dr7(uint64_t dr7); 87227d4fea6SRoman Divacky void load_fs(u_short sel); 87327d4fea6SRoman Divacky void load_gs(u_short sel); 874eb1443c8SPeter Wemm void ltr(u_short sel); 875b63dc6adSAlfred Perlstein void outb(u_int port, u_char data); 876b63dc6adSAlfred Perlstein void outl(u_int port, u_int data); 87793d8be03SDavid E. O'Brien void outsb(u_int port, const void *addr, size_t count); 87893d8be03SDavid E. O'Brien void outsl(u_int port, const void *addr, size_t count); 87993d8be03SDavid E. O'Brien void outsw(u_int port, const void *addr, size_t count); 880b63dc6adSAlfred Perlstein void outw(u_int port, u_short data); 8814f6c19e5SPeter Wemm u_long rcr0(void); 8824f6c19e5SPeter Wemm u_long rcr2(void); 8834f6c19e5SPeter Wemm u_long rcr3(void); 8844f6c19e5SPeter Wemm u_long rcr4(void); 885f5ac47f4SJung-uk Kim uint64_t rdmsr(u_int msr); 8864c918926SKonstantin Belousov uint32_t rdmsr32(u_int msr); 887f5ac47f4SJung-uk Kim uint64_t rdpmc(u_int pmc); 888f5ac47f4SJung-uk Kim uint64_t rdr0(void); 889f5ac47f4SJung-uk Kim uint64_t rdr1(void); 890f5ac47f4SJung-uk Kim uint64_t rdr2(void); 891f5ac47f4SJung-uk Kim uint64_t rdr3(void); 892f5ac47f4SJung-uk Kim uint64_t rdr6(void); 893f5ac47f4SJung-uk Kim uint64_t rdr7(void); 894f5ac47f4SJung-uk Kim uint64_t rdtsc(void); 895a61dd1bdSJohn Baldwin u_long read_rflags(void); 8964f6c19e5SPeter Wemm u_int rfs(void); 8974f6c19e5SPeter Wemm u_int rgs(void); 898b63dc6adSAlfred Perlstein void wbinvd(void); 899afa88623SPeter Wemm void write_rflags(u_int rf); 900f5ac47f4SJung-uk Kim void wrmsr(u_int msr, uint64_t newval); 901004bedebSBruce Evans 902a5f50ef9SJoerg Wunsch #endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */ 9035b81b6b3SRodney W. Grimes 904b63dc6adSAlfred Perlstein void reset_dbregs(void); 905d74ac681SMatthew Dillon 906e085f869SStanislav Sedov #ifdef _KERNEL 907e085f869SStanislav Sedov int rdmsr_safe(u_int msr, uint64_t *val); 908e085f869SStanislav Sedov int wrmsr_safe(u_int msr, uint64_t newval); 909e085f869SStanislav Sedov #endif 910e085f869SStanislav Sedov 911004bedebSBruce Evans #endif /* !_MACHINE_CPUFUNC_H_ */ 912