Esempio n. 1
0
        public void Update()
        {
            if (!Ring0.WaitIsaBusMutex(10))
            {
                return;
            }

            for (int i = 0; i < voltages.Length; i++)
            {
                if (chip == Chip.F71808E && i == 6)
                {
                    // 0x26 is reserved on F71808E
                    voltages[i] = 0;
                }
                else
                {
                    int value = ReadByte((byte)(VOLTAGE_BASE_REG + i));
                    voltages[i] = 0.008f * value;
                }
            }

            for (int i = 0; i < temperatures.Length; i++)
            {
                switch (chip)
                {
                case Chip.F71858: {
                    int tableMode = 0x3 & ReadByte(TEMPERATURE_CONFIG_REG);
                    int high      =
                        ReadByte((byte)(TEMPERATURE_BASE_REG + 2 * i));
                    int low =
                        ReadByte((byte)(TEMPERATURE_BASE_REG + 2 * i + 1));
                    if (high != 0xbb && high != 0xcc)
                    {
                        int bits = 0;
                        switch (tableMode)
                        {
                        case 0: bits = 0; break;

                        case 1: bits = 0; break;

                        case 2: bits = (high & 0x80) << 8; break;

                        case 3: bits = (low & 0x01) << 15; break;
                        }
                        bits |= high << 7;
                        bits |= (low & 0xe0) >> 1;
                        short value = (short)(bits & 0xfff0);
                        temperatures[i] = value / 128.0f;
                    }
                    else
                    {
                        temperatures[i] = null;
                    }
                } break;

                default: {
                    sbyte value = (sbyte)ReadByte((byte)(
                                                      TEMPERATURE_BASE_REG + 2 * (i + 1)));
                    if (value < sbyte.MaxValue && value > 0)
                    {
                        temperatures[i] = value;
                    }
                    else
                    {
                        temperatures[i] = null;
                    }
                } break;
                }
            }

            for (int i = 0; i < fans.Length; i++)
            {
                int value = ReadByte(FAN_TACHOMETER_REG[i]) << 8;
                value |= ReadByte((byte)(FAN_TACHOMETER_REG[i] + 1));

                if (value > 0)
                {
                    fans[i] = (value < 0x0fff) ? 1.5e6f / value : 0;
                }
                else
                {
                    fans[i] = null;
                }
            }

            Ring0.ReleaseIsaBusMutex();
        }
