Пример #1
0
        private void WriteDescription(StringBuilder brand, CpuIdRegister register)
        {
            if (register == null)
            {
                return;
            }

            int eax = register.Result[0];
            int ebx = register.Result[1];
            int ecx = register.Result[2];
            int edx = register.Result[3];

            Append(brand, eax & 0xFF);
            Append(brand, (eax >> 8) & 0xFF);
            Append(brand, (eax >> 16) & 0xFF);
            Append(brand, (eax >> 24) & 0xFF);
            Append(brand, ebx & 0xFF);
            Append(brand, (ebx >> 8) & 0xFF);
            Append(brand, (ebx >> 16) & 0xFF);
            Append(brand, (ebx >> 24) & 0xFF);
            Append(brand, ecx & 0xFF);
            Append(brand, (ecx >> 8) & 0xFF);
            Append(brand, (ecx >> 16) & 0xFF);
            Append(brand, (ecx >> 24) & 0xFF);
            Append(brand, edx & 0xFF);
            Append(brand, (edx >> 8) & 0xFF);
            Append(brand, (edx >> 16) & 0xFF);
            Append(brand, (edx >> 24) & 0xFF);
        }
Пример #2
0
        private void GetCpuTopology(BasicCpu cpu)
        {
            CpuIdRegister apic = cpu.CpuRegisters.GetCpuId(FeatureInformationFunction, 0);

            if (!Features["HTT"] || !Features["CMP"] || cpu.ExtendedFunctionCount < ExtendedFeatureIds - MaxExtendedFunction)
            {
                Topology.ApicId = (apic.Result[1] >> 24) & 0xFF;
                Topology.CoreTopology.Add(new CpuTopo(0, CpuTopoType.Core, 0));
                Topology.CoreTopology.Add(new CpuTopo(Topology.ApicId, CpuTopoType.Package, -1));
                return;
            }

            CpuIdRegister extFeatureIds = cpu.CpuRegisters.GetCpuId(ExtendedFeatureIds, 0);
            int           apicIdSize    = (extFeatureIds.Result[2] >> 12) & 0xF;
            int           coreBits;

            if (apicIdSize == 0)
            {
                // There are two possible places to get this:
                // - from LogicalProcessorCount = CPUID(01h).EBX[23:16] (Intel); or
                // - from NC = CPUID(80000008h).ECX[7:0] (from AMD).
                int mnlp = (extFeatureIds.Result[2] >> 16) & 0xF + 1;
                coreBits = Log2Pof2(mnlp);
            }
            else
            {
                coreBits = apicIdSize;
            }
            long coreMask = ~(-1 << coreBits);
            long pkgMask  = ~coreMask;

            if (!Features["TOPX"] || cpu.ExtendedFunctionCount < ProcessorTopo - MaxExtendedFunction)
            {
                Topology.ApicId = (apic.Result[1] >> 24) & 0xFF;
                Topology.CoreTopology.Add(new CpuTopo(Topology.ApicId & coreMask, CpuTopoType.Core, coreMask));
                Topology.CoreTopology.Add(new CpuTopo(Topology.ApicId >> coreBits, CpuTopoType.Package, pkgMask));
                return;
            }

            // Topology Extensions
            CpuIdRegister topoCpu = cpu.CpuRegisters.GetCpuId(ProcessorTopo, 0);

            Topology.ApicId = topoCpu.Result[0];
            int smt     = ((topoCpu.Result[1] >> 8) & 0xFF) + 1;
            int smtBits = Log2Pof2(smt);
            int smtMask = ~(-1 << smtBits);

            int core = topoCpu.Result[1] & 0xFF;

            // [6] describes NodesPerProcessor, but doesn't describe how to calculate the actual socket number, which
            // this software provides as the "Package". So the Package for now may not reflect the number of sockets if
            // NodesPerProcessor is non-zero (1 node per processor).

            int die = topoCpu.Result[2] & 0xFF;  // AMD calls this the NodeId.

            Topology.CoreTopology.Add(new CpuTopo(Topology.ApicId & smtMask, CpuTopoType.Smt, smtMask));
            Topology.CoreTopology.Add(new CpuTopo(core, CpuTopoType.Core, coreMask));
            Topology.CoreTopology.Add(new CpuTopo(die, CpuTopoType.Node, coreMask));
            Topology.CoreTopology.Add(new CpuTopo(Topology.ApicId >> coreBits, CpuTopoType.Package, pkgMask));
        }
Пример #3
0
        private void GetExtendedTopology(BasicCpu cpu, int leaf)
        {
            int lwidth = 0;
            int level  = 0;

            CpuIdRegister topo = cpu.CpuRegisters.GetCpuId(leaf, level);

            while (topo != null)
            {
                int ltype = (topo.Result[2] >> 8) & 0xFF;
                if (ltype == 0)
                {
                    break;
                }

                int cwidth = topo.Result[0] & 0xF;
                int width  = cwidth - lwidth;
                int mask   = ~(-1 << width);
                int id     = (int)((Topology.ApicId >> lwidth) & mask);

                Topology.CoreTopology.Add(new CpuTopo(id, (CpuTopoType)ltype, mask));

                level++;
                lwidth = cwidth;
                topo   = cpu.CpuRegisters.GetCpuId(leaf, level);
            }

            topo = cpu.CpuRegisters.GetCpuId(FeatureInformationFunction, 0);
            int pwidth = Log2Pof2((topo.Result[1] >> 16) & 0xFF);
            int pmask  = -1 << pwidth;

            Topology.CoreTopology.Add(new CpuTopo(Topology.ApicId >> pwidth, CpuTopoType.Package, pmask));
        }
Пример #4
0
        private void GetLegacyCacheL1Instruction(BasicCpu cpu)
        {
            if (cpu.ExtendedFunctionCount < CacheTlb - MaxExtendedFunction)
            {
                return;
            }
            CpuIdRegister cacheTlb = cpu.CpuRegisters.GetCpuId(CacheTlb, 0);

            if (cacheTlb == null)
            {
                return;
            }

            int ways = (cacheTlb.Result[3] >> 16) & 0xFF;

            if (ways == 0)
            {
                return;
            }

            if (ways == 255)
            {
                ways = 0;
            }
            int lineSize    = cacheTlb.Result[3] & 0xFF;
            int linesPerTag = (cacheTlb.Result[3] >> 8) & 0xFF;
            int size        = (cacheTlb.Result[3] >> 24) & 0xFF;

            Topology.CacheTopology.Add(new CacheTopoCpu(1, CacheType.Instruction, ways, lineSize * linesPerTag, size));
        }
