xref: /openbsd-src/sys/arch/amd64/include/cpu.h (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1 /*	$OpenBSD: cpu.h,v 1.85 2014/07/11 10:53:07 uebayasi Exp $	*/
2 /*	$NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $	*/
3 
4 /*-
5  * Copyright (c) 1990 The Regents of the University of California.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * William Jolitz.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  *	@(#)cpu.h	5.4 (Berkeley) 5/9/91
36  */
37 
38 #ifndef _MACHINE_CPU_H_
39 #define _MACHINE_CPU_H_
40 
41 /*
42  * Definitions unique to x86-64 cpu support.
43  */
44 #ifdef _KERNEL
45 #include <machine/frame.h>
46 #include <machine/segments.h>
47 #include <machine/cacheinfo.h>
48 #include <machine/intrdefs.h>
49 
50 #ifdef MULTIPROCESSOR
51 #include <machine/i82489reg.h>
52 #include <machine/i82489var.h>
53 #endif
54 
55 #endif /* _KERNEL */
56 
57 #include <sys/device.h>
58 #include <sys/lock.h>
59 #include <sys/sched.h>
60 #include <sys/sensors.h>
61 
62 #ifdef _KERNEL
63 
64 struct x86_64_tss;
65 struct cpu_info {
66 	struct device *ci_dev;
67 	struct cpu_info *ci_self;
68 	struct schedstate_percpu ci_schedstate; /* scheduler state */
69 	struct cpu_info *ci_next;
70 
71 	struct proc *ci_curproc;
72 	struct simplelock ci_slock;
73 	u_int ci_cpuid;
74 	u_int ci_apicid;
75 	u_int32_t ci_randseed;
76 
77 	u_int64_t ci_scratch;
78 
79 	struct proc *ci_fpcurproc;
80 	struct proc *ci_fpsaveproc;
81 	int ci_fpsaving;
82 
83 	struct pcb *ci_curpcb;
84 	struct pcb *ci_idle_pcb;
85 
86 	struct intrsource *ci_isources[MAX_INTR_SOURCES];
87 	u_int64_t	ci_ipending;
88 	int		ci_ilevel;
89 	int		ci_idepth;
90 	u_int64_t	ci_imask[NIPL];
91 	u_int64_t	ci_iunmask[NIPL];
92 #ifdef DIAGNOSTIC
93 	int		ci_mutex_level;
94 #endif
95 
96 	volatile u_int	ci_flags;
97 	u_int32_t	ci_ipis;
98 
99 	u_int32_t	ci_feature_flags;
100 	u_int32_t	ci_feature_eflags;
101 	u_int32_t	ci_feature_sefflags;
102 	u_int32_t	ci_signature;
103 	u_int32_t	ci_family;
104 	u_int32_t	ci_model;
105 	u_int32_t	ci_cflushsz;
106 	u_int64_t	ci_tsc_freq;
107 
108 	int		ci_inatomic;
109 
110 #define ARCH_HAVE_CPU_TOPOLOGY
111 	u_int32_t	ci_smt_id;
112 	u_int32_t	ci_core_id;
113 	u_int32_t	ci_pkg_id;
114 
115 	struct cpu_functions *ci_func;
116 	void (*cpu_setup)(struct cpu_info *);
117 	void (*ci_info)(struct cpu_info *);
118 
119 	u_int		*ci_mwait;
120 /* bits in ci_mwait[0] */
121 #define	MWAIT_IN_IDLE		0x1	/* don't need IPI to wake */
122 #define	MWAIT_KEEP_IDLING	0x2	/* cleared by other cpus to wake me */
123 #define	MWAIT_IDLING	(MWAIT_IN_IDLE | MWAIT_KEEP_IDLING)
124 
125 	int		ci_want_resched;
126 
127 	struct x86_cache_info ci_cinfo[CAI_COUNT];
128 
129 	struct	x86_64_tss *ci_tss;
130 	char		*ci_gdt;
131 
132 	volatile int	ci_ddb_paused;
133 #define CI_DDB_RUNNING		0
134 #define CI_DDB_SHOULDSTOP	1
135 #define CI_DDB_STOPPED		2
136 #define CI_DDB_ENTERDDB		3
137 #define CI_DDB_INDDB		4
138 
139 	volatile int ci_setperf_state;
140 #define CI_SETPERF_READY	0
141 #define CI_SETPERF_SHOULDSTOP	1
142 #define CI_SETPERF_INTRANSIT	2
143 #define CI_SETPERF_DONE		3
144 
145 	struct ksensordev	ci_sensordev;
146 	struct ksensor		ci_sensor;
147 #ifdef GPROF
148 	struct gmonparam	*ci_gmon;
149 #endif
150 };
151 
152 #define CPUF_BSP	0x0001		/* CPU is the original BSP */
153 #define CPUF_AP		0x0002		/* CPU is an AP */
154 #define CPUF_SP		0x0004		/* CPU is only processor */
155 #define CPUF_PRIMARY	0x0008		/* CPU is active primary processor */
156 
157 #define CPUF_IDENTIFY	0x0010		/* CPU may now identify */
158 #define CPUF_IDENTIFIED	0x0020		/* CPU has been identified */
159 
160 #define CPUF_CONST_TSC	0x0040		/* CPU has constant TSC */
161 
162 #define CPUF_PRESENT	0x1000		/* CPU is present */
163 #define CPUF_RUNNING	0x2000		/* CPU is running */
164 #define CPUF_PAUSE	0x4000		/* CPU is paused in DDB */
165 #define CPUF_GO		0x8000		/* CPU should start running */
166 #define CPUF_PARK	0x10000		/* CPU should self-park in real mode */
167 
168 #define PROC_PC(p)	((p)->p_md.md_regs->tf_rip)
169 #define PROC_STACK(p)	((p)->p_md.md_regs->tf_rsp)
170 
171 extern struct cpu_info cpu_info_primary;
172 extern struct cpu_info *cpu_info_list;
173 
174 #define CPU_INFO_ITERATOR		int
175 #define CPU_INFO_FOREACH(cii, ci)	for (cii = 0, ci = cpu_info_list; \
176 					    ci != NULL; ci = ci->ci_next)
177 
178 #define CPU_INFO_UNIT(ci)	((ci)->ci_dev ? (ci)->ci_dev->dv_unit : 0)
179 
180 /*
181  * Preempt the current process if in interrupt from user mode,
182  * or after the current trap/syscall if in system mode.
183  */
184 extern void need_resched(struct cpu_info *);
185 #define clear_resched(ci) (ci)->ci_want_resched = 0
186 
187 #if defined(MULTIPROCESSOR)
188 
189 #define MAXCPUS		64	/* bitmask */
190 
191 #define CPU_STARTUP(_ci)	((_ci)->ci_func->start(_ci))
192 #define CPU_STOP(_ci)		((_ci)->ci_func->stop(_ci))
193 #define CPU_START_CLEANUP(_ci)	((_ci)->ci_func->cleanup(_ci))
194 
195 #define curcpu()	({struct cpu_info *__ci;                  \
196 			asm volatile("movq %%gs:8,%0" : "=r" (__ci)); \
197 			__ci;})
198 #define cpu_number()	(curcpu()->ci_cpuid)
199 
200 #define CPU_IS_PRIMARY(ci)	((ci)->ci_flags & CPUF_PRIMARY)
201 
202 extern struct cpu_info *cpu_info[MAXCPUS];
203 
204 void cpu_boot_secondary_processors(void);
205 void cpu_init_idle_pcbs(void);
206 
207 void cpu_kick(struct cpu_info *);
208 void cpu_unidle(struct cpu_info *);
209 
210 #define CPU_BUSY_CYCLE()	__asm volatile("pause": : : "memory")
211 
212 #else /* !MULTIPROCESSOR */
213 
214 #define MAXCPUS		1
215 
216 #ifdef _KERNEL
217 extern struct cpu_info cpu_info_primary;
218 
219 #define curcpu()		(&cpu_info_primary)
220 
221 #define cpu_kick(ci)
222 #define cpu_unidle(ci)
223 
224 #define CPU_BUSY_CYCLE()	do {} while (0)
225 
226 #endif
227 
228 /*
229  * definitions of cpu-dependent requirements
230  * referenced in generic code
231  */
232 #define	cpu_number()		0
233 #define CPU_IS_PRIMARY(ci)	1
234 
235 #endif	/* MULTIPROCESSOR */
236 
237 #include <machine/psl.h>
238 
239 #endif /* _KERNEL */
240 
241 #ifdef MULTIPROCESSOR
242 #include <sys/mplock.h>
243 #endif
244 
245 #define aston(p)	((p)->p_md.md_astpending = 1)
246 
247 #define curpcb		curcpu()->ci_curpcb
248 
249 /*
250  * Arguments to hardclock, softclock and statclock
251  * encapsulate the previous machine state in an opaque
252  * clockframe; for now, use generic intrframe.
253  */
254 #define clockframe intrframe
255 
256 #define	CLKF_USERMODE(frame)	USERMODE((frame)->if_cs, (frame)->if_rflags)
257 #define CLKF_PC(frame)		((frame)->if_rip)
258 #define CLKF_INTR(frame)	(curcpu()->ci_idepth > 1)
259 
260 /*
261  * This is used during profiling to integrate system time.
262  */
263 #define	PROC_PC(p)		((p)->p_md.md_regs->tf_rip)
264 
265 /*
266  * Give a profiling tick to the current process when the user profiling
267  * buffer pages are invalid.  On the i386, request an ast to send us
268  * through trap(), marking the proc as needing a profiling tick.
269  */
270 #define	need_proftick(p)	aston(p)
271 
272 void signotify(struct proc *);
273 
274 /*
275  * We need a machine-independent name for this.
276  */
277 extern void (*delay_func)(int);
278 struct timeval;
279 
280 #define DELAY(x)		(*delay_func)(x)
281 #define delay(x)		(*delay_func)(x)
282 
283 
284 #ifdef _KERNEL
285 extern int biosbasemem;
286 extern int biosextmem;
287 extern int cpu;
288 extern int cpu_feature;
289 extern int cpu_ecxfeature;
290 extern int cpu_perf_eax;
291 extern int cpu_perf_ebx;
292 extern int cpu_perf_edx;
293 extern int cpu_apmi_edx;
294 extern int ecpu_ecxfeature;
295 extern int cpu_id;
296 extern char cpu_vendor[];
297 extern int cpuid_level;
298 extern int cpuspeed;
299 
300 /* identcpu.c */
301 void	identifycpu(struct cpu_info *);
302 int	cpu_amd64speed(int *);
303 
304 /* machdep.c */
305 void	dumpconf(void);
306 void	cpu_reset(void);
307 void	x86_64_proc0_tss_ldt_init(void);
308 void	x86_64_bufinit(void);
309 void	x86_64_init_pcb_tss_ldt(struct cpu_info *);
310 void	cpu_proc_fork(struct proc *, struct proc *);
311 int	amd64_pa_used(paddr_t);
312 extern void (*cpu_idle_enter_fcn)(void);
313 extern void (*cpu_idle_cycle_fcn)(void);
314 extern void (*cpu_idle_leave_fcn)(void);
315 
316 struct region_descriptor;
317 void	lgdt(struct region_descriptor *);
318 
319 struct pcb;
320 void	savectx(struct pcb *);
321 void	switch_exit(struct proc *, void (*)(struct proc *));
322 void	proc_trampoline(void);
323 void	child_trampoline(void);
324 
325 /* clock.c */
326 extern void (*initclock_func)(void);
327 void	startclocks(void);
328 void	rtcstart(void);
329 void	rtcstop(void);
330 void	i8254_delay(int);
331 void	i8254_initclocks(void);
332 void	i8254_startclock(void);
333 void	i8254_inittimecounter(void);
334 void	i8254_inittimecounter_simple(void);
335 
336 /* i8259.c */
337 void	i8259_default_setup(void);
338 
339 
340 void cpu_init_msrs(struct cpu_info *);
341 
342 
343 /* trap.c */
344 void	child_return(void *);
345 
346 /* dkcsum.c */
347 void	dkcsumattach(void);
348 
349 /* bus_machdep.c */
350 void x86_bus_space_init(void);
351 void x86_bus_space_mallocok(void);
352 
353 /* powernow-k8.c */
354 void k8_powernow_init(struct cpu_info *);
355 void k8_powernow_setperf(int);
356 
357 /* k1x-pstate.c */
358 void k1x_init(struct cpu_info *);
359 void k1x_setperf(int);
360 
361 void est_init(struct cpu_info *);
362 void est_setperf(int);
363 
364 #ifdef MULTIPROCESSOR
365 /* mp_setperf.c */
366 void mp_setperf_init(void);
367 #endif
368 
369 #endif /* _KERNEL */
370 
371 /*
372  * CTL_MACHDEP definitions.
373  */
374 #define	CPU_CONSDEV		1	/* dev_t: console terminal device */
375 #define	CPU_BIOS		2	/* BIOS variables */
376 #define	CPU_BLK2CHR		3	/* convert blk maj into chr one */
377 #define	CPU_CHR2BLK		4	/* convert chr maj into blk one */
378 #define CPU_ALLOWAPERTURE	5	/* allow mmap of /dev/xf86 */
379 #define CPU_CPUVENDOR		6	/* cpuid vendor string */
380 #define CPU_CPUID		7	/* cpuid */
381 #define CPU_CPUFEATURE		8	/* cpuid features */
382 #define CPU_APMWARN		9	/* APM battery warning percentage */
383 #define CPU_KBDRESET		10	/* keyboard reset under pcvt */
384 #define CPU_APMHALT		11	/* halt -p hack */
385 #define CPU_XCRYPT		12	/* supports VIA xcrypt in userland */
386 #define CPU_LIDSUSPEND		13	/* lid close causes a suspend */
387 #define CPU_MAXID		14	/* number of valid machdep ids */
388 
389 #define	CTL_MACHDEP_NAMES { \
390 	{ 0, 0 }, \
391 	{ "console_device", CTLTYPE_STRUCT }, \
392 	{ "bios", CTLTYPE_INT }, \
393 	{ "blk2chr", CTLTYPE_STRUCT }, \
394 	{ "chr2blk", CTLTYPE_STRUCT }, \
395 	{ "allowaperture", CTLTYPE_INT }, \
396 	{ "cpuvendor", CTLTYPE_STRING }, \
397 	{ "cpuid", CTLTYPE_INT }, \
398 	{ "cpufeature", CTLTYPE_INT }, \
399 	{ "apmwarn", CTLTYPE_INT }, \
400 	{ "kbdreset", CTLTYPE_INT }, \
401 	{ "apmhalt", CTLTYPE_INT }, \
402 	{ "xcrypt", CTLTYPE_INT }, \
403 	{ "lidsuspend", CTLTYPE_INT }, \
404 }
405 
406 /*
407  * Default cr4 flags.
408  * Doesn't really belong here, but doesn't really belong anywhere else
409  * either. Just to avoid painful mismatches of cr4 flags since they are
410  * set in three different places.
411  */
412 #define CR4_DEFAULT (CR4_PAE|CR4_PGE|CR4_PSE|CR4_OSFXSR|CR4_OSXMMEXCPT)
413 
414 #endif /* !_MACHINE_CPU_H_ */
415