diff --git a/libcpuid/amd_code_t.h b/libcpuid/amd_code_t.h index a742767..2472a3d 100644 --- a/libcpuid/amd_code_t.h +++ b/libcpuid/amd_code_t.h @@ -28,9 +28,7 @@ * 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 AMD products. */ - CODE(NA), - CODE(NO_CODE), - CODE(OPTERON_GENERIC), + CODE2(OPTERON_GENERIC, 1000), CODE(OPTERON_800), CODE(ATHLON_XP), CODE(ATHLON_XP_M), diff --git a/libcpuid/cpuid_main.c b/libcpuid/cpuid_main.c index fa6a5da..9926602 100644 --- a/libcpuid/cpuid_main.c +++ b/libcpuid/cpuid_main.c @@ -24,6 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libcpuid.h" +#include "libcpuid_internal.h" #include "recog_intel.h" #include "recog_amd.h" #include "asm-bits.h" @@ -478,7 +479,7 @@ int cpuid_deserialize_raw_data(struct cpu_raw_data_t* data, const char* filename return set_error(ERR_OK); } -int cpu_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data) +int cpu_ident_internal(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal) { int r; struct cpu_raw_data_t myraw; @@ -492,10 +493,10 @@ int cpu_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data) return set_error(r); switch (data->vendor) { case VENDOR_INTEL: - r = cpuid_identify_intel(raw, data); + r = cpuid_identify_intel(raw, data, internal); break; case VENDOR_AMD: - r = cpuid_identify_amd(raw, data); + r = cpuid_identify_amd(raw, data, internal); break; default: break; @@ -503,6 +504,12 @@ int cpu_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data) return set_error(r); } +int cpu_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data) +{ + struct internal_id_info_t throwaway; + return cpu_ident_internal(raw, data, &throwaway); +} + const char* cpu_feature_str(cpu_feature_t feature) { const struct { cpu_feature_t feature; const char* name; } diff --git a/libcpuid/intel_code_t.h b/libcpuid/intel_code_t.h index a1e0241..f2b95f1 100644 --- a/libcpuid/intel_code_t.h +++ b/libcpuid/intel_code_t.h @@ -28,9 +28,7 @@ * 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 intel products. */ - CODE(NA), - CODE(NO_CODE), - CODE(PENTIUM), + CODE2(PENTIUM, 2000), CODE(MOBILE_PENTIUM), CODE(XEON), diff --git a/libcpuid/libcpuid_internal.h b/libcpuid/libcpuid_internal.h new file mode 100644 index 0000000..9552889 --- /dev/null +++ b/libcpuid/libcpuid_internal.h @@ -0,0 +1,63 @@ +/* + * Copyright 2016 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 __LIBCPUID_INTERNAL_H__ +#define __LIBCPUID_INTERNAL_H__ +/* + * This file contains internal undocumented declarations and function prototypes + * for the workings of the internal library infrastructure. + */ + +enum _common_codes_t { + NA = 0, + NO_CODE, +}; + +#define CODE(x) x +#define CODE2(x, y) x = y +enum _amd_code_t { + #include "amd_code_t.h" +}; +typedef enum _amd_code_t amd_code_t; + +enum _intel_code_t { + #include "intel_code_t.h" +}; +typedef enum _intel_code_t intel_code_t; +#undef CODE +#undef CODE2 + +struct internal_id_info_t { + union { + amd_code_t amd; + intel_code_t intel; + } code; + int score; // detection (matchtable) score +}; + +int cpu_ident_internal(struct cpu_raw_data_t* raw, struct cpu_id_t* data, + struct internal_id_info_t* internal); + +#endif /* __LIBCPUID_INTERNAL_H__ */ diff --git a/libcpuid/libcpuid_util.c b/libcpuid/libcpuid_util.c index c907f5c..dc5f244 100644 --- a/libcpuid/libcpuid_util.c +++ b/libcpuid/libcpuid_util.c @@ -91,7 +91,7 @@ static int score(const struct match_entry_t* entry, const struct cpu_id_t* data, return res; } -void match_cpu_codename(const struct match_entry_t* matchtable, int count, +int match_cpu_codename(const struct match_entry_t* matchtable, int count, struct cpu_id_t* data, int brand_code, int model_code) { int bestscore = -1; @@ -112,6 +112,7 @@ void match_cpu_codename(const struct match_entry_t* matchtable, int count, } } strcpy(data->cpu_codename, matchtable[bestindex].name); + return bestscore; } void generic_get_cpu_list(const struct match_entry_t* matchtable, int count, diff --git a/libcpuid/libcpuid_util.h b/libcpuid/libcpuid_util.h index 34e1efe..22becea 100644 --- a/libcpuid/libcpuid_util.h +++ b/libcpuid/libcpuid_util.h @@ -42,7 +42,8 @@ struct match_entry_t { char name[32]; }; -void match_cpu_codename(const struct match_entry_t* matchtable, int count, +// returns the match score: +int match_cpu_codename(const struct match_entry_t* matchtable, int count, struct cpu_id_t* data, int brand_code, int model_code); void warnf(const char* format, ...) diff --git a/libcpuid/recog_amd.c b/libcpuid/recog_amd.c index c1db973..d50ad97 100644 --- a/libcpuid/recog_amd.c +++ b/libcpuid/recog_amd.c @@ -28,18 +28,13 @@ #include #include #include "libcpuid.h" -#include "recog_amd.h" #include "libcpuid_util.h" - -enum _amd_code_t { - #define CODE(x) x - #include "amd_code_t.h" - #undef CODE -}; -typedef enum _amd_code_t amd_code_t; +#include "libcpuid_internal.h" +#include "recog_amd.h" const struct amd_code_str { amd_code_t code; char *str; } amd_code_str[] = { #define CODE(x) { x, #x } + #define CODE2(x, y) CODE(x) #include "amd_code_t.h" #undef CODE }; @@ -454,7 +449,7 @@ static amd_code_t decode_amd_codename_part1(const char *bs) return NO_CODE; } -static void decode_amd_codename(struct cpu_raw_data_t* raw, struct cpu_id_t* data) +static void decode_amd_codename(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal) { amd_code_t code = decode_amd_codename_part1(data->brand_str); int i = 0; @@ -465,22 +460,22 @@ static void decode_amd_codename(struct cpu_raw_data_t* raw, struct cpu_id_t* dat break; } } + if (code == ATHLON_64_X2 && data->l2_cache < 512) + code = SEMPRON_DUALCORE; if (code_str) debugf(2, "Detected AMD brand code: %d (%s)\n", code, code_str); else debugf(2, "Detected AMD brand code: %d\n", code); - - if (code == ATHLON_64_X2 && data->l2_cache < 512) - code = SEMPRON_DUALCORE; - match_cpu_codename(cpudb_amd, COUNT_OF(cpudb_amd), data, code, 0); + internal->code.amd = code; + internal->score = match_cpu_codename(cpudb_amd, COUNT_OF(cpudb_amd), data, code, 0); } -int cpuid_identify_amd(struct cpu_raw_data_t* raw, struct cpu_id_t* data) +int cpuid_identify_amd(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal) { load_amd_features(raw, data); decode_amd_cache_info(raw, data); decode_amd_number_of_cores(raw, data); - decode_amd_codename(raw, data); + decode_amd_codename(raw, data, internal); return 0; } diff --git a/libcpuid/recog_amd.h b/libcpuid/recog_amd.h index e0f3b61..34e8959 100644 --- a/libcpuid/recog_amd.h +++ b/libcpuid/recog_amd.h @@ -26,7 +26,7 @@ #ifndef __RECOG_AMD_H__ #define __RECOG_AMD_H__ -int cpuid_identify_amd(struct cpu_raw_data_t* raw, struct cpu_id_t* data); +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); #endif /* __RECOG_AMD_H__ */ diff --git a/libcpuid/recog_intel.c b/libcpuid/recog_intel.c index d0a8ebf..bc1c34b 100644 --- a/libcpuid/recog_intel.c +++ b/libcpuid/recog_intel.c @@ -26,19 +26,13 @@ #include #include #include "libcpuid.h" -#include "recog_intel.h" #include "libcpuid_util.h" - - -enum _intel_code_t { - #define CODE(x) x - #include "intel_code_t.h" - #undef CODE -}; -typedef enum _intel_code_t intel_code_t; +#include "libcpuid_internal.h" +#include "recog_intel.h" const struct intel_bcode_str { intel_code_t code; char *str; } intel_bcode_str[] = { #define CODE(x) { x, #x } + #define CODE2(x, y) CODE(x) #include "intel_code_t.h" #undef CODE }; @@ -771,7 +765,7 @@ static intel_model_t get_model_code(struct cpu_id_t* data) #undef HAVE } -int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data) +int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal) { load_intel_features(raw, data); if (raw->basic_cpuid[0][0] >= 4) { @@ -797,8 +791,10 @@ int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data) else debugf(2, "Detected Intel brand code: %d\n", brand_code); debugf(2, "Detected Intel model code: %d\n", model_code); + + internal->code.intel = brand_code; - match_cpu_codename(cpudb_intel, COUNT_OF(cpudb_intel), data, + internal->score = match_cpu_codename(cpudb_intel, COUNT_OF(cpudb_intel), data, brand_code, model_code); return 0; } diff --git a/libcpuid/recog_intel.h b/libcpuid/recog_intel.h index 6727937..b99c783 100644 --- a/libcpuid/recog_intel.h +++ b/libcpuid/recog_intel.h @@ -26,7 +26,7 @@ #ifndef __RECOG_INTEL_H__ #define __RECOG_INTEL_H__ -int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data); +int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal); void cpuid_get_list_intel(struct cpu_list_t* list); #endif /*__RECOG_INTEL_H__*/