diff --git a/libcpuid/cpuid_main.c b/libcpuid/cpuid_main.c index 504c0af..cb8c573 100644 --- a/libcpuid/cpuid_main.c +++ b/libcpuid/cpuid_main.c @@ -264,6 +264,7 @@ static cpu_vendor_t cpuid_vendor_identify(const uint32_t *raw_vendor, char *vend { VENDOR_RISE , "RiseRiseRise" }, { VENDOR_SIS , "SiS SiS SiS " }, { VENDOR_NSC , "Geode by NSC" }, + { VENDOR_HYGON , "HygonGenuine" }, }; memcpy(vendor_str + 0, &raw_vendor[1], 4); @@ -519,6 +520,7 @@ int cpu_ident_internal(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct r = cpuid_identify_intel(raw, data, internal); break; case VENDOR_AMD: + case VENDOR_HYGON: r = cpuid_identify_amd(raw, data, internal); break; default: @@ -729,6 +731,7 @@ void cpuid_get_cpu_list(cpu_vendor_t vendor, struct cpu_list_t* list) cpuid_get_list_intel(list); break; case VENDOR_AMD: + case VENDOR_HYGON: cpuid_get_list_amd(list); break; case VENDOR_CYRIX: diff --git a/libcpuid/libcpuid.h b/libcpuid/libcpuid.h index 6080c2a..d5c8a9b 100644 --- a/libcpuid/libcpuid.h +++ b/libcpuid/libcpuid.h @@ -110,6 +110,7 @@ typedef enum { VENDOR_RISE, /*!< x86 CPU by Rise Technology */ VENDOR_SIS, /*!< x86 CPU by SiS */ VENDOR_NSC, /*!< x86 CPU by National Semiconductor */ + VENDOR_HYGON, /*!< Hygon CPU */ NUM_CPU_VENDORS, /*!< Valid CPU vendor ids: 0..NUM_CPU_VENDORS - 1 */ VENDOR_UNKNOWN = -1, diff --git a/libcpuid/libcpuid_internal.h b/libcpuid/libcpuid_internal.h index 22bee45..36c99f5 100644 --- a/libcpuid/libcpuid_internal.h +++ b/libcpuid/libcpuid_internal.h @@ -99,6 +99,7 @@ enum _amd_bits_t { _X6 = LBIT( 24 ), _FX = LBIT( 25 ), _APU_ = LBIT( 26 ), + C86_ = LBIT( 27 ), }; typedef enum _amd_bits_t amd_bits_t; diff --git a/libcpuid/rdmsr.c b/libcpuid/rdmsr.c index 385b793..c8e82d8 100644 --- a/libcpuid/rdmsr.c +++ b/libcpuid/rdmsr.c @@ -765,7 +765,7 @@ static double get_info_min_multiplier(struct msr_info_t *info) err = cpu_rdmsr_range(info->handle, MSR_PLATFORM_INFO, 47, 40, ®); if (!err) return (double) reg; } - else if(info->id->vendor == VENDOR_AMD) { + else if(info->id->vendor == VENDOR_AMD || info->id->vendor == VENDOR_HYGON) { /* N.B.: Find the last P-state get_amd_last_pstate_addr() returns the last P-state, MSR_PSTATE_0 <= addr <= MSR_PSTATE_7 */ addr = get_amd_last_pstate_addr(info); @@ -794,7 +794,7 @@ static double get_info_cur_multiplier(struct msr_info_t *info) err = cpu_rdmsr_range(info->handle, IA32_PERF_STATUS, 15, 8, ®); if (!err) return (double) reg; } - else if(info->id->vendor == VENDOR_AMD) { + else if(info->id->vendor == VENDOR_AMD || info->id->vendor == VENDOR_HYGON) { /* Refer links above MSRC001_0063[2:0] is CurPstate */ err = cpu_rdmsr_range(info->handle, MSR_PSTATE_S, 2, 0, ®); @@ -834,7 +834,7 @@ static double get_info_max_multiplier(struct msr_info_t *info) err = cpu_rdmsr_range(info->handle, MSR_TURBO_RATIO_LIMIT, 7, 0, ®); if (!err) return (double) reg; } - else if(info->id->vendor == VENDOR_AMD) { + else if(info->id->vendor == VENDOR_AMD || info->id->vendor == VENDOR_HYGON) { /* Refer links above MSRC001_0064 is Pb0 Pb0 is the highest-performance boosted P-state */ @@ -886,7 +886,7 @@ static double get_info_voltage(struct msr_info_t *info) err = cpu_rdmsr_range(info->handle, MSR_PERF_STATUS, 47, 32, ®); if (!err) return (double) reg / (1 << 13); } - else if(info->id->vendor == VENDOR_AMD) { + else if(info->id->vendor == VENDOR_AMD || info->id->vendor == VENDOR_HYGON) { /* Refer links above MSRC001_00[6B:64][15:9] is CpuVid (Jaguar and before) MSRC001_00[6B:64][21:14] is CpuVid (Zen) @@ -926,7 +926,7 @@ static double get_info_bus_clock(struct msr_info_t *info) err = cpu_rdmsr_range(info->handle, MSR_PLATFORM_INFO, 15, 8, ®); if (!err) return (double) info->cpu_clock / reg; } - else if(info->id->vendor == VENDOR_AMD) { + else if(info->id->vendor == VENDOR_AMD || info->id->vendor == VENDOR_HYGON) { /* Refer links above MSRC001_0061[6:4] is PstateMaxVal PstateMaxVal is the the lowest-performance non-boosted P-state */ @@ -1034,6 +1034,7 @@ int msr_serialize_raw_data(struct msr_driver_t* handle, const char* filename) fprintf(f, "CPU is %s %s, stock clock is %dMHz.\n", id.vendor_str, id.brand_str, cpu_clock_measure(250, 1)); switch (id.vendor) { + case VENDOR_HYGON: case VENDOR_AMD: msr = amd_msr; break; case VENDOR_INTEL: msr = intel_msr; break; default: return set_error(ERR_CPU_UNKN); diff --git a/libcpuid/rdtsc.c b/libcpuid/rdtsc.c index df45439..5e948cc 100644 --- a/libcpuid/rdtsc.c +++ b/libcpuid/rdtsc.c @@ -251,7 +251,7 @@ static void adjust_march_ic_multiplier(const struct cpu_id_t* id, int* numerator } // // Bulldozer or later: assume 1.4 IPC - if (id->vendor == VENDOR_AMD && id->ext_family >= 21) { + if ((id->vendor == VENDOR_AMD && id->ext_family >= 21) || (id->vendor == VENDOR_HYGON)) { debugf(1, "cpu_clock_by_ic: Bulldozer (or later) detected, dividing result by 1.4\n"); *numerator = 5; *denom = 7; // multiply by 5/7, to divide by 1.4 diff --git a/libcpuid/recog_amd.c b/libcpuid/recog_amd.c index 52c6120..41d9b73 100644 --- a/libcpuid/recog_amd.c +++ b/libcpuid/recog_amd.c @@ -279,6 +279,10 @@ const struct match_entry_t cpudb_amd[] = { { 15, -1, -1, 23, 8, -1, -1, -1, NC, RYZEN_|_5 , 0, "Ryzen 5 (Pinnacle Ridge)" }, { 15, -1, -1, 23, 8, -1, -1, -1, NC, RYZEN_|_3 , 0, "Ryzen 3 (Pinnacle Ridge)" }, + { 15, -1, -1, 24, 0, -1, -1, -1, NC, C86_|_7 , 0, "C86 7 (Dhyana)" }, + { 15, -1, -1, 24, 0, -1, -1, -1, NC, C86_|_5 , 0, "C86 5 (Dhyana)" }, + { 15, -1, -1, 24, 0, -1, -1, -1, NC, C86_|_3 , 0, "C86 3 (Dhyana)" }, + /* Newer Opterons: */ { 15, 9, -1, 22, 9, 8, -1, -1, NC, OPTERON_ , 0, "Magny-Cours Opteron" }, @@ -459,6 +463,7 @@ static struct amd_code_and_bits_t decode_amd_codename_part1(const char *bs) { _APU_, " APU " }, { EPYC_, "EPYC" }, { RYZEN_TR_, "Ryzen Threadripper" }, + { C86_, "C86" }, }; for (i = 0; i < COUNT_OF(bit_matchtable); i++) { @@ -478,6 +483,16 @@ static struct amd_code_and_bits_t decode_amd_codename_part1(const char *bs) } } + if ((i = match_pattern(bs, "C86 [357]")) != 0) { + bits |= C86_; + i--; + switch (bs[i + 6]) { + case '3': bits |= _3; break; + case '5': bits |= _5; break; + case '7': bits |= _7; break; + } + } + for (i = 0; i < COUNT_OF(code_matchtable); i++) if (match_pattern(bs, code_matchtable[i].search)) { code = code_matchtable[i].c; diff --git a/tests/hygon/dhyana/dhyana_7.test b/tests/hygon/dhyana/dhyana_7.test new file mode 100644 index 0000000..54ff579 --- /dev/null +++ b/tests/hygon/dhyana/dhyana_7.test @@ -0,0 +1,100 @@ +basic_cpuid[0]=0000000d 6f677948 656e6975 6e65476e +basic_cpuid[1]=00900f01 3e400800 7cd83209 178bfbff +basic_cpuid[2]=00000000 00000000 00000000 00000000 +basic_cpuid[3]=00000000 00000000 00000000 00000000 +basic_cpuid[4]=00000000 00000000 00000000 00000000 +basic_cpuid[5]=00000040 00000040 00000003 00000011 +basic_cpuid[6]=00000004 00000000 00000001 00000000 +basic_cpuid[7]=00000000 009c01a9 00000000 00000000 +basic_cpuid[8]=00000000 00000000 00000000 00000000 +basic_cpuid[9]=00000000 00000000 00000000 00000000 +basic_cpuid[10]=00000000 00000000 00000000 00000000 +basic_cpuid[11]=00000000 00000000 00000000 00000000 +basic_cpuid[12]=00000000 00000000 00000000 00000000 +basic_cpuid[13]=00000007 00000340 00000340 00000000 +basic_cpuid[14]=00000000 00000000 00000000 00000000 +basic_cpuid[15]=00000000 00000000 00000000 00000000 +basic_cpuid[16]=00000000 00000000 00000000 00000000 +basic_cpuid[17]=00000000 00000000 00000000 00000000 +basic_cpuid[18]=00000000 00000000 00000000 00000000 +basic_cpuid[19]=00000000 00000000 00000000 00000000 +basic_cpuid[20]=00000000 00000000 00000000 00000000 +basic_cpuid[21]=00000000 00000000 00000000 00000000 +basic_cpuid[22]=00000000 00000000 00000000 00000000 +basic_cpuid[23]=00000000 00000000 00000000 00000000 +basic_cpuid[24]=00000000 00000000 00000000 00000000 +basic_cpuid[25]=00000000 00000000 00000000 00000000 +basic_cpuid[26]=00000000 00000000 00000000 00000000 +basic_cpuid[27]=00000000 00000000 00000000 00000000 +basic_cpuid[28]=00000000 00000000 00000000 00000000 +basic_cpuid[29]=00000000 00000000 00000000 00000000 +basic_cpuid[30]=00000000 00000000 00000000 00000000 +basic_cpuid[31]=00000000 00000000 00000000 00000000 +ext_cpuid[0]=8000001f 6f677948 656e6975 6e65476e +ext_cpuid[1]=00900f01 40000000 35c233ff 2fd3fbff +ext_cpuid[2]=6f677948 3843206e 31372036 33203538 +ext_cpuid[3]=6f632d32 50206572 65636f72 726f7373 +ext_cpuid[4]=20202020 20202020 20202020 00202020 +ext_cpuid[5]=ff40ff40 ff40ff40 20080140 40040140 +ext_cpuid[6]=36006400 56006400 02006140 0200c140 +ext_cpuid[7]=00000000 0000001b 00000000 00006599 +ext_cpuid[8]=00003030 00001007 0000603f 00000000 +ext_cpuid[9]=00000000 00000000 00000000 00000000 +ext_cpuid[10]=00000001 00008000 00000000 0001bcff +ext_cpuid[11]=00000000 00000000 00000000 00000000 +ext_cpuid[12]=00000000 00000000 00000000 00000000 +ext_cpuid[13]=00000000 00000000 00000000 00000000 +ext_cpuid[14]=00000000 00000000 00000000 00000000 +ext_cpuid[15]=00000000 00000000 00000000 00000000 +ext_cpuid[16]=00000000 00000000 00000000 00000000 +ext_cpuid[17]=00000000 00000000 00000000 00000000 +ext_cpuid[18]=00000000 00000000 00000000 00000000 +ext_cpuid[19]=00000000 00000000 00000000 00000000 +ext_cpuid[20]=00000000 00000000 00000000 00000000 +ext_cpuid[21]=00000000 00000000 00000000 00000000 +ext_cpuid[22]=00000000 00000000 00000000 00000000 +ext_cpuid[23]=00000000 00000000 00000000 00000000 +ext_cpuid[24]=00000000 00000000 00000000 00000000 +ext_cpuid[25]=f040f040 00000000 00000000 00000000 +ext_cpuid[26]=00000003 00000000 00000000 00000000 +ext_cpuid[27]=000003ff 00000000 00000000 00000000 +ext_cpuid[28]=00000000 00000000 00000000 00000000 +ext_cpuid[29]=00004121 01c0003f 0000003f 00000000 +ext_cpuid[30]=0000003e 0000011f 00000303 00000000 +ext_cpuid[31]=00000000 00000000 00000000 00000000 +intel_fn4[0]=00000000 00000000 00000000 00000000 +intel_fn4[1]=00000000 00000000 00000000 00000000 +intel_fn4[2]=00000000 00000000 00000000 00000000 +intel_fn4[3]=00000000 00000000 00000000 00000000 +intel_fn4[4]=00000000 00000000 00000000 00000000 +intel_fn4[5]=00000000 00000000 00000000 00000000 +intel_fn4[6]=00000000 00000000 00000000 00000000 +intel_fn4[7]=00000000 00000000 00000000 00000000 +intel_fn11[0]=00000000 00000000 00000000 00000000 +intel_fn11[1]=00000000 00000000 00000000 00000000 +intel_fn11[2]=00000000 00000000 00000000 00000000 +intel_fn11[3]=00000000 00000000 00000000 00000000 +-------------------------------------------------------------------------------- +15 +0 +1 +24 +0 +32 +64 +32 +64 +512 +65536 +-1 +8 +8 +64 +-1 +64 +64 +64 +-1 +128 (authoritative) +C86 7 (Dhyana) +fpu vme de pse tsc msr pae mce cx8 apic mtrr sep pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht pni monitor ssse3 cx16 sse4_1 sse4_2 syscall movbe popcnt xsave osxsave avx mmxext nx fxsr_opt rdtscp lm lahf_lm cmp_legacy svm abm misalignsse sse4a 3dnowprefetch osvw skinit wdt ts ttp tm_amd hwpstate constant_tsc fma3 f16c rdrand aperfmperf avx2 bmi1 bmi2