11817Sdg/*-
21817Sdg * Copyright (c) 1993 The Regents of the University of California.
31817Sdg * All rights reserved.
41817Sdg *
51817Sdg * Redistribution and use in source and binary forms, with or without
61817Sdg * modification, are permitted provided that the following conditions
71817Sdg * are met:
81817Sdg * 1. Redistributions of source code must retain the above copyright
91817Sdg *    notice, this list of conditions and the following disclaimer.
101817Sdg * 2. Redistributions in binary form must reproduce the above copyright
111817Sdg *    notice, this list of conditions and the following disclaimer in the
121817Sdg *    documentation and/or other materials provided with the distribution.
131817Sdg * 4. Neither the name of the University nor the names of its contributors
141817Sdg *    may be used to endorse or promote products derived from this software
151817Sdg *    without specific prior written permission.
161817Sdg *
171817Sdg * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181817Sdg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191817Sdg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201817Sdg * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211817Sdg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221817Sdg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231817Sdg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241817Sdg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251817Sdg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261817Sdg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271817Sdg * SUCH DAMAGE.
281817Sdg *
2950477Speter * $FreeBSD: stable/10/sys/i386/include/cpufunc.h 313150 2017-02-03 12:20:44Z kib $
301817Sdg */
311817Sdg
324Srgrimes/*
334Srgrimes * Functions to provide access to special i386 instructions.
3491497Smarkm * This in included in sys/systm.h, and that file should be
3591497Smarkm * used in preference to this.
364Srgrimes */
374Srgrimes
38719Swollman#ifndef _MACHINE_CPUFUNC_H_
394479Sbde#define	_MACHINE_CPUFUNC_H_
40719Swollman
41143063Sjoerg#ifndef _SYS_CDEFS_H_
42143063Sjoerg#error this file needs sys/cdefs.h as a prerequisite
43143063Sjoerg#endif
44143063Sjoerg
45181775Skmacy#ifdef XEN
46181775Skmacyextern void xen_cli(void);
47181775Skmacyextern void xen_sti(void);
48184040Skmacyextern u_int xen_rcr2(void);
49181775Skmacyextern void xen_load_cr3(u_int data);
50181775Skmacyextern void xen_tlb_flush(void);
51181775Skmacyextern void xen_invlpg(u_int addr);
52197693Skmacyextern void write_eflags(u_int eflags);
53197693Skmacyextern u_int read_eflags(void);
54181775Skmacy#endif
55181775Skmacy
56103778Speterstruct region_descriptor;
5793264Sdillon
58220627Sjkim#define readb(va)	(*(volatile uint8_t *) (va))
59220627Sjkim#define readw(va)	(*(volatile uint16_t *) (va))
60220627Sjkim#define readl(va)	(*(volatile uint32_t *) (va))
6138392Sdfr
62220627Sjkim#define writeb(va, d)	(*(volatile uint8_t *) (va) = (d))
63220627Sjkim#define writew(va, d)	(*(volatile uint16_t *) (va) = (d))
64220627Sjkim#define writel(va, d)	(*(volatile uint32_t *) (va) = (d))
6538392Sdfr
66143063Sjoerg#if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE)
674Srgrimes
6815122Sbdestatic __inline void
6915122Sbdebreakpoint(void)
703102Sdg{
714479Sbde	__asm __volatile("int $3");
723102Sdg}
733102Sdg
7455672Sbdestatic __inline u_int
7555672Sbdebsfl(u_int mask)
7655672Sbde{
7755672Sbde	u_int	result;
7855672Sbde
79194115Sed	__asm("bsfl %1,%0" : "=r" (result) : "rm" (mask) : "cc");
8055672Sbde	return (result);
8155672Sbde}
8255672Sbde
8355672Sbdestatic __inline u_int
8455672Sbdebsrl(u_int mask)
8555672Sbde{
8655672Sbde	u_int	result;
8755672Sbde
88194115Sed	__asm("bsrl %1,%0" : "=r" (result) : "rm" (mask) : "cc");
8955672Sbde	return (result);
9055672Sbde}
9155672Sbde
923102Sdgstatic __inline void
93195940Skibclflush(u_long addr)
94195940Skib{
95195940Skib
96195940Skib	__asm __volatile("clflush %0" : : "m" (*(char *)addr));
97195940Skib}
98195940Skib
99195940Skibstatic __inline void
100290189Skibclflushopt(u_long addr)
101290189Skib{
102290189Skib
103290189Skib	__asm __volatile(".byte 0x66;clflush %0" : : "m" (*(char *)addr));
104290189Skib}
105290189Skib
106290189Skibstatic __inline void
107238311Sjhbclts(void)
108238311Sjhb{
109238311Sjhb
110238311Sjhb	__asm __volatile("clts");
111238311Sjhb}
112238311Sjhb
113238311Sjhbstatic __inline void
1144479Sbdedisable_intr(void)
1153102Sdg{
116181775Skmacy#ifdef XEN
117181775Skmacy	xen_cli();
118181775Skmacy#else
119184040Skmacy	__asm __volatile("cli" : : : "memory");
120181775Skmacy#endif
1213102Sdg}
1223102Sdg
1233102Sdgstatic __inline void
12494386Sdwmalonedo_cpuid(u_int ax, u_int *p)
12594386Sdwmalone{
12694386Sdwmalone	__asm __volatile("cpuid"
12794386Sdwmalone			 : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
12894386Sdwmalone			 :  "0" (ax));
12994386Sdwmalone}
13094386Sdwmalone
13194386Sdwmalonestatic __inline void
132146170Snectarcpuid_count(u_int ax, u_int cx, u_int *p)
133146170Snectar{
134146170Snectar	__asm __volatile("cpuid"
135146170Snectar			 : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
136146170Snectar			 :  "0" (ax), "c" (cx));
137146170Snectar}
138146170Snectar
139146170Snectarstatic __inline void
1404479Sbdeenable_intr(void)
1413102Sdg{
142181775Skmacy#ifdef XEN
143181775Skmacy	xen_sti();
144184040Skmacy#else
14510342Sbde	__asm __volatile("sti");
146181775Skmacy#endif
1473102Sdg}
1483102Sdg
149197647Savgstatic __inline void
150223796Sjkimcpu_monitor(const void *addr, u_long extensions, u_int hints)
151178299Sjeff{
152223796Sjkim
153223796Sjkim	__asm __volatile("monitor"
154223796Sjkim	    : : "a" (addr), "c" (extensions), "d" (hints));
155178299Sjeff}
156178299Sjeff
157197647Savgstatic __inline void
158223796Sjkimcpu_mwait(u_long extensions, u_int hints)
159178299Sjeff{
160223796Sjkim
161223796Sjkim	__asm __volatile("mwait" : : "a" (hints), "c" (extensions));
162178299Sjeff}
163178299Sjeff
164195940Skibstatic __inline void
165238972Skiblfence(void)
166238972Skib{
167238972Skib
168238972Skib	__asm __volatile("lfence" : : : "memory");
169238972Skib}
170238972Skib
171238972Skibstatic __inline void
172195940Skibmfence(void)
173195940Skib{
174195940Skib
175195940Skib	__asm __volatile("mfence" : : : "memory");
176195940Skib}
177195940Skib
178313150Skibstatic __inline void
179313150Skibsfence(void)
180313150Skib{
181313150Skib
182313150Skib	__asm __volatile("sfence" : : : "memory");
183313150Skib}
184313150Skib
185126846Sbde#ifdef _KERNEL
186126846Sbde
18750054Speter#define	HAVE_INLINE_FFS
18850054Speter
18950054Speterstatic __inline int
19050054Speterffs(int mask)
19150054Speter{
19250054Speter	/*
1934479Sbde	 * Note that gcc-2's builtin ffs would be used if we didn't declare
1944479Sbde	 * this inline or turn off the builtin.  The builtin is faster but
19555672Sbde	 * broken in gcc-2.4.5 and slower but working in gcc-2.5 and later
19655672Sbde	 * versions.
1974479Sbde	 */
198100078Smarkm	 return (mask == 0 ? mask : (int)bsfl((u_int)mask) + 1);
19950054Speter}
20050054Speter
201289818Savg#define	HAVE_INLINE_FFSL
202289818Savg
203289818Savgstatic __inline int
204289818Savgffsl(long mask)
205289818Savg{
206289818Savg	return (ffs((int)mask));
207289818Savg}
208289818Savg
20917384Swollman#define	HAVE_INLINE_FLS
21017384Swollman
21117384Swollmanstatic __inline int
21217384Swollmanfls(int mask)
21317384Swollman{
214100078Smarkm	return (mask == 0 ? mask : (int)bsrl((u_int)mask) + 1);
21517384Swollman}
21617384Swollman
217289818Savg#define	HAVE_INLINE_FLSL
218289818Savg
219289818Savgstatic __inline int
220289818Savgflsl(long mask)
221289818Savg{
222289818Savg	return (fls((int)mask));
223289818Savg}
224289818Savg
225126846Sbde#endif /* _KERNEL */
226126846Sbde
227103749Smarkmstatic __inline void
228103749Smarkmhalt(void)
229103749Smarkm{
230103749Smarkm	__asm __volatile("hlt");
231103749Smarkm}
232103749Smarkm
2334479Sbdestatic __inline u_char
234190919Sedinb(u_int port)
2353102Sdg{
2364479Sbde	u_char	data;
2374479Sbde
238220629Sjkim	__asm __volatile("inb %w1, %0" : "=a" (data) : "Nd" (port));
2394479Sbde	return (data);
2403102Sdg}
2413102Sdg
24237552Sbdestatic __inline u_int
2434479Sbdeinl(u_int port)
2442826Sdg{
24537552Sbde	u_int	data;
2462826Sdg
247220629Sjkim	__asm __volatile("inl %w1, %0" : "=a" (data) : "Nd" (port));
2484479Sbde	return (data);
2492826Sdg}
2502826Sdg
2514479Sbdestatic __inline void
252201369Sobrieninsb(u_int port, void *addr, size_t count)
2532826Sdg{
2544479Sbde	__asm __volatile("cld; rep; insb"
255201369Sobrien			 : "+D" (addr), "+c" (count)
25688118Sjhb			 : "d" (port)
25742427Sbde			 : "memory");
2584479Sbde}
2592826Sdg
2604479Sbdestatic __inline void
261201369Sobrieninsw(u_int port, void *addr, size_t count)
2624479Sbde{
2634479Sbde	__asm __volatile("cld; rep; insw"
264201369Sobrien			 : "+D" (addr), "+c" (count)
26588118Sjhb			 : "d" (port)
26642427Sbde			 : "memory");
2672826Sdg}
2682826Sdg
2694479Sbdestatic __inline void
270201369Sobrieninsl(u_int port, void *addr, size_t count)
2712826Sdg{
2724479Sbde	__asm __volatile("cld; rep; insl"
273201369Sobrien			 : "+D" (addr), "+c" (count)
27488118Sjhb			 : "d" (port)
27542427Sbde			 : "memory");
2762826Sdg}
2772826Sdg
27818567Sbdestatic __inline void
27924112Skatoinvd(void)
28024112Skato{
28124112Skato	__asm __volatile("invd");
28224112Skato}
28324112Skato
2844479Sbdestatic __inline u_short
2854479Sbdeinw(u_int port)
2862826Sdg{
2874479Sbde	u_short	data;
2884479Sbde
289220629Sjkim	__asm __volatile("inw %w1, %0" : "=a" (data) : "Nd" (port));
2904479Sbde	return (data);
2912826Sdg}
2922826Sdg
2934479Sbdestatic __inline void
294190919Sedoutb(u_int port, u_char data)
2952826Sdg{
296190919Sed	__asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port));
2972826Sdg}
2982826Sdg
2994479Sbdestatic __inline void
30037552Sbdeoutl(u_int port, u_int data)
3014Srgrimes{
302220629Sjkim	__asm __volatile("outl %0, %w1" : : "a" (data), "Nd" (port));
3034Srgrimes}
3044Srgrimes
3054479Sbdestatic __inline void
306201369Sobrienoutsb(u_int port, const void *addr, size_t count)
3074Srgrimes{
3084479Sbde	__asm __volatile("cld; rep; outsb"
309201369Sobrien			 : "+S" (addr), "+c" (count)
31088118Sjhb			 : "d" (port));
3114Srgrimes}
3124Srgrimes
3134479Sbdestatic __inline void
314201369Sobrienoutsw(u_int port, const void *addr, size_t count)
3154Srgrimes{
3164479Sbde	__asm __volatile("cld; rep; outsw"
317201369Sobrien			 : "+S" (addr), "+c" (count)
31888118Sjhb			 : "d" (port));
3194Srgrimes}
3204Srgrimes
3214479Sbdestatic __inline void
322201369Sobrienoutsl(u_int port, const void *addr, size_t count)
3234Srgrimes{
3244479Sbde	__asm __volatile("cld; rep; outsl"
325201369Sobrien			 : "+S" (addr), "+c" (count)
32688118Sjhb			 : "d" (port));
3274Srgrimes}
3284Srgrimes
3294479Sbdestatic __inline void
3304479Sbdeoutw(u_int port, u_short data)
3314Srgrimes{
332220629Sjkim	__asm __volatile("outw %0, %w1" : : "a" (data), "Nd" (port));
3334Srgrimes}
3344Srgrimes
33597114Sjhbstatic __inline void
33697139Sjhbia32_pause(void)
33797114Sjhb{
33897114Sjhb	__asm __volatile("pause");
33997114Sjhb}
34097114Sjhb
34137552Sbdestatic __inline u_int
342197693Skmacy#ifdef XEN
343197693Skmacy_read_eflags(void)
344197693Skmacy#else
3454479Sbderead_eflags(void)
346197693Skmacy#endif
3474479Sbde{
34837552Sbde	u_int	ef;
3494479Sbde
3508876Srgrimes	__asm __volatile("pushfl; popl %0" : "=r" (ef));
3514479Sbde	return (ef);
3524479Sbde}
3534479Sbde
354171797Snjlstatic __inline uint64_t
35515122Sbderdmsr(u_int msr)
3564479Sbde{
357171797Snjl	uint64_t rv;
35815122Sbde
35969006Smarkm	__asm __volatile("rdmsr" : "=A" (rv) : "c" (msr));
36015122Sbde	return (rv);
3614479Sbde}
3624479Sbde
363171797Snjlstatic __inline uint64_t
36415122Sbderdpmc(u_int pmc)
36514825Swollman{
366171797Snjl	uint64_t rv;
36715122Sbde
36869006Smarkm	__asm __volatile("rdpmc" : "=A" (rv) : "c" (pmc));
36915122Sbde	return (rv);
37014825Swollman}
37114825Swollman
372171797Snjlstatic __inline uint64_t
37314825Swollmanrdtsc(void)
37414825Swollman{
375171797Snjl	uint64_t rv;
37615122Sbde
37769006Smarkm	__asm __volatile("rdtsc" : "=A" (rv));
37815122Sbde	return (rv);
37914825Swollman}
38014825Swollman
381220631Sjkimstatic __inline uint32_t
382220631Sjkimrdtsc32(void)
383220631Sjkim{
384220631Sjkim	uint32_t rv;
385220631Sjkim
386220631Sjkim	__asm __volatile("rdtsc" : "=a" (rv) : : "edx");
387220631Sjkim	return (rv);
388220631Sjkim}
389220631Sjkim
39015122Sbdestatic __inline void
39124112Skatowbinvd(void)
39224112Skato{
39324112Skato	__asm __volatile("wbinvd");
39424112Skato}
39524112Skato
39624112Skatostatic __inline void
397197693Skmacy#ifdef XEN
398197693Skmacy_write_eflags(u_int ef)
399197693Skmacy#else
40037552Sbdewrite_eflags(u_int ef)
401197693Skmacy#endif
40214825Swollman{
40315122Sbde	__asm __volatile("pushl %0; popfl" : : "r" (ef));
40414825Swollman}
40514825Swollman
40614825Swollmanstatic __inline void
407171797Snjlwrmsr(u_int msr, uint64_t newval)
40814825Swollman{
40969006Smarkm	__asm __volatile("wrmsr" : : "A" (newval), "c" (msr));
41014825Swollman}
41114825Swollman
41299862Speterstatic __inline void
41399862Speterload_cr0(u_int data)
41499862Speter{
41599862Speter
41699862Speter	__asm __volatile("movl %0,%%cr0" : : "r" (data));
41799862Speter}
41899862Speter
41946129Sluoqistatic __inline u_int
42099862Speterrcr0(void)
42199862Speter{
42299862Speter	u_int	data;
42399862Speter
42499862Speter	__asm __volatile("movl %%cr0,%0" : "=r" (data));
42599862Speter	return (data);
42699862Speter}
42799862Speter
42899862Speterstatic __inline u_int
42999862Speterrcr2(void)
43099862Speter{
43199862Speter	u_int	data;
43299862Speter
433184040Skmacy#ifdef XEN
434184040Skmacy	return (xen_rcr2());
435184040Skmacy#endif
43699862Speter	__asm __volatile("movl %%cr2,%0" : "=r" (data));
43799862Speter	return (data);
43899862Speter}
43999862Speter
44099862Speterstatic __inline void
44199862Speterload_cr3(u_int data)
44299862Speter{
443181775Skmacy#ifdef XEN
444181775Skmacy	xen_load_cr3(data);
445181775Skmacy#else
44699862Speter	__asm __volatile("movl %0,%%cr3" : : "r" (data) : "memory");
447181775Skmacy#endif
44899862Speter}
44999862Speter
45099862Speterstatic __inline u_int
45199862Speterrcr3(void)
45299862Speter{
45399862Speter	u_int	data;
45499862Speter
45599862Speter	__asm __volatile("movl %%cr3,%0" : "=r" (data));
45699862Speter	return (data);
45799862Speter}
45899862Speter
45999862Speterstatic __inline void
46099862Speterload_cr4(u_int data)
46199862Speter{
46299862Speter	__asm __volatile("movl %0,%%cr4" : : "r" (data));
46399862Speter}
46499862Speter
46599862Speterstatic __inline u_int
46699862Speterrcr4(void)
46799862Speter{
46899862Speter	u_int	data;
46999862Speter
47099862Speter	__asm __volatile("movl %%cr4,%0" : "=r" (data));
47199862Speter	return (data);
47299862Speter}
47399862Speter
474276084Sjhbstatic __inline uint64_t
475276084Sjhbrxcr(u_int reg)
476276084Sjhb{
477276084Sjhb	u_int low, high;
478276084Sjhb
479276084Sjhb	__asm __volatile("xgetbv" : "=a" (low), "=d" (high) : "c" (reg));
480276084Sjhb	return (low | ((uint64_t)high << 32));
481276084Sjhb}
482276084Sjhb
483276084Sjhbstatic __inline void
484276084Sjhbload_xcr(u_int reg, uint64_t val)
485276084Sjhb{
486276084Sjhb	u_int low, high;
487276084Sjhb
488276084Sjhb	low = val;
489276084Sjhb	high = val >> 32;
490276084Sjhb	__asm __volatile("xsetbv" : : "c" (reg), "a" (low), "d" (high));
491276084Sjhb}
492276084Sjhb
49399862Speter/*
49499862Speter * Global TLB flush (except for thise for pages marked PG_G)
49599862Speter */
49699862Speterstatic __inline void
49799862Speterinvltlb(void)
49899862Speter{
499181775Skmacy#ifdef XEN
500181775Skmacy	xen_tlb_flush();
501181775Skmacy#else
50299862Speter	load_cr3(rcr3());
503181775Skmacy#endif
50499862Speter}
50599862Speter
50699862Speter/*
50799862Speter * TLB flush for an individual page (even if it has PG_G).
50899862Speter * Only works on 486+ CPUs (i386 does not have PG_G).
50999862Speter */
51099862Speterstatic __inline void
51199862Speterinvlpg(u_int addr)
51299862Speter{
51399862Speter
514181775Skmacy#ifdef XEN
515181775Skmacy	xen_invlpg(addr);
516181775Skmacy#else
51799862Speter	__asm __volatile("invlpg %0" : : "m" (*(char *)addr) : "memory");
518181775Skmacy#endif
51999862Speter}
52099862Speter
521212177Srdivackystatic __inline u_short
52246129Sluoqirfs(void)
52346129Sluoqi{
524212177Srdivacky	u_short sel;
525212177Srdivacky	__asm __volatile("movw %%fs,%0" : "=rm" (sel));
52646129Sluoqi	return (sel);
52746129Sluoqi}
52846129Sluoqi
529171797Snjlstatic __inline uint64_t
530171797Snjlrgdt(void)
531171797Snjl{
532171797Snjl	uint64_t gdtr;
533171797Snjl	__asm __volatile("sgdt %0" : "=m" (gdtr));
534171797Snjl	return (gdtr);
535171797Snjl}
536171797Snjl
537212177Srdivackystatic __inline u_short
53846129Sluoqirgs(void)
53946129Sluoqi{
540212177Srdivacky	u_short sel;
541212177Srdivacky	__asm __volatile("movw %%gs,%0" : "=rm" (sel));
54246129Sluoqi	return (sel);
54346129Sluoqi}
54446129Sluoqi
545171797Snjlstatic __inline uint64_t
546171797Snjlridt(void)
547171797Snjl{
548171797Snjl	uint64_t idtr;
549171797Snjl	__asm __volatile("sidt %0" : "=m" (idtr));
550171797Snjl	return (idtr);
551171797Snjl}
552171797Snjl
553171797Snjlstatic __inline u_short
554171797Snjlrldt(void)
555171797Snjl{
556171797Snjl	u_short ldtr;
557171797Snjl	__asm __volatile("sldt %0" : "=g" (ldtr));
558171797Snjl	return (ldtr);
559171797Snjl}
560171797Snjl
561212177Srdivackystatic __inline u_short
562127813Smarcelrss(void)
563127813Smarcel{
564212177Srdivacky	u_short sel;
565212177Srdivacky	__asm __volatile("movw %%ss,%0" : "=rm" (sel));
566127813Smarcel	return (sel);
567127813Smarcel}
568127813Smarcel
569171797Snjlstatic __inline u_short
570171797Snjlrtr(void)
571171797Snjl{
572171797Snjl	u_short tr;
573171797Snjl	__asm __volatile("str %0" : "=g" (tr));
574171797Snjl	return (tr);
575171797Snjl}
576171797Snjl
57746129Sluoqistatic __inline void
578212177Srdivackyload_fs(u_short sel)
57946129Sluoqi{
580212177Srdivacky	__asm __volatile("movw %0,%%fs" : : "rm" (sel));
58146129Sluoqi}
58246129Sluoqi
58346129Sluoqistatic __inline void
584212177Srdivackyload_gs(u_short sel)
58546129Sluoqi{
586212177Srdivacky	__asm __volatile("movw %0,%%gs" : : "rm" (sel));
58746129Sluoqi}
58846129Sluoqi
589103778Speterstatic __inline void
590103778Speterlidt(struct region_descriptor *addr)
591103778Speter{
592103778Speter	__asm __volatile("lidt (%0)" : : "r" (addr));
593103778Speter}
594103778Speter
595103778Speterstatic __inline void
596103778Speterlldt(u_short sel)
597103778Speter{
598103778Speter	__asm __volatile("lldt %0" : : "r" (sel));
599103778Speter}
600103778Speter
601103778Speterstatic __inline void
602103778Speterltr(u_short sel)
603103778Speter{
604103778Speter	__asm __volatile("ltr %0" : : "r" (sel));
605103778Speter}
606103778Speter
60757362Sbsdstatic __inline u_int
60857362Sbsdrdr0(void)
60957362Sbsd{
61057362Sbsd	u_int	data;
61157376Sbsd	__asm __volatile("movl %%dr0,%0" : "=r" (data));
61257362Sbsd	return (data);
61357362Sbsd}
61457362Sbsd
61578903Sbsdstatic __inline void
61697115Sjhbload_dr0(u_int dr0)
61778903Sbsd{
61897115Sjhb	__asm __volatile("movl %0,%%dr0" : : "r" (dr0));
61978903Sbsd}
62078903Sbsd
62157362Sbsdstatic __inline u_int
62257362Sbsdrdr1(void)
62357362Sbsd{
62457362Sbsd	u_int	data;
62557376Sbsd	__asm __volatile("movl %%dr1,%0" : "=r" (data));
62657362Sbsd	return (data);
62757362Sbsd}
62857362Sbsd
62978903Sbsdstatic __inline void
63097115Sjhbload_dr1(u_int dr1)
63178903Sbsd{
63297115Sjhb	__asm __volatile("movl %0,%%dr1" : : "r" (dr1));
63378903Sbsd}
63478903Sbsd
63557362Sbsdstatic __inline u_int
63657362Sbsdrdr2(void)
63757362Sbsd{
63857362Sbsd	u_int	data;
63957376Sbsd	__asm __volatile("movl %%dr2,%0" : "=r" (data));
64057362Sbsd	return (data);
64157362Sbsd}
64257362Sbsd
64378903Sbsdstatic __inline void
64497115Sjhbload_dr2(u_int dr2)
64578903Sbsd{
64697115Sjhb	__asm __volatile("movl %0,%%dr2" : : "r" (dr2));
64778903Sbsd}
64878903Sbsd
64957362Sbsdstatic __inline u_int
65057362Sbsdrdr3(void)
65157362Sbsd{
65257362Sbsd	u_int	data;
65357376Sbsd	__asm __volatile("movl %%dr3,%0" : "=r" (data));
65457362Sbsd	return (data);
65557362Sbsd}
65657362Sbsd
65778903Sbsdstatic __inline void
65897115Sjhbload_dr3(u_int dr3)
65978903Sbsd{
66097115Sjhb	__asm __volatile("movl %0,%%dr3" : : "r" (dr3));
66178903Sbsd}
66278903Sbsd
66357362Sbsdstatic __inline u_int
66478903Sbsdrdr4(void)
66578903Sbsd{
66678903Sbsd	u_int	data;
66778903Sbsd	__asm __volatile("movl %%dr4,%0" : "=r" (data));
66878903Sbsd	return (data);
66978903Sbsd}
67078903Sbsd
67178903Sbsdstatic __inline void
67297115Sjhbload_dr4(u_int dr4)
67378903Sbsd{
67497115Sjhb	__asm __volatile("movl %0,%%dr4" : : "r" (dr4));
67578903Sbsd}
67678903Sbsd
67778903Sbsdstatic __inline u_int
67878903Sbsdrdr5(void)
67978903Sbsd{
68078903Sbsd	u_int	data;
68178903Sbsd	__asm __volatile("movl %%dr5,%0" : "=r" (data));
68278903Sbsd	return (data);
68378903Sbsd}
68478903Sbsd
68578903Sbsdstatic __inline void
68697115Sjhbload_dr5(u_int dr5)
68778903Sbsd{
68897115Sjhb	__asm __volatile("movl %0,%%dr5" : : "r" (dr5));
68978903Sbsd}
69078903Sbsd
69178903Sbsdstatic __inline u_int
69257362Sbsdrdr6(void)
69357362Sbsd{
69457362Sbsd	u_int	data;
69557376Sbsd	__asm __volatile("movl %%dr6,%0" : "=r" (data));
69657362Sbsd	return (data);
69757362Sbsd}
69857362Sbsd
69978903Sbsdstatic __inline void
70097115Sjhbload_dr6(u_int dr6)
70178903Sbsd{
70297115Sjhb	__asm __volatile("movl %0,%%dr6" : : "r" (dr6));
70378903Sbsd}
70478903Sbsd
70557362Sbsdstatic __inline u_int
70657362Sbsdrdr7(void)
70757362Sbsd{
70857362Sbsd	u_int	data;
70957376Sbsd	__asm __volatile("movl %%dr7,%0" : "=r" (data));
71057362Sbsd	return (data);
71157362Sbsd}
71257362Sbsd
71378903Sbsdstatic __inline void
71497115Sjhbload_dr7(u_int dr7)
71578903Sbsd{
71697115Sjhb	__asm __volatile("movl %0,%%dr7" : : "r" (dr7));
71778903Sbsd}
71878903Sbsd
719194295Sjhbstatic __inline u_char
720194295Sjhbread_cyrix_reg(u_char reg)
721194295Sjhb{
722194295Sjhb	outb(0x22, reg);
723194295Sjhb	return inb(0x23);
724194295Sjhb}
725194295Sjhb
726194295Sjhbstatic __inline void
727194295Sjhbwrite_cyrix_reg(u_char reg, u_char data)
728194295Sjhb{
729194295Sjhb	outb(0x22, reg);
730194295Sjhb	outb(0x23, data);
731194295Sjhb}
732194295Sjhb
73392860Simpstatic __inline register_t
73492860Simpintr_disable(void)
73592860Simp{
736181911Skmacy	register_t eflags;
73792860Simp
73892860Simp	eflags = read_eflags();
73992860Simp	disable_intr();
74092860Simp	return (eflags);
74192860Simp}
74292860Simp
74392860Simpstatic __inline void
74492860Simpintr_restore(register_t eflags)
74592860Simp{
74692860Simp	write_eflags(eflags);
74792860Simp}
74892860Simp
749143063Sjoerg#else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */
7504Srgrimes
75192819Simpint	breakpoint(void);
75292819Simpu_int	bsfl(u_int mask);
75392819Simpu_int	bsrl(u_int mask);
754238311Sjhbvoid	clflush(u_long addr);
755238311Sjhbvoid	clts(void);
756238311Sjhbvoid	cpuid_count(u_int ax, u_int cx, u_int *p);
75792819Simpvoid	disable_intr(void);
75892819Simpvoid	do_cpuid(u_int ax, u_int *p);
75992819Simpvoid	enable_intr(void);
760103749Smarkmvoid	halt(void);
761126656Sbdevoid	ia32_pause(void);
76292819Simpu_char	inb(u_int port);
76392819Simpu_int	inl(u_int port);
764201369Sobrienvoid	insb(u_int port, void *addr, size_t count);
765201369Sobrienvoid	insl(u_int port, void *addr, size_t count);
766201369Sobrienvoid	insw(u_int port, void *addr, size_t count);
767126656Sbderegister_t	intr_disable(void);
768126656Sbdevoid	intr_restore(register_t ef);
76992819Simpvoid	invd(void);
77092819Simpvoid	invlpg(u_int addr);
77192819Simpvoid	invltlb(void);
77292819Simpu_short	inw(u_int port);
773126656Sbdevoid	lidt(struct region_descriptor *addr);
774126656Sbdevoid	lldt(u_short sel);
77599862Spetervoid	load_cr0(u_int cr0);
77699862Spetervoid	load_cr3(u_int cr3);
77799862Spetervoid	load_cr4(u_int cr4);
778126656Sbdevoid	load_dr0(u_int dr0);
779126656Sbdevoid	load_dr1(u_int dr1);
780126656Sbdevoid	load_dr2(u_int dr2);
781126656Sbdevoid	load_dr3(u_int dr3);
782126656Sbdevoid	load_dr4(u_int dr4);
783126656Sbdevoid	load_dr5(u_int dr5);
784126656Sbdevoid	load_dr6(u_int dr6);
785126656Sbdevoid	load_dr7(u_int dr7);
786212177Srdivackyvoid	load_fs(u_short sel);
787212177Srdivackyvoid	load_gs(u_short sel);
788103778Spetervoid	ltr(u_short sel);
78992819Simpvoid	outb(u_int port, u_char data);
79092819Simpvoid	outl(u_int port, u_int data);
791201369Sobrienvoid	outsb(u_int port, const void *addr, size_t count);
792201369Sobrienvoid	outsl(u_int port, const void *addr, size_t count);
793201369Sobrienvoid	outsw(u_int port, const void *addr, size_t count);
79492819Simpvoid	outw(u_int port, u_short data);
79599862Speteru_int	rcr0(void);
79692819Simpu_int	rcr2(void);
79799862Speteru_int	rcr3(void);
79899862Speteru_int	rcr4(void);
799171797Snjluint64_t rdmsr(u_int msr);
800171797Snjluint64_t rdpmc(u_int pmc);
80197114Sjhbu_int	rdr0(void);
80297114Sjhbu_int	rdr1(void);
80397114Sjhbu_int	rdr2(void);
80497114Sjhbu_int	rdr3(void);
80597114Sjhbu_int	rdr4(void);
80697114Sjhbu_int	rdr5(void);
80797114Sjhbu_int	rdr6(void);
80897114Sjhbu_int	rdr7(void);
809171797Snjluint64_t rdtsc(void);
810194295Sjhbu_char	read_cyrix_reg(u_char reg);
811126656Sbdeu_int	read_eflags(void);
812126656Sbdeu_int	rfs(void);
813171797Snjluint64_t rgdt(void);
814126656Sbdeu_int	rgs(void);
815171797Snjluint64_t ridt(void);
816171797Snjlu_short	rldt(void);
817171797Snjlu_short	rtr(void);
818126656Sbdevoid	wbinvd(void);
819194295Sjhbvoid	write_cyrix_reg(u_char reg, u_char data);
820126656Sbdevoid	write_eflags(u_int ef);
821171797Snjlvoid	wrmsr(u_int msr, uint64_t newval);
8224Srgrimes
823143063Sjoerg#endif	/* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */
8244Srgrimes
82592761Salfredvoid    reset_dbregs(void);
82693264Sdillon
827181430Sstas#ifdef _KERNEL
828181430Sstasint	rdmsr_safe(u_int msr, uint64_t *val);
829181430Sstasint	wrmsr_safe(u_int msr, uint64_t newval);
830181430Sstas#endif
831181430Sstas
8324479Sbde#endif /* !_MACHINE_CPUFUNC_H_ */
833