diff options
| author | 2022-02-23 19:41:27 -0800 | |
|---|---|---|
| committer | 2022-03-09 13:57:47 -0800 | |
| commit | ec5f3351b69b6427d1e411fcc849e98705a044c3 (patch) | |
| tree | c137667f61e31588ef1b07298a7e2c8a0d1a49be /src/common/x64/cpu_detect.cpp | |
| parent | cpu_detect: Update array-types to `span` and `array` (diff) | |
| download | yuzu-ec5f3351b69b6427d1e411fcc849e98705a044c3.tar.gz yuzu-ec5f3351b69b6427d1e411fcc849e98705a044c3.tar.xz yuzu-ec5f3351b69b6427d1e411fcc849e98705a044c3.zip | |
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(!)
Diffstat (limited to 'src/common/x64/cpu_detect.cpp')
| -rw-r--r-- | src/common/x64/cpu_detect.cpp | 37 |
1 files changed, 22 insertions, 15 deletions
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 @@ | |||
| 3 | 3 | ||
| 4 | #include <array> | 4 | #include <array> |
| 5 | #include <cstring> | 5 | #include <cstring> |
| 6 | #include <iterator> | ||
| 6 | #include <span> | 7 | #include <span> |
| 8 | #include <string_view> | ||
| 7 | #include "common/bit_util.h" | 9 | #include "common/bit_util.h" |
| 8 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 9 | #include "common/x64/cpu_detect.h" | 11 | #include "common/x64/cpu_detect.h" |
| @@ -47,6 +49,17 @@ static inline u64 _xgetbv(u32 index) { | |||
| 47 | 49 | ||
| 48 | namespace Common { | 50 | namespace Common { |
| 49 | 51 | ||
| 52 | CPUCaps::Manufacturer CPUCaps::ParseManufacturer(std::string_view brand_string) { | ||
| 53 | if (brand_string == "GenuineIntel") { | ||
| 54 | return Manufacturer::Intel; | ||
| 55 | } else if (brand_string == "AuthenticAMD") { | ||
| 56 | return Manufacturer::AMD; | ||
| 57 | } else if (brand_string == "HygonGenuine") { | ||
| 58 | return Manufacturer::Hygon; | ||
| 59 | } | ||
| 60 | return Manufacturer::Unknown; | ||
| 61 | } | ||
| 62 | |||
| 50 | // Detects the various CPU features | 63 | // Detects the various CPU features |
| 51 | static CPUCaps Detect() { | 64 | static CPUCaps Detect() { |
| 52 | CPUCaps caps = {}; | 65 | CPUCaps caps = {}; |
| @@ -55,30 +68,24 @@ static CPUCaps Detect() { | |||
| 55 | // yuzu at all anyway | 68 | // yuzu at all anyway |
| 56 | 69 | ||
| 57 | std::array<u32, 4> cpu_id; | 70 | std::array<u32, 4> cpu_id; |
| 58 | std::memset(caps.brand_string, 0, sizeof(caps.brand_string)); | ||
| 59 | 71 | ||
| 60 | // Detect CPU's CPUID capabilities and grab CPU string | 72 | // Detect CPU's CPUID capabilities and grab manufacturer string |
| 61 | __cpuid(cpu_id, 0x00000000); | 73 | __cpuid(cpu_id, 0x00000000); |
| 62 | u32 max_std_fn = cpu_id[0]; // EAX | 74 | const u32 max_std_fn = cpu_id[0]; // EAX |
| 63 | 75 | ||
| 76 | std::memset(caps.brand_string, 0, std::size(caps.brand_string)); | ||
| 64 | std::memcpy(&caps.brand_string[0], &cpu_id[1], sizeof(u32)); | 77 | std::memcpy(&caps.brand_string[0], &cpu_id[1], sizeof(u32)); |
| 65 | std::memcpy(&caps.brand_string[4], &cpu_id[3], sizeof(u32)); | 78 | std::memcpy(&caps.brand_string[4], &cpu_id[3], sizeof(u32)); |
| 66 | std::memcpy(&caps.brand_string[8], &cpu_id[2], sizeof(u32)); | 79 | std::memcpy(&caps.brand_string[8], &cpu_id[2], sizeof(u32)); |
| 67 | if (cpu_id[1] == 0x756e6547 && cpu_id[2] == 0x6c65746e && cpu_id[3] == 0x49656e69) | ||
| 68 | caps.manufacturer = Manufacturer::Intel; | ||
| 69 | else if (cpu_id[1] == 0x68747541 && cpu_id[2] == 0x444d4163 && cpu_id[3] == 0x69746e65) | ||
| 70 | caps.manufacturer = Manufacturer::AMD; | ||
| 71 | else if (cpu_id[1] == 0x6f677948 && cpu_id[2] == 0x656e6975 && cpu_id[3] == 0x6e65476e) | ||
| 72 | caps.manufacturer = Manufacturer::Hygon; | ||
| 73 | else | ||
| 74 | caps.manufacturer = Manufacturer::Unknown; | ||
| 75 | 80 | ||
| 76 | __cpuid(cpu_id, 0x80000000); | 81 | caps.manufacturer = CPUCaps::ParseManufacturer(caps.brand_string); |
| 82 | |||
| 83 | // Set reasonable default cpu string even if brand string not available | ||
| 84 | std::strncpy(caps.cpu_string, caps.brand_string, std::size(caps.brand_string)); | ||
| 77 | 85 | ||
| 78 | u32 max_ex_fn = cpu_id[0]; | 86 | __cpuid(cpu_id, 0x80000000); |
| 79 | 87 | ||
| 80 | // Set reasonable default brand string even if brand string not available | 88 | const u32 max_ex_fn = cpu_id[0]; |
| 81 | std::strcpy(caps.cpu_string, caps.brand_string); | ||
| 82 | 89 | ||
| 83 | // Detect family and other miscellaneous features | 90 | // Detect family and other miscellaneous features |
| 84 | if (max_std_fn >= 1) { | 91 | if (max_std_fn >= 1) { |