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(!)
This commit is contained in:
parent
86e9e60f07
commit
ec5f3351b6
|
@ -3,7 +3,9 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <iterator>
|
||||||
#include <span>
|
#include <span>
|
||||||
|
#include <string_view>
|
||||||
#include "common/bit_util.h"
|
#include "common/bit_util.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/x64/cpu_detect.h"
|
#include "common/x64/cpu_detect.h"
|
||||||
|
@ -47,6 +49,17 @@ static inline u64 _xgetbv(u32 index) {
|
||||||
|
|
||||||
namespace Common {
|
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
|
// Detects the various CPU features
|
||||||
static CPUCaps Detect() {
|
static CPUCaps Detect() {
|
||||||
CPUCaps caps = {};
|
CPUCaps caps = {};
|
||||||
|
@ -55,30 +68,24 @@ static CPUCaps Detect() {
|
||||||
// yuzu at all anyway
|
// yuzu at all anyway
|
||||||
|
|
||||||
std::array<u32, 4> cpu_id;
|
std::array<u32, 4> 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);
|
__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[0], &cpu_id[1], sizeof(u32));
|
||||||
std::memcpy(&caps.brand_string[4], &cpu_id[3], sizeof(u32));
|
std::memcpy(&caps.brand_string[4], &cpu_id[3], sizeof(u32));
|
||||||
std::memcpy(&caps.brand_string[8], &cpu_id[2], 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;
|
caps.manufacturer = CPUCaps::ParseManufacturer(caps.brand_string);
|
||||||
else if (cpu_id[1] == 0x68747541 && cpu_id[2] == 0x444d4163 && cpu_id[3] == 0x69746e65)
|
|
||||||
caps.manufacturer = Manufacturer::AMD;
|
// Set reasonable default cpu string even if brand string not available
|
||||||
else if (cpu_id[1] == 0x6f677948 && cpu_id[2] == 0x656e6975 && cpu_id[3] == 0x6e65476e)
|
std::strncpy(caps.cpu_string, caps.brand_string, std::size(caps.brand_string));
|
||||||
caps.manufacturer = Manufacturer::Hygon;
|
|
||||||
else
|
|
||||||
caps.manufacturer = Manufacturer::Unknown;
|
|
||||||
|
|
||||||
__cpuid(cpu_id, 0x80000000);
|
__cpuid(cpu_id, 0x80000000);
|
||||||
|
|
||||||
u32 max_ex_fn = cpu_id[0];
|
const u32 max_ex_fn = cpu_id[0];
|
||||||
|
|
||||||
// Set reasonable default brand string even if brand string not available
|
|
||||||
std::strcpy(caps.cpu_string, caps.brand_string);
|
|
||||||
|
|
||||||
// Detect family and other miscellaneous features
|
// Detect family and other miscellaneous features
|
||||||
if (max_std_fn >= 1) {
|
if (max_std_fn >= 1) {
|
||||||
|
|
|
@ -3,25 +3,32 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace Common {
|
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
|
/// x86/x64 CPU capabilities that may be detected by this module
|
||||||
struct CPUCaps {
|
struct CPUCaps {
|
||||||
|
|
||||||
|
enum class Manufacturer : u8 {
|
||||||
|
Unknown = 0,
|
||||||
|
Intel = 1,
|
||||||
|
AMD = 2,
|
||||||
|
Hygon = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
static Manufacturer ParseManufacturer(std::string_view brand_string);
|
||||||
|
|
||||||
Manufacturer manufacturer;
|
Manufacturer manufacturer;
|
||||||
char cpu_string[0x21];
|
char brand_string[13];
|
||||||
char brand_string[0x41];
|
|
||||||
|
char cpu_string[48];
|
||||||
|
|
||||||
u32 base_frequency;
|
u32 base_frequency;
|
||||||
u32 max_frequency;
|
u32 max_frequency;
|
||||||
u32 bus_frequency;
|
u32 bus_frequency;
|
||||||
|
|
||||||
bool sse : 1;
|
bool sse : 1;
|
||||||
bool sse2 : 1;
|
bool sse2 : 1;
|
||||||
bool sse3 : 1;
|
bool sse3 : 1;
|
||||||
|
|
Reference in New Issue