diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 328f62e6ea02..9327c0ddc3a5 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -1,6 +1,6 @@ /* * turbostat -- show CPU frequency and C-state residency - * on modern Intel turbo-capable processors. + * on modern Intel and AMD processors. * * Copyright (c) 2013 Intel Corporation. * Len Brown @@ -71,6 +71,8 @@ unsigned int do_irtl_snb; unsigned int do_irtl_hsw; unsigned int units = 1000000; /* MHz etc */ unsigned int genuine_intel; +unsigned int authentic_amd; +unsigned int max_level, max_extended_level; unsigned int has_invariant_tsc; unsigned int do_nhm_platform_info; unsigned int no_MSR_MISC_PWR_MGMT; @@ -1667,30 +1669,51 @@ int get_mp(int cpu, struct msr_counter *mp, unsigned long long *counterp) void get_apic_id(struct thread_data *t) { - unsigned int eax, ebx, ecx, edx, max_level; + unsigned int eax, ebx, ecx, edx; - eax = ebx = ecx = edx = 0; + if (DO_BIC(BIC_APIC)) { + eax = ebx = ecx = edx = 0; + __cpuid(1, eax, ebx, ecx, edx); + + t->apic_id = (ebx >> 24) & 0xff; + } + + if (!DO_BIC(BIC_X2APIC)) + return; + + if (authentic_amd) { + unsigned int topology_extensions; + + if (max_extended_level < 0x8000001e) + return; + + eax = ebx = ecx = edx = 0; + __cpuid(0x80000001, eax, ebx, ecx, edx); + topology_extensions = ecx & (1 << 22); + + if (topology_extensions == 0) + return; + + eax = ebx = ecx = edx = 0; + __cpuid(0x8000001e, eax, ebx, ecx, edx); + + t->x2apic_id = eax; + return; + } if (!genuine_intel) return; - __cpuid(0, max_level, ebx, ecx, edx); - - __cpuid(1, eax, ebx, ecx, edx); - t->apic_id = (ebx >> 24) & 0xf; - if (max_level < 0xb) return; - if (!DO_BIC(BIC_X2APIC)) - return; - ecx = 0; __cpuid(0xb, eax, ebx, ecx, edx); t->x2apic_id = edx; - if (debug && (t->apic_id != t->x2apic_id)) - fprintf(outf, "cpu%d: apic 0x%x x2apic 0x%x\n", t->cpu_id, t->apic_id, t->x2apic_id); + if (debug && (t->apic_id != (t->x2apic_id & 0xff))) + fprintf(outf, "cpu%d: BIOS BUG: apic 0x%x x2apic 0x%x\n", + t->cpu_id, t->apic_id, t->x2apic_id); } /* @@ -1953,11 +1976,12 @@ done: #define PCL_7S 11 /* PC7 Shrink */ #define PCL__8 12 /* PC8 */ #define PCL__9 13 /* PC9 */ -#define PCLUNL 14 /* Unlimited */ +#define PCL_10 14 /* PC10 */ +#define PCLUNL 15 /* Unlimited */ int pkg_cstate_limit = PCLUKN; char *pkg_cstate_limit_strings[] = { "reserved", "unknown", "pc0", "pc1", "pc2", - "pc3", "pc4", "pc6", "pc6n", "pc6r", "pc7", "pc7s", "pc8", "pc9", "unlimited"}; + "pc3", "pc4", "pc6", "pc6n", "pc6r", "pc7", "pc7s", "pc8", "pc9", "pc10", "unlimited"}; int nhm_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCL__3, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; int snb_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCL__7, PCL_7S, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; @@ -1965,7 +1989,7 @@ int hsw_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL__3, PCL__6, PCL__7, PCL_7S, int slv_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7}; int amt_pkg_cstate_limits[16] = {PCLUNL, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; int phi_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; -int bxt_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; +int glm_pkg_cstate_limits[16] = {PCLUNL, PCL__1, PCL__3, PCL__6, PCL__7, PCL_7S, PCL__8, PCL__9, PCL_10, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; int skx_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; @@ -3113,13 +3137,8 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) bclk = discover_bclk(family, model); switch (model) { - case INTEL_FAM6_NEHALEM_EP: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */ case INTEL_FAM6_NEHALEM: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */ - case 0x1F: /* Core i7 and i5 Processor - Nehalem */ - case INTEL_FAM6_WESTMERE: /* Westmere Client - Clarkdale, Arrandale */ - case INTEL_FAM6_WESTMERE_EP: /* Westmere EP - Gulftown */ case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */ - case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */ pkg_cstate_limits = nhm_pkg_cstate_limits; break; case INTEL_FAM6_SANDYBRIDGE: /* SNB */ @@ -3131,16 +3150,11 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) break; case INTEL_FAM6_HASWELL_CORE: /* HSW */ case INTEL_FAM6_HASWELL_X: /* HSX */ - case INTEL_FAM6_HASWELL_ULT: /* HSW */ case INTEL_FAM6_HASWELL_GT3E: /* HSW */ case INTEL_FAM6_BROADWELL_CORE: /* BDW */ case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ case INTEL_FAM6_BROADWELL_X: /* BDX */ - case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ - case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ - case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ - case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ pkg_cstate_limits = hsw_pkg_cstate_limits; has_misc_feature_control = 1; @@ -3159,13 +3173,12 @@ int probe_nhm_msrs(unsigned int family, unsigned int model) no_MSR_MISC_PWR_MGMT = 1; break; case INTEL_FAM6_XEON_PHI_KNL: /* PHI */ - case INTEL_FAM6_XEON_PHI_KNM: pkg_cstate_limits = phi_pkg_cstate_limits; break; case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ case INTEL_FAM6_ATOM_GOLDMONT_PLUS: case INTEL_FAM6_ATOM_GOLDMONT_X: /* DNV */ - pkg_cstate_limits = bxt_pkg_cstate_limits; + pkg_cstate_limits = glm_pkg_cstate_limits; break; default: return 0; @@ -3220,7 +3233,6 @@ int is_bdx(unsigned int family, unsigned int model) switch (model) { case INTEL_FAM6_BROADWELL_X: - case INTEL_FAM6_BROADWELL_XEON_D: return 1; } return 0; @@ -3246,9 +3258,7 @@ int has_turbo_ratio_limit(unsigned int family, unsigned int model) switch (model) { /* Nehalem compatible, but do not include turbo-ratio limit support */ case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */ - case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */ case INTEL_FAM6_XEON_PHI_KNL: /* PHI - Knights Landing (different MSR definition) */ - case INTEL_FAM6_XEON_PHI_KNM: return 0; default: return 1; @@ -3303,7 +3313,6 @@ int has_knl_turbo_ratio_limit(unsigned int family, unsigned int model) switch (model) { case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */ - case INTEL_FAM6_XEON_PHI_KNM: return 1; default: return 0; @@ -3337,21 +3346,15 @@ int has_config_tdp(unsigned int family, unsigned int model) case INTEL_FAM6_IVYBRIDGE: /* IVB */ case INTEL_FAM6_HASWELL_CORE: /* HSW */ case INTEL_FAM6_HASWELL_X: /* HSX */ - case INTEL_FAM6_HASWELL_ULT: /* HSW */ case INTEL_FAM6_HASWELL_GT3E: /* HSW */ case INTEL_FAM6_BROADWELL_CORE: /* BDW */ case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ case INTEL_FAM6_BROADWELL_X: /* BDX */ - case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ - case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ - case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ - case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ case INTEL_FAM6_SKYLAKE_X: /* SKX */ case INTEL_FAM6_XEON_PHI_KNL: /* Knights Landing */ - case INTEL_FAM6_XEON_PHI_KNM: return 1; default: return 0; @@ -3744,9 +3747,7 @@ rapl_dram_energy_units_probe(int model, double rapl_energy_units) switch (model) { case INTEL_FAM6_HASWELL_X: /* HSX */ case INTEL_FAM6_BROADWELL_X: /* BDX */ - case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ case INTEL_FAM6_XEON_PHI_KNL: /* KNL */ - case INTEL_FAM6_XEON_PHI_KNM: return (rapl_dram_energy_units = 15.3 / 1000000); default: return (rapl_energy_units); @@ -3775,7 +3776,6 @@ void rapl_probe(unsigned int family, unsigned int model) case INTEL_FAM6_SANDYBRIDGE: case INTEL_FAM6_IVYBRIDGE: case INTEL_FAM6_HASWELL_CORE: /* HSW */ - case INTEL_FAM6_HASWELL_ULT: /* HSW */ case INTEL_FAM6_HASWELL_GT3E: /* HSW */ case INTEL_FAM6_BROADWELL_CORE: /* BDW */ case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ @@ -3799,9 +3799,6 @@ void rapl_probe(unsigned int family, unsigned int model) BIC_PRESENT(BIC_PkgWatt); break; case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ - case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ - case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ - case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_GFX | RAPL_PKG_POWER_INFO; BIC_PRESENT(BIC_PKG__); @@ -3820,10 +3817,8 @@ void rapl_probe(unsigned int family, unsigned int model) break; case INTEL_FAM6_HASWELL_X: /* HSX */ case INTEL_FAM6_BROADWELL_X: /* BDX */ - case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ case INTEL_FAM6_SKYLAKE_X: /* SKX */ case INTEL_FAM6_XEON_PHI_KNL: /* KNL */ - case INTEL_FAM6_XEON_PHI_KNM: do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO; BIC_PRESENT(BIC_PKG__); BIC_PRESENT(BIC_RAM__); @@ -3916,7 +3911,6 @@ void perf_limit_reasons_probe(unsigned int family, unsigned int model) switch (model) { case INTEL_FAM6_HASWELL_CORE: /* HSW */ - case INTEL_FAM6_HASWELL_ULT: /* HSW */ case INTEL_FAM6_HASWELL_GT3E: /* HSW */ do_gfx_perf_limit_reasons = 1; case INTEL_FAM6_HASWELL_X: /* HSX */ @@ -4128,16 +4122,11 @@ int has_snb_msrs(unsigned int family, unsigned int model) case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */ case INTEL_FAM6_HASWELL_CORE: /* HSW */ case INTEL_FAM6_HASWELL_X: /* HSW */ - case INTEL_FAM6_HASWELL_ULT: /* HSW */ case INTEL_FAM6_HASWELL_GT3E: /* HSW */ case INTEL_FAM6_BROADWELL_CORE: /* BDW */ case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ case INTEL_FAM6_BROADWELL_X: /* BDX */ - case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ - case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ - case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ - case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ case INTEL_FAM6_SKYLAKE_X: /* SKX */ case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ @@ -4166,12 +4155,9 @@ int has_hsw_msrs(unsigned int family, unsigned int model) return 0; switch (model) { - case INTEL_FAM6_HASWELL_ULT: /* HSW */ + case INTEL_FAM6_HASWELL_CORE: case INTEL_FAM6_BROADWELL_CORE: /* BDW */ case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ - case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ - case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ - case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ case INTEL_FAM6_ATOM_GOLDMONT_PLUS: @@ -4195,9 +4181,6 @@ int has_skl_msrs(unsigned int family, unsigned int model) switch (model) { case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ - case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ - case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ - case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ case INTEL_FAM6_CANNONLAKE_MOBILE: /* CNL */ return 1; } @@ -4222,7 +4205,6 @@ int is_knl(unsigned int family, unsigned int model) return 0; switch (model) { case INTEL_FAM6_XEON_PHI_KNL: /* KNL */ - case INTEL_FAM6_XEON_PHI_KNM: return 1; } return 0; @@ -4436,18 +4418,56 @@ void decode_c6_demotion_policy_msr(void) base_cpu, msr, msr & (1 << 0) ? "EN" : "DIS"); } +/* + * When models are the same, for the purpose of turbostat, reuse + */ +unsigned int intel_model_duplicates(unsigned int model) +{ + + switch(model) { + case INTEL_FAM6_NEHALEM_EP: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */ + case INTEL_FAM6_NEHALEM: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */ + case 0x1F: /* Core i7 and i5 Processor - Nehalem */ + case INTEL_FAM6_WESTMERE: /* Westmere Client - Clarkdale, Arrandale */ + case INTEL_FAM6_WESTMERE_EP: /* Westmere EP - Gulftown */ + return INTEL_FAM6_NEHALEM; + + case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */ + case INTEL_FAM6_WESTMERE_EX: /* Westmere-EX Xeon - Eagleton */ + return INTEL_FAM6_NEHALEM_EX; + + case INTEL_FAM6_XEON_PHI_KNM: + return INTEL_FAM6_XEON_PHI_KNL; + + case INTEL_FAM6_HASWELL_ULT: + return INTEL_FAM6_HASWELL_CORE; + + case INTEL_FAM6_BROADWELL_X: + case INTEL_FAM6_BROADWELL_XEON_D: /* BDX-DE */ + return INTEL_FAM6_BROADWELL_X; + + case INTEL_FAM6_SKYLAKE_MOBILE: + case INTEL_FAM6_SKYLAKE_DESKTOP: + case INTEL_FAM6_KABYLAKE_MOBILE: + case INTEL_FAM6_KABYLAKE_DESKTOP: + return INTEL_FAM6_SKYLAKE_MOBILE; + } + return model; +} void process_cpuid() { - unsigned int eax, ebx, ecx, edx, max_level, max_extended_level; - unsigned int fms, family, model, stepping; + unsigned int eax, ebx, ecx, edx; + unsigned int fms, family, model, stepping, ecx_flags, edx_flags; unsigned int has_turbo; eax = ebx = ecx = edx = 0; __cpuid(0, max_level, ebx, ecx, edx); - if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e) + if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69) genuine_intel = 1; + else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65) + authentic_amd = 1; if (!quiet) fprintf(outf, "CPUID(0): %.4s%.4s%.4s ", @@ -4461,25 +4481,8 @@ void process_cpuid() family += (fms >> 20) & 0xff; if (family >= 6) model += ((fms >> 16) & 0xf) << 4; - - if (!quiet) { - fprintf(outf, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n", - max_level, family, model, stepping, family, model, stepping); - fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s %s\n", - ecx & (1 << 0) ? "SSE3" : "-", - ecx & (1 << 3) ? "MONITOR" : "-", - ecx & (1 << 6) ? "SMX" : "-", - ecx & (1 << 7) ? "EIST" : "-", - ecx & (1 << 8) ? "TM2" : "-", - edx & (1 << 4) ? "TSC" : "-", - edx & (1 << 5) ? "MSR" : "-", - edx & (1 << 22) ? "ACPI-TM" : "-", - edx & (1 << 28) ? "HT" : "-", - edx & (1 << 29) ? "TM" : "-"); - } - - if (!(edx & (1 << 5))) - errx(1, "CPUID: no MSR"); + ecx_flags = ecx; + edx_flags = edx; /* * check max extended function levels of CPUID. @@ -4489,6 +4492,27 @@ void process_cpuid() ebx = ecx = edx = 0; __cpuid(0x80000000, max_extended_level, ebx, ecx, edx); + if (!quiet) { + fprintf(outf, "0x%x CPUID levels; 0x%x xlevels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n", + max_level, max_extended_level, family, model, stepping, family, model, stepping); + fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s %s\n", + ecx_flags & (1 << 0) ? "SSE3" : "-", + ecx_flags & (1 << 3) ? "MONITOR" : "-", + ecx_flags & (1 << 6) ? "SMX" : "-", + ecx_flags & (1 << 7) ? "EIST" : "-", + ecx_flags & (1 << 8) ? "TM2" : "-", + edx_flags & (1 << 4) ? "TSC" : "-", + edx_flags & (1 << 5) ? "MSR" : "-", + edx_flags & (1 << 22) ? "ACPI-TM" : "-", + edx_flags & (1 << 28) ? "HT" : "-", + edx_flags & (1 << 29) ? "TM" : "-"); + } + if (genuine_intel) + model = intel_model_duplicates(model); + + if (!(edx_flags & (1 << 5))) + errx(1, "CPUID: no MSR"); + if (max_extended_level >= 0x80000007) { /* @@ -4576,9 +4600,6 @@ void process_cpuid() if (crystal_hz == 0) switch(model) { case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ - case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ - case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ - case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ crystal_hz = 24000000; /* 24.0 MHz */ break; case INTEL_FAM6_ATOM_GOLDMONT_X: /* DNV */ @@ -4860,6 +4881,8 @@ void topology_probe() return; for (i = 0; i <= topo.max_cpu_num; ++i) { + if (cpu_is_not_present(i)) + continue; fprintf(outf, "cpu %d pkg %d node %d lnode %d core %d thread %d\n", i, cpus[i].physical_package_id,