Front View plug-in does not init if no sensor added.
Fixing some format to make strings shorter.
Now trying to start SoundGraphAccess.exe process from same directory.
Packed mode now can display three sensors along with the current time.
3 This Source Code Form is subject to the terms of the Mozilla Public
4 License, v. 2.0. If a copy of the MPL was not distributed with this
5 file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 Copyright (C) 2009-2014 Michael Möller <mmoeller@openhardwaremonitor.org>
12 using System.Globalization;
15 namespace OpenHardwareMonitor.Hardware.CPU {
16 internal sealed class IntelCPU : GenericCPU {
18 private enum Microarchitecture {
31 private readonly Sensor[] coreTemperatures;
32 private readonly Sensor packageTemperature;
33 private readonly Sensor[] coreClocks;
34 private readonly Sensor busClock;
35 private readonly Sensor[] powerSensors;
37 private readonly Microarchitecture microarchitecture;
38 private readonly double timeStampCounterMultiplier;
40 private const uint IA32_THERM_STATUS_MSR = 0x019C;
41 private const uint IA32_TEMPERATURE_TARGET = 0x01A2;
42 private const uint IA32_PERF_STATUS = 0x0198;
43 private const uint MSR_PLATFORM_INFO = 0xCE;
44 private const uint IA32_PACKAGE_THERM_STATUS = 0x1B1;
45 private const uint MSR_RAPL_POWER_UNIT = 0x606;
46 private const uint MSR_PKG_ENERY_STATUS = 0x611;
47 private const uint MSR_DRAM_ENERGY_STATUS = 0x619;
48 private const uint MSR_PP0_ENERY_STATUS = 0x639;
49 private const uint MSR_PP1_ENERY_STATUS = 0x641;
51 private readonly uint[] energyStatusMSRs = { MSR_PKG_ENERY_STATUS,
52 MSR_PP0_ENERY_STATUS, MSR_PP1_ENERY_STATUS, MSR_DRAM_ENERGY_STATUS };
53 private readonly string[] powerSensorLabels =
54 { "CPU Package", "CPU Cores", "CPU Graphics", "CPU DRAM" };
55 private float energyUnitMultiplier = 0;
56 private DateTime[] lastEnergyTime;
57 private uint[] lastEnergyConsumed;
60 private float[] Floats(float f) {
61 float[] result = new float[coreCount];
62 for (int i = 0; i < coreCount; i++)
67 private float[] GetTjMaxFromMSR() {
69 float[] result = new float[coreCount];
70 for (int i = 0; i < coreCount; i++) {
71 if (Ring0.RdmsrTx(IA32_TEMPERATURE_TARGET, out eax,
72 out edx, 1UL << cpuid[i][0].Thread)) {
73 result[i] = (eax >> 16) & 0xFF;
81 public IntelCPU(int processorIndex, CPUID[][] cpuid, ISettings settings)
82 : base(processorIndex, cpuid, settings) {
88 case 0x0F: // Intel Core 2 (65nm)
89 microarchitecture = Microarchitecture.Core;
94 tjMax = Floats(80 + 10); break;
96 tjMax = Floats(90 + 10); break;
98 tjMax = Floats(85 + 10); break;
100 tjMax = Floats(80 + 10); break;
102 tjMax = Floats(90 + 10); break;
104 tjMax = Floats(85 + 10); break;
106 tjMax = Floats(85 + 10); break;
108 case 0x17: // Intel Core 2 (45nm)
109 microarchitecture = Microarchitecture.Core;
110 tjMax = Floats(100); break;
111 case 0x1C: // Intel Atom (45nm)
112 microarchitecture = Microarchitecture.Atom;
115 tjMax = Floats(90); break;
117 tjMax = Floats(100); break;
119 tjMax = Floats(90); break;
121 case 0x1A: // Intel Core i7 LGA1366 (45nm)
122 case 0x1E: // Intel Core i5, i7 LGA1156 (45nm)
123 case 0x1F: // Intel Core i5, i7
124 case 0x25: // Intel Core i3, i5, i7 LGA1156 (32nm)
125 case 0x2C: // Intel Core i7 LGA1366 (32nm) 6 Core
126 case 0x2E: // Intel Xeon Processor 7500 series (45nm)
127 case 0x2F: // Intel Xeon Processor (32nm)
128 microarchitecture = Microarchitecture.Nehalem;
129 tjMax = GetTjMaxFromMSR();
131 case 0x2A: // Intel Core i5, i7 2xxx LGA1155 (32nm)
132 case 0x2D: // Next Generation Intel Xeon, i7 3xxx LGA2011 (32nm)
133 microarchitecture = Microarchitecture.SandyBridge;
134 tjMax = GetTjMaxFromMSR();
136 case 0x3A: // Intel Core i5, i7 3xxx LGA1155 (22nm)
137 case 0x3E: // Intel Core i7 4xxx LGA2011 (22nm)
138 microarchitecture = Microarchitecture.IvyBridge;
139 tjMax = GetTjMaxFromMSR();
141 case 0x3C: // Intel Core i5, i7 4xxx LGA1150 (22nm)
142 case 0x3F: // Intel Xeon E5-2600/1600 v3, Core i7-59xx
143 // LGA2011-v3, Haswell-E (22nm)
144 case 0x45: // Intel Core i5, i7 4xxxU (22nm)
146 microarchitecture = Microarchitecture.Haswell;
147 tjMax = GetTjMaxFromMSR();
149 case 0x3D: // Intel Core M-5xxx (14nm)
150 microarchitecture = Microarchitecture.Broadwell;
151 tjMax = GetTjMaxFromMSR();
153 case 0x36: // Intel Atom S1xxx, D2xxx, N2xxx (32nm)
154 microarchitecture = Microarchitecture.Atom;
155 tjMax = GetTjMaxFromMSR();
157 case 0x37: // Intel Atom E3xxx, Z3xxx (22nm)
159 case 0x4D: // Intel Atom C2xxx (22nm)
162 microarchitecture = Microarchitecture.Silvermont;
163 tjMax = GetTjMaxFromMSR();
166 microarchitecture = Microarchitecture.Unknown;
173 case 0x00: // Pentium 4 (180nm)
174 case 0x01: // Pentium 4 (130nm)
175 case 0x02: // Pentium 4 (130nm)
176 case 0x03: // Pentium 4, Celeron D (90nm)
177 case 0x04: // Pentium 4, Pentium D, Celeron D (90nm)
178 case 0x06: // Pentium 4, Pentium D, Celeron D (65nm)
179 microarchitecture = Microarchitecture.NetBurst;
183 microarchitecture = Microarchitecture.Unknown;
189 microarchitecture = Microarchitecture.Unknown;
194 // set timeStampCounterMultiplier
195 switch (microarchitecture) {
196 case Microarchitecture.NetBurst:
197 case Microarchitecture.Atom:
198 case Microarchitecture.Core: {
200 if (Ring0.Rdmsr(IA32_PERF_STATUS, out eax, out edx)) {
201 timeStampCounterMultiplier =
202 ((edx >> 8) & 0x1f) + 0.5 * ((edx >> 14) & 1);
205 case Microarchitecture.Nehalem:
206 case Microarchitecture.SandyBridge:
207 case Microarchitecture.IvyBridge:
208 case Microarchitecture.Haswell:
209 case Microarchitecture.Broadwell:
210 case Microarchitecture.Silvermont: {
212 if (Ring0.Rdmsr(MSR_PLATFORM_INFO, out eax, out edx)) {
213 timeStampCounterMultiplier = (eax >> 8) & 0xff;
217 timeStampCounterMultiplier = 0;
221 // check if processor supports a digital thermal sensor at core level
222 if (cpuid[0][0].Data.GetLength(0) > 6 &&
223 (cpuid[0][0].Data[6, 0] & 1) != 0 &&
224 microarchitecture != Microarchitecture.Unknown)
226 coreTemperatures = new Sensor[coreCount];
227 for (int i = 0; i < coreTemperatures.Length; i++) {
228 coreTemperatures[i] = new Sensor(CoreString(i), i,
229 SensorType.Temperature, this, new[] {
230 new ParameterDescription(
231 "TjMax [°C]", "TjMax temperature of the core sensor.\n" +
232 "Temperature = TjMax - TSlope * Value.", tjMax[i]),
233 new ParameterDescription("TSlope [°C]",
234 "Temperature slope of the digital thermal sensor.\n" +
235 "Temperature = TjMax - TSlope * Value.", 1)}, settings);
236 ActivateSensor(coreTemperatures[i]);
239 coreTemperatures = new Sensor[0];
242 // check if processor supports a digital thermal sensor at package level
243 if (cpuid[0][0].Data.GetLength(0) > 6 &&
244 (cpuid[0][0].Data[6, 0] & 0x40) != 0 &&
245 microarchitecture != Microarchitecture.Unknown)
247 packageTemperature = new Sensor("CPU Package",
248 coreTemperatures.Length, SensorType.Temperature, this, new[] {
249 new ParameterDescription(
250 "TjMax [°C]", "TjMax temperature of the package sensor.\n" +
251 "Temperature = TjMax - TSlope * Value.", tjMax[0]),
252 new ParameterDescription("TSlope [°C]",
253 "Temperature slope of the digital thermal sensor.\n" +
254 "Temperature = TjMax - TSlope * Value.", 1)}, settings);
255 ActivateSensor(packageTemperature);
258 busClock = new Sensor("Bus Speed", 0, SensorType.Clock, this, settings);
259 coreClocks = new Sensor[coreCount];
260 for (int i = 0; i < coreClocks.Length; i++) {
262 new Sensor(CoreString(i), i + 1, SensorType.Clock, this, settings);
263 if (HasTimeStampCounter && microarchitecture != Microarchitecture.Unknown)
264 ActivateSensor(coreClocks[i]);
267 if (microarchitecture == Microarchitecture.SandyBridge ||
268 microarchitecture == Microarchitecture.IvyBridge ||
269 microarchitecture == Microarchitecture.Haswell ||
270 microarchitecture == Microarchitecture.Broadwell ||
271 microarchitecture == Microarchitecture.Silvermont)
273 powerSensors = new Sensor[energyStatusMSRs.Length];
274 lastEnergyTime = new DateTime[energyStatusMSRs.Length];
275 lastEnergyConsumed = new uint[energyStatusMSRs.Length];
278 if (Ring0.Rdmsr(MSR_RAPL_POWER_UNIT, out eax, out edx))
279 switch (microarchitecture) {
280 case Microarchitecture.Silvermont:
281 energyUnitMultiplier = 1.0e-6f * (1 << (int)((eax >> 8) & 0x1F));
284 energyUnitMultiplier = 1.0f / (1 << (int)((eax >> 8) & 0x1F));
287 if (energyUnitMultiplier != 0) {
288 for (int i = 0; i < energyStatusMSRs.Length; i++) {
289 if (!Ring0.Rdmsr(energyStatusMSRs[i], out eax, out edx))
292 lastEnergyTime[i] = DateTime.UtcNow;
293 lastEnergyConsumed[i] = eax;
294 powerSensors[i] = new Sensor(powerSensorLabels[i], i,
295 SensorType.Power, this, settings);
296 ActivateSensor(powerSensors[i]);
304 protected override uint[] GetMSRs() {
308 IA32_THERM_STATUS_MSR,
309 IA32_TEMPERATURE_TARGET,
310 IA32_PACKAGE_THERM_STATUS,
312 MSR_PKG_ENERY_STATUS,
313 MSR_DRAM_ENERGY_STATUS,
314 MSR_PP0_ENERY_STATUS,
319 public override string GetReport() {
320 StringBuilder r = new StringBuilder();
321 r.Append(base.GetReport());
323 r.Append("Microarchitecture: ");
324 r.AppendLine(microarchitecture.ToString());
325 r.Append("Time Stamp Counter Multiplier: ");
326 r.AppendLine(timeStampCounterMultiplier.ToString(
327 CultureInfo.InvariantCulture));
333 public override void Update() {
336 for (int i = 0; i < coreTemperatures.Length; i++) {
338 // if reading is valid
339 if (Ring0.RdmsrTx(IA32_THERM_STATUS_MSR, out eax, out edx,
340 1UL << cpuid[i][0].Thread) && (eax & 0x80000000) != 0)
342 // get the dist from tjMax from bits 22:16
343 float deltaT = ((eax & 0x007F0000) >> 16);
344 float tjMax = coreTemperatures[i].Parameters[0].Value;
345 float tSlope = coreTemperatures[i].Parameters[1].Value;
346 coreTemperatures[i].Value = tjMax - tSlope * deltaT;
348 coreTemperatures[i].Value = null;
352 if (packageTemperature != null) {
354 // if reading is valid
355 if (Ring0.RdmsrTx(IA32_PACKAGE_THERM_STATUS, out eax, out edx,
356 1UL << cpuid[0][0].Thread) && (eax & 0x80000000) != 0)
358 // get the dist from tjMax from bits 22:16
359 float deltaT = ((eax & 0x007F0000) >> 16);
360 float tjMax = packageTemperature.Parameters[0].Value;
361 float tSlope = packageTemperature.Parameters[1].Value;
362 packageTemperature.Value = tjMax - tSlope * deltaT;
364 packageTemperature.Value = null;
368 if (HasTimeStampCounter && timeStampCounterMultiplier > 0) {
369 double newBusClock = 0;
371 for (int i = 0; i < coreClocks.Length; i++) {
372 System.Threading.Thread.Sleep(1);
373 if (Ring0.RdmsrTx(IA32_PERF_STATUS, out eax, out edx,
374 1UL << cpuid[i][0].Thread)) {
376 TimeStampCounterFrequency / timeStampCounterMultiplier;
377 switch (microarchitecture) {
378 case Microarchitecture.Nehalem: {
379 uint multiplier = eax & 0xff;
380 coreClocks[i].Value = (float)(multiplier * newBusClock);
382 case Microarchitecture.SandyBridge:
383 case Microarchitecture.IvyBridge:
384 case Microarchitecture.Haswell:
385 case Microarchitecture.Broadwell:
386 case Microarchitecture.Silvermont: {
387 uint multiplier = (eax >> 8) & 0xff;
388 coreClocks[i].Value = (float)(multiplier * newBusClock);
392 ((eax >> 8) & 0x1f) + 0.5 * ((eax >> 14) & 1);
393 coreClocks[i].Value = (float)(multiplier * newBusClock);
397 // if IA32_PERF_STATUS is not available, assume TSC frequency
398 coreClocks[i].Value = (float)TimeStampCounterFrequency;
401 if (newBusClock > 0) {
402 this.busClock.Value = (float)newBusClock;
403 ActivateSensor(this.busClock);
407 if (powerSensors != null) {
408 foreach (Sensor sensor in powerSensors) {
413 if (!Ring0.Rdmsr(energyStatusMSRs[sensor.Index], out eax, out edx))
416 DateTime time = DateTime.UtcNow;
417 uint energyConsumed = eax;
419 (float)(time - lastEnergyTime[sensor.Index]).TotalSeconds;
420 if (deltaTime < 0.01)
423 sensor.Value = energyUnitMultiplier * unchecked(
424 energyConsumed - lastEnergyConsumed[sensor.Index]) / deltaTime;
425 lastEnergyTime[sensor.Index] = time;
426 lastEnergyConsumed[sensor.Index] = energyConsumed;