23 #include "precompiled.h"
75 const size_t lineSize =
bits(reg, 0, 7);
76 const size_t associativity =
bits(reg, 16, 23);
77 const size_t totalSize =
bits(reg, 24, 31)*
KiB;
78 if(lineSize != 0 && associativity != 0 && totalSize != 0)
91 0, 1, 2, 0, 4, 0, 8, 0,
100 const size_t lineSize =
bits(reg, 0, 7);
101 const size_t idxAssociativity =
bits(reg, 12, 15);
102 const size_t totalSize =
bits(reg, 16, 31)*
KiB;
103 if(lineSize != 0 && idxAssociativity != 0 && totalSize != 0)
119 const size_t lineSize =
bits(reg, 0, 7);
120 const size_t idxAssociativity =
bits(reg, 12, 15);
121 const size_t totalSize =
bits(reg, 18, 31)*512*
KiB;
123 if(lineSize != 0 && idxAssociativity != 0 && totalSize != 0)
138 const size_t numEntries =
bits(reg, bitOffset+0, bitOffset+ 7);
139 const size_t associativity =
bits(reg, bitOffset+8, bitOffset+15);
140 if(numEntries != 0 && associativity != 0)
155 const size_t numEntries =
bits(reg, bitOffset+ 0, bitOffset+11);
156 const size_t idxAssociativity =
bits(reg, bitOffset+12, bitOffset+15);
157 if(numEntries != 0 && idxAssociativity != 0)
170 if(
bits(reg, 16, 31) != 0)
184 regs.
eax = 0x80000005;
196 regs.
eax = 0x80000006;
218 for(
u32 count = 0; ; count++)
230 const size_t level = (size_t)
bits(regs.
eax, 5, 7);
231 const size_t partitions = (size_t)
bits(regs.
ebx, 12, 21)+1;
232 const size_t sets = (size_t)
bits(regs.
ecx, 0, 31)+1;
262 for(
int pos = 24; pos >= 0; pos -= 8)
264 const u8 descriptor = (
u8)
bits(reg, pos, pos+7);
266 descriptors.push_back(descriptor);
276 const uintptr_t firstProcessor = allProcessors & -intptr_t(allProcessors);
285 size_t iterations =
bits(regs.
eax, 0, 7);
292 if(--iterations == 0)
344 const size_t level =
flags & 3;
372 #define CACHE(descriptor, flags, totalSize, assoc, entrySize) { descriptor, assoc, -entrySize, flags | ((totalSize)/(entrySize)) }
373 #define TLB(descriptor, flags, entrySize, assoc, numEntries) { descriptor, assoc, numEntries, flags | (entrySize) }
536 return &characteristics;
539 debug_printf(L
"Unknown cache/TLB descriptor 0x%x\n", (
unsigned int)descriptor);
584 for(Descriptors::const_iterator it = descriptors.begin(); it != descriptors.end(); ++it)
603 if(characteristics->
IsTLB())
626 size_t descriptorFlags = 0;
643 for(
size_t i = 0; i <
numTLBs; i++)
#define CACHE(descriptor, flags, totalSize, assoc, entrySize)
static const size_t pageSize
static x86_x64::Cache L2Cache(u32 reg, x86_x64::Cache::Type type)
const x86_x64::Cache * Caches(size_t idxCache)
static void AppendDescriptors(u32 reg, Descriptors &descriptors)
static bool DetectCache()
static const size_t numCaches
static Descriptors GetDescriptors()
static ModuleInitState initState
static const size_t fullyAssociative
uintptr_t os_cpu_SetThreadAffinityMask(uintptr_t processorMask)
restrict the current thread to a set of processors.
static x86_x64::Cache TLB2(u32 reg, size_t bitOffset, size_t pageSize, x86_x64::Cache::Type type)
size_t NumEntries() const
static Status DetectCacheAndTLB()
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
intptr_t ModuleInitState
initialization state of a module (class, source file, etc.) must be initialized to zero (e...
bool cpuid(CpuidRegs *regs)
invoke CPUID instruction.
static x86_x64::Cache L3Cache(u32 reg, x86_x64::Cache::Type type)
size_t sharedBy
how many logical processors share this cache?
static const size_t maxLevels
static void DetectCacheAndTLB()
bool IsBitSet(T value, size_t index)
static void AddTLB(const x86_x64::Cache &tlb)
static x86_x64::Cache L1Cache(u32 reg, x86_x64::Cache::Type type)
x86_x64::Cache::Type Type() const
static const size_t associativityTable[16]
i64 Status
Error handling system.
static void AddCache(const x86_x64::Cache &cache)
void Initialize(size_t level, Type type)
T bits(T num, size_t lo_idx, size_t hi_idx)
extract the value of bits hi_idx:lo_idx within num
static void AddTLB2Pair(u32 reg, size_t pageSize)
uintptr_t os_cpu_ProcessorMask()
#define DEBUG_WARN_ERR(status)
display the error dialog with text corresponding to the given error code.
static void DetectCacheAndTLB(size_t &descriptorFlags)
static bool HandleSpecialDescriptor(Descriptor descriptor, size_t &descriptorFlags)
static const size_t maxTLBs
static const Characteristics characteristicsTable[]
registers used/returned by cpuid
size_t numEntries
if 0, the cache is disabled and all other values are zero
std::vector< Descriptor > Descriptors
size_t associativity
= fullyAssociative or the actual ways of associativity
size_t entrySize
NB: cache entries are lines, TLB entries are pages.
static Cache caches[numCaches]
Status ModuleInit(volatile ModuleInitState *initState, Status(*init)())
calls a user-defined init function if initState is zero.
static x86_x64::Cache TLB1(u32 reg, size_t bitOffset, size_t pageSize, x86_x64::Cache::Type type)
void debug_printf(const wchar_t *fmt,...)
write a formatted string to the debug channel, subject to filtering (see below).
static const Characteristics * CharacteristicsFromDescriptor(Descriptor descriptor)