Esempio n. 2
0
        public string GetReport()
        {
            StringBuilder r = new StringBuilder();

            r.AppendLine("LPC " + this.GetType().Name);
            r.AppendLine();
            r.Append("Chip ID: 0x"); r.AppendLine(chip.ToString("X"));
            r.Append("Chip revision: 0x");
            r.AppendLine(revision.ToString("X", CultureInfo.InvariantCulture));
            r.Append("Base Adress: 0x");
            r.AppendLine(port.ToString("X4", CultureInfo.InvariantCulture));
            r.AppendLine();

            if (!Ring0.WaitIsaBusMutex(100))
            {
                return(r.ToString());
            }

            ushort[] addresses = new ushort[] {
                0x000, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x0F0,
                0x100, 0x110, 0x120, 0x130, 0x140, 0x150,
                0x200, 0x210, 0x220, 0x230, 0x240, 0x250, 0x260,
                0x300, 0x320, 0x330, 0x340, 0x360,
                0x400, 0x410, 0x420, 0x440, 0x450, 0x460, 0x480, 0x490, 0x4B0,
                0x4C0, 0x4F0,
                0x500, 0x550, 0x560,
                0x600, 0x610, 0x620, 0x630, 0x640, 0x650, 0x660, 0x670,
                0x700, 0x710, 0x720, 0x730,
                0x800, 0x820, 0x830, 0x840,
                0x900, 0x920, 0x930, 0x940, 0x960,
                0xA00, 0xA10, 0xA20, 0xA30, 0xA40, 0xA50, 0xA60, 0xA70,
                0xB00, 0xB10, 0xB20, 0xB30, 0xB50, 0xB60, 0xB70,
                0xC00, 0xC10, 0xC20, 0xC30, 0xC50, 0xC60, 0xC70,
                0xD00, 0xD10, 0xD20, 0xD30, 0xD50, 0xD60,
                0xE00, 0xE10, 0xE20, 0xE30,
                0xF00, 0xF10, 0xF20, 0xF30,
                0x8040, 0x80F0
            };

            r.AppendLine("Hardware Monitor Registers");
            r.AppendLine();
            r.AppendLine("        00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
            r.AppendLine();
            foreach (ushort address in addresses)
            {
                r.Append(" ");
                r.Append(address.ToString("X4", CultureInfo.InvariantCulture));
                r.Append("  ");
                for (ushort j = 0; j <= 0xF; j++)
                {
                    r.Append(" ");
                    r.Append(ReadByte((ushort)(address | j)).ToString(
                                 "X2", CultureInfo.InvariantCulture));
                }
                r.AppendLine();
            }
            r.AppendLine();

            Ring0.ReleaseIsaBusMutex();

            return(r.ToString());
        }
Esempio n. 3
0
        public void Update()
        {
            if (!Ring0.WaitIsaBusMutex(10))
            {
                return;
            }


            for (int i = 0; i < Voltages.Length; i++)
            {
                float value = _voltageGain * ReadByte((byte)(VOLTAGE_BASE_REG + i), out bool valid);

                if (!valid)
                {
                    continue;
                }


                if (value > 0)
                {
                    Voltages[i] = value;
                }
                else
                {
                    Voltages[i] = null;
                }
            }

            for (int i = 0; i < Temperatures.Length; i++)
            {
                sbyte value = (sbyte)ReadByte((byte)(TEMPERATURE_BASE_REG + i), out bool valid);
                if (!valid)
                {
                    continue;
                }


                if (value < sbyte.MaxValue && value > 0)
                {
                    Temperatures[i] = value;
                }
                else
                {
                    Temperatures[i] = null;
                }
            }

            if (_has16BitFanCounter)
            {
                for (int i = 0; i < Fans.Length; i++)
                {
                    if (_fansDisabled[i])
                    {
                        continue;
                    }


                    int value = ReadByte(FAN_TACHOMETER_REG[i], out bool valid);
                    if (!valid)
                    {
                        continue;
                    }


                    value |= ReadByte(FAN_TACHOMETER_EXT_REG[i], out valid) << 8;
                    if (!valid)
                    {
                        continue;
                    }


                    if (value > 0x3f)
                    {
                        Fans[i] = value < 0xffff ? 1.35e6f / (value * 2) : 0;
                    }
                    else
                    {
                        Fans[i] = null;
                    }
                }
            }
            else
            {
                for (int i = 0; i < Fans.Length; i++)
                {
                    int value = ReadByte(FAN_TACHOMETER_REG[i], out bool valid);
                    if (!valid)
                    {
                        continue;
                    }


                    int divisor = 2;
                    if (i < 2)
                    {
                        int divisors = ReadByte(FAN_TACHOMETER_DIVISOR_REGISTER, out valid);
                        if (!valid)
                        {
                            continue;
                        }


                        divisor = 1 << ((divisors >> (3 * i)) & 0x7);
                    }

                    if (value > 0)
                    {
                        Fans[i] = value < 0xff ? 1.35e6f / (value * divisor) : 0;
                    }
                    else
                    {
                        Fans[i] = null;
                    }
                }
            }

            for (int i = 0; i < Controls.Length; i++)
            {
                if (_hasNewerAutoPwm)
                {
                    byte value = ReadByte(FAN_PWM_DUTY_REG[i], out bool valid);
                    if (!valid)
                    {
                        continue;
                    }


                    byte ctrlValue = ReadByte(FAN_PWM_CTRL_REG[i], out valid);
                    if (!valid)
                    {
                        continue;
                    }


                    if ((ctrlValue & 0x80) > 0)
                    {
                        Controls[i] = null; // automatic operation (value can't be read)
                    }
                    else
                    {
                        Controls[i] = (float)Math.Round(value * 100.0f / 0xFF);
                    }
                }
                else
                {
                    byte value = ReadByte(FAN_PWM_CTRL_REG[i], out bool valid);
                    if (!valid)
                    {
                        continue;
                    }


                    if ((value & 0x80) > 0)
                    {
                        // automatic operation (value can't be read)
                        Controls[i] = null;
                    }
                    else
                    {
                        // software operation
                        Controls[i] = (float)Math.Round((value & 0x7F) * 100.0f / 0x7F);
                    }
                }
            }

            Ring0.ReleaseIsaBusMutex();
        }
        public override void Update()
        {
            base.Update();

            if (_temperatureStream == null)
            {
                if (_miscellaneousControlAddress != Interop.Ring0.INVALID_PCI_ADDRESS)
                {
                    bool isValueValid = _hasSmuTemperatureRegister
                        ? ReadSmuRegister(SMU_REPORTED_TEMP_CTRL_OFFSET, out uint value)
                        : Ring0.ReadPciConfig(_miscellaneousControlAddress, REPORTED_TEMPERATURE_CONTROL_REGISTER, out value);

                    if (isValueValid)
                    {
                        if ((_family == 0x15 || _family == 0x16) && (value & 0x30000) == 0x3000)
                        {
                            if (_family == 0x15 && (_model & 0xF0) == 0x00)
                            {
                                _coreTemperature.Value = ((value >> 21) & 0x7FC) / 8.0f + _coreTemperature.Parameters[0].Value - 49;
                            }
                            else
                            {
                                _coreTemperature.Value = ((value >> 21) & 0x7FF) / 8.0f + _coreTemperature.Parameters[0].Value - 49;
                            }
                        }
                        else
                        {
                            _coreTemperature.Value = ((value >> 21) & 0x7FF) / 8.0f + _coreTemperature.Parameters[0].Value;
                        }

                        ActivateSensor(_coreTemperature);
                    }
                    else
                    {
                        DeactivateSensor(_coreTemperature);
                    }
                }
                else
                {
                    DeactivateSensor(_coreTemperature);
                }
            }
            else
            {
                string s = ReadFirstLine(_temperatureStream);
                try
                {
                    _coreTemperature.Value = 0.001f * long.Parse(s, CultureInfo.InvariantCulture);
                    ActivateSensor(_coreTemperature);
                }
                catch
                {
                    DeactivateSensor(_coreTemperature);
                }
            }

            if (HasTimeStampCounter)
            {
                double newBusClock = 0;
                float  maxCoreVoltage = 0, maxNbVoltage = 0;

                for (int i = 0; i < _coreClocks.Length; i++)
                {
                    Thread.Sleep(1);

                    if (Ring0.ReadMsr(COFVID_STATUS, out uint curEax, out uint _, _cpuId[i][0].Affinity))
Esempio n. 5
0
            public void UpdateSensors()
            {
                var node = Nodes[0];

                if (node == null)
                {
                    return;
                }
                Core core = node.Cores[0];

                if (core == null)
                {
                    return;
                }
                CPUID cpu = core.Threads[0];

                if (cpu == null)
                {
                    return;
                }
                uint eax, edx;

                ulong mask = Ring0.ThreadAffinitySet(1UL << cpu.Thread);

                // MSRC001_0299
                // TU [19:16]
                // ESU [12:8] -> Unit 15.3 micro Joule per increment
                // PU [3:0]
                Ring0.Rdmsr(MSR_PWR_UNIT, out eax, out edx);
                int tu  = (int)((eax >> 16) & 0xf);
                int esu = (int)((eax >> 12) & 0xf);
                int pu  = (int)(eax & 0xf);

                // MSRC001_029B
                // total_energy [31:0]
                DateTime sample_time = DateTime.Now;

                Ring0.Rdmsr(MSR_PKG_ENERGY_STAT, out eax, out edx);
                uint total_energy = eax;

                // THM_TCON_CUR_TMP
                // CUR_TEMP [31:21]
                uint temperature = 0;

                Ring0.WritePciConfig(Ring0.GetPciAddress(0, 0, 0), FAMILY_17H_PCI_CONTROL_REGISTER, F17H_M01H_THM_TCON_CUR_TMP);
                Ring0.ReadPciConfig(Ring0.GetPciAddress(0, 0, 0), FAMILY_17H_PCI_CONTROL_REGISTER + 4, out temperature);

                // SVI0_TFN_PLANE0 [0]
                // SVI0_TFN_PLANE1 [1]
                uint smusvi0_tfn = 0;

                Ring0.WritePciConfig(Ring0.GetPciAddress(0, 0, 0), FAMILY_17H_PCI_CONTROL_REGISTER, F17H_M01H_SVI + 0x8);
                Ring0.ReadPciConfig(Ring0.GetPciAddress(0, 0, 0), FAMILY_17H_PCI_CONTROL_REGISTER + 4, out smusvi0_tfn);

                // SVI0_PLANE0_VDDCOR [24:16]
                // SVI0_PLANE0_IDDCOR [7:0]
                uint smusvi0_tel_plane0 = 0;

                Ring0.WritePciConfig(Ring0.GetPciAddress(0, 0, 0), FAMILY_17H_PCI_CONTROL_REGISTER, F17H_M01H_SVI + 0xc);
                Ring0.ReadPciConfig(Ring0.GetPciAddress(0, 0, 0), FAMILY_17H_PCI_CONTROL_REGISTER + 4, out smusvi0_tel_plane0);

                // SVI0_PLANE1_VDDCOR [24:16]
                // SVI0_PLANE1_IDDCOR [7:0]
                uint smusvi0_tel_plane1 = 0;

                Ring0.WritePciConfig(Ring0.GetPciAddress(0, 0, 0), FAMILY_17H_PCI_CONTROL_REGISTER, F17H_M01H_SVI + 0x10);
                Ring0.ReadPciConfig(Ring0.GetPciAddress(0, 0, 0), FAMILY_17H_PCI_CONTROL_REGISTER + 4, out smusvi0_tel_plane1);

                Ring0.ThreadAffinitySet(mask);

                // power consumption
                // power.Value = (float) ((double)pu * 0.125);
                // esu = 15.3 micro Joule per increment
                if (_lastPwrTime.Ticks == 0)
                {
                    _lastPwrTime  = sample_time;
                    _lastPwrValue = total_energy;
                }
                // ticks diff
                TimeSpan time = sample_time - _lastPwrTime;
                long     pwr;

                if (_lastPwrValue <= total_energy)
                {
                    pwr = total_energy - _lastPwrValue;
                }
                else
                {
                    pwr = (0xffffffff - _lastPwrValue) + total_energy;
                }

                // update for next sample
                _lastPwrTime  = sample_time;
                _lastPwrValue = total_energy;

                double energy = 15.3e-6 * pwr;

                energy /= time.TotalSeconds;

                _packagePower.Value = (float)energy;

                // current temp Bit [31:21]
                //If bit 19 of the Temperature Control register is set, there is an additional offset of 49 degrees C.
                bool temp_offset_flag = false;

                if ((temperature & F17H_TEMP_OFFSET_FLAG) != 0)
                {
                    temp_offset_flag = true;
                }
                temperature = (temperature >> 21) * 125;

                float offset = 0.0f;

                if (cpu.Name != null && (cpu.Name.Contains("2600X") || cpu.Name.Contains("2700X")))
                {
                    offset = -10.0f;
                }
                if (cpu.Name != null && (cpu.Name.Contains("1600X") || cpu.Name.Contains("1700X") || cpu.Name.Contains("1800X")))
                {
                    offset = -20.0f;
                }
                else if (cpu.Name != null && (cpu.Name.Contains("1920X") || cpu.Name.Contains("1950X") || cpu.Name.Contains("1900X")))
                {
                    offset = -27.0f;
                }
                else if (cpu.Name != null && (cpu.Name.Contains("1910") || cpu.Name.Contains("1920") || cpu.Name.Contains("1950")))
                {
                    offset = -10.0f;
                }

                float t = (temperature * 0.001f);

                if (temp_offset_flag)
                {
                    t += -49.0f;
                }

                _coreTemperatureTctl.Value = t;
                _coreTemperatureTdie.Value = t + offset;

                // voltage
                double VIDStep = 0.00625;
                double vcc;
                uint   svi0_plane_x_vddcor;
                uint   svi0_plane_x_iddcor;

                //Core
                if ((smusvi0_tfn & 0x01) == 0)
                {
                    svi0_plane_x_vddcor = (smusvi0_tel_plane0 >> 16) & 0xff;
                    svi0_plane_x_iddcor = smusvi0_tel_plane0 & 0xff;
                    vcc = 1.550 - (double)VIDStep * svi0_plane_x_vddcor;
                    _coreVoltage.Value = (float)vcc;
                }

                // SoC
                // not every zen cpu has this voltage
                if ((smusvi0_tfn & 0x02) == 0)
                {
                    svi0_plane_x_vddcor = (smusvi0_tel_plane1 >> 16) & 0xff;
                    svi0_plane_x_iddcor = smusvi0_tel_plane1 & 0xff;
                    vcc = 1.550 - (double)VIDStep * svi0_plane_x_vddcor;
                    _socVoltage.Value = (float)vcc;
                    _hw.ActivateSensor(_socVoltage);
                }
            }
Esempio n. 6
0
        public IntelCpu(int processorIndex, CpuId[][] cpuId, ISettings settings) : base(processorIndex, cpuId, settings)
        {
            // set tjMax
            float[] tjMax;
            switch (_family)
            {
            case 0x06:
            {
                switch (_model)
                {
                case 0x0F:         // Intel Core 2 (65nm)
                    _microArchitecture = MicroArchitecture.Core;
                    switch (_stepping)
                    {
                    case 0x06:             // B2
                        switch (_coreCount)
                        {
                        case 2:
                            tjMax = Floats(80 + 10);
                            break;

                        case 4:
                            tjMax = Floats(90 + 10);
                            break;

                        default:
                            tjMax = Floats(85 + 10);
                            break;
                        }
                        break;

                    case 0x0B:             // G0
                        tjMax = Floats(90 + 10);
                        break;

                    case 0x0D:             // M0
                        tjMax = Floats(85 + 10);
                        break;

                    default:
                        tjMax = Floats(85 + 10);
                        break;
                    }
                    break;

                case 0x17:         // Intel Core 2 (45nm)
                    _microArchitecture = MicroArchitecture.Core;
                    tjMax = Floats(100);
                    break;

                case 0x1C:         // Intel Atom (45nm)
                    _microArchitecture = MicroArchitecture.Atom;
                    switch (_stepping)
                    {
                    case 0x02:             // C0
                        tjMax = Floats(90);
                        break;

                    case 0x0A:             // A0, B0
                        tjMax = Floats(100);
                        break;

                    default:
                        tjMax = Floats(90);
                        break;
                    }
                    break;

                case 0x1A:         // Intel Core i7 LGA1366 (45nm)
                case 0x1E:         // Intel Core i5, i7 LGA1156 (45nm)
                case 0x1F:         // Intel Core i5, i7
                case 0x25:         // Intel Core i3, i5, i7 LGA1156 (32nm)
                case 0x2C:         // Intel Core i7 LGA1366 (32nm) 6 Core
                case 0x2E:         // Intel Xeon Processor 7500 series (45nm)
                case 0x2F:         // Intel Xeon Processor (32nm)
                    _microArchitecture = MicroArchitecture.Nehalem;
                    tjMax = GetTjMaxFromMsr();
                    break;

                case 0x2A:         // Intel Core i5, i7 2xxx LGA1155 (32nm)
                case 0x2D:         // Next Generation Intel Xeon, i7 3xxx LGA2011 (32nm)
                    _microArchitecture = MicroArchitecture.SandyBridge;
                    tjMax = GetTjMaxFromMsr();
                    break;

                case 0x3A:         // Intel Core i5, i7 3xxx LGA1155 (22nm)
                case 0x3E:         // Intel Core i7 4xxx LGA2011 (22nm)
                    _microArchitecture = MicroArchitecture.IvyBridge;
                    tjMax = GetTjMaxFromMsr();
                    break;

                case 0x3C:         // Intel Core i5, i7 4xxx LGA1150 (22nm)
                case 0x3F:         // Intel Xeon E5-2600/1600 v3, Core i7-59xx
                // LGA2011-v3, Haswell-E (22nm)
                case 0x45:         // Intel Core i5, i7 4xxxU (22nm)
                case 0x46:
                    _microArchitecture = MicroArchitecture.Haswell;
                    tjMax = GetTjMaxFromMsr();
                    break;

                case 0x3D:         // Intel Core M-5xxx (14nm)
                case 0x47:         // Intel i5, i7 5xxx, Xeon E3-1200 v4 (14nm)
                case 0x4F:         // Intel Xeon E5-26xx v4
                case 0x56:         // Intel Xeon D-15xx
                    _microArchitecture = MicroArchitecture.Broadwell;
                    tjMax = GetTjMaxFromMsr();
                    break;

                case 0x36:         // Intel Atom S1xxx, D2xxx, N2xxx (32nm)
                    _microArchitecture = MicroArchitecture.Atom;
                    tjMax = GetTjMaxFromMsr();
                    break;

                case 0x37:         // Intel Atom E3xxx, Z3xxx (22nm)
                case 0x4A:
                case 0x4D:         // Intel Atom C2xxx (22nm)
                case 0x5A:
                case 0x5D:
                    _microArchitecture = MicroArchitecture.Silvermont;
                    tjMax = GetTjMaxFromMsr();
                    break;

                case 0x4E:
                case 0x5E:         // Intel Core i5, i7 6xxxx LGA1151 (14nm)
                case 0x55:         // Intel Core X i7, i9 7xxx LGA2066 (14nm)
                    _microArchitecture = MicroArchitecture.Skylake;
                    tjMax = GetTjMaxFromMsr();
                    break;

                case 0x4C:         // Intel Airmont (Cherry Trail, Braswell)
                    _microArchitecture = MicroArchitecture.Airmont;
                    tjMax = GetTjMaxFromMsr();
                    break;

                case 0x8E:         // Intel Core i5, i7 7xxxx (14nm) (Kaby Lake) and 8xxxx (14nm++) (Coffee Lake)
                case 0x9E:
                    _microArchitecture = MicroArchitecture.KabyLake;
                    tjMax = GetTjMaxFromMsr();
                    break;

                case 0x5C:         // Goldmont (Apollo Lake)
                case 0x5F:         // (Denverton)
                    _microArchitecture = MicroArchitecture.Goldmont;
                    tjMax = GetTjMaxFromMsr();
                    break;

                case 0x7A:         // Goldmont plus (Gemini Lake)
                    _microArchitecture = MicroArchitecture.GoldmontPlus;
                    tjMax = GetTjMaxFromMsr();
                    break;

                case 0x66:         // Intel Core i3 8xxx (10nm) (Cannon Lake)
                    _microArchitecture = MicroArchitecture.CannonLake;
                    tjMax = GetTjMaxFromMsr();
                    break;

                case 0x7D:         // Intel Core i3, i5, i7 10xxx (10nm) (Ice Lake)
                case 0x7E:
                case 0x6A:         // Ice Lake server
                case 0x6C:
                    _microArchitecture = MicroArchitecture.IceLake;
                    tjMax = GetTjMaxFromMsr();
                    break;

                case 0xA5:
                case 0xA6:         // Intel Core i3, i5, i7 10xxxU (14nm)
                    _microArchitecture = MicroArchitecture.CometLake;
                    tjMax = GetTjMaxFromMsr();
                    break;

                case 0x86:         // Tremont (10nm) (Elkhart Lake, Skyhawk Lake)
                    _microArchitecture = MicroArchitecture.Tremont;
                    tjMax = GetTjMaxFromMsr();
                    break;

                case 0x8C:         // Tiger Lake (10nm)
                case 0x8D:
                    _microArchitecture = MicroArchitecture.TigerLake;
                    tjMax = GetTjMaxFromMsr();
                    break;

                default:
                    _microArchitecture = MicroArchitecture.Unknown;
                    tjMax = Floats(100);
                    break;
                }
            }
            break;

            case 0x0F:
            {
                switch (_model)
                {
                case 0x00:         // Pentium 4 (180nm)
                case 0x01:         // Pentium 4 (130nm)
                case 0x02:         // Pentium 4 (130nm)
                case 0x03:         // Pentium 4, Celeron D (90nm)
                case 0x04:         // Pentium 4, Pentium D, Celeron D (90nm)
                case 0x06:         // Pentium 4, Pentium D, Celeron D (65nm)
                    _microArchitecture = MicroArchitecture.NetBurst;
                    tjMax = Floats(100);
                    break;

                default:
                    _microArchitecture = MicroArchitecture.Unknown;
                    tjMax = Floats(100);
                    break;
                }
            }
            break;

            default:
                _microArchitecture = MicroArchitecture.Unknown;
                tjMax = Floats(100);
                break;
            }
            // set timeStampCounterMultiplier
            switch (_microArchitecture)
            {
            case MicroArchitecture.Atom:
            case MicroArchitecture.Core:
            case MicroArchitecture.NetBurst:
            {
                if (Ring0.ReadMsr(IA32_PERF_STATUS, out uint _, out uint edx))
                {
                    _timeStampCounterMultiplier = ((edx >> 8) & 0x1f) + 0.5 * ((edx >> 14) & 1);
                }

                break;
            }

            case MicroArchitecture.Airmont:
            case MicroArchitecture.Broadwell:
            case MicroArchitecture.CannonLake:
            case MicroArchitecture.CometLake:
            case MicroArchitecture.Goldmont:
            case MicroArchitecture.GoldmontPlus:
            case MicroArchitecture.Haswell:
            case MicroArchitecture.IceLake:
            case MicroArchitecture.IvyBridge:
            case MicroArchitecture.KabyLake:
            case MicroArchitecture.Nehalem:
            case MicroArchitecture.SandyBridge:
            case MicroArchitecture.Silvermont:
            case MicroArchitecture.Skylake:
            case MicroArchitecture.TigerLake:
            case MicroArchitecture.Tremont:
            {
                if (Ring0.ReadMsr(MSR_PLATFORM_INFO, out uint eax, out uint _))
                {
                    _timeStampCounterMultiplier = (eax >> 8) & 0xff;
                }
            }
            break;

            default:
                _timeStampCounterMultiplier = 0;
                break;
            }

            int coreSensorId = 0;

            // check if processor supports a digital thermal sensor at core level
            if (cpuId[0][0].Data.GetLength(0) > 6 && (cpuId[0][0].Data[6, 0] & 1) != 0 && _microArchitecture != MicroArchitecture.Unknown)
            {
                _coreTemperatures = new Sensor[_coreCount];
                for (int i = 0; i < _coreTemperatures.Length; i++)
                {
                    _coreTemperatures[i] = new Sensor(CoreString(i),
                                                      coreSensorId,
                                                      SensorType.Temperature,
                                                      this,
                                                      new[]
                    {
                        new ParameterDescription("TjMax [°C]", "TjMax temperature of the core sensor.\n" + "Temperature = TjMax - TSlope * Value.", tjMax[i]),
                        new ParameterDescription("TSlope [°C]", "Temperature slope of the digital thermal sensor.\n" + "Temperature = TjMax - TSlope * Value.", 1)
                    },
                                                      settings);

                    ActivateSensor(_coreTemperatures[i]);
                    coreSensorId++;
                }
            }
            else
            {
                _coreTemperatures = new Sensor[0];
            }

            // check if processor supports a digital thermal sensor at package level
            if (cpuId[0][0].Data.GetLength(0) > 6 && (cpuId[0][0].Data[6, 0] & 0x40) != 0 && _microArchitecture != MicroArchitecture.Unknown)
            {
                _packageTemperature = new Sensor("CPU Package",
                                                 coreSensorId,
                                                 SensorType.Temperature,
                                                 this,
                                                 new[]
                {
                    new ParameterDescription("TjMax [°C]", "TjMax temperature of the package sensor.\n" + "Temperature = TjMax - TSlope * Value.", tjMax[0]),
                    new ParameterDescription("TSlope [°C]", "Temperature slope of the digital thermal sensor.\n" + "Temperature = TjMax - TSlope * Value.", 1)
                },
                                                 settings);

                ActivateSensor(_packageTemperature);
                coreSensorId++;
            }

            // dist to tjmax sensor
            if (cpuId[0][0].Data.GetLength(0) > 6 && (cpuId[0][0].Data[6, 0] & 1) != 0 && _microArchitecture != MicroArchitecture.Unknown)
            {
                _distToTjMaxTemperatures = new Sensor[_coreCount];
                for (int i = 0; i < _distToTjMaxTemperatures.Length; i++)
                {
                    _distToTjMaxTemperatures[i] = new Sensor(CoreString(i) + " Distance to TjMax", coreSensorId, SensorType.Temperature, this, settings);
                    ActivateSensor(_distToTjMaxTemperatures[i]);
                    coreSensorId++;
                }
            }
            else
            {
                _distToTjMaxTemperatures = new Sensor[0];
            }

            //core temp avg and max value
            //is only available when the cpu has more than 1 core
            if (cpuId[0][0].Data.GetLength(0) > 6 && (cpuId[0][0].Data[6, 0] & 0x40) != 0 && _microArchitecture != MicroArchitecture.Unknown && _coreCount > 1)
            {
                _coreMax = new Sensor("Core Max", coreSensorId, SensorType.Temperature, this, settings);
                ActivateSensor(_coreMax);
                coreSensorId++;

                _coreAvg = new Sensor("Core Average", coreSensorId, SensorType.Temperature, this, settings);
                ActivateSensor(_coreAvg);
            }
            else
            {
                _coreMax = null;
                _coreAvg = null;
            }

            _busClock   = new Sensor("Bus Speed", 0, SensorType.Clock, this, settings);
            _coreClocks = new Sensor[_coreCount];
            for (int i = 0; i < _coreClocks.Length; i++)
            {
                _coreClocks[i] = new Sensor(CoreString(i), i + 1, SensorType.Clock, this, settings);
                if (HasTimeStampCounter && _microArchitecture != MicroArchitecture.Unknown)
                {
                    ActivateSensor(_coreClocks[i]);
                }
            }

            if (_microArchitecture == MicroArchitecture.Airmont ||
                _microArchitecture == MicroArchitecture.Broadwell ||
                _microArchitecture == MicroArchitecture.CannonLake ||
                _microArchitecture == MicroArchitecture.CometLake ||
                _microArchitecture == MicroArchitecture.Goldmont ||
                _microArchitecture == MicroArchitecture.GoldmontPlus ||
                _microArchitecture == MicroArchitecture.Haswell ||
                _microArchitecture == MicroArchitecture.IceLake ||
                _microArchitecture == MicroArchitecture.IvyBridge ||
                _microArchitecture == MicroArchitecture.KabyLake ||
                _microArchitecture == MicroArchitecture.SandyBridge ||
                _microArchitecture == MicroArchitecture.Silvermont ||
                _microArchitecture == MicroArchitecture.Skylake ||
                _microArchitecture == MicroArchitecture.TigerLake ||
                _microArchitecture == MicroArchitecture.Tremont)
            {
                _powerSensors       = new Sensor[_energyStatusMsrs.Length];
                _lastEnergyTime     = new DateTime[_energyStatusMsrs.Length];
                _lastEnergyConsumed = new uint[_energyStatusMsrs.Length];

                if (Ring0.ReadMsr(MSR_RAPL_POWER_UNIT, out uint eax, out uint _))
                {
                    switch (_microArchitecture)
                    {
                    case MicroArchitecture.Silvermont:
                    case MicroArchitecture.Airmont:
                        _energyUnitMultiplier = 1.0e-6f * (1 << (int)((eax >> 8) & 0x1F));
                        break;

                    default:
                        _energyUnitMultiplier = 1.0f / (1 << (int)((eax >> 8) & 0x1F));
                        break;
                    }
                }

                if (_energyUnitMultiplier != 0)
                {
                    string[] powerSensorLabels = { "CPU Package", "CPU Cores", "CPU Graphics", "CPU Memory" };

                    for (int i = 0; i < _energyStatusMsrs.Length; i++)
                    {
                        if (!Ring0.ReadMsr(_energyStatusMsrs[i], out eax, out uint _))
                        {
                            continue;
                        }


                        _lastEnergyTime[i]     = DateTime.UtcNow;
                        _lastEnergyConsumed[i] = eax;
                        _powerSensors[i]       = new Sensor(powerSensorLabels[i],
                                                            i,
                                                            SensorType.Power,
                                                            this,
                                                            settings);

                        ActivateSensor(_powerSensors[i]);
                    }
                }
            }

            Update();
        }
        public Amd10Cpu(int processorIndex, CpuId[][] cpuId, ISettings settings) : base(processorIndex, cpuId, settings)
        {
            // AMD family 1Xh processors support only one temperature sensor
            ushort miscellaneousControlDeviceId;

            _coreTemperature = new Sensor("CPU Cores", 0, SensorType.Temperature, this, new[] { new ParameterDescription("Offset [°C]", "Temperature offset.", 0) }, settings);
            _coreVoltage     = new Sensor("CPU Cores", 0, SensorType.Voltage, this, settings);
            ActivateSensor(_coreVoltage);
            _northbridgeVoltage = new Sensor("Northbridge", 0, SensorType.Voltage, this, settings);
            ActivateSensor(_northbridgeVoltage);

            _isSvi2 = (_family == 0x15 && _model >= 0x10) || _family == 0x16;

            switch (_family)
            {
            case 0x10:
            {
                miscellaneousControlDeviceId = FAMILY_10H_MISCELLANEOUS_CONTROL_DEVICE_ID;
                break;
            }

            case 0x11:
            {
                miscellaneousControlDeviceId = FAMILY_11H_MISCELLANEOUS_CONTROL_DEVICE_ID;
                break;
            }

            case 0x12:
            {
                miscellaneousControlDeviceId = FAMILY_12H_MISCELLANEOUS_CONTROL_DEVICE_ID;
                break;
            }

            case 0x14:
            {
                miscellaneousControlDeviceId = FAMILY_14H_MISCELLANEOUS_CONTROL_DEVICE_ID;
                break;
            }

            case 0x15:
            {
                switch (_model & 0xF0)
                {
                case 0x00:
                {
                    miscellaneousControlDeviceId = FAMILY_15H_MODEL_00_MISC_CONTROL_DEVICE_ID;
                    break;
                }

                case 0x10:
                {
                    miscellaneousControlDeviceId = FAMILY_15H_MODEL_10_MISC_CONTROL_DEVICE_ID;
                    break;
                }

                case 0x30:
                {
                    miscellaneousControlDeviceId = FAMILY_15H_MODEL_30_MISC_CONTROL_DEVICE_ID;
                    break;
                }

                case 0x70:
                {
                    miscellaneousControlDeviceId = FAMILY_15H_MODEL_70_MISC_CONTROL_DEVICE_ID;
                    _hasSmuTemperatureRegister   = true;
                    break;
                }

                case 0x60:
                {
                    miscellaneousControlDeviceId = FAMILY_15H_MODEL_60_MISC_CONTROL_DEVICE_ID;
                    _hasSmuTemperatureRegister   = true;
                    break;
                }

                default:
                {
                    miscellaneousControlDeviceId = 0;
                    break;
                }
                }
                break;
            }

            case 0x16:
            {
                switch (_model & 0xF0)
                {
                case 0x00:
                {
                    miscellaneousControlDeviceId = FAMILY_16H_MODEL_00_MISC_CONTROL_DEVICE_ID;
                    break;
                }

                case 0x30:
                {
                    miscellaneousControlDeviceId = FAMILY_16H_MODEL_30_MISC_CONTROL_DEVICE_ID;
                    break;
                }

                default:
                {
                    miscellaneousControlDeviceId = 0;
                    break;
                }
                }
                break;
            }

            case 0x17:
            {
                miscellaneousControlDeviceId = FAMILY_17H_MODEL_00_MISC_CONTROL_DEVICE_ID;
                break;
            }

            default:
            {
                miscellaneousControlDeviceId = 0;
                break;
            }
            }

            // get the pci address for the Miscellaneous Control registers
            _miscellaneousControlAddress = GetPciAddress(MISCELLANEOUS_CONTROL_FUNCTION, miscellaneousControlDeviceId);
            _busClock   = new Sensor("Bus Speed", 0, SensorType.Clock, this, settings);
            _coreClocks = new Sensor[_coreCount];
            for (int i = 0; i < _coreClocks.Length; i++)
            {
                _coreClocks[i] = new Sensor(CoreString(i), i + 1, SensorType.Clock, this, settings);
                if (HasTimeStampCounter)
                {
                    ActivateSensor(_coreClocks[i]);
                }
            }

            bool corePerformanceBoostSupport = (cpuId[0][0].ExtData[7, 3] & (1 << 9)) > 0;

            // set affinity to the first thread for all frequency estimations
            var previousAffinity = ThreadAffinity.Set(cpuId[0][0].Affinity);

            // disable core performance boost
            Ring0.ReadMsr(HWCR, out uint hwcrEax, out uint hwcrEdx);
            if (corePerformanceBoostSupport)
            {
                Ring0.WriteMsr(HWCR, hwcrEax | (1 << 25), hwcrEdx);
            }

            Ring0.ReadMsr(PERF_CTL_0, out uint ctlEax, out uint ctlEdx);
            Ring0.ReadMsr(PERF_CTR_0, out uint ctrEax, out uint ctrEdx);

            _timeStampCounterMultiplier = EstimateTimeStampCounterMultiplier();

            // restore the performance counter registers
            Ring0.WriteMsr(PERF_CTL_0, ctlEax, ctlEdx);
            Ring0.WriteMsr(PERF_CTR_0, ctrEax, ctrEdx);

            // restore core performance boost
            if (corePerformanceBoostSupport)
            {
                Ring0.WriteMsr(HWCR, hwcrEax, hwcrEdx);
            }

            // restore the thread affinity.
            ThreadAffinity.Set(previousAffinity);

            // the file reader for lm-sensors support on Linux
            _temperatureStream = null;

            if (Software.OperatingSystem.IsUnix)
            {
                string[] devicePaths = Directory.GetDirectories("/sys/class/hwmon/");
                foreach (string path in devicePaths)
                {
                    string name = null;
                    try
                    {
                        StreamReader reader = new StreamReader(path + "/device/name");

                        name = reader.ReadLine();
                    }
                    catch (IOException)
                    { }

                    switch (name)
                    {
                    case "k10temp":
                        _temperatureStream = new FileStream(path + "/device/temp1_input", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                        break;
                    }
                }
            }

            uint addr = Ring0.GetPciAddress(0, 20, 0);

            if (Ring0.ReadPciConfig(addr, 0, out uint dev))
            {
                Ring0.ReadPciConfig(addr, 8, out uint rev);

                if (dev == 0x43851002)
                {
                    _cStatesIoOffset = (byte)((rev & 0xFF) < 0x40 ? 0xB3 : 0x9C);
                }
                else if (dev == 0x780B1022 || dev == 0x790B1022)
                {
                    _cStatesIoOffset = 0x9C;
                }
            }

            if (_cStatesIoOffset != 0)
            {
                _cStatesResidency = new[] { new Sensor("CPU Package C2", 0, SensorType.Level, this, settings), new Sensor("CPU Package C3", 1, SensorType.Level, this, settings) };
                ActivateSensor(_cStatesResidency[0]);
                ActivateSensor(_cStatesResidency[1]);
            }

            Update();
        }
Esempio n. 8
0
 public void WinbondNuvotonFintekEnter()
 {
     Ring0.WriteIoPort(RegisterPort, 0x87);
     Ring0.WriteIoPort(RegisterPort, 0x87);
 }
Esempio n. 9
0
 public void WinbondNuvotonFintekExit()
 {
     Ring0.WriteIoPort(RegisterPort, 0xAA);
 }
Esempio n. 10
0
 public void WriteByte(byte register, byte value)
 {
     Ring0.WriteIoPort(RegisterPort, register);
     Ring0.WriteIoPort(ValuePort, value);
 }
Esempio n. 11
0
 public void Select(byte logicalDeviceNumber)
 {
     Ring0.WriteIoPort(RegisterPort, DEVCIE_SELECT_REGISTER);
     Ring0.WriteIoPort(ValuePort, logicalDeviceNumber);
 }
Esempio n. 12
0
 public byte ReadByte(byte register)
 {
     Ring0.WriteIoPort(RegisterPort, register);
     return(Ring0.ReadIoPort(ValuePort));
 }
Esempio n. 13
0
        public override void Update()
        {
            base.Update();

            if (Ring0.WaitPciBusMutex(10))
            {
                if (miscellaneousControlAddress != Ring0.InvalidPciAddress)
                {
                    for (uint i = 0; i < coreTemperatures.Length; i++)
                    {
                        if (Ring0.WritePciConfig(
                                miscellaneousControlAddress, THERMTRIP_STATUS_REGISTER,
                                i > 0 ? thermSenseCoreSelCPU1 : thermSenseCoreSelCPU0))
                        {
                            uint value;
                            if (Ring0.ReadPciConfig(
                                    miscellaneousControlAddress, THERMTRIP_STATUS_REGISTER,
                                    out value))
                            {
                                coreTemperatures[i].Value = ((value >> 16) & 0xFF) +
                                                            coreTemperatures[i].Parameters[0].Value;
                                ActivateSensor(coreTemperatures[i]);
                            }
                            else
                            {
                                DeactivateSensor(coreTemperatures[i]);
                            }
                        }
                    }
                }

                Ring0.ReleasePciBusMutex();
            }

            if (HasTimeStampCounter)
            {
                double newBusClock = 0;

                for (int i = 0; i < coreClocks.Length; i++)
                {
                    Thread.Sleep(1);

                    uint eax, edx;
                    if (Ring0.RdmsrTx(FIDVID_STATUS, out eax, out edx,
                                      cpuid[i][0].Affinity))
                    {
                        // CurrFID can be found in eax bits 0-5, MaxFID in 16-21
                        // 8-13 hold StartFID, we don't use that here.
                        double curMP = 0.5 * ((eax & 0x3F) + 8);
                        double maxMP = 0.5 * ((eax >> 16 & 0x3F) + 8);
                        coreClocks[i].Value =
                            (float)(curMP * TimeStampCounterFrequency / maxMP);
                        newBusClock = (float)(TimeStampCounterFrequency / maxMP);
                    }
                    else
                    {
                        // Fail-safe value - if the code above fails, we'll use this instead
                        coreClocks[i].Value = (float)TimeStampCounterFrequency;
                    }
                }

                if (newBusClock > 0)
                {
                    this.busClock.Value = (float)newBusClock;
                    ActivateSensor(this.busClock);
                }
            }
        }
Esempio n. 14
0
 private byte ReadByte(byte register)
 {
     Ring0.WriteIoPort(
         (ushort)(address + ADDRESS_REGISTER_OFFSET), register);
     return(Ring0.ReadIoPort((ushort)(address + DATA_REGISTER_OFFSET)));
 }
Esempio n. 15
0
        public override void Update()
        {
            base.Update();

            if (temperatureStream == null)
            {
                if (miscellaneousControlAddress != Ring0.InvalidPciAddress)
                {
                    uint value;
                    bool valueValid;
                    if (hasSmuTemperatureRegister)
                    {
                        valueValid =
                            ReadSmuRegister(SMU_REPORTED_TEMP_CONTROL_REGISTER, out value);
                    }
                    else
                    {
                        valueValid = Ring0.ReadPciConfig(miscellaneousControlAddress,
                                                         REPORTED_TEMPERATURE_CONTROL_REGISTER, out value);
                    }
                    if (valueValid)
                    {
                        if ((family == 0x15 || family == 0x16) && (value & 0x30000) == 0x30000)
                        {
                            coreTemperature.Value = ((value >> 21) & 0x7FF) * 0.125f +
                                                    coreTemperature.Parameters[0].Value - 49;
                        }
                        else
                        {
                            coreTemperature.Value = ((value >> 21) & 0x7FF) * 0.125f +
                                                    coreTemperature.Parameters[0].Value;
                        }
                        ActivateSensor(coreTemperature);
                    }
                    else
                    {
                        DeactivateSensor(coreTemperature);
                    }
                }
            }
            else
            {
                string s = ReadFirstLine(temperatureStream);
                try {
                    coreTemperature.Value = 0.001f *
                                            long.Parse(s, CultureInfo.InvariantCulture);
                    ActivateSensor(coreTemperature);
                } catch {
                    DeactivateSensor(coreTemperature);
                }
            }

            if (HasTimeStampCounter)
            {
                double newBusClock = 0;

                for (int i = 0; i < coreClocks.Length; i++)
                {
                    Thread.Sleep(1);

                    uint curEax, curEdx;
                    if (Ring0.RdmsrTx(COFVID_STATUS, out curEax, out curEdx,
                                      cpuid[i][0].Affinity))
                    {
                        double multiplier;
                        multiplier = GetCoreMultiplier(curEax);

                        coreClocks[i].Value =
                            (float)(multiplier * TimeStampCounterFrequency /
                                    timeStampCounterMultiplier);
                        newBusClock =
                            (float)(TimeStampCounterFrequency / timeStampCounterMultiplier);
                    }
                    else
                    {
                        coreClocks[i].Value = (float)TimeStampCounterFrequency;
                    }
                }

                if (newBusClock > 0)
                {
                    this.busClock.Value = (float)newBusClock;
                    ActivateSensor(this.busClock);
                }
            }
        }
Esempio n. 16
0
 public void IT87Exit()
 {
     Ring0.WriteIoPort(RegisterPort, CONFIGURATION_CONTROL_REGISTER);
     Ring0.WriteIoPort(ValuePort, 0x02);
 }
Esempio n. 17
0
        public AMD10CPU(int processorIndex, CPUID[][] cpuid, ISettings settings)
            : base(processorIndex, cpuid, settings)
        {
            // AMD family 1Xh processors support only one temperature sensor
            coreTemperature = new Sensor(
                "Core" + (coreCount > 1 ? " #1 - #" + coreCount : ""), 0,
                SensorType.Temperature, this, new [] {
                new ParameterDescription("Offset [°C]", "Temperature offset.", 0)
            }, settings);

            switch (family)
            {
            case 0x10: miscellaneousControlDeviceId =
                FAMILY_10H_MISCELLANEOUS_CONTROL_DEVICE_ID; break;

            case 0x11: miscellaneousControlDeviceId =
                FAMILY_11H_MISCELLANEOUS_CONTROL_DEVICE_ID; break;

            case 0x12: miscellaneousControlDeviceId =
                FAMILY_12H_MISCELLANEOUS_CONTROL_DEVICE_ID; break;

            case 0x14: miscellaneousControlDeviceId =
                FAMILY_14H_MISCELLANEOUS_CONTROL_DEVICE_ID; break;

            case 0x15:
                switch (model & 0xF0)
                {
                case 0x00: miscellaneousControlDeviceId =
                    FAMILY_15H_MODEL_00_MISC_CONTROL_DEVICE_ID; break;

                case 0x10: miscellaneousControlDeviceId =
                    FAMILY_15H_MODEL_10_MISC_CONTROL_DEVICE_ID; break;

                case 0x30: miscellaneousControlDeviceId =
                    FAMILY_15H_MODEL_30_MISC_CONTROL_DEVICE_ID; break;

                case 0x60: miscellaneousControlDeviceId =
                    FAMILY_15H_MODEL_60_MISC_CONTROL_DEVICE_ID;
                    hasSmuTemperatureRegister = true;
                    break;

                case 0x70: miscellaneousControlDeviceId =
                    FAMILY_15H_MODEL_70_MISC_CONTROL_DEVICE_ID;
                    hasSmuTemperatureRegister = true;
                    break;

                default: miscellaneousControlDeviceId = 0; break;
                }
                break;

            case 0x16:
                switch (model & 0xF0)
                {
                case 0x00: miscellaneousControlDeviceId =
                    FAMILY_16H_MODEL_00_MISC_CONTROL_DEVICE_ID; break;

                case 0x30: miscellaneousControlDeviceId =
                    FAMILY_16H_MODEL_30_MISC_CONTROL_DEVICE_ID; break;

                default: miscellaneousControlDeviceId = 0; break;
                }
                break;

            default: miscellaneousControlDeviceId = 0; break;
            }

            // get the pci address for the Miscellaneous Control registers
            miscellaneousControlAddress = GetPciAddress(
                MISCELLANEOUS_CONTROL_FUNCTION, miscellaneousControlDeviceId);

            busClock   = new Sensor("Bus Speed", 0, SensorType.Clock, this, settings);
            coreClocks = new Sensor[coreCount];
            for (int i = 0; i < coreClocks.Length; i++)
            {
                coreClocks[i] = new Sensor(CoreString(i), i + 1, SensorType.Clock,
                                           this, settings);
                if (HasTimeStampCounter)
                {
                    ActivateSensor(coreClocks[i]);
                }
            }

            corePerformanceBoostSupport = (cpuid[0][0].ExtData[7, 3] & (1 << 9)) > 0;

            // set affinity to the first thread for all frequency estimations
            var previousAffinity = ThreadAffinity.Set(cpuid[0][0].Affinity);

            // disable core performance boost
            uint hwcrEax, hwcrEdx;

            Ring0.Rdmsr(HWCR, out hwcrEax, out hwcrEdx);
            if (corePerformanceBoostSupport)
            {
                Ring0.Wrmsr(HWCR, hwcrEax | (1 << 25), hwcrEdx);
            }

            uint ctlEax, ctlEdx;

            Ring0.Rdmsr(PERF_CTL_0, out ctlEax, out ctlEdx);
            uint ctrEax, ctrEdx;

            Ring0.Rdmsr(PERF_CTR_0, out ctrEax, out ctrEdx);

            timeStampCounterMultiplier = estimateTimeStampCounterMultiplier();

            // restore the performance counter registers
            Ring0.Wrmsr(PERF_CTL_0, ctlEax, ctlEdx);
            Ring0.Wrmsr(PERF_CTR_0, ctrEax, ctrEdx);

            // restore core performance boost
            if (corePerformanceBoostSupport)
            {
                Ring0.Wrmsr(HWCR, hwcrEax, hwcrEdx);
            }

            // restore the thread affinity.
            ThreadAffinity.Set(previousAffinity);

            // the file reader for lm-sensors support on Linux
            temperatureStream = null;
            if (OperatingSystem.IsUnix)
            {
                string[] devicePaths = Directory.GetDirectories("/sys/class/hwmon/");
                foreach (string path in devicePaths)
                {
                    string name = null;
                    try {
                        using (StreamReader reader = new StreamReader(path + "/device/name"))
                            name = reader.ReadLine();
                    } catch (IOException) { }
                    switch (name)
                    {
                    case "k10temp":
                        temperatureStream = new FileStream(path + "/device/temp1_input",
                                                           FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                        break;
                    }
                }
            }

            Update();
        }
Esempio n. 18
0
 public void SmscEnter()
 {
     Ring0.WriteIoPort(RegisterPort, 0x55);
 }
Esempio n. 19
0
 private float[] GetTjMaxFromMsr()
 {
     float[] result = new float[_coreCount];
     for (int i = 0; i < _coreCount; i++)
     {
         if (Ring0.ReadMsr(IA32_TEMPERATURE_TARGET, out uint eax, out uint _, _cpuId[i][0].Affinity))
Esempio n. 20
0
 public void SmscExit()
 {
     Ring0.WriteIoPort(RegisterPort, 0xAA);
 }
        private double GetCoreMultiplier(uint cofVidEax)
        {
            switch (_family)
            {
            case 0x10:
            case 0x11:
            case 0x15:
            case 0x16:
            {
                // 8:6 CpuDid: current core divisor ID
                // 5:0 CpuFid: current core frequency ID
                uint cpuDid = (cofVidEax >> 6) & 7;
                uint cpuFid = cofVidEax & 0x1F;
                return(0.5 * (cpuFid + 0x10) / (1 << (int)cpuDid));
            }

            case 0x12:
            {
                // 8:4 CpuFid: current CPU core frequency ID
                // 3:0 CpuDid: current CPU core divisor ID
                uint   cpuFid = (cofVidEax >> 4) & 0x1F;
                uint   cpuDid = cofVidEax & 0xF;
                double divisor;
                switch (cpuDid)
                {
                case 0:
                    divisor = 1;
                    break;

                case 1:
                    divisor = 1.5;
                    break;

                case 2:
                    divisor = 2;
                    break;

                case 3:
                    divisor = 3;
                    break;

                case 4:
                    divisor = 4;
                    break;

                case 5:
                    divisor = 6;
                    break;

                case 6:
                    divisor = 8;
                    break;

                case 7:
                    divisor = 12;
                    break;

                case 8:
                    divisor = 16;
                    break;

                default:
                    divisor = 1;
                    break;
                }

                return((cpuFid + 0x10) / divisor);
            }

            case 0x14:
            {
                // 8:4: current CPU core divisor ID most significant digit
                // 3:0: current CPU core divisor ID least significant digit
                uint divisorIdMsd = (cofVidEax >> 4) & 0x1F;
                uint divisorIdLsd = cofVidEax & 0xF;
                Ring0.ReadPciConfig(_miscellaneousControlAddress, CLOCK_POWER_TIMING_CONTROL_0_REGISTER, out uint value);
                uint frequencyId = value & 0x1F;
                return((frequencyId + 0x10) /
                       (divisorIdMsd + (divisorIdLsd * 0.25) + 1));
            }

            default:
                return(1);
            }
        }
Esempio n. 22
0
            public void UpdateSensors()
            {
                NumaNode node  = Nodes[0];
                Core     core  = node?.Cores[0];
                CpuId    cpuId = core?.Threads[0];

                if (cpuId == null)
                {
                    return;
                }


                GroupAffinity previousAffinity = ThreadAffinity.Set(cpuId.Affinity);

                // MSRC001_0299
                // TU [19:16]
                // ESU [12:8] -> Unit 15.3 micro Joule per increment
                // PU [3:0]
                Ring0.ReadMsr(MSR_PWR_UNIT, out uint _, out uint _);

                // MSRC001_029B
                // total_energy [31:0]
                DateTime sampleTime = DateTime.Now;

                Ring0.ReadMsr(MSR_PKG_ENERGY_STAT, out uint eax, out _);

                uint totalEnergy = eax;

                uint smuSvi0Tfn       = 0;
                uint smuSvi0TelPlane0 = 0;
                uint smuSvi0TelPlane1 = 0;

                if (Ring0.WaitPciBusMutex(10))
                {
                    // THM_TCON_CUR_TMP
                    // CUR_TEMP [31:21]
                    Ring0.WritePciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER, F17H_M01H_THM_TCON_CUR_TMP);
                    Ring0.ReadPciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER + 4, out uint temperature);

                    // SVI0_TFN_PLANE0 [0]
                    // SVI0_TFN_PLANE1 [1]
                    Ring0.WritePciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER, F17H_M01H_SVI + 0x8);
                    Ring0.ReadPciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER + 4, out smuSvi0Tfn);

                    bool supportsPerCcdTemperatures = false;

                    // TODO: find a better way because these will probably keep changing in the future.

                    uint sviPlane0Offset;
                    uint sviPlane1Offset;
                    switch (cpuId.Model)
                    {
                    case 0x31:     // Threadripper 3000.
                    {
                        sviPlane0Offset            = F17H_M01H_SVI + 0x14;
                        sviPlane1Offset            = F17H_M01H_SVI + 0x10;
                        supportsPerCcdTemperatures = true;
                        break;
                    }

                    case 0x71:     // Zen 2.
                    case 0x21:     // Zen 3.
                    {
                        sviPlane0Offset            = F17H_M01H_SVI + 0x10;
                        sviPlane1Offset            = F17H_M01H_SVI + 0xC;
                        supportsPerCcdTemperatures = true;
                        break;
                    }

                    default:     // Zen and Zen+.
                    {
                        sviPlane0Offset = F17H_M01H_SVI + 0xC;
                        sviPlane1Offset = F17H_M01H_SVI + 0x10;
                        break;
                    }
                    }

                    // SVI0_PLANE0_VDDCOR [24:16]
                    // SVI0_PLANE0_IDDCOR [7:0]
                    Ring0.WritePciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER, sviPlane0Offset);
                    Ring0.ReadPciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER + 4, out smuSvi0TelPlane0);

                    // SVI0_PLANE1_VDDCOR [24:16]
                    // SVI0_PLANE1_IDDCOR [7:0]
                    Ring0.WritePciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER, sviPlane1Offset);
                    Ring0.ReadPciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER + 4, out smuSvi0TelPlane1);

                    ThreadAffinity.Set(previousAffinity);

                    // power consumption
                    // power.Value = (float) ((double)pu * 0.125);
                    // esu = 15.3 micro Joule per increment
                    if (_lastPwrTime.Ticks == 0)
                    {
                        _lastPwrTime  = sampleTime;
                        _lastPwrValue = totalEnergy;
                    }

                    // ticks diff
                    TimeSpan time = sampleTime - _lastPwrTime;
                    long     pwr;
                    if (_lastPwrValue <= totalEnergy)
                    {
                        pwr = totalEnergy - _lastPwrValue;
                    }
                    else
                    {
                        pwr = (0xffffffff - _lastPwrValue) + totalEnergy;
                    }

                    // update for next sample
                    _lastPwrTime  = sampleTime;
                    _lastPwrValue = totalEnergy;

                    double energy = 15.3e-6 * pwr;
                    energy /= time.TotalSeconds;

                    if (!double.IsNaN(energy))
                    {
                        _packagePower.Value = (float)energy;
                    }

                    // current temp Bit [31:21]
                    // If bit 19 of the Temperature Control register is set, there is an additional offset of 49 degrees C.
                    bool tempOffsetFlag = (temperature & F17H_TEMP_OFFSET_FLAG) != 0;
                    temperature = (temperature >> 21) * 125;

                    float offset = 0.0f;

                    // Offset table: https://github.com/torvalds/linux/blob/master/drivers/hwmon/k10temp.c#L78
                    if (string.IsNullOrWhiteSpace(cpuId.Name))
                    {
                        offset = 0;
                    }
                    else if (cpuId.Name.Contains("1600X") || cpuId.Name.Contains("1700X") || cpuId.Name.Contains("1800X"))
                    {
                        offset = -20.0f;
                    }
                    else if (cpuId.Name.Contains("Threadripper 19") || cpuId.Name.Contains("Threadripper 29"))
                    {
                        offset = -27.0f;
                    }
                    else if (cpuId.Name.Contains("2700X"))
                    {
                        offset = -10.0f;
                    }

                    float t = temperature * 0.001f;
                    if (tempOffsetFlag)
                    {
                        t += -49.0f;
                    }

                    if (offset < 0)
                    {
                        _coreTemperatureTctl.Value = t;
                        _coreTemperatureTdie.Value = t + offset;

                        _cpu.ActivateSensor(_coreTemperatureTctl);
                        _cpu.ActivateSensor(_coreTemperatureTdie);
                    }
                    else
                    {
                        // Zen 2 doesn't have an offset so Tdie and Tctl are the same.
                        _coreTemperatureTctlTdie.Value = t;
                        _cpu.ActivateSensor(_coreTemperatureTctlTdie);
                    }

                    // Tested only on R5 3600 & Threadripper 3960X.
                    if (supportsPerCcdTemperatures)
                    {
                        for (uint i = 0; i < _ccdTemperatures.Length; i++)
                        {
                            Ring0.WritePciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER, F17H_M70H_CCD1_TEMP + (i * 0x4));
                            Ring0.ReadPciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER + 4, out uint ccdRawTemp);

                            ccdRawTemp &= 0xFFF;
                            float ccdTemp = ((ccdRawTemp * 125) - 305000) * 0.001f;
                            if (ccdRawTemp > 0 && ccdTemp < 125)  // Zen 2 reports 95 degrees C max, but it might exceed that.
                            {
                                if (_ccdTemperatures[i] == null)
                                {
                                    _cpu.ActivateSensor(_ccdTemperatures[i] = new Sensor($"CCD{i + 1} (Tdie)",
                                                                                         _cpu._sensorTemperatures++,
                                                                                         SensorType.Temperature,
                                                                                         _cpu,
                                                                                         _cpu._settings));
                                }
                                _ccdTemperatures[i].Value = ccdTemp;
                            }
                        }

                        Sensor[] activeCcds = _ccdTemperatures.Where(x => x != null).ToArray();
                        if (activeCcds.Length > 1)
                        {
                            // No need to get the max / average ccds temp if there is only one CCD.

                            if (_ccdsMaxTemperature == null)
                            {
                                _cpu.ActivateSensor(_ccdsMaxTemperature = new Sensor("CCDs Max (Tdie)",
                                                                                     _cpu._sensorTemperatures++,
                                                                                     SensorType.Temperature,
                                                                                     _cpu,
                                                                                     _cpu._settings));
                            }

                            if (_ccdsAverageTemperature == null)
                            {
                                _cpu.ActivateSensor(_ccdsAverageTemperature = new Sensor("CCDs Average (Tdie)",
                                                                                         _cpu._sensorTemperatures++,
                                                                                         SensorType.Temperature,
                                                                                         _cpu,
                                                                                         _cpu._settings));
                            }

                            _ccdsMaxTemperature.Value     = activeCcds.Max(x => x.Value);
                            _ccdsAverageTemperature.Value = activeCcds.Average(x => x.Value);
                        }
                    }
                    Ring0.ReleasePciBusMutex();
                }

                // voltage
                const double vidStep = 0.00625;
                double       vcc;
                uint         svi0PlaneXVddCor;

                // Core (0x01).
                if ((smuSvi0Tfn & 0x01) == 0)
                {
                    svi0PlaneXVddCor = (smuSvi0TelPlane0 >> 16) & 0xff;
                    vcc = 1.550 - vidStep * svi0PlaneXVddCor;
                    _coreVoltage.Value = (float)vcc;

                    _cpu.ActivateSensor(_coreVoltage);
                }

                // SoC (0x02), not every Zen cpu has this voltage.
                if (cpuId.Model == 0x21 || cpuId.Model == 0x71 || cpuId.Model == 0x31 || (smuSvi0Tfn & 0x02) == 0)
                {
                    svi0PlaneXVddCor = (smuSvi0TelPlane1 >> 16) & 0xff;
                    vcc = 1.550 - vidStep * svi0PlaneXVddCor;
                    _socVoltage.Value = (float)vcc;

                    _cpu.ActivateSensor(_socVoltage);
                }

                double timeStampCounterMultiplier = GetTimeStampCounterMultiplier();

                if (timeStampCounterMultiplier > 0)
                {
                    _busClock.Value = (float)(_cpu.TimeStampCounterFrequency / timeStampCounterMultiplier);
                    _cpu.ActivateSensor(_busClock);
                }
            }
