xref: /titanic_52/usr/src/boot/sys/amd64/include/cpufunc.h (revision 8ede96251e3dca657102f3a32187d4382bda2ba4)
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