package freenet.support.CPUInformation; /** * Moved out of CPUID.java * * Ref: https://software.intel.com/en-us/articles/intel-architecture-and-processor-identification-with-cpuid-model-and-family-numbers * Ref: http://en.wikipedia.org/wiki/List_of_Intel_CPU_microarchitectures * * @since 0.8.7 */ class IntelInfoImpl extends CPUIDCPUInfo implements IntelCPUInfo { private static boolean isPentiumCompatible; private static boolean isPentiumMMXCompatible; private static boolean isPentium2Compatible; private static boolean isPentium3Compatible; private static boolean isPentium4Compatible; private static boolean isPentiumMCompatible; private static boolean isAtomCompatible; private static boolean isCore2Compatible; private static boolean isCoreiCompatible; private static boolean isSandyCompatible; private static boolean isIvyCompatible; private static boolean isHaswellCompatible; private static boolean isBroadwellCompatible; // If modelString != null, the cpu is considered correctly identified. private static final String smodel = identifyCPU(); public boolean IsPentiumCompatible(){ return isPentiumCompatible; } public boolean IsPentiumMMXCompatible(){ return isPentiumMMXCompatible; } public boolean IsPentium2Compatible(){ return isPentium2Compatible; } public boolean IsPentium3Compatible(){ return isPentium3Compatible; } public boolean IsPentium4Compatible(){ return isPentium4Compatible; } public boolean IsPentiumMCompatible(){ return isPentiumMCompatible; } public boolean IsAtomCompatible(){ return isAtomCompatible; } public boolean IsCore2Compatible(){ return isCore2Compatible; } public boolean IsCoreiCompatible(){ return isCoreiCompatible; } public boolean IsSandyCompatible(){ return isSandyCompatible; } public boolean IsIvyCompatible(){ return isIvyCompatible; } public boolean IsHaswellCompatible(){ return isHaswellCompatible; } public boolean IsBroadwellCompatible(){ return isBroadwellCompatible; } public String getCPUModelString() throws UnknownCPUException { if (smodel != null) return smodel; throw new UnknownCPUException("Unknown Intel CPU; Family="+CPUID.getCPUFamily() + '/' + CPUID.getCPUExtendedFamily()+ ", Model="+CPUID.getCPUModel() + '/' + CPUID.getCPUExtendedModel()); // } private static String identifyCPU() { // http://en.wikipedia.org/wiki/Cpuid // http://web.archive.org/web/20110307080258/http://www.intel.com/Assets/PDF/appnote/241618.pdf // http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-manual-325462.pdf // #include "llvm/Support/Host.h", http://llvm.org/docs/doxygen/html/Host_8cpp_source.html String modelString = null; int family = CPUID.getCPUFamily(); int model = CPUID.getCPUModel(); if (family == 15 || family == 6) { // Intel uses extended model for family = 15 or family = 6, // which is not what wikipedia says model += CPUID.getCPUExtendedModel() << 4; } if (family == 15) { family += CPUID.getCPUExtendedFamily(); } switch (family) { case 4: { switch (model) { case 0: modelString = "486 DX-25/33"; break; case 1: modelString = "486 DX-50"; break; case 2: modelString = "486 SX"; break; case 3: modelString = "486 DX/2"; break; case 4: modelString = "486 SL"; break; case 5: modelString = "486 SX/2"; break; case 7: modelString = "486 DX/2-WB"; break; case 8: modelString = "486 DX/4"; break; case 9: modelString = "486 DX/4-WB"; break; default: modelString = "Intel 486/586 model " + model; break; } } break; // P5 case 5: { isPentiumCompatible = true; switch (model) { case 0: modelString = "Pentium 60/66 A-step"; break; case 1: modelString = "Pentium 60/66"; break; case 2: modelString = "Pentium 75 - 200"; break; case 3: modelString = "OverDrive PODP5V83"; break; case 4: isPentiumMMXCompatible = true; modelString = "Pentium MMX"; break; case 7: modelString = "Mobile Pentium 75 - 200"; break; case 8: isPentiumMMXCompatible = true; modelString = "Mobile Pentium MMX"; break; default: modelString = "Intel Pentium model " + model; break; } } break; // P6 case 6: { isPentiumCompatible = true; isPentiumMMXCompatible = true; int extmodel = model >> 4; if (extmodel >= 1) { isPentium2Compatible = true; isPentium3Compatible = true; isPentium4Compatible = true; isPentiumMCompatible = true; isCore2Compatible = true; if (extmodel >= 2) isCoreiCompatible = true; } switch (model) { case 0: modelString = "Pentium Pro A-step"; break; case 1: modelString = "Pentium Pro"; break; // Spoofed Nehalem by qemu-kvm // Not in any CPUID charts // KVM bug? // # cat /usr/share/kvm/cpus-x86_64.conf | grep 'name = "Nehalem"' -B 1 -A 12 // [cpudef] // name = "Nehalem" // level = "2" // vendor = "GenuineIntel" // family = "6" // model = "2" // stepping = "3" // feature_edx = "sse2 sse fxsr mmx clflush pse36 pat cmov mca pge mtrr sep apic cx8 mce pae msr tsc pse de fpu" // feature_ecx = "popcnt sse4.2 sse4.1 cx16 ssse3 sse3" // extfeature_edx = "i64 syscall xd" // extfeature_ecx = "lahf_lm" // xlevel = "0x8000000A" // model_id = "Intel Core i7 9xx (Nehalem Class Core i7)" //case 2: // ... case 3: isPentium2Compatible = true; modelString = "Pentium II (Klamath)"; break; case 5: isPentium2Compatible = true; modelString = "Pentium II (Deschutes), Celeron (Covington), Mobile Pentium II (Dixon)"; break; case 6: isPentium2Compatible = true; modelString = "Mobile Pentium II, Celeron (Mendocino)"; break; case 7: isPentium2Compatible = true; isPentium3Compatible = true; modelString = "Pentium III (Katmai)"; break; case 8: isPentium2Compatible = true; isPentium3Compatible = true; modelString = "Pentium III (Coppermine), Celeron w/SSE"; break; case 9: isPentium2Compatible = true; isPentium3Compatible = true; isPentiumMCompatible = true; modelString = "Pentium M (Banias)"; break; case 10: isPentium2Compatible = true; isPentium3Compatible = true; modelString = "Pentium III Xeon (Cascades)"; break; case 11: isPentium2Compatible = true; isPentium3Compatible = true; modelString = "Pentium III (130 nm)"; break; case 13: isPentium2Compatible = true; isPentium3Compatible = true; isPentiumMCompatible = true; modelString = "Core (Yonah)"; break; case 14: case 15: isPentium2Compatible = true; isPentium3Compatible = true; isPentiumMCompatible = true; isCore2Compatible = true; modelString = "Penryn"; break; // following are for extended model == 1 // most flags are set above // Celeron 65 nm case 0x16: modelString = "Merom"; break; // Penryn 45 nm case 0x17: modelString = "Penryn"; break; // Nehalem 45 nm case 0x1a: isCoreiCompatible = true; modelString = "Nehalem"; break; // Atom Pineview / Silverthorne 45 nm case 0x1c: isAtomCompatible = true; // Some support SSE3? true for Pineview? TBD... isCore2Compatible = false; isPentium4Compatible = false; modelString = "Atom"; break; // Penryn 45 nm case 0x1d: isCoreiCompatible = true; modelString = "Penryn"; break; // Nehalem 45 nm case 0x1e: isCoreiCompatible = true; modelString = "Nehalem"; break; // following are for extended model == 2 // most flags are set above // isCoreiCompatible = true is the default // Westmere 32 nm case 0x25: modelString = "Westmere"; break; // Atom Lincroft 45 nm case 0x26: isAtomCompatible = true; // Supports SSE 3 isCoreiCompatible = false; modelString = "Atom"; break; // Sandy bridge 32 nm // 1, 2, or 4 cores // ref: https://en.wikipedia.org/wiki/Sandy_Bridge_%28microarchitecture%29 case 0x2a: isSandyCompatible = true; modelString = "Sandy Bridge"; break; // Details unknown, please add a proper model string if 0x2B model is found case 0x2b: modelString = "Core i7/i5 (32nm)"; break; // Westmere case 0x2c: modelString = "Westmere"; break; // Sandy Bridge 32 nm // Sandy Bridge-E up to 8 cores // ref: https://en.wikipedia.org/wiki/Sandy_Bridge_%28microarchitecture%29 case 0x2d: isSandyCompatible = true; modelString = "Sandy Bridge"; break; // Nehalem 45 nm case 0x2e: modelString = "Nehalem"; break; // Westmere 32 nm case 0x2f: modelString = "Westemere"; break; // following are for extended model == 3 // most flags are set above // isCoreiCompatible = true is the default // Atom Cedarview 32 nm case 0x36: isAtomCompatible = true; // Supports SSE 3 isCore2Compatible = false; isCoreiCompatible = false; modelString = "Atom"; break; // Silvermont 22 nm Celeron case 0x37: isAtomCompatible = true; isCore2Compatible = false; isCoreiCompatible = false; modelString = "Atom"; break; // Ivy Bridge 22 nm // ref: https://en.wikipedia.org/wiki/Sandy_Bridge_%28microarchitecture%29 case 0x3a: isSandyCompatible = true; isIvyCompatible = true; modelString = "Ivy Bridge"; break; // case 0x3c: See below // Broadwell 14 nm // See Haswell notes below case 0x3d: { CPUIDCPUInfo c = new CPUIDCPUInfo(); if (c.hasAVX2() && c.hasBMI1() && c.hasBMI2() && c.hasFMA3() && c.hasMOVBE() && c.hasABM()) { isSandyCompatible = true; isIvyCompatible = true; isHaswellCompatible = true; if (c.hasADX()) isBroadwellCompatible = true; modelString = "Broadwell Core i3/i5/i7"; } else { // This processor is "corei" compatible, as we define it, // i.e. SSE4.2 but not necessarily AVX. if (c.hasAVX()) { isSandyCompatible = true; isIvyCompatible = true; modelString = "Broadwell Celeron/Pentium w/ AVX"; } else { modelString = "Broadwell Celeron/Pentium"; } } break; } // Ivy Bridge 22 nm case 0x3e: isSandyCompatible = true; isIvyCompatible = true; modelString = "Ivy Bridge"; break; // case 0x3f: See below // following are for extended model == 4 // most flags are set above // isCoreiCompatible = true is the default // Haswell 22 nm // Pentium and Celeron Haswells do not support new Haswell instructions, // only Corei ones do, but we can't tell that from the model alone. // // We know for sure that GMP coreihwl uses the MULX instruction from BMI2, // unsure about the others, but let's be safe and check all 6 feature bits, as // the Intel app note suggests. // // ref: https://en.wikipedia.org/wiki/Haswell_%28microarchitecture%29 // ref: https://software.intel.com/en-us/articles/how-to-detect-new-instruction-support-in-the-4th-generation-intel-core-processor-family case 0x3c: case 0x3f: case 0x45: case 0x46: { CPUIDCPUInfo c = new CPUIDCPUInfo(); if (c.hasAVX2() && c.hasBMI1() && c.hasBMI2() && c.hasFMA3() && c.hasMOVBE() && c.hasABM()) { isSandyCompatible = true; isIvyCompatible = true; isHaswellCompatible = true; modelString = "Haswell Core i3/i5/i7 model " + model; } else { // This processor is "corei" compatible, as we define it, // i.e. SSE4.2 but not necessarily AVX. if (c.hasAVX()) { isSandyCompatible = true; isIvyCompatible = true; modelString = "Haswell Celeron/Pentium w/ AVX model " + model; } else { modelString = "Haswell Celeron/Pentium model " + model; } } break; } // Quark 32nm case 0x4a: isCore2Compatible = false; isCoreiCompatible = false; modelString = "Quark"; break; // Silvermont 22 nm // Supports SSE 4.2 case 0x4d: isAtomCompatible = true; modelString = "Atom"; break; // following are for extended model == 5 // most flags are set above // isCoreiCompatible = true is the default // Skylake 14 nm // See reference link errata #SKD052 re: BMI // ref: http://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/desktop-6th-gen-core-family-spec-update.pdf // See Haswell notes above case 0x5e: { CPUIDCPUInfo c = new CPUIDCPUInfo(); if (c.hasAVX2() && c.hasBMI1() && c.hasBMI2() && c.hasFMA3() && c.hasMOVBE() && c.hasABM()) { isSandyCompatible = true; isIvyCompatible = true; isHaswellCompatible = true; if (c.hasADX()) isBroadwellCompatible = true; modelString = "Skylake Core i3/i5/i7"; } else { // This processor is "corei" compatible, as we define it, // i.e. SSE4.2 but not necessarily AVX. if (c.hasAVX()) { isSandyCompatible = true; isIvyCompatible = true; modelString = "Skylake Celeron/Pentium w/ AVX"; } else { modelString = "Skylake Celeron/Pentium"; } } break; } // following are for extended model == 8 or 9 // most flags are set above // isCoreiCompatible = true is the default // Kaby Lake // ref: https://github.com/InstLatx64/InstLatx64/commit/9d2ea1a9eb727868dc514900da9e2f175710f9bf // See Haswell notes above case 0x8e: case 0x9e: { CPUIDCPUInfo c = new CPUIDCPUInfo(); if (c.hasAVX2() && c.hasBMI1() && c.hasBMI2() && c.hasFMA3() && c.hasMOVBE() && c.hasABM()) { isSandyCompatible = true; isIvyCompatible = true; isHaswellCompatible = true; if (c.hasADX()) isBroadwellCompatible = true; modelString = "Kaby Lake Core i3/i5/i7"; } else { // This processor is "corei" compatible, as we define it, // i.e. SSE4.2 but not necessarily AVX. if (c.hasAVX()) { isSandyCompatible = true; isIvyCompatible = true; modelString = "Kaby Lake Celeron/Pentium w/ AVX"; } else { modelString = "Kaby Lake Celeron/Pentium"; } } break; } // others default: modelString = "Intel model " + model; break; } // switch model } // case 6 break; case 7: { modelString = "Intel Itanium model " + model; } break; case 15: { isPentiumCompatible = true; isPentiumMMXCompatible = true; isPentium2Compatible = true; isPentium3Compatible = true; isPentium4Compatible = true; switch (model) { case 0: case 1: modelString = "Pentium IV (180 nm)"; break; case 2: modelString = "Pentium IV (130 nm)"; break; case 3: modelString = "Pentium IV (90 nm)"; break; case 4: modelString = "Pentium IV (90 nm)"; break; case 6: modelString = "Pentium IV (65 nm)"; break; default: modelString = "Intel Pentium IV model " + model; break; } } break; case 16: { modelString = "Intel Itanium II model " + model; } } return modelString; } }