Esempio n. 23
0
            public void UpdateSensors()
            {
                // CPUID cpu = threads.FirstOrDefault();
                CPUID cpu = Threads[0];

                if (cpu == null)
                {
                    return;
                }
                uint  eax, edx;
                ulong mask = Ring0.ThreadAffinitySet(1UL << cpu.Thread);

                // MSRC001_0299
                // TU [19:16]
                // ESU [12:8] -> Unit 15.3 micro Joule per increment
                // PU [3:0]
                Ring0.Rdmsr(MSR_PWR_UNIT, out eax, out edx);
                int tu  = (int)((eax >> 16) & 0xf);
                int esu = (int)((eax >> 12) & 0xf);
                int pu  = (int)(eax & 0xf);

                // MSRC001_029A
                // total_energy [31:0]
                DateTime sample_time = DateTime.Now;

                Ring0.Rdmsr(MSR_CORE_ENERGY_STAT, out eax, out edx);
                uint total_energy = eax;

                // MSRC001_0293
                // CurHwPstate [24:22]
                // CurCpuVid [21:14]
                // CurCpuDfsId [13:8]
                // CurCpuFid [7:0]
                Ring0.Rdmsr(MSR_HARDWARE_PSTATE_STATUS, out eax, out edx);
                int CurHwPstate = (int)((eax >> 22) & 0x3);
                int CurCpuVid   = (int)((eax >> 14) & 0xff);
                int CurCpuDfsId = (int)((eax >> 8) & 0x3f);
                int CurCpuFid   = (int)(eax & 0xff);

                // MSRC001_0064 + x
                // IddDiv [31:30]
                // IddValue [29:22]
                // CpuVid [21:14]
                // CpuDfsId [13:8]
                // CpuFid [7:0]
                // Ring0.Rdmsr(MSR_PSTATE_0 + (uint)CurHwPstate, out eax, out edx);
                // int IddDiv = (int)((eax >> 30) & 0x03);
                // int IddValue = (int)((eax >> 22) & 0xff);
                // int CpuVid = (int)((eax >> 14) & 0xff);
                Ring0.ThreadAffinitySet(mask);

                // clock
                // CoreCOF is (Core::X86::Msr::PStateDef[CpuFid[7:0]] / Core::X86::Msr::PStateDef[CpuDfsId]) * 200
                _clock.Value = (float)((double)CurCpuFid / (double)CurCpuDfsId * 200.0);

                // multiplier
                _multiplier.Value = (float)((double)CurCpuFid / (double)CurCpuDfsId * 2.0);

                // Voltage
                double VIDStep = 0.00625;
                double vcc     = 1.550 - (double)VIDStep * CurCpuVid;

                _vcore.Value = (float)vcc;

                // power consumption
                // power.Value = (float) ((double)pu * 0.125);
                // esu = 15.3 micro Joule per increment
                if (_lastPwrTime.Ticks == 0)
                {
                    _lastPwrTime  = sample_time;
                    _lastPwrValue = total_energy;
                }
                // ticks diff
                TimeSpan time = sample_time - _lastPwrTime;
                long     pwr;

                if (_lastPwrValue <= total_energy)
                {
                    pwr = total_energy - _lastPwrValue;
                }
                else
                {
                    pwr = (0xffffffff - _lastPwrValue) + total_energy;
                }

                // update for next sample
                _lastPwrTime  = sample_time;
                _lastPwrValue = total_energy;

                double energy = 15.3e-6 * pwr;

                energy /= time.TotalSeconds;

                _power.Value = (float)energy;
            }
