Beispiel #1
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);
            }
        }
Beispiel #2
0
        public bool Equals(CacheTopo x, CacheTopo y)
        {
            if (x == null && y == null)
            {
                return(true);
            }
            if (x == null || y == null)
            {
                return(false);
            }
            if (x.GetType() != y.GetType())
            {
                return(false);
            }

            if (x.CacheType != y.CacheType || x.Level != y.Level)
            {
                return(false);
            }

            if (x is CacheTopoCpu xc)
            {
                CacheTopoCpu yc = (CacheTopoCpu)y;
                return
                    (xc.Associativity == yc.Associativity &&
                     xc.LineSize == yc.LineSize &&
                     xc.Sets == yc.Sets &&
                     xc.Size == yc.Size);
            }
            else if (x is CacheTopoTlb xt)
            {
                CacheTopoTlb yt = (CacheTopoTlb)y;
                return
                    (xt.Associativity == yt.Associativity &&
                     xt.Sets == yt.Sets &&
                     xt.Entries == yt.Entries);
            }
            return(false);
        }