xref: /openbsd-src/sys/arch/amd64/include/cpu.h (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: cpu.h,v 1.103 2016/09/04 09:22:28 mpi 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 #endif /* _KERNEL */
50 
51 #include <sys/device.h>
52 #include <sys/sched.h>
53 #include <sys/sensors.h>
54 
55 #ifdef _KERNEL
56 
57 /* VMXON region (Intel) */
58 struct vmxon_region {
59         uint32_t        vr_revision;
60 };
61 
62 /*
63  * VMX for Intel CPUs
64  */
65 struct vmx {
66 	uint64_t	vmx_cr0_fixed0;
67 	uint64_t	vmx_cr0_fixed1;
68 	uint64_t	vmx_cr4_fixed0;
69 	uint64_t	vmx_cr4_fixed1;
70 	uint32_t	vmx_vmxon_revision;
71 	uint32_t	vmx_msr_table_size;
72 };
73 
74 /*
75  * SVM for AMD CPUs
76  */
77 struct svm {
78 };
79 
80 union vmm_cpu_cap {
81 	struct vmx vcc_vmx;
82 	struct svm vcc_svm;
83 };
84 
85 struct x86_64_tss;
86 struct cpu_info {
87 	struct device *ci_dev;
88 	struct cpu_info *ci_self;
89 	struct schedstate_percpu ci_schedstate; /* scheduler state */
90 	struct cpu_info *ci_next;
91 
92 	struct proc *ci_curproc;
93 	u_int ci_cpuid;
94 	u_int ci_apicid;
95 	u_int ci_acpi_proc_id;
96 	u_int32_t ci_randseed;
97 
98 	u_int64_t ci_scratch;
99 
100 	struct proc *ci_fpcurproc;
101 	struct proc *ci_fpsaveproc;
102 	int ci_fpsaving;
103 
104 	struct pcb *ci_curpcb;
105 	struct pcb *ci_idle_pcb;
106 
107 	struct intrsource *ci_isources[MAX_INTR_SOURCES];
108 	u_int64_t	ci_ipending;
109 	int		ci_ilevel;
110 	int		ci_idepth;
111 	int		ci_handled_intr_level;
112 	u_int64_t	ci_imask[NIPL];
113 	u_int64_t	ci_iunmask[NIPL];
114 #ifdef DIAGNOSTIC
115 	int		ci_mutex_level;
116 #endif
117 
118 	volatile u_int	ci_flags;
119 	u_int32_t	ci_ipis;
120 
121 	u_int32_t	ci_feature_flags;
122 	u_int32_t	ci_feature_eflags;
123 	u_int32_t	ci_feature_sefflags_ebx;
124 	u_int32_t	ci_feature_sefflags_ecx;
125 	u_int32_t	ci_feature_tpmflags;
126 	u_int32_t	ci_pnfeatset;
127 	u_int32_t	ci_efeature_eax;
128 	u_int32_t	ci_efeature_ecx;
129 	u_int32_t	ci_brand[12];
130 	u_int32_t	ci_amdcacheinfo[4];
131 	u_int32_t	ci_extcacheinfo[4];
132 	u_int32_t	ci_signature;
133 	u_int32_t	ci_family;
134 	u_int32_t	ci_model;
135 	u_int32_t	ci_cflushsz;
136 	u_int64_t	ci_tsc_freq;
137 
138 	int		ci_inatomic;
139 
140 #define ARCH_HAVE_CPU_TOPOLOGY
141 	u_int32_t	ci_smt_id;
142 	u_int32_t	ci_core_id;
143 	u_int32_t	ci_pkg_id;
144 
145 	struct cpu_functions *ci_func;
146 	void (*cpu_setup)(struct cpu_info *);
147 	void (*ci_info)(struct cpu_info *);
148 
149 	struct device	*ci_acpicpudev;
150 	volatile u_int	ci_mwait;
151 #define	MWAIT_IN_IDLE		0x1	/* don't need IPI to wake */
152 #define	MWAIT_KEEP_IDLING	0x2	/* cleared by other cpus to wake me */
153 #define	MWAIT_ONLY		0x4	/* set if all idle states use mwait */
154 #define	MWAIT_IDLING	(MWAIT_IN_IDLE | MWAIT_KEEP_IDLING)
155 
156 	int		ci_want_resched;
157 
158 	struct x86_cache_info ci_cinfo[CAI_COUNT];
159 
160 	struct	x86_64_tss *ci_tss;
161 	char		*ci_gdt;
162 
163 	volatile int	ci_ddb_paused;
164 #define CI_DDB_RUNNING		0
165 #define CI_DDB_SHOULDSTOP	1
166 #define CI_DDB_STOPPED		2
167 #define CI_DDB_ENTERDDB		3
168 #define CI_DDB_INDDB		4
169 
170 #ifdef MULTIPROCESSOR
171 	struct srp_hazard	ci_srp_hazards[SRP_HAZARD_NUM];
172 #endif
173 
174 	struct ksensordev	ci_sensordev;
175 	struct ksensor		ci_sensor;
176 #if defined(GPROF) || defined(DDBPROF)
177 	struct gmonparam	*ci_gmon;
178 #endif
179 	u_int32_t	ci_vmm_flags;
180 #define	CI_VMM_VMX	(1 << 0)
181 #define	CI_VMM_SVM	(1 << 1)
182 #define	CI_VMM_RVI	(1 << 2)
183 #define	CI_VMM_EPT	(1 << 3)
184 	union		vmm_cpu_cap ci_vmm_cap;
185 	paddr_t		ci_vmxon_region_pa;
186 	struct vmxon_region *ci_vmxon_region;
187 };
188 
189 #define CPUF_BSP	0x0001		/* CPU is the original BSP */
190 #define CPUF_AP		0x0002		/* CPU is an AP */
191 #define CPUF_SP		0x0004		/* CPU is only processor */
192 #define CPUF_PRIMARY	0x0008		/* CPU is active primary processor */
193 
194 #define CPUF_IDENTIFY	0x0010		/* CPU may now identify */
195 #define CPUF_IDENTIFIED	0x0020		/* CPU has been identified */
196 
197 #define CPUF_CONST_TSC	0x0040		/* CPU has constant TSC */
198 #define CPUF_USERSEGS_BIT	7	/* CPU has curproc's segments */
199 #define CPUF_USERSEGS	(1<<CPUF_USERSEGS_BIT)		/* and FS.base */
200 
201 #define CPUF_PRESENT	0x1000		/* CPU is present */
202 #define CPUF_RUNNING	0x2000		/* CPU is running */
203 #define CPUF_PAUSE	0x4000		/* CPU is paused in DDB */
204 #define CPUF_GO		0x8000		/* CPU should start running */
205 #define CPUF_PARK	0x10000		/* CPU should self-park in real mode */
206 #define CPUF_VMM	0x20000		/* CPU is executing in VMM mode */
207 
208 #define PROC_PC(p)	((p)->p_md.md_regs->tf_rip)
209 #define PROC_STACK(p)	((p)->p_md.md_regs->tf_rsp)
210 
211 extern struct cpu_info cpu_info_primary;
212 extern struct cpu_info *cpu_info_list;
213 
214 #define CPU_INFO_ITERATOR		int
215 #define CPU_INFO_FOREACH(cii, ci)	for (cii = 0, ci = cpu_info_list; \
216 					    ci != NULL; ci = ci->ci_next)
217 
218 #define CPU_INFO_UNIT(ci)	((ci)->ci_dev ? (ci)->ci_dev->dv_unit : 0)
219 
220 /*
221  * Preempt the current process if in interrupt from user mode,
222  * or after the current trap/syscall if in system mode.
223  */
224 extern void need_resched(struct cpu_info *);
225 #define clear_resched(ci) (ci)->ci_want_resched = 0
226 
227 #if defined(MULTIPROCESSOR)
228 
229 #define MAXCPUS		64	/* bitmask */
230 
231 #define CPU_STARTUP(_ci)	((_ci)->ci_func->start(_ci))
232 #define CPU_STOP(_ci)		((_ci)->ci_func->stop(_ci))
233 #define CPU_START_CLEANUP(_ci)	((_ci)->ci_func->cleanup(_ci))
234 
235 #define curcpu()	({struct cpu_info *__ci;                  \
236 			asm volatile("movq %%gs:8,%0" : "=r" (__ci)); \
237 			__ci;})
238 #define cpu_number()	(curcpu()->ci_cpuid)
239 
240 #define CPU_IS_PRIMARY(ci)	((ci)->ci_flags & CPUF_PRIMARY)
241 
242 extern struct cpu_info *cpu_info[MAXCPUS];
243 
244 void cpu_boot_secondary_processors(void);
245 void cpu_init_idle_pcbs(void);
246 
247 void cpu_kick(struct cpu_info *);
248 void cpu_unidle(struct cpu_info *);
249 
250 #define CPU_BUSY_CYCLE()	__asm volatile("pause": : : "memory")
251 
252 #else /* !MULTIPROCESSOR */
253 
254 #define MAXCPUS		1
255 
256 #ifdef _KERNEL
257 extern struct cpu_info cpu_info_primary;
258 
259 #define curcpu()		(&cpu_info_primary)
260 
261 #define cpu_kick(ci)
262 #define cpu_unidle(ci)
263 
264 #define CPU_BUSY_CYCLE()	do {} while (0)
265 
266 #endif
267 
268 /*
269  * definitions of cpu-dependent requirements
270  * referenced in generic code
271  */
272 #define	cpu_number()		0
273 #define CPU_IS_PRIMARY(ci)	1
274 
275 #endif	/* MULTIPROCESSOR */
276 
277 #include <machine/psl.h>
278 
279 #endif /* _KERNEL */
280 
281 #ifdef MULTIPROCESSOR
282 #include <sys/mplock.h>
283 #endif
284 
285 #define aston(p)	((p)->p_md.md_astpending = 1)
286 
287 #define curpcb		curcpu()->ci_curpcb
288 
289 /*
290  * Arguments to hardclock, softclock and statclock
291  * encapsulate the previous machine state in an opaque
292  * clockframe; for now, use generic intrframe.
293  */
294 #define clockframe intrframe
295 
296 #define	CLKF_USERMODE(frame)	USERMODE((frame)->if_cs, (frame)->if_rflags)
297 #define CLKF_PC(frame)		((frame)->if_rip)
298 #define CLKF_INTR(frame)	(curcpu()->ci_idepth > 1)
299 
300 /*
301  * Give a profiling tick to the current process when the user profiling
302  * buffer pages are invalid.  On the i386, request an ast to send us
303  * through trap(), marking the proc as needing a profiling tick.
304  */
305 #define	need_proftick(p)	aston(p)
306 
307 void signotify(struct proc *);
308 
309 /*
310  * We need a machine-independent name for this.
311  */
312 extern void (*delay_func)(int);
313 struct timeval;
314 
315 #define DELAY(x)		(*delay_func)(x)
316 #define delay(x)		(*delay_func)(x)
317 
318 
319 #ifdef _KERNEL
320 /* locore.S */
321 extern int biosbasemem;
322 extern int biosextmem;
323 extern int cpu;
324 extern int cpu_feature;
325 extern int cpu_ebxfeature;
326 extern int cpu_ecxfeature;
327 extern int cpu_perf_eax;
328 extern int cpu_perf_ebx;
329 extern int cpu_perf_edx;
330 extern int cpu_apmi_edx;
331 extern int ecpu_ecxfeature;
332 extern int cpu_id;
333 extern char cpu_vendor[];
334 extern int cpuid_level;
335 extern int cpuspeed;
336 
337 /* cpu.c */
338 extern u_int cpu_mwait_size;
339 extern u_int cpu_mwait_states;
340 
341 /* identcpu.c */
342 void	identifycpu(struct cpu_info *);
343 int	cpu_amd64speed(int *);
344 
345 /* machdep.c */
346 void	dumpconf(void);
347 void	cpu_reset(void);
348 void	x86_64_proc0_tss_ldt_init(void);
349 void	x86_64_bufinit(void);
350 void	x86_64_init_pcb_tss_ldt(struct cpu_info *);
351 void	cpu_proc_fork(struct proc *, struct proc *);
352 int	amd64_pa_used(paddr_t);
353 extern void (*cpu_idle_enter_fcn)(void);
354 extern void (*cpu_idle_cycle_fcn)(void);
355 extern void (*cpu_idle_leave_fcn)(void);
356 
357 struct region_descriptor;
358 void	lgdt(struct region_descriptor *);
359 
360 struct pcb;
361 void	savectx(struct pcb *);
362 void	switch_exit(struct proc *, void (*)(struct proc *));
363 void	proc_trampoline(void);
364 
365 /* clock.c */
366 extern void (*initclock_func)(void);
367 void	startclocks(void);
368 void	rtcstart(void);
369 void	rtcstop(void);
370 void	i8254_delay(int);
371 void	i8254_initclocks(void);
372 void	i8254_startclock(void);
373 void	i8254_inittimecounter(void);
374 void	i8254_inittimecounter_simple(void);
375 
376 /* i8259.c */
377 void	i8259_default_setup(void);
378 
379 
380 void cpu_init_msrs(struct cpu_info *);
381 
382 
383 /* dkcsum.c */
384 void	dkcsumattach(void);
385 
386 /* bus_machdep.c */
387 void x86_bus_space_init(void);
388 void x86_bus_space_mallocok(void);
389 
390 /* powernow-k8.c */
391 void k8_powernow_init(struct cpu_info *);
392 void k8_powernow_setperf(int);
393 
394 /* k1x-pstate.c */
395 void k1x_init(struct cpu_info *);
396 void k1x_setperf(int);
397 
398 void est_init(struct cpu_info *);
399 void est_setperf(int);
400 
401 #ifdef MULTIPROCESSOR
402 /* mp_setperf.c */
403 void mp_setperf_init(void);
404 #endif
405 
406 #endif /* _KERNEL */
407 
408 /*
409  * CTL_MACHDEP definitions.
410  */
411 #define	CPU_CONSDEV		1	/* dev_t: console terminal device */
412 #define	CPU_BIOS		2	/* BIOS variables */
413 #define	CPU_BLK2CHR		3	/* convert blk maj into chr one */
414 #define	CPU_CHR2BLK		4	/* convert chr maj into blk one */
415 #define CPU_ALLOWAPERTURE	5	/* allow mmap of /dev/xf86 */
416 #define CPU_CPUVENDOR		6	/* cpuid vendor string */
417 #define CPU_CPUID		7	/* cpuid */
418 #define CPU_CPUFEATURE		8	/* cpuid features */
419 #define CPU_APMWARN		9	/* APM battery warning percentage */
420 #define CPU_KBDRESET		10	/* keyboard reset under pcvt */
421 #define CPU_APMHALT		11	/* halt -p hack */
422 #define CPU_XCRYPT		12	/* supports VIA xcrypt in userland */
423 #define CPU_LIDSUSPEND		13	/* lid close causes a suspend */
424 #define CPU_MAXID		14	/* number of valid machdep ids */
425 
426 #define	CTL_MACHDEP_NAMES { \
427 	{ 0, 0 }, \
428 	{ "console_device", CTLTYPE_STRUCT }, \
429 	{ "bios", CTLTYPE_INT }, \
430 	{ "blk2chr", CTLTYPE_STRUCT }, \
431 	{ "chr2blk", CTLTYPE_STRUCT }, \
432 	{ "allowaperture", CTLTYPE_INT }, \
433 	{ "cpuvendor", CTLTYPE_STRING }, \
434 	{ "cpuid", CTLTYPE_INT }, \
435 	{ "cpufeature", CTLTYPE_INT }, \
436 	{ "apmwarn", CTLTYPE_INT }, \
437 	{ "kbdreset", CTLTYPE_INT }, \
438 	{ "apmhalt", CTLTYPE_INT }, \
439 	{ "xcrypt", CTLTYPE_INT }, \
440 	{ "lidsuspend", CTLTYPE_INT }, \
441 }
442 
443 /*
444  * Default cr4 flags.
445  * Doesn't really belong here, but doesn't really belong anywhere else
446  * either. Just to avoid painful mismatches of cr4 flags since they are
447  * set in three different places.
448  */
449 #define CR4_DEFAULT (CR4_PAE|CR4_PGE|CR4_PSE|CR4_OSFXSR|CR4_OSXMMEXCPT)
450 
451 #endif /* !_MACHINE_CPU_H_ */
452