Esempio n. 24
0
            public void UpdateSensors()
            {
                // CPUID cpu = threads.FirstOrDefault();
                CpuId cpu = Threads[0];

                if (cpu == null)
                {
                    return;
                }


                var previousAffinity = ThreadAffinity.Set(cpu.Affinity);

                // MSRC001_0299
                // TU [19:16]
                // ESU [12:8] -> Unit 15.3 micro Joule per increment
                // PU [3:0]
                Ring0.ReadMsr(MSR_PWR_UNIT, out _, out _);

                // MSRC001_029A
                // total_energy [31:0]
                DateTime sampleTime = DateTime.Now;
                uint     eax;

                Ring0.ReadMsr(MSR_CORE_ENERGY_STAT, out eax, out _);
                uint totalEnergy = eax;

                // MSRC001_0293
                // CurHwPstate [24:22]
                // CurCpuVid [21:14]
                // CurCpuDfsId [13:8]
                // CurCpuFid [7:0]
                Ring0.ReadMsr(MSR_HARDWARE_PSTATE_STATUS, out eax, out _);
                int curCpuVid   = (int)((eax >> 14) & 0xff);
                int curCpuDfsId = (int)((eax >> 8) & 0x3f);
                int curCpuFid   = (int)(eax & 0xff);

                // MSRC001_0064 + x
                // IddDiv [31:30]
                // IddValue [29:22]
                // CpuVid [21:14]
                // CpuDfsId [13:8]
                // CpuFid [7:0]
                // Ring0.ReadMsr(MSR_PSTATE_0 + (uint)CurHwPstate, out eax, out edx);
                // int IddDiv = (int)((eax >> 30) & 0x03);
                // int IddValue = (int)((eax >> 22) & 0xff);
                // int CpuVid = (int)((eax >> 14) & 0xff);
                ThreadAffinity.Set(previousAffinity);

                // clock
                // CoreCOF is (Core::X86::Msr::PStateDef[CpuFid[7:0]] / Core::X86::Msr::PStateDef[CpuDfsId]) * 200
                double clock = 200.0;

                _busSpeed ??= _cpu.Sensors.FirstOrDefault(x => x.Name == "Bus Speed");
                if (_busSpeed?.Value.HasValue == true && _busSpeed.Value > 0)
                {
                    clock = (double)(_busSpeed.Value * 2);
                }

                _clock.Value = (float)(curCpuFid / (double)curCpuDfsId * clock);

                // multiplier
                _multiplier.Value = (float)(curCpuFid / (double)curCpuDfsId * 2.0);

                // Voltage
                const double vidStep = 0.00625;
                double       vcc     = 1.550 - vidStep * curCpuVid;

                _vcore.Value = (float)vcc;

                // power consumption
                // power.Value = (float) ((double)pu * 0.125);
                // esu = 15.3 micro Joule per increment
                if (_lastPwrTime.Ticks == 0)
                {
                    _lastPwrTime  = sampleTime;
                    _lastPwrValue = totalEnergy;
                }

                // ticks diff
                TimeSpan time = sampleTime - _lastPwrTime;
                long     pwr;

                if (_lastPwrValue <= totalEnergy)
                {
                    pwr = totalEnergy - _lastPwrValue;
                }
                else
                {
                    pwr = (0xffffffff - _lastPwrValue) + totalEnergy;
                }

                // update for next sample
                _lastPwrTime  = sampleTime;
                _lastPwrValue = totalEnergy;

                double energy = 15.3e-6 * pwr;

                energy /= time.TotalSeconds;

                if (!double.IsNaN(energy))
                {
                    _power.Value = (float)energy;
                }
            }