Пример #5
0
            public static string GetType(AuthenticAmdCpu cpu)
            {
                int brand = GetBrand(cpu);

                if (brand == 0)
                {
                    return("AMD Engineering Sample");
                }

                int str1 = (brand & 0x780000) >> 19;
                int str2 = (brand & 0xF00) >> 8;
                int pm   = ((brand & 0x7F000) >> 12) - 1;
                int pg   = (brand & 0x800000) >> 23;

                CpuIdRegister ext81Reg = cpu.Registers.GetCpuId(GenericIntelCpuBase.ExtendedInformationFunction, 0);
                int           pkgType  = (ext81Reg.Result[1] >> 28) & 0xF;

                CpuIdRegister ext88Reg = cpu.Registers.GetCpuId(GenericIntelCpuBase.ExtendedLmApicId, 0);
                int           nc       = ext88Reg.Result[2] & 0xFF;

                string pma = string.Format("{0:D02}", pm);
                string s1  = Family11hTree[pkgType][1][pg][nc][str1].Value;

                if (!string.IsNullOrEmpty(s1))
                {
                    string s2 = Family11hTree[pkgType][2][pg][nc][str2].Value;
                    if (string.IsNullOrEmpty(s2))
                    {
                        return(string.Format("{0}{1}", s1, pma));
                    }
                    return(string.Format("{0}{1}{2}", s1, pma, s2));
                }
                return("AMD Processor Model Unknown");
            }
Пример #6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CpuRegisters"/> class.
        /// </summary>
        /// <param name="data">The CPUID data.</param>
        /// <param name="offset">The offset into <paramref name="data"/> for the node in question.</param>
        /// <param name="length">The length of the cpu data <paramref name="data"/> for the node in question.</param>
        /// <exception cref="ArgumentNullException"><paramref name="data"/> is <see langword="null"/>.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="offset"/> is negative</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="length"/> is negative</exception>
        /// <exception cref="ArgumentException">
        /// The <paramref name="length"/> and <paramref name="offset"/> would exceed the boundaries of the array/buffer
        /// <paramref name="data"/>.
        /// </exception>
        /// <remarks>
        /// Creates CPU data based on the native CPU data read.
        /// </remarks>
        public CpuRegisters(CpuIdLib.CpuIdInfo[] data, int offset, int length)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(offset), "offset is negative");
            }
            if (length < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(length), "length is negative");
            }
            if (offset > data.Length - length)
            {
                throw new ArgumentException("The length and offset would exceed the boundaries of the array/buffer");
            }

            for (int i = 0; i < length; i++)
            {
                int           r      = offset + i;
                CpuIdRegister result = new CpuIdRegister(data[r].veax, data[r].vecx,
                                                         new int[] { data[r].peax, data[r].pebx, data[r].pecx, data[r].pedx });
                AddRegister(result);
            }
        }
Пример #7
0
 private int GetMaxNumberOfLogicalProcessors(BasicCpu cpu)
 {
     if (Features["HTT"])
     {
         CpuIdRegister apic = cpu.CpuRegisters.GetCpuId(FeatureInformationFunction, 0);
         return((apic.Result[1] >> 16) & 0xFF);
     }
     return(1);
 }
Пример #8
0
        private void GetLegacyCacheL1InstructionTlb(BasicCpu cpu)
        {
            if (cpu.ExtendedFunctionCount < CacheTlb - MaxExtendedFunction)
            {
                return;
            }
            CpuIdRegister cacheTlb = cpu.CpuRegisters.GetCpuId(CacheTlb, 0);

            if (cacheTlb == null)
            {
                return;
            }

            int ways2m = (cacheTlb.Result[0] >> 8) & 0xFF;

            if (ways2m != 0)
            {
                if (ways2m == 255)
                {
                    ways2m = 0;
                }
                int entries2m = cacheTlb.Result[0] & 0xFF;
                Topology.CacheTopology.Add(new CacheTopoTlb(1, CacheType.InstructionTlb2M4M, ways2m, entries2m));
            }

            int ways4k = (cacheTlb.Result[1] >> 8) & 0xFF;

            if (ways4k != 0)
            {
                if (ways4k == 255)
                {
                    ways4k = 0;
                }
                int entries4k = cacheTlb.Result[1] & 0xFF;
                Topology.CacheTopology.Add(new CacheTopoTlb(1, CacheType.InstructionTlb4k, ways4k, entries4k));
            }

            if (cpu.ExtendedFunctionCount < CacheTlb1G - MaxExtendedFunction)
            {
                return;
            }
            CpuIdRegister cacheTlb1g = cpu.CpuRegisters.GetCpuId(CacheTlb1G, 0);

            if (cacheTlb1g == null)
            {
                return;
            }

            int ways1g = GetL2Associativity((cacheTlb1g.Result[0] >> 12) & 0xF);

            if (ways1g >= 0)
            {
                int entries1g = cacheTlb1g.Result[0] & 0xFFF;
                Topology.CacheTopology.Add(new CacheTopoTlb(1, CacheType.InstructionTlb1G, ways1g, entries1g));
            }
        }
Пример #9
0
 private string GetReservedFeatureName(CpuIdRegister register, int result, int bit)
 {
     if (register.SubFunction == 0)
     {
         return(string.Format("CPUID({0:X2}h).{1}[{2}]",
                              register.Function, GetRegisterName(result), bit));
     }
     return(string.Format("CPUID(EAX={0:X2}h,ECX={1:X2}h).{2}[{3}]",
                          register.Function, register.SubFunction, GetRegisterName(result), bit));
 }
Пример #10
0
        /// <summary>
        /// Gets the cache topology leaf.
        /// </summary>
        /// <param name="leaf">The leaf number to use.</param>
        /// <exception cref="NotSupportedException">
        /// A cache entry is fully associative, with the number of sets not one.
        /// </exception>
        /// <remarks>
        /// The Intel leaf 4, and AMD leaf 8000001D have the same implementation, this method provides for common code
        /// between the two. If the exception <see cref="NotSupportedException"/> occurs, this should be reported with a
        /// CPUID dump for investigation.
        /// </remarks>
        protected void GetCacheTopologyLeaf(int leaf)
        {
            int           subleaf = 0;
            CpuIdRegister cache   = m_Cpu.CpuRegisters.GetCpuId(leaf, subleaf);

            while (cache != null && (cache.Result[0] & 0xF) != 0)
            {
                int ltype = cache.Result[0] & 0xF;

                CacheType ctype = CacheType.Invalid;
                switch (ltype)
                {
                case 1:
                    ctype = CacheType.Data;
                    break;

                case 2:
                    ctype = CacheType.Instruction;
                    break;

                case 3:
                    ctype = CacheType.Unified;
                    break;
                }

                if (ctype != CacheType.Invalid)
                {
                    bool fullyAssoc = (cache.Result[0] & 0x200) != 0;
                    int  sets       = cache.Result[2] + 1;

                    if (fullyAssoc && sets != 1)
                    {
                        throw new NotSupportedException("A cache entry is fully associative, with the number of sets not one");
                    }

                    int level      = (cache.Result[0] >> 5) & 0x7;
                    int lineSize   = (cache.Result[1] & 0xFFF) + 1;
                    int partitions = ((cache.Result[1] >> 12) & 0x3FF) + 1;
                    int ways       = ((cache.Result[1] >> 22) & 0x3FF) + 1;

                    CacheTopoCpu cacheTopoCpu = new CacheTopoCpu(level, ctype, ways, lineSize, sets, partitions);

                    int numSharingCache = Log2Pof2(((cache.Result[0] >> 14) & 0xFFF) + 1);
                    cacheTopoCpu.Mask = ~(-1 << numSharingCache);
                    Topology.CacheTopology.Add(cacheTopoCpu);
                }

                subleaf++;
                cache = m_Cpu.CpuRegisters.GetCpuId(leaf, subleaf);
            }
        }
