fixes:
avoid reporting a (not-present) third-level cache for Athlon X2 that don't have one add better documentation of cache information ensure we're running on the same CPU while retrieving cache/TLB descriptors wgfx: always check all known graphics driver names (more robust in the face of changing gfx_card strings), correct the intel driver name This was SVN commit r8991.
This commit is contained in:
parent
567a698628
commit
bb562ce179
@ -258,7 +258,7 @@ size_t x86_x64_Family()
|
||||
// cache
|
||||
|
||||
static const size_t maxCacheLevels = 3;
|
||||
static x86_x64_Cache cacheStorage[maxCacheLevels*2];
|
||||
static x86_x64_Cache cacheStorage[maxCacheLevels*2]; // separate D and I hierarchies
|
||||
static x86_x64_Caches dcaches = { 0, cacheStorage };
|
||||
static x86_x64_Caches icaches = { 0, cacheStorage+maxCacheLevels };
|
||||
|
||||
@ -433,8 +433,13 @@ static void DetectCacheAndTLB()
|
||||
icaches.numLevels = dcaches.numLevels = 2;
|
||||
icaches.levels[1] = dcaches.levels[1] = L2Cache(regs.ecx, X86_X64_CACHE_TYPE_UNIFIED);
|
||||
|
||||
icaches.numLevels = dcaches.numLevels = 3;
|
||||
icaches.levels[2] = dcaches.levels[2] = L3Cache(regs.edx, X86_X64_CACHE_TYPE_UNIFIED);
|
||||
// (some Athlon 64 X2 models have no L3 cache, and it's better to report only 2 levels than
|
||||
// have L3 type == NULL)
|
||||
if(dcaches.levels[2].type != X86_X64_CACHE_TYPE_NULL)
|
||||
{
|
||||
icaches.numLevels = dcaches.numLevels = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -487,6 +492,7 @@ static void DetectCache_CPUID4()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void ExtractDescriptors(u32 reg, std::vector<u8>& descriptors)
|
||||
{
|
||||
if(IsBitSet(reg, 31)) // register contents are reserved
|
||||
@ -529,8 +535,9 @@ static const u8 F = x86_x64_fullyAssociative;
|
||||
|
||||
#define PROPERTIES(descriptor, flags, assoc, entries) { flags, descriptor, assoc, entries }
|
||||
|
||||
// references: [accessed 2009-01-05]
|
||||
// AP485 http://download.intel.com/design/processor/applnots/241618033.pdf
|
||||
// (we only bother with TLB descriptors because CPUID.4 is a much easier way to detect the cache)
|
||||
// references: [accessed 2011-02-26]
|
||||
// AP485 http://www.intel.com/Assets/PDF/appnote/241618.pdf
|
||||
// sandp http://www.sandpile.org/ia32/cpuid.htm
|
||||
// opsol http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/i86pc/os/cpuid.c
|
||||
static const Properties propertyTable[] =
|
||||
@ -541,7 +548,7 @@ static const Properties propertyTable[] =
|
||||
PROPERTIES(0x04, D|S4M, 4, 8),
|
||||
PROPERTIES(0x05, D|S4M, 4, 32),
|
||||
PROPERTIES(0x0B, I|S4M, 4, 4),
|
||||
PROPERTIES(0x4F, I|S4K, F, 32), // sandp: unknown assoc, opsol: full, AP485: unmentioned
|
||||
PROPERTIES(0x4F, I|S4K, F, 32), // sandp: unknown assoc, opsol: full, AP485: unspecified
|
||||
PROPERTIES(0x50, I|S4K, F, 64),
|
||||
PROPERTIES(0x50, I|S4M, F, 64),
|
||||
PROPERTIES(0x50, I|S2M, F, 64),
|
||||
@ -634,7 +641,11 @@ static void DecodeDescriptor(u8 descriptor)
|
||||
|
||||
static void DetectTLB_CPUID2()
|
||||
{
|
||||
// TODO: ensure we are pinned to the same CPU
|
||||
// ensure consistency by pinning to a CPU.
|
||||
// (don't use a hard-coded mask because process affinity may be restricted)
|
||||
const uintptr_t allProcessors = os_cpu_ProcessorMask();
|
||||
const uintptr_t firstProcessor = allProcessors & -intptr_t(allProcessors);
|
||||
const uintptr_t prevAffinityMask = os_cpu_SetThreadAffinityMask(firstProcessor);
|
||||
|
||||
// extract descriptors
|
||||
x86_x64_CpuidRegs regs = { 0 };
|
||||
@ -656,6 +667,8 @@ static void DetectTLB_CPUID2()
|
||||
debug_assert(ok);
|
||||
}
|
||||
|
||||
os_cpu_SetThreadAffinityMask(prevAffinityMask);
|
||||
|
||||
for(std::vector<u8>::const_iterator it = descriptors.begin(); it != descriptors.end(); ++it)
|
||||
{
|
||||
const u8 descriptor = *it;
|
||||
|
@ -141,18 +141,32 @@ enum x86_x64_CacheType
|
||||
// note: further values are "reserved"
|
||||
};
|
||||
|
||||
const u8 x86_x64_fullyAssociative = 0xFF;
|
||||
static const u8 x86_x64_fullyAssociative = 0xFF;
|
||||
|
||||
struct x86_x64_Cache
|
||||
{
|
||||
/**
|
||||
* (used to determine if this cache is unified or disabled)
|
||||
* if X86_X64_CACHE_TYPE_NULL, all other values are invalid.
|
||||
**/
|
||||
x86_x64_CacheType type;
|
||||
|
||||
/**
|
||||
* equal to the index within x86_x64_Caches.levels[] + 1
|
||||
**/
|
||||
size_t level;
|
||||
|
||||
/**
|
||||
* = x86_x64_fullyAssociative or the actual ways of associativity
|
||||
**/
|
||||
size_t associativity;
|
||||
|
||||
size_t lineSize; /// [bytes]
|
||||
|
||||
/**
|
||||
* how many logical processors share this cache?
|
||||
**/
|
||||
size_t sharedBy;
|
||||
|
||||
size_t totalSize; /// [bytes]
|
||||
};
|
||||
|
||||
@ -163,6 +177,9 @@ struct x86_x64_Cache
|
||||
**/
|
||||
struct x86_x64_Caches
|
||||
{
|
||||
/**
|
||||
* equal to the highest value of x86_x64_Cache.level
|
||||
**/
|
||||
size_t numLevels;
|
||||
x86_x64_Cache* levels;
|
||||
};
|
||||
@ -181,7 +198,7 @@ LIB_API size_t x86_x64_L1CacheLineSize();
|
||||
LIB_API size_t x86_x64_L2CacheLineSize();
|
||||
|
||||
/**
|
||||
* Translation Lookaside Buffer.
|
||||
* Translation Lookaside Buffer. (documentation: see x86_x64_Cache)
|
||||
**/
|
||||
struct x86_x64_TLB
|
||||
{
|
||||
|
@ -98,7 +98,7 @@ void wdll_ver_Append(const fs::wpath& pathname, std::wstring& list)
|
||||
|
||||
// read file version. try this with and without FS redirection since
|
||||
// pathname might assume both.
|
||||
wchar_t versionString[500] = L"unknown"; // enclosed in () below
|
||||
wchar_t versionString[500]; // enclosed in () below
|
||||
if(ReadVersionString(modulePathname, versionString, ARRAY_SIZE(versionString)) != INFO::OK)
|
||||
{
|
||||
WinScopedDisableWow64Redirection s;
|
||||
|
@ -169,26 +169,25 @@ static LibError AppendDriverVersionsFromRegistry(std::wstring& versionList)
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
#include "lib/timer.h"
|
||||
|
||||
static LibError AppendDriverVersionsFromKnownFiles(std::wstring& versionList)
|
||||
static void AppendDriverVersionsFromKnownFiles(std::wstring& versionList)
|
||||
{
|
||||
if(!wcsncmp(gfx_card, L"NVIDIA", 6))
|
||||
{
|
||||
wdll_ver_Append(L"nvoglv64.dll", versionList);
|
||||
wdll_ver_Append(L"nvoglv32.dll", versionList);
|
||||
wdll_ver_Append(L"nvoglnt.dll", versionList);
|
||||
}
|
||||
else if(!wcsncmp(gfx_card, L"ATI", 3))
|
||||
{
|
||||
wdll_ver_Append(L"atioglxx.dll", versionList);
|
||||
}
|
||||
else if(!wcsncmp(gfx_card, L"Intel", 5))
|
||||
{
|
||||
wdll_ver_Append(L"igxpdv32.dll", versionList);
|
||||
}
|
||||
else
|
||||
return INFO::CANNOT_HANDLE;
|
||||
return INFO::OK;
|
||||
// (check all known file names regardless of gfx_card, which may change and
|
||||
// defeat our parsing. this takes about 5..10 ms)
|
||||
|
||||
// NVidia
|
||||
wdll_ver_Append(L"nvoglv64.dll", versionList);
|
||||
wdll_ver_Append(L"nvoglv32.dll", versionList);
|
||||
wdll_ver_Append(L"nvoglnt.dll", versionList);
|
||||
|
||||
// ATI
|
||||
wdll_ver_Append(L"atioglxx.dll", versionList);
|
||||
|
||||
// Intel
|
||||
wdll_ver_Append(L"ig4icd32.dll", versionList);
|
||||
wdll_ver_Append(L"ig4icd64.dll", versionList);
|
||||
wdll_ver_Append(L"iglicd32.dll", versionList);
|
||||
}
|
||||
|
||||
|
||||
@ -198,10 +197,9 @@ LibError win_get_gfx_info()
|
||||
|
||||
std::wstring versionList;
|
||||
if(AppendDriverVersionsFromRegistry(versionList) != INFO::OK) // (fails on Windows 7)
|
||||
{
|
||||
if(AppendDriverVersionsFromKnownFiles(versionList) != INFO::OK)
|
||||
versionList = L"(unknown)";
|
||||
}
|
||||
AppendDriverVersionsFromKnownFiles(versionList);
|
||||
if(versionList.empty())
|
||||
versionList = L"(unknown)";
|
||||
wcscpy_s(gfx_drv_ver, GFX_DRV_VER_LEN, versionList.c_str());
|
||||
|
||||
return err;
|
||||
|
@ -107,7 +107,6 @@ LIB_API size_t os_cpu_MemoryAvailable();
|
||||
|
||||
/**
|
||||
* restrict the current thread to a set of processors.
|
||||
* it will not be rescheduled until affinity is again changed.
|
||||
*
|
||||
* @param processorMask a bit mask of acceptable processors
|
||||
* (bit index i corresponds to processor i)
|
||||
|
Loading…
Reference in New Issue
Block a user