Esempio n. 25
0
        public void Update()
        {
            if (!isNuvotonVendor)
            {
                return;
            }

            if (!Ring0.WaitIsaBusMutex(10))
            {
                return;
            }

            DisableIOSpaceLock();

            for (int i = 0; i < voltages.Length; i++)
            {
                float value = 0.008f * ReadByte(voltageRegisters[i]);
                bool  valid = value > 0;

                // check if battery voltage monitor is enabled
                if (valid && voltageRegisters[i] == voltageVBatRegister)
                {
                    valid = (ReadByte(vBatMonitorControlRegister) & 0x01) > 0;
                }

                voltages[i] = valid ? value : (float?)null;
            }

            int temperatureSourceMask = 0;

            for (int i = temperatureRegister.Length - 1; i >= 0; i--)
            {
                int value = ((sbyte)ReadByte(temperatureRegister[i])) << 1;
                if (temperatureHalfBit[i] > 0)
                {
                    value |= ((ReadByte(temperatureHalfRegister[i]) >>
                               temperatureHalfBit[i]) & 0x1);
                }

                byte source = ReadByte(temperatureSourceRegister[i]);
                temperatureSourceMask |= 1 << source;

                float?temperature = 0.5f * value;
                if (temperature > 125 || temperature < -55)
                {
                    temperature = null;
                }

                for (int j = 0; j < temperatures.Length; j++)
                {
                    if (temperaturesSource[j] == source)
                    {
                        temperatures[j] = temperature;
                    }
                }
            }
            for (int i = 0; i < alternateTemperatureRegister.Length; i++)
            {
                if (!alternateTemperatureRegister[i].HasValue)
                {
                    continue;
                }

                if ((temperatureSourceMask & (1 << temperaturesSource[i])) > 0)
                {
                    continue;
                }

                float?temperature = (sbyte)
                                    ReadByte(alternateTemperatureRegister[i].Value);

                if (temperature > 125 || temperature < -55)
                {
                    temperature = null;
                }

                temperatures[i] = temperature;
            }

            for (int i = 0; i < fans.Length; i++)
            {
                byte high  = ReadByte((ushort)(fanRpmBaseRegister + (i << 1)));
                byte low   = ReadByte((ushort)(fanRpmBaseRegister + (i << 1) + 1));
                int  value = (high << 8) | low;

                fans[i] = value > minFanRPM ? value : 0;
            }

            for (int i = 0; i < controls.Length; i++)
            {
                int value = ReadByte(FAN_PWM_OUT_REG[i]);
                controls[i] = value / 2.55f;
            }

            Ring0.ReleaseIsaBusMutex();
        }
