/// <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); } }
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); }