2022-01-26 00:01:06 +00:00
|
|
|
/***
|
|
|
|
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
|
|
|
|
File: CpuId.cpp
|
|
|
|
Date: 2022-1-25
|
|
|
|
Author: Reece
|
|
|
|
***/
|
|
|
|
#include <Source/RuntimeInternal.hpp>
|
|
|
|
#include "HWInfo.hpp"
|
|
|
|
#include "CpuId.hpp"
|
|
|
|
|
|
|
|
#if defined(AURORA_COMPILER_CLANG) || defined(AURORA_IS_POSIX_DERIVED)
|
|
|
|
#include <cpuid.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "CPUInfo.hpp"
|
|
|
|
|
|
|
|
namespace Aurora::HWInfo
|
|
|
|
{
|
|
|
|
union CPUIdContext
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
AuUInt32 eax;
|
|
|
|
AuUInt32 ebx;
|
|
|
|
AuUInt32 ecx;
|
|
|
|
AuUInt32 edx;
|
|
|
|
};
|
|
|
|
int regs[4];
|
|
|
|
};
|
|
|
|
|
|
|
|
#if defined(AURORA_ARCH_X64) || defined(AURORA_ARCH_X86)
|
|
|
|
#if defined(AURORA_COMPILER_MSVC)
|
|
|
|
static CPUIdContext cpuid(AuUInt32 a)
|
|
|
|
{
|
|
|
|
CPUIdContext context;
|
|
|
|
__cpuid(context.regs, a);
|
|
|
|
return context;
|
|
|
|
}
|
|
|
|
#elif defined(AURORA_COMPILER_CLANG) || defined(AURORA_COMPILER_GCC)
|
|
|
|
static CPUIdContext cpuid(AuUInt32 a)
|
|
|
|
{
|
|
|
|
CPUIdContext context;
|
|
|
|
__get_cpuid(a, &context.eax, &context.ebx, &context.ecx, &context.edx);
|
|
|
|
return context;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static CPUIdContext cpuid(AuUInt32 a)
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#else
|
|
|
|
static CPUIdContext cpuid(AuUInt32 a)
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::SSE3() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_ECX, 0);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::PCLMULQDQ() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_ECX, 1);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::MONITOR() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_ECX, 3);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::SSSE3() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_ECX, 9);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::FMA() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_ECX, 12);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::CMPXCHG16B() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_ECX, 13);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::SSE41() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_ECX, 19);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::SSE42() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_ECX, 20);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::MOVBE() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_ECX, 22);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::POPCNT() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_ECX, 23);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::AES() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_ECX, 25);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::XSAVE() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_ECX, 26);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::OSXSAVE() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_ECX, 27);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::AVX() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_ECX, 28);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::F16C() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_ECX, 29);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::RDRAND() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_ECX, 30);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::MSR() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_EDX, 5);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::CX8() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_EDX, 8);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::SEP() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_EDX, 11);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::CMOV() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_EDX, 15);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::CLFSH() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_EDX, 19);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::MMX() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_EDX, 23);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::FXSR() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_EDX, 24);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::SSE() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_EDX, 25);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::SSE2() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_1_EDX, 26);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::FSGSBASE() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_7_EBX, 0);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::BMI1() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_7_EBX, 3);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::HLE() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return isIntel && AuTestBit(f_7_EBX, 4);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::AVX2() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_7_EBX, 5);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::BMI2() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_7_EBX, 8);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::ERMS() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_7_EBX, 9);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::INVPCID() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_7_EBX, 10);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::RTM() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return isIntel && AuTestBit(f_7_EBX, 11);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::AVX512F() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_7_EBX, 16);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::RDSEED() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_7_EBX, 18);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::ADX() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_7_EBX, 19);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::AVX512PF() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_7_EBX, 26);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::AVX512ER() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_7_EBX, 27);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::AVX512CD() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_7_EBX, 28);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::SHA() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_7_EBX, 29);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::PREFETCHWT1() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_7_ECX, 0);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::LAHF() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return AuTestBit(f_81_ECX, 0);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::LZCNT() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return isIntel && AuTestBit(f_81_ECX, 5);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::ABM() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return isAMD && AuTestBit(f_81_ECX, 5);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::SSE4a() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return isAMD && AuTestBit(f_81_ECX, 6);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::XOP() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return isAMD && AuTestBit(f_81_ECX, 11);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::TBM() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return isAMD && AuTestBit(f_81_ECX, 21);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::SYSCALL() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return isIntel && AuTestBit(f_81_EDX, 11);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::MMXEXT() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return isAMD && AuTestBit(f_81_EDX, 22);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::RDTSCP() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return isIntel && AuTestBit(f_81_EDX, 27);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::_3DNOWEXT() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return isAMD && AuTestBit(f_81_EDX, 30);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
bool CpuId::_3DNOW() const
|
2022-01-26 00:01:06 +00:00
|
|
|
{
|
|
|
|
return isAMD && AuTestBit(f_81_EDX, 31);
|
|
|
|
}
|
|
|
|
|
2022-01-27 07:45:42 +00:00
|
|
|
AuString CpuId::ToString() const
|
|
|
|
{
|
|
|
|
return fmt::format(
|
2022-01-27 20:25:04 +00:00
|
|
|
"FMA {}\t\tFSGSBASE {}\t\tCLFSH {}\t\t\tERMS {}{}"
|
|
|
|
"CMPXCHG16B {}\t\tAVX512PF {}\t\tMOVBE {}\t\t\tRTM {}{}"
|
|
|
|
"POPCNT {}\t\tAVX512ER {}\t\tMONITOR {}\t\t\tLAHF {}{}"
|
|
|
|
"SSE {}\t\tAVX512CD {}\t\tF16C {}\t\t\tABM {}{}"
|
|
|
|
"SSE2 {}\t\tSYSCALL {}\t\tRDRAND {}\t\t\tXOP {}{}"
|
|
|
|
"SSE3 {}\t\tAES {}\t\tMSR {}\t\t\tTBM {}{}"
|
|
|
|
"SSSE3 {}\t\tRDTSCP {}\t\tCX8 {}\t\t\tMMXEXT {}{}"
|
|
|
|
"SSE41 {}\t\tXSAVE {}\t\tSEP {}\t\t\tRDSEED {}{}"
|
|
|
|
"SSE42 {}\t\tOSXSAVE {}\t\tCMOV {}\t\t\tPREFETCHWT1 {}{}"
|
|
|
|
"SSE4a {}\t\tSHA {}\t\tFXSR {}\t\t\tPCLMULQDQ {}{}"
|
|
|
|
"AVX {}\t\tAVX512F {}\t\tBMI1 {}\t\t\tINVPCID {}{}"
|
|
|
|
"AVX2 {}\t\tLZCNT {}\t\tHLE {}\t\t\t_3DNOWEXT {}{}"
|
|
|
|
"MMX {}\t\tADX {}\t\tBMI2 {}\t\t\t_3DNOW {}",
|
|
|
|
FMA(), FSGSBASE(), CLFSH(), ERMS(), Aurora::Locale::NewLine(),
|
|
|
|
CMPXCHG16B(), AVX512PF(), MOVBE(), RTM(), Aurora::Locale::NewLine(),
|
|
|
|
POPCNT(), AVX512ER(), MONITOR(), LAHF(), Aurora::Locale::NewLine(),
|
|
|
|
SSE(), AVX512CD(), F16C(), ABM(), Aurora::Locale::NewLine(),
|
|
|
|
SSE2(), SYSCALL(), RDRAND(), XOP(), Aurora::Locale::NewLine(),
|
|
|
|
SSE3(), AES(), MSR(), TBM(), Aurora::Locale::NewLine(),
|
|
|
|
SSSE3(), RDTSCP(), CX8(), MMXEXT(), Aurora::Locale::NewLine(),
|
|
|
|
SSE41(), XSAVE(), SEP(), RDSEED(), Aurora::Locale::NewLine(),
|
|
|
|
SSE42(), OSXSAVE(), CMOV(), PREFETCHWT1(), Aurora::Locale::NewLine(),
|
|
|
|
SSE4a(), SHA(), FXSR(), PCLMULQDQ(), Aurora::Locale::NewLine(),
|
|
|
|
AVX(), AVX512F(), BMI1(), INVPCID(), Aurora::Locale::NewLine(),
|
|
|
|
AVX2(), LZCNT(), HLE(), _3DNOWEXT(), Aurora::Locale::NewLine(),
|
|
|
|
MMX(), ADX(), BMI2(), _3DNOW()
|
2022-01-27 07:45:42 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-01-26 00:01:06 +00:00
|
|
|
AUKN_SYM const CpuInfo &GetCPUInfo()
|
|
|
|
{
|
|
|
|
return gCpuInfo;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetCpuId()
|
|
|
|
{
|
|
|
|
// Credit: https://docs.microsoft.com/en-us/cpp/intrinsics/cpuid-cpuidex?view=msvc-160
|
|
|
|
#if defined(AURORA_ARCH_X64) || defined(AURORA_ARCH_X86)
|
|
|
|
AuList<CPUIdContext> data;
|
|
|
|
AuList<CPUIdContext> extdata;
|
|
|
|
|
|
|
|
auto cpuInfo = cpuid(0);
|
|
|
|
auto nIds = cpuInfo.eax;
|
|
|
|
|
|
|
|
for (int i = 0; i <= nIds; ++i)
|
|
|
|
{
|
|
|
|
data.push_back(cpuid(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
char vendor[0x20];
|
|
|
|
AuMemset(vendor, 0, sizeof(vendor));
|
|
|
|
*reinterpret_cast<AuUInt32 *>(vendor) = cpuInfo.ebx;
|
|
|
|
*reinterpret_cast<AuUInt32 *>(vendor + 4) = cpuInfo.edx;
|
|
|
|
*reinterpret_cast<AuUInt32 *>(vendor + 8) = cpuInfo.ecx;
|
|
|
|
|
|
|
|
gCpuInfo.cpuId.vendor = vendor;
|
|
|
|
|
|
|
|
if (gCpuInfo.cpuId.vendor == "GenuineIntel")
|
|
|
|
{
|
|
|
|
gCpuInfo.cpuId.isIntel = true;
|
|
|
|
}
|
|
|
|
else if (gCpuInfo.cpuId.vendor == "AuthenticAMD")
|
|
|
|
{
|
|
|
|
gCpuInfo.cpuId.isAMD = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// load bitset with flags for function 0x00000001
|
|
|
|
if (nIds >= 1)
|
|
|
|
{
|
|
|
|
gCpuInfo.cpuId.f_1_ECX = data[1].ecx;
|
|
|
|
gCpuInfo.cpuId.f_1_EDX = data[1].edx;
|
|
|
|
}
|
|
|
|
|
|
|
|
// load bitset with flags for function 0x00000007
|
|
|
|
if (nIds >= 7)
|
|
|
|
{
|
|
|
|
gCpuInfo.cpuId.f_7_EBX = data[7].ebx;
|
|
|
|
gCpuInfo.cpuId.f_7_ECX = data[7].ecx;
|
|
|
|
}
|
|
|
|
|
|
|
|
// gets the number of the highest valid extended ID.
|
|
|
|
auto cpui = cpuid(0x80000000);
|
|
|
|
auto nExIds = cpui.eax;
|
|
|
|
|
|
|
|
char brand[0x40];
|
|
|
|
AuMemset(brand, 0, sizeof(brand));
|
|
|
|
|
|
|
|
for (int i = 0x80000000; i <= nExIds; ++i)
|
|
|
|
{
|
|
|
|
extdata.push_back(cpuid(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
// load bitset with flags for function 0x80000001
|
|
|
|
if (nExIds >= 0x80000001)
|
|
|
|
{
|
|
|
|
gCpuInfo.cpuId.f_81_ECX = extdata[1].ecx;
|
|
|
|
gCpuInfo.cpuId.f_81_EDX = extdata[1].edx;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Interpret CPU brand string if reported
|
|
|
|
if (nExIds >= 0x80000004)
|
|
|
|
{
|
|
|
|
AuMemcpy(brand, &extdata[2], sizeof(cpui));
|
|
|
|
AuMemcpy(brand + 16, &extdata[3], sizeof(cpui));
|
|
|
|
AuMemcpy(brand + 32, &extdata[4], sizeof(cpui));
|
|
|
|
gCpuInfo.cpuId.brand = brand;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|