Esempio n. 26
0
        public void Update()
        {
            if (!Ring0.WaitIsaBusMutex(10))
            {
                return;
            }

            for (int i = 0; i < voltages.Length; i++)
            {
                bool valid;

                float value =
                    voltageGain * ReadByte((byte)(VOLTAGE_BASE_REG + i), out valid);

                if (!valid)
                {
                    continue;
                }
                if (value > 0)
                {
                    voltages[i] = value;
                }
                else
                {
                    voltages[i] = null;
                }
            }

            for (int i = 0; i < temperatures.Length; i++)
            {
                bool  valid;
                sbyte value = (sbyte)ReadByte(
                    (byte)(TEMPERATURE_BASE_REG + i), out valid);
                if (!valid)
                {
                    continue;
                }

                if (value < sbyte.MaxValue && value > 0)
                {
                    temperatures[i] = value;
                }
                else
                {
                    temperatures[i] = null;
                }
            }

            if (has16bitFanCounter)
            {
                for (int i = 0; i < fans.Length; i++)
                {
                    bool valid;
                    int  value = ReadByte(FAN_TACHOMETER_REG[i], out valid);
                    if (!valid)
                    {
                        continue;
                    }
                    value |= ReadByte(FAN_TACHOMETER_EXT_REG[i], out valid) << 8;
                    if (!valid)
                    {
                        continue;
                    }

                    if (value > 0x3f)
                    {
                        fans[i] = (value < 0xffff) ? 1.35e6f / (value * 2) : 0;
                    }
                    else
                    {
                        fans[i] = null;
                    }
                }
            }
            else
            {
                for (int i = 0; i < fans.Length; i++)
                {
                    bool valid;
                    int  value = ReadByte(FAN_TACHOMETER_REG[i], out valid);
                    if (!valid)
                    {
                        continue;
                    }

                    int divisor = 2;
                    if (i < 2)
                    {
                        int divisors = ReadByte(FAN_TACHOMETER_DIVISOR_REGISTER, out valid);
                        if (!valid)
                        {
                            continue;
                        }
                        divisor = 1 << ((divisors >> (3 * i)) & 0x7);
                    }

                    if (value > 0)
                    {
                        fans[i] = (value < 0xff) ? 1.35e6f / (value * divisor) : 0;
                    }
                    else
                    {
                        fans[i] = null;
                    }
                }
            }

            for (int i = 0; i < controls.Length; i++)
            {
                bool valid;
                byte value = ReadByte(FAN_PWM_CTRL_REG[i], out valid);
                if (!valid)
                {
                    continue;
                }

                if ((value & 0x80) > 0)
                {
                    // automatic operation (value can't be read)
                    controls[i] = null;
                }
                else
                {
                    // software operation
                    if (chip == Chip.IT8721F ||
                        chip == Chip.IT8665E ||
                        chip == Chip.IT8686E ||
                        chip == Chip.IT8688E ||
                        chip == Chip.IT879XE)
                    {
                        value = ReadByte(FAN_PWM_CTRL_EXT_REG[i], out valid);
                        if (valid)
                        {
                            controls[i] = Math.Round(value * 100.0f / 0xFF);
                        }
                    }
                    else
                    {
                        controls[i] = Math.Round((value & 0x7F) * 100.0f / 0x7F);
                    }
                }
            }

            Ring0.ReleaseIsaBusMutex();
        }
