1 /*        $NetBSD: cpu.h,v 1.140 2025/04/24 01:50:39 riastradh Exp $  */
2 
3 /*
4  * Copyright (c) 1990 The Regents of the University of California.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * William Jolitz.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *        @(#)cpu.h 5.4 (Berkeley) 5/9/91
35  */
36 
37 #ifndef _X86_CPU_H_
38 #define _X86_CPU_H_
39 
40 #if defined(_KERNEL) || defined(_STANDALONE)
41 #include <sys/types.h>
42 #else
43 #include <stdint.h>
44 #include <stdbool.h>
45 #endif /* _KERNEL || _STANDALONE */
46 
47 #if defined(_KERNEL) || defined(_KMEMUSER)
48 #if defined(_KERNEL_OPT)
49 #include "opt_xen.h"
50 #include "opt_svs.h"
51 #endif
52 
53 /*
54  * Definitions unique to x86 cpu support.
55  */
56 #include <machine/frame.h>
57 #include <machine/pte.h>
58 #include <machine/segments.h>
59 #include <machine/tss.h>
60 #include <machine/intrdefs.h>
61 
62 #include <x86/cacheinfo.h>
63 
64 #include <sys/cpu_data.h>
65 #include <sys/evcnt.h>
66 #include <sys/device_if.h> /* for device_t */
67 
68 #ifdef SVS
69 #include <sys/mutex.h>
70 #endif
71 
72 #ifdef XEN
73 #include <xen/include/public/xen.h>
74 #include <xen/include/public/event_channel.h>
75 #include <sys/mutex.h>
76 #endif /* XEN */
77 
78 struct intrsource;
79 struct pmap;
80 struct kcpuset;
81 
82 #ifdef __x86_64__
83 #define   i386tss   x86_64_tss
84 #endif
85 
86 #define   NIOPORTS  1024                /* # of ports we allow to be mapped */
87 #define   IOMAPSIZE (NIOPORTS / 8)      /* I/O bitmap size in bytes */
88 
89 struct cpu_tss {
90 #ifdef i386
91           struct i386tss dblflt_tss;
92           struct i386tss ddbipi_tss;
93 #endif
94           struct i386tss tss;
95           uint8_t iomap[IOMAPSIZE];
96 } __packed;
97 
98 /*
99  * Arguments to hardclock, softclock and statclock
100  * encapsulate the previous machine state in an opaque
101  * clockframe; for now, use generic intrframe.
102  */
103 struct clockframe {
104           struct intrframe cf_if;
105 };
106 
107 struct idt_vec {
108           void *iv_idt;
109           void *iv_idt_pentium;
110           char iv_allocmap[NIDT];
111 };
112 
113 /*
114  * a bunch of this belongs in cpuvar.h; move it later..
115  */
116 
117 struct cpu_info {
118           struct cpu_data ci_data;      /* MI per-cpu data */
119           device_t ci_dev;              /* pointer to our device */
120           struct cpu_info *ci_self;     /* self-pointer */
121 
122           /*
123            * Private members.
124            */
125           struct pmap *ci_pmap;                   /* current pmap */
126           int ci_want_pmapload;                   /* pmap_load() is needed */
127           volatile int ci_tlbstate;     /* one of TLBSTATE_ states. see below */
128 #define   TLBSTATE_VALID      0         /* all user tlbs are valid */
129 #define   TLBSTATE_LAZY       1         /* tlbs are valid but won't be kept uptodate */
130 #define   TLBSTATE_STALE      2         /* we might have stale user tlbs */
131           int ci_curldt;                /* current LDT descriptor */
132           int ci_nintrhand;   /* number of H/W interrupt handlers */
133           uint64_t ci_scratch;
134           uintptr_t ci_pmap_data[128 / sizeof(uintptr_t)];
135           struct kcpuset *ci_tlb_cpuset;
136           struct idt_vec ci_idtvec;
137 
138           int ci_kfpu_spl;
139 
140           struct intrsource *ci_isources[MAX_INTR_SOURCES];
141 
142           volatile int        ci_mtx_count;       /* Negative count of spin mutexes */
143           volatile int        ci_mtx_oldspl;      /* Old SPL at this ci_idepth */
144 
145           /* The following must be aligned for cmpxchg8b. */
146           union {
147                     uint64_t  ci_istate;
148                     struct {
149                               uint64_t  ci_ipending:56;
150                               uint64_t  ci_ilevel:8;
151                     };
152           } __aligned(8);
153           uint64_t  ci_imasked;
154 
155           int                 ci_idepth;
156           void *              ci_intrstack;
157           uint64_t  ci_imask[NIPL];
158           uint64_t  ci_iunmask[NIPL];
159 
160           uint32_t  ci_signature;       /* X86 cpuid type (cpuid.1.%eax) */
161           uint32_t  ci_vendor[4];       /* vendor string */
162           uint32_t  ci_max_cpuid;       /* cpuid.0:%eax */
163           uint32_t  ci_max_ext_cpuid; /* cpuid.80000000:%eax */
164           volatile uint32_t   ci_lapic_counter;
165 
166           uint32_t  ci_feat_val[8]; /* X86 CPUID feature bits */
167                               /* [0] basic features cpuid.1:%edx
168                                * [1] basic features cpuid.1:%ecx (CPUID2_xxx bits)
169                                * [2] extended features cpuid:80000001:%edx
170                                * [3] extended features cpuid:80000001:%ecx
171                                * [4] VIA padlock features
172                                * [5] structured extended features cpuid.7:%ebx
173                                * [6] structured extended features cpuid.7:%ecx
174                                * [7] structured extended features cpuid.7:%edx
175                                */
176 
177           const struct cpu_functions *ci_func;  /* start/stop functions */
178           struct trapframe *ci_ddb_regs;
179 
180           u_int ci_cflush_lsize;        /* CLFLUSH insn line size */
181           struct x86_cache_info ci_cinfo[CAI_COUNT];
182 
183           device_t  ci_frequency;       /* Frequency scaling technology */
184           device_t  ci_padlock;         /* VIA PadLock private storage */
185           device_t  ci_temperature;     /* Intel coretemp(4) or equivalent */
186           device_t  ci_vm;              /* Virtual machine guest driver */
187 
188           /*
189            * Segmentation-related data.
190            */
191           union descriptor *ci_gdt;
192           struct cpu_tss      *ci_tss;  /* Per-cpu TSSes; shared among LWPs */
193           int ci_tss_sel;                         /* TSS selector of this cpu */
194 
195           /*
196            * The following two are actually region_descriptors,
197            * but that would pollute the namespace.
198            */
199           uintptr_t ci_suspend_gdt;
200           uint16_t  ci_suspend_gdt_padding;
201           uintptr_t ci_suspend_idt;
202           uint16_t  ci_suspend_idt_padding;
203 
204           uint16_t  ci_suspend_tr;
205           uint16_t  ci_suspend_ldt;
206           uintptr_t ci_suspend_fs;
207           uintptr_t ci_suspend_gs;
208           uintptr_t ci_suspend_kgs;
209           uintptr_t ci_suspend_efer;
210           uintptr_t ci_suspend_reg[12];
211           uintptr_t ci_suspend_cr0;
212           uintptr_t ci_suspend_cr2;
213           uintptr_t ci_suspend_cr3;
214           uintptr_t ci_suspend_cr4;
215           uintptr_t ci_suspend_cr8;
216 
217           /*
218            * The following must be in their own cache line, as they are
219            * stored to regularly by remote CPUs; when they were mixed with
220            * other fields we observed frequent cache misses.
221            */
222           int                 ci_want_resched __aligned(64);
223           uint32_t  ci_ipis; /* interprocessor interrupts pending */
224 
225           /*
226            * These are largely static, and will be frequently fetched by other
227            * CPUs.  For that reason they get their own cache line, too.
228            */
229           uint32_t  ci_flags __aligned(64);/* general flags */
230           uint32_t  ci_acpiid;          /* our ACPI/MADT ID */
231           uint32_t  ci_initapicid;      /* our initial APIC ID */
232           uint32_t  ci_vcpuid;          /* our CPU id for hypervisor */
233           cpuid_t             ci_cpuid; /* our CPU ID */
234           struct cpu_info     *ci_next; /* next cpu */
235 
236           /*
237            * This is stored frequently, and is fetched by remote CPUs.
238            */
239           struct lwp          *ci_curlwp __aligned(64);/* general flags */
240           struct lwp          *ci_onproc;         /* current user LWP / kthread */
241 
242           /* Here ends the cachline-aligned sections. */
243           int                 ci_padout __aligned(64);
244 
245 #ifndef __HAVE_DIRECT_MAP
246 #define VPAGE_SRC 0
247 #define VPAGE_DST 1
248 #define VPAGE_ZER 2
249 #define VPAGE_PTP 3
250 #define VPAGE_MAX 4
251           vaddr_t             vpage[VPAGE_MAX];
252           pt_entry_t          *vpage_pte[VPAGE_MAX];
253 #endif
254 
255 #ifdef PAE
256           uint32_t  ci_pae_l3_pdirpa; /* PA of L3 PD */
257           pd_entry_t *        ci_pae_l3_pdir; /* VA pointer to L3 PD */
258 #endif
259 
260 #ifdef SVS
261           pd_entry_t *        ci_svs_updir;
262           paddr_t             ci_svs_updirpa;
263           int                 ci_svs_ldt_sel;
264           kmutex_t  ci_svs_mtx;
265           pd_entry_t *        ci_svs_rsp0_pte;
266           vaddr_t             ci_svs_rsp0;
267           vaddr_t             ci_svs_ursp0;
268           vaddr_t             ci_svs_krsp0;
269           vaddr_t             ci_svs_utls;
270 #endif
271 
272 #ifndef XENPV
273           struct evcnt ci_ipi_events[X86_NIPI];
274 #else
275           struct evcnt ci_ipi_events[XEN_NIPIS];
276 #endif
277 #ifdef XEN
278           volatile struct vcpu_info *ci_vcpu; /* for XEN */
279           u_long ci_evtmask[NR_EVENT_CHANNELS]; /* events allowed on this CPU */
280           evtchn_port_t ci_ipi_evtchn;
281 #if defined(XENPV)
282 #if defined(PAE) || defined(__x86_64__)
283           /* Currently active user PGD (can't use rcr3() with Xen) */
284           pd_entry_t *        ci_kpm_pdir;        /* per-cpu PMD (va) */
285           paddr_t             ci_kpm_pdirpa;  /* per-cpu PMD (pa) */
286           kmutex_t  ci_kpm_mtx;
287 #endif /* defined(PAE) || defined(__x86_64__) */
288 
289 #if defined(__x86_64__)
290           /* per-cpu version of normal_pdes */
291           pd_entry_t *        ci_normal_pdes[3]; /* Ok to hardcode. only for x86_64 && XENPV */
292           paddr_t             ci_xen_current_user_pgd;
293 #endif    /* defined(__x86_64__) */
294 
295           size_t              ci_xpq_idx;
296 #endif /* XENPV */
297 
298           /* Xen raw system time at which we last ran hardclock.  */
299           uint64_t  ci_xen_hardclock_systime_ns;
300 
301           /*
302            * Last TSC-adjusted local Xen system time we observed.  Used
303            * to detect whether the Xen clock has gone backwards.
304            */
305           uint64_t  ci_xen_last_systime_ns;
306 
307           /*
308            * Distance in nanoseconds from the local view of system time
309            * to the global view of system time, if the local time is
310            * behind the global time.
311            */
312           uint64_t  ci_xen_systime_ns_skew;
313 
314           /*
315            * Clockframe for timer interrupt handler.
316            * Saved at entry via event callback.
317            */
318           vaddr_t ci_xen_clockf_pc; /* RIP at last event interrupt */
319           bool ci_xen_clockf_usermode; /* Was the guest in usermode ? */
320 
321           /* Event counters for various pathologies that might happen.  */
322           struct evcnt        ci_xen_cpu_tsc_backwards_evcnt;
323           struct evcnt        ci_xen_tsc_delta_negative_evcnt;
324           struct evcnt        ci_xen_raw_systime_wraparound_evcnt;
325           struct evcnt        ci_xen_raw_systime_backwards_evcnt;
326           struct evcnt        ci_xen_systime_backwards_hardclock_evcnt;
327           struct evcnt        ci_xen_missed_hardclock_evcnt;
328           struct evcnt        ci_xen_timecounter_backwards_evcnt;
329           struct evcnt        ci_xen_timecounter_jump_evcnt;
330 #endif    /* XEN */
331 
332 #if defined(GPROF) && defined(MULTIPROCESSOR)
333           struct gmonparam *ci_gmon;    /* MI per-cpu GPROF */
334 #endif
335 };
336 
337 #if defined(XEN) && !defined(XENPV)
338           __CTASSERT(XEN_NIPIS <= X86_NIPI);
339 #endif
340 
341 /*
342  * Macros to handle (some) trapframe registers for common x86 code.
343  */
344 #ifdef __x86_64__
345 #define   X86_TF_RAX(tf)                tf->tf_rax
346 #define   X86_TF_RDX(tf)                tf->tf_rdx
347 #define   X86_TF_RSP(tf)                tf->tf_rsp
348 #define   X86_TF_RIP(tf)                tf->tf_rip
349 #define   X86_TF_RFLAGS(tf)   tf->tf_rflags
350 #else
351 #define   X86_TF_RAX(tf)                tf->tf_eax
352 #define   X86_TF_RDX(tf)                tf->tf_edx
353 #define   X86_TF_RSP(tf)                tf->tf_esp
354 #define   X86_TF_RIP(tf)                tf->tf_eip
355 #define   X86_TF_RFLAGS(tf)   tf->tf_eflags
356 #endif
357 
358 /*
359  * Processor flag notes: The "primary" CPU has certain MI-defined
360  * roles (mostly relating to hardclock handling); we distinguish
361  * between the processor which booted us, and the processor currently
362  * holding the "primary" role just to give us the flexibility later to
363  * change primaries should we be sufficiently twisted.
364  */
365 
366 #define   CPUF_BSP  0x0001              /* CPU is the original BSP */
367 #define   CPUF_AP             0x0002              /* CPU is an AP */
368 #define   CPUF_SP             0x0004              /* CPU is only processor */
369 #define   CPUF_PRIMARY        0x0008              /* CPU is active primary processor */
370 
371 #define   CPUF_SYNCTSC        0x0800              /* Synchronize TSC */
372 #define   CPUF_PRESENT        0x1000              /* CPU is present */
373 #define   CPUF_RUNNING        0x2000              /* CPU is running */
374 #define   CPUF_PAUSE          0x4000              /* CPU is paused in DDB */
375 #define   CPUF_GO             0x8000              /* CPU should start running */
376 
377 #endif /* _KERNEL || __KMEMUSER */
378 
379 #ifdef _KERNEL
380 /*
381  * We statically allocate the CPU info for the primary CPU (or,
382  * the only CPU on uniprocessors), and the primary CPU is the
383  * first CPU on the CPU info list.
384  */
385 extern struct cpu_info cpu_info_primary;
386 extern struct cpu_info *cpu_info_list;
387 
388 #define   CPU_INFO_ITERATOR             int __unused
389 #define   CPU_INFO_FOREACH(cii, ci)     ci = cpu_info_list; \
390                                                   ci != NULL; ci = ci->ci_next
391 
392 #define CPU_STARTUP(_ci, _target)       ((_ci)->ci_func->start(_ci, _target))
393 #define CPU_STOP(_ci)                   ((_ci)->ci_func->stop(_ci))
394 #define CPU_START_CLEANUP(_ci)                    ((_ci)->ci_func->cleanup(_ci))
395 
396 #if !defined(__GNUC__) || defined(_MODULE)
397 /* For non-GCC and modules */
398 struct cpu_info     *x86_curcpu(void);
399 # ifdef __GNUC__
400 lwp_t     *x86_curlwp(void) __attribute__ ((const));
401 # else
402 lwp_t   *x86_curlwp(void);
403 # endif
404 #endif
405 
406 #define cpu_number()                    (cpu_index(curcpu()))
407 
408 #define CPU_IS_PRIMARY(ci)    ((ci)->ci_flags & CPUF_PRIMARY)
409 
410 #define aston(l)              ((l)->l_md.md_astpending = 1)
411 
412 void cpu_boot_secondary_processors(void);
413 void cpu_init_idle_lwps(void);
414 void cpu_init_msrs(struct cpu_info *, bool);
415 void cpu_load_pmap(struct pmap *, struct pmap *);
416 void cpu_broadcast_halt(void);
417 void cpu_kick(struct cpu_info *);
418 
419 void cpu_pcpuarea_init(struct cpu_info *);
420 void cpu_svs_init(struct cpu_info *);
421 void cpu_speculation_init(struct cpu_info *);
422 
423 #define   curcpu()            x86_curcpu()
424 #define   curlwp                        x86_curlwp()
425 #define   curpcb                        ((struct pcb *)lwp_getpcb(curlwp))
426 
427 /*
428  * Give a profiling tick to the current process when the user profiling
429  * buffer pages are invalid.  On the i386, request an ast to send us
430  * through trap(), marking the proc as needing a profiling tick.
431  */
432 extern void         cpu_need_proftick(struct lwp *l);
433 
434 /*
435  * Notify the LWP l that it has a signal pending, process as soon as
436  * possible.
437  */
438 extern void         cpu_signotify(struct lwp *);
439 
440 /*
441  * We need a machine-independent name for this.
442  */
443 extern void (*delay_func)(unsigned int);
444 struct timeval;
445 
446 #ifndef __HIDE_DELAY
447 #define   DELAY(x)            (*delay_func)(x)
448 #define delay(x)              (*delay_func)(x)
449 #endif
450 
451 extern int biosbasemem;
452 extern int biosextmem;
453 extern int cputype;
454 extern int cpuid_level;
455 extern int cpu_class;
456 extern char cpu_brand_string[];
457 extern int use_pae;
458 
459 #ifdef __i386__
460 #define   i386_fpu_present    1
461 int npx586bug1(int, int);
462 extern int i386_fpu_fdivbug;
463 extern int i386_use_fxsave;
464 extern int i386_has_sse;
465 extern int i386_has_sse2;
466 #else
467 #define   i386_fpu_present    1
468 #define   i386_fpu_fdivbug    0
469 #define   i386_use_fxsave               1
470 #define   i386_has_sse                  1
471 #define   i386_has_sse2                 1
472 #endif
473 
474 extern int x86_fpu_save;
475 #define   FPU_SAVE_FSAVE                0
476 #define   FPU_SAVE_FXSAVE               1
477 #define   FPU_SAVE_XSAVE                2
478 #define   FPU_SAVE_XSAVEOPT   3
479 extern unsigned int x86_fpu_save_size;
480 extern uint64_t x86_xsave_features;
481 extern size_t x86_xsave_offsets[];
482 extern size_t x86_xsave_sizes[];
483 extern uint32_t x86_fpu_mxcsr_mask;
484 bool x86_fpu_save_separate_p(void);
485 
486 extern void (*x86_cpu_idle)(void);
487 #define   cpu_idle() (*x86_cpu_idle)()
488 
489 /* machdep.c */
490 #ifdef i386
491 void      cpu_set_tss_gates(struct cpu_info *);
492 #endif
493 void      cpu_reset(void);
494 
495 /* longrun.c */
496 u_int     tmx86_get_longrun_mode(void);
497 void      tmx86_get_longrun_status(u_int *, u_int *, u_int *);
498 void      tmx86_init_longrun(void);
499 
500 /* identcpu.c */
501 void      cpu_probe(struct cpu_info *);
502 void      cpu_identify(struct cpu_info *);
503 void      identify_hypervisor(void);
504 
505 /* identcpu_subr.c */
506 uint64_t cpu_tsc_freq_cpuid(struct cpu_info *);
507 void      cpu_dcp_cacheinfo(struct cpu_info *, uint32_t);
508 
509 typedef enum vm_guest {
510           VM_GUEST_NO = 0,
511           VM_GUEST_VM,
512           VM_GUEST_XENPV,
513           VM_GUEST_XENPVH,
514           VM_GUEST_XENHVM,
515           VM_GUEST_XENPVHVM,
516           VM_GUEST_HV,
517           VM_GUEST_VMWARE,
518           VM_GUEST_KVM,
519           VM_GUEST_VIRTUALBOX,
520           VM_GUEST_GENPVH,
521           VM_GUEST_NVMM,
522           VM_LAST
523 } vm_guest_t;
524 extern vm_guest_t vm_guest;
525 
526 static __inline bool __unused
vm_guest_is_xenpv(void)527 vm_guest_is_xenpv(void)
528 {
529           switch(vm_guest) {
530           case VM_GUEST_XENPV:
531           case VM_GUEST_XENPVH:
532           case VM_GUEST_XENPVHVM:
533                     return true;
534           default:
535                     return false;
536           }
537 }
538 
539 static __inline bool __unused
vm_guest_is_xenpvh_or_pvhvm(void)540 vm_guest_is_xenpvh_or_pvhvm(void)
541 {
542           switch(vm_guest) {
543           case VM_GUEST_XENPVH:
544           case VM_GUEST_XENPVHVM:
545                     return true;
546           default:
547                     return false;
548           }
549 }
550 
551 static __inline bool __unused
vm_guest_is_pvh(void)552 vm_guest_is_pvh(void)
553 {
554           switch(vm_guest) {
555           case VM_GUEST_XENPVH:
556           case VM_GUEST_GENPVH:
557                     return true;
558           default:
559                     return false;
560           }
561 }
562 
563 /* cpu_topology.c */
564 void      x86_cpu_topology(struct cpu_info *);
565 
566 /* locore.s */
567 struct region_descriptor;
568 void      lgdt(struct region_descriptor *);
569 #ifdef XENPV
570 void      lgdt_finish(void);
571 #endif
572 
573 struct pcb;
574 void      savectx(struct pcb *);
575 void      lwp_trampoline(void);
576 #ifdef XEN
577 void      xen_startrtclock(void);
578 void      xen_delay(unsigned int);
579 void      xen_initclocks(void);
580 void      xen_cpu_initclocks(void);
581 void      xen_suspendclocks(struct cpu_info *);
582 void      xen_resumeclocks(struct cpu_info *);
583 #endif /* XEN */
584 /* clock.c */
585 void      initrtclock(u_long);
586 void      startrtclock(void);
587 void      i8254_delay(unsigned int);
588 void      i8254_microtime(struct timeval *);
589 void      i8254_initclocks(void);
590 unsigned int gettick(void);
591 extern void (*x86_delay)(unsigned int);
592 
593 /* cpu.c */
594 void      cpu_probe_features(struct cpu_info *);
595 int       x86_cpu_is_lcall(const void *);
596 
597 /* vm_machdep.c */
598 void      cpu_proc_fork(struct proc *, struct proc *);
599 paddr_t   kvtop(void *);
600 
601 /* isa_machdep.c */
602 void      isa_defaultirq(void);
603 int       isa_nmi(void);
604 
605 /* consinit.c */
606 void kgdb_port_init(void);
607 
608 /* bus_machdep.c */
609 void x86_bus_space_init(void);
610 void x86_bus_space_mallocok(void);
611 
612 #endif /* _KERNEL */
613 
614 #if defined(_KERNEL) || defined(_KMEMUSER)
615 #include <machine/psl.h>      /* Must be after struct cpu_info declaration */
616 #endif /* _KERNEL || __KMEMUSER */
617 
618 /*
619  * CTL_MACHDEP definitions.
620  */
621 #define   CPU_CONSDEV                   1         /* dev_t: console terminal device */
622 #define   CPU_BIOSBASEMEM               2         /* int: bios-reported base mem (K) */
623 #define   CPU_BIOSEXTMEM                3         /* int: bios-reported ext. mem (K) */
624 /*        CPU_NKPDE           4         obsolete: int: number of kernel PDEs */
625 #define   CPU_BOOTED_KERNEL   5         /* string: booted kernel name */
626 #define CPU_DISKINFO                    6         /* struct disklist *:
627                                                    * disk geometry information */
628 #define CPU_FPU_PRESENT                 7         /* int: FPU is present */
629 #define   CPU_OSFXSR                    8         /* int: OS uses FXSAVE/FXRSTOR */
630 #define   CPU_SSE                       9         /* int: OS/CPU supports SSE */
631 #define   CPU_SSE2            10        /* int: OS/CPU supports SSE2 */
632 #define   CPU_TMLR_MODE                 11        /* int: longrun mode
633                                                    * 0: minimum frequency
634                                                    * 1: economy
635                                                    * 2: performance
636                                                    * 3: maximum frequency
637                                                    */
638 #define   CPU_TMLR_FREQUENCY  12        /* int: current frequency */
639 #define   CPU_TMLR_VOLTAGE    13        /* int: current voltage */
640 #define   CPU_TMLR_PERCENTAGE 14        /* int: current clock percentage */
641 #define   CPU_FPU_SAVE                  15        /* int: FPU Instructions layout
642                                                    * to use this, CPU_OSFXSR must be true
643                                                    * 0: FSAVE
644                                                    * 1: FXSAVE
645                                                    * 2: XSAVE
646                                                    * 3: XSAVEOPT
647                                                    */
648 #define   CPU_FPU_SAVE_SIZE   16        /* int: FPU Instruction layout size */
649 #define   CPU_XSAVE_FEATURES  17        /* quad: XSAVE features */
650 
651 /*
652  * Structure for CPU_DISKINFO sysctl call.
653  * XXX this should be somewhere else.
654  */
655 #define MAX_BIOSDISKS         16
656 
657 struct disklist {
658           int dl_nbiosdisks;                         /* number of bios disks */
659           int dl_unused;
660           struct biosdisk_info {
661                     int bi_dev;                                /* BIOS device # (0x80 ..) */
662                     int bi_cyl;                                /* cylinders on disk */
663                     int bi_head;                               /* heads per track */
664                     int bi_sec;                                /* sectors per track */
665                     uint64_t bi_lbasecs;                       /* total sec. (iff ext13) */
666 #define BIFLAG_INVALID                  0x01
667 #define BIFLAG_EXTINT13                 0x02
668                     int bi_flags;
669                     int bi_unused;
670           } dl_biosdisks[MAX_BIOSDISKS];
671 
672           int dl_nnativedisks;                                 /* number of native disks */
673           struct nativedisk_info {
674                     char ni_devname[16];                       /* native device name */
675                     int ni_nmatches;                 /* # of matches w/ BIOS */
676                     int ni_biosmatches[MAX_BIOSDISKS]; /* indices in dl_biosdisks */
677           } dl_nativedisks[1];                                 /* actually longer */
678 };
679 #endif /* !_X86_CPU_H_ */
680