1 /**	$MirOS: src/sys/arch/i386/include/cpu.h,v 1.11 2010/07/25 16:37:59 tg Exp $ */
2 /*	$OpenBSD: cpu.h,v 1.59 2004/04/02 22:28:41 tedu Exp $	*/
3 /*	$NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $	*/
4 
5 /*-
6  * Copyright (c) 2006, 2008, 2010
7  *	Thorsten Glaser <tg@mirbsd.org>
8  * Copyright (c) 1990 The Regents of the University of California.
9  * All rights reserved.
10  *
11  * This code is derived from software contributed to Berkeley by
12  * William Jolitz.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  * 3. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  *	@(#)cpu.h	5.4 (Berkeley) 5/9/91
39  */
40 
41 #ifndef _I386_CPU_H_
42 #define _I386_CPU_H_
43 
44 /*
45  * Definitions unique to i386 cpu support.
46  */
47 #include <machine/psl.h>
48 #include <machine/frame.h>
49 #include <machine/segments.h>
50 
51 /*
52  * definitions of cpu-dependent requirements
53  * referenced in generic code
54  */
55 #define	cpu_swapin(p)			/* nothing */
56 
57 /*
58  * Arguments to hardclock, softclock and statclock
59  * encapsulate the previous machine state in an opaque
60  * clockframe; for now, use generic intrframe.
61  *
62  * XXX intrframe has a lot of gunk we don't need.
63  */
64 #define clockframe intrframe
65 
66 #define	CLKF_USERMODE(frame)	USERMODE((frame)->if_cs, (frame)->if_eflags)
67 #define	CLKF_PC(frame)		((frame)->if_eip)
68 #define	CLKF_INTR(frame)	(IDXSEL((frame)->if_cs) == GICODE_SEL)
69 
70 /*
71  * Preempt the current process if in interrupt from user mode,
72  * or after the current trap/syscall if in system mode.
73  */
74 int	want_resched;		/* resched() was called */
75 #define	need_resched()		(want_resched = 1, setsoftast())
76 
77 /*
78  * Give a profiling tick to the current process when the user profiling
79  * buffer pages are invalid.  On the i386, request an ast to send us
80  * through trap(), marking the proc as needing a profiling tick.
81  */
82 #define	need_proftick(p)	((p)->p_flag |= P_OWEUPC, setsoftast())
83 
84 /*
85  * Notify the current process (p) that it has a signal pending,
86  * process as soon as possible.
87  */
88 #define	signotify(p)		setsoftast()
89 
90 /*
91  * We need a machine-independent name for this.
92  */
93 #define	DELAY(x)		delay(x)
94 void	delay(int);
95 
96 #if defined(I586_CPU) || defined(I686_CPU)
97 /*
98  * High resolution clock support (Pentium only)
99  */
100 void	calibrate_cyclecounter(void);
101 #ifndef	HZ
102 #ifndef PENTIUM_BROKEN_TSC
103 extern u_quad_t pentium_base_tsc;
104 #define CPU_CLOCKUPDATE()						\
105 	do {								\
106 		if (pentium_mhz) {					\
107 			__asm __volatile("cli\n"			\
108 					 "rdtsc\n"			\
109 					 "sti\n"			\
110 					 : "=A" (pentium_base_tsc)	\
111 					 : );				\
112 		}							\
113 	} while (0)
114 #endif /* !PENTIUM_BROKEN_TSC */
115 #define CPU_HARDCLOCKENT_DECL						\
116 	static u_quad_t cpu_hce_tsc
117 #define CPU_HARDCLOCKENT() do {						\
118 	if (pentium_mhz) {						\
119 		u_quad_t cpu_hce_val = cpu_hce_tsc;			\
120 									\
121 		__asm __volatile("cli\n"				\
122 				 "rdtsc\n"				\
123 				 "sti\n"				\
124 				 : "=A" (cpu_hce_tsc) : );		\
125 		HARDCLOCKENT_APPLY(cpu_hce_tsc - cpu_hce_val);		\
126 	}								\
127 } while (0)
128 #endif /* !HZ */
129 #define	__do_calibrate_cyclecounter(rvptr)				\
130 	do {								\
131 		if (pentium_mhz) {					\
132 			int i = splhigh();				\
133 			calibrate_cyclecounter();			\
134 			splx(i);					\
135 		}							\
136 	} while (0)
137 #else /* !(I586_CPU || I686_CPU) */
138 #define __do_calibrate_cyclecounter(rvptr)	/* nothing */
139 #endif /* !(I586_CPU || I686_CPU) */
140 
141 /*
142  * pull in #defines for kinds of processors
143  */
144 #include <machine/cputypes.h>
145 
146 struct cpu_nocpuid_nameclass {
147 	int cpu_vendor;
148 	const char *cpu_vendorname;
149 	const char *cpu_name;
150 	int cpu_class;
151 	void (*cpu_setup)(const char *, int, int);
152 };
153 
154 struct cpu_cpuid_nameclass {
155 	const char *cpu_id;
156 	int cpu_vendor;
157 	const char *cpu_vendorname;
158 	struct cpu_cpuid_family {
159 		int cpu_class;
160 		const char *cpu_models[CPU_MAXMODEL+2];
161 		void (*cpu_setup)(const char *, int, int);
162 	} cpu_family[CPU_MAXFAMILY - CPU_MINFAMILY + 1];
163 };
164 
165 struct cpu_cpuid_feature {
166 	int feature_bit;
167 	const char *feature_name;
168 };
169 
170 #ifdef _KERNEL
171 extern int cpu;
172 extern int cpu_class;
173 extern int cpu_feature;
174 extern int cpu_ecxfeature;
175 extern int cpu_apmwarn;
176 extern int cpu_apmhalt;
177 extern int cpuid_level;
178 extern const struct cpu_nocpuid_nameclass i386_nocpuid_cpus[];
179 extern const struct cpu_cpuid_nameclass i386_cpuid_cpus[];
180 
181 #if defined(I586_CPU) || defined(I686_CPU)
182 extern int pentium_mhz;
183 #endif
184 
185 #ifdef I586_CPU
186 /* F00F bug fix stuff for pentium cpu */
187 extern int cpu_f00f_bug;
188 void fix_f00f(void);
189 #endif
190 
191 /* dkcsum.c */
192 void	dkcsumattach(void);
193 
194 extern int i386_use_fxsave;
195 extern int i386_has_sse;
196 extern int i386_has_sse2;
197 
198 /* machdep.c */
199 void	dumpconf(void);
200 void	cpu_reset(void) __dead;
201 void	i386_proc0_tss_ldt_init(void);
202 void	cpuid(u_int32_t, u_int32_t *);
203 
204 /* locore.s */
205 struct region_descriptor;
206 void	lgdt(struct region_descriptor *);
207 void	fillw(short, void *, size_t);
208 
209 struct pcb;
210 void	savectx(struct pcb *);
211 void	switch_exit(struct proc *);
212 void	proc_trampoline(void);
213 
214 /* clock.c */
215 void	initrtclock(void);
216 void	startrtclock(void);
217 void	rtcdrain(void *);
218 
219 /* est.c */
220 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
221 void	est_init(const char *);
222 int     est_cpuspeed(int *);
223 int     est_setperf(int);
224 #endif
225 
226 /* longrun.c */
227 #if !defined(SMALL_KERNEL) && defined(I586_CPU)
228 void	longrun_init(void);
229 int	longrun_cpuspeed(int *);
230 int	longrun_setperf(int);
231 #endif
232 
233 /* p4tcc.c */
234 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
235 void	p4tcc_init(int, int);
236 int     p4tcc_setperf(int);
237 #endif
238 
239 void	k6_powernow_init(void);
240 int	k6_powernow_setperf(int);
241 void	k7_powernow_init(void);
242 int	k7_powernow_setperf(int);
243 
244 
245 /* npx.c */
246 void	npxdrop(void);
247 void	npxsave(void);
248 
249 #ifdef USER_LDT
250 /* sys_machdep.h */
251 extern int user_ldt_enable;
252 int	i386_get_ldt(struct proc *, void *, register_t *);
253 int	i386_set_ldt(struct proc *, void *, register_t *);
254 #endif
255 
256 /* isa_machdep.c */
257 void	isa_defaultirq(void);
258 int	isa_nmi(void);
259 
260 /* pmap.c */
261 void	pmap_bootstrap(vaddr_t);
262 
263 /* vm_machdep.c */
264 int	kvtop(caddr_t);
265 
266 #ifdef VM86
267 /* vm86.c */
268 void	vm86_gpfault(struct proc *, int);
269 #endif /* VM86 */
270 
271 #ifdef GENERIC
272 /* swapgeneric.c */
273 void	setconf(void);
274 #endif /* GENERIC */
275 
276 #endif /* _KERNEL */
277 
278 /*
279  * CTL_MACHDEP definitions.
280  */
281 #define	CPU_CONSDEV		1	/* dev_t: console terminal device */
282 #define	CPU_BIOS		2	/* BIOS variables */
283 #define	CPU_BLK2CHR		3	/* convert blk maj into chr one */
284 #define	CPU_CHR2BLK		4	/* convert chr maj into blk one */
285 #define CPU_ALLOWAPERTURE	5	/* allow mmap of /dev/xf86 */
286 #define CPU_CPUVENDOR		6	/* cpuid vendor string */
287 #define CPU_CPUID		7	/* cpuid */
288 #define CPU_CPUFEATURE		8	/* cpuid features */
289 #define CPU_APMWARN		9	/* APM battery warning percentage */
290 #define CPU_KBDRESET		10	/* keyboard reset under pcvt */
291 #define CPU_APMHALT		11	/* halt -p hack */
292 #define CPU_USERLDT		12
293 #define CPU_OSFXSR		13	/* uses FXSAVE/FXRSTOR */
294 #define CPU_SSE			14	/* supports SSE */
295 #define CPU_SSE2		15	/* supports SSE2 */
296 #define CPU_XCRYPT		16	/* supports VIA xcrypt in userland */
297 #define CPU_APVRESET		17	/* reset VGA on panic() if XF86 */
298 #define CPU_MAXID		18	/* number of valid machdep ids */
299 
300 #define	CTL_MACHDEP_NAMES { \
301 	{ 0, 0 }, \
302 	{ "console_device", CTLTYPE_STRUCT }, \
303 	{ "bios", CTLTYPE_INT }, \
304 	{ "blk2chr", CTLTYPE_STRUCT }, \
305 	{ "chr2blk", CTLTYPE_STRUCT }, \
306 	{ "allowaperture", CTLTYPE_INT }, \
307 	{ "cpuvendor", CTLTYPE_STRING }, \
308 	{ "cpuid", CTLTYPE_INT }, \
309 	{ "cpufeature", CTLTYPE_INT }, \
310 	{ "apmwarn", CTLTYPE_INT }, \
311 	{ "kbdreset", CTLTYPE_INT }, \
312 	{ "apmhalt", CTLTYPE_INT }, \
313 	{ "userldt", CTLTYPE_INT }, \
314 	{ "osfxsr", CTLTYPE_INT }, \
315 	{ "sse", CTLTYPE_INT }, \
316 	{ "sse2", CTLTYPE_INT }, \
317 	{ "xcrypt", CTLTYPE_INT }, \
318 	{ "apvreset", CTLTYPE_INT }, \
319 }
320 
321 #endif /* !_I386_CPU_H_ */
322