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