/// <summary>
        /// Decodes a P-state from its string representation.
        /// </summary>
        /// <returns></returns>
        public static PState Decode(string text, int pstate)
        {
            if (string.IsNullOrEmpty(text))
            {
                return(null);
            }

            string[] tokens = text.Split(new char[1] {
                '|'
            }, StringSplitOptions.RemoveEmptyEntries);
            if (tokens == null || tokens.Length != _numCores)
            {
                return(null);
            }

            var r = new PState();

            for (int i = 0; i < _numCores; i++)
            {
                uint value = uint.Parse(tokens[i], System.Globalization.NumberStyles.HexNumber);
                r._msrs[i] = PStateMsr.Decode(value, pstate);
            }

            return(r);
        }
        /// <summary>
        /// Loads the specified P-state from the cores' and NB MSRs.
        /// </summary>
        /// <param name="index">Index of the hardware P-state (0-7) to be loaded. Adding NB P-state (8,9)</param>
        public static PState Load(int index)
        {
            //Brazos merge next line from BT
            //if (index < 0 || index > 4)
            if (index < 0 || index > 9)
            {
                throw new ArgumentOutOfRangeException("index");
            }

            var r = new PState();

            for (int i = 0; i < _numCores; i++)
            {
                r._msrs[i] = PStateMsr.Load(index, i);
            }

            return(r);
        }
        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);
            }
        }
Beispiel #4
0
		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;
            }
		}