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/descriptors.h> 21 22 #ifdef __x86_64__ 23 # include <arch/x86/64/cpu.h> 24 #endif 25 26 #endif // !_ASSEMBLER 27 28 29 #define CPU_MAX_CACHE_LEVEL 8 30 31 #define CACHE_LINE_SIZE 64 32 33 34 // MSR registers (possibly Intel specific) 35 #define IA32_MSR_TSC 0x10 36 #define IA32_MSR_APIC_BASE 0x1b 37 38 #define IA32_MSR_PLATFORM_INFO 0xce 39 #define IA32_MSR_MPERF 0xe7 40 #define IA32_MSR_APERF 0xe8 41 #define IA32_MSR_MTRR_CAPABILITIES 0xfe 42 #define IA32_MSR_SYSENTER_CS 0x174 43 #define IA32_MSR_SYSENTER_ESP 0x175 44 #define IA32_MSR_SYSENTER_EIP 0x176 45 #define IA32_MSR_PERF_STATUS 0x198 46 #define IA32_MSR_PERF_CTL 0x199 47 #define IA32_MSR_TURBO_RATIO_LIMIT 0x1ad 48 #define IA32_MSR_ENERGY_PERF_BIAS 0x1b0 49 #define IA32_MSR_MTRR_DEFAULT_TYPE 0x2ff 50 #define IA32_MSR_MTRR_PHYSICAL_BASE_0 0x200 51 #define IA32_MSR_MTRR_PHYSICAL_MASK_0 0x201 52 53 54 // MSR APIC BASE bits 55 #define IA32_MSR_APIC_BASE_BSP 0x00000100 56 #define IA32_MSR_APIC_BASE_X2APIC 0x00000400 57 #define IA32_MSR_APIC_BASE_ENABLED 0x00000800 58 #define IA32_MSR_APIC_BASE_ADDRESS 0xfffff000 59 60 // MSR EFER bits 61 // reference 62 #define IA32_MSR_EFER_SYSCALL (1 << 0) 63 #define IA32_MSR_EFER_NX (1 << 11) 64 65 // X2APIC MSRs. 66 #define IA32_MSR_APIC_ID 0x00000802 67 #define IA32_MSR_APIC_VERSION 0x00000803 68 #define IA32_MSR_APIC_TASK_PRIORITY 0x00000808 69 #define IA32_MSR_APIC_PROCESSOR_PRIORITY 0x0000080a 70 #define IA32_MSR_APIC_EOI 0x0000080b 71 #define IA32_MSR_APIC_LOGICAL_DEST 0x0000080d 72 #define IA32_MSR_APIC_SPURIOUS_INTR_VECTOR 0x0000080f 73 #define IA32_MSR_APIC_ERROR_STATUS 0x00000828 74 #define IA32_MSR_APIC_INTR_COMMAND 0x00000830 75 #define IA32_MSR_APIC_LVT_TIMER 0x00000832 76 #define IA32_MSR_APIC_LVT_THERMAL_SENSOR 0x00000833 77 #define IA32_MSR_APIC_LVT_PERFMON_COUNTERS 0x00000834 78 #define IA32_MSR_APIC_LVT_LINT0 0x00000835 79 #define IA32_MSR_APIC_LVT_LINT1 0x00000836 80 #define IA32_MSR_APIC_LVT_ERROR 0x00000837 81 #define IA32_MSR_APIC_INITIAL_TIMER_COUNT 0x00000838 82 #define IA32_MSR_APIC_CURRENT_TIMER_COUNT 0x00000839 83 #define IA32_MSR_APIC_TIMER_DIVIDE_CONFIG 0x0000083e 84 #define IA32_MSR_APIC_SELF_IPI 0x0000083f 85 #define IA32_MSR_XSS 0x00000da0 86 87 // x86_64 MSRs. 88 #define IA32_MSR_EFER 0xc0000080 89 #define IA32_MSR_STAR 0xc0000081 90 #define IA32_MSR_LSTAR 0xc0000082 91 #define IA32_MSR_CSTAR 0xc0000083 92 #define IA32_MSR_FMASK 0xc0000084 93 #define IA32_MSR_FS_BASE 0xc0000100 94 #define IA32_MSR_GS_BASE 0xc0000101 95 #define IA32_MSR_KERNEL_GS_BASE 0xc0000102 96 97 // K8 MSR registers 98 #define K8_MSR_IPM 0xc0010055 99 100 // x86 features from cpuid eax 1, edx register 101 // reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-5) 102 #define IA32_FEATURE_FPU (1 << 0) // x87 fpu 103 #define IA32_FEATURE_VME (1 << 1) // virtual 8086 104 #define IA32_FEATURE_DE (1 << 2) // debugging extensions 105 #define IA32_FEATURE_PSE (1 << 3) // page size extensions 106 #define IA32_FEATURE_TSC (1 << 4) // rdtsc instruction 107 #define IA32_FEATURE_MSR (1 << 5) // rdmsr/wrmsr instruction 108 #define IA32_FEATURE_PAE (1 << 6) // extended 3 level page table addressing 109 #define IA32_FEATURE_MCE (1 << 7) // machine check exception 110 #define IA32_FEATURE_CX8 (1 << 8) // cmpxchg8b instruction 111 #define IA32_FEATURE_APIC (1 << 9) // local apic on chip 112 // (1 << 10) // Reserved 113 #define IA32_FEATURE_SEP (1 << 11) // SYSENTER/SYSEXIT 114 #define IA32_FEATURE_MTRR (1 << 12) // MTRR 115 #define IA32_FEATURE_PGE (1 << 13) // paging global bit 116 #define IA32_FEATURE_MCA (1 << 14) // machine check architecture 117 #define IA32_FEATURE_CMOV (1 << 15) // cmov instruction 118 #define IA32_FEATURE_PAT (1 << 16) // page attribute table 119 #define IA32_FEATURE_PSE36 (1 << 17) // page size extensions with 4MB pages 120 #define IA32_FEATURE_PSN (1 << 18) // processor serial number 121 #define IA32_FEATURE_CLFSH (1 << 19) // cflush instruction 122 // (1 << 20) // Reserved 123 #define IA32_FEATURE_DS (1 << 21) // debug store 124 #define IA32_FEATURE_ACPI (1 << 22) // thermal monitor and clock ctrl 125 #define IA32_FEATURE_MMX (1 << 23) // mmx instructions 126 #define IA32_FEATURE_FXSR (1 << 24) // FXSAVE/FXRSTOR instruction 127 #define IA32_FEATURE_SSE (1 << 25) // SSE 128 #define IA32_FEATURE_SSE2 (1 << 26) // SSE2 129 #define IA32_FEATURE_SS (1 << 27) // self snoop 130 #define IA32_FEATURE_HTT (1 << 28) // hyperthreading 131 #define IA32_FEATURE_TM (1 << 29) // thermal monitor 132 #define IA32_FEATURE_IA64 (1 << 30) // IA64 processor emulating x86 133 #define IA32_FEATURE_PBE (1 << 31) // pending break enable 134 135 // x86 features from cpuid eax 1, ecx register 136 // reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-4) 137 #define IA32_FEATURE_EXT_SSE3 (1 << 0) // SSE3 138 #define IA32_FEATURE_EXT_PCLMULQDQ (1 << 1) // PCLMULQDQ Instruction 139 #define IA32_FEATURE_EXT_DTES64 (1 << 2) // 64-Bit Debug Store 140 #define IA32_FEATURE_EXT_MONITOR (1 << 3) // MONITOR/MWAIT 141 #define IA32_FEATURE_EXT_DSCPL (1 << 4) // CPL qualified debug store 142 #define IA32_FEATURE_EXT_VMX (1 << 5) // Virtual Machine Extensions 143 #define IA32_FEATURE_EXT_SMX (1 << 6) // Safer Mode Extensions 144 #define IA32_FEATURE_EXT_EST (1 << 7) // Enhanced SpeedStep 145 #define IA32_FEATURE_EXT_TM2 (1 << 8) // Thermal Monitor 2 146 #define IA32_FEATURE_EXT_SSSE3 (1 << 9) // Supplemental SSE-3 147 #define IA32_FEATURE_EXT_CNXTID (1 << 10) // L1 Context ID 148 // (1 << 11) // Reserved 149 #define IA32_FEATURE_EXT_FMA (1 << 12) // Fused Multiply Add 150 #define IA32_FEATURE_EXT_CX16 (1 << 13) // CMPXCHG16B 151 #define IA32_FEATURE_EXT_XTPR (1 << 14) // xTPR Update Control 152 #define IA32_FEATURE_EXT_PDCM (1 << 15) // Perfmon and Debug Capability 153 // (1 << 16) // Reserved 154 #define IA32_FEATURE_EXT_PCID (1 << 17) // Process Context Identifiers 155 #define IA32_FEATURE_EXT_DCA (1 << 18) // Direct Cache Access 156 #define IA32_FEATURE_EXT_SSE4_1 (1 << 19) // SSE4.1 157 #define IA32_FEATURE_EXT_SSE4_2 (1 << 20) // SSE4.2 158 #define IA32_FEATURE_EXT_X2APIC (1 << 21) // Extended xAPIC Support 159 #define IA32_FEATURE_EXT_MOVBE (1 << 22) // MOVBE Instruction 160 #define IA32_FEATURE_EXT_POPCNT (1 << 23) // POPCNT Instruction 161 #define IA32_FEATURE_EXT_TSCDEADLINE (1 << 24) // Time Stamp Counter Deadline 162 #define IA32_FEATURE_EXT_AES (1 << 25) // AES Instruction Extensions 163 #define IA32_FEATURE_EXT_XSAVE (1 << 26) // XSAVE/XSTOR States 164 #define IA32_FEATURE_EXT_OSXSAVE (1 << 27) // OS-Enabled XSAVE 165 #define IA32_FEATURE_EXT_AVX (1 << 28) // Advanced Vector Extensions 166 #define IA32_FEATURE_EXT_F16C (1 << 29) // 16-bit FP conversion 167 #define IA32_FEATURE_EXT_RDRND (1 << 30) // RDRAND instruction 168 #define IA32_FEATURE_EXT_HYPERVISOR (1 << 31) // Running on a hypervisor 169 170 // x86 features from cpuid eax 0x80000001, ecx register (AMD) 171 #define IA32_FEATURE_AMD_EXT_CMPLEGACY (1 << 1) // Core MP legacy mode 172 #define IA32_FEATURE_AMD_EXT_TOPOLOGY (1 << 22) // Topology extensions 173 174 // x86 features from cpuid eax 0x80000001, edx register (AMD) 175 // only care about the ones that are unique to this register 176 #define IA32_FEATURE_AMD_EXT_SYSCALL (1 << 11) // SYSCALL/SYSRET 177 #define IA32_FEATURE_AMD_EXT_NX (1 << 20) // no execute bit 178 #define IA32_FEATURE_AMD_EXT_MMXEXT (1 << 22) // mmx extensions 179 #define IA32_FEATURE_AMD_EXT_FFXSR (1 << 25) // fast FXSAVE/FXRSTOR 180 #define IA32_FEATURE_AMD_EXT_RDTSCP (1 << 27) // rdtscp instruction 181 #define IA32_FEATURE_AMD_EXT_LONG (1 << 29) // long mode 182 #define IA32_FEATURE_AMD_EXT_3DNOWEXT (1 << 30) // 3DNow! extensions 183 #define IA32_FEATURE_AMD_EXT_3DNOW (1 << 31) // 3DNow! 184 185 // some of the features from cpuid eax 0x80000001, edx register (AMD) are also 186 // available on Intel processors 187 #define IA32_FEATURES_INTEL_EXT (IA32_FEATURE_AMD_EXT_SYSCALL \ 188 | IA32_FEATURE_AMD_EXT_NX \ 189 | IA32_FEATURE_AMD_EXT_RDTSCP \ 190 | IA32_FEATURE_AMD_EXT_LONG) 191 192 // x86 defined features from cpuid eax 5, ecx register 193 #define IA32_FEATURE_POWER_MWAIT (1 << 0) 194 #define IA32_FEATURE_INTERRUPT_MWAIT (1 << 1) 195 196 // x86 defined features from cpuid eax 6, eax register 197 // reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-11) 198 #define IA32_FEATURE_DTS (1 << 0) //Digital Thermal Sensor 199 #define IA32_FEATURE_ITB (1 << 1) //Intel Turbo Boost Technology 200 #define IA32_FEATURE_ARAT (1 << 2) //Always running APIC Timer 201 #define IA32_FEATURE_PLN (1 << 4) //Power Limit Notification 202 #define IA32_FEATURE_ECMD (1 << 5) //Extended Clock Modulation Duty 203 #define IA32_FEATURE_PTM (1 << 6) //Package Thermal Management 204 205 // x86 defined features from cpuid eax 6, ecx register 206 // reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-11) 207 #define IA32_FEATURE_APERFMPERF (1 << 0) //IA32_APERF, IA32_MPERF 208 #define IA32_FEATURE_EPB (1 << 3) //IA32_ENERGY_PERF_BIAS 209 210 // x86 features from cpuid eax 7, ebx register 211 // reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 3-8) 212 #define IA32_FEATURE_TSC_ADJUST (1 << 1) // IA32_TSC_ADJUST MSR supported 213 #define IA32_FEATURE_SGX (1 << 2) // Software Guard Extensions 214 #define IA32_FEATURE_BMI1 (1 << 3) // Bit Manipulation Instruction Set 1 215 #define IA32_FEATURE_HLE (1 << 4) // Hardware Lock Elision 216 #define IA32_FEATURE_AVX2 (1 << 5) // Advanced Vector Extensions 2 217 #define IA32_FEATURE_SMEP (1 << 7) // Supervisor-Mode Execution Prevention 218 #define IA32_FEATURE_BMI2 (1 << 8) // Bit Manipulation Instruction Set 2 219 #define IA32_FEATURE_ERMS (1 << 9) // Enhanced REP MOVSB/STOSB 220 #define IA32_FEATURE_INVPCID (1 << 10) // INVPCID instruction 221 #define IA32_FEATURE_RTM (1 << 11) // Transactional Synchronization Extensions 222 #define IA32_FEATURE_CQM (1 << 12) // Platform Quality of Service Monitoring 223 #define IA32_FEATURE_MPX (1 << 14) // Memory Protection Extensions 224 #define IA32_FEATURE_RDT_A (1 << 15) // Resource Director Technology Allocation 225 #define IA32_FEATURE_AVX512F (1 << 16) // AVX-512 Foundation 226 #define IA32_FEATURE_AVX512DQ (1 << 17) // AVX-512 Doubleword and Quadword Instructions 227 #define IA32_FEATURE_RDSEED (1 << 18) // RDSEED instruction 228 #define IA32_FEATURE_ADX (1 << 19) // ADX (Multi-Precision Add-Carry Instruction Extensions) 229 #define IA32_FEATURE_SMAP (1 << 20) // Supervisor Mode Access Prevention 230 #define IA32_FEATURE_AVX512IFMA (1 << 21) // AVX-512 Integer Fused Multiply-Add Instructions 231 #define IA32_FEATURE_PCOMMIT (1 << 22) // PCOMMIT instruction 232 #define IA32_FEATURE_CLFLUSHOPT (1 << 23) // CLFLUSHOPT instruction 233 #define IA32_FEATURE_CLWB (1 << 24) // CLWB instruction 234 #define IA32_FEATURE_INTEL_PT (1 << 25) // Intel Processor Trace 235 #define IA32_FEATURE_AVX512PF (1 << 26) // AVX-512 Prefetch Instructions 236 #define IA32_FEATURE_AVX512ER (1 << 27) // AVX-512 Exponential and Reciprocal Instructions 237 #define IA32_FEATURE_AVX512CD (1 << 28) // AVX-512 Conflict Detection Instructions 238 #define IA32_FEATURE_SHA_NI (1 << 29) // SHA extensions 239 #define IA32_FEATURE_AVX512BW (1 << 30) // AVX-512 Byte and Word Instructions 240 #define IA32_FEATURE_AVX512VI (1 << 31) // AVX-512 Vector Length Extensions 241 242 // x86 features from cpuid eax 7, ecx register 243 // reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 3-8) 244 // https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features 245 #define IA32_FEATURE_AVX512VMBI (1 << 1) // AVX-512 Vector Bit Manipulation Instructions 246 #define IA32_FEATURE_UMIP (1 << 2) // User-mode Instruction Prevention 247 #define IA32_FEATURE_PKU (1 << 3) // Memory Protection Keys for User-mode pages 248 #define IA32_FEATURE_OSPKE (1 << 4) // PKU enabled by OS 249 #define IA32_FEATURE_AVX512VMBI2 (1 << 6) // AVX-512 Vector Bit Manipulation Instructions 2 250 #define IA32_FEATURE_GFNI (1 << 8) // Galois Field instructions 251 #define IA32_FEATURE_VAES (1 << 9) // AES instruction set (VEX-256/EVEX) 252 #define IA32_FEATURE_VPCLMULQDQ (1 << 10) // CLMUL instruction set (VEX-256/EVEX) 253 #define IA32_FEATURE_AVX512_VNNI (1 << 11) // AVX-512 Vector Neural Network Instructions 254 #define IA32_FEATURE_AVX512_BITALG (1 << 12) // AVX-512 BITALG instructions 255 #define IA32_FEATURE_AVX512_VPOPCNTDQ (1 << 14) // AVX-512 Vector Population Count D/Q 256 #define IA32_FEATURE_LA57 (1 << 16) // 5-level page tables 257 #define IA32_FEATURE_RDPID (1 << 22) // RDPID Instruction 258 #define IA32_FEATURE_SGX_LC (1 << 30) // SGX Launch Configuration 259 260 // x86 features from cpuid eax 7, edx register 261 // https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features 262 #define IA32_FEATURE_AVX512_4VNNIW (1 << 2) // AVX-512 4-register Neural Network Instructions 263 #define IA32_FEATURE_AVX512_4FMAPS (1 << 3) // AVX-512 4-register Multiply Accumulation Single precision 264 #define IA32_FEATURE_IBRS (1 << 26) // IBRS / IBPB Speculation Control 265 #define IA32_FEATURE_STIBP (1 << 27) // STIBP Speculation Control 266 267 268 // x86 defined features from cpuid eax 0x80000007, edx register 269 #define IA32_FEATURE_INVARIANT_TSC (1 << 8) 270 271 // x86 defined features from cpuid eax 0x80000008, ebx register 272 #define IA32_FEATURE_AMD_EXT_IBPB (1 << 12) /* IBPB Support only (no IBRS) */ 273 274 275 // cr4 flags 276 #define IA32_CR4_PAE (1UL << 5) 277 #define IA32_CR4_GLOBAL_PAGES (1UL << 7) 278 279 // Memory type ranges 280 #define IA32_MTR_UNCACHED 0 281 #define IA32_MTR_WRITE_COMBINING 1 282 #define IA32_MTR_WRITE_THROUGH 4 283 #define IA32_MTR_WRITE_PROTECTED 5 284 #define IA32_MTR_WRITE_BACK 6 285 286 // EFLAGS register 287 #define X86_EFLAGS_CARRY 0x00000001 288 #define X86_EFLAGS_RESERVED1 0x00000002 289 #define X86_EFLAGS_PARITY 0x00000004 290 #define X86_EFLAGS_AUXILIARY_CARRY 0x00000010 291 #define X86_EFLAGS_ZERO 0x00000040 292 #define X86_EFLAGS_SIGN 0x00000080 293 #define X86_EFLAGS_TRAP 0x00000100 294 #define X86_EFLAGS_INTERRUPT 0x00000200 295 #define X86_EFLAGS_DIRECTION 0x00000400 296 #define X86_EFLAGS_OVERFLOW 0x00000800 297 #define X86_EFLAGS_IO_PRIVILEG_LEVEL 0x00003000 298 #define X86_EFLAGS_IO_PRIVILEG_LEVEL_SHIFT 12 299 #define X86_EFLAGS_NESTED_TASK 0x00004000 300 #define X86_EFLAGS_RESUME 0x00010000 301 #define X86_EFLAGS_V86_MODE 0x00020000 302 #define X86_EFLAGS_ALIGNMENT_CHECK 0x00040000 303 #define X86_EFLAGS_VIRTUAL_INTERRUPT 0x00080000 304 #define X86_EFLAGS_VIRTUAL_INTERRUPT_PENDING 0x00100000 305 #define X86_EFLAGS_ID 0x00200000 306 307 #define X86_EFLAGS_USER_FLAGS (X86_EFLAGS_CARRY | X86_EFLAGS_PARITY \ 308 | X86_EFLAGS_AUXILIARY_CARRY | X86_EFLAGS_ZERO | X86_EFLAGS_SIGN \ 309 | X86_EFLAGS_DIRECTION | X86_EFLAGS_OVERFLOW) 310 311 #define CR0_CACHE_DISABLE (1UL << 30) 312 #define CR0_NOT_WRITE_THROUGH (1UL << 29) 313 #define CR0_FPU_EMULATION (1UL << 2) 314 #define CR0_MONITOR_FPU (1UL << 1) 315 316 #define CR4_OS_FXSR (1UL << 9) 317 #define CR4_OS_XMM_EXCEPTION (1UL << 10) 318 319 320 // iframe types 321 #define IFRAME_TYPE_SYSCALL 0x1 322 #define IFRAME_TYPE_OTHER 0x2 323 #define IFRAME_TYPE_MASK 0xf 324 325 326 #ifndef _ASSEMBLER 327 328 329 struct X86PagingStructures; 330 331 332 typedef struct x86_mtrr_info { 333 uint64 base; 334 uint64 size; 335 uint8 type; 336 } x86_mtrr_info; 337 338 typedef struct x86_cpu_module_info { 339 module_info info; 340 uint32 (*count_mtrrs)(void); 341 void (*init_mtrrs)(void); 342 343 void (*set_mtrr)(uint32 index, uint64 base, uint64 length, 344 uint8 type); 345 status_t (*get_mtrr)(uint32 index, uint64* _base, uint64* _length, 346 uint8* _type); 347 void (*set_mtrrs)(uint8 defaultType, const x86_mtrr_info* infos, 348 uint32 count); 349 } x86_cpu_module_info; 350 351 // features 352 enum x86_feature_type { 353 FEATURE_COMMON = 0, // cpuid eax=1, ecx register 354 FEATURE_EXT, // cpuid eax=1, edx register 355 FEATURE_EXT_AMD_ECX, // cpuid eax=0x80000001, ecx register (AMD) 356 FEATURE_EXT_AMD, // cpuid eax=0x80000001, edx register (AMD) 357 FEATURE_5_ECX, // cpuid eax=5, ecx register 358 FEATURE_6_EAX, // cpuid eax=6, eax registers 359 FEATURE_6_ECX, // cpuid eax=6, ecx registers 360 FEATURE_7_EBX, // cpuid eax=7, ebx registers 361 FEATURE_7_ECX, // cpuid eax=7, ecx registers 362 FEATURE_7_EDX, // cpuid eax=7, edx registers 363 FEATURE_EXT_7_EDX, // cpuid eax=0x80000007, edx register 364 FEATURE_EXT_8_EBX, // cpuid eax=0x80000008, ebx register 365 366 FEATURE_NUM 367 }; 368 369 enum x86_vendors { 370 VENDOR_INTEL = 0, 371 VENDOR_AMD, 372 VENDOR_CYRIX, 373 VENDOR_UMC, 374 VENDOR_NEXGEN, 375 VENDOR_CENTAUR, 376 VENDOR_RISE, 377 VENDOR_TRANSMETA, 378 VENDOR_NSC, 379 380 VENDOR_NUM, 381 VENDOR_UNKNOWN, 382 }; 383 384 385 typedef struct arch_cpu_info { 386 // saved cpu info 387 enum x86_vendors vendor; 388 uint32 feature[FEATURE_NUM]; 389 char model_name[49]; 390 const char* vendor_name; 391 int type; 392 int family; 393 int extended_family; 394 int stepping; 395 int model; 396 int extended_model; 397 398 uint32 logical_apic_id; 399 400 struct X86PagingStructures* active_paging_structures; 401 402 size_t dr6; // temporary storage for debug registers (cf. 403 size_t dr7; // x86_exit_user_debug_at_kernel_entry()) 404 405 // local TSS for this cpu 406 struct tss tss; 407 #ifndef __x86_64__ 408 struct tss double_fault_tss; 409 void* kernel_tls; 410 #endif 411 } arch_cpu_info; 412 413 414 #define nop() __asm__ ("nop"::) 415 416 #define x86_read_cr0() ({ \ 417 size_t _v; \ 418 __asm__("mov %%cr0,%0" : "=r" (_v)); \ 419 _v; \ 420 }) 421 422 #define x86_write_cr0(value) \ 423 __asm__("mov %0,%%cr0" : : "r" (value)) 424 425 #define x86_read_cr2() ({ \ 426 size_t _v; \ 427 __asm__("mov %%cr2,%0" : "=r" (_v)); \ 428 _v; \ 429 }) 430 431 #define x86_read_cr3() ({ \ 432 size_t _v; \ 433 __asm__("mov %%cr3,%0" : "=r" (_v)); \ 434 _v; \ 435 }) 436 437 #define x86_write_cr3(value) \ 438 __asm__("mov %0,%%cr3" : : "r" (value)) 439 440 #define x86_read_cr4() ({ \ 441 size_t _v; \ 442 __asm__("mov %%cr4,%0" : "=r" (_v)); \ 443 _v; \ 444 }) 445 446 #define x86_write_cr4(value) \ 447 __asm__("mov %0,%%cr4" : : "r" (value)) 448 449 #define x86_read_dr3() ({ \ 450 size_t _v; \ 451 __asm__("mov %%dr3,%0" : "=r" (_v)); \ 452 _v; \ 453 }) 454 455 #define x86_write_dr3(value) \ 456 __asm__("mov %0,%%dr3" : : "r" (value)) 457 458 #define invalidate_TLB(va) \ 459 __asm__("invlpg (%0)" : : "r" (va)) 460 461 #define wbinvd() \ 462 __asm__("wbinvd") 463 464 #define out8(value,port) \ 465 __asm__ ("outb %%al,%%dx" : : "a" (value), "d" (port)) 466 467 #define out16(value,port) \ 468 __asm__ ("outw %%ax,%%dx" : : "a" (value), "d" (port)) 469 470 #define out32(value,port) \ 471 __asm__ ("outl %%eax,%%dx" : : "a" (value), "d" (port)) 472 473 #define in8(port) ({ \ 474 uint8 _v; \ 475 __asm__ volatile ("inb %%dx,%%al" : "=a" (_v) : "d" (port)); \ 476 _v; \ 477 }) 478 479 #define in16(port) ({ \ 480 uint16 _v; \ 481 __asm__ volatile ("inw %%dx,%%ax":"=a" (_v) : "d" (port)); \ 482 _v; \ 483 }) 484 485 #define in32(port) ({ \ 486 uint32 _v; \ 487 __asm__ volatile ("inl %%dx,%%eax":"=a" (_v) : "d" (port)); \ 488 _v; \ 489 }) 490 491 #define out8_p(value,port) \ 492 __asm__ ("outb %%al,%%dx\n" \ 493 "\tjmp 1f\n" \ 494 "1:\tjmp 1f\n" \ 495 "1:" : : "a" (value), "d" (port)) 496 497 #define in8_p(port) ({ \ 498 uint8 _v; \ 499 __asm__ volatile ("inb %%dx,%%al\n" \ 500 "\tjmp 1f\n" \ 501 "1:\tjmp 1f\n" \ 502 "1:" : "=a" (_v) : "d" (port)); \ 503 _v; \ 504 }) 505 506 507 extern void (*gCpuIdleFunc)(void); 508 509 510 #ifdef __cplusplus 511 extern "C" { 512 #endif 513 514 struct arch_thread; 515 516 #ifdef __x86_64__ 517 void __x86_setup_system_time(uint64 conversionFactor, 518 uint64 conversionFactorNsecs); 519 #else 520 void __x86_setup_system_time(uint32 conversionFactor, 521 uint32 conversionFactorNsecs, bool conversionFactorNsecsShift); 522 #endif 523 524 void x86_userspace_thread_exit(void); 525 void x86_end_userspace_thread_exit(void); 526 527 addr_t x86_get_stack_frame(); 528 uint32 x86_count_mtrrs(void); 529 void x86_set_mtrr(uint32 index, uint64 base, uint64 length, uint8 type); 530 status_t x86_get_mtrr(uint32 index, uint64* _base, uint64* _length, 531 uint8* _type); 532 void x86_set_mtrrs(uint8 defaultType, const x86_mtrr_info* infos, 533 uint32 count); 534 void x86_init_fpu(); 535 bool x86_check_feature(uint32 feature, enum x86_feature_type type); 536 void* x86_get_double_fault_stack(int32 cpu, size_t* _size); 537 int32 x86_double_fault_get_cpu(void); 538 539 void x86_invalid_exception(iframe* frame); 540 void x86_fatal_exception(iframe* frame); 541 void x86_unexpected_exception(iframe* frame); 542 void x86_hardware_interrupt(iframe* frame); 543 void x86_page_fault_exception(iframe* iframe); 544 545 #ifndef __x86_64__ 546 547 void x86_swap_pgdir(addr_t newPageDir); 548 549 uint64 x86_read_msr(uint32 registerNumber); 550 void x86_write_msr(uint32 registerNumber, uint64 value); 551 552 void x86_context_switch(struct arch_thread* oldState, 553 struct arch_thread* newState); 554 555 void x86_fnsave(void* fpuState); 556 void x86_frstor(const void* fpuState); 557 558 void x86_fxsave(void* fpuState); 559 void x86_fxrstor(const void* fpuState); 560 561 void x86_noop_swap(void* oldFpuState, const void* newFpuState); 562 void x86_fnsave_swap(void* oldFpuState, const void* newFpuState); 563 void x86_fxsave_swap(void* oldFpuState, const void* newFpuState); 564 565 #endif 566 567 568 static inline void 569 arch_cpu_idle(void) 570 { 571 gCpuIdleFunc(); 572 } 573 574 575 static inline void 576 arch_cpu_pause(void) 577 { 578 asm volatile("pause" : : : "memory"); 579 } 580 581 582 #ifdef __cplusplus 583 } // extern "C" { 584 #endif 585 586 #endif // !_ASSEMBLER 587 588 #endif /* _KERNEL_ARCH_x86_CPU_H */ 589