in Source/kwsys/SystemInformation.cxx [2201:2488]
bool SystemInformationImplementation::RetrieveClassicalCPUCacheDetails()
{
#if USE_CPUID
int TLBCode = -1, TLBData = -1, L1Code = -1, L1Data = -1, L1Trace = -1,
L2Unified = -1, L3Unified = -1;
int TLBCacheData[4] = { 0, 0, 0, 0 };
int TLBPassCounter = 0;
int TLBCacheUnit = 0;
do {
if (!call_cpuid(2, TLBCacheData)) {
return false;
}
int bob = ((TLBCacheData[0] & 0x00FF0000) >> 16);
(void)bob;
// Process the returned TLB and cache information.
for (int nCounter = 0; nCounter < TLBCACHE_INFO_UNITS; nCounter++) {
// First of all - decide which unit we are dealing with.
switch (nCounter) {
// eax: bits 8..15 : bits 16..23 : bits 24..31
case 0:
TLBCacheUnit = ((TLBCacheData[0] & 0x0000FF00) >> 8);
break;
case 1:
TLBCacheUnit = ((TLBCacheData[0] & 0x00FF0000) >> 16);
break;
case 2:
TLBCacheUnit = ((TLBCacheData[0] & 0xFF000000) >> 24);
break;
// ebx: bits 0..7 : bits 8..15 : bits 16..23 : bits 24..31
case 3:
TLBCacheUnit = ((TLBCacheData[1] & 0x000000FF) >> 0);
break;
case 4:
TLBCacheUnit = ((TLBCacheData[1] & 0x0000FF00) >> 8);
break;
case 5:
TLBCacheUnit = ((TLBCacheData[1] & 0x00FF0000) >> 16);
break;
case 6:
TLBCacheUnit = ((TLBCacheData[1] & 0xFF000000) >> 24);
break;
// ecx: bits 0..7 : bits 8..15 : bits 16..23 : bits 24..31
case 7:
TLBCacheUnit = ((TLBCacheData[2] & 0x000000FF) >> 0);
break;
case 8:
TLBCacheUnit = ((TLBCacheData[2] & 0x0000FF00) >> 8);
break;
case 9:
TLBCacheUnit = ((TLBCacheData[2] & 0x00FF0000) >> 16);
break;
case 10:
TLBCacheUnit = ((TLBCacheData[2] & 0xFF000000) >> 24);
break;
// edx: bits 0..7 : bits 8..15 : bits 16..23 : bits 24..31
case 11:
TLBCacheUnit = ((TLBCacheData[3] & 0x000000FF) >> 0);
break;
case 12:
TLBCacheUnit = ((TLBCacheData[3] & 0x0000FF00) >> 8);
break;
case 13:
TLBCacheUnit = ((TLBCacheData[3] & 0x00FF0000) >> 16);
break;
case 14:
TLBCacheUnit = ((TLBCacheData[3] & 0xFF000000) >> 24);
break;
// Default case - an error has occurred.
default:
return false;
}
// Now process the resulting unit to see what it means....
switch (TLBCacheUnit) {
case 0x00:
break;
case 0x01:
STORE_TLBCACHE_INFO(TLBCode, 4);
break;
case 0x02:
STORE_TLBCACHE_INFO(TLBCode, 4096);
break;
case 0x03:
STORE_TLBCACHE_INFO(TLBData, 4);
break;
case 0x04:
STORE_TLBCACHE_INFO(TLBData, 4096);
break;
case 0x06:
STORE_TLBCACHE_INFO(L1Code, 8);
break;
case 0x08:
STORE_TLBCACHE_INFO(L1Code, 16);
break;
case 0x0a:
STORE_TLBCACHE_INFO(L1Data, 8);
break;
case 0x0c:
STORE_TLBCACHE_INFO(L1Data, 16);
break;
case 0x10:
STORE_TLBCACHE_INFO(L1Data, 16);
break; // <-- FIXME: IA-64 Only
case 0x15:
STORE_TLBCACHE_INFO(L1Code, 16);
break; // <-- FIXME: IA-64 Only
case 0x1a:
STORE_TLBCACHE_INFO(L2Unified, 96);
break; // <-- FIXME: IA-64 Only
case 0x22:
STORE_TLBCACHE_INFO(L3Unified, 512);
break;
case 0x23:
STORE_TLBCACHE_INFO(L3Unified, 1024);
break;
case 0x25:
STORE_TLBCACHE_INFO(L3Unified, 2048);
break;
case 0x29:
STORE_TLBCACHE_INFO(L3Unified, 4096);
break;
case 0x39:
STORE_TLBCACHE_INFO(L2Unified, 128);
break;
case 0x3c:
STORE_TLBCACHE_INFO(L2Unified, 256);
break;
case 0x40:
STORE_TLBCACHE_INFO(L2Unified, 0);
break; // <-- FIXME: No integrated L2 cache (P6 core) or L3 cache (P4
// core).
case 0x41:
STORE_TLBCACHE_INFO(L2Unified, 128);
break;
case 0x42:
STORE_TLBCACHE_INFO(L2Unified, 256);
break;
case 0x43:
STORE_TLBCACHE_INFO(L2Unified, 512);
break;
case 0x44:
STORE_TLBCACHE_INFO(L2Unified, 1024);
break;
case 0x45:
STORE_TLBCACHE_INFO(L2Unified, 2048);
break;
case 0x50:
STORE_TLBCACHE_INFO(TLBCode, 4096);
break;
case 0x51:
STORE_TLBCACHE_INFO(TLBCode, 4096);
break;
case 0x52:
STORE_TLBCACHE_INFO(TLBCode, 4096);
break;
case 0x5b:
STORE_TLBCACHE_INFO(TLBData, 4096);
break;
case 0x5c:
STORE_TLBCACHE_INFO(TLBData, 4096);
break;
case 0x5d:
STORE_TLBCACHE_INFO(TLBData, 4096);
break;
case 0x66:
STORE_TLBCACHE_INFO(L1Data, 8);
break;
case 0x67:
STORE_TLBCACHE_INFO(L1Data, 16);
break;
case 0x68:
STORE_TLBCACHE_INFO(L1Data, 32);
break;
case 0x70:
STORE_TLBCACHE_INFO(L1Trace, 12);
break;
case 0x71:
STORE_TLBCACHE_INFO(L1Trace, 16);
break;
case 0x72:
STORE_TLBCACHE_INFO(L1Trace, 32);
break;
case 0x77:
STORE_TLBCACHE_INFO(L1Code, 16);
break; // <-- FIXME: IA-64 Only
case 0x79:
STORE_TLBCACHE_INFO(L2Unified, 128);
break;
case 0x7a:
STORE_TLBCACHE_INFO(L2Unified, 256);
break;
case 0x7b:
STORE_TLBCACHE_INFO(L2Unified, 512);
break;
case 0x7c:
STORE_TLBCACHE_INFO(L2Unified, 1024);
break;
case 0x7e:
STORE_TLBCACHE_INFO(L2Unified, 256);
break;
case 0x81:
STORE_TLBCACHE_INFO(L2Unified, 128);
break;
case 0x82:
STORE_TLBCACHE_INFO(L2Unified, 256);
break;
case 0x83:
STORE_TLBCACHE_INFO(L2Unified, 512);
break;
case 0x84:
STORE_TLBCACHE_INFO(L2Unified, 1024);
break;
case 0x85:
STORE_TLBCACHE_INFO(L2Unified, 2048);
break;
case 0x88:
STORE_TLBCACHE_INFO(L3Unified, 2048);
break; // <-- FIXME: IA-64 Only
case 0x89:
STORE_TLBCACHE_INFO(L3Unified, 4096);
break; // <-- FIXME: IA-64 Only
case 0x8a:
STORE_TLBCACHE_INFO(L3Unified, 8192);
break; // <-- FIXME: IA-64 Only
case 0x8d:
STORE_TLBCACHE_INFO(L3Unified, 3096);
break; // <-- FIXME: IA-64 Only
case 0x90:
STORE_TLBCACHE_INFO(TLBCode, 262144);
break; // <-- FIXME: IA-64 Only
case 0x96:
STORE_TLBCACHE_INFO(TLBCode, 262144);
break; // <-- FIXME: IA-64 Only
case 0x9b:
STORE_TLBCACHE_INFO(TLBCode, 262144);
break; // <-- FIXME: IA-64 Only
// Default case - an error has occurred.
default:
return false;
}
}
// Increment the TLB pass counter.
TLBPassCounter++;
} while ((TLBCacheData[0] & 0x000000FF) > TLBPassCounter);
// Ok - we now have the maximum TLB, L1, L2, and L3 sizes...
if ((L1Code == -1) && (L1Data == -1) && (L1Trace == -1)) {
this->Features.L1CacheSize = -1;
} else if ((L1Code == -1) && (L1Data == -1) && (L1Trace != -1)) {
this->Features.L1CacheSize = L1Trace;
} else if ((L1Code != -1) && (L1Data == -1)) {
this->Features.L1CacheSize = L1Code;
} else if ((L1Code == -1) && (L1Data != -1)) {
this->Features.L1CacheSize = L1Data;
} else if ((L1Code != -1) && (L1Data != -1)) {
this->Features.L1CacheSize = L1Code + L1Data;
} else {
this->Features.L1CacheSize = -1;
}
// Ok - we now have the maximum TLB, L1, L2, and L3 sizes...
if (L2Unified == -1) {
this->Features.L2CacheSize = -1;
} else {
this->Features.L2CacheSize = L2Unified;
}
// Ok - we now have the maximum TLB, L1, L2, and L3 sizes...
if (L3Unified == -1) {
this->Features.L3CacheSize = -1;
} else {
this->Features.L3CacheSize = L3Unified;
}
return true;
#else
return false;
#endif
}