xref: /openbsd/sys/arch/i386/include/cpufunc.h (revision d485f761)
1 /*	$OpenBSD: cpufunc.h,v 1.7 2001/08/18 20:37:42 espie Exp $	*/
2 /*	$NetBSD: cpufunc.h,v 1.8 1994/10/27 04:15:59 cgd Exp $	*/
3 
4 /*
5  * Copyright (c) 1993 Charles Hannum.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by Charles Hannum.
19  * 4. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #ifndef _I386_CPUFUNC_H_
35 #define	_I386_CPUFUNC_H_
36 
37 /*
38  * Functions to provide access to i386-specific instructions.
39  */
40 
41 #include <sys/cdefs.h>
42 #include <sys/types.h>
43 
44 static __inline void invlpg __P((u_int));
45 static __inline void lidt __P((void *));
46 static __inline void lldt __P((u_short));
47 static __inline void ltr __P((u_short));
48 static __inline void lcr0 __P((u_int));
49 static __inline u_int rcr0 __P((void));
50 static __inline u_int rcr2 __P((void));
51 static __inline void lcr3 __P((u_int));
52 static __inline u_int rcr3 __P((void));
53 static __inline void lcr4 __P((u_int));
54 static __inline u_int rcr4 __P((void));
55 static __inline void tlbflush __P((void));
56 static __inline void disable_intr __P((void));
57 static __inline void enable_intr __P((void));
58 static __inline void wbinvd __P((void));
59 static __inline void wrmsr __P((u_int, u_int64_t));
60 static __inline u_int64_t rdmsr __P((u_int));
61 static __inline void breakpoint __P((void));
62 
63 static __inline void
64 invlpg(u_int addr)
65 {
66         __asm __volatile("invlpg (%0)" : : "r" (addr) : "memory");
67 }
68 
69 static __inline void
70 lidt(void *p)
71 {
72 	__asm __volatile("lidt (%0)" : : "r" (p));
73 }
74 
75 static __inline void
76 lldt(u_short sel)
77 {
78 	__asm __volatile("lldt %0" : : "r" (sel));
79 }
80 
81 static __inline void
82 ltr(u_short sel)
83 {
84 	__asm __volatile("ltr %0" : : "r" (sel));
85 }
86 
87 static __inline void
88 lcr0(u_int val)
89 {
90 	__asm __volatile("movl %0,%%cr0" : : "r" (val));
91 }
92 
93 static __inline u_int
94 rcr0(void)
95 {
96 	u_int val;
97 	__asm __volatile("movl %%cr0,%0" : "=r" (val));
98 	return val;
99 }
100 
101 static __inline u_int
102 rcr2(void)
103 {
104 	u_int val;
105 	__asm __volatile("movl %%cr2,%0" : "=r" (val));
106 	return val;
107 }
108 
109 static __inline void
110 lcr3(u_int val)
111 {
112 	__asm __volatile("movl %0,%%cr3" : : "r" (val));
113 }
114 
115 static __inline u_int
116 rcr3(void)
117 {
118 	u_int val;
119 	__asm __volatile("movl %%cr3,%0" : "=r" (val));
120 	return val;
121 }
122 
123 static __inline void
124 lcr4(u_int val)
125 {
126 	__asm __volatile("movl %0,%%cr4" : : "r" (val));
127 }
128 
129 static __inline u_int
130 rcr4(void)
131 {
132 	u_int val;
133 	__asm __volatile("movl %%cr4,%0" : "=r" (val));
134 	return val;
135 }
136 
137 static __inline void
138 tlbflush(void)
139 {
140 	u_int val;
141 	__asm __volatile("movl %%cr3,%0" : "=r" (val));
142 	__asm __volatile("movl %0,%%cr3" : : "r" (val));
143 }
144 
145 #ifdef notyet
146 void	setidt	__P((int idx, /*XXX*/caddr_t func, int typ, int dpl));
147 #endif
148 
149 
150 /* XXXX ought to be in psl.h with spl() functions */
151 
152 static __inline void
153 disable_intr(void)
154 {
155 	__asm __volatile("cli");
156 }
157 
158 static __inline void
159 enable_intr(void)
160 {
161 	__asm __volatile("sti");
162 }
163 
164 static __inline void
165 wbinvd(void)
166 {
167         __asm __volatile("wbinvd");
168 }
169 
170 
171 static __inline void
172 wrmsr(u_int msr, u_int64_t newval)
173 {
174         __asm __volatile(".byte 0x0f, 0x30" : : "A" (newval), "c" (msr));
175 }
176 
177 static __inline u_int64_t
178 rdmsr(u_int msr)
179 {
180         u_int64_t rv;
181 
182         __asm __volatile(".byte 0x0f, 0x32" : "=A" (rv) : "c" (msr));
183         return (rv);
184 }
185 
186 /* Break into DDB/KGDB. */
187 static __inline void
188 breakpoint(void)
189 {
190 	__asm __volatile("int $3");
191 }
192 
193 #endif /* !_I386_CPUFUNC_H_ */
194