+ if (family == 6) {
+ switch (model) {
+ /* Atom (partial) */
+ case 0x27:
+ do_smi = 0;
+ do_core_cstate = 0;
+ do_pkg_cstate = (1 << 2) | (1 << 4) | (1 << 6);
+ break;
+ /* Silvermont */
+ case 0x37: /* BYT */
+ case 0x4D: /* AVN */
+ do_smi = 1;
+ do_core_cstate = (1 << 1) | (1 << 6);
+ do_pkg_cstate = (1 << 6);
+ break;
+ /* Nehalem */
+ case 0x1A: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown NHM-EP */
+ case 0x1E: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, Jasper Forest */
+ case 0x1F: /* Core i7 and i5 Processor - Nehalem */
+ case 0x2E: /* Nehalem-EX Xeon - Beckton */
+ do_smi = 1;
+ do_core_cstate = (1 << 3) | (1 << 6);
+ do_pkg_cstate = (1 << 3) | (1 << 6) | (1 << 7);
+ break;
+ /* Westmere */
+ case 0x25: /* Westmere Client - Clarkdale, Arrandale */
+ case 0x2C: /* Westmere EP - Gulftown */
+ case 0x2F: /* Westmere-EX Xeon - Eagleton */
+ do_smi = 1;
+ do_core_cstate = (1 << 3) | (1 << 6);
+ do_pkg_cstate = (1 << 3) | (1 << 6) | (1 << 7);
+ break;
+ /* Sandy Bridge */
+ case 0x2A: /* SNB */
+ case 0x2D: /* SNB Xeon */
+ do_smi = 1;
+ do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7);
+ do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7);
+ break;
+ /* Ivy Bridge */
+ case 0x3A: /* IVB */
+ case 0x3E: /* IVB Xeon */
+ do_smi = 1;
+ do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7);
+ do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7);
+ break;
+ /* Haswell Bridge */
+ case 0x3C: /* HSW */
+ case 0x3F: /* HSW */
+ case 0x46: /* HSW */
+ do_smi = 1;
+ do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7);
+ do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7);
+ break;
+ case 0x45: /* HSW */
+ do_smi = 1;
+ do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7);
+ do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10);
+ break;
+ /* Broadwel */
+ case 0x4F: /* BDW */
+ case 0x56: /* BDX-DE */
+ do_smi = 1;
+ do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7);
+ do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7);
+ break;
+ case 0x3D: /* BDW */
+ do_smi = 1;
+ do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7);
+ do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10);
+ break;
+ default:
+ do_smi = 0;
+ do_core_cstate = 0;
+ do_pkg_cstate = 0;
+ break;
+ }
+ switch (model) {
+ case 0x2A: /* SNB */
+ case 0x3A: /* IVB */
+ case 0x3C: /* HSW */
+ case 0x45: /* HSW */
+ case 0x46: /* HSW */
+ case 0x3D: /* BDW */
+ do_rapl = RAPL_PKG | RAPL_CORES | RAPL_GFX;
+ break;
+ case 0x3F: /* HSX */
+ case 0x4F: /* BDX */
+ case 0x56: /* BDX-DE */
+ do_rapl = RAPL_PKG | RAPL_DRAM ;
+ break;
+ case 0x2D: /* SNB Xeon */
+ case 0x3E: /* IVB Xeon */
+ do_rapl = RAPL_PKG | RAPL_CORES | RAPL_DRAM;
+ break;
+ case 0x37: /* BYT */
+ case 0x4D: /* AVN */
+ do_rapl = RAPL_PKG | RAPL_CORES;
+ break;
+ default:
+ do_rapl = 0;
+ }
+ } else {
+ ERROR("turbostat plugin: Unsupported CPU (family: %#x, "
+ "model: %#x)", family, model);
+ return -1;
+ }
+
+ /* Override detected values with configuration */
+ if (apply_config_core_cstate)
+ do_core_cstate = config_core_cstate;
+ if (apply_config_pkg_cstate)
+ do_pkg_cstate = config_pkg_cstate;
+ if (apply_config_smi)
+ do_smi = config_smi;
+ if (apply_config_dts)
+ do_dts = config_dts;
+ if (apply_config_ptm)
+ do_ptm = config_ptm;
+ if (apply_config_rapl)
+ do_rapl = config_rapl;
+
+ if (do_rapl) {
+ unsigned long long msr;
+ if (get_msr(0, MSR_RAPL_POWER_UNIT, &msr))
+ return 0;
+
+ if (model == 0x37)
+ rapl_energy_units = 1.0 * (1 << (msr >> 8 & 0x1F)) / 1000000;
+ else
+ rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F));
+ }
+
+ return 0;
+}
+
+
+/********************
+ * Topology Probing *
+ ********************/
+
+/*
+ * Read a single int from a file.
+ */
+static int __attribute__ ((format(printf,1,2)))
+parse_int_file(const char *fmt, ...)
+{
+ va_list args;
+ char path[PATH_MAX];
+ FILE *filep;
+ int len, value;