/* Copyright (c) 2013 Wildfire Games * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef INCLUDED_X86_X64_CACHE #define INCLUDED_X86_X64_CACHE namespace x86_x64 { struct Cache // POD (may be used before static constructors) { enum Type { // (values match the CPUID.4 definition) kNull, kData, kInstruction, kUnified // note: further values are "reserved" }; static const size_t maxLevels = 4; static const size_t fullyAssociative = 0xFF; // (CPUID.4 definition) /** * 1..maxLevels **/ size_t level; /** * never kNull **/ Type type; /** * if 0, the cache is disabled and all other values are zero **/ size_t numEntries; /** * NB: cache entries are lines, TLB entries are pages **/ size_t entrySize; /** * = fullyAssociative or the actual ways of associativity **/ size_t associativity; /** * how many logical processors share this cache? **/ size_t sharedBy; void Initialize(size_t level, Type type) { this->level = level; this->type = type; numEntries = 0; entrySize = 0; associativity = 0; sharedBy = 0; ENSURE(Validate()); } bool Validate() const { if(!(1 <= level && level <= maxLevels)) return false; if(type == kNull) return false; if(numEntries == 0) // disabled { if(entrySize != 0) return false; if(associativity != 0) return false; if(sharedBy != 0) return false; } else { if(entrySize == 0) return false; if(associativity == 0 || associativity > fullyAssociative) return false; if(sharedBy == 0) return false; } return true; } u64 TotalSize() const { return u64(numEntries)*entrySize; } }; enum IdxCache { // (AddCache relies upon this order) L1D = 1, L2D, L3D, L4D, L1I, L2I, L3I, L4I, TLB }; /** * @return 0 if idxCache >= TLB+numTLBs, otherwise a valid pointer to * a Cache whose numEntries is 0 if disabled / not present. **/ LIB_API const Cache* Caches(size_t idxCache); } // namespace x86_x64 #endif // #ifndef INCLUDED_X86_X64_CACHE