1/* 2 * Copyright 2018, J��r��me Duval, jerome.duval@gmail.com. 3 * Copyright 2002-2009, Axel D��rfler, axeld@pinc-software.de. 4 * Copyright 2012, Alex Smith, alex@alex-smith.me.uk. 5 * Distributed under the terms of the MIT License. 6 * 7 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. 8 * Distributed under the terms of the NewOS License. 9 */ 10#ifndef _KERNEL_ARCH_x86_CPU_H 11#define _KERNEL_ARCH_x86_CPU_H 12 13 14#ifndef _ASSEMBLER 15 16#include <module.h> 17 18#include <arch_thread_types.h> 19 20#include <arch/x86/arch_altcodepatch.h> 21#include <arch/x86/arch_cpuasm.h> 22#include <arch/x86/descriptors.h> 23 24#ifdef __x86_64__ 25# include <arch/x86/64/cpu.h> 26#endif 27 28#endif // !_ASSEMBLER 29 30 31#define CPU_MAX_CACHE_LEVEL 8 32 33#define CACHE_LINE_SIZE 64 34 35 36// MSR registers (possibly Intel specific) 37#define IA32_MSR_TSC 0x10 38#define IA32_MSR_PLATFORM_ID 0x17 39#define IA32_MSR_APIC_BASE 0x1b 40#define IA32_MSR_SPEC_CTRL 0x48 41#define IA32_MSR_PRED_CMD 0x49 42#define IA32_MSR_UCODE_WRITE 0x79 // IA32_BIOS_UPDT_TRIG 43#define IA32_MSR_UCODE_REV 0x8b // IA32_BIOS_SIGN_ID 44#define IA32_MSR_PLATFORM_INFO 0xce 45#define IA32_MSR_MPERF 0xe7 46#define IA32_MSR_APERF 0xe8 47#define IA32_MSR_MTRR_CAPABILITIES 0xfe 48#define IA32_MSR_ARCH_CAPABILITIES 0x10a 49#define IA32_MSR_FLUSH_CMD 0x10b 50#define IA32_MSR_SYSENTER_CS 0x174 51#define IA32_MSR_SYSENTER_ESP 0x175 52#define IA32_MSR_SYSENTER_EIP 0x176 53#define IA32_MSR_PERF_STATUS 0x198 54#define IA32_MSR_PERF_CTL 0x199 55#define IA32_MSR_TURBO_RATIO_LIMIT 0x1ad 56#define IA32_MSR_ENERGY_PERF_BIAS 0x1b0 57#define IA32_MSR_MTRR_DEFAULT_TYPE 0x2ff 58#define IA32_MSR_MTRR_PHYSICAL_BASE_0 0x200 59#define IA32_MSR_MTRR_PHYSICAL_MASK_0 0x201 60 61// MSR SPEC CTRL bits 62#define IA32_MSR_SPEC_CTRL_IBRS (1 << 0) 63#define IA32_MSR_SPEC_CTRL_STIBP (1 << 1) 64#define IA32_MSR_SPEC_CTRL_SSBD (1 << 2) 65 66// MSR PRED CMD bits 67#define IA32_MSR_PRED_CMD_IBPB (1 << 0) 68 69// MSR APIC BASE bits 70#define IA32_MSR_APIC_BASE_BSP 0x00000100 71#define IA32_MSR_APIC_BASE_X2APIC 0x00000400 72#define IA32_MSR_APIC_BASE_ENABLED 0x00000800 73#define IA32_MSR_APIC_BASE_ADDRESS 0xfffff000 74 75// MSR EFER bits 76// reference 77#define IA32_MSR_EFER_SYSCALL (1 << 0) 78#define IA32_MSR_EFER_NX (1 << 11) 79 80// MSR ARCH CAPABILITIES bits 81#define IA32_MSR_ARCH_CAP_RDCL_NO (1 << 0) 82#define IA32_MSR_ARCH_CAP_IBRS_ALL (1 << 1) 83#define IA32_MSR_ARCH_CAP_RSBA (1 << 2) 84#define IA32_MSR_ARCH_CAP_SKIP_L1D_VMENTRY (1 << 3) 85#define IA32_MSR_ARCH_CAP_SSB_NO (1 << 4) 86 87// MSR FLUSH CMD bits 88#define IA32_MSR_L1D_FLUSH (1 << 1) 89 90// X2APIC MSRs. 91#define IA32_MSR_APIC_ID 0x00000802 92#define IA32_MSR_APIC_VERSION 0x00000803 93#define IA32_MSR_APIC_TASK_PRIORITY 0x00000808 94#define IA32_MSR_APIC_PROCESSOR_PRIORITY 0x0000080a 95#define IA32_MSR_APIC_EOI 0x0000080b 96#define IA32_MSR_APIC_LOGICAL_DEST 0x0000080d 97#define IA32_MSR_APIC_SPURIOUS_INTR_VECTOR 0x0000080f 98#define IA32_MSR_APIC_ERROR_STATUS 0x00000828 99#define IA32_MSR_APIC_INTR_COMMAND 0x00000830 100#define IA32_MSR_APIC_LVT_TIMER 0x00000832 101#define IA32_MSR_APIC_LVT_THERMAL_SENSOR 0x00000833 102#define IA32_MSR_APIC_LVT_PERFMON_COUNTERS 0x00000834 103#define IA32_MSR_APIC_LVT_LINT0 0x00000835 104#define IA32_MSR_APIC_LVT_LINT1 0x00000836 105#define IA32_MSR_APIC_LVT_ERROR 0x00000837 106#define IA32_MSR_APIC_INITIAL_TIMER_COUNT 0x00000838 107#define IA32_MSR_APIC_CURRENT_TIMER_COUNT 0x00000839 108#define IA32_MSR_APIC_TIMER_DIVIDE_CONFIG 0x0000083e 109#define IA32_MSR_APIC_SELF_IPI 0x0000083f 110#define IA32_MSR_XSS 0x00000da0 111 112// x86_64 MSRs. 113#define IA32_MSR_EFER 0xc0000080 114#define IA32_MSR_STAR 0xc0000081 115#define IA32_MSR_LSTAR 0xc0000082 116#define IA32_MSR_CSTAR 0xc0000083 117#define IA32_MSR_FMASK 0xc0000084 118#define IA32_MSR_FS_BASE 0xc0000100 119#define IA32_MSR_GS_BASE 0xc0000101 120#define IA32_MSR_KERNEL_GS_BASE 0xc0000102 121#define IA32_MSR_TSC_AUX 0xc0000103 122 123// AMD MSR registers 124#define MSR_F10H_HWCR 0xc0010015 125#define HWCR_TSCFREQSEL (1 << 24) 126#define MSR_K8_UCODE_UPDATE 0xc0010020 127#define K8_MSR_IPM 0xc0010055 128#define MSR_F10H_PSTATEDEF(x) (0xc0010064 + (x)) 129#define PSTATEDEF_EN (1ULL << 63) 130#define MSR_F10H_DE_CFG 0xc0011029 131#define DE_CFG_SERIALIZE_LFENCE (1 << 1) 132 133#define MSR_AMD_CPPC_CAP1 0xc00102b0 134#define AMD_CPPC_LOWEST_PERF(x) ((x) & 0xff) 135#define AMD_CPPC_LOWNONLIN_PERF(x) ((x >> 8) & 0xff) 136#define AMD_CPPC_NOMINAL_PERF(x) ((x >> 16) & 0xff) 137#define AMD_CPPC_HIGHEST_PERF(x) ((x >> 24) & 0xff) 138#define MSR_AMD_CPPC_ENABLE 0xc00102b1 139#define MSR_AMD_CPPC_REQ 0xc00102b3 140#define AMD_CPPC_MAX_PERF(x) ((x) & 0xff) 141#define AMD_CPPC_MIN_PERF(x) (((x) & 0xff) << 8) 142#define AMD_CPPC_DES_PERF(x) (((x) & 0xff) << 16) 143#define AMD_CPPC_EPP_PERF(x) (((x) & 0xff) << 24) 144 145#define AMD_CPPC_EPP_PERFORMANCE 0x00 146#define AMD_CPPC_EPP_BALANCE_PERFORMANCE 0x80 147#define AMD_CPPC_EPP_BALANCE_POWERSAVE 0xbf 148#define AMD_CPPC_EPP_POWERSAVE 0xff 149#define MSR_AMD_CPPC_STATUS 0xc00102b4 150 151 152// Hardware P-States MSR registers ��14.4.1 153// reference https://software.intel.com/content/dam/develop/public/us/en/documents/253669-sdm-vol-3b.pdf 154#define IA32_MSR_PM_ENABLE 0x00000770 155#define IA32_MSR_HWP_CAPABILITIES 0x00000771 156#define IA32_MSR_HWP_REQUEST_PKG 0x00000772 157#define IA32_MSR_HWP_INTERRUPT 0x00000773 158#define IA32_MSR_HWP_REQUEST 0x00000774 159#define IA32_MSR_HWP_STATUS 0x00000777 160 161// IA32_MSR_HWP_CAPABILITIES bits ��14.4.3 162#define IA32_HWP_CAPS_HIGHEST_PERFORMANCE(x) (((x) >> 0) & 0xff) 163#define IA32_HWP_CAPS_GUARANTEED_PERFORMANCE(x) (((x) >> 8) & 0xff) 164#define IA32_HWP_CAPS_EFFICIENT_PERFORMANCE(x) (((x) >> 16) & 0xff) 165#define IA32_HWP_CAPS_LOWEST_PERFORMANCE(x) (((x) >> 24) & 0xff) 166 167// IA32_MSR_HWP_REQUEST bits ��14.4.4.1 168#define IA32_HWP_REQUEST_MINIMUM_PERFORMANCE (0xffULL << 0) 169#define IA32_HWP_REQUEST_MAXIMUM_PERFORMANCE (0xffULL << 8) 170#define IA32_HWP_REQUEST_DESIRED_PERFORMANCE (0xffULL << 16) 171#define IA32_HWP_REQUEST_ENERGY_PERFORMANCE_PREFERENCE (0xffULL << 24) 172#define IA32_HWP_REQUEST_ACTIVITY_WINDOW (0x3ffULL << 32) 173#define IA32_HWP_REQUEST_PACKAGE_CONTROL (1ULL << 42) 174#define IA32_HWP_REQUEST_ACTIVITY_WINDOW_VALID (1ULL << 59) 175#define IA32_HWP_REQUEST_EPP_VALID (1ULL << 60) 176#define IA32_HWP_REQUEST_DESIRED_VALID (1ULL << 61) 177#define IA32_HWP_REQUEST_MAXIMUM_VALID (1ULL << 62) 178#define IA32_HWP_REQUEST_MINIMUM_VALID (1ULL << 63) 179 180// x86 features from cpuid eax 1, edx register 181// reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-5) 182#define IA32_FEATURE_FPU (1 << 0) // x87 fpu 183#define IA32_FEATURE_VME (1 << 1) // virtual 8086 184#define IA32_FEATURE_DE (1 << 2) // debugging extensions 185#define IA32_FEATURE_PSE (1 << 3) // page size extensions 186#define IA32_FEATURE_TSC (1 << 4) // rdtsc instruction 187#define IA32_FEATURE_MSR (1 << 5) // rdmsr/wrmsr instruction 188#define IA32_FEATURE_PAE (1 << 6) // extended 3 level page table addressing 189#define IA32_FEATURE_MCE (1 << 7) // machine check exception 190#define IA32_FEATURE_CX8 (1 << 8) // cmpxchg8b instruction 191#define IA32_FEATURE_APIC (1 << 9) // local apic on chip 192// (1 << 10) // Reserved 193#define IA32_FEATURE_SEP (1 << 11) // SYSENTER/SYSEXIT 194#define IA32_FEATURE_MTRR (1 << 12) // MTRR 195#define IA32_FEATURE_PGE (1 << 13) // paging global bit 196#define IA32_FEATURE_MCA (1 << 14) // machine check architecture 197#define IA32_FEATURE_CMOV (1 << 15) // cmov instruction 198#define IA32_FEATURE_PAT (1 << 16) // page attribute table 199#define IA32_FEATURE_PSE36 (1 << 17) // page size extensions with 4MB pages 200#define IA32_FEATURE_PSN (1 << 18) // processor serial number 201#define IA32_FEATURE_CLFSH (1 << 19) // cflush instruction 202// (1 << 20) // Reserved 203#define IA32_FEATURE_DS (1 << 21) // debug store 204#define IA32_FEATURE_ACPI (1 << 22) // thermal monitor and clock ctrl 205#define IA32_FEATURE_MMX (1 << 23) // mmx instructions 206#define IA32_FEATURE_FXSR (1 << 24) // FXSAVE/FXRSTOR instruction 207#define IA32_FEATURE_SSE (1 << 25) // SSE 208#define IA32_FEATURE_SSE2 (1 << 26) // SSE2 209#define IA32_FEATURE_SS (1 << 27) // self snoop 210#define IA32_FEATURE_HTT (1 << 28) // hyperthreading 211#define IA32_FEATURE_TM (1 << 29) // thermal monitor 212#define IA32_FEATURE_IA64 (1 << 30) // IA64 processor emulating x86 213#define IA32_FEATURE_PBE (1 << 31) // pending break enable 214 215// x86 features from cpuid eax 1, ecx register 216// reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-4) 217#define IA32_FEATURE_EXT_SSE3 (1 << 0) // SSE3 218#define IA32_FEATURE_EXT_PCLMULQDQ (1 << 1) // PCLMULQDQ Instruction 219#define IA32_FEATURE_EXT_DTES64 (1 << 2) // 64-Bit Debug Store 220#define IA32_FEATURE_EXT_MONITOR (1 << 3) // MONITOR/MWAIT 221#define IA32_FEATURE_EXT_DSCPL (1 << 4) // CPL qualified debug store 222#define IA32_FEATURE_EXT_VMX (1 << 5) // Virtual Machine Extensions 223#define IA32_FEATURE_EXT_SMX (1 << 6) // Safer Mode Extensions 224#define IA32_FEATURE_EXT_EST (1 << 7) // Enhanced SpeedStep 225#define IA32_FEATURE_EXT_TM2 (1 << 8) // Thermal Monitor 2 226#define IA32_FEATURE_EXT_SSSE3 (1 << 9) // Supplemental SSE-3 227#define IA32_FEATURE_EXT_CNXTID (1 << 10) // L1 Context ID 228// (1 << 11) // Reserved 229#define IA32_FEATURE_EXT_FMA (1 << 12) // Fused Multiply Add 230#define IA32_FEATURE_EXT_CX16 (1 << 13) // CMPXCHG16B 231#define IA32_FEATURE_EXT_XTPR (1 << 14) // xTPR Update Control 232#define IA32_FEATURE_EXT_PDCM (1 << 15) // Perfmon and Debug Capability 233// (1 << 16) // Reserved 234#define IA32_FEATURE_EXT_PCID (1 << 17) // Process Context Identifiers 235#define IA32_FEATURE_EXT_DCA (1 << 18) // Direct Cache Access 236#define IA32_FEATURE_EXT_SSE4_1 (1 << 19) // SSE4.1 237#define IA32_FEATURE_EXT_SSE4_2 (1 << 20) // SSE4.2 238#define IA32_FEATURE_EXT_X2APIC (1 << 21) // Extended xAPIC Support 239#define IA32_FEATURE_EXT_MOVBE (1 << 22) // MOVBE Instruction 240#define IA32_FEATURE_EXT_POPCNT (1 << 23) // POPCNT Instruction 241#define IA32_FEATURE_EXT_TSCDEADLINE (1 << 24) // Time Stamp Counter Deadline 242#define IA32_FEATURE_EXT_AES (1 << 25) // AES Instruction Extensions 243#define IA32_FEATURE_EXT_XSAVE (1 << 26) // XSAVE/XSTOR States 244#define IA32_FEATURE_EXT_OSXSAVE (1 << 27) // OS-Enabled XSAVE 245#define IA32_FEATURE_EXT_AVX (1 << 28) // Advanced Vector Extensions 246#define IA32_FEATURE_EXT_F16C (1 << 29) // 16-bit FP conversion 247#define IA32_FEATURE_EXT_RDRND (1 << 30) // RDRAND instruction 248#define IA32_FEATURE_EXT_HYPERVISOR (1 << 31) // Running on a hypervisor 249 250// x86 features from cpuid eax 0x80000001, ecx register (AMD) 251#define IA32_FEATURE_AMD_EXT_CMPLEGACY (1 << 1) // Core MP legacy mode 252#define IA32_FEATURE_AMD_EXT_TOPOLOGY (1 << 22) // Topology extensions 253 254// x86 features from cpuid eax 0x80000001, edx register (AMD) 255// only care about the ones that are unique to this register 256#define IA32_FEATURE_AMD_EXT_SYSCALL (1 << 11) // SYSCALL/SYSRET 257#define IA32_FEATURE_AMD_EXT_NX (1 << 20) // no execute bit 258#define IA32_FEATURE_AMD_EXT_MMXEXT (1 << 22) // mmx extensions 259#define IA32_FEATURE_AMD_EXT_FFXSR (1 << 25) // fast FXSAVE/FXRSTOR 260#define IA32_FEATURE_AMD_EXT_PDPE1GB (1 << 26) // Gibibyte pages 261#define IA32_FEATURE_AMD_EXT_RDTSCP (1 << 27) // rdtscp instruction 262#define IA32_FEATURE_AMD_EXT_LONG (1 << 29) // long mode 263#define IA32_FEATURE_AMD_EXT_3DNOWEXT (1 << 30) // 3DNow! extensions 264#define IA32_FEATURE_AMD_EXT_3DNOW (1 << 31) // 3DNow! 265 266// some of the features from cpuid eax 0x80000001, edx register (AMD) are also 267// available on Intel processors 268#define IA32_FEATURES_INTEL_EXT (IA32_FEATURE_AMD_EXT_SYSCALL \ 269 | IA32_FEATURE_AMD_EXT_NX \ 270 | IA32_FEATURE_AMD_EXT_PDPE1GB \ 271 | IA32_FEATURE_AMD_EXT_RDTSCP \ 272 | IA32_FEATURE_AMD_EXT_LONG) 273 274// x86 defined features from cpuid eax 5, ecx register 275#define IA32_FEATURE_POWER_MWAIT (1 << 0) 276#define IA32_FEATURE_INTERRUPT_MWAIT (1 << 1) 277 278// x86 defined features from cpuid eax 6, eax register 279// reference https://software.intel.com/content/dam/develop/public/us/en/documents/253666-sdm-vol-2a.pdf (Table 3-8) 280#define IA32_FEATURE_DTS (1 << 0) // Digital Thermal Sensor 281#define IA32_FEATURE_ITB (1 << 1) // Intel Turbo Boost Technology 282#define IA32_FEATURE_ARAT (1 << 2) // Always running APIC Timer 283#define IA32_FEATURE_PLN (1 << 4) // Power Limit Notification 284#define IA32_FEATURE_ECMD (1 << 5) // Extended Clock Modulation Duty 285#define IA32_FEATURE_PTM (1 << 6) // Package Thermal Management 286#define IA32_FEATURE_HWP (1 << 7) // Hardware P-states 287#define IA32_FEATURE_HWP_NOTIFY (1 << 8) // HWP Notification 288#define IA32_FEATURE_HWP_ACTWIN (1 << 9) // HWP Activity Window 289#define IA32_FEATURE_HWP_EPP (1 << 10) // HWP Energy Performance Preference 290#define IA32_FEATURE_HWP_PLR (1 << 11) // HWP Package Level Request 291#define IA32_FEATURE_HDC (1 << 13) // Hardware Duty Cycling 292#define IA32_FEATURE_TBMT3 (1 << 14) // Turbo Boost Max Technology 3.0 293#define IA32_FEATURE_HWP_CAP (1 << 15) // HWP Capabilities 294#define IA32_FEATURE_HWP_PECI (1 << 16) // HWP PECI override 295#define IA32_FEATURE_HWP_FLEX (1 << 17) // Flexible HWP 296#define IA32_FEATURE_HWP_FAST (1 << 18) // Fast access for HWP_REQUEST MSR 297#define IA32_FEATURE_HW_FEEDBACK (1 << 19) // HW_FEEDBACK*, PACKAGE_THERM* 298#define IA32_FEATURE_HWP_IGNIDL (1 << 20) // Ignore Idle Logical Processor HWP 299 300// x86 defined features from cpuid eax 6, ecx register 301// reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-11) 302#define IA32_FEATURE_APERFMPERF (1 << 0) // IA32_APERF, IA32_MPERF 303#define IA32_FEATURE_EPB (1 << 3) // IA32_ENERGY_PERF_BIAS 304 305// x86 features from cpuid eax 7, ebx register 306// reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 3-8) 307#define IA32_FEATURE_TSC_ADJUST (1 << 1) // IA32_TSC_ADJUST MSR supported 308#define IA32_FEATURE_SGX (1 << 2) // Software Guard Extensions 309#define IA32_FEATURE_BMI1 (1 << 3) // Bit Manipulation Instruction Set 1 310#define IA32_FEATURE_HLE (1 << 4) // Hardware Lock Elision 311#define IA32_FEATURE_AVX2 (1 << 5) // Advanced Vector Extensions 2 312#define IA32_FEATURE_SMEP (1 << 7) // Supervisor-Mode Execution Prevention 313#define IA32_FEATURE_BMI2 (1 << 8) // Bit Manipulation Instruction Set 2 314#define IA32_FEATURE_ERMS (1 << 9) // Enhanced REP MOVSB/STOSB 315#define IA32_FEATURE_INVPCID (1 << 10) // INVPCID instruction 316#define IA32_FEATURE_RTM (1 << 11) // Transactional Synchronization Extensions 317#define IA32_FEATURE_CQM (1 << 12) // Platform Quality of Service Monitoring 318#define IA32_FEATURE_MPX (1 << 14) // Memory Protection Extensions 319#define IA32_FEATURE_RDT_A (1 << 15) // Resource Director Technology Allocation 320#define IA32_FEATURE_AVX512F (1 << 16) // AVX-512 Foundation 321#define IA32_FEATURE_AVX512DQ (1 << 17) // AVX-512 Doubleword and Quadword Instructions 322#define IA32_FEATURE_RDSEED (1 << 18) // RDSEED instruction 323#define IA32_FEATURE_ADX (1 << 19) // ADX (Multi-Precision Add-Carry Instruction Extensions) 324#define IA32_FEATURE_SMAP (1 << 20) // Supervisor Mode Access Prevention 325#define IA32_FEATURE_AVX512IFMA (1 << 21) // AVX-512 Integer Fused Multiply-Add Instructions 326#define IA32_FEATURE_PCOMMIT (1 << 22) // PCOMMIT instruction 327#define IA32_FEATURE_CLFLUSHOPT (1 << 23) // CLFLUSHOPT instruction 328#define IA32_FEATURE_CLWB (1 << 24) // CLWB instruction 329#define IA32_FEATURE_INTEL_PT (1 << 25) // Intel Processor Trace 330#define IA32_FEATURE_AVX512PF (1 << 26) // AVX-512 Prefetch Instructions 331#define IA32_FEATURE_AVX512ER (1 << 27) // AVX-512 Exponential and Reciprocal Instructions 332#define IA32_FEATURE_AVX512CD (1 << 28) // AVX-512 Conflict Detection Instructions 333#define IA32_FEATURE_SHA_NI (1 << 29) // SHA extensions 334#define IA32_FEATURE_AVX512BW (1 << 30) // AVX-512 Byte and Word Instructions 335#define IA32_FEATURE_AVX512VI (1 << 31) // AVX-512 Vector Length Extensions 336 337// x86 features from cpuid eax 7, ecx register 338// reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 3-8) 339// https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features 340#define IA32_FEATURE_AVX512VMBI (1 << 1) // AVX-512 Vector Bit Manipulation Instructions 341#define IA32_FEATURE_UMIP (1 << 2) // User-mode Instruction Prevention 342#define IA32_FEATURE_PKU (1 << 3) // Memory Protection Keys for User-mode pages 343#define IA32_FEATURE_OSPKE (1 << 4) // PKU enabled by OS 344#define IA32_FEATURE_AVX512VMBI2 (1 << 6) // AVX-512 Vector Bit Manipulation Instructions 2 345#define IA32_FEATURE_GFNI (1 << 8) // Galois Field instructions 346#define IA32_FEATURE_VAES (1 << 9) // AES instruction set (VEX-256/EVEX) 347#define IA32_FEATURE_VPCLMULQDQ (1 << 10) // CLMUL instruction set (VEX-256/EVEX) 348#define IA32_FEATURE_AVX512_VNNI (1 << 11) // AVX-512 Vector Neural Network Instructions 349#define IA32_FEATURE_AVX512_BITALG (1 << 12) // AVX-512 BITALG instructions 350#define IA32_FEATURE_AVX512_VPOPCNTDQ (1 << 14) // AVX-512 Vector Population Count D/Q 351#define IA32_FEATURE_LA57 (1 << 16) // 5-level page tables 352#define IA32_FEATURE_RDPID (1 << 22) // RDPID Instruction 353#define IA32_FEATURE_SGX_LC (1 << 30) // SGX Launch Configuration 354 355// x86 features from cpuid eax 7, edx register 356// https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features 357#define IA32_FEATURE_AVX512_4VNNIW (1 << 2) // AVX-512 4-register Neural Network Instructions 358#define IA32_FEATURE_AVX512_4FMAPS (1 << 3) // AVX-512 4-register Multiply Accumulation Single precision 359#define IA32_FEATURE_HYBRID_CPU (1 << 15) // CPUs are of several types 360#define IA32_FEATURE_IBRS (1 << 26) // IBRS / IBPB Speculation Control 361#define IA32_FEATURE_STIBP (1 << 27) // STIBP Speculation Control 362#define IA32_FEATURE_L1D_FLUSH (1 << 28) // L1D_FLUSH supported 363#define IA32_FEATURE_ARCH_CAPABILITIES (1 << 29) // IA32_ARCH_CAPABILITIES MSR 364#define IA32_FEATURE_SSBD (1 << 31) // Speculative Store Bypass Disable 365 366// x86 features from cpuid eax 0xd, ecx 1, eax register 367// reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 3-8) 368#define IA32_FEATURE_XSAVEOPT (1 << 0) // XSAVEOPT Instruction 369#define IA32_FEATURE_XSAVEC (1 << 1) // XSAVEC and compacted XRSTOR 370#define IA32_FEATURE_XGETBV1 (1 << 2) // XGETBV with ECX=1 Instruction 371#define IA32_FEATURE_XSAVES (1 << 3) // XSAVES and XRSTORS Instruction 372 373// x86 defined features from cpuid eax 0x80000007, edx register 374#define IA32_FEATURE_INVARIANT_TSC (1 << 8) 375 376// x86 defined features from cpuid eax 0x80000008, ebx register 377#define IA32_FEATURE_CLZERO (1 << 0) // CLZERO instruction 378#define IA32_FEATURE_IBPB (1 << 12) // IBPB Support only (no IBRS) 379#define IA32_FEATURE_AMD_SSBD (1 << 24) // Speculative Store Bypass Disable 380#define IA32_FEATURE_VIRT_SSBD (1 << 25) // Virtualized Speculative Store Bypass Disable 381#define IA32_FEATURE_AMD_SSB_NO (1 << 26) // Speculative Store Bypass is fixed in hardware 382#define IA32_FEATURE_CPPC (1 << 27) // Collaborative Processor Performance Control 383 384 385// Memory type ranges 386#define IA32_MTR_UNCACHED 0 387#define IA32_MTR_WRITE_COMBINING 1 388#define IA32_MTR_WRITE_THROUGH 4 389#define IA32_MTR_WRITE_PROTECTED 5 390#define IA32_MTR_WRITE_BACK 6 391 392// EFLAGS register 393#define X86_EFLAGS_CARRY 0x00000001 394#define X86_EFLAGS_RESERVED1 0x00000002 395#define X86_EFLAGS_PARITY 0x00000004 396#define X86_EFLAGS_AUXILIARY_CARRY 0x00000010 397#define X86_EFLAGS_ZERO 0x00000040 398#define X86_EFLAGS_SIGN 0x00000080 399#define X86_EFLAGS_TRAP 0x00000100 400#define X86_EFLAGS_INTERRUPT 0x00000200 401#define X86_EFLAGS_DIRECTION 0x00000400 402#define X86_EFLAGS_OVERFLOW 0x00000800 403#define X86_EFLAGS_IO_PRIVILEG_LEVEL 0x00003000 404#define X86_EFLAGS_IO_PRIVILEG_LEVEL_SHIFT 12 405#define X86_EFLAGS_NESTED_TASK 0x00004000 406#define X86_EFLAGS_RESUME 0x00010000 407#define X86_EFLAGS_V86_MODE 0x00020000 408#define X86_EFLAGS_ALIGNMENT_CHECK 0x00040000 // also SMAP status 409#define X86_EFLAGS_VIRTUAL_INTERRUPT 0x00080000 410#define X86_EFLAGS_VIRTUAL_INTERRUPT_PENDING 0x00100000 411#define X86_EFLAGS_ID 0x00200000 412 413#define X86_EFLAGS_USER_FLAGS (X86_EFLAGS_CARRY | X86_EFLAGS_PARITY \ 414 | X86_EFLAGS_AUXILIARY_CARRY | X86_EFLAGS_ZERO | X86_EFLAGS_SIGN \ 415 | X86_EFLAGS_DIRECTION | X86_EFLAGS_OVERFLOW) 416 417#define CR0_CACHE_DISABLE (1UL << 30) 418#define CR0_NOT_WRITE_THROUGH (1UL << 29) 419#define CR0_FPU_EMULATION (1UL << 2) 420#define CR0_MONITOR_FPU (1UL << 1) 421 422// Control Register CR4 flags ��2.5 423// https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.pdf 424#define IA32_CR4_VME (1UL << 0) 425#define IA32_CR4_PVI (1UL << 1) 426#define IA32_CR4_TSD (1UL << 2) 427#define IA32_CR4_DE (1UL << 3) 428#define IA32_CR4_PSE (1UL << 4) 429#define IA32_CR4_PAE (1UL << 5) 430#define IA32_CR4_MCE (1UL << 6) 431#define IA32_CR4_GLOBAL_PAGES (1UL << 7) 432#define IA32_CR4_PCE (1UL << 8) 433#define CR4_OS_FXSR (1UL << 9) 434#define CR4_OS_XMM_EXCEPTION (1UL << 10) 435#define IA32_CR4_UMIP (1UL << 11) 436#define IA32_CR4_LA57 (1UL << 12) 437#define IA32_CR4_VMXE (1UL << 13) 438#define IA32_CR4_SMXE (1UL << 14) 439#define IA32_CR4_FSGSBASE (1UL << 16) 440#define IA32_CR4_PCIDE (1UL << 17) 441#define IA32_CR4_OSXSAVE (1UL << 18) 442#define IA32_CR4_SMEP (1UL << 20) 443#define IA32_CR4_SMAP (1UL << 21) 444#define IA32_CR4_PKE (1UL << 22) 445 446// Extended Control Register XCR0 flags ��13.3 447// https://software.intel.com/content/dam/develop/public/us/en/documents/253665-sdm-vol-1.pdf 448#define IA32_XCR0_X87 (1UL << 0) 449#define IA32_XCR0_SSE (1UL << 1) 450#define IA32_XCR0_AVX (1UL << 2) 451#define IA32_XCR0_BNDREG (1UL << 3) 452#define IA32_XCR0_BNDCSR (1UL << 4) 453#define IA32_XCR0_OPMASK (1UL << 5) 454#define IA32_XCR0_ZMM_HI256 (1UL << 6) 455#define IA32_XCR0_HI16_ZMM (1UL << 7) 456#define IA32_XCR0_PT (1UL << 8) 457#define IA32_XCR0_PKRU (1UL << 9) 458 459// page fault error codes (http://wiki.osdev.org/Page_Fault) 460#define PGFAULT_P 0x01 // Protection violation 461#define PGFAULT_W 0x02 // Write 462#define PGFAULT_U 0x04 // Usermode 463#define PGFAULT_RSVD 0x08 // Reserved bits 464#define PGFAULT_I 0x10 // Instruction fetch 465 466// iframe types 467#define IFRAME_TYPE_SYSCALL 0x1 468#define IFRAME_TYPE_OTHER 0x2 469#define IFRAME_TYPE_MASK 0xf 470 471 472#ifndef _ASSEMBLER 473 474 475struct X86PagingStructures; 476 477 478typedef struct x86_mtrr_info { 479 uint64 base; 480 uint64 size; 481 uint8 type; 482} x86_mtrr_info; 483 484typedef struct x86_cpu_module_info { 485 module_info info; 486 uint32 (*count_mtrrs)(void); 487 void (*init_mtrrs)(void); 488 489 void (*set_mtrr)(uint32 index, uint64 base, uint64 length, 490 uint8 type); 491 status_t (*get_mtrr)(uint32 index, uint64* _base, uint64* _length, 492 uint8* _type); 493 void (*set_mtrrs)(uint8 defaultType, const x86_mtrr_info* infos, 494 uint32 count); 495} x86_cpu_module_info; 496 497// features 498enum x86_feature_type { 499 FEATURE_COMMON = 0, // cpuid eax=1, ecx register 500 FEATURE_EXT, // cpuid eax=1, edx register 501 FEATURE_EXT_AMD_ECX, // cpuid eax=0x80000001, ecx register (AMD) 502 FEATURE_EXT_AMD, // cpuid eax=0x80000001, edx register (AMD) 503 FEATURE_5_ECX, // cpuid eax=5, ecx register 504 FEATURE_6_EAX, // cpuid eax=6, eax registers 505 FEATURE_6_ECX, // cpuid eax=6, ecx registers 506 FEATURE_7_EBX, // cpuid eax=7, ebx registers 507 FEATURE_7_ECX, // cpuid eax=7, ecx registers 508 FEATURE_7_EDX, // cpuid eax=7, edx registers 509 FEATURE_EXT_7_EDX, // cpuid eax=0x80000007, edx register 510 FEATURE_EXT_8_EBX, // cpuid eax=0x80000008, ebx register 511 FEATURE_D_1_EAX, // cpuid eax=0xd, ecx=1, eax register 512 513 FEATURE_NUM 514}; 515 516enum x86_vendors { 517 VENDOR_INTEL = 0, 518 VENDOR_AMD, 519 VENDOR_CYRIX, 520 VENDOR_UMC, 521 VENDOR_NEXGEN, 522 VENDOR_CENTAUR, 523 VENDOR_RISE, 524 VENDOR_TRANSMETA, 525 VENDOR_NSC, 526 VENDOR_HYGON, 527 528 VENDOR_NUM, 529 VENDOR_UNKNOWN, 530}; 531 532 533typedef struct arch_cpu_info { 534 // saved cpu info 535 enum x86_vendors vendor; 536 uint32 feature[FEATURE_NUM]; 537 char model_name[49]; 538 const char* vendor_name; 539 int type; 540 int family; 541 int extended_family; 542 int stepping; 543 int model; 544 int extended_model; 545 uint32 patch_level; 546 uint8 hybrid_type; 547 548 uint32 logical_apic_id; 549 550 uint64 mperf_prev; 551 uint64 aperf_prev; 552 bigtime_t perf_timestamp; 553 uint64 frequency; 554 555 struct X86PagingStructures* active_paging_structures; 556 557 size_t dr6; // temporary storage for debug registers (cf. 558 size_t dr7; // x86_exit_user_debug_at_kernel_entry()) 559 560 // local TSS for this cpu 561 struct tss tss; 562#ifndef __x86_64__ 563 struct tss double_fault_tss; 564 void* kernel_tls; 565#endif 566} arch_cpu_info; 567 568 569// Reference Intel SDM Volume 3 9.11 "Microcode Update Facilities" 570// https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.pdf 571// 9.11.1 Table 9-7. Microcode Update Field Definitions 572struct intel_microcode_header { 573 uint32 header_version; 574 uint32 update_revision; 575 uint32 date; 576 uint32 processor_signature; 577 uint32 checksum; 578 uint32 loader_revision; 579 uint32 processor_flags; 580 uint32 data_size; 581 uint32 total_size; 582 uint32 reserved[3]; 583}; 584 585 586struct intel_microcode_extended_signature_header { 587 uint32 extended_signature_count; 588 uint32 extended_checksum; 589 uint32 reserved[3]; 590}; 591 592 593struct intel_microcode_extended_signature { 594 uint32 processor_signature; 595 uint32 processor_flags; 596 uint32 checksum; 597}; 598 599 600// AMD Microcode structures 601 602struct amd_container_header { 603 uint32 magic; 604}; 605 606 607struct amd_section_header { 608 uint32 type; 609 uint32 size; 610}; 611 612 613struct amd_equiv_cpu_entry { 614 uint32 installed_cpu; 615 uint32 fixed_errata_mask; 616 uint32 fixed_errata_compare; 617 uint16 equiv_cpu; 618 uint16 res; 619}; 620 621 622struct amd_microcode_header { 623 uint32 data_code; 624 uint32 patch_id; 625 uint16 mc_patch_data_id; 626 uint8 mc_patch_data_len; 627 uint8 init_flag; 628 uint32 mc_patch_data_checksum; 629 uint32 nb_dev_id; 630 uint32 sb_dev_id; 631 uint16 processor_rev_id; 632 uint8 nb_rev_id; 633 uint8 sb_rev_id; 634 uint8 bios_api_rev; 635 uint8 reserved1[3]; 636 uint32 match_reg[8]; 637}; 638 639 640extern void (*gCpuIdleFunc)(void); 641 642 643#ifdef __cplusplus 644extern "C" { 645#endif 646 647struct arch_thread; 648 649#ifdef __x86_64__ 650void __x86_setup_system_time(uint64 conversionFactor, 651 uint64 conversionFactorNsecs); 652#else 653void __x86_setup_system_time(uint32 conversionFactor, 654 uint32 conversionFactorNsecs, bool conversionFactorNsecsShift); 655#endif 656 657status_t __x86_patch_errata_percpu(int cpu); 658 659void x86_userspace_thread_exit(void); 660void x86_end_userspace_thread_exit(void); 661 662addr_t x86_get_stack_frame(); 663uint32 x86_count_mtrrs(void); 664void x86_set_mtrr(uint32 index, uint64 base, uint64 length, uint8 type); 665status_t x86_get_mtrr(uint32 index, uint64* _base, uint64* _length, 666 uint8* _type); 667void x86_set_mtrrs(uint8 defaultType, const x86_mtrr_info* infos, 668 uint32 count); 669void x86_init_fpu(); 670bool x86_check_feature(uint32 feature, enum x86_feature_type type); 671void* x86_get_double_fault_stack(int32 cpu, size_t* _size); 672int32 x86_double_fault_get_cpu(void); 673 674void x86_invalid_exception(iframe* frame); 675void x86_fatal_exception(iframe* frame); 676void x86_unexpected_exception(iframe* frame); 677void x86_hardware_interrupt(iframe* frame); 678void x86_page_fault_exception(iframe* iframe); 679 680#ifndef __x86_64__ 681 682void x86_swap_pgdir(addr_t newPageDir); 683 684uint64 x86_read_msr(uint32 registerNumber); 685void x86_write_msr(uint32 registerNumber, uint64 value); 686 687void x86_context_switch(struct arch_thread* oldState, 688 struct arch_thread* newState); 689 690void x86_fnsave(void* fpuState); 691void x86_frstor(const void* fpuState); 692 693void x86_fxsave(void* fpuState); 694void x86_fxrstor(const void* fpuState); 695 696void x86_noop_swap(void* oldFpuState, const void* newFpuState); 697void x86_fnsave_swap(void* oldFpuState, const void* newFpuState); 698void x86_fxsave_swap(void* oldFpuState, const void* newFpuState); 699 700#endif 701 702 703static inline void 704arch_cpu_idle(void) 705{ 706 gCpuIdleFunc(); 707} 708 709 710static inline void 711arch_cpu_pause(void) 712{ 713 asm volatile("pause" : : : "memory"); 714} 715 716 717#ifdef __cplusplus 718} // extern "C" { 719#endif 720 721#endif // !_ASSEMBLER 722 723#endif /* _KERNEL_ARCH_x86_CPU_H */ 724