From ec5f3351b69b6427d1e411fcc849e98705a044c3 Mon Sep 17 00:00:00 2001 From: Wunkolo Date: Wed, 23 Feb 2022 19:41:27 -0800 Subject: cpu_detect: Refactor cpu/manufacturer identification Set the zero-enum value to Unknown Move the Manufacterer enum into the CPUCaps structure namespace Add "ParseManufacturer" utility-function Fix cpu/brand string buffer sizes(!) --- src/common/x64/cpu_detect.cpp | 37 ++++++++++++++++++++++--------------- src/common/x64/cpu_detect.h | 25 ++++++++++++++++--------- 2 files changed, 38 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/common/x64/cpu_detect.cpp b/src/common/x64/cpu_detect.cpp index 23adc5c75..65369bfbe 100644 --- a/src/common/x64/cpu_detect.cpp +++ b/src/common/x64/cpu_detect.cpp @@ -3,7 +3,9 @@ #include #include +#include #include +#include #include "common/bit_util.h" #include "common/common_types.h" #include "common/x64/cpu_detect.h" @@ -47,6 +49,17 @@ static inline u64 _xgetbv(u32 index) { namespace Common { +CPUCaps::Manufacturer CPUCaps::ParseManufacturer(std::string_view brand_string) { + if (brand_string == "GenuineIntel") { + return Manufacturer::Intel; + } else if (brand_string == "AuthenticAMD") { + return Manufacturer::AMD; + } else if (brand_string == "HygonGenuine") { + return Manufacturer::Hygon; + } + return Manufacturer::Unknown; +} + // Detects the various CPU features static CPUCaps Detect() { CPUCaps caps = {}; @@ -55,30 +68,24 @@ static CPUCaps Detect() { // yuzu at all anyway std::array cpu_id; - std::memset(caps.brand_string, 0, sizeof(caps.brand_string)); - // Detect CPU's CPUID capabilities and grab CPU string + // Detect CPU's CPUID capabilities and grab manufacturer string __cpuid(cpu_id, 0x00000000); - u32 max_std_fn = cpu_id[0]; // EAX + const u32 max_std_fn = cpu_id[0]; // EAX + std::memset(caps.brand_string, 0, std::size(caps.brand_string)); std::memcpy(&caps.brand_string[0], &cpu_id[1], sizeof(u32)); std::memcpy(&caps.brand_string[4], &cpu_id[3], sizeof(u32)); std::memcpy(&caps.brand_string[8], &cpu_id[2], sizeof(u32)); - if (cpu_id[1] == 0x756e6547 && cpu_id[2] == 0x6c65746e && cpu_id[3] == 0x49656e69) - caps.manufacturer = Manufacturer::Intel; - else if (cpu_id[1] == 0x68747541 && cpu_id[2] == 0x444d4163 && cpu_id[3] == 0x69746e65) - caps.manufacturer = Manufacturer::AMD; - else if (cpu_id[1] == 0x6f677948 && cpu_id[2] == 0x656e6975 && cpu_id[3] == 0x6e65476e) - caps.manufacturer = Manufacturer::Hygon; - else - caps.manufacturer = Manufacturer::Unknown; - __cpuid(cpu_id, 0x80000000); + caps.manufacturer = CPUCaps::ParseManufacturer(caps.brand_string); + + // Set reasonable default cpu string even if brand string not available + std::strncpy(caps.cpu_string, caps.brand_string, std::size(caps.brand_string)); - u32 max_ex_fn = cpu_id[0]; + __cpuid(cpu_id, 0x80000000); - // Set reasonable default brand string even if brand string not available - std::strcpy(caps.cpu_string, caps.brand_string); + const u32 max_ex_fn = cpu_id[0]; // Detect family and other miscellaneous features if (max_std_fn >= 1) { diff --git a/src/common/x64/cpu_detect.h b/src/common/x64/cpu_detect.h index e4f90bee1..3e6d808f3 100644 --- a/src/common/x64/cpu_detect.h +++ b/src/common/x64/cpu_detect.h @@ -3,25 +3,32 @@ #pragma once +#include #include "common/common_types.h" namespace Common { -enum class Manufacturer : u8 { - Intel = 0, - AMD = 1, - Hygon = 2, - Unknown = 3, -}; - /// x86/x64 CPU capabilities that may be detected by this module struct CPUCaps { + + enum class Manufacturer : u8 { + Unknown = 0, + Intel = 1, + AMD = 2, + Hygon = 3, + }; + + static Manufacturer ParseManufacturer(std::string_view brand_string); + Manufacturer manufacturer; - char cpu_string[0x21]; - char brand_string[0x41]; + char brand_string[13]; + + char cpu_string[48]; + u32 base_frequency; u32 max_frequency; u32 bus_frequency; + bool sse : 1; bool sse2 : 1; bool sse3 : 1; -- cgit v1.2.3