public static PStateMsr Decode(uint value, int pstate) { //uint maxDiv = (uint)K10Manager.MaxCOF(); uint maxDiv = (uint)K10Manager.CurrCOF(); uint clk = (uint)Form1.clock; bool turbo = K10Manager.IsTurboSupported(); if (pstate < 8) { if (Form1.family == 12) //Llano { uint cpuDid = (value >> 0) & 0x0F; uint cpuFid = (value >> 4) & 0x1F; uint cpuVid = (value >> 9) & 0x7F; uint enabled = (value >> 63) & 0x1; double Did = 1; switch (cpuDid) { case 0: Did = 1; break; case 1: Did = 1.5; break; case 2: Did = 2; break; case 3: Did = 3; break; case 4: Did = 4; break; case 5: Did = 6; break; case 6: Did = 8; break; case 7: Did = 12; break; case 8: Did = 16; break; default: throw new NotSupportedException("This Divider is not supported"); } double Mult = (cpuFid + 16) / Did; var msr = new PStateMsr() { CPUMultNBDivider = Mult, Vid = 1.55 - 0.0125 * cpuVid, Enabled = enabled, PLL = Mult * clk }; return(msr); } else if (Form1.family == 14) //Brazos { if (pstate <= K10Manager.GetHighestPState()) { uint cpuDidLSD = (value >> 0) & 0x0F; uint cpuDidMSD = (value >> 4) & 0x1F; uint cpuVid = (value >> 9) & 0x7F; uint enabled = (value >> 63) & 0x1; double Div = cpuDidMSD + (cpuDidLSD * 0.25) + 1; double DivPLL = cpuDidMSD + (cpuDidLSD * 0.25) + 1; if (maxDiv == 16 && Div < 2) //E-350 seems to restrict PLL frequencies higher than 1.6GHz { DivPLL = 2; } else if (maxDiv == 24 && Div < 4 && !turbo) //C-50 seems to restrict PLL frequencies higher than 1.0GHz { DivPLL = 4; } else if (maxDiv == 24 && Div < 3 && turbo) //C-60 (with turbo seems to restrict PLL frequencies higher than 1.33GHz { DivPLL = 3; } var msr = new PStateMsr() { CPUMultNBDivider = Div, Vid = 1.55 - 0.0125 * cpuVid, Enabled = enabled, PLL = (16 + maxDiv) / DivPLL * clk }; return(msr); } else { var msr = new PStateMsr() { CPUMultNBDivider = 10, Vid = 0.4, Enabled = 0, PLL = 0 }; return(msr); } } else //family 16 Kabini { if (pstate <= K10Manager.GetHighestPState()) { uint cpuDid = (value >> 6) & 0x7; uint cpuFid = value & 0x3F; uint cpuVid = (value >> 10) & 0x7F; //this works for SVI only - 7bits (CPUVid7:1 are used, CPUVid0 gets ignored) uint enabled = (value >> 63) & 0x1; if (cpuDid > 4) { throw new NotSupportedException("This Divider is not supported"); } double CoreCOF = (cpuFid + 16) / (Math.Pow(2, cpuDid)); var msr = new PStateMsr() { CPUMultNBDivider = CoreCOF, Vid = 1.55 - 0.0125 * cpuVid, Enabled = enabled, PLL = CoreCOF * clk }; return(msr); } else { var msr = new PStateMsr() { CPUMultNBDivider = 10, Vid = 0.4, Enabled = 0, PLL = 0 }; return(msr); } } } else if (pstate == 8) { if (Form1.family == 16) //Kabini { uint nbvidh = ((value >> 21) & 0x1); //uint nbvidl = ((value >> 10) & 0x7F); //SVI2 - 8bits uint nbvidl = ((value >> 11) & 0x3F); uint nbvid = (nbvidh * 64 + nbvidl); uint nbdid = ((value >> 7) & 0x1); uint nbfid = ((value >> 1) & 0x3F); double nclkdiv = (nbfid + 4) / (Math.Pow(2, nbdid)); var msr = new PStateMsr() { CPUMultNBDivider = nclkdiv, Vid = 1.55 - 0.0125 * nbvid, Enabled = 1, PLL = nclkdiv * clk }; return(msr); } else { uint nclk = ((value >> 20) & 0x7F); uint nbVid = ((value >> 12) & 0x7F); double nclkdiv = 1; //NCLK Div 2-16 ind 0.25 steps / Div 16-32 in 0.5 steps / Div 32-63 in 1.0 steps if (nclk >= 8 && nclk <= 63) { nclkdiv = nclk * 0.25; } else if (nclk >= 64 && nclk <= 95) { nclkdiv = (nclk - 64) * 0.5 - 16; } else if (nclk >= 96 && nclk <= 127) { nclkdiv = nclk - 64; } else { nclkdiv = 1; } var msr = new PStateMsr() { CPUMultNBDivider = nclkdiv, Vid = 1.55 - 0.0125 * nbVid, Enabled = 1, PLL = (16 + maxDiv) / nclkdiv * clk }; return(msr); } } else if (pstate == 9) { if (Form1.family == 16) //Kabini { uint nbvidh = ((value >> 21) & 0x1); //uint nbvidl = ((value >> 10) & 0x7F); //SVI2 - 8bits uint nbvidl = ((value >> 11) & 0x3F); uint nbvid = (nbvidh * 64 + nbvidl); uint nbdid = ((value >> 7) & 0x1); uint nbfid = ((value >> 1) & 0x3F); double nclkdiv = (nbfid + 4) / (Math.Pow(2, nbdid)); var msr = new PStateMsr() { CPUMultNBDivider = nclkdiv, Vid = 1.55 - 0.0125 * nbvid, Enabled = 1, PLL = nclkdiv * clk }; return(msr); } else { uint nclk = ((value >> 0) & 0x7F); uint nbVid = ((value >> 8) & 0x7F); double nclkdiv = 1; //NCLK Div 2-16 ind 0.25 steps / Div 16-32 in 0.5 steps / Div 32-63 in 1.0 steps if (nclk >= 8 && nclk <= 63) { nclkdiv = nclk * 0.25; } else if (nclk >= 64 && nclk <= 95) { nclkdiv = (nclk - 64) * 0.5 - 16; } else if (nclk >= 96 && nclk <= 127) { nclkdiv = nclk - 64; } else { nclkdiv = 1; } var msr = new PStateMsr() { CPUMultNBDivider = nclkdiv, Vid = 1.55 - 0.0125 * nbVid, Enabled = 1, PLL = (16 + maxDiv) / nclkdiv * clk }; return(msr); } } else { var msr = new PStateMsr() { CPUMultNBDivider = 0, Vid = 1, Enabled = 1, PLL = 1600 }; return(msr); } }
public Form1() { InitializeComponent(); family = K10Manager.GetFamily(); numPstates = K10Manager.GetHighestPState(); clock = K10Manager.GetBIOSBusSpeed(); //Brazos merge next line removed in BT //numBoostedPstates = K10Manager.GetNumBoostedStates(); numBoostedPstates = 0; processBarSteps = numPstates + numBoostedPstates + 1; processBarPerc = 100 / processBarSteps; if ((family != 12) && (family != 14) && (family != 16)) { MessageBox.Show("Your CPU/APU from AMD family: " + family + "h is not supported!"); } //needed to reduces flickering SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.OptimizedDoubleBuffer, true); if (numCores == 3) { this.Controls.Remove(this.pstateLabel4); this.Controls.Remove(this.core4label); this.Controls.Remove(this.cpu4Bar); ShiftTable(-15); } else if (numCores == 2) { this.Controls.Remove(this.pstateLabel4); this.Controls.Remove(this.core4label); this.Controls.Remove(this.cpu4Bar); this.Controls.Remove(this.pstateLabel3); this.Controls.Remove(this.core3label); this.Controls.Remove(this.cpu3Bar); ShiftTable(-30); } else if (numCores == 1) { this.Controls.Remove(this.pstateLabel4); this.Controls.Remove(this.core4label); this.Controls.Remove(this.cpu4Bar); this.Controls.Remove(this.pstateLabel3); this.Controls.Remove(this.core3label); this.Controls.Remove(this.cpu3Bar); this.Controls.Remove(this.pstateLabel2); this.Controls.Remove(this.core2label); this.Controls.Remove(this.cpu2Bar); ShiftTable(-50); } notifyIcon.Icon = this.Icon; notifyIcon.ContextMenuStrip = new ContextMenuStrip(); notifyIcon.Visible = true; if (family == 16) { //MessageBox.Show("Jetzt wird ein Log für den Editor erstellt!"); //log_now(); } //Brazos merge next line was active in BT //this.Width += p0StateControl.GetDeltaOptimalWidth(); //Brazos merge p3 trough p7 inactive in BT //BT also provides integer value to Load for PState, which shouldn't be needed //MessageBox.Show("Jetzt werden die Register der GPU gelesen!"); nbp0StateControl.LoadFromHardware(); nbp1StateControl.LoadFromHardware(); //MessageBox.Show("Jetzt werden zusätzliche Register gelesen!"); statusinfo.LoadFromHardware(); //MessageBox.Show("Jetzt werden die Register der CPU gelesen!"); p0StateControl.LoadFromHardware(); p1StateControl.LoadFromHardware(); p2StateControl.LoadFromHardware(); p3StateControl.LoadFromHardware(); p4StateControl.LoadFromHardware(); p5StateControl.LoadFromHardware(); p6StateControl.LoadFromHardware(); p7StateControl.LoadFromHardware(); //MessageBox.Show("Alle Register gelesen!"); if (!_useWindowsPowerSchemes) { // use FusionTweaker's power schemes (via the registry) powerSchemesComboBox.Items.Add(new PowerScheme() { Name = "Balanced" }); powerSchemesComboBox.Items.Add(new PowerScheme() { Name = "High performance" }); powerSchemesComboBox.Items.Add(new PowerScheme() { Name = "Power saver" }); var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"Software\FusionTweaker"); if (key == null) { powerSchemesComboBox.SelectedIndex = 0; } else { powerSchemesComboBox.SelectedIndex = (int)key.GetValue("PowerScheme", 0); key.Close(); } InitializeNotifyIconContextMenu(); powerSchemesComboBox.SelectedIndexChanged += (s, e) => { var k = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(@"Software\FusionTweaker"); k.SetValue("PowerScheme", powerSchemesComboBox.SelectedIndex); k.Close(); SynchronizeNotifyIconContextMenu(); }; return; } int guidSize = 16; IntPtr guid = Marshal.AllocHGlobal(guidSize); // get the GUID of the current power scheme IntPtr activeGuidPointer; if (PowerGetActiveScheme(IntPtr.Zero, out activeGuidPointer) != 0) { throw new Exception("PowerGetActiveScheme()"); } Guid activeGuid = (Guid)Marshal.PtrToStructure(activeGuidPointer, typeof(Guid)); LocalFree(activeGuidPointer); // iterate over all power schemes for (int i = 0; true; i++) { if (PowerEnumerate(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 0x10, i, guid, ref guidSize) != 0) { break; } // get the required buffer size int size = 0; if (PowerReadFriendlyName(IntPtr.Zero, guid, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, ref size) != 0) { break;//throw new Exception("PowerReadFriendlyName()"); } IntPtr stringBuffer = Marshal.AllocHGlobal(size); // get the scheme name if (PowerReadFriendlyName(IntPtr.Zero, guid, IntPtr.Zero, IntPtr.Zero, stringBuffer, ref size) != 0) { throw new Exception("PowerReadFriendlyName()"); } var item = new PowerScheme() { Guid = (Guid)Marshal.PtrToStructure(guid, typeof(Guid)), Name = Marshal.PtrToStringUni(stringBuffer) }; Marshal.FreeHGlobal(stringBuffer); powerSchemesComboBox.Items.Add(item); if (item.Guid == activeGuid) { powerSchemesComboBox.SelectedIndex = i; } } Marshal.FreeHGlobal(guid); InitializeNotifyIconContextMenu(); powerSchemesComboBox.SelectedIndexChanged += (s, e) => { var item = (PowerScheme)powerSchemesComboBox.SelectedItem; if (PowerSetActiveScheme(IntPtr.Zero, ref item.Guid) != 0) { throw new Exception("PowerSetActiveScheme()"); } SynchronizeNotifyIconContextMenu(); }; }
/// <summary> /// Saves the P-state to the cores' and NB MSRs. /// </summary> /// <param name="index">Index of the hardware P-state (0-4) to be modified. Adding NB P-state (8,9)</param> public void Save(int index) { //Brazos merge next line from BT //if (index < 0 || index > 4) if (index < 0 || index > 9) { throw new ArgumentOutOfRangeException("index"); } if (index < 8) //dealing with CPU P-States { uint msrIndex = 0xC0010064u + (uint)index; //Brazos merge next line commented out in BT int boostedStates = K10Manager.GetNumBoostedStates(); //Brazos merge next line active in BT //int boostedStates = 0; int indexSw = Math.Max(0, index - boostedStates); //Brazos merge next line active in BT //int tempPStateHw = (index <= boostedStates ? _maxPstate : 0); int tempPStateHw = (index <= boostedStates ? K10Manager.GetHighestPState() : 0); int tempPStateSw = Math.Max(0, tempPStateHw - boostedStates); // switch temporarily to the highest thread priority // (we try not to interfere with any kind of C&Q) var previousPriority = Thread.CurrentThread.Priority; Thread.CurrentThread.Priority = ThreadPriority.Highest; bool[] applyImmediately = new bool[_numCores]; for (int i = 0; i < _numCores; i++) { applyImmediately[i] = (K10Manager.GetCurrentPState(i) == index); // if the settings are to be applied immediately, switch temporarily to another P-state if (applyImmediately[i]) { K10Manager.SwitchToPState(tempPStateSw, i); } } Thread.Sleep(3); // let transitions complete for (int i = 0; i < _numCores; i++) { // save the new settings ulong msr = Program.Ols.ReadMsr(msrIndex, i); ulong mask = 0xFE00FFFFu; //Brazos + Llano Bits 15 .. 0 Vid + Mult if (Form1.family == 16) { mask = 0xFE01FFFFu; //Kabini Bits 16 .. 0 Vid + Mult msr = (msr & ~mask) | (_msrs[i].Encode(index) & mask); Program.Ols.WriteMsr(msrIndex, msr, i); } else { msr = (msr & ~mask) | (_msrs[i].Encode(index) & mask); Program.Ols.WriteMsr(msrIndex, msr, i); } // apply the new settings by switching back if (applyImmediately[i]) { K10Manager.SwitchToPState(indexSw, i); } } Thread.Sleep(3); // let transitions complete Thread.CurrentThread.Priority = previousPriority; } else if (index == 8 || index == 9) //dealing with NB P-State 0 { if (Form1.family == 16) //Kabini { // switch temporarily to the highest thread priority // (we try not to interfere with any kind of C&Q) var previousPriority = Thread.CurrentThread.Priority; Thread.CurrentThread.Priority = ThreadPriority.Highest; //check, if current NB P-State is the one, which is going to be modified //Brazos merge next line from BT index = index - 8; int curNbstate = K10Manager.GetNbPState(); int maxPstate = K10Manager.GetCurHighestPState(); if (index == 0) // NB P-state0 { for (int i = 0; i < _numCores; i++) { K10Manager.SwitchToPState(maxPstate, i); //switches to slowest core pstate to get to slowest NB pstate } Thread.Sleep(3); // let transitions complete //Kabini 16h //D18F5x160 NB P-state 0 //D18F5x164 NB P-state 1 //21 NbVid[7]. //16:10 NbVid[6:0]: Northbridge VID // save the new settings uint config = Program.Ols.ReadPciConfig(0xC5, 0x160); const uint mask = 0x0021F800; //enable overwrite of Vid only config = (config & ~mask) | (_msrs[0].Encode(index + 8) & mask); Program.Ols.WritePciConfig(0xC5, 0x160, config); for (int i = 0; i < _numCores; i++) { K10Manager.SwitchToPState(0, i); //switches to fastest core pstate to get to fastest NB pstate } Thread.Sleep(3); // let transitions complete } else if (index == 1) { for (int i = 0; i < _numCores; i++) { K10Manager.SwitchToPState(0, i); //switches to fastest core pstate to get to fastest NB pstate } Thread.Sleep(3); // let transitions complete // save the new settings uint config = Program.Ols.ReadPciConfig(0xC5, 0x164); const uint mask = 0x0021F800; //enable overwrite of Vid only config = (config & ~mask) | (_msrs[0].Encode(index + 8) & mask); Program.Ols.WritePciConfig(0xC5, 0x164, config); for (int i = 0; i < _numCores; i++) { K10Manager.SwitchToPState(maxPstate, i); //switches to slowest core pstate to get to slowest NB pstate } Thread.Sleep(3); // let transitions complete } //MessageBox.Show(message); Thread.CurrentThread.Priority = previousPriority; } else //Brazos + Llano { // switch temporarily to the highest thread priority // (we try not to interfere with any kind of C&Q) var previousPriority = Thread.CurrentThread.Priority; Thread.CurrentThread.Priority = ThreadPriority.Highest; //check, if current NB P-State is the one, which is going to be modified index = index - 8; int curNbstate = K10Manager.GetNbPState(); string message = "Start: " + curNbstate + "\n"; int changedNbstate = curNbstate; bool applyImmediately = (curNbstate != index); K10Manager.EnableNBPstateSwitching(); applyImmediately = (curNbstate != index); // if the settings are to be applied immediately, switch temporarily to another P-state if (applyImmediately) { K10Manager.SwitchToNbPState(index); for (int i = 0; i < 10; i++) { //Brazos merge BT uses Sleep 100 and i=1000 Thread.Sleep(20); // let transitions complete changedNbstate = K10Manager.GetNbPState(); if (changedNbstate == index) { message += "Time_init_switch: " + i + "\n"; i = 10; } } } curNbstate = K10Manager.GetNbPState(); if (index == 0) // NB P-state0 { // save the new settings uint config = Program.Ols.ReadPciConfig(0xC3, 0xDC); const uint mask = 0x0007F000; //enable overwrite of Vid only config = (config & ~mask) | (_msrs[0].Encode(index + 8) & mask); uint voltage = Program.Ols.ReadPciConfig(0xC3, 0x15C); const uint maskvolt = 0x00007F00; uint check = _msrs[0].Encode(index + 8) >> 12 & 0x7F; voltage = (voltage & ~maskvolt) | ((check << 8) & maskvolt); Program.Ols.WritePciConfig(0xC3, 0xDC, config); Program.Ols.WritePciConfig(0xC3, 0x15C, voltage); } else if (index == 1) { // save the new settings uint config = Program.Ols.ReadPciConfig(0xC6, 0x90); const uint mask = 0x00007F00; //enable VID modification only config = (config & ~mask) | (_msrs[0].Encode(index + 8) & mask); uint voltage = Program.Ols.ReadPciConfig(0xC3, 0x15C); const uint maskvolt = 0x0000007F; uint check = _msrs[0].Encode(index + 8) >> 8; voltage = (voltage & ~maskvolt) | (check & maskvolt); Program.Ols.WritePciConfig(0xC6, 0x90, config); Program.Ols.WritePciConfig(0xC3, 0x15C, voltage); } curNbstate = K10Manager.GetNbPState(); if (curNbstate == 0) { K10Manager.SwitchToNbPState(1); for (int i = 0; i < 10; i++) { //Brazos merge BT uses Sleep 100 and i=1000 Thread.Sleep(20); // let transitions complete changedNbstate = K10Manager.GetNbPState(); if (changedNbstate == 1) { message += "Time_P0_P1: " + i + "\n"; i = 10; } } K10Manager.SwitchToNbPState(0); for (int i = 0; i < 10; i++) { //Brazos merge BT uses Sleep 100 and i=1000 Thread.Sleep(20); // let transitions complete changedNbstate = K10Manager.GetNbPState(); if (changedNbstate == 0) { message += "Time_P1_P0: " + i + "\n"; i = 10; } } } else if (curNbstate == 1) { K10Manager.SwitchToNbPState(0); for (int i = 0; i < 10; i++) { //Brazos merge BT uses Sleep 100 and i=1000 Thread.Sleep(20); // let transitions complete changedNbstate = K10Manager.GetNbPState(); if (changedNbstate == 0) { message += "Time_P1_P0: " + i + "\n"; i = 10; } } K10Manager.SwitchToNbPState(1); for (int i = 0; i < 10; i++) { //Brazos merge BT uses Sleep 100 and i=1000 Thread.Sleep(20); // let transitions complete changedNbstate = K10Manager.GetNbPState(); if (changedNbstate == 1) { message += "Time_P0_P1: " + i + "\n"; i = 10; } } } //K10Manager.ExitDramSelfRefresh(); //K10Manager.EnDllShutDown(); K10Manager.DisableNBPstateSwitching(); //MessageBox.Show(message); Thread.CurrentThread.Priority = previousPriority; } } }
/// <summary> /// Constructor. /// </summary> public PStateControl() { InitializeComponent(); // check if the CPU's maximum multi is limited (non Black Edition CPUs) if (_maxCOF < 0) { // in DesignMode, Program.Ols is null if (Program.Ols == null) { _maxCOF = 48; _minVid = 0.0125; _maxVid = 1.55; //Brazos merge next line added from BT _maxPstate = -1; } else { //Brazos merge next line added from BT _maxPstate = K10Manager.GetHighestPState(); _family = K10Manager.GetFamily(); if (_family == 14) { _maxCOF = K10Manager.MaxCOF() + 16; } else { _maxCOF = K10Manager.MaxCOF(); } K10Manager.GetVidLimits(out _minVid, out _maxVid); } } VidNumericUpDown.Minimum = (decimal)_minVid; VidNumericUpDown.Maximum = (decimal)_maxVid; // add as many NumericUpDown controls as there are CPU cores for the multis for (int i = 0; i < _numCores; i++) { double _incr = 0.25; int _min = 1; if (_family == 12) //Llano { _incr = 1; _min = 4; } else if (_family == 14) //Brazos { _incr = 0.25; _min = 1; } else if (_family == 16) //Kabini { _incr = 0.5; _min = 4; } var control = new NumericUpDown() { AutoSize = true, DecimalPlaces = 2, Increment = (decimal)_incr, Maximum = (decimal)_maxCOF, Minimum = _min, TabIndex = i, TextAlign = HorizontalAlignment.Center, Value = 4, }; toolTip1.SetToolTip(control, "CPUMultNBDivider for core " + (i + 1) + ".\r\nReference clock (default: 100 MHz) times " + _maxCOF + " divided by the chosen value yields the core speed."); control.ValueChanged += (s, e) => _modified = true; if (i == 0) { control.ValueChanged += (s, e) => { for (int j = 1; j < _numCores; j++) { var otherControl = (NumericUpDown)flowLayoutPanel1.Controls[j]; otherControl.Value = control.Value; } }; } flowLayoutPanel1.Controls.Add(control); } VidNumericUpDown.ValueChanged += (s, e) => _modified = true; // set the tab order VidNumericUpDown.TabIndex = 3 + _numCores; refreshButton.TabIndex = VidNumericUpDown.TabIndex + 1; // compute the optimal width, based on the number of cores _optimalWidth = Cofstate.Width + Cofstate.Margin.Horizontal + flowLayoutPanel1.Controls.Count * (flowLayoutPanel1.Controls[0].Width + flowLayoutPanel1.Controls[0].Margin.Horizontal) + 270; //Brazos merge next line from BT //refreshButton.Click += (s, e) => LoadFromHardware(_index); refreshButton.Click += (s, e) => LoadFromHardware(); }