diff --git a/ChangeLog b/ChangeLog index c9b537ff..2210ace3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,7 @@ dd.mm.yy hh:mm - smooth alpha 0.9.11 - fixed crash querying CPU info on systems without affinity setting support in libcpuid - upgraded fribidi to version 1.0.13 +- upgraded libcpuid to version 0.6.4 - upgraded libxml2 to version 2.11.5 - upgraded libcurl to version 8.4.0 - upgraded libpng to version 1.6.40 diff --git a/libraries/libcpuid/Makefile b/libraries/libcpuid/Makefile index 70793e1f..eab96ba9 100755 --- a/libraries/libcpuid/Makefile +++ b/libraries/libcpuid/Makefile @@ -14,7 +14,7 @@ ifeq ($(BUILD_LINUX),True) endif # Enter object files here: -OBJECTS = asm-bits.o cpuid_main.o libcpuid_util.o rdtsc.o recog_amd.o recog_intel.o +OBJECTS = asm-bits.o cpuid_main.o libcpuid_util.o rdtsc.o recog_amd.o recog_centaur.o recog_intel.o ## Do not change anything below this line. ## diff --git a/libraries/libcpuid/centaur_code_t.h b/libraries/libcpuid/centaur_code_t.h new file mode 100644 index 00000000..5e91aadf --- /dev/null +++ b/libraries/libcpuid/centaur_code_t.h @@ -0,0 +1,32 @@ +/* + * Copyright 2023 Veselin Georgiev, + * anrieffNOSPAM @ mgail_DOT.com (convert to gmail) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file contains a list of internal codes we use in detection. It is + * of no external use and isn't a complete list of Centaur products. + */ + CODE2(VIA, 3000), + CODE(ZHAOXIN), diff --git a/libraries/libcpuid/cpuid_main.c b/libraries/libcpuid/cpuid_main.c index 3893f2c1..43b5311b 100755 --- a/libraries/libcpuid/cpuid_main.c +++ b/libraries/libcpuid/cpuid_main.c @@ -25,8 +25,9 @@ */ #include "libcpuid.h" #include "libcpuid_internal.h" -#include "recog_intel.h" #include "recog_amd.h" +#include "recog_centaur.h" +#include "recog_intel.h" #include "asm-bits.h" #include "libcpuid_util.h" #ifdef HAVE_CONFIG_H @@ -49,13 +50,13 @@ INTERNAL_SCOPE int _libcpuid_errno = ERR_OK; -int set_error(cpu_error_t err) +int cpuid_set_error(cpu_error_t err) { _libcpuid_errno = (int) err; return (int) err; } -int get_error() +int cpuid_get_error() { return _libcpuid_errno; } @@ -126,7 +127,7 @@ static void cpuid_grow_raw_data_array(struct cpu_raw_data_array_t* raw_array, lo debugf(3, "Growing cpu_raw_data_array_t from %u to %u items\n", raw_array->num_raw, n); tmp = realloc(raw_array->raw, sizeof(struct cpu_raw_data_t) * n); if (tmp == NULL) { /* Memory allocation failure */ - set_error(ERR_NO_MEM); + cpuid_set_error(ERR_NO_MEM); return; } @@ -145,7 +146,7 @@ static void cpuid_grow_system_id(struct system_id_t* system, uint8_t n) debugf(3, "Growing system_id_t from %u to %u items\n", system->num_cpu_types, n); tmp = realloc(system->cpu_types, sizeof(struct cpu_id_t) * n); if (tmp == NULL) { /* Memory allocation failure */ - set_error(ERR_NO_MEM); + cpuid_set_error(ERR_NO_MEM); return; } @@ -177,14 +178,14 @@ static int get_total_cpus(void) INTERNAL_SCOPE thread_affinity_policy_data_t saved_affinity; -static bool save_cpu_affinity() +static bool save_cpu_affinity(void) { mach_msg_type_number_t count = THREAD_AFFINITY_POLICY_COUNT; boolean_t get_default = false; return thread_policy_get(mach_thread_self(), THREAD_AFFINITY_POLICY, (thread_policy_t) &saved_affinity, &count, &get_default) == KERN_SUCCESS; } -static bool restore_cpu_affinity() +static bool restore_cpu_affinity(void) { return thread_policy_set(mach_thread_self(), THREAD_AFFINITY_POLICY, (thread_policy_t) &saved_affinity, THREAD_AFFINITY_POLICY_COUNT) == KERN_SUCCESS; } @@ -219,7 +220,7 @@ INTERNAL_SCOPE GROUP_AFFINITY savedGroupAffinity; INTERNAL_SCOPE DWORD_PTR savedAffinityMask = 0; #endif -static bool save_cpu_affinity() +static bool save_cpu_affinity(void) { #if (_WIN32_WINNT >= 0x0601) HANDLE thread = GetCurrentThread(); @@ -241,7 +242,7 @@ static bool save_cpu_affinity() #endif } -static bool restore_cpu_affinity() +static bool restore_cpu_affinity(void) { #if (_WIN32_WINNT >= 0x0601) if (!savedGroupAffinity.Mask) @@ -327,12 +328,12 @@ static int get_total_cpus(void) INTERNAL_SCOPE cpu_set_t saved_affinity; -static bool save_cpu_affinity() +static bool save_cpu_affinity(void) { return sched_getaffinity(0, sizeof(saved_affinity), &saved_affinity) == 0; } -static bool restore_cpu_affinity() +static bool restore_cpu_affinity(void) { return sched_setaffinity(0, sizeof(saved_affinity), &saved_affinity) == 0; } @@ -355,12 +356,12 @@ static bool set_cpu_affinity(logical_cpu_t logical_cpu) INTERNAL_SCOPE processorid_t saved_binding = PBIND_NONE; -static bool save_cpu_affinity() +static bool save_cpu_affinity(void) { return processor_bind(P_LWPID, P_MYID, PBIND_QUERY, &saved_binding) == 0; } -static bool restore_cpu_affinity() +static bool restore_cpu_affinity(void) { return processor_bind(P_LWPID, P_MYID, saved_binding, NULL) == 0; } @@ -398,12 +399,12 @@ static int get_total_cpus(void) INTERNAL_SCOPE cpuset_t saved_affinity; -static bool save_cpu_affinity() +static bool save_cpu_affinity(void) { return cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(saved_affinity), &saved_affinity) == 0; } -static bool restore_cpu_affinity() +static bool restore_cpu_affinity(void) { return cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(saved_affinity), &saved_affinity) == 0; } @@ -425,12 +426,12 @@ static bool set_cpu_affinity(logical_cpu_t logical_cpu) INTERNAL_SCOPE cpuset_t saved_affinity; -static bool save_cpu_affinity() +static bool save_cpu_affinity(void) { return pthread_getaffinity_np(pthread_self(), sizeof(saved_affinity), &saved_affinity) == 0; } -static bool restore_cpu_affinity() +static bool restore_cpu_affinity(void) { return pthread_setaffinity_np(pthread_self(), sizeof(saved_affinity), &saved_affinity) == 0; } @@ -452,7 +453,7 @@ static bool set_cpu_affinity(logical_cpu_t logical_cpu) INTERNAL_SCOPE cpuset_t *saved_affinity = NULL; -static bool save_cpu_affinity() +static bool save_cpu_affinity(void) { if (!saved_affinity) saved_affinity = cpuset_create(); @@ -460,7 +461,7 @@ static bool save_cpu_affinity() return pthread_getaffinity_np(pthread_self(), cpuset_size(saved_affinity), saved_affinity) == 0; } -static bool restore_cpu_affinity() +static bool restore_cpu_affinity(void) { if (!saved_affinity) return false; @@ -499,12 +500,12 @@ static int get_total_cpus(void) #endif /* GET_TOTAL_CPUS_DEFINED */ #ifndef PRESERVE_CPU_AFFINITY -static bool save_cpu_affinity() +static bool save_cpu_affinity(void) { return false; } -static bool restore_cpu_affinity() +static bool restore_cpu_affinity(void) { return false; } @@ -534,7 +535,7 @@ static int cpuid_serialize_raw_data_internal(struct cpu_raw_data_t* single_raw, /* Open file descriptor */ f = !strcmp(filename, "") ? stdout : fopen(filename, "wt"); if (!f) - return set_error(ERR_OPEN); + return cpuid_set_error(ERR_OPEN); debugf(1, "Writing raw CPUID dump to '%s'\n", f == stdout ? "stdout" : filename); /* Write raw data to output file */ @@ -580,7 +581,7 @@ static int cpuid_serialize_raw_data_internal(struct cpu_raw_data_t* single_raw, /* Close file descriptor */ if (strcmp(filename, "")) fclose(f); - return set_error(ERR_OK); + return cpuid_set_error(ERR_OK); } #define RAW_ASSIGN_LINE(__line) __line[EAX] = eax ; __line[EBX] = ebx ; __line[ECX] = ecx ; __line[EDX] = edx @@ -604,7 +605,7 @@ static int cpuid_deserialize_raw_data_internal(struct cpu_raw_data_t* single_raw /* Open file descriptor */ f = !strcmp(filename, "") ? stdin : fopen(filename, "rt"); if (!f) - return set_error(ERR_OPEN); + return cpuid_set_error(ERR_OPEN); debugf(1, "Opening raw dump from '%s'\n", f == stdin ? "stdin" : filename); if (use_raw_array) @@ -637,7 +638,10 @@ static int cpuid_deserialize_raw_data_internal(struct cpu_raw_data_t* single_raw raw_array->with_affinity = false; } } - else if (!strcmp(line, "------[ Versions ]------") || !strcmp(line, "------[ Logical CPU #0 ]------") || !strcmp(line, "------[ CPUID Registers / Logical CPU #0 ]------")) { + else if (!strcmp(line, "------[ Versions ]------") || + !strcmp(line, "------[ Logical CPU #0 ]------") || + !strcmp(line, "------[ CPUID Registers / Logical CPU #0 ]------") || + strstr(line, "CPU#000 AffMask: 0x")) { debugf(2, "Recognized AIDA64 raw dump\n"); is_header = false; is_libcpuid_dump = false; @@ -679,8 +683,9 @@ static int cpuid_deserialize_raw_data_internal(struct cpu_raw_data_t* single_raw } } else if (is_aida64_dump) { - if (use_raw_array && ((sscanf(line, "------[ Logical CPU #%hi ]------", &logical_cpu) >= 1) || \ - (sscanf(line, "------[ CPUID Registers / Logical CPU #%hi ]------", &logical_cpu) >= 1))) { + if (use_raw_array && ((sscanf(line, "------[ Logical CPU #%hi ]------", &logical_cpu) >= 1) || + (sscanf(line, "------[ CPUID Registers / Logical CPU #%hi ]------", &logical_cpu) >= 1) || + (sscanf(line, "CPU#%hi AffMask: 0x%*x", &logical_cpu) >= 1))) { debugf(2, "Parsing AIDA64 raw dump for logical CPU %i\n", logical_cpu); cpuid_grow_raw_data_array(raw_array, logical_cpu + 1); raw_ptr = &raw_array->raw[logical_cpu]; @@ -717,7 +722,7 @@ static int cpuid_deserialize_raw_data_internal(struct cpu_raw_data_t* single_raw /* Close file descriptor */ if (strcmp(filename, "")) fclose(f); - return set_error(ERR_OK); + return cpuid_set_error(ERR_OK); } #undef RAW_ASSIGN_LINE @@ -859,7 +864,7 @@ static int cpuid_basic_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* dat data->vendor = cpuid_vendor_identify(raw->basic_cpuid[0], data->vendor_str); if (data->vendor == VENDOR_UNKNOWN) - return set_error(ERR_CPU_UNKN); + return cpuid_set_error(ERR_CPU_UNKN); data->architecture = ARCHITECTURE_X86; basic = raw->basic_cpuid[0][EAX]; if (basic >= 1) { @@ -890,7 +895,7 @@ static int cpuid_basic_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* dat } load_features_common(raw, data); data->total_logical_cpus = get_total_cpus(); - return set_error(ERR_OK); + return cpuid_set_error(ERR_OK); } static void make_list_from_string(const char* csv, struct cpu_list_t* list) @@ -903,7 +908,7 @@ static void make_list_from_string(const char* csv, struct cpu_list_t* list) list->names = (char**) malloc(sizeof(char*) * n); if (!list->names) { /* Memory allocation failed */ list->num_entries = 0; - set_error(ERR_NO_MEM); + cpuid_set_error(ERR_NO_MEM); return; } list->num_entries = n; @@ -912,7 +917,7 @@ static void make_list_from_string(const char* csv, struct cpu_list_t* list) for (i = 0; i <= l; i++) if (i == l || csv[i] == ',') { list->names[n] = (char*) malloc(i - last); if (!list->names[n]) { /* Memory allocation failed */ - set_error(ERR_NO_MEM); + cpuid_set_error(ERR_NO_MEM); for (j = 0; j < n; j++) free(list->names[j]); free(list->names); list->num_entries = 0; @@ -946,7 +951,7 @@ static bool cpu_ident_apic_id(logical_cpu_t logical_cpu, struct cpu_raw_data_t* is_apic_id_supported = true; break; case VENDOR_UNKNOWN: - set_error(ERR_CPU_UNKN); + cpuid_set_error(ERR_CPU_UNKN); /* Fall through */ default: is_apic_id_supported = false; @@ -1025,7 +1030,7 @@ int cpuid_get_raw_data(struct cpu_raw_data_t* data) { unsigned i; if (!cpuid_present()) - return set_error(ERR_NO_CPUID); + return cpuid_set_error(ERR_NO_CPUID); for (i = 0; i < 32; i++) cpu_exec_cpuid(i, data->basic_cpuid[i]); for (i = 0; i < 32; i++) @@ -1060,18 +1065,18 @@ int cpuid_get_raw_data(struct cpu_raw_data_t* data) data->amd_fn8000001dh[i][ECX] = i; cpu_exec_cpuid_ext(data->amd_fn8000001dh[i]); } - return set_error(ERR_OK); + return cpuid_set_error(ERR_OK); } int cpuid_get_all_raw_data(struct cpu_raw_data_array_t* data) { - int cur_error = set_error(ERR_OK); - int ret_error = set_error(ERR_OK); + int cur_error = cpuid_set_error(ERR_OK); + int ret_error = cpuid_set_error(ERR_OK); logical_cpu_t logical_cpu = 0; struct cpu_raw_data_t* raw_ptr = NULL; if (data == NULL) - return set_error(ERR_HANDLE); + return cpuid_set_error(ERR_HANDLE); bool affinity_saved = save_cpu_affinity(); @@ -1119,13 +1124,13 @@ int cpu_ident_internal(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct struct cpu_raw_data_t myraw; if (!raw) { if ((r = cpuid_get_raw_data(&myraw)) < 0) - return set_error(r); + return cpuid_set_error(r); raw = &myraw; } cpu_id_t_constructor(data); memset(internal->cache_mask, 0, sizeof(internal->cache_mask)); if ((r = cpuid_basic_identify(raw, data)) < 0) - return set_error(r); + return cpuid_set_error(r); switch (data->vendor) { case VENDOR_INTEL: r = cpuid_identify_intel(raw, data, internal); @@ -1134,6 +1139,9 @@ int cpu_ident_internal(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct case VENDOR_HYGON: r = cpuid_identify_amd(raw, data, internal); break; + case VENDOR_CENTAUR: + r = cpuid_identify_centaur(raw, data, internal); + break; default: break; } @@ -1141,7 +1149,7 @@ int cpu_ident_internal(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct /* - Deprecated since v0.5.0 */ data->l1_assoc = data->l1_data_assoc; data->l1_cacheline = data->l1_data_cacheline; - return set_error(r); + return cpuid_set_error(r); } static cpu_purpose_t cpu_ident_purpose(struct cpu_raw_data_t* raw) @@ -1152,11 +1160,14 @@ static cpu_purpose_t cpu_ident_purpose(struct cpu_raw_data_t* raw) vendor = cpuid_vendor_identify(raw->basic_cpuid[0], vendor_str); if (vendor == VENDOR_UNKNOWN) { - set_error(ERR_CPU_UNKN); + cpuid_set_error(ERR_CPU_UNKN); return purpose; } switch (vendor) { + case VENDOR_AMD: + purpose = cpuid_identify_purpose_amd(raw); + break; case VENDOR_INTEL: purpose = cpuid_identify_purpose_intel(raw); break; @@ -1230,8 +1241,8 @@ static void update_cache_instances(struct internal_cache_instances_t* caches, int cpu_identify_all(struct cpu_raw_data_array_t* raw_array, struct system_id_t* system) { - int cur_error = set_error(ERR_OK); - int ret_error = set_error(ERR_OK); + int cur_error = cpuid_set_error(ERR_OK); + int ret_error = cpuid_set_error(ERR_OK); double smt_divisor; bool is_new_cpu_type; bool is_last_item; @@ -1251,10 +1262,10 @@ int cpu_identify_all(struct cpu_raw_data_array_t* raw_array, struct system_id_t* struct internal_cache_instances_t caches_type, caches_all; if (system == NULL) - return set_error(ERR_HANDLE); + return cpuid_set_error(ERR_HANDLE); if (!raw_array) { if ((ret_error = cpuid_get_all_raw_data(&my_raw_array)) < 0) - return set_error(ret_error); + return cpuid_set_error(ret_error); raw_array = &my_raw_array; } system_id_t_constructor(system); @@ -1322,7 +1333,7 @@ int cpu_identify_all(struct cpu_raw_data_array_t* raw_array, struct system_id_t* switch (event) { case EVENT_NEW_CPU_TYPE: cpu_type_index = system->num_cpu_types - 2; break; case EVENT_LAST_ITEM: cpu_type_index = system->num_cpu_types - 1; break; - default: warnf("Warning: event %i in cpu_identify_all() not handled.\n", event); return set_error(ERR_NOT_IMP); + default: warnf("Warning: event %i in cpu_identify_all() not handled.\n", event); return cpuid_set_error(ERR_NOT_IMP); } copy_affinity_mask(&system->cpu_types[cpu_type_index].affinity_mask, &affinity_mask); if (event != EVENT_LAST_ITEM) { @@ -1346,9 +1357,9 @@ int cpu_identify_all(struct cpu_raw_data_array_t* raw_array, struct system_id_t* } else { /* Note: if SMT is disabled by BIOS, smt_divisor will no reflect the current state properly */ - is_smt_supported = (system->cpu_types[cpu_type_index].num_logical_cpus % system->cpu_types[cpu_type_index].num_cores) == 0; + is_smt_supported = system->cpu_types[cpu_type_index].num_cores > 0 ? (system->cpu_types[cpu_type_index].num_logical_cpus % system->cpu_types[cpu_type_index].num_cores) == 0 : false; smt_divisor = is_smt_supported ? system->cpu_types[cpu_type_index].num_logical_cpus / system->cpu_types[cpu_type_index].num_cores : 1.0; - system->cpu_types[cpu_type_index].num_cores = (int32_t) num_logical_cpus / smt_divisor; + system->cpu_types[cpu_type_index].num_cores = (int32_t) (num_logical_cpus / smt_divisor); } /* Save current values in system->cpu_types[cpu_type_index] and reset values for the next purpose */ system->cpu_types[cpu_type_index].num_logical_cpus = num_logical_cpus; @@ -1383,18 +1394,18 @@ int cpu_request_core_type(cpu_purpose_t purpose, struct cpu_raw_data_array_t* ra if (!raw_array) { if ((error = cpuid_get_all_raw_data(&my_raw_array)) < 0) - return set_error(error); + return cpuid_set_error(error); raw_array = &my_raw_array; } for (logical_cpu = 0; logical_cpu < raw_array->num_raw; logical_cpu++) { if (cpu_ident_purpose(&raw_array->raw[logical_cpu]) == purpose) { cpu_ident_internal(&raw_array->raw[logical_cpu], data, &throwaway); - return set_error(ERR_OK); + return cpuid_set_error(ERR_OK); } } - return set_error(ERR_NOT_FOUND); + return cpuid_set_error(ERR_NOT_FOUND); } const char* cpu_architecture_str(cpu_architecture_t architecture) @@ -1646,7 +1657,7 @@ cpu_vendor_t cpuid_get_vendor(void) if(vendor == VENDOR_UNKNOWN) { if (!cpuid_present()) - set_error(ERR_NO_CPUID); + cpuid_set_error(ERR_NO_CPUID); else { cpu_exec_cpuid(0, raw_vendor); vendor = cpuid_vendor_identify(raw_vendor, vendor_str); @@ -1678,7 +1689,7 @@ void cpuid_get_cpu_list(cpu_vendor_t vendor, struct cpu_list_t* list) make_list_from_string("UMC x86 CPU", list); break; case VENDOR_CENTAUR: - make_list_from_string("VIA C3,VIA C7,VIA Nano", list); + cpuid_get_list_centaur(list); break; case VENDOR_RISE: make_list_from_string("Rise mP6", list); @@ -1691,7 +1702,7 @@ void cpuid_get_cpu_list(cpu_vendor_t vendor, struct cpu_list_t* list) break; default: warnf("Unknown vendor passed to cpuid_get_cpu_list()\n"); - set_error(ERR_INVRANGE); + cpuid_set_error(ERR_INVRANGE); list->num_entries = 0; list->names = NULL; break; diff --git a/libraries/libcpuid/libcpuid.h b/libraries/libcpuid/libcpuid.h index b5b05bec..037e29fc 100755 --- a/libraries/libcpuid/libcpuid.h +++ b/libraries/libcpuid/libcpuid.h @@ -29,7 +29,7 @@ * \file libcpuid.h * \author Veselin Georgiev * \date Oct 2008 - * \version 0.6.2 + * \version 0.6.4 * * Version history: * @@ -68,7 +68,15 @@ * cpu_id_t is now different). * * 0.6.1 (2022-10-23): A lot of DB updates, fix set_cpu_affinity() on Windows, * fix cpu_identify_all() when HT is disabled. - * * 0.6.6 (2022-11-11): A lot of DB updates, fix cpu_identify_all() for single-core CPUs. + * * 0.6.2 (2022-11-11): A lot of DB updates, fix cpu_identify_all() for single-core CPUs. + * * 0.6.3 (2023-04-02): A lot of DB updates, fix infinite loop in set_cpu_affinity() on macOS, + * fix a misprint of extended CPUID in cpuid_basic_identify(), + * restore previous thread CPU affinity before returning from cpuid_get_all_raw_data(), + * query CPU info at least once even if set_cpu_affinity() fails, + * rename set_error() to cpuid_set_error() and get_error() to cpuid_get_error(). + * * 0.6.4 (2023-10-08): A lot of DB updates, add support for Centaur CPUs (VIA and Zhaoxin), + * fix floating point exception in cpu_identify_all(), + * fix build for NetBSD and DragonFly BSD. */ /** @mainpage A simple libcpuid introduction @@ -403,7 +411,7 @@ struct cpu_id_t { /** Cache associativity for the L1 data cache. -1 if undetermined */ int32_t l1_data_assoc; - /** Cache associativity for the L1 intruction cache. -1 if undetermined */ + /** Cache associativity for the L1 instruction cache. -1 if undetermined */ int32_t l1_instruction_assoc; /** Cache associativity for the L2 cache. -1 if undetermined */ @@ -423,7 +431,7 @@ struct cpu_id_t { /** Cache-line size for L1 data cache. -1 if undetermined */ int32_t l1_data_cacheline; - /** Cache-line size for L1 intruction cache. -1 if undetermined */ + /** Cache-line size for L1 instruction cache. -1 if undetermined */ int32_t l1_instruction_cacheline; /** Cache-line size for L2 cache. -1 if undetermined */ @@ -438,7 +446,7 @@ struct cpu_id_t { /** Number of L1 data cache instances. -1 if undetermined */ int32_t l1_data_instances; - /** Number of L1 intruction cache instances. -1 if undetermined */ + /** Number of L1 instruction cache instances. -1 if undetermined */ int32_t l1_instruction_instances; /** Number of L2 cache instances. -1 if undetermined */ @@ -464,7 +472,7 @@ struct cpu_id_t { * +--------+--------+-------+-------+-------+---------------------------------------+-----------------------+ * @endcode */ - char cpu_codename[64]; + char cpu_codename[CODENAME_STR_MAX]; /** SSE execution unit size (64 or 128; -1 if N/A) */ int32_t sse_size; @@ -499,7 +507,7 @@ struct system_id_t { /** Number of total L1 data cache instances. -1 if undetermined */ int32_t l1_data_total_instances; - /** Number of total L1 intruction cache instances. -1 if undetermined */ + /** Number of total L1 instruction cache instances. -1 if undetermined */ int32_t l1_instruction_total_instances; /** Number of total L2 cache instances. -1 if undetermined */ diff --git a/libraries/libcpuid/libcpuid_constants.h b/libraries/libcpuid/libcpuid_constants.h index be5bc0eb..a88a7d09 100755 --- a/libraries/libcpuid/libcpuid_constants.h +++ b/libraries/libcpuid/libcpuid_constants.h @@ -34,6 +34,7 @@ #define VENDOR_STR_MAX 16 #define BRAND_STR_MAX 64 +#define CODENAME_STR_MAX 64 #define CPU_FLAGS_MAX 128 #define MAX_CPUID_LEVEL 32 #define MAX_EXT_CPUID_LEVEL 32 diff --git a/libraries/libcpuid/libcpuid_internal.h b/libraries/libcpuid/libcpuid_internal.h index e2d67742..b6e6e99b 100644 --- a/libraries/libcpuid/libcpuid_internal.h +++ b/libraries/libcpuid/libcpuid_internal.h @@ -55,6 +55,11 @@ enum _amd_code_t { }; typedef enum _amd_code_t amd_code_t; +enum _centaur_code_t { + #include "centaur_code_t.h" +}; +typedef enum _centaur_code_t centaur_code_t; + enum _intel_code_t { #include "intel_code_t.h" }; @@ -64,8 +69,9 @@ typedef enum _intel_code_t intel_code_t; struct internal_id_info_t { union { - amd_code_t amd; - intel_code_t intel; + amd_code_t amd; + centaur_code_t centaur; + intel_code_t intel; } code; uint64_t bits; int score; // detection (matchtable) score @@ -113,6 +119,10 @@ enum _common_bits_t { _5 = LBIT( 4 ), _7 = LBIT( 5 ), _9 = LBIT( 6 ), + _H = LBIT( 7 ), + _S = LBIT( 8 ), + _U = LBIT( 9 ), + _X = LBIT( 10 ), }; // additional detection bits for Intel CPUs: @@ -123,6 +133,16 @@ enum _intel_bits_t { _I_ = LBIT( 13 ), XEON_ = LBIT( 14 ), ATOM_ = LBIT( 15 ), + _K = LBIT( 16 ), + _P = LBIT( 17 ), + _N = LBIT( 18 ), + _W_ = LBIT( 19 ), + _D_ = LBIT( 20 ), + _BRONZE_ = LBIT( 21 ), + _SILVER_ = LBIT( 22 ), + _GOLD_ = LBIT( 23 ), + _PLATINIUM_ = LBIT( 24 ), + _MAX_ = LBIT( 25 ), }; typedef enum _intel_bits_t intel_bits_t; @@ -145,9 +165,33 @@ enum _amd_bits_t { _FX = LBIT( 25 ), _APU_ = LBIT( 26 ), C86_ = LBIT( 27 ), + _Z = LBIT( 28 ), }; typedef enum _amd_bits_t amd_bits_t; +enum _via_bits_t { + SAMUEL_ = LBIT( 10 ), + EZRA_ = LBIT( 11 ), + NEHEMIAH_ = LBIT( 12 ), + ESTHER_ = LBIT( 13 ), + EDEN_ = LBIT( 14 ), + CNA_ = LBIT( 15 ), + NANO_ = LBIT( 16 ), + QUADCORE_ = LBIT( 17 ), +}; +typedef enum _via_bits_t via_bits_t; + +enum _zhaoxin_bits_t { + KAISHENG_ = LBIT( 10 ), + KAIXIAN_ = LBIT( 11 ), + _KH_ = LBIT( 12 ), + _KX_ = LBIT( 13 ), + _ZX_ = LBIT( 14 ), + _C = LBIT( 15 ), + _D = LBIT( 16 ), + _E = LBIT( 17 ), +}; +typedef enum _zhaoxin_bits_t zhaoxin_bits_t; int cpu_ident_internal(struct cpu_raw_data_t* raw, struct cpu_id_t* data, diff --git a/libraries/libcpuid/libcpuid_util.c b/libraries/libcpuid/libcpuid_util.c index f2281f8c..34933eff 100755 --- a/libraries/libcpuid/libcpuid_util.c +++ b/libraries/libcpuid/libcpuid_util.c @@ -142,7 +142,7 @@ int match_cpu_codename(const struct match_entry_t* matchtable, int count, bestindex = i; } } - strcpy(data->cpu_codename, matchtable[bestindex].name); + strncpy(data->cpu_codename, matchtable[bestindex].name, CODENAME_STR_MAX); return bestscore; } @@ -153,7 +153,7 @@ void generic_get_cpu_list(const struct match_entry_t* matchtable, int count, n = 0; list->names = (char**) malloc(sizeof(char*) * count); if (!list->names) { /* Memory allocation failure */ - set_error(ERR_NO_MEM); + cpuid_set_error(ERR_NO_MEM); list->num_entries = 0; return; } @@ -172,7 +172,7 @@ void generic_get_cpu_list(const struct match_entry_t* matchtable, int count, list->names[n] = strdup(matchtable[i].name); #endif if (!list->names[n]) { /* Memory allocation failure */ - set_error(ERR_NO_MEM); + cpuid_set_error(ERR_NO_MEM); list->num_entries = 0; for (j = 0; j < n; j++) { free(list->names[j]); @@ -348,6 +348,31 @@ void assign_cache_data(uint8_t on, cache_type_t cache, int size, int assoc, int } } +void decode_number_of_cores_x86(struct cpu_raw_data_t* raw, struct cpu_id_t* data) +{ + int logical_cpus = -1, num_cores = -1; + + if (raw->basic_cpuid[0][EAX] >= 1) { + logical_cpus = (raw->basic_cpuid[1][EBX] >> 16) & 0xff; + if (raw->basic_cpuid[0][EAX] >= 4) { + num_cores = 1 + ((raw->basic_cpuid[4][EAX] >> 26) & 0x3f); + } + } + if (data->flags[CPU_FEATURE_HT]) { + if (num_cores > 1) { + data->num_cores = num_cores; + data->num_logical_cpus = logical_cpus; + } else { + data->num_cores = 1; + data->num_logical_cpus = (logical_cpus >= 1 ? logical_cpus : 1); + if (data->num_logical_cpus == 1) + data->flags[CPU_FEATURE_HT] = 0; + } + } else { + data->num_cores = data->num_logical_cpus = (logical_cpus >= 1 ? logical_cpus : 1); + } +} + void decode_deterministic_cache_info_x86(uint32_t cache_regs[][NUM_REGS], uint8_t subleaf_count, struct cpu_id_t* data, diff --git a/libraries/libcpuid/libcpuid_util.h b/libraries/libcpuid/libcpuid_util.h index 43c61283..7c4d1beb 100755 --- a/libraries/libcpuid/libcpuid_util.h +++ b/libraries/libcpuid/libcpuid_util.h @@ -43,7 +43,7 @@ struct match_entry_t { int ncores, l2cache, l3cache, brand_code; uint64_t model_bits; int model_code; - char name[32]; + char name[CODENAME_STR_MAX]; }; // returns the match score: @@ -92,12 +92,12 @@ void debug_print_lbits(int debuglevel, uint64_t mask); /* * Sets the current errno */ -int set_error(cpu_error_t err); +int cpuid_set_error(cpu_error_t err); /* * Gets the current errno */ -int get_error(void); +int cpuid_get_error(void); extern libcpuid_warn_fn_t _warn_fun; extern int _current_verboselevel; @@ -124,6 +124,9 @@ void clear_affinity_mask_bit(logical_cpu_t logical_cpu, cpu_affinity_mask_t *aff /* assign cache values in cpu_id_t type */ void assign_cache_data(uint8_t on, cache_type_t cache, int size, int assoc, int linesize, struct cpu_id_t* data); +/* generic way to retrieve core count for x86 CPUs */ +void decode_number_of_cores_x86(struct cpu_raw_data_t* raw, struct cpu_id_t* data); + /* generic way to retrieve cache topology for x86 CPUs */ void decode_deterministic_cache_info_x86(uint32_t cache_regs[][NUM_REGS], uint8_t subleaf_count, diff --git a/libraries/libcpuid/recog_amd.c b/libraries/libcpuid/recog_amd.c index bce6fba3..c93abc21 100755 --- a/libraries/libcpuid/recog_amd.c +++ b/libraries/libcpuid/recog_amd.c @@ -347,20 +347,22 @@ const struct match_entry_t cpudb_amd[] = { { 15, -1, -1, 25, 68, -1, -1, -1, NC, RYZEN_|_5 , 0, "Ryzen 5 (Rembrandt)" }, { 15, -1, -1, 25, 68, -1, -1, -1, NC, RYZEN_|_3 , 0, "Ryzen 3 (Rembrandt)" }, /* Zen 4 (2022) => https://en.wikichip.org/wiki/amd/microarchitectures/zen_4 */ - //{ 15, -1, -1, 25, ??, -1, -1, -1, NC, EPYC_ , 0, "EPYC (Genoa)" }, + { 15, -1, -1, 25, 17, -1, -1, -1, NC, EPYC_ , 0, "EPYC (Genoa)" }, //{ 15, -1, -1, 25, ??, -1, -1, -1, NC, RYZEN_TR_ , 0, "Threadripper (Storm Peak)" }, { 15, -1, 2, 25, 97, -1, -1, -1, NC, RYZEN_|_9 , 0, "Ryzen 9 (Raphael)" }, { 15, -1, 2, 25, 97, -1, -1, -1, NC, RYZEN_|_7 , 0, "Ryzen 7 (Raphael)" }, { 15, -1, 2, 25, 97, -1, -1, -1, NC, RYZEN_|_5 , 0, "Ryzen 5 (Raphael)" }, { 15, -1, 2, 25, 97, -1, -1, -1, NC, RYZEN_|_3 , 0, "Ryzen 3 (Raphael)" }, - //{ 15, -1, -1, 25, ??, -1, -1, -1, NC, RYZEN_|_9 , 0, "Ryzen 9 (Dragon Range)" }, - //{ 15, -1, -1, 25, ??, -1, -1, -1, NC, RYZEN_|_7 , 0, "Ryzen 7 (Dragon Range)" }, - //{ 15, -1, -1, 25, ??, -1, -1, -1, NC, RYZEN_|_5 , 0, "Ryzen 5 (Dragon Range)" }, - //{ 15, -1, -1, 25, ??, -1, -1, -1, NC, RYZEN_|_3 , 0, "Ryzen 3 (Dragon Range)" }, - //{ 15, -1, -1, 25, ??, -1, -1, -1, NC, RYZEN_|_9 , 0, "Ryzen 9 (Phoenix Point)" }, - //{ 15, -1, -1, 25, ??, -1, -1, -1, NC, RYZEN_|_7 , 0, "Ryzen 7 (Phoenix Point)" }, - //{ 15, -1, -1, 25, ??, -1, -1, -1, NC, RYZEN_|_5 , 0, "Ryzen 5 (Phoenix Point)" }, - //{ 15, -1, -1, 25, ??, -1, -1, -1, NC, RYZEN_|_3 , 0, "Ryzen 3 (Phoenix Point)" }, + { 15, -1, -1, 25, 97, -1, -1, -1, NC, RYZEN_|_9|_H , 0, "Ryzen 9 (Dragon Range)" }, + { 15, -1, -1, 25, 97, -1, -1, -1, NC, RYZEN_|_7|_H , 0, "Ryzen 7 (Dragon Range)" }, + { 15, -1, -1, 25, 97, -1, -1, -1, NC, RYZEN_|_5|_H , 0, "Ryzen 5 (Dragon Range)" }, + { 15, -1, -1, 25, 116, -1, -1, -1, NC, RYZEN_|_9|_H , 0, "Ryzen 9 (Phoenix)" }, + { 15, -1, -1, 25, 116, -1, -1, -1, NC, RYZEN_|_7|_H , 0, "Ryzen 7 (Phoenix)" }, + { 15, -1, -1, 25, 116, -1, -1, -1, NC, RYZEN_|_7|_U , 0, "Ryzen 7 (Phoenix)" }, + { 15, -1, -1, 25, 116, -1, -1, -1, NC, RYZEN_|_5|_H , 0, "Ryzen 5 (Phoenix)" }, + { 15, -1, -1, 25, 116, -1, -1, -1, NC, RYZEN_|_5|_U , 0, "Ryzen 5 (Phoenix)" }, + { 15, -1, -1, 25, 116, -1, -1, -1, NC, RYZEN_|_3|_U , 0, "Ryzen 3 (Phoenix)" }, + { 15, -1, -1, 25, 116, -1, -1, -1, NC, RYZEN_|_Z , 0, "Ryzen Z1 (Phoenix)" }, /* F M S EF EM #cores L2$ L3$ BC ModelBits ModelCode Name */ }; @@ -520,6 +522,7 @@ static struct amd_code_and_bits_t decode_amd_codename_part1(const char *bs) struct amd_code_and_bits_t result; uint64_t bits = 0; int i = 0; + const size_t n = strlen(bs); const struct { amd_code_t c; const char *search; } code_matchtable[] = { { PHENOM2, "Phenom(tm) II" }, @@ -565,7 +568,7 @@ static struct amd_code_and_bits_t decode_amd_codename_part1(const char *bs) if (amd_has_turion_modelname(bs)) { bits |= TURION_; } - if ((i = match_pattern(bs, "Ryzen [3579]")) != 0) { + if ((i = match_pattern(bs, "Ryzen [3579Z]")) != 0) { bits |= RYZEN_; i--; switch (bs[i + 6]) { @@ -573,6 +576,15 @@ static struct amd_code_and_bits_t decode_amd_codename_part1(const char *bs) case '5': bits |= _5; break; case '7': bits |= _7; break; case '9': bits |= _9; break; + case 'Z': bits |= _Z; break; + } + for(i = i + 7; i < n; i++) { + switch (bs[i]) { + case 'H': bits |= _H; break; + case 'S': bits |= _S; break; + case 'U': bits |= _U; break; + case 'X': bits |= _X; break; + } } } @@ -646,3 +658,31 @@ void cpuid_get_list_amd(struct cpu_list_t* list) { generic_get_cpu_list(cpudb_amd, COUNT_OF(cpudb_amd), list); } + +cpu_purpose_t cpuid_identify_purpose_amd(struct cpu_raw_data_t* raw) +{ + //FIXME: ext_cpuid[0x26] => index 38 is past the end of the array (which contains 32 elements) + //TODO: leaf CPUID_Fn80000026 needs to be added in cpu_raw_data_t + (void)(raw); +#if 0 + /* Check for hybrid architecture + From Processor Programming Reference (PPR) for AMD Family 19h Model 70h, Revision A0 Processors + Available at https://www.amd.com/system/files/TechDocs/57019-A0-PUB_3.00.zip + + - CPUID_Fn80000026_ECX [Extended CPU Topology][15:8] is LevelType. + LevelType 01h is Core. + + - CPUID_Fn80000026_EBX [Extended CPU Topology][31:28] is CoreType. + Only valid while LevelType=Core. + */ + if (EXTRACTS_BITS(raw->ext_cpuid[0x26][ECX], 15, 8) == 0x1) { + debugf(3, "Detected AMD CPU hybrid architecture\n"); + switch (EXTRACTS_BITS(raw->ext_cpuid[0x26][EBX], 31, 28)) { + case 0x0: return PURPOSE_PERFORMANCE; + case 0x1: return PURPOSE_EFFICIENCY; + default: return PURPOSE_GENERAL; + } + } +#endif + return PURPOSE_GENERAL; +} diff --git a/libraries/libcpuid/recog_amd.h b/libraries/libcpuid/recog_amd.h index 34e89598..798f7a38 100755 --- a/libraries/libcpuid/recog_amd.h +++ b/libraries/libcpuid/recog_amd.h @@ -28,5 +28,6 @@ int cpuid_identify_amd(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal); void cpuid_get_list_amd(struct cpu_list_t* list); +cpu_purpose_t cpuid_identify_purpose_amd(struct cpu_raw_data_t* raw); #endif /* __RECOG_AMD_H__ */ diff --git a/libraries/libcpuid/recog_centaur.c b/libraries/libcpuid/recog_centaur.c new file mode 100644 index 00000000..c21cc935 --- /dev/null +++ b/libraries/libcpuid/recog_centaur.c @@ -0,0 +1,240 @@ +/* + * Copyright 2023 Veselin Georgiev, + * anrieffNOSPAM @ mgail_DOT.com (convert to gmail) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include "libcpuid.h" +#include "libcpuid_util.h" +#include "libcpuid_internal.h" +#include "recog_centaur.h" + +const struct centaur_code_str { centaur_code_t code; char *str; } centaur_code_str[] = { + #define CODE(x) { x, #x } + #define CODE2(x, y) CODE(x) + #include "centaur_code_t.h" + #undef CODE +}; + +typedef struct { + int code; + uint64_t bits; +} centaur_code_and_bits_t; + +enum _centaur_model_t { + UNKNOWN = -1, + _4000 = 100, /* Zhaoxin KaiXian (KX) / KaisHeng (KH) Zhangjiang */ + _5000, /* Zhaoxin KaiXian (KX) WuDaoKou */ + _6000, /* Zhaoxin KaiXian (KX) LuJiaZui */ + _7000, /* Zhaoxin KaiXian (KX) Yongfeng */ + _20000 = 1000, /* Zhaoxin KaisHeng (KH) WuDaoKou */ + _30000, /* Zhaoxin KaisHeng (KH) LuJiaZui */ + _40000, /* Zhaoxin KaisHeng (KH) Yongfeng */ +}; +typedef enum _centaur_model_t centaur_model_t; + +const struct match_entry_t cpudb_centaur[] = { +// F M S EF EM #cores L2$ L3$ BC ModelBits ModelCode Name + { -1, -1, -1, -1, -1, -1, -1, -1, NC, 0, 0, "Unknown Centaur CPU" }, +// F M S EF EM #cores L2$ L3$ BC ModelBits ModelCode Name + + + /* VIA */ +// F M S EF EM #cores L2$ L3$ BC ModelBits ModelCode Name + { 6, -1, -1, -1, -1, -1, -1, -1, VIA, 0 , 0, "Unknown VIA CPU" }, + /* Samuel (2000, 180 nm) */ + { 6, 6, -1, -1, -1, -1, -1, -1, VIA, SAMUEL_ , 0, "VIA Cyrix III (Samuel)" }, + /* Samuel 2 (2001, 150 nm) */ + { 6, 7, -1, -1, -1, -1, -1, -1, VIA, SAMUEL_ , 0, "VIA C3 (Samuel 2)" }, + /* Ezra (2001, 130 nm) */ + { 6, 7, -1, -1, -1, -1, -1, -1, VIA, EZRA_ , 0, "VIA C3 (Ezra)" }, + { 6, 8, -1, -1, -1, -1, -1, -1, VIA, EZRA_ , 0, "VIA C3 (Ezra-T)" }, + /* Nehemiah (2003, 130 nm) */ + { 6, 9, -1, -1, -1, -1, -1, -1, VIA, NEHEMIAH_ , 0, "VIA C3 (Nehemiah)" }, + /* Esther (2005, 90 nm) */ + { 6, 10, -1, -1, -1, -1, -1, -1, VIA, ESTHER_ , 0, "VIA C7 (Esther)" }, + { 6, 13, -1, -1, -1, -1, -1, -1, VIA, ESTHER_ , 0, "VIA C7-M (Esther)" }, + /* Isaiah (2008, 65 nm) */ + { 6, 15, -1, -1, -1, -1, -1, -1, VIA, CNA_ , 0, "VIA Nano (Isaiah)" }, + { 6, 15, -1, -1, -1, 1, -1, -1, VIA, NANO_ , 0, "VIA Nano (Isaiah)" }, + { 6, 15, -1, -1, -1, 2, -1, -1, VIA, NANO_ , 0, "VIA Nano X2 (Isaiah)" }, + { 6, 15, -1, -1, -1, -1, -1, -1, VIA, QUADCORE_ , 0, "VIA Nano X4 (Isaiah)" }, + { 6, 15, -1, -1, -1, 4, -1, -1, VIA, EDEN_ , 0, "VIA Eden X4 (Isaiah)" }, +// F M S EF EM #cores L2$ L3$ BC ModelBits ModelCode Name + + + /* Zhaoxin */ +// F M S EF EM #cores L2$ L3$ BC ModelBits ModelCode Name + { 7, -1, -1, -1, -1, -1, -1, -1, ZHAOXIN, 0 , 0, "Unknown Zhaoxin CPU" }, + /* Zhangjiang (2015, 28 nm) */ + { 7, -1, -1, -1, 15, -1, -1, -1, ZHAOXIN, KAISHENG_|_KH_|_C, 0, "Zhaoxin KaisHeng (ZhangJiang)" }, // C+ (4000) + { 7, -1, -1, -1, 15, -1, -1, -1, ZHAOXIN, KAIXIAN_|_ZX_|_C , 0, "Zhaoxin KaiXian (ZhangJiang)" }, // C/C+ (4000) + /* WuDaoKou (2017, 28 nm) */ + { 7, -1, -1, -1, 27, -1, -1, -1, ZHAOXIN, KAISHENG_|_KH_ , _20000, "Zhaoxin KaisHeng (WuDaoKou)" }, // KH (20000) + { 7, -1, -1, -1, 27, -1, -1, -1, ZHAOXIN, KAIXIAN_|_KX_ , _5000, "Zhaoxin KaiXian (WuDaoKou)" }, // KX (5000) + /* LuJiaZui (2019, 16 nm) */ + { 7, -1, -1, -1, 59, -1, -1, -1, ZHAOXIN, KAISHENG_|_KH_ , _30000, "Zhaoxin KaisHeng (LuJiaZui)" }, // KH (30000) + { 7, -1, -1, -1, 59, -1, -1, -1, ZHAOXIN, KAIXIAN_|_KX_ , _6000, "Zhaoxin KaiXian (LuJiaZui)" }, // KX (6000) + /* Yongfeng (2022, 16 nm) */ + { 7, -1, -1, -1, 91, -1, -1, -1, ZHAOXIN, KAISHENG_|_KH_ , _40000, "Zhaoxin KaisHeng (Yongfeng)" }, // KH (40000) + { 7, -1, -1, -1, 91, -1, -1, -1, ZHAOXIN, KAIXIAN_|_KX_ , _7000, "Zhaoxin KaiXian (Yongfeng)" }, // KX (7000) +// F M S EF EM #cores L2$ L3$ BC ModelBits ModelCode Name +}; + +static centaur_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data) +{ + centaur_code_t code = (centaur_code_t) NC; + centaur_code_and_bits_t result; + uint64_t bits = 0; + int i = 0; + + const char* bs = data->brand_str; + const struct { centaur_code_t c; const char *search; } code_matchtable[] = { + { VIA, "VIA" }, + { ZHAOXIN, "ZHAOXIN" }, + }; + + const struct { uint64_t bit; const char* search; } bit_matchtable_via[] = { + { SAMUEL_, "Samuel" }, + { EZRA_, "Ezra" }, + { NEHEMIAH_, "Nehemiah" }, + { ESTHER_, "Esther" }, + { EDEN_, "Eden" }, + { CNA_, "CNA" }, + { NANO_, "Nano" }, + { QUADCORE_, "QuadCore" }, + }; + const struct { uint64_t bit; const char* search; } bit_matchtable_zhaoxin[] = { + { KAISHENG_, "KaisHeng" }, + { KAIXIAN_, "KaiXian" }, + { _KH_, "KH" }, + { _KX_, "KX" }, + { _ZX_, "ZX" }, + { _C, "-C" }, + { _D, "-D" }, + { _E, "-E" }, + }; + + for (i = 0; i < COUNT_OF(code_matchtable); i++) { + if (match_pattern(bs, code_matchtable[i].search)) { + code = code_matchtable[i].c; + break; + } + } + + if (code == VIA) { + for (i = 0; i < COUNT_OF(bit_matchtable_via); i++) { + if (match_pattern(bs, bit_matchtable_via[i].search)) + bits |= bit_matchtable_via[i].bit; + } + } + else if (code == ZHAOXIN) { + for (i = 0; i < COUNT_OF(bit_matchtable_zhaoxin); i++) { + if (match_pattern(bs, bit_matchtable_zhaoxin[i].search)) + bits |= bit_matchtable_zhaoxin[i].bit; + } + } + + result.code = code; + result.bits = bits; + return result; +} + +static centaur_model_t get_model_code(struct cpu_id_t* data, centaur_code_and_bits_t brand) +{ + int i = 0; + int l = (int) strlen(data->brand_str); + const char *bs = data->brand_str; + + if (brand.code == ZHAOXIN) { + if ((i = match_pattern(bs, "KaiSheng KH-")) != 0) { + i += 11; + if (i + 4 >= l) return UNKNOWN; + switch(bs[i]) { + case '2': return _20000; + case '3': return _30000; + case '4': return _40000; + default: return UNKNOWN; + } + } + else if ((i = match_pattern(bs, "KaiXian KX-")) != 0) { + i += 10; + if (bs[i] == 'U') i++; + if (i + 3 >= l) return UNKNOWN; + switch(bs[i]) { + case '4': return _4000; + case '5': return _5000; + case '6': return _6000; + case '7': return _7000; + default: return UNKNOWN; + } + } + } + + return UNKNOWN; +} + +int cpuid_identify_centaur(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal) +{ + centaur_code_and_bits_t brand; + centaur_model_t model_code; + int i; + char* brand_code_str = NULL; + + if (raw->basic_cpuid[0][EAX] >= 4) + decode_deterministic_cache_info_x86(raw->intel_fn4, MAX_INTELFN4_LEVEL, data, internal); + decode_number_of_cores_x86(raw, data); + + brand = get_brand_code_and_bits(data); + model_code = get_model_code(data, brand); + for (i = 0; i < COUNT_OF(centaur_code_str); i++) { + if (brand.code == centaur_code_str[i].code) { + brand_code_str = centaur_code_str[i].str; + break; + } + } + if (brand_code_str) + debugf(2, "Detected Centaur brand code: %d (%s)\n", brand.code, brand_code_str); + else + debugf(2, "Detected Centaur brand code: %d\n", brand.code); + if (brand.bits) { + debugf(2, "Detected Centaur bits: "); + debug_print_lbits(2, brand.bits); + } + debugf(2, "Detected Centaur model code: %d\n", model_code); + + internal->code.centaur = brand.code; + internal->bits = brand.bits; + internal->score = match_cpu_codename(cpudb_centaur, COUNT_OF(cpudb_centaur), data, + brand.code, brand.bits, model_code); + + return 0; +} + +void cpuid_get_list_centaur(struct cpu_list_t* list) +{ + generic_get_cpu_list(cpudb_centaur, COUNT_OF(cpudb_centaur), list); +} diff --git a/libraries/libcpuid/recog_centaur.h b/libraries/libcpuid/recog_centaur.h new file mode 100644 index 00000000..09b5ebd9 --- /dev/null +++ b/libraries/libcpuid/recog_centaur.h @@ -0,0 +1,32 @@ +/* + * Copyright 2023 Veselin Georgiev, + * anrieffNOSPAM @ mgail_DOT.com (convert to gmail) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __RECOG_CENTAUR_H__ +#define __RECOG_CENTAUR_H__ + +int cpuid_identify_centaur(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal); +void cpuid_get_list_centaur(struct cpu_list_t* list); + +#endif /* __RECOG_CENTAUR_H__ */ diff --git a/libraries/libcpuid/recog_intel.c b/libraries/libcpuid/recog_intel.c index c4dd9d98..f0ccef08 100755 --- a/libraries/libcpuid/recog_intel.c +++ b/libraries/libcpuid/recog_intel.c @@ -66,6 +66,10 @@ enum _intel_model_t { _11xxx, /* Core i[3579] 11xxx */ _12xxx, /* Core i[3579] 12xxx */ _13xxx, /* Core i[3579] 13xxx */ + _x1xx, /* Xeon Bronze/Silver/Gold/Platinum x1xx */ + _x2xx, /* Xeon Bronze/Silver/Gold/Platinum x2xx */ + _x3xx, /* Xeon Bronze/Silver/Gold/Platinum x3xx */ + _x4xx, /* Xeon Bronze/Silver/Gold/Platinum/Max x4xx */ }; typedef enum _intel_model_t intel_model_t; @@ -214,10 +218,9 @@ const struct match_entry_t cpudb_intel[] = { { 6, 15, -1, -1, -1, 2, 2048, -1, MEROM, 0 , 0, "Merom (Core 2 Duo) 2048K" }, { 6, 15, -1, -1, -1, 2, 4096, -1, MEROM, 0 , 0, "Merom (Core 2 Duo) 4096K" }, - { 6, 15, -1, -1, 15, 1, -1, -1, NC, CELERON_ , 0, "Conroe-L (Celeron)" }, + { 6, 15, -1, -1, 15, 2, -1, -1, NC, PENTIUM_ , 0, "Allendale (Pentium)" }, + { 6, 15, -1, -1, 15, 2, -1, -1, NC, CELERON_ , 0, "Allendale (Celeron)" }, { 6, 6, -1, -1, 22, 1, -1, -1, NC, CELERON_ , 0, "Conroe-L (Celeron)" }, - { 6, 15, -1, -1, 15, 2, -1, -1, NC, CELERON_ , 0, "Conroe-L (Allendale)" }, - { 6, 6, -1, -1, 22, 2, -1, -1, NC, CELERON_ , 0, "Conroe-L (Allendale)" }, { 6, 6, -1, -1, 22, 1, -1, -1, NC, 0 , 0, "Unknown Core ?" }, @@ -260,7 +263,7 @@ const struct match_entry_t cpudb_intel[] = { { 6, 10, -1, -1, 26, 4, -1, -1, NC, XEON_|_7 , 0, "Bloomfield (Xeon)" }, { 6, 10, -1, -1, 26, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Bloomfield (Core i7)" }, { 6, 10, -1, -1, 30, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Lynnfield (Core i7)" }, - { 6, 5, -1, -1, 37, 4, -1, 8192, NC, CORE_|_I_|_5 , 0, "Lynnfield (Core i5)" }, + { 6, 5, -1, -1, 30, 4, -1, 8192, NC, CORE_|_I_|_5 , 0, "Lynnfield (Core i5)" }, /* Westmere CPUs (32nm): */ { 6, 5, -1, -1, 37, 2, -1, -1, NC, 0 , 0, "Unknown Core i3/i5" }, @@ -269,10 +272,11 @@ const struct match_entry_t cpudb_intel[] = { { 6, 12, -1, -1, 44, 4, -1, 12288, NC, CORE_|_I_|_7 , 0, "Gulftown (Core i7)" }, { 6, 5, -1, -1, 37, 2, -1, 4096, NC, CORE_|_I_|_5 , 0, "Clarkdale (Core i5)" }, { 6, 5, -1, -1, 37, 2, -1, 4096, NC, CORE_|_I_|_3 , 0, "Clarkdale (Core i3)" }, - { 6, 5, -1, -1, 37, 2, -1, -1, NC, PENTIUM_ , 0, "Arrandale" }, { 6, 5, -1, -1, 37, 2, -1, 4096, NC, CORE_|_I_|_7 , 0, "Arrandale (Core i7)" }, { 6, 5, -1, -1, 37, 2, -1, 3072, NC, CORE_|_I_|_5 , 0, "Arrandale (Core i5)" }, { 6, 5, -1, -1, 37, 2, -1, 3072, NC, CORE_|_I_|_3 , 0, "Arrandale (Core i3)" }, + { 6, 5, -1, -1, 37, 2, -1, -1, NC, PENTIUM_ , 0, "Arrandale (Pentium)" }, + { 6, 5, -1, -1, 37, 2, -1, -1, NC, CELERON_ , 0, "Arrandale (Celeron)" }, /* Sandy Bridge CPUs (2nd gen, 32nm): */ { 6, 10, -1, -1, 42, -1, -1, -1, NC, 0 , 0, "Unknown Sandy Bridge" }, @@ -285,7 +289,7 @@ const struct match_entry_t cpudb_intel[] = { { 6, 10, -1, -1, 42, 2, -1, -1, NC, PENTIUM_ , 0, "Sandy Bridge (Pentium)" }, { 6, 10, -1, -1, 42, 1, -1, -1, NC, CELERON_ , 0, "Sandy Bridge (Celeron)" }, { 6, 10, -1, -1, 42, 2, -1, -1, NC, CELERON_ , 0, "Sandy Bridge (Celeron)" }, - { 6, 13, -1, -1, 45, -1, -1, -1, NC, CORE_|_I_|_3 , 0, "Sandy Bridge-E" }, + { 6, 13, -1, -1, 45, -1, -1, -1, NC, CORE_|_I_|_7 , 0, "Sandy Bridge-E (Core i7)" }, { 6, 13, -1, -1, 45, -1, -1, -1, NC, XEON_ , 0, "Sandy Bridge-E (Xeon)" }, /* Ivy Bridge CPUs (3rd gen, 22nm): */ @@ -332,52 +336,58 @@ const struct match_entry_t cpudb_intel[] = { { 6, 15, -1, -1, 79, 2, -1, -1, NC, CORE_|_I_|_7 , 0, "Broadwell-E (Core i7)" }, { 6, 15, -1, -1, 79, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Broadwell-E (Core i7)" }, - /* Skylake CPUs (6th gen, 14nm): */ - { 6, 14, -1, -1, 94, -1, -1, -1, NC, XEON_ , 0, "Skylake (Xeon)" }, - { 6, 14, -1, -1, 94, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Skylake (Core i7)" }, - { 6, 14, -1, -1, 94, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Skylake (Core i5)" }, - { 6, 14, -1, -1, 94, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Skylake (Core i3)" }, - { 6, 14, -1, -1, 94, 2, -1, -1, NC, PENTIUM_ , 0, "Skylake (Pentium)" }, - { 6, 14, -1, -1, 78, 2, -1, -1, NC, PENTIUM_ , 0, "Skylake (Pentium)" }, - { 6, 14, -1, -1, 94, 2, -1, -1, NC, CELERON_ , 0, "Skylake (Celeron)" }, - { 6, 14, -1, -1, 78, 2, -1, -1, NC, CELERON_ , 0, "Skylake (Celeron)" }, - { 6, 14, -1, -1, 78, 2, -1, -1, NC, CORE_|_M_|_7 , 0, "Skylake (Core m7)" }, - { 6, 14, -1, -1, 78, 2, -1, -1, NC, CORE_|_M_|_5 , 0, "Skylake (Core m5)" }, - { 6, 14, -1, -1, 78, 2, -1, -1, NC, CORE_|_M_|_3 , 0, "Skylake (Core m3)" }, - { 6, 5, -1, -1, 85, 8, -1, -1, NC, XEON_, 0, "Skylake (Xeon Scalable)" }, - { 6, 5, -1, -1, 85, -1, -1, -1, NC, CORE_|_I_|_9, 0, "Skylake-X (Core i9)" }, /* 10 to 18 cores */ - { 6, 5, -1, -1, 85, -1, -1, -1, NC, CORE_|_I_|_7, 0, "Skylake-X (Core i7)" }, /* 6 to 8 cores */ + /* Skylake (client) CPUs (2015, 6th Core i gen, 14nm) => https://en.wikichip.org/wiki/intel/microarchitectures/skylake_(client) */ + { 6, 14, -1, -1, 94, -1, -1, -1, NC, XEON_ , 0, "Skylake (Xeon)" }, + { 6, 14, -1, -1, 94, 4, -1, -1, NC, CORE_|_I_|_7 , _6xxx, "Skylake (Core i7)" }, + { 6, 14, -1, -1, 94, 4, -1, -1, NC, CORE_|_I_|_5 , _6xxx, "Skylake (Core i5)" }, + { 6, 14, -1, -1, 94, 2, -1, -1, NC, CORE_|_I_|_3 , _6xxx, "Skylake (Core i3)" }, + { 6, 14, -1, -1, 94, 2, -1, -1, NC, PENTIUM_ , 0, "Skylake (Pentium)" }, + { 6, 14, -1, -1, 78, 2, -1, -1, NC, PENTIUM_ , 0, "Skylake (Pentium)" }, + { 6, 14, -1, -1, 94, 2, -1, -1, NC, CELERON_ , 0, "Skylake (Celeron)" }, + { 6, 14, -1, -1, 78, 2, -1, -1, NC, CELERON_ , 0, "Skylake (Celeron)" }, + { 6, 14, -1, -1, 78, 2, -1, -1, NC, CORE_|_M_|_7 , _6xxx, "Skylake (Core m7)" }, + { 6, 14, -1, -1, 78, 2, -1, -1, NC, CORE_|_M_|_5 , _6xxx, "Skylake (Core m5)" }, + { 6, 14, -1, -1, 78, 2, -1, -1, NC, CORE_|_M_|_3 , _6xxx, "Skylake (Core m3)" }, + /* Skylake (server) CPUs (2017, 1st Xeon Scalable gen, 14nm) => https://en.wikichip.org/wiki/intel/microarchitectures/skylake_(server) */ + { 6, 5, -1, -1, 85, -1, -1, -1, NC, CORE_|_I_|_9 , _6xxx, "Skylake-X (Core i9)" }, /* 10 to 18 cores */ + { 6, 5, -1, -1, 85, -1, -1, -1, NC, CORE_|_I_|_7 , _6xxx, "Skylake-X (Core i7)" }, /* 6 to 8 cores */ + { 6, 5, -1, -1, 85, -1, -1, -1, NC, XEON_|_W_ , _x1xx, "Skylake-W (Xeon W)" }, + { 6, 5, -1, -1, 85, -1, -1, -1, NC, XEON_|_D_ , _x1xx, "Skylake-DE (Xeon D)" }, + { 6, 5, -1, -1, 85, -1, -1, -1, NC, XEON_|_PLATINIUM_, _x1xx, "Skylake-SP (Xeon Platinum)" }, + { 6, 5, -1, -1, 85, -1, -1, -1, NC, XEON_|_GOLD_ , _x1xx, "Skylake-SP (Xeon Gold)" }, + { 6, 5, -1, -1, 85, -1, -1, -1, NC, XEON_|_SILVER_ , _x1xx, "Skylake-SP (Xeon Silver)" }, + { 6, 5, -1, -1, 85, -1, -1, -1, NC, XEON_|_BRONZE_ , _x1xx, "Skylake-SP (Xeon Bronze)" }, /* Kaby Lake CPUs (7th gen, 14nm): */ - { 6, 14, -1, -1, 158, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Kaby Lake (Core i7)" }, - { 6, 14, -1, -1, 158, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Kaby Lake (Core i5)" }, - { 6, 14, -1, -1, 158, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Kaby Lake (Core i3)" }, + { 6, 14, -1, -1, 158, 4, -1, -1, NC, CORE_|_I_|_7 , _7xxx, "Kaby Lake (Core i7)" }, + { 6, 14, -1, -1, 158, 4, -1, -1, NC, CORE_|_I_|_5 , _7xxx, "Kaby Lake (Core i5)" }, + { 6, 14, -1, -1, 158, 2, -1, -1, NC, CORE_|_I_|_3 , _7xxx, "Kaby Lake (Core i3)" }, { 6, 14, -1, -1, 158, 2, -1, -1, NC, PENTIUM_ , 0, "Kaby Lake (Pentium)" }, { 6, 14, -1, -1, 158, 2, -1, -1, NC, CELERON_ , 0, "Kaby Lake (Celeron)" }, - { 6, 14, 9, -1, 142, 2, -1, -1, NC, CORE_|_I_|_7 , 0, "Kaby Lake-U (Core i7)" }, - { 6, 14, 9, -1, 142, 2, -1, -1, NC, CORE_|_I_|_5 , 0, "Kaby Lake-U (Core i5)" }, - { 6, 14, 9, -1, 142, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Kaby Lake-U (Core i3)" }, + { 6, 14, 9, -1, 142, 2, -1, -1, NC, CORE_|_I_|_7 , _7xxx, "Kaby Lake-U (Core i7)" }, + { 6, 14, 9, -1, 142, 2, -1, -1, NC, CORE_|_I_|_5 , _7xxx, "Kaby Lake-U (Core i5)" }, + { 6, 14, 9, -1, 142, 2, -1, -1, NC, CORE_|_I_|_3 , _7xxx, "Kaby Lake-U (Core i3)" }, { 6, 14, 9, -1, 142, 2, -1, -1, NC, PENTIUM_ , 0, "Kaby Lake-U (Pentium)" }, { 6, 14, 9, -1, 142, 2, -1, -1, NC, CELERON_ , 0, "Kaby Lake-U (Celeron)" }, - { 6, 14, 9, -1, 142, 2, -1, -1, NC, CORE_|_M_|_3 , 0, "Kaby Lake-U (Core m3)" }, - { 6, 14, 9, -1, 158, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Kaby Lake-G (Core i7)" }, - { 6, 14, 9, -1, 158, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Kaby Lake-G (Core i5)" }, - { 6, 14, 10, -1, 142, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Kaby Lake-R (Core i7)" }, /* i7-8550U + i7-8650U */ - { 6, 14, 10, -1, 142, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Kaby Lake-R (Core i5)" }, /* i5-8250U + i5-8350U */ + { 6, 14, 9, -1, 142, 2, -1, -1, NC, CORE_|_M_|_3 , _7xxx, "Kaby Lake-U (Core m3)" }, + { 6, 14, 9, -1, 158, 4, -1, -1, NC, CORE_|_I_|_7 , _8xxx, "Kaby Lake-G (Core i7)" }, + { 6, 14, 9, -1, 158, 4, -1, -1, NC, CORE_|_I_|_5 , _8xxx, "Kaby Lake-G (Core i5)" }, + { 6, 14, 10, -1, 142, 4, -1, -1, NC, CORE_|_I_|_7 , _8xxx, "Kaby Lake-R (Core i7)" }, /* i7-8550U + i7-8650U */ + { 6, 14, 10, -1, 142, 4, -1, -1, NC, CORE_|_I_|_5 , _8xxx, "Kaby Lake-R (Core i5)" }, /* i5-8250U + i5-8350U */ /* Coffee Lake CPUs (8th gen, 14nm): */ - { 6, 14, 10, -1, 158, 8, -1, -1, NC, CORE_|_I_|_9 , 0, "Coffee Lake (Core i9)" }, - { 6, 14, 10, -1, 158, 8, -1, -1, NC, CORE_|_I_|_7 , 0, "Coffee Lake (Core i7)" }, - { 6, 14, 10, -1, 158, 6, -1, -1, NC, CORE_|_I_|_7 , 0, "Coffee Lake (Core i7)" }, - { 6, 14, 10, -1, 158, 6, -1, -1, NC, CORE_|_I_|_5 , 0, "Coffee Lake (Core i5)" }, - { 6, 14, 10, -1, 158, 4, -1, -1, NC, CORE_|_I_|_3 , 0, "Coffee Lake (Core i3)" }, + { 6, 14, 10, -1, 158, 8, -1, -1, NC, CORE_|_I_|_9 , _8xxx, "Coffee Lake (Core i9)" }, + { 6, 14, 10, -1, 158, 8, -1, -1, NC, CORE_|_I_|_7 , _8xxx, "Coffee Lake (Core i7)" }, + { 6, 14, 10, -1, 158, 6, -1, -1, NC, CORE_|_I_|_7 , _8xxx, "Coffee Lake (Core i7)" }, + { 6, 14, 10, -1, 158, 6, -1, -1, NC, CORE_|_I_|_5 , _8xxx, "Coffee Lake (Core i5)" }, + { 6, 14, 10, -1, 158, 4, -1, -1, NC, CORE_|_I_|_3 , _8xxx, "Coffee Lake (Core i3)" }, { 6, 14, 10, -1, 158, 2, -1, -1, NC, PENTIUM_ , 0, "Coffee Lake (Pentium)" }, { 6, 14, 10, -1, 158, 2, -1, -1, NC, CELERON_ , 0, "Coffee Lake (Celeron)" }, - { 6, 14, 10, -1, 142, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Coffee Lake-U (Core i7)" }, - { 6, 14, 10, -1, 142, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Coffee Lake-U (Core i5)" }, - { 6, 14, 10, -1, 142, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Coffee Lake-U (Core i3)" }, - { 6, 6, -1, -1, 102, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Cannon Lake (Core i3)" }, /* Core i3 8121U */ - { 6, 6, -1, -1, 102, 2, -1, -1, NC, CORE_|_M_|_3 , 0, "Cannon Lake (Core m3)" }, /* Core m3 8114Y */ + { 6, 14, 10, -1, 142, 4, -1, -1, NC, CORE_|_I_|_7 , _8xxx, "Coffee Lake-U (Core i7)" }, + { 6, 14, 10, -1, 142, 4, -1, -1, NC, CORE_|_I_|_5 , _8xxx, "Coffee Lake-U (Core i5)" }, + { 6, 14, 10, -1, 142, 2, -1, -1, NC, CORE_|_I_|_3 , _8xxx, "Coffee Lake-U (Core i3)" }, + { 6, 6, -1, -1, 102, 2, -1, -1, NC, CORE_|_I_|_3 , _8xxx, "Cannon Lake (Core i3)" }, /* Core i3 8121U */ + { 6, 6, -1, -1, 102, 2, -1, -1, NC, CORE_|_M_|_3 , _8xxx, "Cannon Lake (Core m3)" }, /* Core m3 8114Y */ { 6, 14, 12, -1, 142, 4, -1, -1, NC, CORE_|_I_|_7 , _8xxx, "Whiskey Lake-U (Core i7)" }, { 6, 14, 12, -1, 142, 4, -1, -1, NC, CORE_|_I_|_5 , _8xxx, "Whiskey Lake-U (Core i5)" }, { 6, 14, 12, -1, 142, 2, -1, -1, NC, CORE_|_I_|_3 , _8xxx, "Whiskey Lake-U (Core i3)" }, @@ -385,40 +395,58 @@ const struct match_entry_t cpudb_intel[] = { { 6, 14, 12, -1, 142, 2, -1, -1, NC, CELERON_ , _8xxx, "Whiskey Lake-U (Celeron)" }, /* Coffee Lake Refresh CPUs (9th gen, 14nm): */ - { 6, 14, 13, -1, 158, 8, -1, -1, NC, CORE_|_I_|_9 , 0, "Coffee Lake-R (Core i9)" }, - { 6, 14, 12, -1, 158, 8, -1, -1, NC, CORE_|_I_|_9 , 0, "Coffee Lake-R (Core i9)" }, - { 6, 14, 13, -1, 158, 8, -1, -1, NC, CORE_|_I_|_7 , 0, "Coffee Lake-R (Core i7)" }, - { 6, 14, 12, -1, 158, 8, -1, -1, NC, CORE_|_I_|_7 , 0, "Coffee Lake-R (Core i7)" }, - { 6, 14, 13, -1, 158, 6, -1, -1, NC, CORE_|_I_|_5 , 0, "Coffee Lake-R (Core i5)" }, - { 6, 14, 11, -1, 158, 4, -1, -1, NC, CORE_|_I_|_3 , 0, "Coffee Lake-R (Core i3)" }, + { 6, 14, 13, -1, 158, 8, -1, -1, NC, CORE_|_I_|_9 , _9xxx, "Coffee Lake-R (Core i9)" }, + { 6, 14, 12, -1, 158, 8, -1, -1, NC, CORE_|_I_|_9 , _9xxx, "Coffee Lake-R (Core i9)" }, + { 6, 14, 13, -1, 158, 8, -1, -1, NC, CORE_|_I_|_7 , _9xxx, "Coffee Lake-R (Core i7)" }, + { 6, 14, 12, -1, 158, 8, -1, -1, NC, CORE_|_I_|_7 , _9xxx, "Coffee Lake-R (Core i7)" }, + { 6, 14, 13, -1, 158, 6, -1, -1, NC, CORE_|_I_|_5 , _9xxx, "Coffee Lake-R (Core i5)" }, + { 6, 14, 11, -1, 158, 4, -1, -1, NC, CORE_|_I_|_3 , _9xxx, "Coffee Lake-R (Core i3)" }, + + /* Cascade Lake CPUs (2019, 2nd Xeon Scalable gen, 14nm) => https://en.wikichip.org/wiki/intel/microarchitectures/cascade_lake */ + { 6, 5, 7, -1, 85, -1, -1, -1, NC, CORE_|_I_|_9 , _10xxx, "Cascade Lake-X (Core i9)" }, + { 6, 5, -1, -1, 85, -1, -1, -1, NC, XEON_|_W_ , _x2xx, "Cascade Lake-W (Xeon W)" }, + { 6, 5, -1, -1, 85, -1, -1, -1, NC, XEON_|_PLATINIUM_, _x2xx, "Cascade Lake-SP (Xeon Platinum)" }, + { 6, 5, -1, -1, 85, -1, -1, -1, NC, XEON_|_GOLD_ , _x2xx, "Cascade Lake-SP (Xeon Gold)" }, + { 6, 5, -1, -1, 85, -1, -1, -1, NC, XEON_|_SILVER_ , _x2xx, "Cascade Lake-SP (Xeon Silver)" }, + { 6, 5, -1, -1, 85, -1, -1, -1, NC, XEON_|_BRONZE_ , _x2xx, "Cascade Lake-SP (Xeon Bronze)" }, /* Comet Lake CPUs (10th gen, 14nm): */ - { 6, 5, -1, -1, 165, 10, -1, -1, NC, CORE_|_I_|_9 , 0, "Comet Lake (Core i9)" }, - { 6, 5, -1, -1, 165, 8, -1, -1, NC, CORE_|_I_|_7 , 0, "Comet Lake (Core i7)" }, - { 6, 5, -1, -1, 165, 6, -1, -1, NC, CORE_|_I_|_5 , 0, "Comet Lake (Core i5)" }, - { 6, 5, -1, -1, 165, 4, -1, -1, NC, CORE_|_I_|_3 , 0, "Comet Lake (Core i3)" }, - { 6, 5, -1, -1, 165, 2, -1, -1, NC, PENTIUM_ , 0, "Comet Lake (Pentium)" }, - { 6, 5, -1, -1, 165, 2, -1, -1, NC, CELERON_ , 0, "Comet Lake (Celeron)" }, - { 6, 14, 12, -1, 142, 6, -1, -1, NC, CORE_|_I_|_7 ,_10xxx, "Comet Lake-U (Core i7)" }, - { 6, 14, 12, -1, 142, 4, -1, -1, NC, CORE_|_I_|_7 ,_10xxx, "Comet Lake-U (Core i7)" }, - { 6, 14, 12, -1, 142, 4, -1, -1, NC, CORE_|_I_|_5 ,_10xxx, "Comet Lake-U (Core i5)" }, - { 6, 14, 12, -1, 142, 2, -1, -1, NC, PENTIUM_ ,_10xxx, "Comet Lake-U (Pentium)" }, - { 6, 14, 12, -1, 142, 2, -1, -1, NC, CELERON_ ,_10xxx, "Comet Lake-U (Celeron)" }, - { 6, 12, -1, -1, 108, 4, -1, -1, NC, XEON_ , 0, "Ice Lake (Xeon-D)" }, + { 6, 5, -1, -1, 165, 10, -1, -1, NC, CORE_|_I_|_9, _10xxx, "Comet Lake (Core i9)" }, + { 6, 5, -1, -1, 165, 8, -1, -1, NC, CORE_|_I_|_7, _10xxx, "Comet Lake (Core i7)" }, + { 6, 5, -1, -1, 165, 6, -1, -1, NC, CORE_|_I_|_5, _10xxx, "Comet Lake (Core i5)" }, + { 6, 5, -1, -1, 165, 4, -1, -1, NC, CORE_|_I_|_3, _10xxx, "Comet Lake (Core i3)" }, + { 6, 5, -1, -1, 165, 2, -1, -1, NC, PENTIUM_ , 0, "Comet Lake (Pentium)" }, + { 6, 5, -1, -1, 165, 2, -1, -1, NC, CELERON_ , 0, "Comet Lake (Celeron)" }, + { 6, 14, 12, -1, 142, 6, -1, -1, NC, CORE_|_I_|_7, _10xxx, "Comet Lake-U (Core i7)" }, + { 6, 14, 12, -1, 142, 4, -1, -1, NC, CORE_|_I_|_7, _10xxx, "Comet Lake-U (Core i7)" }, + { 6, 14, 12, -1, 142, 4, -1, -1, NC, CORE_|_I_|_5, _10xxx, "Comet Lake-U (Core i5)" }, + { 6, 14, 12, -1, 142, 2, -1, -1, NC, PENTIUM_ , 0, "Comet Lake-U (Pentium)" }, + { 6, 14, 12, -1, 142, 2, -1, -1, NC, CELERON_ , 0, "Comet Lake-U (Celeron)" }, + + /* Ice Lake (client) CPUs (2019, 10th Core i gen, 10nm) => https://en.wikichip.org/wiki/intel/microarchitectures/ice_lake_(client) */ { 6, 14, -1, -1, 126, 4, -1, -1, NC, CORE_|_I_|_7 ,_10xxx, "Ice Lake (Core i7)" }, { 6, 14, -1, -1, 126, 4, -1, -1, NC, CORE_|_I_|_5 ,_10xxx, "Ice Lake (Core i5)" }, { 6, 14, -1, -1, 126, 2, -1, -1, NC, CORE_|_I_|_3 ,_10xxx, "Ice Lake (Core i3)" }, + /* Ice Lake (server) CPUs (2021, 3rd Xeon Scalable gen, 10nm) => https://en.wikichip.org/wiki/intel/microarchitectures/ice_lake_(server) */ + { 6, 12, -1, -1, 108, 4, -1, -1, NC, XEON_ , 0, "Ice Lake-D (Xeon-D)" }, + { 6, 10, -1, -1, 106, -1, -1, -1, NC, XEON_|_W_ , _x3xx, "Ice Lake-W (Xeon W)" }, + { 6, 10, -1, -1, 106, -1, -1, -1, NC, XEON_|_PLATINIUM_, _x3xx, "Ice Lake-SP (Xeon Platinum)" }, + { 6, 10, -1, -1, 106, -1, -1, -1, NC, XEON_|_GOLD_, _x3xx, "Ice Lake-SP (Xeon Gold)" }, + { 6, 10, -1, -1, 106, -1, -1, -1, NC, XEON_|_SILVER_, _x3xx, "Ice Lake-SP (Xeon Silver)" }, + { 6, 10, -1, -1, 106, -1, -1, -1, NC, XEON_|_BRONZE_, _x3xx, "Ice Lake-SP (Xeon Bronze)" }, /* Rocket Lake CPUs (11th gen, 14nm): */ { 6, 7, -1, -1, 167, -1, -1, -1, NC, CORE_|_I_|_9 ,_11xxx, "Rocket Lake (Core i9)" }, { 6, 7, -1, -1, 167, -1, -1, -1, NC, CORE_|_I_|_7 ,_11xxx, "Rocket Lake (Core i7)" }, { 6, 7, -1, -1, 167, -1, -1, -1, NC, CORE_|_I_|_5 ,_11xxx, "Rocket Lake (Core i5)" }, { 6, 7, -1, -1, 167, -1, -1, -1, NC, CORE_|_I_|_3 ,_11xxx, "Rocket Lake (Core i3)" }, + { 6, 7, -1, -1, 167, -1, -1, -1, NC, XEON_ , 0, "Rocket Lake (Xeon-E)" }, /* Goldmont Plus CPUs (2017, 14nm, low-power) */ { 6, 10, -1, -1, 122, 4, -1, -1, NC, PENTIUM_ , 0, "Gemini Lake (Pentium)" }, { 6, 10, -1, -1, 122, 4, -1, -1, NC, CELERON_ , 0, "Gemini Lake (Celeron)" }, { 6, 10, -1, -1, 122, 2, -1, -1, NC, CELERON_ , 0, "Gemini Lake (Celeron)" }, + { 6, 12, -1, -1, 92, -1, -1, -1, NC, ATOM_ , 0, "Apollo Lake (Atom)" }, /* Tremont CPUs (2020, 10nm, low-power) */ { 6, 6, -1, -1, 150, -1, -1, -1, NC, PENTIUM_ , 0, "Elkhart Lake (Pentium)" }, @@ -438,25 +466,61 @@ const struct match_entry_t cpudb_intel[] = { { 6, 12, -1, -1, 140, 2, -1, -1, NC, CELERON_ , 0, "Tiger Lake (Celeron)" }, /* Alder Lake CPUs (2021, 12th gen, 10nm) => https://en.wikichip.org/wiki/intel/microarchitectures/alder_lake */ - { 6, 7, -1, -1, 151, -1, -1, -1, NC, CORE_|_I_|_9 ,_12xxx, "Alder Lake-S (Core i9)" }, - { 6, 7, -1, -1, 151, -1, -1, -1, NC, CORE_|_I_|_7 ,_12xxx, "Alder Lake-S (Core i7)" }, - { 6, 7, -1, -1, 151, -1, -1, -1, NC, CORE_|_I_|_5 ,_12xxx, "Alder Lake-S (Core i5)" }, - { 6, 7, -1, -1, 151, -1, -1, -1, NC, CORE_|_I_|_3 ,_12xxx, "Alder Lake-S (Core i3)" }, - { 6, 10, -1, -1, 154, -1, -1, -1, NC, CORE_|_I_|_9 ,_12xxx, "Alder Lake-P (Core i9)" }, - { 6, 10, -1, -1, 154, -1, -1, -1, NC, CORE_|_I_|_7 ,_12xxx, "Alder Lake-P (Core i7)" }, - { 6, 10, -1, -1, 154, -1, -1, -1, NC, CORE_|_I_|_5 ,_12xxx, "Alder Lake-P (Core i5)" }, - { 6, 10, -1, -1, 154, -1, -1, -1, NC, CORE_|_I_|_3 ,_12xxx, "Alder Lake-P (Core i3)" }, - - /* Raptor Lake CPUs (2022, 13th gen, 7nm) => https://en.wikichip.org/wiki/intel/microarchitectures/raptor_lake */ - { 6, 7, -1, -1, 183, -1, -1, -1, NC, CORE_|_I_|_9 ,_13xxx, "Raptor Lake-S (Core i9)" }, - { 6, 7, -1, -1, 183, -1, -1, -1, NC, CORE_|_I_|_7 ,_13xxx, "Raptor Lake-S (Core i7)" }, - { 6, 7, -1, -1, 183, -1, -1, -1, NC, CORE_|_I_|_5 ,_13xxx, "Raptor Lake-S (Core i5)" }, - { 6, 7, -1, -1, 183, -1, -1, -1, NC, CORE_|_I_|_3 ,_13xxx, "Raptor Lake-S (Core i3)" }, - //{ 6, ??, -1, -1, ???, -1, -1, -1, NC, CORE_|_I_|_9 ,_13xxx, "Raptor Lake-P (Core i9)" }, - //{ 6, ??, -1, -1, ???, -1, -1, -1, NC, CORE_|_I_|_7 ,_13xxx, "Raptor Lake-P (Core i7)" }, - //{ 6, ??, -1, -1, ???, -1, -1, -1, NC, CORE_|_I_|_5 ,_13xxx, "Raptor Lake-P (Core i5)" }, - //{ 6, ??, -1, -1, ???, -1, -1, -1, NC, CORE_|_I_|_3 ,_13xxx, "Raptor Lake-P (Core i3)" }, - /* F M S EF EM C L2 L3 Brand */ + { 6, 7, -1, -1, 151, -1, -1, -1, NC, CORE_|_I_|_9 , _12xxx, "Alder Lake-S (Core i9)" }, + { 6, 7, -1, -1, 151, -1, -1, -1, NC, CORE_|_I_|_7 , _12xxx, "Alder Lake-S (Core i7)" }, + { 6, 7, -1, -1, 151, -1, -1, -1, NC, CORE_|_I_|_5 , _12xxx, "Alder Lake-S (Core i5)" }, + { 6, 7, -1, -1, 151, -1, -1, -1, NC, CORE_|_I_|_3 , _12xxx, "Alder Lake-S (Core i3)" }, + { 6, 7, -1, -1, 151, -1, -1, -1, NC, PENTIUM_ , 0, "Alder Lake-S (Pentium)" }, + { 6, 7, -1, -1, 151, -1, -1, -1, NC, CELERON_ , 0, "Alder Lake-S (Celeron)" }, + { 6, 7, -1, -1, 151, -1, -1, -1, NC, CORE_|_I_|_9|_H|_X, _12xxx, "Alder Lake-HX (Core i9)" }, + { 6, 7, -1, -1, 151, -1, -1, -1, NC, CORE_|_I_|_7|_H|_X, _12xxx, "Alder Lake-HX (Core i7)" }, + { 6, 7, -1, -1, 151, -1, -1, -1, NC, CORE_|_I_|_5|_H|_X, _12xxx, "Alder Lake-HX (Core i5)" }, + { 6, 10, -1, -1, 154, -1, -1, -1, NC, CORE_|_I_|_7|_P , 0, "Alder Lake-P (Core i7)" }, + { 6, 10, -1, -1, 154, -1, -1, -1, NC, CORE_|_I_|_5|_P , 0, "Alder Lake-P (Core i5)" }, + { 6, 10, -1, -1, 154, -1, -1, -1, NC, CORE_|_I_|_3|_P , 0, "Alder Lake-P (Core i3)" }, + { 6, 10, -1, -1, 154, -1, -1, -1, NC, CORE_|_I_|_7|_U , 0, "Alder Lake-U (Core i7)" }, + { 6, 10, -1, -1, 154, -1, -1, -1, NC, CORE_|_I_|_5|_U , 0, "Alder Lake-U (Core i5)" }, + { 6, 10, -1, -1, 154, -1, -1, -1, NC, CORE_|_I_|_3|_U , 0, "Alder Lake-U (Core i3)" }, + { 6, 10, -1, -1, 154, -1, -1, -1, NC, PENTIUM_ , 0, "Alder Lake-U (Pentium)" }, + { 6, 10, -1, -1, 154, -1, -1, -1, NC, CELERON_ , 0, "Alder Lake-U (Celeron)" }, + { 6, 10, -1, -1, 154, -1, -1, -1, NC, CORE_|_I_|_9|_H , _12xxx, "Alder Lake-H (Core i9)" }, + { 6, 10, -1, -1, 154, -1, -1, -1, NC, CORE_|_I_|_7|_H , _12xxx, "Alder Lake-H (Core i7)" }, + { 6, 10, -1, -1, 154, -1, -1, -1, NC, CORE_|_I_|_5|_H , _12xxx, "Alder Lake-H (Core i5)" }, + { 6, 14, -1, -1, 190, -1, -1, -1, NC, CORE_|_I_|_3|_N , 0, "Alder Lake-N (Core i3)" }, + { 6, 14, -1, -1, 190, -1, -1, -1, NC, ATOM_ , 0, "Alder Lake-N (Atom)" }, + { 6, 14, -1, -1, 190, 4, -1, -1, NC, _N , 0, "Alder Lake-N" }, + { 6, 14, -1, -1, 190, 2, -1, -1, NC, _N , 0, "Alder Lake-N" }, + + /* Raptor Lake CPUs (2022, 13th Core i gen, Intel 7) => https://en.wikichip.org/wiki/intel/microarchitectures/raptor_lake */ + { 6, 15, -1, -1, 191, -1, -1, -1, NC, CORE_|_I_|_5 , _13xxx, "Raptor Lake-S (Core i5)" }, // "Golden Cove" cores + { 6, 15, -1, -1, 191, -1, -1, -1, NC, CORE_|_I_|_3 , _13xxx, "Raptor Lake-S (Core i3)" }, // "Golden Cove" cores + { 6, 7, -1, -1, 183, -1, -1, -1, NC, CORE_|_I_|_9 , _13xxx, "Raptor Lake-S (Core i9)" }, + { 6, 7, -1, -1, 183, -1, -1, -1, NC, CORE_|_I_|_7 , _13xxx, "Raptor Lake-S (Core i7)" }, + { 6, 7, -1, -1, 183, -1, -1, -1, NC, CORE_|_I_|_5 , _13xxx, "Raptor Lake-S (Core i5)" }, + { 6, 7, -1, -1, 183, -1, -1, -1, NC, CORE_|_I_|_3 , _13xxx, "Raptor Lake-S (Core i3)" }, + { 6, 7, -1, -1, 183, -1, -1, -1, NC, CORE_|_I_|_9|_H|_X, _13xxx, "Raptor Lake-HX (Core i9)" }, + { 6, 7, -1, -1, 183, -1, -1, -1, NC, CORE_|_I_|_7|_H|_X, _13xxx, "Raptor Lake-HX (Core i7)" }, + { 6, 7, -1, -1, 183, -1, -1, -1, NC, CORE_|_I_|_5|_H|_X, _13xxx, "Raptor Lake-HX (Core i5)" }, + { 6, 10, 2, -1, 186, -1, -1, -1, NC, CORE_|_I_|_7|_P , 0, "Raptor Lake-P (Core i7)" }, + { 6, 10, 2, -1, 186, -1, -1, -1, NC, CORE_|_I_|_5|_P , 0, "Raptor Lake-P (Core i5)" }, + { 6, 10, 3, -1, 186, -1, -1, -1, NC, CORE_|_I_|_7|_U , 0, "Raptor Lake-U (Core i7)" }, + { 6, 10, 3, -1, 186, -1, -1, -1, NC, CORE_|_I_|_5|_U , 0, "Raptor Lake-U (Core i5)" }, + { 6, 10, 3, -1, 186, -1, -1, -1, NC, CORE_|_I_|_3|_U , 0, "Raptor Lake-U (Core i3)" }, + { 6, 10, -1, -1, 186, -1, -1, -1, NC, CORE_|_I_|_9|_H , _13xxx, "Raptor Lake-H (Core i9)" }, + { 6, 10, -1, -1, 186, -1, -1, -1, NC, CORE_|_I_|_7|_H , _13xxx, "Raptor Lake-H (Core i7)" }, + { 6, 10, -1, -1, 186, -1, -1, -1, NC, CORE_|_I_|_5|_H , _13xxx, "Raptor Lake-H (Core i5)" }, + + /* Sapphire Rapids CPUs (2023, 4th Xeon Scalable gen, Intel 7) => https://en.wikichip.org/wiki/intel/microarchitectures/sapphire_rapids */ + { 6, 15, -1, -1, 143, -1, -1, -1, NC, XEON_|_W_|_9 , _x4xx, "Sapphire Rapids-WS (Xeon w9)" }, + { 6, 15, -1, -1, 143, -1, -1, -1, NC, XEON_|_W_|_7 , _x4xx, "Sapphire Rapids-WS (Xeon w7)" }, + { 6, 15, -1, -1, 143, -1, -1, -1, NC, XEON_|_W_|_5 , _x4xx, "Sapphire Rapids-WS (Xeon w5)" }, + { 6, 15, -1, -1, 143, -1, -1, -1, NC, XEON_|_W_|_3 , _x4xx, "Sapphire Rapids-WS (Xeon w3)" }, + { 6, 15, -1, -1, 143, -1, -1, -1, NC, XEON_|_MAX_ , _x4xx, "Sapphire Rapids-SP (Xeon Max)" }, + { 6, 15, -1, -1, 143, -1, -1, -1, NC, XEON_|_PLATINIUM_, _x4xx, "Sapphire Rapids-SP (Xeon Platinum)" }, + { 6, 15, -1, -1, 143, -1, -1, -1, NC, XEON_|_GOLD_ , _x4xx, "Sapphire Rapids-SP (Xeon Gold)" }, + { 6, 15, -1, -1, 143, -1, -1, -1, NC, XEON_|_SILVER_ , _x4xx, "Sapphire Rapids-SP (Xeon Silver)" }, + { 6, 15, -1, -1, 143, -1, -1, -1, NC, XEON_|_BRONZE_ , _x4xx, "Sapphire Rapids-SP (Xeon Bronze)" }, + /* F M S EF EM #cores L2$ L3$ BC ModelBits ModelCode Name */ /* Itaniums */ @@ -649,35 +713,6 @@ static int decode_intel_extended_topology(struct cpu_raw_data_t* raw, struct cpu return 1; } -static void decode_intel_number_of_cores(struct cpu_raw_data_t* raw, struct cpu_id_t* data) -{ - int logical_cpus = -1, num_cores = -1; - - if (raw->basic_cpuid[0][EAX] >= 11) { - if (decode_intel_extended_topology(raw, data)) return; - } - - if (raw->basic_cpuid[0][EAX] >= 1) { - logical_cpus = (raw->basic_cpuid[1][EBX] >> 16) & 0xff; - if (raw->basic_cpuid[0][EAX] >= 4) { - num_cores = 1 + ((raw->basic_cpuid[4][EAX] >> 26) & 0x3f); - } - } - if (data->flags[CPU_FEATURE_HT]) { - if (num_cores > 1) { - data->num_cores = num_cores; - data->num_logical_cpus = logical_cpus; - } else { - data->num_cores = 1; - data->num_logical_cpus = (logical_cpus >= 1 ? logical_cpus : 1); - if (data->num_logical_cpus == 1) - data->flags[CPU_FEATURE_HT] = 0; - } - } else { - data->num_cores = data->num_logical_cpus = 1; - } -} - static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data) { intel_code_t code = (intel_code_t) NC; @@ -686,6 +721,7 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data) int i = 0; const char* bs = data->brand_str; const char* s; + const size_t n = strlen(bs); const struct { intel_code_t c; const char *search; } matchtable[] = { { PENTIUM_M, "Pentium(R) M" }, { CORE_SOLO, "Pentium(R) Dual CPU" }, @@ -706,6 +742,11 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data) { MOBILE_, "Mobile" }, { CELERON_, "Celeron" }, { PENTIUM_, "Pentium" }, + { _BRONZE_, "Bronze" }, + { _SILVER_, "Silver" }, + { _GOLD_, "Gold" }, + { _PLATINIUM_, "Platinum" }, + { _MAX_, "Max" }, }; for (i = 0; i < COUNT_OF(bit_matchtable); i++) { @@ -726,6 +767,38 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data) case '7': bits |= _7; break; case '9': bits |= _9; break; } + for(i = i + 11; i < n; i++) { + switch (bs[i]) { + case 'H': bits |= _H; break; + case 'K': bits |= _K; break; + case 'N': bits |= _N; break; + case 'P': bits |= _P; break; + case 'S': bits |= _S; break; + case 'U': bits |= _U; break; + case 'X': bits |= _X; break; + } + } + } + else if ((i = match_pattern(bs, "Xeon(R) w[3579]")) != 0) { + bits |= XEON_; + i--; + switch (bs[i + 8]) { + case 'w': bits |= _W_; break; + } + switch (bs[i + 9]) { + case '3': bits |= _3; break; + case '5': bits |= _5; break; + case '7': bits |= _7; break; + case '9': bits |= _9; break; + } + } + else if ((i = match_pattern(bs, "Xeon(R) [DW]")) != 0) { + bits |= XEON_; + i--; + switch (bs[i + 8]) { + case 'D': bits |= _D_; break; + case 'W': bits |= _W_; break; + } } for (i = 0; i < COUNT_OF(matchtable); i++) if (match_pattern(bs, matchtable[i].search)) { @@ -814,6 +887,24 @@ static intel_model_t get_model_code(struct cpu_id_t* data) if (bs[i] == '9') return _9xxx; if ((bs[i] == '1') && (bs[i+1] == '0')) return _10xxx; if ((bs[i] == '1') && (bs[i+1] == '1')) return _11xxx; + if ((bs[i] == '1') && (bs[i+1] == '2')) return _12xxx; + if ((bs[i] == '1') && (bs[i+1] == '3')) return _13xxx; + return UNKNOWN; + } + else if ((i = match_pattern(bs, "Xeon(R) [WBSGP]")) != 0) { + i = 0; + if ((i = match_pattern(bs, "Xeon(R) W-")) != 0) i += 10; + else if ((i == 0) && ((i = match_pattern(bs, "Xeon(R) Bronze")) != 0)) i += 15; + else if ((i == 0) && ((i = match_pattern(bs, "Xeon(R) Silver")) != 0)) i += 15; + else if ((i == 0) && ((i = match_pattern(bs, "Xeon(R) Gold")) != 0)) i += 13; + else if ((i == 0) && ((i = match_pattern(bs, "Xeon(R) Platinum")) != 0)) i += 17; + else if ((i == 0) && ((i = match_pattern(bs, "Xeon(R) Max")) != 0)) i += 12; + + if (i == 0) return UNKNOWN; + if (bs[i] == '1') return _x1xx; + if (bs[i] == '2') return _x2xx; + if (bs[i] == '3') return _x3xx; + if (bs[i] == '4') return _x4xx; return UNKNOWN; } @@ -937,7 +1028,8 @@ int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data, stru } else if (raw->basic_cpuid[0][EAX] >= 2) { decode_intel_oldstyle_cache_info(raw, data); } - decode_intel_number_of_cores(raw, data); + if ((raw->basic_cpuid[0][EAX] < 11) || (decode_intel_extended_topology(raw, data) == 0)) + decode_number_of_cores_x86(raw, data); data->purpose = cpuid_identify_purpose_intel(raw); brand = get_brand_code_and_bits(data); diff --git a/msvc/Libraries/libcpuid/libcpuid.vcxproj b/msvc/Libraries/libcpuid/libcpuid.vcxproj index 87ce52f4..0979f5ca 100644 --- a/msvc/Libraries/libcpuid/libcpuid.vcxproj +++ b/msvc/Libraries/libcpuid/libcpuid.vcxproj @@ -174,15 +174,20 @@ + + + + + diff --git a/msvc/Libraries/libcpuid/libcpuid.vcxproj.filters b/msvc/Libraries/libcpuid/libcpuid.vcxproj.filters index f5587a28..64627e41 100644 --- a/msvc/Libraries/libcpuid/libcpuid.vcxproj.filters +++ b/msvc/Libraries/libcpuid/libcpuid.vcxproj.filters @@ -33,6 +33,9 @@ Quelldateien + + Quelldateien + @@ -56,6 +59,18 @@ Headerdateien + + Headerdateien + + + Headerdateien + + + Headerdateien + + + Headerdateien +