Esempio n. 1
0
 internal static bool ReadTxOut(uint index, uint subLeaf, ref CpuidRegisters registers, ulong threadAffinityMask)
 {
     return(Kernel.Cpuid.ReadTx(
                index,
                subLeaf,
                ref registers.Eax,
                ref registers.Ebx,
                ref registers.Ecx,
                ref registers.Edx,
                (UIntPtr)threadAffinityMask));
 }
Esempio n. 2
0
        public static CpuVendor VendorFromCpuidString(CpuidRegisters registers)
        {
            switch (registers.GetVendorString())
            {
            case "GenuineIntel":
                return(CpuVendor.Intel);

            case "AuthenticAMD":
                return(CpuVendor.Amd);

            default:
                return(CpuVendor.Unknown);
            }
        }
Esempio n. 3
0
        public CpuidThreadInfo(uint threadIndex)
        {
            ThreadIndex = threadIndex;

            var  affinityMask = 1UL << (int)ThreadIndex;
            uint maxCpuidExtLen;

            var registers = new CpuidRegisters();

            if (!Cpuid.ReadTxOut(Cpuid.Cpuid0, 0, ref registers, affinityMask))
            {
                throw new Exception($"Unable to get CPUID0 registers from thread {ThreadIndex}");
            }

            if (registers.Eax <= Cpuid.Cpuid0)
            {
                throw new Exception($"CPUID0_Eax: {registers.Eax} <= {Cpuid.Cpuid0}");
            }

            Vendor = Cpuid.VendorFromCpuidString(registers);
            var maxCpuidLen = registers.Eax;

            registers.Clear();
            if (!Cpuid.ReadTxOut(Cpuid.CpuidExt, 0, ref registers, affinityMask))
            {
                throw new Exception("ReadTxOut_CpuidExt: fail");
            }

            if (registers.Eax > Cpuid.CpuidExt)
            {
                maxCpuidExtLen = registers.Eax - Cpuid.CpuidExt;
            }
            else
            {
                throw new Exception($"CPUIDExt_Eax: {registers.Eax} <= {Cpuid.CpuidExt}");
            }

            maxCpuidLen    = Math.Min(maxCpuidLen, 1024);
            maxCpuidExtLen = Math.Min(maxCpuidExtLen, 1024);

            // Read short core thread info
            DataRegisters = new CpuidRegisters[maxCpuidLen + 1];
            for (uint i = 0; i < maxCpuidLen + 1; i++)
            {
                DataRegisters[i] = new CpuidRegisters();
                Cpuid.ReadTxOut(Cpuid.Cpuid0 + i, 0, ref DataRegisters[i], affinityMask);
            }

            // Read full core thread info
            DataRegistersExt = new CpuidRegisters[maxCpuidExtLen + 1];
            for (uint i = 0; i < maxCpuidExtLen + 1; i++)
            {
                DataRegistersExt[i] = new CpuidRegisters();
                Cpuid.ReadTxOut(Cpuid.CpuidExt + i, 0, ref DataRegistersExt[i], affinityMask);
            }

            var coreNameBuilder = new StringBuilder();

            for (uint i = 2; i <= 4; i++)
            {
                Cpuid.ReadTxOut(Cpuid.CpuidExt + i, 0, ref registers, affinityMask);
                registers.GetVendorExtendedString(ref coreNameBuilder);
            }

            BrandName = coreNameBuilder.ToString().Trim().TrimEnd(' ').Replace("\0", string.Empty);
            Name      = Cpuid.RemoveSpechialBrandSymbolsFromString(coreNameBuilder);

            Family   = ((DataRegisters[1].Eax & 0x0FF00000) >> 20) + ((DataRegisters[1].Eax & 0x0F00) >> 8);
            Model    = ((DataRegisters[1].Eax & 0x0F0000) >> 12) + ((DataRegisters[1].Eax & 0xF0) >> 4);
            Stepping = DataRegisters[1].Eax & 0x0F;
            ApicId   = (DataRegisters[1].Ebx >> 24) & 0xFF;

            if (Vendor == CpuVendor.Intel)
            {
                var  maxCoreAndThreadIdPerPackage = (DataRegisters[1].Ebx >> 16) & 0xFF;
                uint maxCoreIdPerPackage;
                if (maxCpuidLen >= 4)
                {
                    maxCoreIdPerPackage = ((DataRegisters[4].Eax >> 26) & 0x3F) + 1;
                }
                else
                {
                    maxCoreIdPerPackage = 1;
                }

                _threadMaskWith = MathUtils.NextLog2(maxCoreAndThreadIdPerPackage / maxCoreIdPerPackage);
                _coreMaskWith   = MathUtils.NextLog2(maxCoreIdPerPackage);
            }
            else if (Vendor == CpuVendor.Amd)
            {
                uint corePerPackage;
                if (maxCpuidExtLen >= 8)
                {
                    corePerPackage = (DataRegistersExt[8].Ecx & 0xFF) + 1;
                }
                else
                {
                    corePerPackage = 1;
                }

                _threadMaskWith = 0;
                _coreMaskWith   = MathUtils.NextLog2(corePerPackage);
            }
            else
            {
                _threadMaskWith = 0;
                _coreMaskWith   = 0;
            }

            ProcessorId = ApicId >> (int)(_coreMaskWith + _threadMaskWith);
            CoreId      = (ApicId >> (int)_threadMaskWith) - (ProcessorId << (int)_coreMaskWith);
            ThreadId    = ApicId - (ProcessorId << (int)(_coreMaskWith + _threadMaskWith)) - (CoreId << (int)_threadMaskWith);
        }