| 23 | #ifdef CPUID_CAPABLE |
| 24 | |
| 25 | CPUInfo::CPUInfo() |
| 26 | : mVendorId("") |
| 27 | , mModelName("") |
| 28 | , mNumSMT(0) |
| 29 | , mNumCores(0) |
| 30 | , mNumLogCpus(0) |
| 31 | , mIsHTT(false) { |
| 32 | // Get vendor name EAX=0 |
| 33 | CPUID cpuID1(1, 0); |
| 34 | mIsHTT = cpuID1.EDX() & HTT_POS; |
| 35 | |
| 36 | CPUID cpuID0(0, 0); |
| 37 | uint32_t HFS = cpuID0.EAX(); |
| 38 | mVendorId += string(reinterpret_cast<const char*>(&cpuID0.EBX()), 4); |
| 39 | mVendorId += string(reinterpret_cast<const char*>(&cpuID0.EDX()), 4); |
| 40 | mVendorId += string(reinterpret_cast<const char*>(&cpuID0.ECX()), 4); |
| 41 | |
| 42 | string upVId = mVendorId; |
| 43 | |
| 44 | for_each(upVId.begin(), upVId.end(), |
| 45 | [](char& in) { in = static_cast<char>(::toupper(in)); }); |
| 46 | |
| 47 | // Get num of cores |
| 48 | if (upVId.find("INTEL") != std::string::npos) { |
| 49 | mVendorId = "Intel"; |
| 50 | if (HFS >= 11) { |
| 51 | for (int lvl = 0; lvl < MAX_INTEL_TOP_LVL; ++lvl) { |
| 52 | CPUID cpuID4(0x0B, lvl); |
| 53 | uint32_t currLevel = (LVL_TYPE & cpuID4.ECX()) >> 8U; |
| 54 | switch (currLevel) { |
| 55 | case 0x01: mNumSMT = LVL_CORES & cpuID4.EBX(); break; |
| 56 | case 0x02: mNumLogCpus = LVL_CORES & cpuID4.EBX(); break; |
| 57 | default: break; |
| 58 | } |
| 59 | } |
| 60 | // Fixes Possible divide by zero error |
| 61 | // TODO: Fix properly |
| 62 | mNumCores = mNumLogCpus / (mNumSMT == 0 ? 1 : mNumSMT); |
| 63 | } else { |
| 64 | if (HFS >= 1) { |
| 65 | mNumLogCpus = (cpuID1.EBX() >> 16U) & 0xFFU; |
| 66 | if (HFS >= 4) { |
| 67 | mNumCores = 1 + ((CPUID(4, 0).EAX() >> 26U) & 0x3FU); |
| 68 | } |
| 69 | } |
| 70 | if (mIsHTT) { |
| 71 | if (!(mNumCores > 1)) { |
| 72 | mNumCores = 1; |
| 73 | mNumLogCpus = (mNumLogCpus >= 2 ? mNumLogCpus : 2U); |
| 74 | } |
| 75 | } else { |
| 76 | mNumCores = mNumLogCpus = 1; |
| 77 | } |
| 78 | } |
| 79 | } else if (upVId.find("AMD") != std::string::npos) { |
| 80 | mVendorId = "AMD"; |
| 81 | if (HFS >= 1) { |
| 82 | mNumLogCpus = (cpuID1.EBX() >> 16U) & 0xFFU; |