Пример #11
0
        public override CpuIdRegister GetCpuId(int function, int subfunction)
        {
            CpuIdRegister result = base.GetCpuId(function, subfunction);

            if (result == null)
            {
                // It's not cached, so query the CPU for it. Note, we assume that each EAX/ECX pair always returns the
                // same result for the same CPU core/thread.
                CpuIdLib.cpuid(function, subfunction, out int eax, out int ebx, out int ecx, out int edx);
                result = new CpuIdRegister(function, subfunction, new int[] { eax, ebx, ecx, edx });
                AddRegister(result);
            }

            return(result);
        }
Пример #12
0
        private void GetLegacyCacheL2DataTlb(BasicCpu cpu)
        {
            if (cpu.ExtendedFunctionCount < CacheL2Tlb - MaxExtendedFunction)
            {
                return;
            }
            CpuIdRegister cacheL2Tlb = cpu.CpuRegisters.GetCpuId(CacheL2Tlb, 0);

            if (cacheL2Tlb == null)
            {
                return;
            }

            int ways2m = GetL2Associativity((cacheL2Tlb.Result[0] >> 28) & 0xF);

            if (ways2m >= 0)
            {
                int entries2m = (cacheL2Tlb.Result[0] >> 16) & 0xFFF;
                Topology.CacheTopology.Add(new CacheTopoTlb(2, CacheType.DataTlb2M4M, ways2m, entries2m));
            }

            int ways4k = GetL2Associativity((cacheL2Tlb.Result[1] >> 28) & 0xF);

            if (ways4k >= 0)
            {
                int entries4k = (cacheL2Tlb.Result[1] >> 16) & 0xFFF;
                Topology.CacheTopology.Add(new CacheTopoTlb(2, CacheType.DataTlb4k, ways4k, entries4k));
            }

            if (cpu.ExtendedFunctionCount < CacheTlb1G - MaxExtendedFunction)
            {
                return;
            }
            CpuIdRegister cacheTlb1g = cpu.CpuRegisters.GetCpuId(CacheTlb1G, 0);

            if (cacheTlb1g == null)
            {
                return;
            }

            int ways1g = GetL2Associativity((cacheTlb1g.Result[1] >> 28) & 0xF);

            if (ways1g >= 0)
            {
                int entries1g = (cacheTlb1g.Result[1] >> 16) & 0xFFF;
                Topology.CacheTopology.Add(new CacheTopoTlb(2, CacheType.DataTlb1G, ways1g, entries1g));
            }
        }
Пример #13
0
        protected void AddRegister(CpuIdRegister result)
        {
            if (result == null)
            {
                throw new ArgumentNullException(nameof(result));
            }

            if (!m_Registers.TryGetValue(result.Function, out List <CpuIdRegister> registers))
            {
                registers = new List <CpuIdRegister>();
                m_Registers.Add(result.Function, registers);
            }

            registers.Add(result);
            m_RegisterList.Add(result);
        }
Пример #14
0
        /// <summary>
        /// Tests a bit in the feature flag.
        /// </summary>
        /// <param name="feature">The name of the CPU feature, e.g. "FPU".</param>
        /// <param name="register">The feature register obtained from a query of CPUID.</param>
        /// <param name="result">The register to query, 0 is EAX, to 3 for EDX.</param>
        /// <param name="bit">The bit to test for.</param>
        /// <param name="invert">Inverts the result if <see langword="true"/>, otherwise feature is set if the bit is one.</param>
        protected void TestFeature(string feature, CpuIdRegister register, int result, int bit, bool invert)
        {
            bool value = (register.Result[result] & (1 << bit)) != 0;

            if (invert)
            {
                value = !value;
            }
            Features[feature] = value;

#if DEBUG
            if (!m_MainFunction.Set(register.Function, register.SubFunction, result, 1 << bit))
            {
                throw new InvalidOperationException("Bit was already set");
            }
#endif
        }
Пример #15
0
        private void CheckReservedBitMask(CpuIdRegister register, int result, int mask)
        {
            int  bit       = 0;
            uint checkMask = unchecked ((uint)mask);

            while (checkMask != 0)
            {
                if ((checkMask & 0x01) != 0 &&
                    !m_MainFunction.Set(register.Function, register.SubFunction, result, 1 << bit))
                {
                    string message = string.Format("CPUID[EAX={0:X2}h,ECX={1:X2}h].{2}[{3}] already set",
                                                   register.Function, register.SubFunction, GetRegisterName(result), bit);
                    throw new InvalidOperationException(message);
                }
                checkMask >>= 1;
                bit++;
            }
        }
Пример #16
0
        /// <summary>
        /// Adds a bit field that a feature is reserved, only if it is set.
        /// </summary>
        /// <param name="register">The feature register obtained from a query of CPUID.</param>
        /// <param name="result">The register to query, 0 is EAX, to 3 for EDX.</param>
        /// <param name="mask">The bit mask of reserved bits set to 1.</param>
        /// <remarks>
        /// This should be used after testing for all features, to ensure that any unknown features are tested for and
        /// set with the generic name <c>CPUID(XXh).REG[bit]</c> or <c>CPUID(EAX=XXh,ECX=XXh).REG[bit]</c>, where the
        /// REG is one of EAX, EBX, ECX, EDX and the bit is the bit given in <paramref name="mask"/> which is a bit
        /// field of reserved features. CPUs in the future may set these bits and so it's useful to see if there are new
        /// features which are not defined. Bits that are "don't care" in the specifications should not be part of the
        /// bit field, but as most bits are "reserved" are usually zero, so that future processors can set them as set
        /// when a new feature is defined.
        /// </remarks>
        protected void ReservedFeature(CpuIdRegister register, int result, int mask)
        {
#if DEBUG
            CheckReservedBitMask(register, result, mask);
#endif

            int  bit       = 0;
            uint checkMask = unchecked ((uint)(mask & register.Result[result]));
            while (checkMask != 0)
            {
                if ((checkMask & 0x01) != 0)
                {
                    Features[GetReservedFeatureName(register, result, bit)] = true;
                }
                checkMask >>= 1;     // Unsigned means zero is rolled into MSB, so we don't need to clear the MSB.
                bit++;
            }
        }
Пример #17
0
        private string GetVendorId(CpuIdRegister register)
        {
            char[] vendorId = new char[12];
            int    ebx      = register.Result[1];
            int    ecx      = register.Result[2];
            int    edx      = register.Result[3];

            vendorId[0]  = (char)(ebx & 0xFF);
            vendorId[1]  = (char)((ebx >> 8) & 0xFF);
            vendorId[2]  = (char)((ebx >> 16) & 0xFF);
            vendorId[3]  = (char)((ebx >> 24) & 0xFF);
            vendorId[4]  = (char)(edx & 0xFF);
            vendorId[5]  = (char)((edx >> 8) & 0xFF);
            vendorId[6]  = (char)((edx >> 16) & 0xFF);
            vendorId[7]  = (char)((edx >> 24) & 0xFF);
            vendorId[8]  = (char)(ecx & 0xFF);
            vendorId[9]  = (char)((ecx >> 8) & 0xFF);
            vendorId[10] = (char)((ecx >> 16) & 0xFF);
            vendorId[11] = (char)((ecx >> 24) & 0xFF);
            return(new string(vendorId));
        }
