diff options
| -rw-r--r-- | src/common/x64/cpu_detect.cpp | 37 | ||||
| -rw-r--r-- | src/common/x64/cpu_detect.h | 25 |
2 files changed, 38 insertions, 24 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) { |
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 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <string_view> | ||
| 6 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 7 | 8 | ||
| 8 | namespace Common { | 9 | namespace Common { |
| 9 | 10 | ||
| 10 | enum class Manufacturer : u8 { | ||
| 11 | Intel = 0, | ||
| 12 | AMD = 1, | ||
| 13 | Hygon = 2, | ||
| 14 | Unknown = 3, | ||
| 15 | }; | ||
| 16 | |||
| 17 | /// x86/x64 CPU capabilities that may be detected by this module | 11 | /// x86/x64 CPU capabilities that may be detected by this module |
| 18 | struct CPUCaps { | 12 | struct CPUCaps { |
| 13 | |||
| 14 | enum class Manufacturer : u8 { | ||
| 15 | Unknown = 0, | ||
| 16 | Intel = 1, | ||
| 17 | AMD = 2, | ||
| 18 | Hygon = 3, | ||
| 19 | }; | ||
| 20 | |||
| 21 | static Manufacturer ParseManufacturer(std::string_view brand_string); | ||
| 22 | |||
| 19 | Manufacturer manufacturer; | 23 | Manufacturer manufacturer; |
| 20 | char cpu_string[0x21]; | 24 | char brand_string[13]; |
| 21 | char brand_string[0x41]; | 25 | |
| 26 | char cpu_string[48]; | ||
| 27 | |||
| 22 | u32 base_frequency; | 28 | u32 base_frequency; |
| 23 | u32 max_frequency; | 29 | u32 max_frequency; |
| 24 | u32 bus_frequency; | 30 | u32 bus_frequency; |
| 31 | |||
| 25 | bool sse : 1; | 32 | bool sse : 1; |
| 26 | bool sse2 : 1; | 33 | bool sse2 : 1; |
| 27 | bool sse3 : 1; | 34 | bool sse3 : 1; |