| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | #pragma once |
| 4 | |
| 5 | #include <mos/types.h> |
| 6 | |
| 7 | // consume counter once |
| 8 | static constexpr auto __CPU_FEATURE_START_LINE_ = __COUNTER__ + __LINE__; |
| 9 | #define CPU_FEATURE_FPU 1, 0, d, 0 // Floating-point unit on-chip |
| 10 | #define CPU_FEATURE_VME 1, 0, d, 1 // Virtual 8086 mode extensions |
| 11 | #define CPU_FEATURE_DE 1, 0, d, 2 // Debugging extensions |
| 12 | #define CPU_FEATURE_PSE 1, 0, d, 3 // Page Size Extension |
| 13 | #define CPU_FEATURE_TSC 1, 0, d, 4 // Time Stamp Counter |
| 14 | #define CPU_FEATURE_MSR 1, 0, d, 5 // Model Specific Registers |
| 15 | #define CPU_FEATURE_PAE 1, 0, d, 6 // Physical Address Extension |
| 16 | #define CPU_FEATURE_MCE 1, 0, d, 7 // Machine Check Exception |
| 17 | #define CPU_FEATURE_CX8 1, 0, d, 8 // CMPXCHG8 instruction |
| 18 | #define CPU_FEATURE_APIC 1, 0, d, 9 // APIC on-chip |
| 19 | #define CPU_FEATURE_SEP 1, 0, d, 11 // SYSENTER and SYSEXIT instructions |
| 20 | #define CPU_FEATURE_MTRR 1, 0, d, 12 // Memory Type Range Registers |
| 21 | #define CPU_FEATURE_PGE 1, 0, d, 13 // Page Global Enable |
| 22 | #define CPU_FEATURE_MCA 1, 0, d, 14 // Machine Check Architecture |
| 23 | #define CPU_FEATURE_CMOV 1, 0, d, 15 // Conditional move and FCMOV instructions |
| 24 | #define CPU_FEATURE_PAT 1, 0, d, 16 // Page Attribute Table |
| 25 | #define CPU_FEATURE_PSE36 1, 0, d, 17 // 36-bit page size extension |
| 26 | #define CPU_FEATURE_PSN 1, 0, d, 18 // Processor Serial Number |
| 27 | #define CPU_FEATURE_CLFSH 1, 0, d, 19 // CLFLUSH instruction |
| 28 | #define CPU_FEATURE_DS 1, 0, d, 21 // Debug store |
| 29 | #define CPU_FEATURE_ACPI 1, 0, d, 22 // Thermal controls MSR for ACPI |
| 30 | #define CPU_FEATURE_MMX 1, 0, d, 23 // MMX technology |
| 31 | #define CPU_FEATURE_FXSR 1, 0, d, 24 // FXSAVE and FXSTOR instructions |
| 32 | #define CPU_FEATURE_SSE 1, 0, d, 25 // Streaming SIMD Extensions |
| 33 | #define CPU_FEATURE_SSE2 1, 0, d, 26 // Streaming SIMD Extensions 2 |
| 34 | #define CPU_FEATURE_SS 1, 0, d, 27 // Self Snoop |
| 35 | #define CPU_FEATURE_HTT 1, 0, d, 28 // Multi-Threading |
| 36 | #define CPU_FEATURE_TM1 1, 0, d, 29 // Thermal Monitor 1 |
| 37 | #define CPU_FEATURE_IA64 1, 0, d, 30 // IA64 processor emulating x86 |
| 38 | #define CPU_FEATURE_PBE 1, 0, d, 31 // Pending Break Enable |
| 39 | #define CPU_FEATURE_SSE3 1, 0, c, 0 // Streaming SIMD Extensions 3 |
| 40 | #define CPU_FEATURE_SSSE3 1, 0, c, 9 // Supplemental Streaming SIMD Extensions 3 |
| 41 | #define CPU_FEATURE_PCID 1, 0, c, 17 // Process-Context Identifiers |
| 42 | #define CPU_FEATURE_DCA 1, 0, c, 18 // Direct Cache Access |
| 43 | #define CPU_FEATURE_SSE4_1 1, 0, c, 19 // Streaming SIMD Extensions 4.1 |
| 44 | #define CPU_FEATURE_SSE4_2 1, 0, c, 20 // Streaming SIMD Extensions 4.2 |
| 45 | #define CPU_FEATURE_X2APIC 1, 0, c, 21 // x2APIC |
| 46 | #define CPU_FEATURE_MOVBE 1, 0, c, 22 // MOVBE instruction |
| 47 | #define CPU_FEATURE_POPCNT 1, 0, c, 23 // POPCNT instruction |
| 48 | #define CPU_FEATURE_TSC_DEADLINE 1, 0, c, 24 // Local APIC supports one-shot operation using a TSC deadline value |
| 49 | #define CPU_FEATURE_AES_NI 1, 0, c, 25 // AESNI instruction extensions |
| 50 | #define CPU_FEATURE_XSAVE 1, 0, c, 26 // XSAVE |
| 51 | #define CPU_FEATURE_OSXSAVE 1, 0, c, 27 // XSAVE and Processor Extended States |
| 52 | #define CPU_FEATURE_AVX 1, 0, c, 28 // Advanced Vector Extensions |
| 53 | #define CPU_FEATURE_F16C 1, 0, c, 29 // 16-bit floating-point conversion instructions |
| 54 | #define CPU_FEATURE_RDRAND 1, 0, c, 30 // RDRAND instruction |
| 55 | #define CPU_FEATURE_HYPERVISOR 1, 0, c, 31 // Running on a hypervisor |
| 56 | #define CPU_FEATURE_AVX2 7, 0, b, 5 // Advanced Vector Extensions 2 |
| 57 | #define CPU_FEATURE_FSGSBASE 7, 0, b, 0 // RDFSBASE, RDGSBASE, WRFSBASE, WRGSBASE |
| 58 | #define CPU_FEATURE_LA57 7, 0, c, 16 // 5-Level Paging |
| 59 | #define CPU_FEATURE_XSAVES 0xd, 1, a, 3 // XSAVES, XSTORS, and IA32_XSS |
| 60 | #define CPU_FEATURE_NX 0x80000001, 0, d, 20 // No-Execute Bit |
| 61 | #define CPU_FEATURE_PDPE1GB 0x80000001, 0, d, 26 // GB pages |
| 62 | static constexpr auto __CPU_FEATURE_END_LINE_ = __LINE__; |
| 63 | |
| 64 | // clang-format off |
| 65 | #define FOR_ALL_CPU_FEATURES(M) \ |
| 66 | M(FPU) M(VME) M(DE) M(PSE) M(TSC) M(MSR) M(PAE) M(MCE) M(CX8) M(APIC) \ |
| 67 | M(SEP) M(MTRR) M(PGE) M(MCA) M(CMOV) M(PAT) M(PSE36) M(PSN) M(CLFSH) M(DS) \ |
| 68 | M(ACPI) M(MMX) M(FXSR) M(SSE) M(SSE2) M(SS) M(HTT) M(TM1) M(IA64) M(PBE) \ |
| 69 | M(SSE3) M(SSSE3) M(PCID) M(DCA) M(SSE4_1) M(SSE4_2) M(X2APIC) M(MOVBE) M(POPCNT) M(TSC_DEADLINE) \ |
| 70 | M(AES_NI) M(XSAVE) M(OSXSAVE) M(AVX) M(F16C) M(RDRAND) M(HYPERVISOR) M(AVX2) M(FSGSBASE) M(LA57) \ |
| 71 | M(XSAVES) M(NX) M(PDPE1GB) |
| 72 | // clang-format on |
| 73 | |
| 74 | #define _do_count(leaf) , __COUNTER__ |
| 75 | MOS_WARNING_PUSH |
| 76 | MOS_WARNING_DISABLE("-Wunused-value" ) |
| 77 | MOS_STATIC_ASSERT((0 FOR_ALL_CPU_FEATURES(_do_count)) == __CPU_FEATURE_END_LINE_ - __CPU_FEATURE_START_LINE_ - 1, "FOR_ALL_CPU_FEATURES is incomplete" ); |
| 78 | MOS_WARNING_POP |
| 79 | #undef _do_count |
| 80 | |
| 81 | #define x86_cpu_get_feature_impl(leaf, subleaf, reg, bit) (per_cpu(platform_info->cpu)->cpuinfo.cpuid[X86_CPUID_LEAF_ENUM(leaf, subleaf, reg, )] & (1 << bit)) |
| 82 | |
| 83 | #define cpu_has_feature(feat) x86_cpu_get_feature_impl(feat) |
| 84 | |
| 85 | #define FOR_ALL_SUPPORTED_CPUID_LEAF(M) \ |
| 86 | M(1, 0, d) \ |
| 87 | M(1, 0, c) \ |
| 88 | M(7, 0, b) \ |
| 89 | M(7, 0, c) \ |
| 90 | M(0xd, 1, a) \ |
| 91 | M(0x80000001, 0, d) |
| 92 | |
| 93 | #define X86_CPUID_LEAF_ENUM(leaf, subleaf, reg, ...) X86_CPUID_##leaf##_##subleaf##_##reg |
| 94 | |
| 95 | enum |
| 96 | { |
| 97 | #define _do_define_enum(leaf, subleaf, reg) X86_CPUID_LEAF_ENUM(leaf, subleaf, reg, _unused_), |
| 98 | FOR_ALL_SUPPORTED_CPUID_LEAF(_do_define_enum) |
| 99 | #undef _do_define_enum |
| 100 | _X86_CPUID_COUNT, |
| 101 | }; |
| 102 | |
| 103 | typedef reg32_t x86_cpuid_array[_X86_CPUID_COUNT]; |
| 104 | |
| 105 | #define XCR0_X87 BIT(0) |
| 106 | #define XCR0_SSE BIT(1) |
| 107 | #define XCR0_AVX BIT(2) |
| 108 | #define XCR0_BNDREGS BIT(3) |
| 109 | #define XCR0_BNDCSR BIT(4) |
| 110 | #define XCR0_OPMASK BIT(5) |
| 111 | #define XCR0_ZMM_Hi256 BIT(6) |
| 112 | #define XCR0_Hi16_ZMM BIT(7) |
| 113 | #define XCR0_PT BIT(8) |
| 114 | #define XCR0_PKRU BIT(9) |
| 115 | #define XCR0_PASID BIT(10) |
| 116 | #define XCR0_CET_U BIT(11) |
| 117 | #define XCR0_CET_S BIT(12) |
| 118 | #define XCR0_HDC BIT(13) |
| 119 | #define XCR0_UINTR BIT(14) |
| 120 | #define XCR0_LBR BIT(15) |
| 121 | #define XCR0_HMP BIT(16) |
| 122 | #define XCR0_AMX_TILECFG BIT(17) |
| 123 | #define XCR0_AMX_TILEDATA BIT(18) |
| 124 | #define XCR0_APX_EXGPRS BIT(19) |
| 125 | |