14a5d661aSToomas Soome /*- 24a5d661aSToomas Soome * Copyright (c) 2003 Peter Wemm. 34a5d661aSToomas Soome * Copyright (c) 1993 The Regents of the University of California. 44a5d661aSToomas Soome * All rights reserved. 54a5d661aSToomas Soome * 64a5d661aSToomas Soome * Redistribution and use in source and binary forms, with or without 74a5d661aSToomas Soome * modification, are permitted provided that the following conditions 84a5d661aSToomas Soome * are met: 94a5d661aSToomas Soome * 1. Redistributions of source code must retain the above copyright 104a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer. 114a5d661aSToomas Soome * 2. Redistributions in binary form must reproduce the above copyright 124a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer in the 134a5d661aSToomas Soome * documentation and/or other materials provided with the distribution. 14*8ede9625SToomas Soome * 3. Neither the name of the University nor the names of its contributors 154a5d661aSToomas Soome * may be used to endorse or promote products derived from this software 164a5d661aSToomas Soome * without specific prior written permission. 174a5d661aSToomas Soome * 184a5d661aSToomas Soome * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 194a5d661aSToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 204a5d661aSToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 214a5d661aSToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 224a5d661aSToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 234a5d661aSToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 244a5d661aSToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 254a5d661aSToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 264a5d661aSToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 274a5d661aSToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 284a5d661aSToomas Soome * SUCH DAMAGE. 294a5d661aSToomas Soome * 304a5d661aSToomas Soome * $FreeBSD$ 314a5d661aSToomas Soome */ 324a5d661aSToomas Soome 334a5d661aSToomas Soome /* 344a5d661aSToomas Soome * Functions to provide access to special i386 instructions. 354a5d661aSToomas Soome * This in included in sys/systm.h, and that file should be 364a5d661aSToomas Soome * used in preference to this. 374a5d661aSToomas Soome */ 384a5d661aSToomas Soome 394a5d661aSToomas Soome #ifndef _MACHINE_CPUFUNC_H_ 404a5d661aSToomas Soome #define _MACHINE_CPUFUNC_H_ 414a5d661aSToomas Soome 424a5d661aSToomas Soome #ifndef _SYS_CDEFS_H_ 434a5d661aSToomas Soome #error this file needs sys/cdefs.h as a prerequisite 444a5d661aSToomas Soome #endif 454a5d661aSToomas Soome 464a5d661aSToomas Soome struct region_descriptor; 474a5d661aSToomas Soome 484a5d661aSToomas Soome #define readb(va) (*(volatile uint8_t *) (va)) 494a5d661aSToomas Soome #define readw(va) (*(volatile uint16_t *) (va)) 504a5d661aSToomas Soome #define readl(va) (*(volatile uint32_t *) (va)) 514a5d661aSToomas Soome #define readq(va) (*(volatile uint64_t *) (va)) 524a5d661aSToomas Soome 534a5d661aSToomas Soome #define writeb(va, d) (*(volatile uint8_t *) (va) = (d)) 544a5d661aSToomas Soome #define writew(va, d) (*(volatile uint16_t *) (va) = (d)) 554a5d661aSToomas Soome #define writel(va, d) (*(volatile uint32_t *) (va) = (d)) 564a5d661aSToomas Soome #define writeq(va, d) (*(volatile uint64_t *) (va) = (d)) 574a5d661aSToomas Soome 584a5d661aSToomas Soome #if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE) 594a5d661aSToomas Soome 604a5d661aSToomas Soome static __inline void 614a5d661aSToomas Soome breakpoint(void) 624a5d661aSToomas Soome { 634a5d661aSToomas Soome __asm __volatile("int $3"); 644a5d661aSToomas Soome } 654a5d661aSToomas Soome 664a5d661aSToomas Soome static __inline u_int 674a5d661aSToomas Soome bsfl(u_int mask) 684a5d661aSToomas Soome { 694a5d661aSToomas Soome u_int result; 704a5d661aSToomas Soome 714a5d661aSToomas Soome __asm __volatile("bsfl %1,%0" : "=r" (result) : "rm" (mask)); 724a5d661aSToomas Soome return (result); 734a5d661aSToomas Soome } 744a5d661aSToomas Soome 754a5d661aSToomas Soome static __inline u_long 764a5d661aSToomas Soome bsfq(u_long mask) 774a5d661aSToomas Soome { 784a5d661aSToomas Soome u_long result; 794a5d661aSToomas Soome 804a5d661aSToomas Soome __asm __volatile("bsfq %1,%0" : "=r" (result) : "rm" (mask)); 814a5d661aSToomas Soome return (result); 824a5d661aSToomas Soome } 834a5d661aSToomas Soome 844a5d661aSToomas Soome static __inline u_int 854a5d661aSToomas Soome bsrl(u_int mask) 864a5d661aSToomas Soome { 874a5d661aSToomas Soome u_int result; 884a5d661aSToomas Soome 894a5d661aSToomas Soome __asm __volatile("bsrl %1,%0" : "=r" (result) : "rm" (mask)); 904a5d661aSToomas Soome return (result); 914a5d661aSToomas Soome } 924a5d661aSToomas Soome 934a5d661aSToomas Soome static __inline u_long 944a5d661aSToomas Soome bsrq(u_long mask) 954a5d661aSToomas Soome { 964a5d661aSToomas Soome u_long result; 974a5d661aSToomas Soome 984a5d661aSToomas Soome __asm __volatile("bsrq %1,%0" : "=r" (result) : "rm" (mask)); 994a5d661aSToomas Soome return (result); 1004a5d661aSToomas Soome } 1014a5d661aSToomas Soome 1024a5d661aSToomas Soome static __inline void 1034a5d661aSToomas Soome clflush(u_long addr) 1044a5d661aSToomas Soome { 1054a5d661aSToomas Soome 1064a5d661aSToomas Soome __asm __volatile("clflush %0" : : "m" (*(char *)addr)); 1074a5d661aSToomas Soome } 1084a5d661aSToomas Soome 1094a5d661aSToomas Soome static __inline void 1104a5d661aSToomas Soome clflushopt(u_long addr) 1114a5d661aSToomas Soome { 1124a5d661aSToomas Soome 1134a5d661aSToomas Soome __asm __volatile(".byte 0x66;clflush %0" : : "m" (*(char *)addr)); 1144a5d661aSToomas Soome } 1154a5d661aSToomas Soome 1164a5d661aSToomas Soome static __inline void 1174a5d661aSToomas Soome clts(void) 1184a5d661aSToomas Soome { 1194a5d661aSToomas Soome 1204a5d661aSToomas Soome __asm __volatile("clts"); 1214a5d661aSToomas Soome } 1224a5d661aSToomas Soome 1234a5d661aSToomas Soome static __inline void 1244a5d661aSToomas Soome disable_intr(void) 1254a5d661aSToomas Soome { 1264a5d661aSToomas Soome __asm __volatile("cli" : : : "memory"); 1274a5d661aSToomas Soome } 1284a5d661aSToomas Soome 1294a5d661aSToomas Soome static __inline void 1304a5d661aSToomas Soome do_cpuid(u_int ax, u_int *p) 1314a5d661aSToomas Soome { 1324a5d661aSToomas Soome __asm __volatile("cpuid" 1334a5d661aSToomas Soome : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) 1344a5d661aSToomas Soome : "0" (ax)); 1354a5d661aSToomas Soome } 1364a5d661aSToomas Soome 1374a5d661aSToomas Soome static __inline void 1384a5d661aSToomas Soome cpuid_count(u_int ax, u_int cx, u_int *p) 1394a5d661aSToomas Soome { 1404a5d661aSToomas Soome __asm __volatile("cpuid" 1414a5d661aSToomas Soome : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) 1424a5d661aSToomas Soome : "0" (ax), "c" (cx)); 1434a5d661aSToomas Soome } 1444a5d661aSToomas Soome 1454a5d661aSToomas Soome static __inline void 1464a5d661aSToomas Soome enable_intr(void) 1474a5d661aSToomas Soome { 1484a5d661aSToomas Soome __asm __volatile("sti"); 1494a5d661aSToomas Soome } 1504a5d661aSToomas Soome 1514a5d661aSToomas Soome #ifdef _KERNEL 1524a5d661aSToomas Soome 1534a5d661aSToomas Soome #define HAVE_INLINE_FFS 1544a5d661aSToomas Soome #define ffs(x) __builtin_ffs(x) 1554a5d661aSToomas Soome 1564a5d661aSToomas Soome #define HAVE_INLINE_FFSL 1574a5d661aSToomas Soome 1584a5d661aSToomas Soome static __inline int 1594a5d661aSToomas Soome ffsl(long mask) 1604a5d661aSToomas Soome { 1614a5d661aSToomas Soome return (mask == 0 ? mask : (int)bsfq((u_long)mask) + 1); 1624a5d661aSToomas Soome } 1634a5d661aSToomas Soome 1644a5d661aSToomas Soome #define HAVE_INLINE_FFSLL 1654a5d661aSToomas Soome 1664a5d661aSToomas Soome static __inline int 1674a5d661aSToomas Soome ffsll(long long mask) 1684a5d661aSToomas Soome { 1694a5d661aSToomas Soome return (ffsl((long)mask)); 1704a5d661aSToomas Soome } 1714a5d661aSToomas Soome 1724a5d661aSToomas Soome #define HAVE_INLINE_FLS 1734a5d661aSToomas Soome 1744a5d661aSToomas Soome static __inline int 1754a5d661aSToomas Soome fls(int mask) 1764a5d661aSToomas Soome { 1774a5d661aSToomas Soome return (mask == 0 ? mask : (int)bsrl((u_int)mask) + 1); 1784a5d661aSToomas Soome } 1794a5d661aSToomas Soome 1804a5d661aSToomas Soome #define HAVE_INLINE_FLSL 1814a5d661aSToomas Soome 1824a5d661aSToomas Soome static __inline int 1834a5d661aSToomas Soome flsl(long mask) 1844a5d661aSToomas Soome { 1854a5d661aSToomas Soome return (mask == 0 ? mask : (int)bsrq((u_long)mask) + 1); 1864a5d661aSToomas Soome } 1874a5d661aSToomas Soome 1884a5d661aSToomas Soome #define HAVE_INLINE_FLSLL 1894a5d661aSToomas Soome 1904a5d661aSToomas Soome static __inline int 1914a5d661aSToomas Soome flsll(long long mask) 1924a5d661aSToomas Soome { 1934a5d661aSToomas Soome return (flsl((long)mask)); 1944a5d661aSToomas Soome } 1954a5d661aSToomas Soome 1964a5d661aSToomas Soome #endif /* _KERNEL */ 1974a5d661aSToomas Soome 1984a5d661aSToomas Soome static __inline void 1994a5d661aSToomas Soome halt(void) 2004a5d661aSToomas Soome { 2014a5d661aSToomas Soome __asm __volatile("hlt"); 2024a5d661aSToomas Soome } 2034a5d661aSToomas Soome 2044a5d661aSToomas Soome static __inline u_char 2054a5d661aSToomas Soome inb(u_int port) 2064a5d661aSToomas Soome { 2074a5d661aSToomas Soome u_char data; 2084a5d661aSToomas Soome 2094a5d661aSToomas Soome __asm __volatile("inb %w1, %0" : "=a" (data) : "Nd" (port)); 2104a5d661aSToomas Soome return (data); 2114a5d661aSToomas Soome } 2124a5d661aSToomas Soome 2134a5d661aSToomas Soome static __inline u_int 2144a5d661aSToomas Soome inl(u_int port) 2154a5d661aSToomas Soome { 2164a5d661aSToomas Soome u_int data; 2174a5d661aSToomas Soome 2184a5d661aSToomas Soome __asm __volatile("inl %w1, %0" : "=a" (data) : "Nd" (port)); 2194a5d661aSToomas Soome return (data); 2204a5d661aSToomas Soome } 2214a5d661aSToomas Soome 2224a5d661aSToomas Soome static __inline void 2234a5d661aSToomas Soome insb(u_int port, void *addr, size_t count) 2244a5d661aSToomas Soome { 2254a5d661aSToomas Soome __asm __volatile("cld; rep; insb" 2264a5d661aSToomas Soome : "+D" (addr), "+c" (count) 2274a5d661aSToomas Soome : "d" (port) 2284a5d661aSToomas Soome : "memory"); 2294a5d661aSToomas Soome } 2304a5d661aSToomas Soome 2314a5d661aSToomas Soome static __inline void 2324a5d661aSToomas Soome insw(u_int port, void *addr, size_t count) 2334a5d661aSToomas Soome { 2344a5d661aSToomas Soome __asm __volatile("cld; rep; insw" 2354a5d661aSToomas Soome : "+D" (addr), "+c" (count) 2364a5d661aSToomas Soome : "d" (port) 2374a5d661aSToomas Soome : "memory"); 2384a5d661aSToomas Soome } 2394a5d661aSToomas Soome 2404a5d661aSToomas Soome static __inline void 2414a5d661aSToomas Soome insl(u_int port, void *addr, size_t count) 2424a5d661aSToomas Soome { 2434a5d661aSToomas Soome __asm __volatile("cld; rep; insl" 2444a5d661aSToomas Soome : "+D" (addr), "+c" (count) 2454a5d661aSToomas Soome : "d" (port) 2464a5d661aSToomas Soome : "memory"); 2474a5d661aSToomas Soome } 2484a5d661aSToomas Soome 2494a5d661aSToomas Soome static __inline void 2504a5d661aSToomas Soome invd(void) 2514a5d661aSToomas Soome { 2524a5d661aSToomas Soome __asm __volatile("invd"); 2534a5d661aSToomas Soome } 2544a5d661aSToomas Soome 2554a5d661aSToomas Soome static __inline u_short 2564a5d661aSToomas Soome inw(u_int port) 2574a5d661aSToomas Soome { 2584a5d661aSToomas Soome u_short data; 2594a5d661aSToomas Soome 2604a5d661aSToomas Soome __asm __volatile("inw %w1, %0" : "=a" (data) : "Nd" (port)); 2614a5d661aSToomas Soome return (data); 2624a5d661aSToomas Soome } 2634a5d661aSToomas Soome 2644a5d661aSToomas Soome static __inline void 2654a5d661aSToomas Soome outb(u_int port, u_char data) 2664a5d661aSToomas Soome { 2674a5d661aSToomas Soome __asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port)); 2684a5d661aSToomas Soome } 2694a5d661aSToomas Soome 2704a5d661aSToomas Soome static __inline void 2714a5d661aSToomas Soome outl(u_int port, u_int data) 2724a5d661aSToomas Soome { 2734a5d661aSToomas Soome __asm __volatile("outl %0, %w1" : : "a" (data), "Nd" (port)); 2744a5d661aSToomas Soome } 2754a5d661aSToomas Soome 2764a5d661aSToomas Soome static __inline void 2774a5d661aSToomas Soome outsb(u_int port, const void *addr, size_t count) 2784a5d661aSToomas Soome { 2794a5d661aSToomas Soome __asm __volatile("cld; rep; outsb" 2804a5d661aSToomas Soome : "+S" (addr), "+c" (count) 2814a5d661aSToomas Soome : "d" (port)); 2824a5d661aSToomas Soome } 2834a5d661aSToomas Soome 2844a5d661aSToomas Soome static __inline void 2854a5d661aSToomas Soome outsw(u_int port, const void *addr, size_t count) 2864a5d661aSToomas Soome { 2874a5d661aSToomas Soome __asm __volatile("cld; rep; outsw" 2884a5d661aSToomas Soome : "+S" (addr), "+c" (count) 2894a5d661aSToomas Soome : "d" (port)); 2904a5d661aSToomas Soome } 2914a5d661aSToomas Soome 2924a5d661aSToomas Soome static __inline void 2934a5d661aSToomas Soome outsl(u_int port, const void *addr, size_t count) 2944a5d661aSToomas Soome { 2954a5d661aSToomas Soome __asm __volatile("cld; rep; outsl" 2964a5d661aSToomas Soome : "+S" (addr), "+c" (count) 2974a5d661aSToomas Soome : "d" (port)); 2984a5d661aSToomas Soome } 2994a5d661aSToomas Soome 3004a5d661aSToomas Soome static __inline void 3014a5d661aSToomas Soome outw(u_int port, u_short data) 3024a5d661aSToomas Soome { 3034a5d661aSToomas Soome __asm __volatile("outw %0, %w1" : : "a" (data), "Nd" (port)); 3044a5d661aSToomas Soome } 3054a5d661aSToomas Soome 3064a5d661aSToomas Soome static __inline u_long 3074a5d661aSToomas Soome popcntq(u_long mask) 3084a5d661aSToomas Soome { 3094a5d661aSToomas Soome u_long result; 3104a5d661aSToomas Soome 3114a5d661aSToomas Soome __asm __volatile("popcntq %1,%0" : "=r" (result) : "rm" (mask)); 3124a5d661aSToomas Soome return (result); 3134a5d661aSToomas Soome } 3144a5d661aSToomas Soome 3154a5d661aSToomas Soome static __inline void 3164a5d661aSToomas Soome lfence(void) 3174a5d661aSToomas Soome { 3184a5d661aSToomas Soome 3194a5d661aSToomas Soome __asm __volatile("lfence" : : : "memory"); 3204a5d661aSToomas Soome } 3214a5d661aSToomas Soome 3224a5d661aSToomas Soome static __inline void 3234a5d661aSToomas Soome mfence(void) 3244a5d661aSToomas Soome { 3254a5d661aSToomas Soome 3264a5d661aSToomas Soome __asm __volatile("mfence" : : : "memory"); 3274a5d661aSToomas Soome } 3284a5d661aSToomas Soome 3294a5d661aSToomas Soome static __inline void 330*8ede9625SToomas Soome sfence(void) 331*8ede9625SToomas Soome { 332*8ede9625SToomas Soome 333*8ede9625SToomas Soome __asm __volatile("sfence" : : : "memory"); 334*8ede9625SToomas Soome } 335*8ede9625SToomas Soome 336*8ede9625SToomas Soome static __inline void 3374a5d661aSToomas Soome ia32_pause(void) 3384a5d661aSToomas Soome { 3394a5d661aSToomas Soome __asm __volatile("pause"); 3404a5d661aSToomas Soome } 3414a5d661aSToomas Soome 3424a5d661aSToomas Soome static __inline u_long 3434a5d661aSToomas Soome read_rflags(void) 3444a5d661aSToomas Soome { 3454a5d661aSToomas Soome u_long rf; 3464a5d661aSToomas Soome 3474a5d661aSToomas Soome __asm __volatile("pushfq; popq %0" : "=r" (rf)); 3484a5d661aSToomas Soome return (rf); 3494a5d661aSToomas Soome } 3504a5d661aSToomas Soome 3514a5d661aSToomas Soome static __inline uint64_t 3524a5d661aSToomas Soome rdmsr(u_int msr) 3534a5d661aSToomas Soome { 3544a5d661aSToomas Soome uint32_t low, high; 3554a5d661aSToomas Soome 3564a5d661aSToomas Soome __asm __volatile("rdmsr" : "=a" (low), "=d" (high) : "c" (msr)); 3574a5d661aSToomas Soome return (low | ((uint64_t)high << 32)); 3584a5d661aSToomas Soome } 3594a5d661aSToomas Soome 3604a5d661aSToomas Soome static __inline uint32_t 3614a5d661aSToomas Soome rdmsr32(u_int msr) 3624a5d661aSToomas Soome { 3634a5d661aSToomas Soome uint32_t low; 3644a5d661aSToomas Soome 3654a5d661aSToomas Soome __asm __volatile("rdmsr" : "=a" (low) : "c" (msr) : "rdx"); 3664a5d661aSToomas Soome return (low); 3674a5d661aSToomas Soome } 3684a5d661aSToomas Soome 3694a5d661aSToomas Soome static __inline uint64_t 3704a5d661aSToomas Soome rdpmc(u_int pmc) 3714a5d661aSToomas Soome { 3724a5d661aSToomas Soome uint32_t low, high; 3734a5d661aSToomas Soome 3744a5d661aSToomas Soome __asm __volatile("rdpmc" : "=a" (low), "=d" (high) : "c" (pmc)); 3754a5d661aSToomas Soome return (low | ((uint64_t)high << 32)); 3764a5d661aSToomas Soome } 3774a5d661aSToomas Soome 3784a5d661aSToomas Soome static __inline uint64_t 3794a5d661aSToomas Soome rdtsc(void) 3804a5d661aSToomas Soome { 3814a5d661aSToomas Soome uint32_t low, high; 3824a5d661aSToomas Soome 3834a5d661aSToomas Soome __asm __volatile("rdtsc" : "=a" (low), "=d" (high)); 3844a5d661aSToomas Soome return (low | ((uint64_t)high << 32)); 3854a5d661aSToomas Soome } 3864a5d661aSToomas Soome 3874a5d661aSToomas Soome static __inline uint32_t 3884a5d661aSToomas Soome rdtsc32(void) 3894a5d661aSToomas Soome { 3904a5d661aSToomas Soome uint32_t rv; 3914a5d661aSToomas Soome 3924a5d661aSToomas Soome __asm __volatile("rdtsc" : "=a" (rv) : : "edx"); 3934a5d661aSToomas Soome return (rv); 3944a5d661aSToomas Soome } 3954a5d661aSToomas Soome 3964a5d661aSToomas Soome static __inline void 3974a5d661aSToomas Soome wbinvd(void) 3984a5d661aSToomas Soome { 3994a5d661aSToomas Soome __asm __volatile("wbinvd"); 4004a5d661aSToomas Soome } 4014a5d661aSToomas Soome 4024a5d661aSToomas Soome static __inline void 4034a5d661aSToomas Soome write_rflags(u_long rf) 4044a5d661aSToomas Soome { 4054a5d661aSToomas Soome __asm __volatile("pushq %0; popfq" : : "r" (rf)); 4064a5d661aSToomas Soome } 4074a5d661aSToomas Soome 4084a5d661aSToomas Soome static __inline void 4094a5d661aSToomas Soome wrmsr(u_int msr, uint64_t newval) 4104a5d661aSToomas Soome { 4114a5d661aSToomas Soome uint32_t low, high; 4124a5d661aSToomas Soome 4134a5d661aSToomas Soome low = newval; 4144a5d661aSToomas Soome high = newval >> 32; 4154a5d661aSToomas Soome __asm __volatile("wrmsr" : : "a" (low), "d" (high), "c" (msr)); 4164a5d661aSToomas Soome } 4174a5d661aSToomas Soome 4184a5d661aSToomas Soome static __inline void 4194a5d661aSToomas Soome load_cr0(u_long data) 4204a5d661aSToomas Soome { 4214a5d661aSToomas Soome 4224a5d661aSToomas Soome __asm __volatile("movq %0,%%cr0" : : "r" (data)); 4234a5d661aSToomas Soome } 4244a5d661aSToomas Soome 4254a5d661aSToomas Soome static __inline u_long 4264a5d661aSToomas Soome rcr0(void) 4274a5d661aSToomas Soome { 4284a5d661aSToomas Soome u_long data; 4294a5d661aSToomas Soome 4304a5d661aSToomas Soome __asm __volatile("movq %%cr0,%0" : "=r" (data)); 4314a5d661aSToomas Soome return (data); 4324a5d661aSToomas Soome } 4334a5d661aSToomas Soome 4344a5d661aSToomas Soome static __inline u_long 4354a5d661aSToomas Soome rcr2(void) 4364a5d661aSToomas Soome { 4374a5d661aSToomas Soome u_long data; 4384a5d661aSToomas Soome 4394a5d661aSToomas Soome __asm __volatile("movq %%cr2,%0" : "=r" (data)); 4404a5d661aSToomas Soome return (data); 4414a5d661aSToomas Soome } 4424a5d661aSToomas Soome 4434a5d661aSToomas Soome static __inline void 4444a5d661aSToomas Soome load_cr3(u_long data) 4454a5d661aSToomas Soome { 4464a5d661aSToomas Soome 4474a5d661aSToomas Soome __asm __volatile("movq %0,%%cr3" : : "r" (data) : "memory"); 4484a5d661aSToomas Soome } 4494a5d661aSToomas Soome 4504a5d661aSToomas Soome static __inline u_long 4514a5d661aSToomas Soome rcr3(void) 4524a5d661aSToomas Soome { 4534a5d661aSToomas Soome u_long data; 4544a5d661aSToomas Soome 4554a5d661aSToomas Soome __asm __volatile("movq %%cr3,%0" : "=r" (data)); 4564a5d661aSToomas Soome return (data); 4574a5d661aSToomas Soome } 4584a5d661aSToomas Soome 4594a5d661aSToomas Soome static __inline void 4604a5d661aSToomas Soome load_cr4(u_long data) 4614a5d661aSToomas Soome { 4624a5d661aSToomas Soome __asm __volatile("movq %0,%%cr4" : : "r" (data)); 4634a5d661aSToomas Soome } 4644a5d661aSToomas Soome 4654a5d661aSToomas Soome static __inline u_long 4664a5d661aSToomas Soome rcr4(void) 4674a5d661aSToomas Soome { 4684a5d661aSToomas Soome u_long data; 4694a5d661aSToomas Soome 4704a5d661aSToomas Soome __asm __volatile("movq %%cr4,%0" : "=r" (data)); 4714a5d661aSToomas Soome return (data); 4724a5d661aSToomas Soome } 4734a5d661aSToomas Soome 4744a5d661aSToomas Soome static __inline u_long 4754a5d661aSToomas Soome rxcr(u_int reg) 4764a5d661aSToomas Soome { 4774a5d661aSToomas Soome u_int low, high; 4784a5d661aSToomas Soome 4794a5d661aSToomas Soome __asm __volatile("xgetbv" : "=a" (low), "=d" (high) : "c" (reg)); 4804a5d661aSToomas Soome return (low | ((uint64_t)high << 32)); 4814a5d661aSToomas Soome } 4824a5d661aSToomas Soome 4834a5d661aSToomas Soome static __inline void 4844a5d661aSToomas Soome load_xcr(u_int reg, u_long val) 4854a5d661aSToomas Soome { 4864a5d661aSToomas Soome u_int low, high; 4874a5d661aSToomas Soome 4884a5d661aSToomas Soome low = val; 4894a5d661aSToomas Soome high = val >> 32; 4904a5d661aSToomas Soome __asm __volatile("xsetbv" : : "c" (reg), "a" (low), "d" (high)); 4914a5d661aSToomas Soome } 4924a5d661aSToomas Soome 4934a5d661aSToomas Soome /* 4944a5d661aSToomas Soome * Global TLB flush (except for thise for pages marked PG_G) 4954a5d661aSToomas Soome */ 4964a5d661aSToomas Soome static __inline void 4974a5d661aSToomas Soome invltlb(void) 4984a5d661aSToomas Soome { 4994a5d661aSToomas Soome 5004a5d661aSToomas Soome load_cr3(rcr3()); 5014a5d661aSToomas Soome } 5024a5d661aSToomas Soome 5034a5d661aSToomas Soome #ifndef CR4_PGE 5044a5d661aSToomas Soome #define CR4_PGE 0x00000080 /* Page global enable */ 5054a5d661aSToomas Soome #endif 5064a5d661aSToomas Soome 5074a5d661aSToomas Soome /* 5084a5d661aSToomas Soome * Perform the guaranteed invalidation of all TLB entries. This 5094a5d661aSToomas Soome * includes the global entries, and entries in all PCIDs, not only the 5104a5d661aSToomas Soome * current context. The function works both on non-PCID CPUs and CPUs 5114a5d661aSToomas Soome * with the PCID turned off or on. See IA-32 SDM Vol. 3a 4.10.4.1 5124a5d661aSToomas Soome * Operations that Invalidate TLBs and Paging-Structure Caches. 5134a5d661aSToomas Soome */ 5144a5d661aSToomas Soome static __inline void 5154a5d661aSToomas Soome invltlb_glob(void) 5164a5d661aSToomas Soome { 5174a5d661aSToomas Soome uint64_t cr4; 5184a5d661aSToomas Soome 5194a5d661aSToomas Soome cr4 = rcr4(); 5204a5d661aSToomas Soome load_cr4(cr4 & ~CR4_PGE); 5214a5d661aSToomas Soome /* 5224a5d661aSToomas Soome * Although preemption at this point could be detrimental to 5234a5d661aSToomas Soome * performance, it would not lead to an error. PG_G is simply 5244a5d661aSToomas Soome * ignored if CR4.PGE is clear. Moreover, in case this block 5254a5d661aSToomas Soome * is re-entered, the load_cr4() either above or below will 5264a5d661aSToomas Soome * modify CR4.PGE flushing the TLB. 5274a5d661aSToomas Soome */ 5284a5d661aSToomas Soome load_cr4(cr4 | CR4_PGE); 5294a5d661aSToomas Soome } 5304a5d661aSToomas Soome 5314a5d661aSToomas Soome /* 5324a5d661aSToomas Soome * TLB flush for an individual page (even if it has PG_G). 5334a5d661aSToomas Soome * Only works on 486+ CPUs (i386 does not have PG_G). 5344a5d661aSToomas Soome */ 5354a5d661aSToomas Soome static __inline void 5364a5d661aSToomas Soome invlpg(u_long addr) 5374a5d661aSToomas Soome { 5384a5d661aSToomas Soome 5394a5d661aSToomas Soome __asm __volatile("invlpg %0" : : "m" (*(char *)addr) : "memory"); 5404a5d661aSToomas Soome } 5414a5d661aSToomas Soome 5424a5d661aSToomas Soome #define INVPCID_ADDR 0 5434a5d661aSToomas Soome #define INVPCID_CTX 1 5444a5d661aSToomas Soome #define INVPCID_CTXGLOB 2 5454a5d661aSToomas Soome #define INVPCID_ALLCTX 3 5464a5d661aSToomas Soome 5474a5d661aSToomas Soome struct invpcid_descr { 5484a5d661aSToomas Soome uint64_t pcid:12 __packed; 5494a5d661aSToomas Soome uint64_t pad:52 __packed; 5504a5d661aSToomas Soome uint64_t addr; 5514a5d661aSToomas Soome } __packed; 5524a5d661aSToomas Soome 5534a5d661aSToomas Soome static __inline void 5544a5d661aSToomas Soome invpcid(struct invpcid_descr *d, int type) 5554a5d661aSToomas Soome { 5564a5d661aSToomas Soome 5574a5d661aSToomas Soome __asm __volatile("invpcid (%0),%1" 5584a5d661aSToomas Soome : : "r" (d), "r" ((u_long)type) : "memory"); 5594a5d661aSToomas Soome } 5604a5d661aSToomas Soome 5614a5d661aSToomas Soome static __inline u_short 5624a5d661aSToomas Soome rfs(void) 5634a5d661aSToomas Soome { 5644a5d661aSToomas Soome u_short sel; 5654a5d661aSToomas Soome __asm __volatile("movw %%fs,%0" : "=rm" (sel)); 5664a5d661aSToomas Soome return (sel); 5674a5d661aSToomas Soome } 5684a5d661aSToomas Soome 5694a5d661aSToomas Soome static __inline u_short 5704a5d661aSToomas Soome rgs(void) 5714a5d661aSToomas Soome { 5724a5d661aSToomas Soome u_short sel; 5734a5d661aSToomas Soome __asm __volatile("movw %%gs,%0" : "=rm" (sel)); 5744a5d661aSToomas Soome return (sel); 5754a5d661aSToomas Soome } 5764a5d661aSToomas Soome 5774a5d661aSToomas Soome static __inline u_short 5784a5d661aSToomas Soome rss(void) 5794a5d661aSToomas Soome { 5804a5d661aSToomas Soome u_short sel; 5814a5d661aSToomas Soome __asm __volatile("movw %%ss,%0" : "=rm" (sel)); 5824a5d661aSToomas Soome return (sel); 5834a5d661aSToomas Soome } 5844a5d661aSToomas Soome 5854a5d661aSToomas Soome static __inline void 5864a5d661aSToomas Soome load_ds(u_short sel) 5874a5d661aSToomas Soome { 5884a5d661aSToomas Soome __asm __volatile("movw %0,%%ds" : : "rm" (sel)); 5894a5d661aSToomas Soome } 5904a5d661aSToomas Soome 5914a5d661aSToomas Soome static __inline void 5924a5d661aSToomas Soome load_es(u_short sel) 5934a5d661aSToomas Soome { 5944a5d661aSToomas Soome __asm __volatile("movw %0,%%es" : : "rm" (sel)); 5954a5d661aSToomas Soome } 5964a5d661aSToomas Soome 5974a5d661aSToomas Soome static __inline void 5984a5d661aSToomas Soome cpu_monitor(const void *addr, u_long extensions, u_int hints) 5994a5d661aSToomas Soome { 6004a5d661aSToomas Soome 6014a5d661aSToomas Soome __asm __volatile("monitor" 6024a5d661aSToomas Soome : : "a" (addr), "c" (extensions), "d" (hints)); 6034a5d661aSToomas Soome } 6044a5d661aSToomas Soome 6054a5d661aSToomas Soome static __inline void 6064a5d661aSToomas Soome cpu_mwait(u_long extensions, u_int hints) 6074a5d661aSToomas Soome { 6084a5d661aSToomas Soome 6094a5d661aSToomas Soome __asm __volatile("mwait" : : "a" (hints), "c" (extensions)); 6104a5d661aSToomas Soome } 6114a5d661aSToomas Soome 6124a5d661aSToomas Soome #ifdef _KERNEL 6134a5d661aSToomas Soome /* This is defined in <machine/specialreg.h> but is too painful to get to */ 6144a5d661aSToomas Soome #ifndef MSR_FSBASE 6154a5d661aSToomas Soome #define MSR_FSBASE 0xc0000100 6164a5d661aSToomas Soome #endif 6174a5d661aSToomas Soome static __inline void 6184a5d661aSToomas Soome load_fs(u_short sel) 6194a5d661aSToomas Soome { 6204a5d661aSToomas Soome /* Preserve the fsbase value across the selector load */ 6214a5d661aSToomas Soome __asm __volatile("rdmsr; movw %0,%%fs; wrmsr" 6224a5d661aSToomas Soome : : "rm" (sel), "c" (MSR_FSBASE) : "eax", "edx"); 6234a5d661aSToomas Soome } 6244a5d661aSToomas Soome 6254a5d661aSToomas Soome #ifndef MSR_GSBASE 6264a5d661aSToomas Soome #define MSR_GSBASE 0xc0000101 6274a5d661aSToomas Soome #endif 6284a5d661aSToomas Soome static __inline void 6294a5d661aSToomas Soome load_gs(u_short sel) 6304a5d661aSToomas Soome { 6314a5d661aSToomas Soome /* 6324a5d661aSToomas Soome * Preserve the gsbase value across the selector load. 6334a5d661aSToomas Soome * Note that we have to disable interrupts because the gsbase 6344a5d661aSToomas Soome * being trashed happens to be the kernel gsbase at the time. 6354a5d661aSToomas Soome */ 6364a5d661aSToomas Soome __asm __volatile("pushfq; cli; rdmsr; movw %0,%%gs; wrmsr; popfq" 6374a5d661aSToomas Soome : : "rm" (sel), "c" (MSR_GSBASE) : "eax", "edx"); 6384a5d661aSToomas Soome } 6394a5d661aSToomas Soome #else 6404a5d661aSToomas Soome /* Usable by userland */ 6414a5d661aSToomas Soome static __inline void 6424a5d661aSToomas Soome load_fs(u_short sel) 6434a5d661aSToomas Soome { 6444a5d661aSToomas Soome __asm __volatile("movw %0,%%fs" : : "rm" (sel)); 6454a5d661aSToomas Soome } 6464a5d661aSToomas Soome 6474a5d661aSToomas Soome static __inline void 6484a5d661aSToomas Soome load_gs(u_short sel) 6494a5d661aSToomas Soome { 6504a5d661aSToomas Soome __asm __volatile("movw %0,%%gs" : : "rm" (sel)); 6514a5d661aSToomas Soome } 6524a5d661aSToomas Soome #endif 6534a5d661aSToomas Soome 6544a5d661aSToomas Soome static __inline void 655*8ede9625SToomas Soome bare_lgdt(struct region_descriptor *addr) 656*8ede9625SToomas Soome { 657*8ede9625SToomas Soome __asm __volatile("lgdt (%0)" : : "r" (addr)); 658*8ede9625SToomas Soome } 659*8ede9625SToomas Soome 660*8ede9625SToomas Soome static __inline void 661*8ede9625SToomas Soome sgdt(struct region_descriptor *addr) 662*8ede9625SToomas Soome { 663*8ede9625SToomas Soome char *loc; 664*8ede9625SToomas Soome 665*8ede9625SToomas Soome loc = (char *)addr; 666*8ede9625SToomas Soome __asm __volatile("sgdt %0" : "=m" (*loc) : : "memory"); 667*8ede9625SToomas Soome } 668*8ede9625SToomas Soome 669*8ede9625SToomas Soome static __inline void 6704a5d661aSToomas Soome lidt(struct region_descriptor *addr) 6714a5d661aSToomas Soome { 6724a5d661aSToomas Soome __asm __volatile("lidt (%0)" : : "r" (addr)); 6734a5d661aSToomas Soome } 6744a5d661aSToomas Soome 6754a5d661aSToomas Soome static __inline void 676*8ede9625SToomas Soome sidt(struct region_descriptor *addr) 677*8ede9625SToomas Soome { 678*8ede9625SToomas Soome char *loc; 679*8ede9625SToomas Soome 680*8ede9625SToomas Soome loc = (char *)addr; 681*8ede9625SToomas Soome __asm __volatile("sidt %0" : "=m" (*loc) : : "memory"); 682*8ede9625SToomas Soome } 683*8ede9625SToomas Soome 684*8ede9625SToomas Soome static __inline void 6854a5d661aSToomas Soome lldt(u_short sel) 6864a5d661aSToomas Soome { 6874a5d661aSToomas Soome __asm __volatile("lldt %0" : : "r" (sel)); 6884a5d661aSToomas Soome } 6894a5d661aSToomas Soome 6904a5d661aSToomas Soome static __inline void 6914a5d661aSToomas Soome ltr(u_short sel) 6924a5d661aSToomas Soome { 6934a5d661aSToomas Soome __asm __volatile("ltr %0" : : "r" (sel)); 6944a5d661aSToomas Soome } 6954a5d661aSToomas Soome 696*8ede9625SToomas Soome static __inline uint32_t 697*8ede9625SToomas Soome read_tr(void) 698*8ede9625SToomas Soome { 699*8ede9625SToomas Soome u_short sel; 700*8ede9625SToomas Soome 701*8ede9625SToomas Soome __asm __volatile("str %0" : "=r" (sel)); 702*8ede9625SToomas Soome return (sel); 703*8ede9625SToomas Soome } 704*8ede9625SToomas Soome 7054a5d661aSToomas Soome static __inline uint64_t 7064a5d661aSToomas Soome rdr0(void) 7074a5d661aSToomas Soome { 7084a5d661aSToomas Soome uint64_t data; 7094a5d661aSToomas Soome __asm __volatile("movq %%dr0,%0" : "=r" (data)); 7104a5d661aSToomas Soome return (data); 7114a5d661aSToomas Soome } 7124a5d661aSToomas Soome 7134a5d661aSToomas Soome static __inline void 7144a5d661aSToomas Soome load_dr0(uint64_t dr0) 7154a5d661aSToomas Soome { 7164a5d661aSToomas Soome __asm __volatile("movq %0,%%dr0" : : "r" (dr0)); 7174a5d661aSToomas Soome } 7184a5d661aSToomas Soome 7194a5d661aSToomas Soome static __inline uint64_t 7204a5d661aSToomas Soome rdr1(void) 7214a5d661aSToomas Soome { 7224a5d661aSToomas Soome uint64_t data; 7234a5d661aSToomas Soome __asm __volatile("movq %%dr1,%0" : "=r" (data)); 7244a5d661aSToomas Soome return (data); 7254a5d661aSToomas Soome } 7264a5d661aSToomas Soome 7274a5d661aSToomas Soome static __inline void 7284a5d661aSToomas Soome load_dr1(uint64_t dr1) 7294a5d661aSToomas Soome { 7304a5d661aSToomas Soome __asm __volatile("movq %0,%%dr1" : : "r" (dr1)); 7314a5d661aSToomas Soome } 7324a5d661aSToomas Soome 7334a5d661aSToomas Soome static __inline uint64_t 7344a5d661aSToomas Soome rdr2(void) 7354a5d661aSToomas Soome { 7364a5d661aSToomas Soome uint64_t data; 7374a5d661aSToomas Soome __asm __volatile("movq %%dr2,%0" : "=r" (data)); 7384a5d661aSToomas Soome return (data); 7394a5d661aSToomas Soome } 7404a5d661aSToomas Soome 7414a5d661aSToomas Soome static __inline void 7424a5d661aSToomas Soome load_dr2(uint64_t dr2) 7434a5d661aSToomas Soome { 7444a5d661aSToomas Soome __asm __volatile("movq %0,%%dr2" : : "r" (dr2)); 7454a5d661aSToomas Soome } 7464a5d661aSToomas Soome 7474a5d661aSToomas Soome static __inline uint64_t 7484a5d661aSToomas Soome rdr3(void) 7494a5d661aSToomas Soome { 7504a5d661aSToomas Soome uint64_t data; 7514a5d661aSToomas Soome __asm __volatile("movq %%dr3,%0" : "=r" (data)); 7524a5d661aSToomas Soome return (data); 7534a5d661aSToomas Soome } 7544a5d661aSToomas Soome 7554a5d661aSToomas Soome static __inline void 7564a5d661aSToomas Soome load_dr3(uint64_t dr3) 7574a5d661aSToomas Soome { 7584a5d661aSToomas Soome __asm __volatile("movq %0,%%dr3" : : "r" (dr3)); 7594a5d661aSToomas Soome } 7604a5d661aSToomas Soome 7614a5d661aSToomas Soome static __inline uint64_t 7624a5d661aSToomas Soome rdr6(void) 7634a5d661aSToomas Soome { 7644a5d661aSToomas Soome uint64_t data; 7654a5d661aSToomas Soome __asm __volatile("movq %%dr6,%0" : "=r" (data)); 7664a5d661aSToomas Soome return (data); 7674a5d661aSToomas Soome } 7684a5d661aSToomas Soome 7694a5d661aSToomas Soome static __inline void 7704a5d661aSToomas Soome load_dr6(uint64_t dr6) 7714a5d661aSToomas Soome { 7724a5d661aSToomas Soome __asm __volatile("movq %0,%%dr6" : : "r" (dr6)); 7734a5d661aSToomas Soome } 7744a5d661aSToomas Soome 7754a5d661aSToomas Soome static __inline uint64_t 7764a5d661aSToomas Soome rdr7(void) 7774a5d661aSToomas Soome { 7784a5d661aSToomas Soome uint64_t data; 7794a5d661aSToomas Soome __asm __volatile("movq %%dr7,%0" : "=r" (data)); 7804a5d661aSToomas Soome return (data); 7814a5d661aSToomas Soome } 7824a5d661aSToomas Soome 7834a5d661aSToomas Soome static __inline void 7844a5d661aSToomas Soome load_dr7(uint64_t dr7) 7854a5d661aSToomas Soome { 7864a5d661aSToomas Soome __asm __volatile("movq %0,%%dr7" : : "r" (dr7)); 7874a5d661aSToomas Soome } 7884a5d661aSToomas Soome 7894a5d661aSToomas Soome static __inline register_t 7904a5d661aSToomas Soome intr_disable(void) 7914a5d661aSToomas Soome { 7924a5d661aSToomas Soome register_t rflags; 7934a5d661aSToomas Soome 7944a5d661aSToomas Soome rflags = read_rflags(); 7954a5d661aSToomas Soome disable_intr(); 7964a5d661aSToomas Soome return (rflags); 7974a5d661aSToomas Soome } 7984a5d661aSToomas Soome 7994a5d661aSToomas Soome static __inline void 8004a5d661aSToomas Soome intr_restore(register_t rflags) 8014a5d661aSToomas Soome { 8024a5d661aSToomas Soome write_rflags(rflags); 8034a5d661aSToomas Soome } 8044a5d661aSToomas Soome 8054a5d661aSToomas Soome #else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */ 8064a5d661aSToomas Soome 8074a5d661aSToomas Soome int breakpoint(void); 8084a5d661aSToomas Soome u_int bsfl(u_int mask); 8094a5d661aSToomas Soome u_int bsrl(u_int mask); 8104a5d661aSToomas Soome void clflush(u_long addr); 8114a5d661aSToomas Soome void clts(void); 8124a5d661aSToomas Soome void cpuid_count(u_int ax, u_int cx, u_int *p); 8134a5d661aSToomas Soome void disable_intr(void); 8144a5d661aSToomas Soome void do_cpuid(u_int ax, u_int *p); 8154a5d661aSToomas Soome void enable_intr(void); 8164a5d661aSToomas Soome void halt(void); 8174a5d661aSToomas Soome void ia32_pause(void); 8184a5d661aSToomas Soome u_char inb(u_int port); 8194a5d661aSToomas Soome u_int inl(u_int port); 8204a5d661aSToomas Soome void insb(u_int port, void *addr, size_t count); 8214a5d661aSToomas Soome void insl(u_int port, void *addr, size_t count); 8224a5d661aSToomas Soome void insw(u_int port, void *addr, size_t count); 8234a5d661aSToomas Soome register_t intr_disable(void); 8244a5d661aSToomas Soome void intr_restore(register_t rf); 8254a5d661aSToomas Soome void invd(void); 8264a5d661aSToomas Soome void invlpg(u_int addr); 8274a5d661aSToomas Soome void invltlb(void); 8284a5d661aSToomas Soome u_short inw(u_int port); 8294a5d661aSToomas Soome void lidt(struct region_descriptor *addr); 8304a5d661aSToomas Soome void lldt(u_short sel); 8314a5d661aSToomas Soome void load_cr0(u_long cr0); 8324a5d661aSToomas Soome void load_cr3(u_long cr3); 8334a5d661aSToomas Soome void load_cr4(u_long cr4); 8344a5d661aSToomas Soome void load_dr0(uint64_t dr0); 8354a5d661aSToomas Soome void load_dr1(uint64_t dr1); 8364a5d661aSToomas Soome void load_dr2(uint64_t dr2); 8374a5d661aSToomas Soome void load_dr3(uint64_t dr3); 8384a5d661aSToomas Soome void load_dr6(uint64_t dr6); 8394a5d661aSToomas Soome void load_dr7(uint64_t dr7); 8404a5d661aSToomas Soome void load_fs(u_short sel); 8414a5d661aSToomas Soome void load_gs(u_short sel); 8424a5d661aSToomas Soome void ltr(u_short sel); 8434a5d661aSToomas Soome void outb(u_int port, u_char data); 8444a5d661aSToomas Soome void outl(u_int port, u_int data); 8454a5d661aSToomas Soome void outsb(u_int port, const void *addr, size_t count); 8464a5d661aSToomas Soome void outsl(u_int port, const void *addr, size_t count); 8474a5d661aSToomas Soome void outsw(u_int port, const void *addr, size_t count); 8484a5d661aSToomas Soome void outw(u_int port, u_short data); 8494a5d661aSToomas Soome u_long rcr0(void); 8504a5d661aSToomas Soome u_long rcr2(void); 8514a5d661aSToomas Soome u_long rcr3(void); 8524a5d661aSToomas Soome u_long rcr4(void); 8534a5d661aSToomas Soome uint64_t rdmsr(u_int msr); 8544a5d661aSToomas Soome uint32_t rdmsr32(u_int msr); 8554a5d661aSToomas Soome uint64_t rdpmc(u_int pmc); 8564a5d661aSToomas Soome uint64_t rdr0(void); 8574a5d661aSToomas Soome uint64_t rdr1(void); 8584a5d661aSToomas Soome uint64_t rdr2(void); 8594a5d661aSToomas Soome uint64_t rdr3(void); 8604a5d661aSToomas Soome uint64_t rdr6(void); 8614a5d661aSToomas Soome uint64_t rdr7(void); 8624a5d661aSToomas Soome uint64_t rdtsc(void); 8634a5d661aSToomas Soome u_long read_rflags(void); 8644a5d661aSToomas Soome u_int rfs(void); 8654a5d661aSToomas Soome u_int rgs(void); 8664a5d661aSToomas Soome void wbinvd(void); 8674a5d661aSToomas Soome void write_rflags(u_int rf); 8684a5d661aSToomas Soome void wrmsr(u_int msr, uint64_t newval); 8694a5d661aSToomas Soome 8704a5d661aSToomas Soome #endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */ 8714a5d661aSToomas Soome 8724a5d661aSToomas Soome void reset_dbregs(void); 8734a5d661aSToomas Soome 8744a5d661aSToomas Soome #ifdef _KERNEL 8754a5d661aSToomas Soome int rdmsr_safe(u_int msr, uint64_t *val); 8764a5d661aSToomas Soome int wrmsr_safe(u_int msr, uint64_t newval); 8774a5d661aSToomas Soome #endif 8784a5d661aSToomas Soome 8794a5d661aSToomas Soome #endif /* !_MACHINE_CPUFUNC_H_ */ 880