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