Пример #18
0
        private void GetProcessorSignature(BasicCpu cpu)
        {
            if (cpu.FunctionCount == 0)
            {
                return;
            }

            CpuIdRegister feature = cpu.CpuRegisters.GetCpuId(FeatureInformationFunction, 0);

            if (feature == null)
            {
                return;
            }

            m_ProcessorSignature = feature.Result[0] & 0x0FFF3FFF;
            m_ExtendedFamily     = (m_ProcessorSignature >> 20) & 0xFF;
            m_ExtendedModel      = (m_ProcessorSignature >> 16) & 0xF;
            m_ProcessorType      = (m_ProcessorSignature >> 12) & 0x3;
            m_FamilyCode         = (m_ProcessorSignature >> 8) & 0xF;
            m_ModelNumber        = (m_ProcessorSignature >> 4) & 0xF;
            m_SteppingId         = m_ProcessorSignature & 0xF;
        }
Пример #19
0
        private void AddCpuRegister(XmlNode registerNode)
        {
            if (!TryGetHexValue(registerNode.Attributes["eax"]?.Value, out int function))
            {
                return;
            }
            if (!TryGetHexValue(registerNode.Attributes["ecx"]?.Value, out int subfunction))
            {
                return;
            }
            string registerOutput = registerNode.InnerText;

            if (string.IsNullOrWhiteSpace(registerOutput))
            {
                return;
            }
            string[] registerValues = registerOutput.Split(',');
            if (registerValues.Length != 4)
            {
                return;
            }

            int[] registers = new int[4];
            int   i         = 0;

            foreach (string registerValue in registerValues)
            {
                if (!TryGetHexValue(registerValue, out registers[i]))
                {
                    return;
                }
                i++;
            }

            CpuIdRegister result = new CpuIdRegister(function, subfunction, registers);

            AddRegister(result);
        }
Пример #20
0
        private void GetProcessorSignature(BasicCpu cpu)
        {
            if (cpu.FunctionCount == 0)
            {
                return;
            }

            CpuIdRegister feature = cpu.CpuRegisters.GetCpuId(FeatureInformationFunction, 0);

            if (feature == null)
            {
                return;
            }

            int eax = feature.Result[0];
            int ebx = feature.Result[1];

            if ((eax & 0xf00) == 0x300)
            {
                // Sounds crazy, but someone's emulating an i386. Major Stepping is the Model property.
                m_ProcessorSignature = eax & 0xFFFF;
                m_ProcessorType      = (m_ProcessorSignature >> 12) & 0xF;
                m_FamilyCode         = (m_ProcessorSignature >> 8) & 0xF;
                m_ModelNumber        = (m_ProcessorSignature >> 4) & 0xF;
                m_SteppingId         = m_ProcessorSignature & 0xF;
            }
            else
            {
                m_ProcessorSignature = eax & 0x0FFF3FFF;
                m_ExtendedFamily     = (m_ProcessorSignature >> 20) & 0xFF;
                m_ExtendedModel      = (m_ProcessorSignature >> 16) & 0xF;
                m_ProcessorType      = (m_ProcessorSignature >> 12) & 0x3;
                m_FamilyCode         = (m_ProcessorSignature >> 8) & 0xF;
                m_ModelNumber        = (m_ProcessorSignature >> 4) & 0xF;
                m_SteppingId         = m_ProcessorSignature & 0xF;
                m_Brand = ebx & 0xFF;
            }
        }
Пример #21
0
        private void FindExtendedFeatures(BasicCpu cpu)
        {
            if (cpu.ExtendedFunctionCount < 1)
            {
                return;
            }
            CpuIdRegister extfeat = cpu.CpuRegisters.GetCpuId(ExtendedInformationFunction, 0);

            if (extfeat != null)
            {
                TestFeature("AHF64", extfeat, 2, 0);
                TestFeature("ABM", extfeat, 2, 5);
                TestFeature("PREFETCHW", extfeat, 2, 8);
                ReservedFeature(extfeat, 2, unchecked ((int)0xFFFFFEDE));

                TestFeature("SYSCALL", extfeat, 3, 11);
                TestFeature("XD", extfeat, 3, 20);
                TestFeature("1GB_PAGE", extfeat, 3, 26);
                TestFeature("RDTSCP", extfeat, 3, 27);
                TestFeature("LM", extfeat, 3, 29);
                ReservedFeature(extfeat, 3, unchecked ((int)0xD3EFF7FF));
            }
        }
Пример #22
0
        private void GetLegacyTopology(CpuIdRegister apic, CpuIdRegister topo)
        {
            int maxApic = (apic.Result[1] >> 16) & 0xFF;
            int maxCore = ((topo.Result[0] >> 26) & 0x3F) + 1;

            int  smtWidth = Log2Pof2(maxApic / maxCore);
            long smtMask  = ~(-1 << smtWidth);
            long smtId    = Topology.ApicId & smtMask;

            Topology.CoreTopology.Add(new CpuTopo(smtId, CpuTopoType.Smt, smtMask));

            int  coreWidth = Log2Pof2(maxCore);
            long coreMask  = ~(-1 << coreWidth);
            long coreId    = (Topology.ApicId >> smtWidth) & coreMask;

            Topology.CoreTopology.Add(new CpuTopo(coreId, CpuTopoType.Core, coreMask));

            int  pkgWidth = smtWidth + coreWidth; // Should be the same as maxApic.
            long pkgId    = Topology.ApicId >> pkgWidth;
            long pkgMask  = -1 << pkgWidth;

            Topology.CoreTopology.Add(new CpuTopo(pkgId, CpuTopoType.Package, pkgMask));
        }
Пример #23
0
        private void GetCacheTopology(BasicCpu cpu)
        {
            if (cpu.FunctionCount >= LegacyCache)
            {
                bool          leafTlb      = false;
                bool          leafCpu      = false;
                bool          noExtraCache = false;
                CpuIdRegister cache        = cpu.CpuRegisters.GetCpuId(LegacyCache, 0);
                if (cache != null && (cache.Result[0] & 0xFF) == 0x01)
                {
                    GetLegacyCacheTopology(cache.Result[0] & unchecked ((int)0xFFFFFF00), ref leafCpu, ref leafTlb, ref noExtraCache);
                    GetLegacyCacheTopology(cache.Result[1], ref leafCpu, ref leafTlb, ref noExtraCache);
                    GetLegacyCacheTopology(cache.Result[2], ref leafCpu, ref leafTlb, ref noExtraCache);
                    GetLegacyCacheTopology(cache.Result[3], ref leafCpu, ref leafTlb, ref noExtraCache);
                }
                FixLegacyCacheMask(noExtraCache);

                if (leafCpu && cpu.FunctionCount > LegacyTopology)
                {
                    GetCacheTopologyLeaf(LegacyTopology);
                }
            }
        }
