xref: /freebsd/sys/i386/include/cpufunc.h (revision b0056b31e90029553894d17c441cbb2c06d31412)
13c4dd356SDavid Greenman /*-
251369649SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
351369649SPedro F. Giffuni  *
43c4dd356SDavid Greenman  * Copyright (c) 1993 The Regents of the University of California.
53c4dd356SDavid Greenman  * All rights reserved.
63c4dd356SDavid Greenman  *
73c4dd356SDavid Greenman  * Redistribution and use in source and binary forms, with or without
83c4dd356SDavid Greenman  * modification, are permitted provided that the following conditions
93c4dd356SDavid Greenman  * are met:
103c4dd356SDavid Greenman  * 1. Redistributions of source code must retain the above copyright
113c4dd356SDavid Greenman  *    notice, this list of conditions and the following disclaimer.
123c4dd356SDavid Greenman  * 2. Redistributions in binary form must reproduce the above copyright
133c4dd356SDavid Greenman  *    notice, this list of conditions and the following disclaimer in the
143c4dd356SDavid Greenman  *    documentation and/or other materials provided with the distribution.
15fbbd9655SWarner Losh  * 3. Neither the name of the University nor the names of its contributors
163c4dd356SDavid Greenman  *    may be used to endorse or promote products derived from this software
173c4dd356SDavid Greenman  *    without specific prior written permission.
183c4dd356SDavid Greenman  *
193c4dd356SDavid Greenman  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
203c4dd356SDavid Greenman  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
213c4dd356SDavid Greenman  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
223c4dd356SDavid Greenman  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
233c4dd356SDavid Greenman  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
243c4dd356SDavid Greenman  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
253c4dd356SDavid Greenman  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
263c4dd356SDavid Greenman  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
273c4dd356SDavid Greenman  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
283c4dd356SDavid Greenman  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
293c4dd356SDavid Greenman  * SUCH DAMAGE.
303c4dd356SDavid Greenman  */
313c4dd356SDavid Greenman 
325b81b6b3SRodney W. Grimes /*
335b81b6b3SRodney W. Grimes  * Functions to provide access to special i386 instructions.
34f5d9a10bSMark Murray  * This in included in sys/systm.h, and that file should be
35f5d9a10bSMark Murray  * used in preference to this.
365b81b6b3SRodney W. Grimes  */
375b81b6b3SRodney W. Grimes 
386e393973SGarrett Wollman #ifndef _MACHINE_CPUFUNC_H_
39004bedebSBruce Evans #define	_MACHINE_CPUFUNC_H_
406e393973SGarrett Wollman 
41eb1443c8SPeter Wemm struct region_descriptor;
42d74ac681SMatthew Dillon 
43f54c13eaSJung-uk Kim #define readb(va)	(*(volatile uint8_t *) (va))
44f54c13eaSJung-uk Kim #define readw(va)	(*(volatile uint16_t *) (va))
45f54c13eaSJung-uk Kim #define readl(va)	(*(volatile uint32_t *) (va))
46e31fa854SDoug Rabson 
47f54c13eaSJung-uk Kim #define writeb(va, d)	(*(volatile uint8_t *) (va) = (d))
48f54c13eaSJung-uk Kim #define writew(va, d)	(*(volatile uint16_t *) (va) = (d))
49f54c13eaSJung-uk Kim #define writel(va, d)	(*(volatile uint32_t *) (va) = (d))
50e31fa854SDoug Rabson 
515dbd168eSBruce Evans static __inline void
525dbd168eSBruce Evans breakpoint(void)
53004bedebSBruce Evans {
54004bedebSBruce Evans 	__asm __volatile("int $3");
555b81b6b3SRodney W. Grimes }
565b81b6b3SRodney W. Grimes 
576f240e18SConrad Meyer static __inline __pure2 u_int
58c83b1328SBruce Evans bsfl(u_int mask)
59c83b1328SBruce Evans {
60c83b1328SBruce Evans 	u_int	result;
61c83b1328SBruce Evans 
622b7ceeb0SEd Schouten 	__asm("bsfl %1,%0" : "=r" (result) : "rm" (mask) : "cc");
63c83b1328SBruce Evans 	return (result);
64c83b1328SBruce Evans }
65c83b1328SBruce Evans 
66004bedebSBruce Evans static __inline void
678a5ac5d5SKonstantin Belousov clflush(u_long addr)
688a5ac5d5SKonstantin Belousov {
698a5ac5d5SKonstantin Belousov 
708a5ac5d5SKonstantin Belousov 	__asm __volatile("clflush %0" : : "m" (*(char *)addr));
718a5ac5d5SKonstantin Belousov }
728a5ac5d5SKonstantin Belousov 
738a5ac5d5SKonstantin Belousov static __inline void
743f8e0710SKonstantin Belousov clflushopt(u_long addr)
753f8e0710SKonstantin Belousov {
763f8e0710SKonstantin Belousov 
7705f10487SKonstantin Belousov 	__asm __volatile(".byte 0x66;clflush %0" : : "m" (*(char *)addr));
783f8e0710SKonstantin Belousov }
793f8e0710SKonstantin Belousov 
803f8e0710SKonstantin Belousov static __inline void
81d706ec29SJohn Baldwin clts(void)
82d706ec29SJohn Baldwin {
83d706ec29SJohn Baldwin 
84d706ec29SJohn Baldwin 	__asm __volatile("clts");
85d706ec29SJohn Baldwin }
86d706ec29SJohn Baldwin 
87d706ec29SJohn Baldwin static __inline void
885b81b6b3SRodney W. Grimes disable_intr(void)
895b81b6b3SRodney W. Grimes {
908966b85cSJohn Dyson 	__asm __volatile("cli" : : : "memory");
915b81b6b3SRodney W. Grimes }
925b81b6b3SRodney W. Grimes 
93642bb66bSKonstantin Belousov #ifdef _KERNEL
94004bedebSBruce Evans static __inline void
95a983fdfeSDavid Malone do_cpuid(u_int ax, u_int *p)
96a983fdfeSDavid Malone {
97a983fdfeSDavid Malone 	__asm __volatile("cpuid"
98a983fdfeSDavid Malone 	    : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
99a983fdfeSDavid Malone 	    :  "0" (ax));
100a983fdfeSDavid Malone }
101a983fdfeSDavid Malone 
102a983fdfeSDavid Malone static __inline void
103f6108b61SJacques Vidrine cpuid_count(u_int ax, u_int cx, u_int *p)
104f6108b61SJacques Vidrine {
105f6108b61SJacques Vidrine 	__asm __volatile("cpuid"
106f6108b61SJacques Vidrine 	    : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
107f6108b61SJacques Vidrine 	    :  "0" (ax), "c" (cx));
108f6108b61SJacques Vidrine }
109642bb66bSKonstantin Belousov #else
110642bb66bSKonstantin Belousov static __inline void
111642bb66bSKonstantin Belousov do_cpuid(u_int ax, u_int *p)
112642bb66bSKonstantin Belousov {
113642bb66bSKonstantin Belousov 	__asm __volatile(
114642bb66bSKonstantin Belousov 	    "pushl\t%%ebx\n\t"
115642bb66bSKonstantin Belousov 	    "cpuid\n\t"
116642bb66bSKonstantin Belousov 	    "movl\t%%ebx,%1\n\t"
117642bb66bSKonstantin Belousov 	    "popl\t%%ebx"
118642bb66bSKonstantin Belousov 	    : "=a" (p[0]), "=DS" (p[1]), "=c" (p[2]), "=d" (p[3])
119642bb66bSKonstantin Belousov 	    :  "0" (ax));
120642bb66bSKonstantin Belousov }
121642bb66bSKonstantin Belousov 
122642bb66bSKonstantin Belousov static __inline void
123642bb66bSKonstantin Belousov cpuid_count(u_int ax, u_int cx, u_int *p)
124642bb66bSKonstantin Belousov {
125642bb66bSKonstantin Belousov 	__asm __volatile(
126642bb66bSKonstantin Belousov 	    "pushl\t%%ebx\n\t"
127642bb66bSKonstantin Belousov 	    "cpuid\n\t"
128642bb66bSKonstantin Belousov 	    "movl\t%%ebx,%1\n\t"
129642bb66bSKonstantin Belousov 	    "popl\t%%ebx"
130642bb66bSKonstantin Belousov 	    : "=a" (p[0]), "=DS" (p[1]), "=c" (p[2]), "=d" (p[3])
131642bb66bSKonstantin Belousov 	    :  "0" (ax), "c" (cx));
132642bb66bSKonstantin Belousov }
133642bb66bSKonstantin Belousov #endif
134f6108b61SJacques Vidrine 
135f6108b61SJacques Vidrine static __inline void
1365b81b6b3SRodney W. Grimes enable_intr(void)
1375b81b6b3SRodney W. Grimes {
138fadc51bdSBruce Evans 	__asm __volatile("sti");
1395b81b6b3SRodney W. Grimes }
1405b81b6b3SRodney W. Grimes 
141beb2c1f3SAndriy Gapon static __inline void
142f0b28f00SJung-uk Kim cpu_monitor(const void *addr, u_long extensions, u_int hints)
14366247efaSJeff Roberson {
144f0b28f00SJung-uk Kim 	__asm __volatile("monitor"
14566247efaSJeff Roberson 	    : : "a" (addr), "c" (extensions), "d" (hints));
14666247efaSJeff Roberson }
14766247efaSJeff Roberson 
148beb2c1f3SAndriy Gapon static __inline void
149f0b28f00SJung-uk Kim cpu_mwait(u_long extensions, u_int hints)
15066247efaSJeff Roberson {
151f0b28f00SJung-uk Kim 	__asm __volatile("mwait" : : "a" (hints), "c" (extensions));
15266247efaSJeff Roberson }
15366247efaSJeff Roberson 
1548a5ac5d5SKonstantin Belousov static __inline void
1550220d04fSKonstantin Belousov lfence(void)
1560220d04fSKonstantin Belousov {
1570220d04fSKonstantin Belousov 	__asm __volatile("lfence" : : : "memory");
1580220d04fSKonstantin Belousov }
1590220d04fSKonstantin Belousov 
1600220d04fSKonstantin Belousov static __inline void
1618a5ac5d5SKonstantin Belousov mfence(void)
1628a5ac5d5SKonstantin Belousov {
1638a5ac5d5SKonstantin Belousov 	__asm __volatile("mfence" : : : "memory");
1648a5ac5d5SKonstantin Belousov }
1658a5ac5d5SKonstantin Belousov 
1665611aaa1SKonstantin Belousov static __inline void
1675611aaa1SKonstantin Belousov sfence(void)
1685611aaa1SKonstantin Belousov {
1695611aaa1SKonstantin Belousov 	__asm __volatile("sfence" : : : "memory");
1705611aaa1SKonstantin Belousov }
1715611aaa1SKonstantin Belousov 
172d7ee4425SMark Murray static __inline void
173d7ee4425SMark Murray halt(void)
174d7ee4425SMark Murray {
175d7ee4425SMark Murray 	__asm __volatile("hlt");
176d7ee4425SMark Murray }
177d7ee4425SMark Murray 
178004bedebSBruce Evans static __inline u_char
179e1048f76SEd Schouten inb(u_int port)
180004bedebSBruce Evans {
181004bedebSBruce Evans 	u_char	data;
182004bedebSBruce Evans 
1834854ae24SJung-uk Kim 	__asm __volatile("inb %w1, %0" : "=a" (data) : "Nd" (port));
184004bedebSBruce Evans 	return (data);
185004bedebSBruce Evans }
186004bedebSBruce Evans 
18700be8601SBruce Evans static __inline u_int
188004bedebSBruce Evans inl(u_int port)
189004bedebSBruce Evans {
19000be8601SBruce Evans 	u_int	data;
191004bedebSBruce Evans 
1924854ae24SJung-uk Kim 	__asm __volatile("inl %w1, %0" : "=a" (data) : "Nd" (port));
193004bedebSBruce Evans 	return (data);
194004bedebSBruce Evans }
195004bedebSBruce Evans 
196004bedebSBruce Evans static __inline void
19793d8be03SDavid E. O'Brien insb(u_int port, void *addr, size_t count)
198004bedebSBruce Evans {
199004bedebSBruce Evans 	__asm __volatile("cld; rep; insb"
20093d8be03SDavid E. O'Brien 			 : "+D" (addr), "+c" (count)
2013f9a462fSJohn Baldwin 			 : "d" (port)
202896763faSBruce Evans 			 : "memory");
203004bedebSBruce Evans }
204004bedebSBruce Evans 
205004bedebSBruce Evans static __inline void
20693d8be03SDavid E. O'Brien insw(u_int port, void *addr, size_t count)
207004bedebSBruce Evans {
208004bedebSBruce Evans 	__asm __volatile("cld; rep; insw"
20993d8be03SDavid E. O'Brien 			 : "+D" (addr), "+c" (count)
2103f9a462fSJohn Baldwin 			 : "d" (port)
211896763faSBruce Evans 			 : "memory");
212004bedebSBruce Evans }
213004bedebSBruce Evans 
214004bedebSBruce Evans static __inline void
21593d8be03SDavid E. O'Brien insl(u_int port, void *addr, size_t count)
216004bedebSBruce Evans {
217004bedebSBruce Evans 	__asm __volatile("cld; rep; insl"
21893d8be03SDavid E. O'Brien 			 : "+D" (addr), "+c" (count)
2193f9a462fSJohn Baldwin 			 : "d" (port)
220896763faSBruce Evans 			 : "memory");
221004bedebSBruce Evans }
222004bedebSBruce Evans 
223ece15d78SBruce Evans static __inline void
2244c024bbdSKATO Takenori invd(void)
2254c024bbdSKATO Takenori {
2264c024bbdSKATO Takenori 	__asm __volatile("invd");
2274c024bbdSKATO Takenori }
2284c024bbdSKATO Takenori 
229004bedebSBruce Evans static __inline u_short
230004bedebSBruce Evans inw(u_int port)
231004bedebSBruce Evans {
232004bedebSBruce Evans 	u_short	data;
233004bedebSBruce Evans 
2344854ae24SJung-uk Kim 	__asm __volatile("inw %w1, %0" : "=a" (data) : "Nd" (port));
235004bedebSBruce Evans 	return (data);
236004bedebSBruce Evans }
237004bedebSBruce Evans 
238004bedebSBruce Evans static __inline void
239e1048f76SEd Schouten outb(u_int port, u_char data)
240004bedebSBruce Evans {
241e1048f76SEd Schouten 	__asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port));
242004bedebSBruce Evans }
243004bedebSBruce Evans 
244004bedebSBruce Evans static __inline void
24500be8601SBruce Evans outl(u_int port, u_int data)
246004bedebSBruce Evans {
2474854ae24SJung-uk Kim 	__asm __volatile("outl %0, %w1" : : "a" (data), "Nd" (port));
248004bedebSBruce Evans }
249004bedebSBruce Evans 
250004bedebSBruce Evans static __inline void
25193d8be03SDavid E. O'Brien outsb(u_int port, const void *addr, size_t count)
252004bedebSBruce Evans {
253004bedebSBruce Evans 	__asm __volatile("cld; rep; outsb"
25493d8be03SDavid E. O'Brien 			 : "+S" (addr), "+c" (count)
2553f9a462fSJohn Baldwin 			 : "d" (port));
256004bedebSBruce Evans }
257004bedebSBruce Evans 
258004bedebSBruce Evans static __inline void
25993d8be03SDavid E. O'Brien outsw(u_int port, const void *addr, size_t count)
260004bedebSBruce Evans {
261004bedebSBruce Evans 	__asm __volatile("cld; rep; outsw"
26293d8be03SDavid E. O'Brien 			 : "+S" (addr), "+c" (count)
2633f9a462fSJohn Baldwin 			 : "d" (port));
264004bedebSBruce Evans }
265004bedebSBruce Evans 
266004bedebSBruce Evans static __inline void
26793d8be03SDavid E. O'Brien outsl(u_int port, const void *addr, size_t count)
268004bedebSBruce Evans {
269004bedebSBruce Evans 	__asm __volatile("cld; rep; outsl"
27093d8be03SDavid E. O'Brien 			 : "+S" (addr), "+c" (count)
2713f9a462fSJohn Baldwin 			 : "d" (port));
272004bedebSBruce Evans }
273004bedebSBruce Evans 
274004bedebSBruce Evans static __inline void
275004bedebSBruce Evans outw(u_int port, u_short data)
276004bedebSBruce Evans {
2774854ae24SJung-uk Kim 	__asm __volatile("outw %0, %w1" : : "a" (data), "Nd" (port));
278004bedebSBruce Evans }
279004bedebSBruce Evans 
2802be69f32SJohn Baldwin static __inline void
2816b8c6989SJohn Baldwin ia32_pause(void)
2822be69f32SJohn Baldwin {
2832be69f32SJohn Baldwin 	__asm __volatile("pause");
2842be69f32SJohn Baldwin }
2852be69f32SJohn Baldwin 
28600be8601SBruce Evans static __inline u_int
287004bedebSBruce Evans read_eflags(void)
2885b81b6b3SRodney W. Grimes {
28900be8601SBruce Evans 	u_int	ef;
290004bedebSBruce Evans 
291004bedebSBruce Evans 	__asm __volatile("pushfl; popl %0" : "=r" (ef));
2928db02de8SPaul Richards 	return (ef);
2935b81b6b3SRodney W. Grimes }
2945b81b6b3SRodney W. Grimes 
2953b3f2813SNate Lawson static __inline uint64_t
2965dbd168eSBruce Evans rdmsr(u_int msr)
2975dbd168eSBruce Evans {
2983b3f2813SNate Lawson 	uint64_t rv;
2995dbd168eSBruce Evans 
30039413503SMark Murray 	__asm __volatile("rdmsr" : "=A" (rv) : "c" (msr));
3015dbd168eSBruce Evans 	return (rv);
3025dbd168eSBruce Evans }
3035dbd168eSBruce Evans 
3044c918926SKonstantin Belousov static __inline uint32_t
3054c918926SKonstantin Belousov rdmsr32(u_int msr)
3064c918926SKonstantin Belousov {
3074c918926SKonstantin Belousov 	uint32_t low;
3084c918926SKonstantin Belousov 
3094c918926SKonstantin Belousov 	__asm __volatile("rdmsr" : "=a" (low) : "c" (msr) : "edx");
3104c918926SKonstantin Belousov 	return (low);
3114c918926SKonstantin Belousov }
3124c918926SKonstantin Belousov 
3133b3f2813SNate Lawson static __inline uint64_t
3145dbd168eSBruce Evans rdpmc(u_int pmc)
3155dbd168eSBruce Evans {
3163b3f2813SNate Lawson 	uint64_t rv;
3175dbd168eSBruce Evans 
31839413503SMark Murray 	__asm __volatile("rdpmc" : "=A" (rv) : "c" (pmc));
3195dbd168eSBruce Evans 	return (rv);
3205dbd168eSBruce Evans }
3215dbd168eSBruce Evans 
3223b3f2813SNate Lawson static __inline uint64_t
3235dbd168eSBruce Evans rdtsc(void)
3245dbd168eSBruce Evans {
3253b3f2813SNate Lawson 	uint64_t rv;
3265dbd168eSBruce Evans 
32739413503SMark Murray 	__asm __volatile("rdtsc" : "=A" (rv));
3285dbd168eSBruce Evans 	return (rv);
3295dbd168eSBruce Evans }
3305dbd168eSBruce Evans 
33115504639SMatt Macy static __inline uint64_t
332*652ae7b1SAdam Fenn rdtsc_ordered_lfence(void)
333*652ae7b1SAdam Fenn {
334*652ae7b1SAdam Fenn 	lfence();
335*652ae7b1SAdam Fenn 	return (rdtsc());
336*652ae7b1SAdam Fenn }
337*652ae7b1SAdam Fenn 
338*652ae7b1SAdam Fenn static __inline uint64_t
339*652ae7b1SAdam Fenn rdtsc_ordered_mfence(void)
340*652ae7b1SAdam Fenn {
341*652ae7b1SAdam Fenn 	mfence();
342*652ae7b1SAdam Fenn 	return (rdtsc());
343*652ae7b1SAdam Fenn }
344*652ae7b1SAdam Fenn 
345*652ae7b1SAdam Fenn static __inline uint64_t
34615504639SMatt Macy rdtscp(void)
34715504639SMatt Macy {
34815504639SMatt Macy 	uint64_t rv;
34915504639SMatt Macy 
350f090f675SMark Johnston 	__asm __volatile("rdtscp" : "=A" (rv) : : "ecx");
35115504639SMatt Macy 	return (rv);
35215504639SMatt Macy }
35315504639SMatt Macy 
354908e2772SAdam Fenn static __inline uint64_t
355908e2772SAdam Fenn rdtscp_aux(uint32_t *aux)
356908e2772SAdam Fenn {
357908e2772SAdam Fenn 	uint64_t rv;
358908e2772SAdam Fenn 
359908e2772SAdam Fenn 	__asm __volatile("rdtscp" : "=A" (rv), "=c" (*aux));
360908e2772SAdam Fenn 	return (rv);
361908e2772SAdam Fenn }
362908e2772SAdam Fenn 
3630e727642SJung-uk Kim static __inline uint32_t
3640e727642SJung-uk Kim rdtsc32(void)
3650e727642SJung-uk Kim {
3660e727642SJung-uk Kim 	uint32_t rv;
3670e727642SJung-uk Kim 
3680e727642SJung-uk Kim 	__asm __volatile("rdtsc" : "=a" (rv) : : "edx");
3690e727642SJung-uk Kim 	return (rv);
3700e727642SJung-uk Kim }
3710e727642SJung-uk Kim 
37245974de8SKonstantin Belousov static __inline uint32_t
37345974de8SKonstantin Belousov rdtscp32(void)
37445974de8SKonstantin Belousov {
37545974de8SKonstantin Belousov 	uint32_t rv;
37645974de8SKonstantin Belousov 
37745974de8SKonstantin Belousov 	__asm __volatile("rdtscp" : "=a" (rv) : : "ecx", "edx");
37845974de8SKonstantin Belousov 	return (rv);
37945974de8SKonstantin Belousov }
38045974de8SKonstantin Belousov 
381004bedebSBruce Evans static __inline void
3824c024bbdSKATO Takenori wbinvd(void)
3834c024bbdSKATO Takenori {
3844c024bbdSKATO Takenori 	__asm __volatile("wbinvd");
3854c024bbdSKATO Takenori }
3864c024bbdSKATO Takenori 
3874c024bbdSKATO Takenori static __inline void
38800be8601SBruce Evans write_eflags(u_int ef)
3895b81b6b3SRodney W. Grimes {
390004bedebSBruce Evans 	__asm __volatile("pushl %0; popfl" : : "r" (ef));
3915b81b6b3SRodney W. Grimes }
3925b81b6b3SRodney W. Grimes 
393d69e8502SGarrett Wollman static __inline void
3943b3f2813SNate Lawson wrmsr(u_int msr, uint64_t newval)
395d69e8502SGarrett Wollman {
39639413503SMark Murray 	__asm __volatile("wrmsr" : : "A" (newval), "c" (msr));
397d69e8502SGarrett Wollman }
398d69e8502SGarrett Wollman 
399f1b665c8SPeter Wemm static __inline void
400f1b665c8SPeter Wemm load_cr0(u_int data)
401f1b665c8SPeter Wemm {
402f1b665c8SPeter Wemm 
403f1b665c8SPeter Wemm 	__asm __volatile("movl %0,%%cr0" : : "r" (data));
404f1b665c8SPeter Wemm }
405f1b665c8SPeter Wemm 
406f1b665c8SPeter Wemm static __inline u_int
407f1b665c8SPeter Wemm rcr0(void)
408f1b665c8SPeter Wemm {
409f1b665c8SPeter Wemm 	u_int	data;
410f1b665c8SPeter Wemm 
411f1b665c8SPeter Wemm 	__asm __volatile("movl %%cr0,%0" : "=r" (data));
412f1b665c8SPeter Wemm 	return (data);
413f1b665c8SPeter Wemm }
414f1b665c8SPeter Wemm 
415f1b665c8SPeter Wemm static __inline u_int
416f1b665c8SPeter Wemm rcr2(void)
417f1b665c8SPeter Wemm {
418f1b665c8SPeter Wemm 	u_int	data;
419f1b665c8SPeter Wemm 
420f1b665c8SPeter Wemm 	__asm __volatile("movl %%cr2,%0" : "=r" (data));
421f1b665c8SPeter Wemm 	return (data);
422f1b665c8SPeter Wemm }
423f1b665c8SPeter Wemm 
424f1b665c8SPeter Wemm static __inline void
425f1b665c8SPeter Wemm load_cr3(u_int data)
426f1b665c8SPeter Wemm {
427ed95805eSJohn Baldwin 
428f1b665c8SPeter Wemm 	__asm __volatile("movl %0,%%cr3" : : "r" (data) : "memory");
429f1b665c8SPeter Wemm }
430f1b665c8SPeter Wemm 
431f1b665c8SPeter Wemm static __inline u_int
432f1b665c8SPeter Wemm rcr3(void)
433f1b665c8SPeter Wemm {
434f1b665c8SPeter Wemm 	u_int	data;
435f1b665c8SPeter Wemm 
436f1b665c8SPeter Wemm 	__asm __volatile("movl %%cr3,%0" : "=r" (data));
437f1b665c8SPeter Wemm 	return (data);
438f1b665c8SPeter Wemm }
439f1b665c8SPeter Wemm 
440f1b665c8SPeter Wemm static __inline void
441f1b665c8SPeter Wemm load_cr4(u_int data)
442f1b665c8SPeter Wemm {
443f1b665c8SPeter Wemm 	__asm __volatile("movl %0,%%cr4" : : "r" (data));
444f1b665c8SPeter Wemm }
445f1b665c8SPeter Wemm 
446f1b665c8SPeter Wemm static __inline u_int
447f1b665c8SPeter Wemm rcr4(void)
448f1b665c8SPeter Wemm {
449f1b665c8SPeter Wemm 	u_int	data;
450f1b665c8SPeter Wemm 
451f1b665c8SPeter Wemm 	__asm __volatile("movl %%cr4,%0" : "=r" (data));
452f1b665c8SPeter Wemm 	return (data);
453f1b665c8SPeter Wemm }
454f1b665c8SPeter Wemm 
455824fc460SJohn Baldwin static __inline uint64_t
456824fc460SJohn Baldwin rxcr(u_int reg)
457824fc460SJohn Baldwin {
458824fc460SJohn Baldwin 	u_int low, high;
459824fc460SJohn Baldwin 
460824fc460SJohn Baldwin 	__asm __volatile("xgetbv" : "=a" (low), "=d" (high) : "c" (reg));
461824fc460SJohn Baldwin 	return (low | ((uint64_t)high << 32));
462824fc460SJohn Baldwin }
463824fc460SJohn Baldwin 
464824fc460SJohn Baldwin static __inline void
465824fc460SJohn Baldwin load_xcr(u_int reg, uint64_t val)
466824fc460SJohn Baldwin {
467824fc460SJohn Baldwin 	u_int low, high;
468824fc460SJohn Baldwin 
469824fc460SJohn Baldwin 	low = val;
470824fc460SJohn Baldwin 	high = val >> 32;
471824fc460SJohn Baldwin 	__asm __volatile("xsetbv" : : "c" (reg), "a" (low), "d" (high));
472824fc460SJohn Baldwin }
473824fc460SJohn Baldwin 
474f1b665c8SPeter Wemm /*
475f1b665c8SPeter Wemm  * Global TLB flush (except for thise for pages marked PG_G)
476f1b665c8SPeter Wemm  */
477f1b665c8SPeter Wemm static __inline void
478f1b665c8SPeter Wemm invltlb(void)
479f1b665c8SPeter Wemm {
480ed95805eSJohn Baldwin 
481f1b665c8SPeter Wemm 	load_cr3(rcr3());
482f1b665c8SPeter Wemm }
483f1b665c8SPeter Wemm 
484f1b665c8SPeter Wemm /*
485f1b665c8SPeter Wemm  * TLB flush for an individual page (even if it has PG_G).
486f1b665c8SPeter Wemm  * Only works on 486+ CPUs (i386 does not have PG_G).
487f1b665c8SPeter Wemm  */
488f1b665c8SPeter Wemm static __inline void
489f1b665c8SPeter Wemm invlpg(u_int addr)
490f1b665c8SPeter Wemm {
491f1b665c8SPeter Wemm 
492f1b665c8SPeter Wemm 	__asm __volatile("invlpg %0" : : "m" (*(char *)addr) : "memory");
493f1b665c8SPeter Wemm }
494f1b665c8SPeter Wemm 
49527d4fea6SRoman Divacky static __inline u_short
4965206bca1SLuoqi Chen rfs(void)
4975206bca1SLuoqi Chen {
49827d4fea6SRoman Divacky 	u_short sel;
49927d4fea6SRoman Divacky 	__asm __volatile("movw %%fs,%0" : "=rm" (sel));
5005206bca1SLuoqi Chen 	return (sel);
5015206bca1SLuoqi Chen }
5025206bca1SLuoqi Chen 
5033b3f2813SNate Lawson static __inline uint64_t
5043b3f2813SNate Lawson rgdt(void)
5053b3f2813SNate Lawson {
5063b3f2813SNate Lawson 	uint64_t gdtr;
5073b3f2813SNate Lawson 	__asm __volatile("sgdt %0" : "=m" (gdtr));
5083b3f2813SNate Lawson 	return (gdtr);
5093b3f2813SNate Lawson }
5103b3f2813SNate Lawson 
51127d4fea6SRoman Divacky static __inline u_short
5125206bca1SLuoqi Chen rgs(void)
5135206bca1SLuoqi Chen {
51427d4fea6SRoman Divacky 	u_short sel;
51527d4fea6SRoman Divacky 	__asm __volatile("movw %%gs,%0" : "=rm" (sel));
5165206bca1SLuoqi Chen 	return (sel);
5175206bca1SLuoqi Chen }
5185206bca1SLuoqi Chen 
5193b3f2813SNate Lawson static __inline uint64_t
5203b3f2813SNate Lawson ridt(void)
5213b3f2813SNate Lawson {
5223b3f2813SNate Lawson 	uint64_t idtr;
5233b3f2813SNate Lawson 	__asm __volatile("sidt %0" : "=m" (idtr));
5243b3f2813SNate Lawson 	return (idtr);
5253b3f2813SNate Lawson }
5263b3f2813SNate Lawson 
5273b3f2813SNate Lawson static __inline u_short
5283b3f2813SNate Lawson rldt(void)
5293b3f2813SNate Lawson {
5303b3f2813SNate Lawson 	u_short ldtr;
5313b3f2813SNate Lawson 	__asm __volatile("sldt %0" : "=g" (ldtr));
5323b3f2813SNate Lawson 	return (ldtr);
5333b3f2813SNate Lawson }
5343b3f2813SNate Lawson 
53527d4fea6SRoman Divacky static __inline u_short
53660aa1737SMarcel Moolenaar rss(void)
53760aa1737SMarcel Moolenaar {
53827d4fea6SRoman Divacky 	u_short sel;
53927d4fea6SRoman Divacky 	__asm __volatile("movw %%ss,%0" : "=rm" (sel));
54060aa1737SMarcel Moolenaar 	return (sel);
54160aa1737SMarcel Moolenaar }
54260aa1737SMarcel Moolenaar 
5433b3f2813SNate Lawson static __inline u_short
5443b3f2813SNate Lawson rtr(void)
5453b3f2813SNate Lawson {
5463b3f2813SNate Lawson 	u_short tr;
5473b3f2813SNate Lawson 	__asm __volatile("str %0" : "=g" (tr));
5483b3f2813SNate Lawson 	return (tr);
5493b3f2813SNate Lawson }
5503b3f2813SNate Lawson 
5515206bca1SLuoqi Chen static __inline void
55227d4fea6SRoman Divacky load_fs(u_short sel)
5535206bca1SLuoqi Chen {
55427d4fea6SRoman Divacky 	__asm __volatile("movw %0,%%fs" : : "rm" (sel));
5555206bca1SLuoqi Chen }
5565206bca1SLuoqi Chen 
5575206bca1SLuoqi Chen static __inline void
55827d4fea6SRoman Divacky load_gs(u_short sel)
5595206bca1SLuoqi Chen {
56027d4fea6SRoman Divacky 	__asm __volatile("movw %0,%%gs" : : "rm" (sel));
5615206bca1SLuoqi Chen }
5625206bca1SLuoqi Chen 
563eb1443c8SPeter Wemm static __inline void
564eb1443c8SPeter Wemm lidt(struct region_descriptor *addr)
565eb1443c8SPeter Wemm {
566eb1443c8SPeter Wemm 	__asm __volatile("lidt (%0)" : : "r" (addr));
567eb1443c8SPeter Wemm }
568eb1443c8SPeter Wemm 
569eb1443c8SPeter Wemm static __inline void
570eb1443c8SPeter Wemm lldt(u_short sel)
571eb1443c8SPeter Wemm {
572eb1443c8SPeter Wemm 	__asm __volatile("lldt %0" : : "r" (sel));
573eb1443c8SPeter Wemm }
574eb1443c8SPeter Wemm 
575eb1443c8SPeter Wemm static __inline void
576eb1443c8SPeter Wemm ltr(u_short sel)
577eb1443c8SPeter Wemm {
578eb1443c8SPeter Wemm 	__asm __volatile("ltr %0" : : "r" (sel));
579eb1443c8SPeter Wemm }
580eb1443c8SPeter Wemm 
581de8050f9SBrian S. Dean static __inline u_int
582de8050f9SBrian S. Dean rdr0(void)
583de8050f9SBrian S. Dean {
584de8050f9SBrian S. Dean 	u_int	data;
58580275388SBrian S. Dean 	__asm __volatile("movl %%dr0,%0" : "=r" (data));
586de8050f9SBrian S. Dean 	return (data);
587de8050f9SBrian S. Dean }
588de8050f9SBrian S. Dean 
5896eda157eSBrian S. Dean static __inline void
59007508f90SJohn Baldwin load_dr0(u_int dr0)
5916eda157eSBrian S. Dean {
59207508f90SJohn Baldwin 	__asm __volatile("movl %0,%%dr0" : : "r" (dr0));
5936eda157eSBrian S. Dean }
5946eda157eSBrian S. Dean 
595de8050f9SBrian S. Dean static __inline u_int
596de8050f9SBrian S. Dean rdr1(void)
597de8050f9SBrian S. Dean {
598de8050f9SBrian S. Dean 	u_int	data;
59980275388SBrian S. Dean 	__asm __volatile("movl %%dr1,%0" : "=r" (data));
600de8050f9SBrian S. Dean 	return (data);
601de8050f9SBrian S. Dean }
602de8050f9SBrian S. Dean 
6036eda157eSBrian S. Dean static __inline void
60407508f90SJohn Baldwin load_dr1(u_int dr1)
6056eda157eSBrian S. Dean {
60607508f90SJohn Baldwin 	__asm __volatile("movl %0,%%dr1" : : "r" (dr1));
6076eda157eSBrian S. Dean }
6086eda157eSBrian S. Dean 
609de8050f9SBrian S. Dean static __inline u_int
610de8050f9SBrian S. Dean rdr2(void)
611de8050f9SBrian S. Dean {
612de8050f9SBrian S. Dean 	u_int	data;
61380275388SBrian S. Dean 	__asm __volatile("movl %%dr2,%0" : "=r" (data));
614de8050f9SBrian S. Dean 	return (data);
615de8050f9SBrian S. Dean }
616de8050f9SBrian S. Dean 
6176eda157eSBrian S. Dean static __inline void
61807508f90SJohn Baldwin load_dr2(u_int dr2)
6196eda157eSBrian S. Dean {
62007508f90SJohn Baldwin 	__asm __volatile("movl %0,%%dr2" : : "r" (dr2));
6216eda157eSBrian S. Dean }
6226eda157eSBrian S. Dean 
623de8050f9SBrian S. Dean static __inline u_int
624de8050f9SBrian S. Dean rdr3(void)
625de8050f9SBrian S. Dean {
626de8050f9SBrian S. Dean 	u_int	data;
62780275388SBrian S. Dean 	__asm __volatile("movl %%dr3,%0" : "=r" (data));
628de8050f9SBrian S. Dean 	return (data);
629de8050f9SBrian S. Dean }
630de8050f9SBrian S. Dean 
6316eda157eSBrian S. Dean static __inline void
63207508f90SJohn Baldwin load_dr3(u_int dr3)
6336eda157eSBrian S. Dean {
63407508f90SJohn Baldwin 	__asm __volatile("movl %0,%%dr3" : : "r" (dr3));
6356eda157eSBrian S. Dean }
6366eda157eSBrian S. Dean 
6376eda157eSBrian S. Dean static __inline u_int
638de8050f9SBrian S. Dean rdr6(void)
639de8050f9SBrian S. Dean {
640de8050f9SBrian S. Dean 	u_int	data;
64180275388SBrian S. Dean 	__asm __volatile("movl %%dr6,%0" : "=r" (data));
642de8050f9SBrian S. Dean 	return (data);
643de8050f9SBrian S. Dean }
644de8050f9SBrian S. Dean 
6456eda157eSBrian S. Dean static __inline void
64607508f90SJohn Baldwin load_dr6(u_int dr6)
6476eda157eSBrian S. Dean {
64807508f90SJohn Baldwin 	__asm __volatile("movl %0,%%dr6" : : "r" (dr6));
6496eda157eSBrian S. Dean }
6506eda157eSBrian S. Dean 
651de8050f9SBrian S. Dean static __inline u_int
652de8050f9SBrian S. Dean rdr7(void)
653de8050f9SBrian S. Dean {
654de8050f9SBrian S. Dean 	u_int	data;
65580275388SBrian S. Dean 	__asm __volatile("movl %%dr7,%0" : "=r" (data));
656de8050f9SBrian S. Dean 	return (data);
657de8050f9SBrian S. Dean }
658de8050f9SBrian S. Dean 
6596eda157eSBrian S. Dean static __inline void
66007508f90SJohn Baldwin load_dr7(u_int dr7)
6616eda157eSBrian S. Dean {
66207508f90SJohn Baldwin 	__asm __volatile("movl %0,%%dr7" : : "r" (dr7));
6636eda157eSBrian S. Dean }
6646eda157eSBrian S. Dean 
66538a9df71SJohn Baldwin static __inline u_char
66638a9df71SJohn Baldwin read_cyrix_reg(u_char reg)
66738a9df71SJohn Baldwin {
66838a9df71SJohn Baldwin 	outb(0x22, reg);
66938a9df71SJohn Baldwin 	return inb(0x23);
67038a9df71SJohn Baldwin }
67138a9df71SJohn Baldwin 
67238a9df71SJohn Baldwin static __inline void
67338a9df71SJohn Baldwin write_cyrix_reg(u_char reg, u_char data)
67438a9df71SJohn Baldwin {
67538a9df71SJohn Baldwin 	outb(0x22, reg);
67638a9df71SJohn Baldwin 	outb(0x23, data);
67738a9df71SJohn Baldwin }
67838a9df71SJohn Baldwin 
679ba74981eSWarner Losh static __inline register_t
680ba74981eSWarner Losh intr_disable(void)
681ba74981eSWarner Losh {
68218bad857SKip Macy 	register_t eflags;
683ba74981eSWarner Losh 
684ba74981eSWarner Losh 	eflags = read_eflags();
685ba74981eSWarner Losh 	disable_intr();
686ba74981eSWarner Losh 	return (eflags);
687ba74981eSWarner Losh }
688ba74981eSWarner Losh 
689ba74981eSWarner Losh static __inline void
690ba74981eSWarner Losh intr_restore(register_t eflags)
691ba74981eSWarner Losh {
692ba74981eSWarner Losh 	write_eflags(eflags);
693ba74981eSWarner Losh }
694ba74981eSWarner Losh 
6955ddeaf67SKonstantin Belousov static __inline uint32_t
6965ddeaf67SKonstantin Belousov rdpkru(void)
6975ddeaf67SKonstantin Belousov {
6985ddeaf67SKonstantin Belousov 	uint32_t res;
6995ddeaf67SKonstantin Belousov 
7005ddeaf67SKonstantin Belousov 	__asm __volatile("rdpkru" :  "=a" (res) : "c" (0) : "edx");
7015ddeaf67SKonstantin Belousov 	return (res);
7025ddeaf67SKonstantin Belousov }
7035ddeaf67SKonstantin Belousov 
7045ddeaf67SKonstantin Belousov static __inline void
7055ddeaf67SKonstantin Belousov wrpkru(uint32_t mask)
7065ddeaf67SKonstantin Belousov {
7075ddeaf67SKonstantin Belousov 
7085ddeaf67SKonstantin Belousov 	__asm __volatile("wrpkru" :  : "a" (mask),  "c" (0), "d" (0));
7095ddeaf67SKonstantin Belousov }
7105ddeaf67SKonstantin Belousov 
711b63dc6adSAlfred Perlstein void    reset_dbregs(void);
712d74ac681SMatthew Dillon 
713e085f869SStanislav Sedov #ifdef _KERNEL
714e085f869SStanislav Sedov int	rdmsr_safe(u_int msr, uint64_t *val);
715e085f869SStanislav Sedov int	wrmsr_safe(u_int msr, uint64_t newval);
716e085f869SStanislav Sedov #endif
717e085f869SStanislav Sedov 
718004bedebSBruce Evans #endif /* !_MACHINE_CPUFUNC_H_ */
719