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. 143c4dd356SDavid Greenman * 4. 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 66c83b1328SBruce Evans static __inline 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 75176ce2b1SPeter Wemm static __inline 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 84c83b1328SBruce Evans static __inline 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 93176ce2b1SPeter Wemm static __inline 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 110d706ec29SJohn Baldwin clts(void) 111d706ec29SJohn Baldwin { 112d706ec29SJohn Baldwin 113d706ec29SJohn Baldwin __asm __volatile("clts"); 114d706ec29SJohn Baldwin } 115d706ec29SJohn Baldwin 116d706ec29SJohn Baldwin static __inline void 1175b81b6b3SRodney W. Grimes disable_intr(void) 1185b81b6b3SRodney W. Grimes { 1198966b85cSJohn Dyson __asm __volatile("cli" : : : "memory"); 1205b81b6b3SRodney W. Grimes } 1215b81b6b3SRodney W. Grimes 122004bedebSBruce Evans static __inline void 123a983fdfeSDavid Malone do_cpuid(u_int ax, u_int *p) 124a983fdfeSDavid Malone { 125a983fdfeSDavid Malone __asm __volatile("cpuid" 126a983fdfeSDavid Malone : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) 127a983fdfeSDavid Malone : "0" (ax)); 128a983fdfeSDavid Malone } 129a983fdfeSDavid Malone 130a983fdfeSDavid Malone static __inline void 131f6108b61SJacques Vidrine cpuid_count(u_int ax, u_int cx, u_int *p) 132f6108b61SJacques Vidrine { 133f6108b61SJacques Vidrine __asm __volatile("cpuid" 134f6108b61SJacques Vidrine : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) 135f6108b61SJacques Vidrine : "0" (ax), "c" (cx)); 136f6108b61SJacques Vidrine } 137f6108b61SJacques Vidrine 138f6108b61SJacques Vidrine static __inline void 1395b81b6b3SRodney W. Grimes enable_intr(void) 1405b81b6b3SRodney W. Grimes { 141fadc51bdSBruce Evans __asm __volatile("sti"); 1425b81b6b3SRodney W. Grimes } 1435b81b6b3SRodney W. Grimes 144a67ef0a7SBruce Evans #ifdef _KERNEL 145a67ef0a7SBruce Evans 146264c3d87SPeter Wemm #define HAVE_INLINE_FFS 147bc35f5dcSPaul Saab #define ffs(x) __builtin_ffs(x) 148176ce2b1SPeter Wemm 149176ce2b1SPeter Wemm #define HAVE_INLINE_FFSL 150176ce2b1SPeter Wemm 151176ce2b1SPeter Wemm static __inline int 152176ce2b1SPeter Wemm ffsl(long mask) 153176ce2b1SPeter Wemm { 154176ce2b1SPeter Wemm return (mask == 0 ? mask : (int)bsfq((u_long)mask) + 1); 155004bedebSBruce Evans } 156004bedebSBruce Evans 157f25e50cfSAndriy Gapon #define HAVE_INLINE_FFSLL 158f25e50cfSAndriy Gapon 159f25e50cfSAndriy Gapon static __inline int 160f25e50cfSAndriy Gapon ffsll(long long mask) 161f25e50cfSAndriy Gapon { 162f25e50cfSAndriy Gapon return (ffsl((long)mask)); 163f25e50cfSAndriy Gapon } 164f25e50cfSAndriy Gapon 16513f588f8SGarrett Wollman #define HAVE_INLINE_FLS 16613f588f8SGarrett Wollman 16713f588f8SGarrett Wollman static __inline int 16813f588f8SGarrett Wollman fls(int mask) 16913f588f8SGarrett Wollman { 1707e622d3cSMark Murray return (mask == 0 ? mask : (int)bsrl((u_int)mask) + 1); 17113f588f8SGarrett Wollman } 17213f588f8SGarrett Wollman 173176ce2b1SPeter Wemm #define HAVE_INLINE_FLSL 174176ce2b1SPeter Wemm 175176ce2b1SPeter Wemm static __inline int 176176ce2b1SPeter Wemm flsl(long mask) 177176ce2b1SPeter Wemm { 178176ce2b1SPeter Wemm return (mask == 0 ? mask : (int)bsrq((u_long)mask) + 1); 179176ce2b1SPeter Wemm } 180176ce2b1SPeter Wemm 181f25e50cfSAndriy Gapon #define HAVE_INLINE_FLSLL 182f25e50cfSAndriy Gapon 183f25e50cfSAndriy Gapon static __inline int 184f25e50cfSAndriy Gapon flsll(long long mask) 185f25e50cfSAndriy Gapon { 186f25e50cfSAndriy Gapon return (flsl((long)mask)); 187f25e50cfSAndriy Gapon } 188f25e50cfSAndriy Gapon 189a67ef0a7SBruce Evans #endif /* _KERNEL */ 190a67ef0a7SBruce Evans 191d7ee4425SMark Murray static __inline void 192d7ee4425SMark Murray halt(void) 193d7ee4425SMark Murray { 194d7ee4425SMark Murray __asm __volatile("hlt"); 195d7ee4425SMark Murray } 196d7ee4425SMark Murray 197004bedebSBruce Evans static __inline u_char 198e1048f76SEd Schouten inb(u_int port) 199004bedebSBruce Evans { 200004bedebSBruce Evans u_char data; 201004bedebSBruce Evans 2024854ae24SJung-uk Kim __asm __volatile("inb %w1, %0" : "=a" (data) : "Nd" (port)); 203004bedebSBruce Evans return (data); 204004bedebSBruce Evans } 205004bedebSBruce Evans 20600be8601SBruce Evans static __inline u_int 207004bedebSBruce Evans inl(u_int port) 208004bedebSBruce Evans { 20900be8601SBruce Evans u_int data; 210004bedebSBruce Evans 2114854ae24SJung-uk Kim __asm __volatile("inl %w1, %0" : "=a" (data) : "Nd" (port)); 212004bedebSBruce Evans return (data); 213004bedebSBruce Evans } 214004bedebSBruce Evans 215004bedebSBruce Evans static __inline void 21693d8be03SDavid E. O'Brien insb(u_int port, void *addr, size_t count) 217004bedebSBruce Evans { 218004bedebSBruce Evans __asm __volatile("cld; rep; insb" 21993d8be03SDavid E. O'Brien : "+D" (addr), "+c" (count) 2203f9a462fSJohn Baldwin : "d" (port) 221896763faSBruce Evans : "memory"); 222004bedebSBruce Evans } 223004bedebSBruce Evans 224004bedebSBruce Evans static __inline void 22593d8be03SDavid E. O'Brien insw(u_int port, void *addr, size_t count) 226004bedebSBruce Evans { 227004bedebSBruce Evans __asm __volatile("cld; rep; insw" 22893d8be03SDavid E. O'Brien : "+D" (addr), "+c" (count) 2293f9a462fSJohn Baldwin : "d" (port) 230896763faSBruce Evans : "memory"); 231004bedebSBruce Evans } 232004bedebSBruce Evans 233004bedebSBruce Evans static __inline void 23493d8be03SDavid E. O'Brien insl(u_int port, void *addr, size_t count) 235004bedebSBruce Evans { 236004bedebSBruce Evans __asm __volatile("cld; rep; insl" 23793d8be03SDavid E. O'Brien : "+D" (addr), "+c" (count) 2383f9a462fSJohn Baldwin : "d" (port) 239896763faSBruce Evans : "memory"); 240004bedebSBruce Evans } 241004bedebSBruce Evans 242ece15d78SBruce Evans static __inline void 2434c024bbdSKATO Takenori invd(void) 2444c024bbdSKATO Takenori { 2454c024bbdSKATO Takenori __asm __volatile("invd"); 2464c024bbdSKATO Takenori } 2474c024bbdSKATO Takenori 248004bedebSBruce Evans static __inline u_short 249004bedebSBruce Evans inw(u_int port) 250004bedebSBruce Evans { 251004bedebSBruce Evans u_short data; 252004bedebSBruce Evans 2534854ae24SJung-uk Kim __asm __volatile("inw %w1, %0" : "=a" (data) : "Nd" (port)); 254004bedebSBruce Evans return (data); 255004bedebSBruce Evans } 256004bedebSBruce Evans 257004bedebSBruce Evans static __inline void 258e1048f76SEd Schouten outb(u_int port, u_char data) 259004bedebSBruce Evans { 2604854ae24SJung-uk Kim __asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port)); 261004bedebSBruce Evans } 262004bedebSBruce Evans 263004bedebSBruce Evans static __inline void 26400be8601SBruce Evans outl(u_int port, u_int data) 265004bedebSBruce Evans { 2664854ae24SJung-uk Kim __asm __volatile("outl %0, %w1" : : "a" (data), "Nd" (port)); 267004bedebSBruce Evans } 268004bedebSBruce Evans 269004bedebSBruce Evans static __inline void 27093d8be03SDavid E. O'Brien outsb(u_int port, const void *addr, size_t count) 271004bedebSBruce Evans { 272004bedebSBruce Evans __asm __volatile("cld; rep; outsb" 27393d8be03SDavid E. O'Brien : "+S" (addr), "+c" (count) 2743f9a462fSJohn Baldwin : "d" (port)); 275004bedebSBruce Evans } 276004bedebSBruce Evans 277004bedebSBruce Evans static __inline void 27893d8be03SDavid E. O'Brien outsw(u_int port, const void *addr, size_t count) 279004bedebSBruce Evans { 280004bedebSBruce Evans __asm __volatile("cld; rep; outsw" 28193d8be03SDavid E. O'Brien : "+S" (addr), "+c" (count) 2823f9a462fSJohn Baldwin : "d" (port)); 283004bedebSBruce Evans } 284004bedebSBruce Evans 285004bedebSBruce Evans static __inline void 28693d8be03SDavid E. O'Brien outsl(u_int port, const void *addr, size_t count) 287004bedebSBruce Evans { 288004bedebSBruce Evans __asm __volatile("cld; rep; outsl" 28993d8be03SDavid E. O'Brien : "+S" (addr), "+c" (count) 2903f9a462fSJohn Baldwin : "d" (port)); 291004bedebSBruce Evans } 292004bedebSBruce Evans 293004bedebSBruce Evans static __inline void 294004bedebSBruce Evans outw(u_int port, u_short data) 295004bedebSBruce Evans { 2964854ae24SJung-uk Kim __asm __volatile("outw %0, %w1" : : "a" (data), "Nd" (port)); 297004bedebSBruce Evans } 298004bedebSBruce Evans 2992bde6e35SAlan Cox static __inline u_long 3002bde6e35SAlan Cox popcntq(u_long mask) 3012bde6e35SAlan Cox { 3022bde6e35SAlan Cox u_long result; 3032bde6e35SAlan Cox 3042bde6e35SAlan Cox __asm __volatile("popcntq %1,%0" : "=r" (result) : "rm" (mask)); 3052bde6e35SAlan Cox return (result); 3062bde6e35SAlan Cox } 3072bde6e35SAlan Cox 3082be69f32SJohn Baldwin static __inline void 3090220d04fSKonstantin Belousov lfence(void) 3100220d04fSKonstantin Belousov { 3110220d04fSKonstantin Belousov 3120220d04fSKonstantin Belousov __asm __volatile("lfence" : : : "memory"); 3130220d04fSKonstantin Belousov } 3140220d04fSKonstantin Belousov 3150220d04fSKonstantin Belousov static __inline void 316206a3368SKonstantin Belousov mfence(void) 317206a3368SKonstantin Belousov { 318206a3368SKonstantin Belousov 319beb2c1f3SAndriy Gapon __asm __volatile("mfence" : : : "memory"); 320206a3368SKonstantin Belousov } 321206a3368SKonstantin Belousov 322206a3368SKonstantin Belousov static __inline void 3236b8c6989SJohn Baldwin ia32_pause(void) 3242be69f32SJohn Baldwin { 3252be69f32SJohn Baldwin __asm __volatile("pause"); 3262be69f32SJohn Baldwin } 3272be69f32SJohn Baldwin 328afa88623SPeter Wemm static __inline u_long 329afa88623SPeter Wemm read_rflags(void) 3305b81b6b3SRodney W. Grimes { 331afa88623SPeter Wemm u_long rf; 332004bedebSBruce Evans 333afa88623SPeter Wemm __asm __volatile("pushfq; popq %0" : "=r" (rf)); 334afa88623SPeter Wemm return (rf); 3355b81b6b3SRodney W. Grimes } 3365b81b6b3SRodney W. Grimes 337f5ac47f4SJung-uk Kim static __inline uint64_t 3385dbd168eSBruce Evans rdmsr(u_int msr) 3395dbd168eSBruce Evans { 340f5ac47f4SJung-uk Kim uint32_t low, high; 3415dbd168eSBruce Evans 342afa88623SPeter Wemm __asm __volatile("rdmsr" : "=a" (low), "=d" (high) : "c" (msr)); 343f5ac47f4SJung-uk Kim return (low | ((uint64_t)high << 32)); 3445dbd168eSBruce Evans } 3455dbd168eSBruce Evans 3464c918926SKonstantin Belousov static __inline uint32_t 3474c918926SKonstantin Belousov rdmsr32(u_int msr) 3484c918926SKonstantin Belousov { 3494c918926SKonstantin Belousov uint32_t low; 3504c918926SKonstantin Belousov 3514c918926SKonstantin Belousov __asm __volatile("rdmsr" : "=a" (low) : "c" (msr) : "rdx"); 3524c918926SKonstantin Belousov return (low); 3534c918926SKonstantin Belousov } 3544c918926SKonstantin Belousov 355f5ac47f4SJung-uk Kim static __inline uint64_t 3565dbd168eSBruce Evans rdpmc(u_int pmc) 3575dbd168eSBruce Evans { 358f5ac47f4SJung-uk Kim uint32_t low, high; 3595dbd168eSBruce Evans 360afa88623SPeter Wemm __asm __volatile("rdpmc" : "=a" (low), "=d" (high) : "c" (pmc)); 361f5ac47f4SJung-uk Kim return (low | ((uint64_t)high << 32)); 3625dbd168eSBruce Evans } 3635dbd168eSBruce Evans 364f5ac47f4SJung-uk Kim static __inline uint64_t 3655dbd168eSBruce Evans rdtsc(void) 3665dbd168eSBruce Evans { 367f5ac47f4SJung-uk Kim uint32_t low, high; 3685dbd168eSBruce Evans 369afa88623SPeter Wemm __asm __volatile("rdtsc" : "=a" (low), "=d" (high)); 370f5ac47f4SJung-uk Kim return (low | ((uint64_t)high << 32)); 3715dbd168eSBruce Evans } 3725dbd168eSBruce Evans 3730e727642SJung-uk Kim static __inline uint32_t 3740e727642SJung-uk Kim rdtsc32(void) 3750e727642SJung-uk Kim { 3760e727642SJung-uk Kim uint32_t rv; 3770e727642SJung-uk Kim 3780e727642SJung-uk Kim __asm __volatile("rdtsc" : "=a" (rv) : : "edx"); 3790e727642SJung-uk Kim return (rv); 3800e727642SJung-uk Kim } 3810e727642SJung-uk Kim 382004bedebSBruce Evans static __inline void 3834c024bbdSKATO Takenori wbinvd(void) 3844c024bbdSKATO Takenori { 3854c024bbdSKATO Takenori __asm __volatile("wbinvd"); 3864c024bbdSKATO Takenori } 3874c024bbdSKATO Takenori 3884c024bbdSKATO Takenori static __inline void 389afa88623SPeter Wemm write_rflags(u_long rf) 3905b81b6b3SRodney W. Grimes { 391afa88623SPeter Wemm __asm __volatile("pushq %0; popfq" : : "r" (rf)); 3925b81b6b3SRodney W. Grimes } 3935b81b6b3SRodney W. Grimes 394d69e8502SGarrett Wollman static __inline void 395f5ac47f4SJung-uk Kim wrmsr(u_int msr, uint64_t newval) 396d69e8502SGarrett Wollman { 397f5ac47f4SJung-uk Kim uint32_t low, high; 398afa88623SPeter Wemm 399afa88623SPeter Wemm low = newval; 400afa88623SPeter Wemm high = newval >> 32; 401afa88623SPeter Wemm __asm __volatile("wrmsr" : : "a" (low), "d" (high), "c" (msr)); 402d69e8502SGarrett Wollman } 403d69e8502SGarrett Wollman 404f1b665c8SPeter Wemm static __inline void 405afa88623SPeter Wemm load_cr0(u_long data) 406f1b665c8SPeter Wemm { 407f1b665c8SPeter Wemm 408afa88623SPeter Wemm __asm __volatile("movq %0,%%cr0" : : "r" (data)); 409f1b665c8SPeter Wemm } 410f1b665c8SPeter Wemm 411afa88623SPeter Wemm static __inline u_long 412f1b665c8SPeter Wemm rcr0(void) 413f1b665c8SPeter Wemm { 414afa88623SPeter Wemm u_long data; 415f1b665c8SPeter Wemm 416afa88623SPeter Wemm __asm __volatile("movq %%cr0,%0" : "=r" (data)); 417f1b665c8SPeter Wemm return (data); 418f1b665c8SPeter Wemm } 419f1b665c8SPeter Wemm 420afa88623SPeter Wemm static __inline u_long 421f1b665c8SPeter Wemm rcr2(void) 422f1b665c8SPeter Wemm { 423afa88623SPeter Wemm u_long data; 424f1b665c8SPeter Wemm 425afa88623SPeter Wemm __asm __volatile("movq %%cr2,%0" : "=r" (data)); 426f1b665c8SPeter Wemm return (data); 427f1b665c8SPeter Wemm } 428f1b665c8SPeter Wemm 429f1b665c8SPeter Wemm static __inline void 430afa88623SPeter Wemm load_cr3(u_long data) 431f1b665c8SPeter Wemm { 432f1b665c8SPeter Wemm 433afa88623SPeter Wemm __asm __volatile("movq %0,%%cr3" : : "r" (data) : "memory"); 434f1b665c8SPeter Wemm } 435f1b665c8SPeter Wemm 436afa88623SPeter Wemm static __inline u_long 437f1b665c8SPeter Wemm rcr3(void) 438f1b665c8SPeter Wemm { 439afa88623SPeter Wemm u_long data; 440f1b665c8SPeter Wemm 441afa88623SPeter Wemm __asm __volatile("movq %%cr3,%0" : "=r" (data)); 442f1b665c8SPeter Wemm return (data); 443f1b665c8SPeter Wemm } 444f1b665c8SPeter Wemm 445f1b665c8SPeter Wemm static __inline void 446afa88623SPeter Wemm load_cr4(u_long data) 447f1b665c8SPeter Wemm { 448afa88623SPeter Wemm __asm __volatile("movq %0,%%cr4" : : "r" (data)); 449f1b665c8SPeter Wemm } 450f1b665c8SPeter Wemm 451afa88623SPeter Wemm static __inline u_long 452f1b665c8SPeter Wemm rcr4(void) 453f1b665c8SPeter Wemm { 454afa88623SPeter Wemm u_long data; 455f1b665c8SPeter Wemm 456afa88623SPeter Wemm __asm __volatile("movq %%cr4,%0" : "=r" (data)); 457f1b665c8SPeter Wemm return (data); 458f1b665c8SPeter Wemm } 459f1b665c8SPeter Wemm 4607574a595SJohn Baldwin static __inline u_long 4617574a595SJohn Baldwin rxcr(u_int reg) 4627574a595SJohn Baldwin { 4637574a595SJohn Baldwin u_int low, high; 4647574a595SJohn Baldwin 4657574a595SJohn Baldwin __asm __volatile("xgetbv" : "=a" (low), "=d" (high) : "c" (reg)); 4667574a595SJohn Baldwin return (low | ((uint64_t)high << 32)); 4677574a595SJohn Baldwin } 4687574a595SJohn Baldwin 4697574a595SJohn Baldwin static __inline void 4707574a595SJohn Baldwin load_xcr(u_int reg, u_long val) 4717574a595SJohn Baldwin { 4727574a595SJohn Baldwin u_int low, high; 4737574a595SJohn Baldwin 4747574a595SJohn Baldwin low = val; 4757574a595SJohn Baldwin high = val >> 32; 4767574a595SJohn Baldwin __asm __volatile("xsetbv" : : "c" (reg), "a" (low), "d" (high)); 4777574a595SJohn Baldwin } 4787574a595SJohn Baldwin 479f1b665c8SPeter Wemm /* 480f1b665c8SPeter Wemm * Global TLB flush (except for thise for pages marked PG_G) 481f1b665c8SPeter Wemm */ 482f1b665c8SPeter Wemm static __inline void 483f1b665c8SPeter Wemm invltlb(void) 484f1b665c8SPeter Wemm { 485f1b665c8SPeter Wemm 486f1b665c8SPeter Wemm load_cr3(rcr3()); 487f1b665c8SPeter Wemm } 488f1b665c8SPeter Wemm 489e44af46eSJustin T. Gibbs #ifndef CR4_PGE 490e44af46eSJustin T. Gibbs #define CR4_PGE 0x00000080 /* Page global enable */ 491e44af46eSJustin T. Gibbs #endif 492e44af46eSJustin T. Gibbs 493e44af46eSJustin T. Gibbs /* 494e44af46eSJustin T. Gibbs * Perform the guaranteed invalidation of all TLB entries. This 495e44af46eSJustin T. Gibbs * includes the global entries, and entries in all PCIDs, not only the 496e44af46eSJustin T. Gibbs * current context. The function works both on non-PCID CPUs and CPUs 497e44af46eSJustin T. Gibbs * with the PCID turned off or on. See IA-32 SDM Vol. 3a 4.10.4.1 498e44af46eSJustin T. Gibbs * Operations that Invalidate TLBs and Paging-Structure Caches. 499e44af46eSJustin T. Gibbs */ 500e44af46eSJustin T. Gibbs static __inline void 501e44af46eSJustin T. Gibbs invltlb_globpcid(void) 502e44af46eSJustin T. Gibbs { 503e44af46eSJustin T. Gibbs uint64_t cr4; 504e44af46eSJustin T. Gibbs 505e44af46eSJustin T. Gibbs cr4 = rcr4(); 506e44af46eSJustin T. Gibbs load_cr4(cr4 & ~CR4_PGE); 507e44af46eSJustin T. Gibbs /* 508e44af46eSJustin T. Gibbs * Although preemption at this point could be detrimental to 509e44af46eSJustin T. Gibbs * performance, it would not lead to an error. PG_G is simply 510e44af46eSJustin T. Gibbs * ignored if CR4.PGE is clear. Moreover, in case this block 511e44af46eSJustin T. Gibbs * is re-entered, the load_cr4() either above or below will 512e44af46eSJustin T. Gibbs * modify CR4.PGE flushing the TLB. 513e44af46eSJustin T. Gibbs */ 514e44af46eSJustin T. Gibbs load_cr4(cr4 | CR4_PGE); 515e44af46eSJustin T. Gibbs } 516e44af46eSJustin T. Gibbs 517f1b665c8SPeter Wemm /* 518f1b665c8SPeter Wemm * TLB flush for an individual page (even if it has PG_G). 519f1b665c8SPeter Wemm * Only works on 486+ CPUs (i386 does not have PG_G). 520f1b665c8SPeter Wemm */ 521f1b665c8SPeter Wemm static __inline void 522afa88623SPeter Wemm invlpg(u_long addr) 523f1b665c8SPeter Wemm { 524f1b665c8SPeter Wemm 525f1b665c8SPeter Wemm __asm __volatile("invlpg %0" : : "m" (*(char *)addr) : "memory"); 526f1b665c8SPeter Wemm } 527f1b665c8SPeter Wemm 5285f5703efSKonstantin Belousov #define INVPCID_ADDR 0 5295f5703efSKonstantin Belousov #define INVPCID_CTX 1 5305f5703efSKonstantin Belousov #define INVPCID_CTXGLOB 2 5315f5703efSKonstantin Belousov #define INVPCID_ALLCTX 3 5325f5703efSKonstantin Belousov 5335f5703efSKonstantin Belousov struct invpcid_descr { 5345f5703efSKonstantin Belousov uint64_t pcid:12 __packed; 5355f5703efSKonstantin Belousov uint64_t pad:52 __packed; 5365f5703efSKonstantin Belousov uint64_t addr; 5375f5703efSKonstantin Belousov } __packed; 5385f5703efSKonstantin Belousov 5395f5703efSKonstantin Belousov static __inline void 5405f5703efSKonstantin Belousov invpcid(struct invpcid_descr *d, int type) 5415f5703efSKonstantin Belousov { 5425f5703efSKonstantin Belousov 543*a546448bSKonstantin Belousov __asm __volatile("invpcid (%0),%1" 544*a546448bSKonstantin Belousov : : "r" (d), "r" ((u_long)type) : "memory"); 5455f5703efSKonstantin Belousov } 5465f5703efSKonstantin Belousov 54727d4fea6SRoman Divacky static __inline u_short 5485206bca1SLuoqi Chen rfs(void) 5495206bca1SLuoqi Chen { 55027d4fea6SRoman Divacky u_short sel; 55127d4fea6SRoman Divacky __asm __volatile("movw %%fs,%0" : "=rm" (sel)); 5525206bca1SLuoqi Chen return (sel); 5535206bca1SLuoqi Chen } 5545206bca1SLuoqi Chen 55527d4fea6SRoman Divacky static __inline u_short 5565206bca1SLuoqi Chen rgs(void) 5575206bca1SLuoqi Chen { 55827d4fea6SRoman Divacky u_short sel; 55927d4fea6SRoman Divacky __asm __volatile("movw %%gs,%0" : "=rm" (sel)); 5605206bca1SLuoqi Chen return (sel); 5615206bca1SLuoqi Chen } 5625206bca1SLuoqi Chen 56327d4fea6SRoman Divacky static __inline u_short 564cd0149e3SPeter Wemm rss(void) 565cd0149e3SPeter Wemm { 56627d4fea6SRoman Divacky u_short sel; 56727d4fea6SRoman Divacky __asm __volatile("movw %%ss,%0" : "=rm" (sel)); 568cd0149e3SPeter Wemm return (sel); 569cd0149e3SPeter Wemm } 570cd0149e3SPeter Wemm 5715206bca1SLuoqi Chen static __inline void 57227d4fea6SRoman Divacky load_ds(u_short sel) 573d85631c4SPeter Wemm { 57427d4fea6SRoman Divacky __asm __volatile("movw %0,%%ds" : : "rm" (sel)); 575d85631c4SPeter Wemm } 576d85631c4SPeter Wemm 577d85631c4SPeter Wemm static __inline void 57827d4fea6SRoman Divacky load_es(u_short sel) 579d85631c4SPeter Wemm { 58027d4fea6SRoman Divacky __asm __volatile("movw %0,%%es" : : "rm" (sel)); 581d85631c4SPeter Wemm } 582d85631c4SPeter Wemm 583beb2c1f3SAndriy Gapon static __inline void 584f0b28f00SJung-uk Kim cpu_monitor(const void *addr, u_long extensions, u_int hints) 58566247efaSJeff Roberson { 586f0b28f00SJung-uk Kim 587f0b28f00SJung-uk Kim __asm __volatile("monitor" 58866247efaSJeff Roberson : : "a" (addr), "c" (extensions), "d" (hints)); 58966247efaSJeff Roberson } 59066247efaSJeff Roberson 591beb2c1f3SAndriy Gapon static __inline void 592f0b28f00SJung-uk Kim cpu_mwait(u_long extensions, u_int hints) 59366247efaSJeff Roberson { 594f0b28f00SJung-uk Kim 595f0b28f00SJung-uk Kim __asm __volatile("mwait" : : "a" (hints), "c" (extensions)); 59666247efaSJeff Roberson } 59766247efaSJeff Roberson 598c0a54ff6SPeter Wemm #ifdef _KERNEL 599c0a54ff6SPeter Wemm /* This is defined in <machine/specialreg.h> but is too painful to get to */ 600c0a54ff6SPeter Wemm #ifndef MSR_FSBASE 601c0a54ff6SPeter Wemm #define MSR_FSBASE 0xc0000100 602c0a54ff6SPeter Wemm #endif 603c0a54ff6SPeter Wemm static __inline void 60427d4fea6SRoman Divacky load_fs(u_short sel) 605c0a54ff6SPeter Wemm { 606c0a54ff6SPeter Wemm /* Preserve the fsbase value across the selector load */ 60727d4fea6SRoman Divacky __asm __volatile("rdmsr; movw %0,%%fs; wrmsr" 608db26a671SEd Schouten : : "rm" (sel), "c" (MSR_FSBASE) : "eax", "edx"); 609c0a54ff6SPeter Wemm } 610c0a54ff6SPeter Wemm 611c0a54ff6SPeter Wemm #ifndef MSR_GSBASE 612c0a54ff6SPeter Wemm #define MSR_GSBASE 0xc0000101 613c0a54ff6SPeter Wemm #endif 614c0a54ff6SPeter Wemm static __inline void 61527d4fea6SRoman Divacky load_gs(u_short sel) 616c0a54ff6SPeter Wemm { 617c0a54ff6SPeter Wemm /* 618c0a54ff6SPeter Wemm * Preserve the gsbase value across the selector load. 619c0a54ff6SPeter Wemm * Note that we have to disable interrupts because the gsbase 620c0a54ff6SPeter Wemm * being trashed happens to be the kernel gsbase at the time. 621c0a54ff6SPeter Wemm */ 62227d4fea6SRoman Divacky __asm __volatile("pushfq; cli; rdmsr; movw %0,%%gs; wrmsr; popfq" 623db26a671SEd Schouten : : "rm" (sel), "c" (MSR_GSBASE) : "eax", "edx"); 624c0a54ff6SPeter Wemm } 625c0a54ff6SPeter Wemm #else 626c0a54ff6SPeter Wemm /* Usable by userland */ 627d85631c4SPeter Wemm static __inline void 62827d4fea6SRoman Divacky load_fs(u_short sel) 6295206bca1SLuoqi Chen { 63027d4fea6SRoman Divacky __asm __volatile("movw %0,%%fs" : : "rm" (sel)); 6315206bca1SLuoqi Chen } 6325206bca1SLuoqi Chen 6335206bca1SLuoqi Chen static __inline void 63427d4fea6SRoman Divacky load_gs(u_short sel) 6355206bca1SLuoqi Chen { 63627d4fea6SRoman Divacky __asm __volatile("movw %0,%%gs" : : "rm" (sel)); 6375206bca1SLuoqi Chen } 638c0a54ff6SPeter Wemm #endif 6395206bca1SLuoqi Chen 640eb1443c8SPeter Wemm static __inline void 641eb1443c8SPeter Wemm lidt(struct region_descriptor *addr) 642eb1443c8SPeter Wemm { 643eb1443c8SPeter Wemm __asm __volatile("lidt (%0)" : : "r" (addr)); 644eb1443c8SPeter Wemm } 645eb1443c8SPeter Wemm 646eb1443c8SPeter Wemm static __inline void 647eb1443c8SPeter Wemm lldt(u_short sel) 648eb1443c8SPeter Wemm { 649eb1443c8SPeter Wemm __asm __volatile("lldt %0" : : "r" (sel)); 650eb1443c8SPeter Wemm } 651eb1443c8SPeter Wemm 652eb1443c8SPeter Wemm static __inline void 653eb1443c8SPeter Wemm ltr(u_short sel) 654eb1443c8SPeter Wemm { 655eb1443c8SPeter Wemm __asm __volatile("ltr %0" : : "r" (sel)); 656eb1443c8SPeter Wemm } 657eb1443c8SPeter Wemm 658f5ac47f4SJung-uk Kim static __inline uint64_t 6591182b177SPeter Wemm rdr0(void) 6601182b177SPeter Wemm { 661f5ac47f4SJung-uk Kim uint64_t data; 6621182b177SPeter Wemm __asm __volatile("movq %%dr0,%0" : "=r" (data)); 6631182b177SPeter Wemm return (data); 6641182b177SPeter Wemm } 6651182b177SPeter Wemm 6661182b177SPeter Wemm static __inline void 667f5ac47f4SJung-uk Kim load_dr0(uint64_t dr0) 6681182b177SPeter Wemm { 6691182b177SPeter Wemm __asm __volatile("movq %0,%%dr0" : : "r" (dr0)); 6701182b177SPeter Wemm } 6711182b177SPeter Wemm 672f5ac47f4SJung-uk Kim static __inline uint64_t 6731182b177SPeter Wemm rdr1(void) 6741182b177SPeter Wemm { 675f5ac47f4SJung-uk Kim uint64_t data; 6761182b177SPeter Wemm __asm __volatile("movq %%dr1,%0" : "=r" (data)); 6771182b177SPeter Wemm return (data); 6781182b177SPeter Wemm } 6791182b177SPeter Wemm 6801182b177SPeter Wemm static __inline void 681f5ac47f4SJung-uk Kim load_dr1(uint64_t dr1) 6821182b177SPeter Wemm { 6831182b177SPeter Wemm __asm __volatile("movq %0,%%dr1" : : "r" (dr1)); 6841182b177SPeter Wemm } 6851182b177SPeter Wemm 686f5ac47f4SJung-uk Kim static __inline uint64_t 6871182b177SPeter Wemm rdr2(void) 6881182b177SPeter Wemm { 689f5ac47f4SJung-uk Kim uint64_t data; 6901182b177SPeter Wemm __asm __volatile("movq %%dr2,%0" : "=r" (data)); 6911182b177SPeter Wemm return (data); 6921182b177SPeter Wemm } 6931182b177SPeter Wemm 6941182b177SPeter Wemm static __inline void 695f5ac47f4SJung-uk Kim load_dr2(uint64_t dr2) 6961182b177SPeter Wemm { 6971182b177SPeter Wemm __asm __volatile("movq %0,%%dr2" : : "r" (dr2)); 6981182b177SPeter Wemm } 6991182b177SPeter Wemm 700f5ac47f4SJung-uk Kim static __inline uint64_t 7011182b177SPeter Wemm rdr3(void) 7021182b177SPeter Wemm { 703f5ac47f4SJung-uk Kim uint64_t data; 7041182b177SPeter Wemm __asm __volatile("movq %%dr3,%0" : "=r" (data)); 7051182b177SPeter Wemm return (data); 7061182b177SPeter Wemm } 7071182b177SPeter Wemm 7081182b177SPeter Wemm static __inline void 709f5ac47f4SJung-uk Kim load_dr3(uint64_t dr3) 7101182b177SPeter Wemm { 7111182b177SPeter Wemm __asm __volatile("movq %0,%%dr3" : : "r" (dr3)); 7121182b177SPeter Wemm } 7131182b177SPeter Wemm 714f5ac47f4SJung-uk Kim static __inline uint64_t 7151182b177SPeter Wemm rdr4(void) 7161182b177SPeter Wemm { 717f5ac47f4SJung-uk Kim uint64_t data; 7181182b177SPeter Wemm __asm __volatile("movq %%dr4,%0" : "=r" (data)); 7191182b177SPeter Wemm return (data); 7201182b177SPeter Wemm } 7211182b177SPeter Wemm 7221182b177SPeter Wemm static __inline void 723f5ac47f4SJung-uk Kim load_dr4(uint64_t dr4) 7241182b177SPeter Wemm { 7251182b177SPeter Wemm __asm __volatile("movq %0,%%dr4" : : "r" (dr4)); 7261182b177SPeter Wemm } 7271182b177SPeter Wemm 728f5ac47f4SJung-uk Kim static __inline uint64_t 7291182b177SPeter Wemm rdr5(void) 7301182b177SPeter Wemm { 731f5ac47f4SJung-uk Kim uint64_t data; 7321182b177SPeter Wemm __asm __volatile("movq %%dr5,%0" : "=r" (data)); 7331182b177SPeter Wemm return (data); 7341182b177SPeter Wemm } 7351182b177SPeter Wemm 7361182b177SPeter Wemm static __inline void 737f5ac47f4SJung-uk Kim load_dr5(uint64_t dr5) 7381182b177SPeter Wemm { 7391182b177SPeter Wemm __asm __volatile("movq %0,%%dr5" : : "r" (dr5)); 7401182b177SPeter Wemm } 7411182b177SPeter Wemm 742f5ac47f4SJung-uk Kim static __inline uint64_t 7431182b177SPeter Wemm rdr6(void) 7441182b177SPeter Wemm { 745f5ac47f4SJung-uk Kim uint64_t data; 7461182b177SPeter Wemm __asm __volatile("movq %%dr6,%0" : "=r" (data)); 7471182b177SPeter Wemm return (data); 7481182b177SPeter Wemm } 7491182b177SPeter Wemm 7501182b177SPeter Wemm static __inline void 751f5ac47f4SJung-uk Kim load_dr6(uint64_t dr6) 7521182b177SPeter Wemm { 7531182b177SPeter Wemm __asm __volatile("movq %0,%%dr6" : : "r" (dr6)); 7541182b177SPeter Wemm } 7551182b177SPeter Wemm 756f5ac47f4SJung-uk Kim static __inline uint64_t 7571182b177SPeter Wemm rdr7(void) 7581182b177SPeter Wemm { 759f5ac47f4SJung-uk Kim uint64_t data; 7601182b177SPeter Wemm __asm __volatile("movq %%dr7,%0" : "=r" (data)); 7611182b177SPeter Wemm return (data); 7621182b177SPeter Wemm } 7631182b177SPeter Wemm 7641182b177SPeter Wemm static __inline void 765f5ac47f4SJung-uk Kim load_dr7(uint64_t dr7) 7661182b177SPeter Wemm { 7671182b177SPeter Wemm __asm __volatile("movq %0,%%dr7" : : "r" (dr7)); 7681182b177SPeter Wemm } 7691182b177SPeter Wemm 770ba74981eSWarner Losh static __inline register_t 771ba74981eSWarner Losh intr_disable(void) 772ba74981eSWarner Losh { 773afa88623SPeter Wemm register_t rflags; 774ba74981eSWarner Losh 775afa88623SPeter Wemm rflags = read_rflags(); 776ba74981eSWarner Losh disable_intr(); 777afa88623SPeter Wemm return (rflags); 778ba74981eSWarner Losh } 779ba74981eSWarner Losh 780ba74981eSWarner Losh static __inline void 781afa88623SPeter Wemm intr_restore(register_t rflags) 782ba74981eSWarner Losh { 783afa88623SPeter Wemm write_rflags(rflags); 784ba74981eSWarner Losh } 785ba74981eSWarner Losh 786a5f50ef9SJoerg Wunsch #else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */ 7875b81b6b3SRodney W. Grimes 788b63dc6adSAlfred Perlstein int breakpoint(void); 789b63dc6adSAlfred Perlstein u_int bsfl(u_int mask); 790b63dc6adSAlfred Perlstein u_int bsrl(u_int mask); 791d706ec29SJohn Baldwin void clflush(u_long addr); 792d706ec29SJohn Baldwin void clts(void); 793d706ec29SJohn Baldwin void cpuid_count(u_int ax, u_int cx, u_int *p); 794b63dc6adSAlfred Perlstein void disable_intr(void); 795b63dc6adSAlfred Perlstein void do_cpuid(u_int ax, u_int *p); 796b63dc6adSAlfred Perlstein void enable_intr(void); 797d7ee4425SMark Murray void halt(void); 7984f6c19e5SPeter Wemm void ia32_pause(void); 799b63dc6adSAlfred Perlstein u_char inb(u_int port); 800b63dc6adSAlfred Perlstein u_int inl(u_int port); 80193d8be03SDavid E. O'Brien void insb(u_int port, void *addr, size_t count); 80293d8be03SDavid E. O'Brien void insl(u_int port, void *addr, size_t count); 80393d8be03SDavid E. O'Brien void insw(u_int port, void *addr, size_t count); 8044f6c19e5SPeter Wemm register_t intr_disable(void); 8054f6c19e5SPeter Wemm void intr_restore(register_t rf); 806b63dc6adSAlfred Perlstein void invd(void); 807b63dc6adSAlfred Perlstein void invlpg(u_int addr); 808b63dc6adSAlfred Perlstein void invltlb(void); 809b63dc6adSAlfred Perlstein u_short inw(u_int port); 810eb1443c8SPeter Wemm void lidt(struct region_descriptor *addr); 811eb1443c8SPeter Wemm void lldt(u_short sel); 8124f6c19e5SPeter Wemm void load_cr0(u_long cr0); 8134f6c19e5SPeter Wemm void load_cr3(u_long cr3); 8144f6c19e5SPeter Wemm void load_cr4(u_long cr4); 815f5ac47f4SJung-uk Kim void load_dr0(uint64_t dr0); 816f5ac47f4SJung-uk Kim void load_dr1(uint64_t dr1); 817f5ac47f4SJung-uk Kim void load_dr2(uint64_t dr2); 818f5ac47f4SJung-uk Kim void load_dr3(uint64_t dr3); 819f5ac47f4SJung-uk Kim void load_dr4(uint64_t dr4); 820f5ac47f4SJung-uk Kim void load_dr5(uint64_t dr5); 821f5ac47f4SJung-uk Kim void load_dr6(uint64_t dr6); 822f5ac47f4SJung-uk Kim void load_dr7(uint64_t dr7); 82327d4fea6SRoman Divacky void load_fs(u_short sel); 82427d4fea6SRoman Divacky void load_gs(u_short sel); 825eb1443c8SPeter Wemm void ltr(u_short sel); 826b63dc6adSAlfred Perlstein void outb(u_int port, u_char data); 827b63dc6adSAlfred Perlstein void outl(u_int port, u_int data); 82893d8be03SDavid E. O'Brien void outsb(u_int port, const void *addr, size_t count); 82993d8be03SDavid E. O'Brien void outsl(u_int port, const void *addr, size_t count); 83093d8be03SDavid E. O'Brien void outsw(u_int port, const void *addr, size_t count); 831b63dc6adSAlfred Perlstein void outw(u_int port, u_short data); 8324f6c19e5SPeter Wemm u_long rcr0(void); 8334f6c19e5SPeter Wemm u_long rcr2(void); 8344f6c19e5SPeter Wemm u_long rcr3(void); 8354f6c19e5SPeter Wemm u_long rcr4(void); 836f5ac47f4SJung-uk Kim uint64_t rdmsr(u_int msr); 8374c918926SKonstantin Belousov uint32_t rdmsr32(u_int msr); 838f5ac47f4SJung-uk Kim uint64_t rdpmc(u_int pmc); 839f5ac47f4SJung-uk Kim uint64_t rdr0(void); 840f5ac47f4SJung-uk Kim uint64_t rdr1(void); 841f5ac47f4SJung-uk Kim uint64_t rdr2(void); 842f5ac47f4SJung-uk Kim uint64_t rdr3(void); 843f5ac47f4SJung-uk Kim uint64_t rdr4(void); 844f5ac47f4SJung-uk Kim uint64_t rdr5(void); 845f5ac47f4SJung-uk Kim uint64_t rdr6(void); 846f5ac47f4SJung-uk Kim uint64_t rdr7(void); 847f5ac47f4SJung-uk Kim uint64_t rdtsc(void); 848a61dd1bdSJohn Baldwin u_long read_rflags(void); 8494f6c19e5SPeter Wemm u_int rfs(void); 8504f6c19e5SPeter Wemm u_int rgs(void); 851b63dc6adSAlfred Perlstein void wbinvd(void); 852afa88623SPeter Wemm void write_rflags(u_int rf); 853f5ac47f4SJung-uk Kim void wrmsr(u_int msr, uint64_t newval); 854004bedebSBruce Evans 855a5f50ef9SJoerg Wunsch #endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */ 8565b81b6b3SRodney W. Grimes 857b63dc6adSAlfred Perlstein void reset_dbregs(void); 858d74ac681SMatthew Dillon 859e085f869SStanislav Sedov #ifdef _KERNEL 860e085f869SStanislav Sedov int rdmsr_safe(u_int msr, uint64_t *val); 861e085f869SStanislav Sedov int wrmsr_safe(u_int msr, uint64_t newval); 862e085f869SStanislav Sedov #endif 863e085f869SStanislav Sedov 864004bedebSBruce Evans #endif /* !_MACHINE_CPUFUNC_H_ */ 865