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