From 786a5bda7d66550556369f3ab70240e5931fefb7 Mon Sep 17 00:00:00 2001 From: Veselin Georgiev Date: Fri, 14 Nov 2008 16:41:18 +0000 Subject: [PATCH] AMD feature support. All features now detected. Needs testing. Feature consistency script expanded git-svn-id: https://svn.code.sf.net/p/libcpuid/code/HEAD/libcpuid@9 3b4be424-7ac5-41d7-8526-f4ddcb85d872 --- libcpuid/check-consistency.py | 24 ++++++++++++++++++++++++ libcpuid/cpuid_main.c | 10 +++++++++- libcpuid/libcpuid.h | 4 ++-- libcpuid/recog_amd.c | 35 +++++++++++++++++++++++++++++++++++ libcpuid/recog_intel.c | 19 +++++++++++++------ 5 files changed, 83 insertions(+), 9 deletions(-) diff --git a/libcpuid/check-consistency.py b/libcpuid/check-consistency.py index 9b212bd..d81e136 100755 --- a/libcpuid/check-consistency.py +++ b/libcpuid/check-consistency.py @@ -46,3 +46,27 @@ f.close() for feature in allf: if not feature in impf: print "cpu_feature_str(): don't have entry for %s" % feature + +# Check whether all features have detection code: + +files_code = {} + +rexp = re.compile('.*{ *[0-9]+, (CPU_FEATURE_[^ }]+).*') + +for fn in glob.glob("%s/*.c" % sys.argv[1]): + f = open(fn, "rt") + files_code[fn] = [] + for s in f.readlines(): + if rexp.match(s): + entry = rexp.findall(s)[0] + files_code[fn].append(entry) + +for feature in allf: + matching_files = [] + for fn in files_code: + if feature in files_code[fn]: + matching_files.append(fn) + if len(matching_files) == 0: + print "No detection code for %s" % feature + if len(matching_files) > 1: + print "Conflicting detection code for %s in files %s" % (feature, " and ".join(matching_files)) diff --git a/libcpuid/cpuid_main.c b/libcpuid/cpuid_main.c index a6bf13f..78f7bc0 100644 --- a/libcpuid/cpuid_main.c +++ b/libcpuid/cpuid_main.c @@ -150,6 +150,7 @@ static void load_features_common(struct cpu_raw_data_t* raw, struct cpu_id_t* da { 7, CPU_FEATURE_MCE }, { 8, CPU_FEATURE_CX8 }, { 9, CPU_FEATURE_APIC }, + { 11, CPU_FEATURE_SEP }, { 12, CPU_FEATURE_MTRR }, { 13, CPU_FEATURE_PGE }, { 14, CPU_FEATURE_MCA }, @@ -169,12 +170,17 @@ static void load_features_common(struct cpu_raw_data_t* raw, struct cpu_id_t* da { 9, CPU_FEATURE_SSSE3 }, { 13, CPU_FEATURE_CX16 }, { 19, CPU_FEATURE_SSE4_1 }, + { 23, CPU_FEATURE_POPCNT }, }; const struct feature_map_t matchtable_edx81[] = { + { 11, CPU_FEATURE_SYSCALL }, { 29, CPU_FEATURE_LM }, }; const struct feature_map_t matchtable_ecx81[] = { - { 0, CPU_FEATURE_LAHF_LM }, + { 0, CPU_FEATURE_LAHF_LM }, + }; + const struct feature_map_t matchtable_edx87[] = { + { 8, CPU_FEATURE_CONSTANT_TSC }, }; if (raw->basic_cpuid[0][0] >= 1) { match_features(matchtable_edx1, COUNT_OF(matchtable_edx1), raw->basic_cpuid[1][3], data); @@ -184,6 +190,8 @@ static void load_features_common(struct cpu_raw_data_t* raw, struct cpu_id_t* da match_features(matchtable_edx81, COUNT_OF(matchtable_edx81), raw->ext_cpuid[1][3], data); match_features(matchtable_ecx81, COUNT_OF(matchtable_ecx81), raw->ext_cpuid[1][2], data); } + if (raw->ext_cpuid[0][0] >= 7) + match_features(matchtable_edx87, COUNT_OF(matchtable_edx87), raw->ext_cpuid[7][3], data); } static int cpuid_basic_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data) diff --git a/libcpuid/libcpuid.h b/libcpuid/libcpuid.h index ebffc48..279cce6 100644 --- a/libcpuid/libcpuid.h +++ b/libcpuid/libcpuid.h @@ -286,9 +286,9 @@ enum _cpu_feature_t { CPU_FEATURE_LM, /*!< Long mode (x86_64/EM64T) supported */ CPU_FEATURE_LAHF_LM, /*!< LAHF/SAHF supported in 64-bit mode */ CPU_FEATURE_SVM, /*!< AMD Secure virtual machine */ - CPU_FEATURE_SSE4A, /*!< SSE 4a from AMD */ - CPU_FEATURE_MISALIGNSSE,/*!< Misaligned SSE supported */ CPU_FEATURE_ABM, /*!< LZCNT instruction support */ + CPU_FEATURE_MISALIGNSSE,/*!< Misaligned SSE supported */ + CPU_FEATURE_SSE4A, /*!< SSE 4a from AMD */ CPU_FEATURE_3DNOWPREFETCH, /*!< PREFETCH/PREFETCHW support */ CPU_FEATURE_OSVW, /*!< OS Visible Workaround (AMD) */ CPU_FEATURE_IBS, /*!< Instruction-based sampling */ diff --git a/libcpuid/recog_amd.c b/libcpuid/recog_amd.c index ce07a2a..4017154 100644 --- a/libcpuid/recog_amd.c +++ b/libcpuid/recog_amd.c @@ -23,10 +23,45 @@ * (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 "libcpuid.h" #include "recog_amd.h" +#include "libcpuid_util.h" + +/* +*/ + +static void load_amd_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data) +{ + const struct feature_map_t matchtable_edx81[] = { + { 20, CPU_FEATURE_NX }, + { 22, CPU_FEATURE_MMXEXT }, + { 27, CPU_FEATURE_RDTSCP }, + { 30, CPU_FEATURE_3DNOWEXT }, + { 31, CPU_FEATURE_3DNOW }, + }; + const struct feature_map_t matchtable_ecx81[] = { + { 2, CPU_FEATURE_SVM }, + { 5, CPU_FEATURE_ABM }, + { 6, CPU_FEATURE_SSE4A }, + { 7, CPU_FEATURE_MISALIGNSSE }, + { 8, CPU_FEATURE_3DNOWPREFETCH }, + { 9, CPU_FEATURE_OSVW }, + { 10, CPU_FEATURE_IBS }, + { 11, CPU_FEATURE_SSE5 }, + { 12, CPU_FEATURE_SKINIT }, + { 13, CPU_FEATURE_WDT }, + }; + if (raw->ext_cpuid[0][0] >= 1) { + match_features(matchtable_edx81, COUNT_OF(matchtable_edx81), raw->ext_cpuid[1][3], data); + match_features(matchtable_ecx81, COUNT_OF(matchtable_ecx81), raw->ext_cpuid[1][2], data); + } +} + + int cpuid_identify_amd(struct cpu_raw_data_t* raw, struct cpu_id_t* data) { + load_amd_features(raw, data); return 0; } diff --git a/libcpuid/recog_intel.c b/libcpuid/recog_intel.c index d05ae00..dfe9f7d 100644 --- a/libcpuid/recog_intel.c +++ b/libcpuid/recog_intel.c @@ -183,7 +183,6 @@ const struct match_entry_t cpudb_intel[] = { static void load_intel_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data) { const struct feature_map_t matchtable_edx1[] = { - { 11, CPU_FEATURE_SEP }, { 18, CPU_FEATURE_PN }, { 21, CPU_FEATURE_DTS }, { 22, CPU_FEATURE_ACPI }, @@ -194,7 +193,7 @@ static void load_intel_features(struct cpu_raw_data_t* raw, struct cpu_id_t* dat }; const struct feature_map_t matchtable_ecx1[] = { { 1, CPU_FEATURE_PCLMUL }, - { 2, CPU_FEATURE_SVM }, + { 2, CPU_FEATURE_DTS64 }, { 4, CPU_FEATURE_DS_CPL }, { 5, CPU_FEATURE_VMX }, { 6, CPU_FEATURE_SMX }, @@ -205,14 +204,22 @@ static void load_intel_features(struct cpu_raw_data_t* raw, struct cpu_id_t* dat { 15, CPU_FEATURE_PDCM }, { 18, CPU_FEATURE_DCA }, { 20, CPU_FEATURE_SSE4_2 }, + { 22, CPU_FEATURE_MOVBE }, + { 25, CPU_FEATURE_AES }, + { 26, CPU_FEATURE_XSAVE }, + { 27, CPU_FEATURE_OSXSAVE }, + { 28, CPU_FEATURE_AVX }, }; const struct feature_map_t matchtable_edx81[] = { - { 11, CPU_FEATURE_SYSCALL }, { 20, CPU_FEATURE_XD }, }; - match_features(matchtable_edx1, COUNT_OF(matchtable_edx1), raw->basic_cpuid[1][3], data); - match_features(matchtable_ecx1, COUNT_OF(matchtable_ecx1), raw->basic_cpuid[1][2], data); - match_features(matchtable_edx81, COUNT_OF(matchtable_edx81), raw->ext_cpuid[1][3], data); + if (raw->basic_cpuid[0][0] >= 1) { + match_features(matchtable_edx1, COUNT_OF(matchtable_edx1), raw->basic_cpuid[1][3], data); + match_features(matchtable_ecx1, COUNT_OF(matchtable_ecx1), raw->basic_cpuid[1][2], data); + } + if (raw->ext_cpuid[0][0] >= 1) { + match_features(matchtable_edx81, COUNT_OF(matchtable_edx81), raw->ext_cpuid[1][3], data); + } } enum _cache_type_t {