cpu_type.h: Refinement to CPU strings.
The AMD CPU string logic was updated to add a condition to correctly identify the AMD Athlon 64 X2. Both Intel and AMD logic sections were cleaned to remove hardcoded values that can be provided by the CPU. Intel logic was cleaned up even more based on what the Intel SDM states should be used for CPU identification. First use the CPU String if returned, else use the CPU Brand, else use CPU model/family. https://software.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-1-manual.pdf Tested as much as I could in QEMU since I don't have 32bit hardware. Fixes #4644 and #9262 Change-Id: Iaae0bae81b0691dd29865b33727da8d7b0d5a069 Reviewed-on: https://review.haiku-os.org/c/haiku/+/11061 Haiku-Format: Haiku-format Bot <[email protected]> Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
f50963ad4e
commit
38814666ba
@@ -239,6 +239,40 @@ get_cpuid_model_string(char *name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8
|
||||
get_intel_brand_id(void)
|
||||
{
|
||||
cpuid_info info;
|
||||
if (get_cpuid(&info, 1, 0) != B_OK)
|
||||
return 0;
|
||||
return info.regs.ebx & 0xff;
|
||||
}
|
||||
|
||||
|
||||
//! Manually construct a Brand String based on Brand ID for the few older CPUs
|
||||
//! that do not return a Brand String
|
||||
static const char*
|
||||
get_intel_brand_id_string(uint8 brandId, uint32 signature)
|
||||
{
|
||||
switch (brandId) {
|
||||
case 0x01:
|
||||
return "Celeron";
|
||||
case 0x02:
|
||||
return "Pentium III";
|
||||
case 0x04:
|
||||
return "Pentium III";
|
||||
case 0x03:
|
||||
return signature == 0x06B1 ? "Celeron" : "Pentium III Xeon";
|
||||
case 0x06:
|
||||
return "Mobile Pentium III-M";
|
||||
case 0x07:
|
||||
return "Mobile Celeron";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif /* __i386__ || __x86_64__ */
|
||||
|
||||
|
||||
@@ -283,52 +317,11 @@ get_cpu_model_string(enum cpu_platform platform, enum cpu_vendor cpuVendor,
|
||||
if (model == 0xa)
|
||||
return "Geode LX";
|
||||
} else if (family == 6) {
|
||||
if (model <= 2 || model == 4)
|
||||
return "Athlon";
|
||||
if (model == 3)
|
||||
return "Duron";
|
||||
if (model <= 8 || model == 0xa)
|
||||
return "Athlon XP";
|
||||
} else if (family == 0xf) {
|
||||
if (model <= 4 || model == 7 || model == 8
|
||||
|| (model >= 0xb && model <= 0xf) || model == 0x14
|
||||
|| model == 0x18 || model == 0x1b || model == 0x1f
|
||||
|| model == 0x23 || model == 0x2b
|
||||
|| ((model & 0xf) == 0xf && model >= 0x2f && model <= 0x7e)) {
|
||||
return "Athlon 64";
|
||||
}
|
||||
if (model == 5 || model == 0x15 || model == 0x21 || model == 0x25
|
||||
|| model == 0x27) {
|
||||
return "Opteron";
|
||||
}
|
||||
if (model == 0x1c || model == 0x2c || model == 0x7f)
|
||||
return "Sempron 64";
|
||||
if (model == 0x24 || model == 0x4c || model == 0x68)
|
||||
return "Turion 64";
|
||||
} else if (family == 0x1f) {
|
||||
if (model == 2)
|
||||
return "Phenom";
|
||||
if ((model >= 4 && model <= 6) || model == 0xa) {
|
||||
get_cpuid_model_string(cpuidName);
|
||||
if (strcasestr(cpuidName, "Athlon") != NULL)
|
||||
return "Athlon II";
|
||||
return "Phenom II";
|
||||
}
|
||||
} else if (family == 0x3f)
|
||||
return "A-Series";
|
||||
else if (family == 0x5f) {
|
||||
if (model == 1)
|
||||
return "C-Series";
|
||||
if (model == 2)
|
||||
return "E-Series";
|
||||
} else if (family == 0x6f) {
|
||||
if (model == 1 || model == 2)
|
||||
return "FX-Series";
|
||||
if (model == 0x10 || model == 0x13)
|
||||
return "A-Series";
|
||||
if (model <= 4)
|
||||
return "Athlon";
|
||||
}
|
||||
|
||||
// Fallback to manual parsing of the model string
|
||||
get_cpuid_model_string(cpuidName);
|
||||
return parse_amd(cpuidName);
|
||||
}
|
||||
@@ -342,6 +335,22 @@ get_cpu_model_string(enum cpu_platform platform, enum cpu_vendor cpuVendor,
|
||||
}
|
||||
|
||||
if (cpuVendor == B_CPU_VENDOR_INTEL) {
|
||||
const char* brandIdName;
|
||||
|
||||
// We want to use the CPUID Brand String when the CPU returns one
|
||||
// this should be Pentium 4 and later CPUs
|
||||
get_cpuid_model_string(cpuidName);
|
||||
if (cpuidName[0] != '\0')
|
||||
return parse_intel(cpuidName);
|
||||
|
||||
// Some CPUs do not return a Brand String, but do return a Brand ID
|
||||
// we can use that Brand ID to determine the CPU
|
||||
brandIdName = get_intel_brand_id_string(get_intel_brand_id(), cpuModel);
|
||||
if (brandIdName != NULL)
|
||||
return brandIdName;
|
||||
|
||||
// Even older CPUs do not return a Brand ID or a Brand String, so we
|
||||
// need to look at Model and Family
|
||||
if (family == 5) {
|
||||
if (model == 1 || model == 2)
|
||||
return "Pentium";
|
||||
@@ -358,58 +367,10 @@ get_cpu_model_string(enum cpu_platform platform, enum cpu_vendor cpuVendor,
|
||||
return "Celeron";
|
||||
if (model == 7 || model == 8 || model == 0xa || model == 0xb)
|
||||
return "Pentium III";
|
||||
if (model == 9 || model == 0xd) {
|
||||
get_cpuid_model_string(cpuidName);
|
||||
if (strcasestr(cpuidName, "Celeron") != NULL)
|
||||
return "Pentium M Celeron";
|
||||
if (model == 9 || model == 0xd)
|
||||
return "Pentium M";
|
||||
}
|
||||
if (model == 0x1c || model == 0x26 || model == 0x36)
|
||||
return "Atom";
|
||||
if (model == 0xe) {
|
||||
get_cpuid_model_string(cpuidName);
|
||||
if (strcasestr(cpuidName, "Celeron") != NULL)
|
||||
return "Core Celeron";
|
||||
return "Core";
|
||||
}
|
||||
if (model == 0xf || model == 0x17) {
|
||||
get_cpuid_model_string(cpuidName);
|
||||
if (strcasestr(cpuidName, "Celeron") != NULL)
|
||||
return "Core 2 Celeron";
|
||||
if (strcasestr(cpuidName, "Xeon") != NULL)
|
||||
return "Core 2 Xeon";
|
||||
if (strcasestr(cpuidName, "Pentium") != NULL)
|
||||
return "Pentium";
|
||||
if (strcasestr(cpuidName, "Extreme") != NULL)
|
||||
return "Core 2 Extreme";
|
||||
return "Core 2";
|
||||
}
|
||||
if (model == 0x25) {
|
||||
get_cpuid_model_string(cpuidName);
|
||||
if (strcasestr(cpuidName, "i3") != NULL)
|
||||
return "Core i3";
|
||||
return "Core i5";
|
||||
}
|
||||
if (model == 0x1a || model == 0x1e) {
|
||||
get_cpuid_model_string(cpuidName);
|
||||
if (strcasestr(cpuidName, "Xeon") != NULL)
|
||||
return "Core i7 Xeon";
|
||||
return "Core i7";
|
||||
}
|
||||
} else if (family == 0xf) {
|
||||
if (model <= 4) {
|
||||
get_cpuid_model_string(cpuidName);
|
||||
if (strcasestr(cpuidName, "Celeron") != NULL)
|
||||
return "Pentium 4 Celeron";
|
||||
if (strcasestr(cpuidName, "Xeon") != NULL)
|
||||
return "Pentium 4 Xeon";
|
||||
return "Pentium 4";
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to manual parsing of the model string
|
||||
get_cpuid_model_string(cpuidName);
|
||||
return parse_intel(cpuidName);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cpuVendor == B_CPU_VENDOR_NATIONAL_SEMICONDUCTOR) {
|
||||
|
||||
Reference in New Issue
Block a user