aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-20 16:25:04 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-20 16:25:04 -0500
commit82023bb7f75b0052f40d3e74169d191c3e4e6286 (patch)
tree06ad7f507852adf41a2ca33d5cb7100faeaf8499 /tools
parente6d69a60b77a6ea8d5f9d41765c7571bb8d45531 (diff)
parented6a82546d2e8f6b5902269541733814d4adacc2 (diff)
Merge tag 'pm+acpi-2-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull more ACPI and power management updates from Rafael Wysocki: - ACPI-based device hotplug fixes for issues introduced recently and a fix for an older error code path bug in the ACPI PCI host bridge driver - Fix for recently broken OMAP cpufreq build from Viresh Kumar - Fix for a recent hibernation regression related to s2disk - Fix for a locking-related regression in the ACPI EC driver from Puneet Kumar - System suspend error code path fix related to runtime PM and runtime PM documentation update from Ulf Hansson - cpufreq's conservative governor fix from Xiaoguang Chen - New processor IDs for intel_idle and turbostat and removal of an obsolete Kconfig option from Len Brown - New device IDs for the ACPI LPSS (Low-Power Subsystem) driver and ACPI-based PCI hotplug (ACPIPHP) cleanup from Mika Westerberg - Removal of several ACPI video DMI blacklist entries that are not necessary any more from Aaron Lu - Rework of the ACPI companion representation in struct device and code cleanup related to that change from Rafael J Wysocki, Lan Tianyu and Jarkko Nikula - Fixes for assigning names to ACPI-enumerated I2C and SPI devices from Jarkko Nikula * tag 'pm+acpi-2-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (24 commits) PCI / hotplug / ACPI: Drop unused acpiphp_debug declaration ACPI / scan: Set flags.match_driver in acpi_bus_scan_fixed() ACPI / PCI root: Clear driver_data before failing enumeration ACPI / hotplug: Fix PCI host bridge hot removal ACPI / hotplug: Fix acpi_bus_get_device() return value check cpufreq: governor: Remove fossil comment in the cpufreq_governor_dbs() ACPI / video: clean up DMI table for initial black screen problem ACPI / EC: Ensure lock is acquired before accessing ec struct members PM / Hibernate: Do not crash kernel in free_basic_memory_bitmaps() ACPI / AC: Remove struct acpi_device pointer from struct acpi_ac spi: Use stable dev_name for ACPI enumerated SPI slaves i2c: Use stable dev_name for ACPI enumerated I2C slaves ACPI: Provide acpi_dev_name accessor for struct acpi_device device name ACPI / bind: Use (put|get)_device() on ACPI device objects too ACPI: Eliminate the DEVICE_ACPI_HANDLE() macro ACPI / driver core: Store an ACPI device pointer in struct acpi_dev_node cpufreq: OMAP: Fix compilation error 'r & ret undeclared' PM / Runtime: Fix error path for prepare PM / Runtime: Update documentation around probe|remove|suspend cpufreq: conservative: set requested_freq to policy max when it is over policy max ...
Diffstat (limited to 'tools')
-rw-r--r--tools/power/x86/turbostat/turbostat.c197
1 files changed, 141 insertions, 56 deletions
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index fe702076ca46..9d77f13c2d25 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -2,7 +2,7 @@
2 * turbostat -- show CPU frequency and C-state residency 2 * turbostat -- show CPU frequency and C-state residency
3 * on modern Intel turbo-capable processors. 3 * on modern Intel turbo-capable processors.
4 * 4 *
5 * Copyright (c) 2012 Intel Corporation. 5 * Copyright (c) 2013 Intel Corporation.
6 * Len Brown <len.brown@intel.com> 6 * Len Brown <len.brown@intel.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
@@ -47,6 +47,8 @@ unsigned int skip_c1;
47unsigned int do_nhm_cstates; 47unsigned int do_nhm_cstates;
48unsigned int do_snb_cstates; 48unsigned int do_snb_cstates;
49unsigned int do_c8_c9_c10; 49unsigned int do_c8_c9_c10;
50unsigned int do_slm_cstates;
51unsigned int use_c1_residency_msr;
50unsigned int has_aperf; 52unsigned int has_aperf;
51unsigned int has_epb; 53unsigned int has_epb;
52unsigned int units = 1000000000; /* Ghz etc */ 54unsigned int units = 1000000000; /* Ghz etc */
@@ -81,6 +83,8 @@ double rapl_joule_counter_range;
81#define RAPL_DRAM (1 << 3) 83#define RAPL_DRAM (1 << 3)
82#define RAPL_PKG_PERF_STATUS (1 << 4) 84#define RAPL_PKG_PERF_STATUS (1 << 4)
83#define RAPL_DRAM_PERF_STATUS (1 << 5) 85#define RAPL_DRAM_PERF_STATUS (1 << 5)
86#define RAPL_PKG_POWER_INFO (1 << 6)
87#define RAPL_CORE_POLICY (1 << 7)
84#define TJMAX_DEFAULT 100 88#define TJMAX_DEFAULT 100
85 89
86#define MAX(a, b) ((a) > (b) ? (a) : (b)) 90#define MAX(a, b) ((a) > (b) ? (a) : (b))
@@ -96,7 +100,7 @@ struct thread_data {
96 unsigned long long tsc; 100 unsigned long long tsc;
97 unsigned long long aperf; 101 unsigned long long aperf;
98 unsigned long long mperf; 102 unsigned long long mperf;
99 unsigned long long c1; /* derived */ 103 unsigned long long c1;
100 unsigned long long extra_msr64; 104 unsigned long long extra_msr64;
101 unsigned long long extra_delta64; 105 unsigned long long extra_delta64;
102 unsigned long long extra_msr32; 106 unsigned long long extra_msr32;
@@ -266,7 +270,7 @@ void print_header(void)
266 outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset64); 270 outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset64);
267 if (do_nhm_cstates) 271 if (do_nhm_cstates)
268 outp += sprintf(outp, " %%c1"); 272 outp += sprintf(outp, " %%c1");
269 if (do_nhm_cstates) 273 if (do_nhm_cstates && !do_slm_cstates)
270 outp += sprintf(outp, " %%c3"); 274 outp += sprintf(outp, " %%c3");
271 if (do_nhm_cstates) 275 if (do_nhm_cstates)
272 outp += sprintf(outp, " %%c6"); 276 outp += sprintf(outp, " %%c6");
@@ -280,9 +284,9 @@ void print_header(void)
280 284
281 if (do_snb_cstates) 285 if (do_snb_cstates)
282 outp += sprintf(outp, " %%pc2"); 286 outp += sprintf(outp, " %%pc2");
283 if (do_nhm_cstates) 287 if (do_nhm_cstates && !do_slm_cstates)
284 outp += sprintf(outp, " %%pc3"); 288 outp += sprintf(outp, " %%pc3");
285 if (do_nhm_cstates) 289 if (do_nhm_cstates && !do_slm_cstates)
286 outp += sprintf(outp, " %%pc6"); 290 outp += sprintf(outp, " %%pc6");
287 if (do_snb_cstates) 291 if (do_snb_cstates)
288 outp += sprintf(outp, " %%pc7"); 292 outp += sprintf(outp, " %%pc7");
@@ -480,7 +484,7 @@ int format_counters(struct thread_data *t, struct core_data *c,
480 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) 484 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
481 goto done; 485 goto done;
482 486
483 if (do_nhm_cstates) 487 if (do_nhm_cstates && !do_slm_cstates)
484 outp += sprintf(outp, " %6.2f", 100.0 * c->c3/t->tsc); 488 outp += sprintf(outp, " %6.2f", 100.0 * c->c3/t->tsc);
485 if (do_nhm_cstates) 489 if (do_nhm_cstates)
486 outp += sprintf(outp, " %6.2f", 100.0 * c->c6/t->tsc); 490 outp += sprintf(outp, " %6.2f", 100.0 * c->c6/t->tsc);
@@ -499,9 +503,9 @@ int format_counters(struct thread_data *t, struct core_data *c,
499 503
500 if (do_snb_cstates) 504 if (do_snb_cstates)
501 outp += sprintf(outp, " %6.2f", 100.0 * p->pc2/t->tsc); 505 outp += sprintf(outp, " %6.2f", 100.0 * p->pc2/t->tsc);
502 if (do_nhm_cstates) 506 if (do_nhm_cstates && !do_slm_cstates)
503 outp += sprintf(outp, " %6.2f", 100.0 * p->pc3/t->tsc); 507 outp += sprintf(outp, " %6.2f", 100.0 * p->pc3/t->tsc);
504 if (do_nhm_cstates) 508 if (do_nhm_cstates && !do_slm_cstates)
505 outp += sprintf(outp, " %6.2f", 100.0 * p->pc6/t->tsc); 509 outp += sprintf(outp, " %6.2f", 100.0 * p->pc6/t->tsc);
506 if (do_snb_cstates) 510 if (do_snb_cstates)
507 outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc); 511 outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc);
@@ -648,17 +652,24 @@ delta_thread(struct thread_data *new, struct thread_data *old,
648 } 652 }
649 653
650 654
651 /* 655 if (use_c1_residency_msr) {
652 * As counter collection is not atomic, 656 /*
653 * it is possible for mperf's non-halted cycles + idle states 657 * Some models have a dedicated C1 residency MSR,
654 * to exceed TSC's all cycles: show c1 = 0% in that case. 658 * which should be more accurate than the derivation below.
655 */ 659 */
656 if ((old->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > old->tsc) 660 } else {
657 old->c1 = 0; 661 /*
658 else { 662 * As counter collection is not atomic,
659 /* normal case, derive c1 */ 663 * it is possible for mperf's non-halted cycles + idle states
660 old->c1 = old->tsc - old->mperf - core_delta->c3 664 * to exceed TSC's all cycles: show c1 = 0% in that case.
665 */
666 if ((old->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > old->tsc)
667 old->c1 = 0;
668 else {
669 /* normal case, derive c1 */
670 old->c1 = old->tsc - old->mperf - core_delta->c3
661 - core_delta->c6 - core_delta->c7; 671 - core_delta->c6 - core_delta->c7;
672 }
662 } 673 }
663 674
664 if (old->mperf == 0) { 675 if (old->mperf == 0) {
@@ -872,13 +883,21 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
872 if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64)) 883 if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64))
873 return -5; 884 return -5;
874 885
886 if (use_c1_residency_msr) {
887 if (get_msr(cpu, MSR_CORE_C1_RES, &t->c1))
888 return -6;
889 }
890
875 /* collect core counters only for 1st thread in core */ 891 /* collect core counters only for 1st thread in core */
876 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) 892 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
877 return 0; 893 return 0;
878 894
879 if (do_nhm_cstates) { 895 if (do_nhm_cstates && !do_slm_cstates) {
880 if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3)) 896 if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3))
881 return -6; 897 return -6;
898 }
899
900 if (do_nhm_cstates) {
882 if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6)) 901 if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6))
883 return -7; 902 return -7;
884 } 903 }
@@ -898,7 +917,7 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
898 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) 917 if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
899 return 0; 918 return 0;
900 919
901 if (do_nhm_cstates) { 920 if (do_nhm_cstates && !do_slm_cstates) {
902 if (get_msr(cpu, MSR_PKG_C3_RESIDENCY, &p->pc3)) 921 if (get_msr(cpu, MSR_PKG_C3_RESIDENCY, &p->pc3))
903 return -9; 922 return -9;
904 if (get_msr(cpu, MSR_PKG_C6_RESIDENCY, &p->pc6)) 923 if (get_msr(cpu, MSR_PKG_C6_RESIDENCY, &p->pc6))
@@ -977,7 +996,7 @@ void print_verbose_header(void)
977 ratio, bclk, ratio * bclk); 996 ratio, bclk, ratio * bclk);
978 997
979 get_msr(0, MSR_IA32_POWER_CTL, &msr); 998 get_msr(0, MSR_IA32_POWER_CTL, &msr);
980 fprintf(stderr, "cpu0: MSR_IA32_POWER_CTL: 0x%08llx (C1E: %sabled)\n", 999 fprintf(stderr, "cpu0: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n",
981 msr, msr & 0x2 ? "EN" : "DIS"); 1000 msr, msr & 0x2 ? "EN" : "DIS");
982 1001
983 if (!do_ivt_turbo_ratio_limit) 1002 if (!do_ivt_turbo_ratio_limit)
@@ -1046,25 +1065,28 @@ print_nhm_turbo_ratio_limits:
1046 1065
1047 switch(msr & 0x7) { 1066 switch(msr & 0x7) {
1048 case 0: 1067 case 0:
1049 fprintf(stderr, "pc0"); 1068 fprintf(stderr, do_slm_cstates ? "no pkg states" : "pc0");
1050 break; 1069 break;
1051 case 1: 1070 case 1:
1052 fprintf(stderr, do_snb_cstates ? "pc2" : "pc0"); 1071 fprintf(stderr, do_slm_cstates ? "no pkg states" : do_snb_cstates ? "pc2" : "pc0");
1053 break; 1072 break;
1054 case 2: 1073 case 2:
1055 fprintf(stderr, do_snb_cstates ? "pc6-noret" : "pc3"); 1074 fprintf(stderr, do_slm_cstates ? "invalid" : do_snb_cstates ? "pc6-noret" : "pc3");
1056 break; 1075 break;
1057 case 3: 1076 case 3:
1058 fprintf(stderr, "pc6"); 1077 fprintf(stderr, do_slm_cstates ? "invalid" : "pc6");
1059 break; 1078 break;
1060 case 4: 1079 case 4:
1061 fprintf(stderr, "pc7"); 1080 fprintf(stderr, do_slm_cstates ? "pc4" : "pc7");
1062 break; 1081 break;
1063 case 5: 1082 case 5:
1064 fprintf(stderr, do_snb_cstates ? "pc7s" : "invalid"); 1083 fprintf(stderr, do_slm_cstates ? "invalid" : do_snb_cstates ? "pc7s" : "invalid");
1084 break;
1085 case 6:
1086 fprintf(stderr, do_slm_cstates ? "pc6" : "invalid");
1065 break; 1087 break;
1066 case 7: 1088 case 7:
1067 fprintf(stderr, "unlimited"); 1089 fprintf(stderr, do_slm_cstates ? "pc7" : "unlimited");
1068 break; 1090 break;
1069 default: 1091 default:
1070 fprintf(stderr, "invalid"); 1092 fprintf(stderr, "invalid");
@@ -1460,6 +1482,8 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
1460 case 0x3F: /* HSW */ 1482 case 0x3F: /* HSW */
1461 case 0x45: /* HSW */ 1483 case 0x45: /* HSW */
1462 case 0x46: /* HSW */ 1484 case 0x46: /* HSW */
1485 case 0x37: /* BYT */
1486 case 0x4D: /* AVN */
1463 return 1; 1487 return 1;
1464 case 0x2E: /* Nehalem-EX Xeon - Beckton */ 1488 case 0x2E: /* Nehalem-EX Xeon - Beckton */
1465 case 0x2F: /* Westmere-EX Xeon - Eagleton */ 1489 case 0x2F: /* Westmere-EX Xeon - Eagleton */
@@ -1532,14 +1556,33 @@ int print_epb(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1532#define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */ 1556#define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */
1533#define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */ 1557#define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */
1534 1558
1559double get_tdp(model)
1560{
1561 unsigned long long msr;
1562
1563 if (do_rapl & RAPL_PKG_POWER_INFO)
1564 if (!get_msr(0, MSR_PKG_POWER_INFO, &msr))
1565 return ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units;
1566
1567 switch (model) {
1568 case 0x37:
1569 case 0x4D:
1570 return 30.0;
1571 default:
1572 return 135.0;
1573 }
1574}
1575
1576
1535/* 1577/*
1536 * rapl_probe() 1578 * rapl_probe()
1537 * 1579 *
1538 * sets do_rapl 1580 * sets do_rapl, rapl_power_units, rapl_energy_units, rapl_time_units
1539 */ 1581 */
1540void rapl_probe(unsigned int family, unsigned int model) 1582void rapl_probe(unsigned int family, unsigned int model)
1541{ 1583{
1542 unsigned long long msr; 1584 unsigned long long msr;
1585 unsigned int time_unit;
1543 double tdp; 1586 double tdp;
1544 1587
1545 if (!genuine_intel) 1588 if (!genuine_intel)
@@ -1555,11 +1598,15 @@ void rapl_probe(unsigned int family, unsigned int model)
1555 case 0x3F: /* HSW */ 1598 case 0x3F: /* HSW */
1556 case 0x45: /* HSW */ 1599 case 0x45: /* HSW */
1557 case 0x46: /* HSW */ 1600 case 0x46: /* HSW */
1558 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_GFX; 1601 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO;
1559 break; 1602 break;
1560 case 0x2D: 1603 case 0x2D:
1561 case 0x3E: 1604 case 0x3E:
1562 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_DRAM | RAPL_PKG_PERF_STATUS | RAPL_DRAM_PERF_STATUS; 1605 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_PKG_PERF_STATUS | RAPL_DRAM_PERF_STATUS | RAPL_PKG_POWER_INFO;
1606 break;
1607 case 0x37: /* BYT */
1608 case 0x4D: /* AVN */
1609 do_rapl = RAPL_PKG | RAPL_CORES ;
1563 break; 1610 break;
1564 default: 1611 default:
1565 return; 1612 return;
@@ -1570,19 +1617,22 @@ void rapl_probe(unsigned int family, unsigned int model)
1570 return; 1617 return;
1571 1618
1572 rapl_power_units = 1.0 / (1 << (msr & 0xF)); 1619 rapl_power_units = 1.0 / (1 << (msr & 0xF));
1573 rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F)); 1620 if (model == 0x37)
1574 rapl_time_units = 1.0 / (1 << (msr >> 16 & 0xF)); 1621 rapl_energy_units = 1.0 * (1 << (msr >> 8 & 0x1F)) / 1000000;
1622 else
1623 rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F));
1575 1624
1576 /* get TDP to determine energy counter range */ 1625 time_unit = msr >> 16 & 0xF;
1577 if (get_msr(0, MSR_PKG_POWER_INFO, &msr)) 1626 if (time_unit == 0)
1578 return; 1627 time_unit = 0xA;
1579 1628
1580 tdp = ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units; 1629 rapl_time_units = 1.0 / (1 << (time_unit));
1581 1630
1582 rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp; 1631 tdp = get_tdp(model);
1583 1632
1633 rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
1584 if (verbose) 1634 if (verbose)
1585 fprintf(stderr, "RAPL: %.0f sec. Joule Counter Range\n", rapl_joule_counter_range); 1635 fprintf(stderr, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp);
1586 1636
1587 return; 1637 return;
1588} 1638}
@@ -1668,7 +1718,6 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1668{ 1718{
1669 unsigned long long msr; 1719 unsigned long long msr;
1670 int cpu; 1720 int cpu;
1671 double local_rapl_power_units, local_rapl_energy_units, local_rapl_time_units;
1672 1721
1673 if (!do_rapl) 1722 if (!do_rapl)
1674 return 0; 1723 return 0;
@@ -1686,23 +1735,13 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1686 if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr)) 1735 if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr))
1687 return -1; 1736 return -1;
1688 1737
1689 local_rapl_power_units = 1.0 / (1 << (msr & 0xF));
1690 local_rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F));
1691 local_rapl_time_units = 1.0 / (1 << (msr >> 16 & 0xF));
1692
1693 if (local_rapl_power_units != rapl_power_units)
1694 fprintf(stderr, "cpu%d, ERROR: Power units mis-match\n", cpu);
1695 if (local_rapl_energy_units != rapl_energy_units)
1696 fprintf(stderr, "cpu%d, ERROR: Energy units mis-match\n", cpu);
1697 if (local_rapl_time_units != rapl_time_units)
1698 fprintf(stderr, "cpu%d, ERROR: Time units mis-match\n", cpu);
1699
1700 if (verbose) { 1738 if (verbose) {
1701 fprintf(stderr, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx " 1739 fprintf(stderr, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx "
1702 "(%f Watts, %f Joules, %f sec.)\n", cpu, msr, 1740 "(%f Watts, %f Joules, %f sec.)\n", cpu, msr,
1703 local_rapl_power_units, local_rapl_energy_units, local_rapl_time_units); 1741 rapl_power_units, rapl_energy_units, rapl_time_units);
1704 } 1742 }
1705 if (do_rapl & RAPL_PKG) { 1743 if (do_rapl & RAPL_PKG_POWER_INFO) {
1744
1706 if (get_msr(cpu, MSR_PKG_POWER_INFO, &msr)) 1745 if (get_msr(cpu, MSR_PKG_POWER_INFO, &msr))
1707 return -5; 1746 return -5;
1708 1747
@@ -1714,6 +1753,9 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1714 ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units, 1753 ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units,
1715 ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units); 1754 ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units);
1716 1755
1756 }
1757 if (do_rapl & RAPL_PKG) {
1758
1717 if (get_msr(cpu, MSR_PKG_POWER_LIMIT, &msr)) 1759 if (get_msr(cpu, MSR_PKG_POWER_LIMIT, &msr))
1718 return -9; 1760 return -9;
1719 1761
@@ -1749,12 +1791,16 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1749 1791
1750 print_power_limit_msr(cpu, msr, "DRAM Limit"); 1792 print_power_limit_msr(cpu, msr, "DRAM Limit");
1751 } 1793 }
1752 if (do_rapl & RAPL_CORES) { 1794 if (do_rapl & RAPL_CORE_POLICY) {
1753 if (verbose) { 1795 if (verbose) {
1754 if (get_msr(cpu, MSR_PP0_POLICY, &msr)) 1796 if (get_msr(cpu, MSR_PP0_POLICY, &msr))
1755 return -7; 1797 return -7;
1756 1798
1757 fprintf(stderr, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF); 1799 fprintf(stderr, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF);
1800 }
1801 }
1802 if (do_rapl & RAPL_CORES) {
1803 if (verbose) {
1758 1804
1759 if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr)) 1805 if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr))
1760 return -9; 1806 return -9;
@@ -1813,10 +1859,48 @@ int has_c8_c9_c10(unsigned int family, unsigned int model)
1813} 1859}
1814 1860
1815 1861
1862int is_slm(unsigned int family, unsigned int model)
1863{
1864 if (!genuine_intel)
1865 return 0;
1866 switch (model) {
1867 case 0x37: /* BYT */
1868 case 0x4D: /* AVN */
1869 return 1;
1870 }
1871 return 0;
1872}
1873
1874#define SLM_BCLK_FREQS 5
1875double slm_freq_table[SLM_BCLK_FREQS] = { 83.3, 100.0, 133.3, 116.7, 80.0};
1876
1877double slm_bclk(void)
1878{
1879 unsigned long long msr = 3;
1880 unsigned int i;
1881 double freq;
1882
1883 if (get_msr(0, MSR_FSB_FREQ, &msr))
1884 fprintf(stderr, "SLM BCLK: unknown\n");
1885
1886 i = msr & 0xf;
1887 if (i >= SLM_BCLK_FREQS) {
1888 fprintf(stderr, "SLM BCLK[%d] invalid\n", i);
1889 msr = 3;
1890 }
1891 freq = slm_freq_table[i];
1892
1893 fprintf(stderr, "SLM BCLK: %.1f Mhz\n", freq);
1894
1895 return freq;
1896}
1897
1816double discover_bclk(unsigned int family, unsigned int model) 1898double discover_bclk(unsigned int family, unsigned int model)
1817{ 1899{
1818 if (is_snb(family, model)) 1900 if (is_snb(family, model))
1819 return 100.00; 1901 return 100.00;
1902 else if (is_slm(family, model))
1903 return slm_bclk();
1820 else 1904 else
1821 return 133.33; 1905 return 133.33;
1822} 1906}
@@ -1873,7 +1957,7 @@ int set_temperature_target(struct thread_data *t, struct core_data *c, struct pk
1873 fprintf(stderr, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n", 1957 fprintf(stderr, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n",
1874 cpu, msr, target_c_local); 1958 cpu, msr, target_c_local);
1875 1959
1876 if (target_c_local < 85 || target_c_local > 120) 1960 if (target_c_local < 85 || target_c_local > 127)
1877 goto guess; 1961 goto guess;
1878 1962
1879 tcc_activation_temp = target_c_local; 1963 tcc_activation_temp = target_c_local;
@@ -1970,6 +2054,7 @@ void check_cpuid()
1970 do_smi = do_nhm_cstates; 2054 do_smi = do_nhm_cstates;
1971 do_snb_cstates = is_snb(family, model); 2055 do_snb_cstates = is_snb(family, model);
1972 do_c8_c9_c10 = has_c8_c9_c10(family, model); 2056 do_c8_c9_c10 = has_c8_c9_c10(family, model);
2057 do_slm_cstates = is_slm(family, model);
1973 bclk = discover_bclk(family, model); 2058 bclk = discover_bclk(family, model);
1974 2059
1975 do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model); 2060 do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model);
@@ -2331,7 +2416,7 @@ int main(int argc, char **argv)
2331 cmdline(argc, argv); 2416 cmdline(argc, argv);
2332 2417
2333 if (verbose) 2418 if (verbose)
2334 fprintf(stderr, "turbostat v3.4 April 17, 2013" 2419 fprintf(stderr, "turbostat v3.5 April 26, 2013"
2335 " - Len Brown <lenb@kernel.org>\n"); 2420 " - Len Brown <lenb@kernel.org>\n");
2336 2421
2337 turbostat_init(); 2422 turbostat_init();