Пример #24
0
        private void Initialize(ICpuRegisters register)
        {
            CpuRegisters = register;

            CpuIdRegister vendorFunction = register.GetCpuId(VendorIdFunction, 0);

            if (vendorFunction == null)
            {
                return;
            }
            FunctionCount = vendorFunction.Result[0];
            VendorId      = GetVendorId(vendorFunction);

            CpuIdRegister extendedFunction = register.GetCpuId(ExtendedFunction, 0);

            if (extendedFunction == null)
            {
                return;
            }
            if ((extendedFunction.Result[0] & ExtendedFunction) != 0)
            {
                ExtendedFunctionCount = extendedFunction.Result[0] & 0x7FFFFFFF;
            }
        }
Пример #25
0
        private void FindFeatures(BasicCpu cpu)
        {
            if (cpu.FunctionCount < FeatureInformationFunction)
            {
                return;
            }

            CpuIdRegister features = cpu.CpuRegisters.GetCpuId(FeatureInformationFunction, 0);

            if (features != null)
            {
                TestFeature("FPU", features, 3, 0);
                TestFeature("VME", features, 3, 1);
                TestFeature("DE", features, 3, 2);
                TestFeature("PSE", features, 3, 3);
                TestFeature("TSC", features, 3, 4);
                TestFeature("MSR", features, 3, 5);
                TestFeature("PAE", features, 3, 6);
                TestFeature("MCE", features, 3, 7);
                TestFeature("CX8", features, 3, 8);
                TestFeature("APIC", features, 3, 9);
                TestFeature("SEP", features, 3, 11);
                TestFeature("MTRR", features, 3, 12);
                TestFeature("PGE", features, 3, 13);
                TestFeature("MCA", features, 3, 14);
                TestFeature("CMOV", features, 3, 15);
                TestFeature("PAT", features, 3, 16);
                TestFeature("PSE-36", features, 3, 17);
                TestFeature("PSN", features, 3, 18);
                TestFeature("CLFSH", features, 3, 19);
                TestFeature("DS", features, 3, 21);
                TestFeature("ACPI", features, 3, 22);
                TestFeature("MMX", features, 3, 23);
                TestFeature("FXSR", features, 3, 24);
                TestFeature("SSE", features, 3, 25);
                TestFeature("SSE2", features, 3, 26);
                TestFeature("SS", features, 3, 27);
                TestFeature("HTT", features, 3, 28);
                TestFeature("TM", features, 3, 29);
                TestFeature("IA64", features, 3, 30);                // Wikipedia https://en.wikipedia.org/wiki/CPUID
                TestFeature("PBE", features, 3, 31);
                if (Features["SEP"] && ProcessorSignature < 0x633)
                {
                    Features["SEP"] = false;
                }
                ReservedFeature(features, 3, 0x00100400);

                TestFeature("SSE3", features, 2, 0);
                TestFeature("PCLMULQDQ", features, 2, 1);
                TestFeature("DTES64", features, 2, 2);
                TestFeature("MONITOR", features, 2, 3);
                TestFeature("DS-CPL", features, 2, 4);
                TestFeature("VMX", features, 2, 5);
                TestFeature("SMX", features, 2, 6);
                TestFeature("EIST", features, 2, 7);
                TestFeature("TM2", features, 2, 8);
                TestFeature("SSSE3", features, 2, 9);
                TestFeature("CNXT-ID", features, 2, 10);
                TestFeature("SDBG", features, 2, 11);
                TestFeature("FMA", features, 2, 12);
                TestFeature("CMPXCHG16B", features, 2, 13);
                TestFeature("xTPR", features, 2, 14);
                TestFeature("PDCM", features, 2, 15);
                TestFeature("PCID", features, 2, 17);
                TestFeature("DCA", features, 2, 18);
                TestFeature("SSE4.1", features, 2, 19);
                TestFeature("SSE4.2", features, 2, 20);
                TestFeature("x2APIC", features, 2, 21);
                TestFeature("MOVBE", features, 2, 22);
                TestFeature("POPCNT", features, 2, 23);
                TestFeature("TSC-DEADLINE", features, 2, 24);
                TestFeature("AESNI", features, 2, 25);
                TestFeature("XSAVE", features, 2, 26);
                TestFeature("OSXSAVE", features, 2, 27);
                TestFeature("AVX", features, 2, 28);
                TestFeature("F16C", features, 2, 29);
                TestFeature("RDRAND", features, 2, 30);
                TestFeature("HYPERVISOR", features, 2, 31);          // Wikipedia https://en.wikipedia.org/wiki/CPUID
                ReservedFeature(features, 2, 0x00010000);
            }

            FindExtendedFeatures(cpu);

            if (cpu.FunctionCount < ExtendedFeatureFunction)
            {
                return;
            }
            CpuIdRegister features7 = cpu.CpuRegisters.GetCpuId(ExtendedFeatureFunction, 0);

            if (features7 != null)
            {
                TestFeature("FSGSBASE", features7, 1, 0);
                TestFeature("IA32_TSC_ADJUST", features7, 1, 1);
                TestFeature("SGX", features7, 1, 2);
                TestFeature("BMI1", features7, 1, 3);
                TestFeature("HLE", features7, 1, 4);
                TestFeature("AVX2", features7, 1, 5);
                TestFeature("FDP_EXCPTN_ONLY", features7, 1, 6);
                TestFeature("SMEP", features7, 1, 7);
                TestFeature("BMI2", features7, 1, 8);
                TestFeature("ERMS", features7, 1, 9);
                TestFeature("INVPCID", features7, 1, 10);
                TestFeature("RTM", features7, 1, 11);
                TestFeature("PQM", features7, 1, 12);
                TestFeature("FPU-CS Dep", features7, 1, 13);
                TestFeature("MPX", features7, 1, 14);
                TestFeature("PQE", features7, 1, 15);
                TestFeature("AVX512F", features7, 1, 16);
                TestFeature("AVX512DQ", features7, 1, 17);
                TestFeature("RDSEED", features7, 1, 18);
                TestFeature("ADX", features7, 1, 19);
                TestFeature("SMAP", features7, 1, 20);
                TestFeature("AVX512_IFMA", features7, 1, 21);
                TestFeature("CLFLUSHOPT", features7, 1, 23);
                TestFeature("CLWB", features7, 1, 24);
                TestFeature("INTEL_PT", features7, 1, 25);
                TestFeature("AVX512PF", features7, 1, 26);
                TestFeature("AVX512ER", features7, 1, 27);
                TestFeature("AVX512CD", features7, 1, 28);
                TestFeature("SHA", features7, 1, 29);
                TestFeature("AVX512BW", features7, 1, 30);
                TestFeature("AVX512VL", features7, 1, 31);
                ReservedFeature(features7, 1, 0x00400000);

                TestFeature("PREFETCHWT1", features7, 2, 0);
                TestFeature("AVX512_VBMI", features7, 2, 1);
                TestFeature("UMIP", features7, 2, 2);
                TestFeature("PKU", features7, 2, 3);
                TestFeature("OSPKE", features7, 2, 4);
                TestFeature("WAITPKG", features7, 2, 5);
                TestFeature("AVX512_VBMI2", features7, 2, 6);
                TestFeature("CET_SS", features7, 2, 7);
                TestFeature("GFNI", features7, 2, 8);
                TestFeature("VAES", features7, 2, 9);
                TestFeature("VPCLMULQDQ", features7, 2, 10);
                TestFeature("AVX512_VNNI", features7, 2, 11);
                TestFeature("AVX512_BITALG", features7, 2, 12);
                TestFeature("AVX512_VPOPCNTDQ", features7, 2, 14);
                TestFeature("5L_PAGE", features7, 2, 15);              // Wikipedia https://en.wikipedia.org/wiki/CPUID
                TestFeature("RDPID", features7, 2, 22);
                TestFeature("CLDEMOTE", features7, 2, 25);
                TestFeature("MOVDIRI", features7, 2, 27);
                TestFeature("MOVDIR64B", features7, 2, 28);
                TestFeature("ENQCMD", features7, 2, 29);               // Wikipedia https://en.wikipedia.org/wiki/CPUID
                TestFeature("SGX_LC", features7, 2, 30);
                TestFeature("PKS", features7, 2, 31);
                ReservedFeature(features7, 2, 0x05BF2000);

                TestFeature("AVX512_4VNNIW", features7, 3, 2);
                TestFeature("AVX512_4FMAPS", features7, 3, 3);
                TestFeature("FSRM", features7, 3, 4);
                TestFeature("AVX512_VP2INTERSECT", features7, 3, 8);   // Wikipedia https://en.wikipedia.org/wiki/CPUID
                TestFeature("SRBDS_CTRL", features7, 3, 9);            // Wikipedia https://en.wikipedia.org/wiki/CPUID
                TestFeature("MD_CLEAR", features7, 3, 10);
                TestFeature("TSX_FORCE_ABORT", features7, 3, 13);      // Wikipedia https://en.wikipedia.org/wiki/CPUID
                TestFeature("SERIALIZE", features7, 3, 14);            // Wikipedia https://en.wikipedia.org/wiki/CPUID
                TestFeature("Hybrid", features7, 3, 15);
                TestFeature("TSXLDTRK", features7, 3, 16);             // Wikipedia https://en.wikipedia.org/wiki/CPUID
                TestFeature("PCONFIG", features7, 3, 18);              // Wikipedia https://en.wikipedia.org/wiki/CPUID
                TestFeature("LBR", features7, 3, 19);                  // Wikipedia https://en.wikipedia.org/wiki/CPUID
                TestFeature("CET_IBT", features7, 3, 20);
                TestFeature("AMX_BF16", features7, 3, 22);             // Wikipedia https://en.wikipedia.org/wiki/CPUID
                TestFeature("AMX_TILE", features7, 3, 24);             // Wikipedia https://en.wikipedia.org/wiki/CPUID
                TestFeature("AMX_INT8", features7, 3, 25);             // Wikipedia https://en.wikipedia.org/wiki/CPUID
                TestFeature("IBRS_IBPB", features7, 3, 26);
                TestFeature("STIBP", features7, 3, 27);
                TestFeature("L1D_FLUSH", features7, 3, 28);
                TestFeature("IA32_ARCH_CAPABILITIES", features7, 3, 29);
                TestFeature("IA32_CORE_CAPABILITIES", features7, 3, 30);
                TestFeature("SSBD", features7, 3, 31);
                ReservedFeature(features7, 3, 0x00A218E3);

                if (features7.Result[0] > 0)
                {
                    CpuIdRegister features7s1 = cpu.CpuRegisters.GetCpuId(ExtendedFeatureFunction, 1);
                    if (features7s1 != null)
                    {
                        TestFeature("AVX_BF16", features7s1, 0, 5);         // Wikipedia https://en.wikipedia.org/wiki/CPUID
                        ReservedFeature(features7s1, 0, unchecked ((int)0xFFFFFFDF));

                        ReservedFeature(features7s1, 1, unchecked ((int)0xFFFFFFFF));
                        ReservedFeature(features7s1, 2, unchecked ((int)0xFFFFFFFF));
                        ReservedFeature(features7s1, 3, unchecked ((int)0xFFFFFFFF));
                    }

                    for (int subfunction = 2; subfunction < features7.Result[0]; subfunction++)
                    {
                        CpuIdRegister features7sX = cpu.CpuRegisters.GetCpuId(ExtendedFeatureFunction, subfunction);
                        if (features7sX != null)
                        {
                            ReservedFeature(features7sX, 0, unchecked ((int)0xFFFFFFFF));
                            ReservedFeature(features7sX, 1, unchecked ((int)0xFFFFFFFF));
                            ReservedFeature(features7sX, 2, unchecked ((int)0xFFFFFFFF));
                            ReservedFeature(features7sX, 3, unchecked ((int)0xFFFFFFFF));
                        }
                    }
                }
            }

            if (cpu.FunctionCount < ExtendedProcessorState)
            {
                return;
            }
            CpuIdRegister features13 = cpu.CpuRegisters.GetCpuId(ExtendedProcessorState, 1);

            if (features13 != null)
            {
                TestFeature("XSAVEOPT", features13, 0, 0);
                TestFeature("XSAVEC", features13, 0, 1);
                TestFeature("XGETBV", features13, 0, 2);
                TestFeature("XSAVES", features13, 0, 3);
            }
        }
