From b9c0af7c3bd903259be9d2e78054abfd3b8435cf Mon Sep 17 00:00:00 2001 From: Lioncache Date: Wed, 25 Mar 2026 13:01:11 -0400 Subject: [PATCH] CPUID: Add basic handling for AVX10 info Just gets the feature bit handling stuff in place for various facilities, so it can be easily expanded in the future. --- FEXCore/Source/Interface/Core/CPUID.cpp | 110 ++++++++++++++++++++++++ FEXCore/Source/Interface/Core/CPUID.h | 84 +++++++++++++++++- 2 files changed, 193 insertions(+), 1 deletion(-) diff --git a/FEXCore/Source/Interface/Core/CPUID.cpp b/FEXCore/Source/Interface/Core/CPUID.cpp index c8283ceb7..6736ddf21 100644 --- a/FEXCore/Source/Interface/Core/CPUID.cpp +++ b/FEXCore/Source/Interface/Core/CPUID.cpp @@ -756,6 +756,95 @@ FEXCore::CPUID::FunctionResults CPUIDEmu::Function_07h(uint32_t Leaf) const { (0 << 29) | // Arch capabilities - Speculative side channel mitigations (0 << 30) | // Arch capabilities - MSR module specific (0 << 31); // SSBD - Speculative Store Bypass Disable + } else if (Leaf == 1) { + Res.eax = (0U << 0) | // SHA512 + (0U << 1) | // SM3 + (0U << 2) | // SM4 + (0U << 3) | // RAO_INT + (0U << 4) | // AVX_VNNI + (0U << 5) | // AVX512_BF16 + (0U << 6) | // LASS (Linear Address Space Separation) + (0U << 7) | // CMPCCXADD + (0U << 8) | // ARCH_PERFMON_EXT + (0U << 9) | // Reserved + (0U << 10) | // FAST_REP_MOVSB + (0U << 11) | // FAST_REP_STOSB + (0U << 12) | // FAST_REP_CMPSB_SCASB + (0U << 13) | // Reserved + (0U << 14) | // Reserved + (0U << 15) | // Reserved + (0U << 16) | // Reserved + (0U << 17) | // FRED (Flexible Return and Event Delivery) + (0U << 18) | // LKGS (Load into Kernel GS Base) + (0U << 19) | // WRMSRNS + (0U << 20) | // NMI_SRC + (0U << 21) | // AMX_FP16 + (0U << 22) | // HRESET + (0U << 23) | // AVX_IFMA + (0U << 24) | // Reserved + (0U << 25) | // Reserved + (0U << 26) | // LAM (Linear Address Masking) + (0U << 27) | // MSRLIST + (0U << 28) | // Reserved + (0U << 29) | // Reserved + (0U << 30) | // INVD_DISABLE_POST_BIOS_DONE + (0U << 31); // MOVRS + + // Bits 4-31 currently reserved. + Res.ebx = (0U << 0) | // PPIN + (0U << 1) | // PBNDKB + (0U << 2) | // Reserved + (0U << 3); // CPUIDMAXVAL_LIM_RMV + + // Bits 6-31 also reserved. + Res.ecx = (0U << 0) | // RDT_M_ASYM + (0U << 1) | // RDT_A_ASYM + (0U << 2) | // Reserved + (0U << 3) | // Reserved + (0U << 4) | // Reserved + (0U << 5); // MSR_IMM + + // Bits 25-31 also reserved. + Res.edx = (0U << 0) | // Reserved + (0U << 1) | // Reserved + (0U << 2) | // Reserved + (0U << 3) | // Reserved + (0U << 4) | // AVX_VNNI_INT8 + (0U << 5) | // AVX_NE_CONVERT + (0U << 6) | // Reserved + (0U << 7) | // Reserved + (0U << 8) | // AMX_COMPLEX + (0U << 9) | // Reserved + (0U << 10) | // AVX_VNNI_INT16 + (0U << 11) | // Reserved + (0U << 12) | // Reserved + (0U << 13) | // UTMR (User-timer events) + (0U << 14) | // PREFETCHI + (0U << 15) | // USER_MSR + (0U << 16) | // Reserved + (0U << 17) | // UIRET_UIF + (0U << 18) | // CET_SSS + (0U << 19) | // AVX10 + (0U << 20) | // Reserved + (0U << 21) | // APX_F + (0U << 22) | // SEC-TEE_ATTESTATION + (0U << 23) | // MWAIT + (0U << 24); // SLSM (Static LSM) + } else if (Leaf == 2) { + // All bits are reserved except for EDX + Res.eax = 0; + Res.ebx = 0; + Res.ecx = 0; + + // Bits 8-31 are reserved. + Res.edx = (0U << 0) | // PSFD + (0U << 1) | // IPRED_CTRL + (0U << 2) | // RRSBA_CTRL + (0U << 3) | // DDPD_U + (0U << 4) | // BHI_CTRL + (0U << 5) | // MCDT_NO + (0U << 6) | // UC_LOCK_DISABLE + (0U << 7); // MONITOR_MITG_NO } return Res; @@ -834,6 +923,27 @@ FEXCore::CPUID::FunctionResults CPUIDEmu::Function_1Ah(uint32_t Leaf) const { return Res; } +FEXCore::CPUID::FunctionResults CPUIDEmu::Function_24h(uint32_t Leaf) const { + FEXCore::CPUID::FunctionResults Res {}; + + if (Leaf == 0) { + // EAX indicates the maximum number of subleaves. + Res.eax = 0; + + // Bits 19-31 reserved + // NOTE: We return all zero here until we have a CPU with AVX10 + // even if some of the fields otherwise have fixed values. + Res.ebx = (0U << 0) | // (bits 0-7 specify the vector ISA version) + (0U << 16); // Defined as always 0b111 + + // All bits reserved + Res.ecx = 0; + Res.edx = 0; + } + + return Res; +} + // Hypervisor CPUID information leaf FEXCore::CPUID::FunctionResults CPUIDEmu::Function_4000_0000h(uint32_t Leaf) const { FEXCore::CPUID::FunctionResults Res {}; diff --git a/FEXCore/Source/Interface/Core/CPUID.h b/FEXCore/Source/Interface/Core/CPUID.h index 5d3ab1708..f7f32571b 100644 --- a/FEXCore/Source/Interface/Core/CPUID.h +++ b/FEXCore/Source/Interface/Core/CPUID.h @@ -176,6 +176,7 @@ private: FEXCore::CPUID::FunctionResults Function_0Dh(uint32_t Leaf) const; FEXCore::CPUID::FunctionResults Function_15h(uint32_t Leaf) const; FEXCore::CPUID::FunctionResults Function_1Ah(uint32_t Leaf) const; + FEXCore::CPUID::FunctionResults Function_24h(uint32_t Leaf) const; FEXCore::CPUID::FunctionResults Function_4000_0000h(uint32_t Leaf) const; FEXCore::CPUID::FunctionResults Function_4000_0001h(uint32_t Leaf) const; FEXCore::CPUID::FunctionResults Function_8000_0000h(uint32_t Leaf) const; @@ -200,7 +201,7 @@ private: void SetupHostHybridFlag(); void SetupFeatures(); - static constexpr size_t PRIMARY_FUNCTION_COUNT = 27; + static constexpr size_t PRIMARY_FUNCTION_COUNT = 37; static constexpr size_t HYPERVISOR_FUNCTION_COUNT = 2; static constexpr size_t EXTENDED_FUNCTION_COUNT = 32; static constexpr std::array Primary = { @@ -268,7 +269,48 @@ private: #ifndef CPUID_AMD // 0x1A: Hybrid Information Sub-leaf &CPUIDEmu::Function_1Ah, + // 0x1B: PCONFIG info + &CPUIDEmu::Function_Reserved, + // 0x1C: Last Branch Records (LBR) info + &CPUIDEmu::Function_Reserved, + // 0x1D: Tile info + &CPUIDEmu::Function_Reserved, + // 0x1E: TMUL info + &CPUIDEmu::Function_Reserved, + // 0x1F: V2 Extended topology + &CPUIDEmu::Function_Reserved, + // 0x20: Processor History Reset info + &CPUIDEmu::Function_Reserved, + // 0x21: Unimplemented + &CPUIDEmu::Function_Reserved, + // 0x22: Reserved + &CPUIDEmu::Function_Reserved, + // 0x23: Architectural Performance Monitoring Extended + &CPUIDEmu::Function_Reserved, + // 0x24: Converged Vector ISA + &CPUIDEmu::Function_24h, #else + // 0x1A: Reserved + &CPUIDEmu::Function_Reserved, + // 0x1B: Reserved + &CPUIDEmu::Function_Reserved, + // 0x1C: Reserved + &CPUIDEmu::Function_Reserved, + // 0x1D: Reserved + &CPUIDEmu::Function_Reserved, + // 0x1E: Reserved + &CPUIDEmu::Function_Reserved, + // 0x1F: Reserved + &CPUIDEmu::Function_Reserved, + // 0x20: Reserved + &CPUIDEmu::Function_Reserved, + // 0x21: Reserved + &CPUIDEmu::Function_Reserved, + // 0x22: Reserved + &CPUIDEmu::Function_Reserved, + // 0x23: Reserved + &CPUIDEmu::Function_Reserved, + // 0x24: Reserved &CPUIDEmu::Function_Reserved, #endif }; @@ -340,9 +382,49 @@ private: #ifndef CPUID_AMD // 0x1A: Hybrid Information Sub-leaf {SupportsConstant::NONCONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, + // 0x1B: PCONFIG info + {SupportsConstant::CONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, + // 0x1C: Last Branch Records (LBR) info + {SupportsConstant::CONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, + // 0x1D: Tile info + {SupportsConstant::CONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, + // 0x1E: TMUL info + {SupportsConstant::CONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, + // 0x1F: V2 Extended topology + {SupportsConstant::CONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, + // 0x20: Processor History Reset info + {SupportsConstant::CONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, + // 0x21: Unimplemented/Reserved + {SupportsConstant::CONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, + // 0x22: Reserved + {SupportsConstant::CONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, + // 0x23: Architectural Performance Monitoring Extended + {SupportsConstant::CONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, + // 0x24: Converged Vector ISA + {SupportsConstant::CONSTANT, NeedsLeafConstant::NEEDSLEAFCONSTANT}, #else // 0x1A: Reserved {SupportsConstant::CONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, + // 0x1B: Reserved + {SupportsConstant::CONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, + // 0x1C: Reserved + {SupportsConstant::CONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, + // 0x1D: Reserved + {SupportsConstant::CONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, + // 0x1E: Reserved + {SupportsConstant::CONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, + // 0x1F: Reserved + {SupportsConstant::CONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, + // 0x20: Reserved + {SupportsConstant::CONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, + // 0x21: Reserved + {SupportsConstant::CONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, + // 0x22: Reserved + {SupportsConstant::CONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, + // 0x23: Reserved + {SupportsConstant::CONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, + // 0x24: Reserved + {SupportsConstant::CONSTANT, NeedsLeafConstant::NOLEAFCONSTANT}, #endif }};