Esempio n. 27
0
        public void Update()
        {
            if (!Ring0.WaitIsaBusMutex(10))
            {
                return;
            }

            for (var i = 0; i < Voltages.Length; i++)
            {
                if (voltageRegister[i] != VOLTAGE_VBAT_REG)
                {
                    // two special VCore measurement modes for W83627THF
                    float fvalue;
                    if ((Chip == Chip.W83627HF || Chip == Chip.W83627THF ||
                         Chip == Chip.W83687THF) && i == 0)
                    {
                        var vrmConfiguration = ReadByte(0, 0x18);
                        int value            = ReadByte(voltageBank[i], voltageRegister[i]);
                        if ((vrmConfiguration & 0x01) == 0)
                        {
                            fvalue = 0.016f * value; // VRM8 formula
                        }
                        else
                        {
                            fvalue = 0.00488f * value + 0.69f; // VRM9 formula
                        }
                    }
                    else
                    {
                        int value = ReadByte(voltageBank[i], voltageRegister[i]);
                        fvalue = voltageGain * value;
                    }
                    if (fvalue > 0)
                    {
                        Voltages[i] = fvalue;
                    }
                    else
                    {
                        Voltages[i] = null;
                    }
                }
                else
                {
                    // Battery voltage
                    var valid = (ReadByte(0, 0x5D) & 0x01) > 0;
                    if (valid)
                    {
                        Voltages[i] = voltageGain * ReadByte(5, VOLTAGE_VBAT_REG);
                    }
                    else
                    {
                        Voltages[i] = null;
                    }
                }
            }

            for (var i = 0; i < Temperatures.Length; i++)
            {
                var value = ((sbyte)ReadByte(TEMPERATURE_BANK[i],
                                             TEMPERATURE_REG[i])) << 1;
                if (TEMPERATURE_BANK[i] > 0)
                {
                    value |= ReadByte(TEMPERATURE_BANK[i],
                                      (byte)(TEMPERATURE_REG[i] + 1)) >> 7;
                }

                var temperature = value / 2.0f;
                if (temperature <= 125 && temperature >= -55 && !peciTemperature[i])
                {
                    Temperatures[i] = temperature;
                }
                else
                {
                    Temperatures[i] = null;
                }
            }

            ulong bits = 0;

            for (var i = 0; i < FAN_BIT_REG.Length; i++)
            {
                bits = (bits << 8) | ReadByte(0, FAN_BIT_REG[i]);
            }
            var newBits = bits;

            for (var i = 0; i < Fans.Length; i++)
            {
                int count = ReadByte(FAN_TACHO_BANK[i], FAN_TACHO_REG[i]);

                // assemble fan divisor
                var divisorBits = (int)(
                    (((bits >> FAN_DIV_BIT2[i]) & 1) << 2) |
                    (((bits >> FAN_DIV_BIT1[i]) & 1) << 1) |
                    ((bits >> FAN_DIV_BIT0[i]) & 1));
                var divisor = 1 << divisorBits;

                var value = (count < 0xff) ? 1.35e6f / (count * divisor) : 0;
                Fans[i] = value;

                // update fan divisor
                if (count > 192 && divisorBits < 7)
                {
                    divisorBits++;
                }
                if (count < 96 && divisorBits > 0)
                {
                    divisorBits--;
                }

                newBits = SetBit(newBits, FAN_DIV_BIT2[i], (divisorBits >> 2) & 1);
                newBits = SetBit(newBits, FAN_DIV_BIT1[i], (divisorBits >> 1) & 1);
                newBits = SetBit(newBits, FAN_DIV_BIT0[i], divisorBits & 1);
            }

            // write new fan divisors
            for (var i = FAN_BIT_REG.Length - 1; i >= 0; i--)
            {
                var oldByte = (byte)(bits & 0xFF);
                var newByte = (byte)(newBits & 0xFF);
                bits    = bits >> 8;
                newBits = newBits >> 8;
                if (oldByte != newByte)
                {
                    WriteByte(0, FAN_BIT_REG[i], newByte);
                }
            }

            Ring0.ReleaseIsaBusMutex();
        }