Пример #26
0
        private void GetCpuTopology(BasicCpu cpu)
        {
            if (!Features["HTT"] || !Features["APIC"])
            {
                if (Features["x2APIC"] && cpu.FunctionCount >= ExtendedTopology)
                {
                    CpuIdRegister x2apic = cpu.CpuRegisters.GetCpuId(ExtendedTopology, 0);
                    Topology.ApicId = x2apic.Result[3];
                }
                else if (cpu.FunctionCount >= FeatureInformationFunction)
                {
                    CpuIdRegister apic = cpu.CpuRegisters.GetCpuId(FeatureInformationFunction, 0);
                    Topology.ApicId = (apic.Result[1] >> 24) & 0xFF;
                }
                else
                {
                    Topology.ApicId = -1;
                    return;
                }

                int mnlpbits = Log2Pof2(GetMaxNumberOfLogicalProcessors(cpu));
                Topology.CoreTopology.Add(new CpuTopo(0, CpuTopoType.Core, ~(-1 << mnlpbits)));
                Topology.CoreTopology.Add(new CpuTopo(Topology.ApicId, CpuTopoType.Package, -1 << mnlpbits));
                return;
            }

            if (Features["x2APIC"] && cpu.FunctionCount >= ExtendedTopology2)
            {
                CpuIdRegister x2apic = cpu.CpuRegisters.GetCpuId(ExtendedTopology, 0);
                Topology.ApicId = x2apic.Result[3];
                GetExtendedTopology(cpu, ExtendedTopology2);
            }
            else if (Features["x2APIC"] && cpu.FunctionCount >= ExtendedTopology)
            {
                CpuIdRegister x2apic = cpu.CpuRegisters.GetCpuId(ExtendedTopology, 0);
                Topology.ApicId = x2apic.Result[3];
                GetExtendedTopology(cpu, ExtendedTopology);
            }
            else if (cpu.FunctionCount >= LegacyTopology)
            {
                CpuIdRegister apic = cpu.CpuRegisters.GetCpuId(FeatureInformationFunction, 0);
                CpuIdRegister topo = cpu.CpuRegisters.GetCpuId(LegacyTopology, 0);
                Topology.ApicId = (apic.Result[1] >> 24) & 0xFF;
                GetLegacyTopology(apic, topo);
            }
            else
            {
                CpuIdRegister apic = cpu.CpuRegisters.GetCpuId(FeatureInformationFunction, 0);
                if (Features["APIC"])
                {
                    Topology.ApicId = (apic.Result[1] >> 24) & 0xFF;
                }
                else
                {
                    Topology.ApicId = 0;
                }

                int mnlpbits = Log2Pof2(GetMaxNumberOfLogicalProcessors(cpu));
                Topology.CoreTopology.Add(new CpuTopo(0, CpuTopoType.Core, ~(-1 << mnlpbits)));
                Topology.CoreTopology.Add(new CpuTopo(Topology.ApicId, CpuTopoType.Package, -1 << mnlpbits));
            }
        }
