1bf21cd93STycho Nightingale /*
2bf21cd93STycho Nightingale  * This file and its contents are supplied under the terms of the
3bf21cd93STycho Nightingale  * Common Development and Distribution License ("CDDL"), version 1.0.
4bf21cd93STycho Nightingale  * You may only use this file in accordance with the terms of version
5bf21cd93STycho Nightingale  * 1.0 of the CDDL.
6bf21cd93STycho Nightingale  *
7bf21cd93STycho Nightingale  * A full copy of the text of the CDDL should have accompanied this
8bf21cd93STycho Nightingale  * source.  A copy of the CDDL is also available via the Internet at
9bf21cd93STycho Nightingale  * http://www.illumos.org/license/CDDL.
10bf21cd93STycho Nightingale  */
11bf21cd93STycho Nightingale 
12bf21cd93STycho Nightingale /*
13bf21cd93STycho Nightingale  * Copyright 2014 Pluribus Networks Inc.
14bf21cd93STycho Nightingale  */
15bf21cd93STycho Nightingale 
16bf21cd93STycho Nightingale #ifndef _COMPAT_FREEBSD_AMD64_MACHINE_CPUFUNC_H_
17bf21cd93STycho Nightingale #define	_COMPAT_FREEBSD_AMD64_MACHINE_CPUFUNC_H_
18bf21cd93STycho Nightingale 
194c87aefeSPatrick Mooney #include <sys/types.h>
204c87aefeSPatrick Mooney 
21bf21cd93STycho Nightingale static __inline u_long
bsfq(u_long mask)22bf21cd93STycho Nightingale bsfq(u_long mask)
23bf21cd93STycho Nightingale {
24bf21cd93STycho Nightingale 	u_long	result;
25bf21cd93STycho Nightingale 
26bf21cd93STycho Nightingale 	__asm __volatile("bsfq %1,%0" : "=r" (result) : "rm" (mask));
27bf21cd93STycho Nightingale 	return (result);
28bf21cd93STycho Nightingale }
29bf21cd93STycho Nightingale 
30bf21cd93STycho Nightingale static __inline u_int
bsrl(u_int mask)31bf21cd93STycho Nightingale bsrl(u_int mask)
32bf21cd93STycho Nightingale {
33bf21cd93STycho Nightingale 	u_int	result;
34bf21cd93STycho Nightingale 
35bf21cd93STycho Nightingale 	__asm __volatile("bsrl %1,%0" : "=r" (result) : "rm" (mask));
36bf21cd93STycho Nightingale 	return (result);
37bf21cd93STycho Nightingale }
38bf21cd93STycho Nightingale 
39bf21cd93STycho Nightingale static __inline u_long
bsrq(u_long mask)40bf21cd93STycho Nightingale bsrq(u_long mask)
41bf21cd93STycho Nightingale {
42bf21cd93STycho Nightingale 	u_long	result;
43bf21cd93STycho Nightingale 
44bf21cd93STycho Nightingale 	__asm __volatile("bsrq %1,%0" : "=r" (result) : "rm" (mask));
45bf21cd93STycho Nightingale 	return (result);
46bf21cd93STycho Nightingale }
47bf21cd93STycho Nightingale 
48bf21cd93STycho Nightingale static __inline void
clts(void)49bf21cd93STycho Nightingale clts(void)
50bf21cd93STycho Nightingale {
51bf21cd93STycho Nightingale 	__asm __volatile("clts");
52bf21cd93STycho Nightingale }
53bf21cd93STycho Nightingale 
54bf21cd93STycho Nightingale static __inline void
do_cpuid(u_int ax,u_int * p)55bf21cd93STycho Nightingale do_cpuid(u_int ax, u_int *p)
56bf21cd93STycho Nightingale {
57bf21cd93STycho Nightingale 	__asm __volatile("cpuid"
58bf21cd93STycho Nightingale 			 : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
59bf21cd93STycho Nightingale 			 :  "0" (ax));
60bf21cd93STycho Nightingale }
61bf21cd93STycho Nightingale 
62bf21cd93STycho Nightingale static __inline void
cpuid_count(u_int ax,u_int cx,u_int * p)63bf21cd93STycho Nightingale cpuid_count(u_int ax, u_int cx, u_int *p)
64bf21cd93STycho Nightingale {
65bf21cd93STycho Nightingale 	__asm __volatile("cpuid"
66bf21cd93STycho Nightingale 			 : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
67bf21cd93STycho Nightingale 			 :  "0" (ax), "c" (cx));
68bf21cd93STycho Nightingale }
69bf21cd93STycho Nightingale 
704c87aefeSPatrick Mooney static __inline void
disable_intr(void)714c87aefeSPatrick Mooney disable_intr(void)
724c87aefeSPatrick Mooney {
734c87aefeSPatrick Mooney 	__asm __volatile("cli");
744c87aefeSPatrick Mooney }
754c87aefeSPatrick Mooney 
76bf21cd93STycho Nightingale static __inline void
enable_intr(void)77bf21cd93STycho Nightingale enable_intr(void)
78bf21cd93STycho Nightingale {
79bf21cd93STycho Nightingale 	__asm __volatile("sti");
80bf21cd93STycho Nightingale }
81bf21cd93STycho Nightingale 
82bf21cd93STycho Nightingale static __inline int
ffsl(long mask)83bf21cd93STycho Nightingale ffsl(long mask)
84bf21cd93STycho Nightingale {
85bf21cd93STycho Nightingale 	return (mask == 0 ? mask : (int)bsfq((u_long)mask) + 1);
86bf21cd93STycho Nightingale }
87bf21cd93STycho Nightingale 
88bf21cd93STycho Nightingale static __inline int
fls(int mask)89bf21cd93STycho Nightingale fls(int mask)
90bf21cd93STycho Nightingale {
91bf21cd93STycho Nightingale 	return (mask == 0 ? mask : (int)bsrl((u_int)mask) + 1);
92bf21cd93STycho Nightingale }
93bf21cd93STycho Nightingale 
94bf21cd93STycho Nightingale static __inline int
flsl(long mask)95bf21cd93STycho Nightingale flsl(long mask)
96bf21cd93STycho Nightingale {
97bf21cd93STycho Nightingale 	return (mask == 0 ? mask : (int)bsrq((u_long)mask) + 1);
98bf21cd93STycho Nightingale }
99bf21cd93STycho Nightingale 
100bf21cd93STycho Nightingale static __inline int
flsll(long long mask)101bf21cd93STycho Nightingale flsll(long long mask)
102bf21cd93STycho Nightingale {
103bf21cd93STycho Nightingale 	return (flsl((long)mask));
104bf21cd93STycho Nightingale }
105bf21cd93STycho Nightingale 
1064c87aefeSPatrick Mooney static __inline u_long
read_rflags(void)1074c87aefeSPatrick Mooney read_rflags(void)
1084c87aefeSPatrick Mooney {
1094c87aefeSPatrick Mooney 	u_long  rf;
1104c87aefeSPatrick Mooney 
1114c87aefeSPatrick Mooney 	__asm __volatile("pushfq; popq %0" : "=r" (rf));
1124c87aefeSPatrick Mooney 	return (rf);
1134c87aefeSPatrick Mooney }
1144c87aefeSPatrick Mooney 
115*9250eb13SPatrick Mooney /* Equivalent to the FreeBSD rdtsc(), but with any necessary per-cpu offset */
116*9250eb13SPatrick Mooney uint64_t rdtsc_offset(void);
117*9250eb13SPatrick Mooney 
118bf21cd93STycho Nightingale static __inline uint64_t
rdmsr(u_int msr)119bf21cd93STycho Nightingale rdmsr(u_int msr)
120bf21cd93STycho Nightingale {
121bf21cd93STycho Nightingale 	uint32_t low, high;
12284971882SPatrick Mooney 
123bf21cd93STycho Nightingale 	__asm __volatile("rdmsr" : "=a" (low), "=d" (high) : "c" (msr));
124bf21cd93STycho Nightingale 	return (low | ((uint64_t)high << 32));
125bf21cd93STycho Nightingale }
126bf21cd93STycho Nightingale 
127bf21cd93STycho Nightingale static __inline void
wrmsr(u_int msr,uint64_t newval)128bf21cd93STycho Nightingale wrmsr(u_int msr, uint64_t newval)
129bf21cd93STycho Nightingale {
130bf21cd93STycho Nightingale 	uint32_t low, high;
131bf21cd93STycho Nightingale 
132bf21cd93STycho Nightingale 	low = newval;
133bf21cd93STycho Nightingale 	high = newval >> 32;
134bf21cd93STycho Nightingale 	__asm __volatile("wrmsr" : : "a" (low), "d" (high), "c" (msr));
135bf21cd93STycho Nightingale }
136bf21cd93STycho Nightingale 
137bf21cd93STycho Nightingale static __inline void
load_cr0(u_long data)138bf21cd93STycho Nightingale load_cr0(u_long data)
139bf21cd93STycho Nightingale {
140bf21cd93STycho Nightingale 	__asm __volatile("movq %0,%%cr0" : : "r" (data));
141bf21cd93STycho Nightingale }
142bf21cd93STycho Nightingale 
143bf21cd93STycho Nightingale static __inline u_long
rcr0(void)144bf21cd93STycho Nightingale rcr0(void)
145bf21cd93STycho Nightingale {
146bf21cd93STycho Nightingale 	u_long  data;
14784971882SPatrick Mooney 
148bf21cd93STycho Nightingale 	__asm __volatile("movq %%cr0,%0" : "=r" (data));
149bf21cd93STycho Nightingale 	return (data);
150bf21cd93STycho Nightingale }
151bf21cd93STycho Nightingale 
152bf21cd93STycho Nightingale static __inline u_long
rcr3(void)153bf21cd93STycho Nightingale rcr3(void)
154bf21cd93STycho Nightingale {
155bf21cd93STycho Nightingale 	u_long  data;
156bf21cd93STycho Nightingale 
157bf21cd93STycho Nightingale 	__asm __volatile("movq %%cr3,%0" : "=r" (data));
158bf21cd93STycho Nightingale 	return (data);
159bf21cd93STycho Nightingale }
160bf21cd93STycho Nightingale 
161bf21cd93STycho Nightingale static __inline void
load_cr4(u_long data)162bf21cd93STycho Nightingale load_cr4(u_long data)
163bf21cd93STycho Nightingale {
164bf21cd93STycho Nightingale 	__asm __volatile("movq %0,%%cr4" : : "r" (data));
165bf21cd93STycho Nightingale }
166bf21cd93STycho Nightingale 
167bf21cd93STycho Nightingale static __inline u_long
rcr4(void)168bf21cd93STycho Nightingale rcr4(void)
169bf21cd93STycho Nightingale {
170bf21cd93STycho Nightingale 	u_long  data;
17184971882SPatrick Mooney 
172bf21cd93STycho Nightingale 	__asm __volatile("movq %%cr4,%0" : "=r" (data));
173bf21cd93STycho Nightingale 	return (data);
174bf21cd93STycho Nightingale }
175bf21cd93STycho Nightingale 
1764c87aefeSPatrick Mooney static __inline u_long
rxcr(u_int reg)1774c87aefeSPatrick Mooney rxcr(u_int reg)
1784c87aefeSPatrick Mooney {
1794c87aefeSPatrick Mooney 	u_int low, high;
1804c87aefeSPatrick Mooney 
1814c87aefeSPatrick Mooney 	__asm __volatile("xgetbv" : "=a" (low), "=d" (high) : "c" (reg));
1824c87aefeSPatrick Mooney 	return (low | ((uint64_t)high << 32));
1834c87aefeSPatrick Mooney }
1844c87aefeSPatrick Mooney 
1854c87aefeSPatrick Mooney static __inline void
load_xcr(u_int reg,u_long val)1864c87aefeSPatrick Mooney load_xcr(u_int reg, u_long val)
1874c87aefeSPatrick Mooney {
1884c87aefeSPatrick Mooney 	u_int low, high;
1894c87aefeSPatrick Mooney 
1904c87aefeSPatrick Mooney 	low = val;
1914c87aefeSPatrick Mooney 	high = val >> 32;
1924c87aefeSPatrick Mooney 	__asm __volatile("xsetbv" : : "c" (reg), "a" (low), "d" (high));
1934c87aefeSPatrick Mooney }
1944c87aefeSPatrick Mooney 
1954c87aefeSPatrick Mooney static __inline void
write_rflags(u_long rf)1964c87aefeSPatrick Mooney write_rflags(u_long rf)
1974c87aefeSPatrick Mooney {
1984c87aefeSPatrick Mooney 	__asm __volatile("pushq %0;  popfq" : : "r" (rf));
1994c87aefeSPatrick Mooney }
2004c87aefeSPatrick Mooney 
2014c87aefeSPatrick Mooney static __inline uint64_t
rdr0(void)2024c87aefeSPatrick Mooney rdr0(void)
2034c87aefeSPatrick Mooney {
2044c87aefeSPatrick Mooney 	uint64_t data;
2054c87aefeSPatrick Mooney 	__asm __volatile("movq %%dr0,%0" : "=r" (data));
2064c87aefeSPatrick Mooney 	return (data);
2074c87aefeSPatrick Mooney }
2084c87aefeSPatrick Mooney 
2094c87aefeSPatrick Mooney static __inline void
load_dr0(uint64_t dr0)2104c87aefeSPatrick Mooney load_dr0(uint64_t dr0)
2114c87aefeSPatrick Mooney {
2124c87aefeSPatrick Mooney 	__asm __volatile("movq %0,%%dr0" : : "r" (dr0));
2134c87aefeSPatrick Mooney }
2144c87aefeSPatrick Mooney 
2154c87aefeSPatrick Mooney static __inline uint64_t
rdr1(void)2164c87aefeSPatrick Mooney rdr1(void)
2174c87aefeSPatrick Mooney {
2184c87aefeSPatrick Mooney 	uint64_t data;
2194c87aefeSPatrick Mooney 	__asm __volatile("movq %%dr1,%0" : "=r" (data));
2204c87aefeSPatrick Mooney 	return (data);
2214c87aefeSPatrick Mooney }
2224c87aefeSPatrick Mooney 
2234c87aefeSPatrick Mooney static __inline void
load_dr1(uint64_t dr1)2244c87aefeSPatrick Mooney load_dr1(uint64_t dr1)
2254c87aefeSPatrick Mooney {
2264c87aefeSPatrick Mooney 	__asm __volatile("movq %0,%%dr1" : : "r" (dr1));
2274c87aefeSPatrick Mooney }
2284c87aefeSPatrick Mooney 
2294c87aefeSPatrick Mooney static __inline uint64_t
rdr2(void)2304c87aefeSPatrick Mooney rdr2(void)
2314c87aefeSPatrick Mooney {
2324c87aefeSPatrick Mooney 	uint64_t data;
2334c87aefeSPatrick Mooney 	__asm __volatile("movq %%dr2,%0" : "=r" (data));
2344c87aefeSPatrick Mooney 	return (data);
2354c87aefeSPatrick Mooney }
2364c87aefeSPatrick Mooney 
2374c87aefeSPatrick Mooney static __inline void
load_dr2(uint64_t dr2)2384c87aefeSPatrick Mooney load_dr2(uint64_t dr2)
2394c87aefeSPatrick Mooney {
2404c87aefeSPatrick Mooney 	__asm __volatile("movq %0,%%dr2" : : "r" (dr2));
2414c87aefeSPatrick Mooney }
2424c87aefeSPatrick Mooney 
2434c87aefeSPatrick Mooney static __inline uint64_t
rdr3(void)2444c87aefeSPatrick Mooney rdr3(void)
2454c87aefeSPatrick Mooney {
2464c87aefeSPatrick Mooney 	uint64_t data;
2474c87aefeSPatrick Mooney 	__asm __volatile("movq %%dr3,%0" : "=r" (data));
2484c87aefeSPatrick Mooney 	return (data);
2494c87aefeSPatrick Mooney }
2504c87aefeSPatrick Mooney 
2514c87aefeSPatrick Mooney static __inline void
load_dr3(uint64_t dr3)2524c87aefeSPatrick Mooney load_dr3(uint64_t dr3)
2534c87aefeSPatrick Mooney {
2544c87aefeSPatrick Mooney 	__asm __volatile("movq %0,%%dr3" : : "r" (dr3));
2554c87aefeSPatrick Mooney }
2564c87aefeSPatrick Mooney 
2574c87aefeSPatrick Mooney static __inline uint64_t
rdr6(void)2584c87aefeSPatrick Mooney rdr6(void)
2594c87aefeSPatrick Mooney {
2604c87aefeSPatrick Mooney 	uint64_t data;
2614c87aefeSPatrick Mooney 	__asm __volatile("movq %%dr6,%0" : "=r" (data));
2624c87aefeSPatrick Mooney 	return (data);
2634c87aefeSPatrick Mooney }
2644c87aefeSPatrick Mooney 
2654c87aefeSPatrick Mooney static __inline void
load_dr6(uint64_t dr6)2664c87aefeSPatrick Mooney load_dr6(uint64_t dr6)
2674c87aefeSPatrick Mooney {
2684c87aefeSPatrick Mooney 	__asm __volatile("movq %0,%%dr6" : : "r" (dr6));
2694c87aefeSPatrick Mooney }
2704c87aefeSPatrick Mooney 
2714c87aefeSPatrick Mooney static __inline uint64_t
rdr7(void)2724c87aefeSPatrick Mooney rdr7(void)
2734c87aefeSPatrick Mooney {
2744c87aefeSPatrick Mooney 	uint64_t data;
2754c87aefeSPatrick Mooney 	__asm __volatile("movq %%dr7,%0" : "=r" (data));
2764c87aefeSPatrick Mooney 	return (data);
2774c87aefeSPatrick Mooney }
2784c87aefeSPatrick Mooney 
2794c87aefeSPatrick Mooney static __inline void
load_dr7(uint64_t dr7)2804c87aefeSPatrick Mooney load_dr7(uint64_t dr7)
2814c87aefeSPatrick Mooney {
2824c87aefeSPatrick Mooney 	__asm __volatile("movq %0,%%dr7" : : "r" (dr7));
2834c87aefeSPatrick Mooney }
2844c87aefeSPatrick Mooney 
2854c87aefeSPatrick Mooney #ifdef _KERNEL
2864c87aefeSPatrick Mooney /*
2874c87aefeSPatrick Mooney  * Including the native sys/segments.h in userspace seriously conflicts with
2884c87aefeSPatrick Mooney  * the FreeBSD compat/contrib headers.
2894c87aefeSPatrick Mooney  */
2904c87aefeSPatrick Mooney #include <sys/segments.h>
2914c87aefeSPatrick Mooney 
2924c87aefeSPatrick Mooney static __inline void
lldt(u_short sel)2934c87aefeSPatrick Mooney lldt(u_short sel)
2944c87aefeSPatrick Mooney {
2954c87aefeSPatrick Mooney 	wr_ldtr(sel);
2964c87aefeSPatrick Mooney }
2974c87aefeSPatrick Mooney 
2984c87aefeSPatrick Mooney static __inline u_short
sldt()2994c87aefeSPatrick Mooney sldt()
3004c87aefeSPatrick Mooney {
3014c87aefeSPatrick Mooney 	return (rd_ldtr());
3024c87aefeSPatrick Mooney }
3034c87aefeSPatrick Mooney #endif /* _KERNEL */
3044c87aefeSPatrick Mooney 
305bf21cd93STycho Nightingale #endif	/* _COMPAT_FREEBSD_AMD64_MACHINE_CPUFUNC_H_ */
306