Esempio n. 28
0
 private bool WriteByte(byte register, byte value)
 {
     Ring0.WriteIoPort(addressReg, register);
     Ring0.WriteIoPort(dataReg, value);
     return(register == Ring0.ReadIoPort(addressReg));
 }
Esempio n. 29
0
 private void WriteByte(byte register, byte value)
 {
     Ring0.WriteIoPort(_addressReg, register);
     Ring0.WriteIoPort(_dataReg, value);
     Ring0.ReadIoPort(_addressReg);
 }
Esempio n. 30
0
        internal AmdCpu10(int processorIndex, Cpuid[][] cpuid)
            : base(processorIndex, cpuid)
        {
            // AMD family 1Xh processors support only one temperature sensor
            CoreTemperatures    = new Sensor[1];
            CoreTemperatures[0] = new Sensor(
                "Core" + (CoreCount > 1 ? " #1 - #" + CoreCount : ""),
                SensorType.Temperature, new[]
            {
                new Parameter("Offset [°C]", "Temperature offset.", 0)
            });

            switch (Family)
            {
            case 0x10:
                _miscellaneousControlDeviceId =
                    Family10HMiscellaneousControlDeviceId;
                break;

            case 0x11:
                _miscellaneousControlDeviceId =
                    Family11HMiscellaneousControlDeviceId;
                break;

            case 0x12:
                _miscellaneousControlDeviceId =
                    Family12HMiscellaneousControlDeviceId;
                break;

            case 0x14:
                _miscellaneousControlDeviceId =
                    Family14HMiscellaneousControlDeviceId;
                break;

            case 0x15:
                switch (Model & 0xF0)
                {
                case 0x00:
                    _miscellaneousControlDeviceId =
                        Family15HModel00MiscControlDeviceId;
                    break;

                case 0x10:
                    _miscellaneousControlDeviceId =
                        Family15HModel10MiscControlDeviceId;
                    break;

                case 0x30:
                    _miscellaneousControlDeviceId =
                        Family15HModel30MiscControlDeviceId;
                    break;

                case 0x60:
                    _miscellaneousControlDeviceId =
                        Family15HModel60MiscControlDeviceId;
                    break;

                default:
                    _miscellaneousControlDeviceId = 0;
                    break;
                }

                break;

            case 0x16:
                switch (Model & 0xF0)
                {
                case 0x00:
                    _miscellaneousControlDeviceId =
                        Family16HModel00MiscControlDeviceId;
                    break;

                case 0x30:
                    _miscellaneousControlDeviceId =
                        Family16HModel30MiscControlDeviceId;
                    break;

                default:
                    _miscellaneousControlDeviceId = 0;
                    break;
                }

                break;

            case 0x17:
                _miscellaneousControlDeviceId =
                    Family17HModel00MiscControlDeviceId;
                break;

            default:
                _miscellaneousControlDeviceId = 0;
                break;
            }

            // get the pci address for the Miscellaneous Control registers
            _miscellaneousControlAddress = GetPciAddress(
                MiscellaneousControlFunction, _miscellaneousControlDeviceId);

            BusClock   = new Sensor("Bus Speed", SensorType.Clock);
            CoreClocks = new Sensor[CoreCount];
            for (var i = 0; i < CoreClocks.Length; i++)
            {
                CoreClocks[i] = new Sensor(CoreString(i), SensorType.Clock);
            }

            CorePerformanceBoostSupport = (cpuid[0][0].ExtData[7, 3] & (1 << 9)) > 0;

            // set affinity to the first thread for all frequency estimations
            var mask = ThreadAffinity.Set(1UL << cpuid[0][0].Thread);

            // disable core performance boost
            Ring0.Rdmsr(Hwcr, out var hwcrEax, out var hwcrEdx);
            if (CorePerformanceBoostSupport)
            {
                Ring0.Wrmsr(Hwcr, hwcrEax | (1 << 25), hwcrEdx);
            }

            Ring0.Rdmsr(PerfCtl0, out var ctlEax, out var ctlEdx);
            Ring0.Rdmsr(PerfCtr0, out var ctrEax, out var ctrEdx);

            _timeStampCounterMultiplier = EstimateTimeStampCounterMultiplier();

            // restore the performance counter registers
            Ring0.Wrmsr(PerfCtl0, ctlEax, ctlEdx);
            Ring0.Wrmsr(PerfCtr0, ctrEax, ctrEdx);

            // restore core performance boost
            if (CorePerformanceBoostSupport)
            {
                Ring0.Wrmsr(Hwcr, hwcrEax, hwcrEdx);
            }

            // restore the thread affinity.
            ThreadAffinity.Set(mask);

            // the file reader for lm-sensors support on Linux
            _temperatureStream = null;

            Update();
        }