Пример #27
0
        private void FindExtendedFeatures(BasicCpu cpu)
        {
            if (cpu.ExtendedFunctionCount < 1)
            {
                return;
            }

            CpuIdRegister extfeat = cpu.CpuRegisters.GetCpuId(ExtendedInformationFunction, 0);

            if (extfeat != null)
            {
                TestFeature("AHF64", extfeat, 2, 0);
                TestFeature("CMP", extfeat, 2, 1);                   // CmpLegacy
                TestFeature("SVM", extfeat, 2, 2);
                TestFeature("ExtApicSpace", extfeat, 2, 3);
                TestFeature("AM", extfeat, 2, 4);
                TestFeature("ABM", extfeat, 2, 5);
                TestFeature("SSE4A", extfeat, 2, 6);
                TestFeature("MisAlignSSE", extfeat, 2, 7);
                TestFeature("PREFETCHW", extfeat, 2, 8);
                TestFeature("OSVW", extfeat, 2, 9);
                TestFeature("IBS", extfeat, 2, 10);
                TestFeature("XOP", extfeat, 2, 11);
                TestFeature("SKINIT", extfeat, 2, 12);
                TestFeature("WDT", extfeat, 2, 13);
                TestFeature("LWP", extfeat, 2, 15);
                TestFeature("FMA4", extfeat, 2, 16);
                TestFeature("TCE", extfeat, 2, 17);                  // [9]
                TestFeature("NODEID", extfeat, 2, 19);               // [9]
                TestFeature("TBM", extfeat, 2, 21);                  // [9]
                TestFeature("TOPX", extfeat, 2, 22);                 // TopologyExtensions
                TestFeature("PerfCtrExtCore", extfeat, 2, 23);
                TestFeature("PerfCtrExtNB", extfeat, 2, 24);
                TestFeature("StreamPerfMon", extfeat, 2, 25);        // [6a], now reserved
                TestFeature("DBE", extfeat, 2, 26);
                TestFeature("PerfTSC", extfeat, 2, 27);
                TestFeature("PerfL2I", extfeat, 2, 28);              // Sandpile.org
                TestFeature("MONITORX", extfeat, 2, 29);
                TestFeature("ADMSK", extfeat, 2, 30);                // [10]
                ReservedFeature(extfeat, 2, unchecked ((int)0x80144000));

                TestFeature("SYSCALL", extfeat, 3, 11);
                TestFeature("MP", extfeat, 3, 19);                   // [17a], now reserved
                TestFeature("XD", extfeat, 3, 20);
                TestFeature("MMXEXT", extfeat, 3, 22);
                TestFeature("FFXSR", extfeat, 3, 25);
                TestFeature("1GB_PAGE", extfeat, 3, 26);
                TestFeature("RDTSCP", extfeat, 3, 27);
                TestFeature("LM", extfeat, 3, 29);
                TestFeature("3DNowExt", extfeat, 3, 30);
                TestFeature("3DNow", extfeat, 3, 31);
                // 3DNowPrefetch ECX[8] || EDX[29] || EDX[31]
                Features["PREFETCHW"] |= Features["LM"] || Features["3DNow"];
                // The following are duplicated from 0000_0001h.EDX
                //  0: FPU       8: CX8      16: PAT      24: FXSR
                //  1: VME       9: APIC     17: PSE-36   25:
                //  2: DE       10: (RSVD)   18: (RSVD)   26:
                //  3: PSE      11: SEP      19:          27:
                //  4: TSC      12: MTRR     20:          28: (RSVD)
                //  5: MSR      13: PGE      21: (RSVD)   29:
                //  6: PAE      14: MCA      22:          30:
                //  7: MCE      15: CMOV     23: MMX      31:
                ReservedFeature(extfeat, 3, 0x10240400);
            }

            if (cpu.ExtendedFunctionCount < ExtendedLmApicId - MaxExtendedFunction)
            {
                return;
            }
            CpuIdRegister extfeat8 = cpu.CpuRegisters.GetCpuId(ExtendedLmApicId, 0);

            if (extfeat8 != null)
            {
                TestFeature("CLZERO", extfeat8, 1, 0);
                TestFeature("IRPERF", extfeat8, 1, 1);            // Instruction Retired Counter
                TestFeature("ASRFPEP", extfeat8, 1, 2);           // Error Pointer Zero/Restore
                TestFeature("INVLPGB", extfeat8, 1, 3);
                TestFeature("RDPRU", extfeat8, 1, 4);
                TestFeature("MBE", extfeat8, 1, 6);               // [10]
                TestFeature("MCOMMIT", extfeat8, 1, 8);
                TestFeature("WBNOINVD", extfeat8, 1, 9);
                TestFeature("IBPB", extfeat8, 1, 12);             // [10]
                TestFeature("INT_WBINVD", extfeat8, 1, 13);       // [10]
                TestFeature("IBRS", extfeat8, 1, 14);             // [10]
                TestFeature("STIBP", extfeat8, 1, 15);            // [10]
                TestFeature("IBRS_ALL", extfeat8, 1, 16);         // Sandpile.org
                TestFeature("STIBP_ALL", extfeat8, 1, 17);        // [10]
                TestFeature("IBRS_PREF", extfeat8, 1, 18);        // [10]
                TestFeature("IBRS_SMP", extfeat8, 1, 19);         // [10]
                TestFeature("EFER.LMSLE", extfeat8, 1, 20);
                TestFeature("INVLPGB_NESTED", extfeat8, 1, 21);
                TestFeature("PPIN", extfeat8, 1, 23);             // [10]
                TestFeature("SSBD", extfeat8, 1, 24);             // [10]
                ReservedFeature(extfeat8, 1, unchecked ((int)0xFE400CA0));
            }

            if (cpu.ExtendedFunctionCount < ExtendedEncMem - MaxExtendedFunction)
            {
                return;
            }
            CpuIdRegister extfeat1f = cpu.CpuRegisters.GetCpuId(ExtendedEncMem, 0);

            if (extfeat1f != null)
            {
                TestFeature("SME", extfeat1f, 0, 0);
                TestFeature("SEV", extfeat1f, 0, 1);
                TestFeature("PageFlushMsr", extfeat1f, 0, 2);
                TestFeature("ES", extfeat1f, 0, 3);
                TestFeature("SNP", extfeat1f, 0, 4);
                TestFeature("VMPL", extfeat1f, 0, 5);
                TestFeature("VTE", extfeat1f, 0, 16);
                ReservedFeature(extfeat1f, 0, unchecked ((int)0xFFFEFFC0));
            }
        }
