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
breakpoint(void)614a5d661aSToomas Soome breakpoint(void)
624a5d661aSToomas Soome {
634a5d661aSToomas Soome __asm __volatile("int $3");
644a5d661aSToomas Soome }
654a5d661aSToomas Soome
664a5d661aSToomas Soome static __inline u_int
bsfl(u_int mask)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
bsfq(u_long mask)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
bsrl(u_int mask)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
bsrq(u_long mask)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
clflush(u_long addr)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
clflushopt(u_long addr)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
clts(void)1174a5d661aSToomas Soome clts(void)
1184a5d661aSToomas Soome {
1194a5d661aSToomas Soome
1204a5d661aSToomas Soome __asm __volatile("clts");
1214a5d661aSToomas Soome }
1224a5d661aSToomas Soome
1234a5d661aSToomas Soome static __inline void
disable_intr(void)1244a5d661aSToomas Soome disable_intr(void)
1254a5d661aSToomas Soome {
1264a5d661aSToomas Soome __asm __volatile("cli" : : : "memory");
1274a5d661aSToomas Soome }
1284a5d661aSToomas Soome
1294a5d661aSToomas Soome static __inline void
do_cpuid(u_int ax,u_int * p)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
cpuid_count(u_int ax,u_int cx,u_int * p)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
enable_intr(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
ffsl(long mask)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
ffsll(long long mask)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
fls(int mask)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
flsl(long mask)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
flsll(long long mask)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
halt(void)1994a5d661aSToomas Soome halt(void)
2004a5d661aSToomas Soome {
2014a5d661aSToomas Soome __asm __volatile("hlt");
2024a5d661aSToomas Soome }
2034a5d661aSToomas Soome
2044a5d661aSToomas Soome static __inline u_char
inb(u_int port)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
inl(u_int port)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
insb(u_int port,void * addr,size_t count)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
insw(u_int port,void * addr,size_t count)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
insl(u_int port,void * addr,size_t count)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
invd(void)2504a5d661aSToomas Soome invd(void)
2514a5d661aSToomas Soome {
2524a5d661aSToomas Soome __asm __volatile("invd");
2534a5d661aSToomas Soome }
2544a5d661aSToomas Soome
2554a5d661aSToomas Soome static __inline u_short
inw(u_int port)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
outb(u_int port,u_char data)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
outl(u_int port,u_int data)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
outsb(u_int port,const void * addr,size_t count)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
outsw(u_int port,const void * addr,size_t count)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
outsl(u_int port,const void * addr,size_t count)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
outw(u_int port,u_short data)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
popcntq(u_long mask)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
lfence(void)3164a5d661aSToomas Soome lfence(void)
3174a5d661aSToomas Soome {
3184a5d661aSToomas Soome
3194a5d661aSToomas Soome __asm __volatile("lfence" : : : "memory");
3204a5d661aSToomas Soome }
3214a5d661aSToomas Soome
3224a5d661aSToomas Soome static __inline void
mfence(void)3234a5d661aSToomas Soome mfence(void)
3244a5d661aSToomas Soome {
3254a5d661aSToomas Soome
3264a5d661aSToomas Soome __asm __volatile("mfence" : : : "memory");
3274a5d661aSToomas Soome }
3284a5d661aSToomas Soome
3294a5d661aSToomas Soome static __inline void
sfence(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
ia32_pause(void)3374a5d661aSToomas Soome ia32_pause(void)
3384a5d661aSToomas Soome {
3394a5d661aSToomas Soome __asm __volatile("pause");
3404a5d661aSToomas Soome }
3414a5d661aSToomas Soome
3424a5d661aSToomas Soome static __inline u_long
read_rflags(void)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
rdmsr(u_int msr)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
rdmsr32(u_int msr)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
rdpmc(u_int pmc)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
rdtsc(void)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
rdtsc32(void)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
wbinvd(void)3974a5d661aSToomas Soome wbinvd(void)
3984a5d661aSToomas Soome {
3994a5d661aSToomas Soome __asm __volatile("wbinvd");
4004a5d661aSToomas Soome }
4014a5d661aSToomas Soome
4024a5d661aSToomas Soome static __inline void
write_rflags(u_long rf)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
wrmsr(u_int msr,uint64_t newval)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
load_cr0(u_long data)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
rcr0(void)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
rcr2(void)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
load_cr3(u_long data)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
rcr3(void)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
load_cr4(u_long data)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
rcr4(void)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
rxcr(u_int reg)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
load_xcr(u_int reg,u_long val)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
invltlb(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
invltlb_glob(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
invlpg(u_long addr)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
invpcid(struct invpcid_descr * d,int type)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
rfs(void)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
rgs(void)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
rss(void)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
load_ds(u_short sel)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
load_es(u_short sel)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
cpu_monitor(const void * addr,u_long extensions,u_int hints)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
cpu_mwait(u_long extensions,u_int hints)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
load_fs(u_short sel)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
load_gs(u_short sel)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
load_fs(u_short sel)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
load_gs(u_short sel)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
bare_lgdt(struct region_descriptor * addr)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
sgdt(struct region_descriptor * addr)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
lidt(struct region_descriptor * addr)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
sidt(struct region_descriptor * addr)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
lldt(u_short sel)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
ltr(u_short sel)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
read_tr(void)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
rdr0(void)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
load_dr0(uint64_t dr0)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
rdr1(void)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
load_dr1(uint64_t dr1)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
rdr2(void)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
load_dr2(uint64_t dr2)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
rdr3(void)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
load_dr3(uint64_t dr3)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
rdr6(void)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
load_dr6(uint64_t dr6)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
rdr7(void)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
load_dr7(uint64_t dr7)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
intr_disable(void)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
intr_restore(register_t rflags)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