1199767fToomas Soome/*-
2199767fToomas Soome * Copyright (c) 1993 The Regents of the University of California.
3199767fToomas Soome * All rights reserved.
4199767fToomas Soome *
5199767fToomas Soome * Redistribution and use in source and binary forms, with or without
6199767fToomas Soome * modification, are permitted provided that the following conditions
7199767fToomas Soome * are met:
8199767fToomas Soome * 1. Redistributions of source code must retain the above copyright
9199767fToomas Soome *    notice, this list of conditions and the following disclaimer.
10199767fToomas Soome * 2. Redistributions in binary form must reproduce the above copyright
11199767fToomas Soome *    notice, this list of conditions and the following disclaimer in the
12199767fToomas Soome *    documentation and/or other materials provided with the distribution.
13199767fToomas Soome * 4. Neither the name of the University nor the names of its contributors
14199767fToomas Soome *    may be used to endorse or promote products derived from this software
15199767fToomas Soome *    without specific prior written permission.
16199767fToomas Soome *
17199767fToomas Soome * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18199767fToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19199767fToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20199767fToomas Soome * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21199767fToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22199767fToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23199767fToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24199767fToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25199767fToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26199767fToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27199767fToomas Soome * SUCH DAMAGE.
28199767fToomas Soome *
29199767fToomas Soome * $FreeBSD$
30199767fToomas Soome */
31199767fToomas Soome
32199767fToomas Soome/*
33199767fToomas Soome * Functions to provide access to special i386 instructions.
34199767fToomas Soome * This in included in sys/systm.h, and that file should be
35199767fToomas Soome * used in preference to this.
36199767fToomas Soome */
37199767fToomas Soome
38199767fToomas Soome#ifndef _MACHINE_CPUFUNC_H_
39199767fToomas Soome#define	_MACHINE_CPUFUNC_H_
40199767fToomas Soome
41199767fToomas Soome#ifndef _SYS_CDEFS_H_
42199767fToomas Soome#error this file needs sys/cdefs.h as a prerequisite
43199767fToomas Soome#endif
44199767fToomas Soome
45199767fToomas Soomestruct region_descriptor;
46199767fToomas Soome
47199767fToomas Soome#define readb(va)	(*(volatile uint8_t *) (va))
48199767fToomas Soome#define readw(va)	(*(volatile uint16_t *) (va))
49199767fToomas Soome#define readl(va)	(*(volatile uint32_t *) (va))
50199767fToomas Soome
51199767fToomas Soome#define writeb(va, d)	(*(volatile uint8_t *) (va) = (d))
52199767fToomas Soome#define writew(va, d)	(*(volatile uint16_t *) (va) = (d))
53199767fToomas Soome#define writel(va, d)	(*(volatile uint32_t *) (va) = (d))
54199767fToomas Soome
55199767fToomas Soome#if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE)
56199767fToomas Soome
57199767fToomas Soomestatic __inline void
58199767fToomas Soomebreakpoint(void)
59199767fToomas Soome{
60199767fToomas Soome	__asm __volatile("int $3");
61199767fToomas Soome}
62199767fToomas Soome
63199767fToomas Soomestatic __inline u_int
64199767fToomas Soomebsfl(u_int mask)
65199767fToomas Soome{
66199767fToomas Soome	u_int	result;
67199767fToomas Soome
68199767fToomas Soome	__asm("bsfl %1,%0" : "=r" (result) : "rm" (mask) : "cc");
69199767fToomas Soome	return (result);
70199767fToomas Soome}
71199767fToomas Soome
72199767fToomas Soomestatic __inline u_int
73199767fToomas Soomebsrl(u_int mask)
74199767fToomas Soome{
75199767fToomas Soome	u_int	result;
76199767fToomas Soome
77199767fToomas Soome	__asm("bsrl %1,%0" : "=r" (result) : "rm" (mask) : "cc");
78199767fToomas Soome	return (result);
79199767fToomas Soome}
80199767fToomas Soome
81199767fToomas Soomestatic __inline void
82199767fToomas Soomeclflush(u_long addr)
83199767fToomas Soome{
84199767fToomas Soome
85199767fToomas Soome	__asm __volatile("clflush %0" : : "m" (*(char *)addr));
86199767fToomas Soome}
87199767fToomas Soome
88199767fToomas Soomestatic __inline void
89199767fToomas Soomeclflushopt(u_long addr)
90199767fToomas Soome{
91199767fToomas Soome
92199767fToomas Soome	__asm __volatile(".byte 0x66;clflush %0" : : "m" (*(char *)addr));
93199767fToomas Soome}
94199767fToomas Soome
95199767fToomas Soomestatic __inline void
96199767fToomas Soomeclts(void)
97199767fToomas Soome{
98199767fToomas Soome
99199767fToomas Soome	__asm __volatile("clts");
100199767fToomas Soome}
101199767fToomas Soome
102199767fToomas Soomestatic __inline void
103199767fToomas Soomedisable_intr(void)
104199767fToomas Soome{
105199767fToomas Soome
106199767fToomas Soome	__asm __volatile("cli" : : : "memory");
107199767fToomas Soome}
108199767fToomas Soome
109199767fToomas Soomestatic __inline void
110199767fToomas Soomedo_cpuid(u_int ax, u_int *p)
111199767fToomas Soome{
1126efcf43Toomas Soome	__asm __volatile("pushl %%ebx      \n\t"
1136efcf43Toomas Soome			 "cpuid            \n\t"
1146efcf43Toomas Soome			 "movl %%ebx, %1   \n\t"
1156efcf43Toomas Soome			 "popl %%ebx       \n\t"
1166efcf43Toomas Soome			 : "=a" (p[0]), "=m" (p[1]), "=c" (p[2]), "=d" (p[3])
1176efcf43Toomas Soome			 : "0" (ax));
118199767fToomas Soome}
119199767fToomas Soome
120199767fToomas Soomestatic __inline void
121199767fToomas Soomecpuid_count(u_int ax, u_int cx, u_int *p)
122199767fToomas Soome{
123199767fToomas Soome	__asm __volatile("cpuid"
124199767fToomas Soome			 : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
125199767fToomas Soome			 :  "0" (ax), "c" (cx));
126199767fToomas Soome}
127199767fToomas Soome
128199767fToomas Soomestatic __inline void
129199767fToomas Soomeenable_intr(void)
130199767fToomas Soome{
131199767fToomas Soome
132199767fToomas Soome	__asm __volatile("sti");
133199767fToomas Soome}
134199767fToomas Soome
135199767fToomas Soomestatic __inline void
136199767fToomas Soomecpu_monitor(const void *addr, u_long extensions, u_int hints)
137199767fToomas Soome{
138199767fToomas Soome
139199767fToomas Soome	__asm __volatile("monitor"
140199767fToomas Soome	    : : "a" (addr), "c" (extensions), "d" (hints));
141199767fToomas Soome}
142199767fToomas Soome
143199767fToomas Soomestatic __inline void
144199767fToomas Soomecpu_mwait(u_long extensions, u_int hints)
145199767fToomas Soome{
146199767fToomas Soome
147199767fToomas Soome	__asm __volatile("mwait" : : "a" (hints), "c" (extensions));
148199767fToomas Soome}
149199767fToomas Soome
150199767fToomas Soomestatic __inline void
151199767fToomas Soomelfence(void)
152199767fToomas Soome{
153199767fToomas Soome
154199767fToomas Soome	__asm __volatile("lfence" : : : "memory");
155199767fToomas Soome}
156199767fToomas Soome
157199767fToomas Soomestatic __inline void
158199767fToomas Soomemfence(void)
159199767fToomas Soome{
160199767fToomas Soome
161199767fToomas Soome	__asm __volatile("mfence" : : : "memory");
162199767fToomas Soome}
163199767fToomas Soome
164199767fToomas Soome#ifdef _KERNEL
165199767fToomas Soome
166199767fToomas Soome#define	HAVE_INLINE_FFS
167199767fToomas Soome
168199767fToomas Soomestatic __inline int
169199767fToomas Soomeffs(int mask)
170199767fToomas Soome{
171199767fToomas Soome	/*
172199767fToomas Soome	 * Note that gcc-2's builtin ffs would be used if we didn't declare
173199767fToomas Soome	 * this inline or turn off the builtin.  The builtin is faster but
174199767fToomas Soome	 * broken in gcc-2.4.5 and slower but working in gcc-2.5 and later
175199767fToomas Soome	 * versions.
176199767fToomas Soome	 */
177199767fToomas Soome	 return (mask == 0 ? mask : (int)bsfl((u_int)mask) + 1);
178199767fToomas Soome}
179199767fToomas Soome
180199767fToomas Soome#define	HAVE_INLINE_FFSL
181199767fToomas Soome
182199767fToomas Soomestatic __inline int
183199767fToomas Soomeffsl(long mask)
184199767fToomas Soome{
185199767fToomas Soome	return (ffs((int)mask));
186199767fToomas Soome}
187199767fToomas Soome
188199767fToomas Soome#define	HAVE_INLINE_FLS
189199767fToomas Soome
190199767fToomas Soomestatic __inline int
191199767fToomas Soomefls(int mask)
192199767fToomas Soome{
193199767fToomas Soome	return (mask == 0 ? mask : (int)bsrl((u_int)mask) + 1);
194199767fToomas Soome}
195199767fToomas Soome
196199767fToomas Soome#define	HAVE_INLINE_FLSL
197199767fToomas Soome
198199767fToomas Soomestatic __inline int
199199767fToomas Soomeflsl(long mask)
200199767fToomas Soome{
201199767fToomas Soome	return (fls((int)mask));
202199767fToomas Soome}
203199767fToomas Soome
204199767fToomas Soome#endif /* _KERNEL */
205199767fToomas Soome
206199767fToomas Soomestatic __inline void
207199767fToomas Soomehalt(void)
208199767fToomas Soome{
209199767fToomas Soome	__asm __volatile("hlt");
210199767fToomas Soome}
211199767fToomas Soome
212199767fToomas Soomestatic __inline u_char
213199767fToomas Soomeinb(u_int port)
214199767fToomas Soome{
215199767fToomas Soome	u_char	data;
216199767fToomas Soome
217199767fToomas Soome	__asm __volatile("inb %w1, %0" : "=a" (data) : "Nd" (port));
218199767fToomas Soome	return (data);
219199767fToomas Soome}
220199767fToomas Soome
221199767fToomas Soomestatic __inline u_int
222199767fToomas Soomeinl(u_int port)
223199767fToomas Soome{
224199767fToomas Soome	u_int	data;
225199767fToomas Soome
226199767fToomas Soome	__asm __volatile("inl %w1, %0" : "=a" (data) : "Nd" (port));
227199767fToomas Soome	return (data);
228199767fToomas Soome}
229199767fToomas Soome
230199767fToomas Soomestatic __inline void
231199767fToomas Soomeinsb(u_int port, void *addr, size_t count)
232199767fToomas Soome{
233199767fToomas Soome	__asm __volatile("cld; rep; insb"
234199767fToomas Soome			 : "+D" (addr), "+c" (count)
235199767fToomas Soome			 : "d" (port)
236199767fToomas Soome			 : "memory");
237199767fToomas Soome}
238199767fToomas Soome
239199767fToomas Soomestatic __inline void
240199767fToomas Soomeinsw(u_int port, void *addr, size_t count)
241199767fToomas Soome{
242199767fToomas Soome	__asm __volatile("cld; rep; insw"
243199767fToomas Soome			 : "+D" (addr), "+c" (count)
244199767fToomas Soome			 : "d" (port)
245199767fToomas Soome			 : "memory");
246199767fToomas Soome}
247199767fToomas Soome
248199767fToomas Soomestatic __inline void
249199767fToomas Soomeinsl(u_int port, void *addr, size_t count)
250199767fToomas Soome{
251199767fToomas Soome	__asm __volatile("cld; rep; insl"
252199767fToomas Soome			 : "+D" (addr), "+c" (count)
253199767fToomas Soome			 : "d" (port)
254199767fToomas Soome			 : "memory");
255199767fToomas Soome}
256199767fToomas Soome
257199767fToomas Soomestatic __inline void
258199767fToomas Soomeinvd(void)
259199767fToomas Soome{
260199767fToomas Soome	__asm __volatile("invd");
261199767fToomas Soome}
262199767fToomas Soome
263199767fToomas Soomestatic __inline u_short
264199767fToomas Soomeinw(u_int port)
265199767fToomas Soome{
266199767fToomas Soome	u_short	data;
267199767fToomas Soome
268199767fToomas Soome	__asm __volatile("inw %w1, %0" : "=a" (data) : "Nd" (port));
269199767fToomas Soome	return (data);
270199767fToomas Soome}
271199767fToomas Soome
272199767fToomas Soomestatic __inline void
273199767fToomas Soomeoutb(u_int port, u_char data)
274199767fToomas Soome{
275199767fToomas Soome	__asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port));
276199767fToomas Soome}
277199767fToomas Soome
278199767fToomas Soomestatic __inline void
279199767fToomas Soomeoutl(u_int port, u_int data)
280199767fToomas Soome{
281199767fToomas Soome	__asm __volatile("outl %0, %w1" : : "a" (data), "Nd" (port));
282199767fToomas Soome}
283199767fToomas Soome
284199767fToomas Soomestatic __inline void
285199767fToomas Soomeoutsb(u_int port, const void *addr, size_t count)
286199767fToomas Soome{
287199767fToomas Soome	__asm __volatile("cld; rep; outsb"
288199767fToomas Soome			 : "+S" (addr), "+c" (count)
289199767fToomas Soome			 : "d" (port));
290199767fToomas Soome}
291199767fToomas Soome
292199767fToomas Soomestatic __inline void
293199767fToomas Soomeoutsw(u_int port, const void *addr, size_t count)
294199767fToomas Soome{
295199767fToomas Soome	__asm __volatile("cld; rep; outsw"
296199767fToomas Soome			 : "+S" (addr), "+c" (count)
297199767fToomas Soome			 : "d" (port));
298199767fToomas Soome}
299199767fToomas Soome
300199767fToomas Soomestatic __inline void
301199767fToomas Soomeoutsl(u_int port, const void *addr, size_t count)
302199767fToomas Soome{
303199767fToomas Soome	__asm __volatile("cld; rep; outsl"
304199767fToomas Soome			 : "+S" (addr), "+c" (count)
305199767fToomas Soome			 : "d" (port));
306199767fToomas Soome}
307199767fToomas Soome
308199767fToomas Soomestatic __inline void
309199767fToomas Soomeoutw(u_int port, u_short data)
310199767fToomas Soome{
311199767fToomas Soome	__asm __volatile("outw %0, %w1" : : "a" (data), "Nd" (port));
312199767fToomas Soome}
313199767fToomas Soome
314199767fToomas Soomestatic __inline void
315199767fToomas Soomeia32_pause(void)
316199767fToomas Soome{
317199767fToomas Soome	__asm __volatile("pause");
318199767fToomas Soome}
319199767fToomas Soome
320199767fToomas Soomestatic __inline u_int
321199767fToomas Soomeread_eflags(void)
322199767fToomas Soome{
323199767fToomas Soome	u_int	ef;
324199767fToomas Soome
325199767fToomas Soome	__asm __volatile("pushfl; popl %0" : "=r" (ef));
326199767fToomas Soome	return (ef);
327199767fToomas Soome}
328199767fToomas Soome
329199767fToomas Soomestatic __inline uint64_t
330199767fToomas Soomerdmsr(u_int msr)
331199767fToomas Soome{
332199767fToomas Soome	uint64_t rv;
333199767fToomas Soome
334199767fToomas Soome	__asm __volatile("rdmsr" : "=A" (rv) : "c" (msr));
335199767fToomas Soome	return (rv);
336199767fToomas Soome}
337199767fToomas Soome
338199767fToomas Soomestatic __inline uint32_t
339199767fToomas Soomerdmsr32(u_int msr)
340199767fToomas Soome{
341199767fToomas Soome	uint32_t low;
342199767fToomas Soome
343199767fToomas Soome	__asm __volatile("rdmsr" : "=a" (low) : "c" (msr) : "edx");
344199767fToomas Soome	return (low);
345199767fToomas Soome}
346199767fToomas Soome
347199767fToomas Soomestatic __inline uint64_t
348199767fToomas Soomerdpmc(u_int pmc)
349199767fToomas Soome{
350199767fToomas Soome	uint64_t rv;
351199767fToomas Soome
352199767fToomas Soome	__asm __volatile("rdpmc" : "=A" (rv) : "c" (pmc));
353199767fToomas Soome	return (rv);
354199767fToomas Soome}
355199767fToomas Soome
356199767fToomas Soomestatic __inline uint64_t
357199767fToomas Soomerdtsc(void)
358199767fToomas Soome{
359199767fToomas Soome	uint64_t rv;
360199767fToomas Soome
361199767fToomas Soome	__asm __volatile("rdtsc" : "=A" (rv));
362199767fToomas Soome	return (rv);
363199767fToomas Soome}
364199767fToomas Soome
365199767fToomas Soomestatic __inline uint32_t
366199767fToomas Soomerdtsc32(void)
367199767fToomas Soome{
368199767fToomas Soome	uint32_t rv;
369199767fToomas Soome
370199767fToomas Soome	__asm __volatile("rdtsc" : "=a" (rv) : : "edx");
371199767fToomas Soome	return (rv);
372199767fToomas Soome}
373199767fToomas Soome
374199767fToomas Soomestatic __inline void
375199767fToomas Soomewbinvd(void)
376199767fToomas Soome{
377199767fToomas Soome	__asm __volatile("wbinvd");
378199767fToomas Soome}
379199767fToomas Soome
380199767fToomas Soomestatic __inline void
381199767fToomas Soomewrite_eflags(u_int ef)
382199767fToomas Soome{
383199767fToomas Soome	__asm __volatile("pushl %0; popfl" : : "r" (ef));
384199767fToomas Soome}
385199767fToomas Soome
386199767fToomas Soomestatic __inline void
387199767fToomas Soomewrmsr(u_int msr, uint64_t newval)
388199767fToomas Soome{
389199767fToomas Soome	__asm __volatile("wrmsr" : : "A" (newval), "c" (msr));
390199767fToomas Soome}
391199767fToomas Soome
392199767fToomas Soomestatic __inline void
393199767fToomas Soomeload_cr0(u_int data)
394199767fToomas Soome{
395199767fToomas Soome
396199767fToomas Soome	__asm __volatile("movl %0,%%cr0" : : "r" (data));
397199767fToomas Soome}
398199767fToomas Soome
399199767fToomas Soomestatic __inline u_int
400199767fToomas Soomercr0(void)
401199767fToomas Soome{
402199767fToomas Soome	u_int	data;
403199767fToomas Soome
404199767fToomas Soome	__asm __volatile("movl %%cr0,%0" : "=r" (data));
405199767fToomas Soome	return (data);
406199767fToomas Soome}
407199767fToomas Soome
408199767fToomas Soomestatic __inline u_int
409199767fToomas Soomercr2(void)
410199767fToomas Soome{
411199767fToomas Soome	u_int	data;
412199767fToomas Soome
413199767fToomas Soome	__asm __volatile("movl %%cr2,%0" : "=r" (data));
414199767fToomas Soome	return (data);
415199767fToomas Soome}
416199767fToomas Soome
417199767fToomas Soomestatic __inline void
418199767fToomas Soomeload_cr3(u_int data)
419199767fToomas Soome{
420199767fToomas Soome
421199767fToomas Soome	__asm __volatile("movl %0,%%cr3" : : "r" (data) : "memory");
422199767fToomas Soome}
423199767fToomas Soome
424199767fToomas Soomestatic __inline u_int
425199767fToomas Soomercr3(void)
426199767fToomas Soome{
427199767fToomas Soome	u_int	data;
428199767fToomas Soome
429199767fToomas Soome	__asm __volatile("movl %%cr3,%0" : "=r" (data));
430199767fToomas Soome	return (data);
431199767fToomas Soome}
432199767fToomas Soome
433199767fToomas Soomestatic __inline void
434199767fToomas Soomeload_cr4(u_int data)
435199767fToomas Soome{
436199767fToomas Soome	__asm __volatile("movl %0,%%cr4" : : "r" (data));
437199767fToomas Soome}
438199767fToomas Soome
439199767fToomas Soomestatic __inline u_int
440199767fToomas Soomercr4(void)
441199767fToomas Soome{
442199767fToomas Soome	u_int	data;
443199767fToomas Soome
444199767fToomas Soome	__asm __volatile("movl %%cr4,%0" : "=r" (data));
445199767fToomas Soome	return (data);
446199767fToomas Soome}
447199767fToomas Soome
448199767fToomas Soomestatic __inline uint64_t
449199767fToomas Soomerxcr(u_int reg)
450199767fToomas Soome{
451199767fToomas Soome	u_int low, high;
452199767fToomas Soome
453199767fToomas Soome	__asm __volatile("xgetbv" : "=a" (low), "=d" (high) : "c" (reg));
454199767fToomas Soome	return (low | ((uint64_t)high << 32));
455199767fToomas Soome}
456199767fToomas Soome
457199767fToomas Soomestatic __inline void
458199767fToomas Soomeload_xcr(u_int reg, uint64_t val)
459199767fToomas Soome{
460199767fToomas Soome	u_int low, high;
461199767fToomas Soome
462199767fToomas Soome	low = val;
463199767fToomas Soome	high = val >> 32;
464199767fToomas Soome	__asm __volatile("xsetbv" : : "c" (reg), "a" (low), "d" (high));
465199767fToomas Soome}
466199767fToomas Soome
467199767fToomas Soome/*
468199767fToomas Soome * Global TLB flush (except for thise for pages marked PG_G)
469199767fToomas Soome */
470199767fToomas Soomestatic __inline void
471199767fToomas Soomeinvltlb(void)
472199767fToomas Soome{
473199767fToomas Soome
474199767fToomas Soome	load_cr3(rcr3());
475199767fToomas Soome}
476199767fToomas Soome
477199767fToomas Soome/*
478199767fToomas Soome * TLB flush for an individual page (even if it has PG_G).
479199767fToomas Soome * Only works on 486+ CPUs (i386 does not have PG_G).
480199767fToomas Soome */
481199767fToomas Soomestatic __inline void
482199767fToomas Soomeinvlpg(u_int addr)
483199767fToomas Soome{
484199767fToomas Soome
485199767fToomas Soome	__asm __volatile("invlpg %0" : : "m" (*(char *)addr) : "memory");
486199767fToomas Soome}
487199767fToomas Soome
488199767fToomas Soomestatic __inline u_short
489199767fToomas Soomerfs(void)
490199767fToomas Soome{
491199767fToomas Soome	u_short sel;
492199767fToomas Soome	__asm __volatile("movw %%fs,%0" : "=rm" (sel));
493199767fToomas Soome	return (sel);
494199767fToomas Soome}
495199767fToomas Soome
496199767fToomas Soomestatic __inline uint64_t
497199767fToomas Soomergdt(void)
498199767fToomas Soome{
499199767fToomas Soome	uint64_t gdtr;
500199767fToomas Soome	__asm __volatile("sgdt %0" : "=m" (gdtr));
501199767fToomas Soome	return (gdtr);
502199767fToomas Soome}
503199767fToomas Soome
504199767fToomas Soomestatic __inline u_short
505199767fToomas Soomergs(void)
506199767fToomas Soome{
507199767fToomas Soome	u_short sel;
508199767fToomas Soome	__asm __volatile("movw %%gs,%0" : "=rm" (sel));
509199767fToomas Soome	return (sel);
510199767fToomas Soome}
511199767fToomas Soome
512199767fToomas Soomestatic __inline uint64_t
513199767fToomas Soomeridt(void)
514199767fToomas Soome{
515199767fToomas Soome	uint64_t idtr;
516199767fToomas Soome	__asm __volatile("sidt %0" : "=m" (idtr));
517199767fToomas Soome	return (idtr);
518199767fToomas Soome}
519199767fToomas Soome
520199767fToomas Soomestatic __inline u_short
521199767fToomas Soomerldt(void)
522199767fToomas Soome{
523199767fToomas Soome	u_short ldtr;
524199767fToomas Soome	__asm __volatile("sldt %0" : "=g" (ldtr));
525199767fToomas Soome	return (ldtr);
526199767fToomas Soome}
527199767fToomas Soome
528199767fToomas Soomestatic __inline u_short
529199767fToomas Soomerss(void)
530199767fToomas Soome{
531199767fToomas Soome	u_short sel;
532199767fToomas Soome	__asm __volatile("movw %%ss,%0" : "=rm" (sel));
533199767fToomas Soome	return (sel);
534199767fToomas Soome}
535199767fToomas Soome
536199767fToomas Soomestatic __inline u_short
537199767fToomas Soomertr(void)
538199767fToomas Soome{
539199767fToomas Soome	u_short tr;
540199767fToomas Soome	__asm __volatile("str %0" : "=g" (tr));
541199767fToomas Soome	return (tr);
542199767fToomas Soome}
543199767fToomas Soome
544199767fToomas Soomestatic __inline void
545199767fToomas Soomeload_fs(u_short sel)
546199767fToomas Soome{
547199767fToomas Soome	__asm __volatile("movw %0,%%fs" : : "rm" (sel));
548199767fToomas Soome}
549199767fToomas Soome
550199767fToomas Soomestatic __inline void
551199767fToomas Soomeload_gs(u_short sel)
552199767fToomas Soome{
553199767fToomas Soome	__asm __volatile("movw %0,%%gs" : : "rm" (sel));
554199767fToomas Soome}
555199767fToomas Soome
556199767fToomas Soomestatic __inline void
557199767fToomas Soomelidt(struct region_descriptor *addr)
558199767fToomas Soome{
559199767fToomas Soome	__asm __volatile("lidt (%0)" : : "r" (addr));
560199767fToomas Soome}
561199767fToomas Soome
562199767fToomas Soomestatic __inline void
563199767fToomas Soomelldt(u_short sel)
564199767fToomas Soome{
565199767fToomas Soome	__asm __volatile("lldt %0" : : "r" (sel));
566199767fToomas Soome}
567199767fToomas Soome
568199767fToomas Soomestatic __inline void
569199767fToomas Soomeltr(u_short sel)
570199767fToomas Soome{
571199767fToomas Soome	__asm __volatile("ltr %0" : : "r" (sel));
572199767fToomas Soome}
573199767fToomas Soome
574199767fToomas Soomestatic __inline u_int
575199767fToomas Soomerdr0(void)
576199767fToomas Soome{
577199767fToomas Soome	u_int	data;
578199767fToomas Soome	__asm __volatile("movl %%dr0,%0" : "=r" (data));
579199767fToomas Soome	return (data);
580199767fToomas Soome}
581199767fToomas Soome
582199767fToomas Soomestatic __inline void
583199767fToomas Soomeload_dr0(u_int dr0)
584199767fToomas Soome{
585199767fToomas Soome	__asm __volatile("movl %0,%%dr0" : : "r" (dr0));
586199767fToomas Soome}
587199767fToomas Soome
588199767fToomas Soomestatic __inline u_int
589199767fToomas Soomerdr1(void)
590199767fToomas Soome{
591199767fToomas Soome	u_int	data;
592199767fToomas Soome	__asm __volatile("movl %%dr1,%0" : "=r" (data));
593199767fToomas Soome	return (data);
594199767fToomas Soome}
595199767fToomas Soome
596199767fToomas Soomestatic __inline void
597199767fToomas Soomeload_dr1(u_int dr1)
598199767fToomas Soome{
599199767fToomas Soome	__asm __volatile("movl %0,%%dr1" : : "r" (dr1));
600199767fToomas Soome}
601199767fToomas Soome
602199767fToomas Soomestatic __inline u_int
603199767fToomas Soomerdr2(void)
604199767fToomas Soome{
605199767fToomas Soome	u_int	data;
606199767fToomas Soome	__asm __volatile("movl %%dr2,%0" : "=r" (data));
607199767fToomas Soome	return (data);
608199767fToomas Soome}
609199767fToomas Soome
610199767fToomas Soomestatic __inline void
611199767fToomas Soomeload_dr2(u_int dr2)
612199767fToomas Soome{
613199767fToomas Soome	__asm __volatile("movl %0,%%dr2" : : "r" (dr2));
614199767fToomas Soome}
615199767fToomas Soome
616199767fToomas Soomestatic __inline u_int
617199767fToomas Soomerdr3(void)
618199767fToomas Soome{
619199767fToomas Soome	u_int	data;
620199767fToomas Soome	__asm __volatile("movl %%dr3,%0" : "=r" (data));
621199767fToomas Soome	return (data);
622199767fToomas Soome}
623199767fToomas Soome
624199767fToomas Soomestatic __inline void
625199767fToomas Soomeload_dr3(u_int dr3)
626199767fToomas Soome{
627199767fToomas Soome	__asm __volatile("movl %0,%%dr3" : : "r" (dr3));
628199767fToomas Soome}
629199767fToomas Soome
630199767fToomas Soomestatic __inline u_int
631199767fToomas Soomerdr4(void)
632199767fToomas Soome{
633199767fToomas Soome	u_int	data;
634199767fToomas Soome	__asm __volatile("movl %%dr4,%0" : "=r" (data));
635199767fToomas Soome	return (data);
636199767fToomas Soome}
637199767fToomas Soome
638199767fToomas Soomestatic __inline void
639199767fToomas Soomeload_dr4(u_int dr4)
640199767fToomas Soome{
641199767fToomas Soome	__asm __volatile("movl %0,%%dr4" : : "r" (dr4));
642199767fToomas Soome}
643199767fToomas Soome
644199767fToomas Soomestatic __inline u_int
645199767fToomas Soomerdr5(void)
646199767fToomas Soome{
647199767fToomas Soome	u_int	data;
648199767fToomas Soome	__asm __volatile("movl %%dr5,%0" : "=r" (data));
649199767fToomas Soome	return (data);
650199767fToomas Soome}
651199767fToomas Soome
652199767fToomas Soomestatic __inline void
653199767fToomas Soomeload_dr5(u_int dr5)
654199767fToomas Soome{
655199767fToomas Soome	__asm __volatile("movl %0,%%dr5" : : "r" (dr5));
656199767fToomas Soome}
657199767fToomas Soome
658199767fToomas Soomestatic __inline u_int
659199767fToomas Soomerdr6(void)
660199767fToomas Soome{
661199767fToomas Soome	u_int	data;
662199767fToomas Soome	__asm __volatile("movl %%dr6,%0" : "=r" (data));
663199767fToomas Soome	return (data);
664199767fToomas Soome}
665199767fToomas Soome
666199767fToomas Soomestatic __inline void
667199767fToomas Soomeload_dr6(u_int dr6)
668199767fToomas Soome{
669199767fToomas Soome	__asm __volatile("movl %0,%%dr6" : : "r" (dr6));
670199767fToomas Soome}
671199767fToomas Soome
672199767fToomas Soomestatic __inline u_int
673199767fToomas Soomerdr7(void)
674199767fToomas Soome{
675199767fToomas Soome	u_int	data;
676199767fToomas Soome	__asm __volatile("movl %%dr7,%0" : "=r" (data));
677199767fToomas Soome	return (data);
678199767fToomas Soome}
679199767fToomas Soome
680199767fToomas Soomestatic __inline void
681199767fToomas Soomeload_dr7(u_int dr7)
682199767fToomas Soome{
683199767fToomas Soome	__asm __volatile("movl %0,%%dr7" : : "r" (dr7));
684199767fToomas Soome}
685199767fToomas Soome
686199767fToomas Soomestatic __inline u_char
687199767fToomas Soomeread_cyrix_reg(u_char reg)
688199767fToomas Soome{
689199767fToomas Soome	outb(0x22, reg);
690199767fToomas Soome	return inb(0x23);
691199767fToomas Soome}
692199767fToomas Soome
693199767fToomas Soomestatic __inline void
694199767fToomas Soomewrite_cyrix_reg(u_char reg, u_char data)
695199767fToomas Soome{
696199767fToomas Soome	outb(0x22, reg);
697199767fToomas Soome	outb(0x23, data);
698199767fToomas Soome}
699199767fToomas Soome
700199767fToomas Soomestatic __inline register_t
701199767fToomas Soomeintr_disable(void)
702199767fToomas Soome{
703199767fToomas Soome	register_t eflags;
704199767fToomas Soome
705199767fToomas Soome	eflags = read_eflags();
706199767fToomas Soome	disable_intr();
707199767fToomas Soome	return (eflags);
708199767fToomas Soome}
709199767fToomas Soome
710199767fToomas Soomestatic __inline void
711199767fToomas Soomeintr_restore(register_t eflags)
712199767fToomas Soome{
713199767fToomas Soome	write_eflags(eflags);
714199767fToomas Soome}
715199767fToomas Soome
716199767fToomas Soome#else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */
717199767fToomas Soome
718199767fToomas Soomeint	breakpoint(void);
719199767fToomas Soomeu_int	bsfl(u_int mask);
720199767fToomas Soomeu_int	bsrl(u_int mask);
721199767fToomas Soomevoid	clflush(u_long addr);
722199767fToomas Soomevoid	clts(void);
723199767fToomas Soomevoid	cpuid_count(u_int ax, u_int cx, u_int *p);
724199767fToomas Soomevoid	disable_intr(void);
725199767fToomas Soomevoid	do_cpuid(u_int ax, u_int *p);
726199767fToomas Soomevoid	enable_intr(void);
727199767fToomas Soomevoid	halt(void);
728199767fToomas Soomevoid	ia32_pause(void);
729199767fToomas Soomeu_char	inb(u_int port);
730199767fToomas Soomeu_int	inl(u_int port);
731199767fToomas Soomevoid	insb(u_int port, void *addr, size_t count);
732199767fToomas Soomevoid	insl(u_int port, void *addr, size_t count);
733199767fToomas Soomevoid	insw(u_int port, void *addr, size_t count);
734199767fToomas Soomeregister_t	intr_disable(void);
735199767fToomas Soomevoid	intr_restore(register_t ef);
736199767fToomas Soomevoid	invd(void);
737199767fToomas Soomevoid	invlpg(u_int addr);
738199767fToomas Soomevoid	invltlb(void);
739199767fToomas Soomeu_short	inw(u_int port);
740199767fToomas Soomevoid	lidt(struct region_descriptor *addr);
741199767fToomas Soomevoid	lldt(u_short sel);
742199767fToomas Soomevoid	load_cr0(u_int cr0);
743199767fToomas Soomevoid	load_cr3(u_int cr3);
744199767fToomas Soomevoid	load_cr4(u_int cr4);
745199767fToomas Soomevoid	load_dr0(u_int dr0);
746199767fToomas Soomevoid	load_dr1(u_int dr1);
747199767fToomas Soomevoid	load_dr2(u_int dr2);
748199767fToomas Soomevoid	load_dr3(u_int dr3);
749199767fToomas Soomevoid	load_dr4(u_int dr4);
750199767fToomas Soomevoid	load_dr5(u_int dr5);
751199767fToomas Soomevoid	load_dr6(u_int dr6);
752199767fToomas Soomevoid	load_dr7(u_int dr7);
753199767fToomas Soomevoid	load_fs(u_short sel);
754199767fToomas Soomevoid	load_gs(u_short sel);
755199767fToomas Soomevoid	ltr(u_short sel);
756199767fToomas Soomevoid	outb(u_int port, u_char data);
757199767fToomas Soomevoid	outl(u_int port, u_int data);
758199767fToomas Soomevoid	outsb(u_int port, const void *addr, size_t count);
759199767fToomas Soomevoid	outsl(u_int port, const void *addr, size_t count);
760199767fToomas Soomevoid	outsw(u_int port, const void *addr, size_t count);
761199767fToomas Soomevoid	outw(u_int port, u_short data);
762199767fToomas Soomeu_int	rcr0(void);
763199767fToomas Soomeu_int	rcr2(void);
764199767fToomas Soomeu_int	rcr3(void);
765199767fToomas Soomeu_int	rcr4(void);
766199767fToomas Soomeuint64_t rdmsr(u_int msr);
767199767fToomas Soomeuint64_t rdpmc(u_int pmc);
768199767fToomas Soomeu_int	rdr0(void);
769199767fToomas Soomeu_int	rdr1(void);
770199767fToomas Soomeu_int	rdr2(void);
771199767fToomas Soomeu_int	rdr3(void);
772199767fToomas Soomeu_int	rdr4(void);
773199767fToomas Soomeu_int	rdr5(void);
774199767fToomas Soomeu_int	rdr6(void);
775199767fToomas Soomeu_int	rdr7(void);
776199767fToomas Soomeuint64_t rdtsc(void);
777199767fToomas Soomeu_char	read_cyrix_reg(u_char reg);
778199767fToomas Soomeu_int	read_eflags(void);
779199767fToomas Soomeu_int	rfs(void);
780199767fToomas Soomeuint64_t rgdt(void);
781199767fToomas Soomeu_int	rgs(void);
782199767fToomas Soomeuint64_t ridt(void);
783199767fToomas Soomeu_short	rldt(void);
784199767fToomas Soomeu_short	rtr(void);
785199767fToomas Soomevoid	wbinvd(void);
786199767fToomas Soomevoid	write_cyrix_reg(u_char reg, u_char data);
787199767fToomas Soomevoid	write_eflags(u_int ef);
788199767fToomas Soomevoid	wrmsr(u_int msr, uint64_t newval);
789199767fToomas Soome
790199767fToomas Soome#endif	/* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */
791199767fToomas Soome
792199767fToomas Soomevoid    reset_dbregs(void);
793199767fToomas Soome
794199767fToomas Soome#ifdef _KERNEL
795199767fToomas Soomeint	rdmsr_safe(u_int msr, uint64_t *val);
796199767fToomas Soomeint	wrmsr_safe(u_int msr, uint64_t newval);
797199767fToomas Soome#endif
798199767fToomas Soome
799199767fToomas Soome#endif /* !_MACHINE_CPUFUNC_H_ */
800