Пример #28
0
        private void FindFeatures(BasicCpu cpu)
        {
            if (cpu.FunctionCount < FeatureInformationFunction)
            {
                return;
            }

            CpuIdRegister features = cpu.CpuRegisters.GetCpuId(FeatureInformationFunction, 0);

            if (features != null)
            {
                TestFeature("FPU", features, 3, 0);
                TestFeature("VME", features, 3, 1);
                TestFeature("DE", features, 3, 2);
                TestFeature("PSE", features, 3, 3);
                TestFeature("TSC", features, 3, 4);
                TestFeature("MSR", features, 3, 5);
                TestFeature("PAE", features, 3, 6);
                TestFeature("MCE", features, 3, 7);
                TestFeature("CX8", features, 3, 8);
                TestFeature("SEP", features, 3, 11);
                TestFeature("MTRR", features, 3, 12);
                TestFeature("MCA", features, 3, 14);
                TestFeature("CMOV", features, 3, 15);
                TestFeature("PAT", features, 3, 16);
                TestFeature("PSE-36", features, 3, 17);
                TestFeature("CLFSH", features, 3, 19);
                TestFeature("MMX", features, 3, 23);
                TestFeature("FXSR", features, 3, 24);
                TestFeature("SSE", features, 3, 25);
                TestFeature("SSE2", features, 3, 26);
                TestFeature("HTT", features, 3, 28);
                if (Family == 5 && Model == 0)
                {
                    // [17] says AMD K5 Model 0, bit 9 is for PGE, where bit 13 is reserved.
                    TestFeature("PGE", features, 3, 9);
                }
                else
                {
                    TestFeature("APIC", features, 3, 9);
                    TestFeature("PGE", features, 3, 13);
                }
                ReservedFeature(features, 3, unchecked ((int)0xE8740400));

                TestFeature("SSE3", features, 2, 0);
                TestFeature("PCLMULQDQ", features, 2, 1);
                TestFeature("MONITOR", features, 2, 3);
                TestFeature("SSSE3", features, 2, 9);
                TestFeature("FMA", features, 2, 12);
                TestFeature("CMPXCHG16B", features, 2, 13);
                TestFeature("PCID", features, 2, 17);
                TestFeature("SSE4.1", features, 2, 19);
                TestFeature("SSE4.2", features, 2, 20);
                TestFeature("x2APIC", features, 2, 21);                         // [8]
                TestFeature("MOVBE", features, 2, 22);
                TestFeature("POPCNT", features, 2, 23);
                TestFeature("AESNI", features, 2, 25);
                TestFeature("XSAVE", features, 2, 26);
                TestFeature("OSXSAVE", features, 2, 27);
                TestFeature("AVX", features, 2, 28);
                TestFeature("F16C", features, 2, 29);
                TestFeature("RDRAND", features, 2, 30);
                TestFeature("HYPERVISOR", features, 2, 31);
                ReservedFeature(features, 2, 0x0105CDF4);
            }

            FindExtendedFeatures(cpu);

            if (cpu.FunctionCount < ExtendedFeatureFunction)
            {
                return;
            }
            CpuIdRegister features7 = cpu.CpuRegisters.GetCpuId(ExtendedFeatureFunction, 0);

            if (features7 != null)
            {
                TestFeature("FSGSBASE", features7, 1, 0);
                TestFeature("BMI1", features7, 1, 3);
                TestFeature("AVX2", features7, 1, 5);
                TestFeature("SMEP", features7, 1, 7);
                TestFeature("BMI2", features7, 1, 8);
                TestFeature("INVPCID", features7, 1, 10);
                TestFeature("PQM", features7, 1, 12);
                TestFeature("PQE", features7, 1, 15);
                TestFeature("RDSEED", features7, 1, 18);
                TestFeature("ADX", features7, 1, 19);
                TestFeature("SMAP", features7, 1, 20);
                // [6] has an error, bit 22 is not RDPID as given on p606
                TestFeature("CLFLUSHOPT", features7, 1, 23);
                TestFeature("CLWB", features7, 1, 24);
                TestFeature("SHA", features7, 1, 29);
                ReservedFeature(features7, 1, unchecked ((int)0xDE636A56));

                TestFeature("UMIP", features7, 2, 2);
                TestFeature("PKU", features7, 2, 3);
                TestFeature("OSPKE", features7, 2, 4);
                TestFeature("CET_SS", features7, 2, 7);
                TestFeature("VAES", features7, 2, 9);
                TestFeature("VPCLMULQDQ", features7, 2, 10);
                ReservedFeature(features7, 2, unchecked ((int)0xFFBFF963));

                TestFeature("RDPID", features7, 3, 22);
                ReservedFeature(features7, 3, unchecked ((int)0xFFBFFFFF));

                if (features7.Result[0] > 0)
                {
                    for (int subfunction = 1; subfunction < features7.Result[0]; subfunction++)
                    {
                        CpuIdRegister features7sX = cpu.CpuRegisters.GetCpuId(ExtendedFeatureFunction, subfunction);
                        if (features7sX != null)
                        {
                            ReservedFeature(features7sX, 0, unchecked ((int)0xFFFFFFFF));
                            ReservedFeature(features7sX, 1, unchecked ((int)0xFFFFFFFF));
                            ReservedFeature(features7sX, 2, unchecked ((int)0xFFFFFFFF));
                            ReservedFeature(features7sX, 3, unchecked ((int)0xFFFFFFFF));
                        }
                    }
                }
            }

            if (cpu.FunctionCount < ExtendedProcessorState)
            {
                return;
            }
            CpuIdRegister features13 = cpu.CpuRegisters.GetCpuId(ExtendedProcessorState, 1);

            if (features13 != null)
            {
                TestFeature("XSAVEOPT", features13, 0, 0);
                TestFeature("XSAVEC", features13, 0, 1);
                TestFeature("XGETBV", features13, 0, 2);
                TestFeature("XSAVES", features13, 0, 3);
            }
        }
Пример #29
0
 /// <summary>
 /// Tests a bit in the feature flag.
 /// </summary>
 /// <param name="feature">The name of the CPU feature, e.g. "FPU".</param>
 /// <param name="register">The feature register obtained from a query of CPUID.</param>
 /// <param name="result">The register to query, 0 is EAX, to 3 for EDX.</param>
 /// <param name="bit">The bit to test for.</param>
 protected void TestFeature(string feature, CpuIdRegister register, int result, int bit)
 {
     TestFeature(feature, register, result, bit, false);
 }