⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lincpuid.c

📁 270的linux说明
💻 C
📖 第 1 页 / 共 3 页
字号:
		}	}	if ( wil_quad_fix )	{		g_WinCPUID_Info.bSSE2_Supported = 1;	}	else if (!(features & 0x04000000) && (wil_support==TRUE)) {		g_WinCPUID_Info.bSSE2_Supported = 1; // SSE2 Instructions Supported Due To Pentium 4 Emulator Being Present		g_WinCPUID_Info.EmulCode = SSE2_BIT; // flag SSE2 being emulated	}	// TODO: suuport it on Linux	//CheckPNISupport(&g_WinCPUID_Info);	//CheckTNISupport(&g_WinCPUID_Info);	getFeatures8_1(&g_WinCPUID_Info);	getFeatures8_8(&g_WinCPUID_Info);	g_WinCPUID_Info.bEM64T_Supported = !(g_WinCPUID_Info.bCloneFlag) && ((g_WinCPUID_Info.coreInfo.dwFeatures8_1_edx & (1<<29)) != 0);	g_WinCPUID_Info.bNX_Supported = !(g_WinCPUID_Info.bCloneFlag) && ((g_WinCPUID_Info.coreInfo.dwFeatures8_1_edx & (1<<20)) != 0);	// AMD Features check	if (g_WinCPUID_Info.eCPUVendor == VENDOR_AMD) {		if (g_WinCPUID_Info.coreInfo.dwCPUAMDExtSignature & AMD3DNOW_BIT) {			g_WinCPUID_Info.b3DNow_Supported = 1;		}		if (g_WinCPUID_Info.coreInfo.dwCPUAMDExtSignature & AMDEXT3DNOW_BIT) {			g_WinCPUID_Info.bExt3DNow_Supported = 1;		}		if (g_WinCPUID_Info.coreInfo.dwCPUAMDExtSignature & AMDSSEMMXEXT_BIT) {			g_WinCPUID_Info.bSSEMMXExt_Supported = 1;		}	}	g_WinCPUID_Info.bDAZ_Supported = checkDAZ();	g_WinCPUID_Info.htInfo.nLogicalPerPackage = WinCPUID_getLogicalPerPackage(&g_WinCPUID_Info);	// Set extended HT info pointer	if (pInfo->htInfo.pPhysProcAff) {		g_WinCPUID_Info.htInfo.pPhysProcAff = pInfo->htInfo.pPhysProcAff;		g_WinCPUID_Info.htInfo.nMaxPhysGetProcAff = pInfo->htInfo.nMaxPhysGetProcAff;		g_WinCPUID_Info.htInfo.nMaxCoreGetProcAff = pInfo->htInfo.nMaxCoreGetProcAff;	}	if (testHT(&g_WinCPUID_Info))		g_WinCPUID_Info.bHT_Supported = 1;	g_WinCPUID_Info.bIsInitialized = 1;	if (((!g_WinCPUID_Info.bCloneFlag) || (g_WinCPUID_Info.eCPUVendor == VENDOR_AMD))		&& (g_WinCPUID_Info.coreInfo.dwCPUFamily >= 6)) {		if (pInfo->pCacheInfo) {			g_WinCPUID_Info.pCacheInfo = pInfo->pCacheInfo;			// Cache Info			initDescTable();			getCacheInfo();		}	} else {		if (pInfo->pCacheInfo) {			g_WinCPUID_Info.pCacheInfo = pInfo->pCacheInfo;		}	}	// Processor string	if (g_WinCPUID_Info.coreInfo.dwCPUFamily >= 6) {		if (pInfo->pProcString) {			g_WinCPUID_Info.pProcString = pInfo->pProcString;			getProcStr(g_WinCPUID_Info.pProcString);		}	} else {		if (pInfo->pProcString) {			g_WinCPUID_Info.pProcString = pInfo->pProcString;			strcpy(g_WinCPUID_Info.pProcString, "");		}	}	*pInfo = g_WinCPUID_Info; // copy to external structure;		//printf("LinCPU Init Success!\n");	return TRUE;}#ifndef _M_X64DWORD WinCPUID_FindMaskWidth(DWORD Max_Count){	DWORD mask_width=0, cnt = Max_Count;	return mask_width;}#endif// Returns the value of the sub ID, this is not a zero-based valuestatic BYTE GetSubID(BYTE Full_ID, BYTE MaxSubIDValue, BYTE ShiftValue){	DWORD MaskWidth, Shift_Count;	BYTE MaskBits, SubID;		Shift_Count = (ShiftValue == 0) ? 0 : WinCPUID_FindMaskWidth(ShiftValue);	MaskWidth = WinCPUID_FindMaskWidth(MaxSubIDValue);	MaskBits = ((BYTE) (0xff << Shift_Count)) ^ ((BYTE) (0xff << (Shift_Count + MaskWidth))) ;	// New version, but it is the same as SK's	//MaskBits  =          (0xff << ShiftCount) ^	  ((BYTE) (0xff << (Shift_Count + MaskWidth)));	SubID = Full_ID & MaskBits;	return SubID;}static int GetMaxCacheLevel(const CPUINFO_T *pInfo){	DWORD maxLLCLevel = 0;	DWORD HT_MC_Sup = pInfo->coreInfo.dwCPUFeatures & HT_BIT;	int nExpCaches;	if (!HT_MC_Sup || pInfo->bNonIntelFlag) { // must be single-core and discrete cache		return 2;	}	nExpCaches = WinCPUID_GetNumExplicitCaches();	if (nExpCaches > 0)	{		EXPLICITCACHEINFO_T expCI;		EXPCACHE_COMMON_T expCC;		BOOL bRet;		int i;		for (i=0; i < nExpCaches; i++) {			ZeroMemory(&expCC, sizeof(EXPCACHE_COMMON_T));			bRet = WinCPUID_GetExplicitCache(&expCI, i);			//BREAK_ON_ERR_B(bRet);			bRet = WinCPUID_GetExpCacheCommonInfo(&expCC, &expCI);			//BREAK_ON_ERR_B(bRet);			if (expCC.CacheLevel > maxLLCLevel)				maxLLCLevel = expCC.CacheLevel;		}	} else {		maxLLCLevel = 2;	}	return maxLLCLevel;} /*** end GetMaxNumLPSharingCache() ***/static DWORD GetIndexForCacheLevelAndType(int level, int type){	EXPLICITCACHEINFO_T expCI;	DWORD cacheIndex;	DWORD targetIdx = (DWORD)-1;	int nExpCaches = WinCPUID_GetNumExplicitCaches();	DWORD t;	CPUID_ARGS ca;		ca.eax = 0;	CPUIDF(&ca);	t = ca.eax;	for (cacheIndex=0; cacheIndex < nExpCaches; cacheIndex++) {		EXPCACHE_COMMON_T expCC;		BOOL bRet;		ZeroMemory(&expCC, sizeof(EXPCACHE_COMMON_T));		bRet = WinCPUID_GetExplicitCache(&expCI, cacheIndex);		if (!bRet)			break;		bRet = WinCPUID_GetExpCacheCommonInfo(&expCC, &expCI);		//BREAK_ON_ERR_B(bRet);		if ( (expCC.CacheLevel == level) && (expCC.CacheType == type) ) {			targetIdx = cacheIndex;			break;		}	}	return targetIdx;}// From Shihjong Kuo// Only for unified inst & data (UL2, UL3, etc) cachesstatic DWORD getMaxNumLPSharingCache(int level, const CPUINFO_T *pInfo){	DWORD maxLPSharingCache = 0;	DWORD HT_MC_Sup = pInfo->coreInfo.dwCPUFeatures & HT_BIT;	if (!HT_MC_Sup || pInfo->bNonIntelFlag) { // must be single-core and discrete cache		return 1;	}	if (WinCPUID_GetNumExplicitCaches() > 0)	{		EXPLICITCACHEINFO_T expCI;		EXPCACHE_COMMON_T expCC;		BOOL bRet;		ZeroMemory(&expCC, sizeof(EXPCACHE_COMMON_T));		bRet = WinCPUID_GetExplicitCache(&expCI, GetIndexForCacheLevelAndType(level, 3));		//BREAK_ON_ERR_B(bRet);		bRet = WinCPUID_GetExpCacheCommonInfo(&expCC, &expCI);		//BREAK_ON_ERR_B(bRet);		maxLPSharingCache = expCC.ThreadsPerCache;	} else {		maxLPSharingCache = pInfo->htInfo.nLogicalPerPackage;	}	return maxLPSharingCache;} /*** end GetMaxNumLPSharingCache() ***/// If this was C++, these structs would belong in a private namespacetypedef struct _log_ids_s{	BYTE SMT_ID;	BYTE CORE_ID;	BYTE PACKAGE_ID;	BYTE LLC_ID;	// Extend SK's alg by adding the core/pkg index into this array when the affinity masks are computed	// This makes filling in the 3-level array for package/core/logical mapping much easier	int coreIndex;	int packageIndex;	int L2CacheIndex;	int CacheSharedIndex;	int bIsFirstSMTonCore; // TRUE if this is the first SMT logical on a core} TLogicalID;static BOOL getLogPhysProcs(CPUINFO_T *pi) {	HANDLE hCurrentProcessHandle;	DWORD_PTR dwProcessAffinity;	DWORD_PTR dwSystemAffinity;	DWORD_PTR dwAffinityMask;	BOOL MCorHT_Enabled = FALSE;	EXPLICITCACHEINFO_T expCI;	EXPCACHE_COMMON_T expCC;	int nCores = 0;	TLogicalID *LogIDs;		// index is logical number	int *PackageIDBucket;	// index is package number	int *CoreIDBucket;		// index is core number	int *L2CacheIDBucket;	int *LLCSharingBucket;	DWORD_PTR *PackageProcessorMask;	// index is package number	DWORD_PTR *CoreProcessorMask;		// index is core number	DWORD_PTR PackagesAffinity = 0;		// Affinity mask for the first logical on each package, for WinCPUID API	DWORD_PTR CoresAffinity = 0;		// Affinity mask for the first logical on each core, for WinCPUID API	CPUAFFINITY LLCSharingAffinity = 0;	int curLogical;    int nLogicalFound = 0;	// number of booted logicals found	int nPackagesFound = 0;	int nCoresFound = 0;	int L2CachesFound = 0;	int curSharedIndex = 0;	int LLC_Level = GetMaxCacheLevel(pi);	int nLogicalSystem;		// number reported by sytem	SYSTEM_INFO si;	ZeroMemory(&si, sizeof(SYSTEM_INFO));//	GetSystemInfo(&si);//	nLogicalSystem = si.dwNumberOfProcessors;	nLogicalSystem = 1;	LogIDs = (TLogicalID*)_alloca( nLogicalSystem * sizeof(TLogicalID) );	ZeroMemory(LogIDs, sizeof( nLogicalSystem * sizeof(TLogicalID)) );	ZeroMemory(&expCC, sizeof(EXPCACHE_COMMON_T));	// If the cpu has the explicit cache info, check any explicit cache to get the number of cores per package	if (WinCPUID_GetNumExplicitCaches() > 0) {		WinCPUID_GetExplicitCaches(&expCI, 1);		WinCPUID_GetExpCacheCommonInfo(&expCC, &expCI);		pi->htInfo.nCoresPerPackage = expCC.CoresPerPackage;	} else if (pi->eCPUVendor == VENDOR_AMD) {		// nCoresPerPackage already set by WinCPUID_GetLogicalPerPackage		if (pi->htInfo.nCoresPerPackage == 0)			pi->htInfo.nCoresPerPackage = 1;	} else {		// We know it is not multi-core		pi->htInfo.nCoresPerPackage = 1;	}	pi->htInfo.nLogicalPerCore = pi->htInfo.nLogicalPerPackage / pi->htInfo.nCoresPerPackage;	hCurrentProcessHandle = GetCurrentProcess();	GetProcessAffinityMask(hCurrentProcessHandle, &dwProcessAffinity, &dwSystemAffinity);	// Iterate over all available logical processors and collect topology info	for (curLogical = 0, dwAffinityMask = 1; 		( (dwAffinityMask != 0) && (dwAffinityMask <= dwProcessAffinity) && 		(curLogical < nLogicalSystem) ); curLogical++) 	{		if (SetProcessAffinityMask(hCurrentProcessHandle, dwAffinityMask)) {			BYTE PackageIDMask, CacheIDMask;			BYTE APIC_ID, SMT_ID, CORE_ID, PACKAGE_ID, LLC_ID;			Sleep(0); // continue from next time slice on appropriate CPU			APIC_ID = (BYTE) WinCPUID_getAPIC_ID();			SMT_ID = GetSubID(APIC_ID, pi->htInfo.nLogicalPerCore, 0);			CORE_ID = GetSubID(APIC_ID, pi->htInfo.nCoresPerPackage, pi->htInfo.nLogicalPerCore);			PackageIDMask = (BYTE) (0xff << WinCPUID_FindMaskWidth(pi->htInfo.nLogicalPerPackage));			PACKAGE_ID = APIC_ID & PackageIDMask;			// Cache topology may vary for each cache level, one mask for each level.			// The target level is selected by the input value index			CacheIDMask = ((BYTE) (0xff <<	WinCPUID_FindMaskWidth(getMaxNumLPSharingCache(LLC_Level, pi)))); // Find LLC's level and max sharing			LLC_ID = APIC_ID & CacheIDMask;			LogIDs[curLogical].SMT_ID = SMT_ID;			LogIDs[curLogical].CORE_ID = CORE_ID;			LogIDs[curLogical].PACKAGE_ID = PACKAGE_ID;			LogIDs[curLogical].LLC_ID = LLC_ID;			LogIDs[curLogical].packageIndex = -1;			LogIDs[curLogical].coreIndex = -1;			LogIDs[curLogical].bIsFirstSMTonCore = FALSE;		} else {			pi->htInfo.htResultCode = htError;		}		dwAffinityMask <<= 1;		nLogicalFound++;	}	// Reset affinity to all logical CPUs	SetProcessAffinityMask(hCurrentProcessHandle, dwProcessAffinity);	Sleep(0);	PackageIDBucket = (int*)_alloca(nLogicalFound * sizeof(int));	memset(PackageIDBucket, -1, nLogicalFound * sizeof(int));	CoreIDBucket = (int*)_alloca(nLogicalFound * sizeof(int));	memset(CoreIDBucket, -1, nLogicalFound * sizeof(int));	L2CacheIDBucket = (int*)_alloca(nLogicalFound * sizeof(int));	memset(L2CacheIDBucket, -1, nLogicalFound * sizeof(int));	LLCSharingBucket = (int*)_alloca(nLogicalFound*sizeof(int));	memset(LLCSharingBucket, 0, nLogicalFound * sizeof(int));	PackageProcessorMask = (DWORD_PTR*)_alloca(nLogicalFound * sizeof(DWORD_PTR));	ZeroMemory(PackageProcessorMask, nLogicalFound * sizeof(DWORD_PTR));	CoreProcessorMask = (DWORD_PTR*)_alloca(nLogicalFound * sizeof(DWORD_PTR));	ZeroMemory(CoreProcessorMask, nLogicalFound * sizeof(DWORD_PTR));	// Find the number of distinct packages	// To start, there must be at least 1 package	nPackagesFound = 1;	dwAffinityMask = 1;	LogIDs[0].packageIndex = 0;	PackageIDBucket[0] = LogIDs[0].PACKAGE_ID;	PackageProcessorMask[0] = dwAffinityMask;	PackagesAffinity = dwAffinityMask;	for (curLogical=1; curLogical < nLogicalFound; curLogical++) 	{		int curPackage;		dwAffinityMask <<= 1;		for (curPackage=0; curPackage < nPackagesFound; curPackage++)		{			if (LogIDs[curLogical].PACKAGE_ID == PackageIDBucket[curPackage])			{				PackageProcessorMask[curPackage] |= dwAffinityMask;				LogIDs[curLogical].packageIndex = curPackage;				break;			}		}		if (curPackage == nPackagesFound) 		{			// no match, found a new package			PackageIDBucket[curPackage] = LogIDs[curLogical].PACKAGE_ID;			LogIDs[curLogical].packageIndex = curPackage;			PackagesAffinity |= dwAffinityMask;			PackageProcessorMask[curPackage] |= dwAffinityMask;			nPackagesFound++;		}	}	nCoresFound = 1;	dwAffinityMask = 1;	LogIDs[0].coreIndex = 0;	LogIDs[0].bIsFirstSMTonCore = TRUE; // mark first logical on core	CoreIDBucket[0] = LogIDs[0].PACKAGE_ID | LogIDs[0].CORE_ID;	CoreProcessorMask[0] = dwAffinityMask;	CoresAffinity = dwAffinityMask;	for (curLogical=1; curLogical < nLogicalFound; curLogical++) 	{		int curCore;		dwAffinityMask <<= 1;		for (curCore=0; curCore < nCoresFound; curCore++)		{			if ( (LogIDs[curLogical].PACKAGE_ID | LogIDs[curLogical].CORE_ID) == CoreIDBucket[curCore])			{				CoreProcessorMask[curCore] |= dwAffinityMask;				LogIDs[curLogical].coreIndex = curCore;				break;			}		}		if (curCore == nCoresFound) 		{			// no match, found a new core			CoreIDBucket[curCore] = LogIDs[curLogical].PACKAGE_ID | LogIDs[curLogical].CORE_ID;			LogIDs[curLogical].coreIndex = curCore;			LogIDs[curLogical].bIsFirstSMTonCore = TRUE; // mark first logical on core			CoresAffinity |= dwAffinityMask;			CoreProcessorMask[curCore] |= dwAffinityMask;			nCoresFound++;		}	}	// Find number of unique LLC IDs	L2CachesFound = 1;	dwAffinityMask = 1;	LogIDs[0].L2CacheIndex = 0;	LogIDs[0].CacheSharedIndex = 0;	L2CacheIDBucket[0] = LogIDs[0].LLC_ID;	LLCSharingBucket[0]++;	LLCSharingAffinity = dwAffinityMask;	for (curLogical=1; curLogical < nLogicalFound; curLogical++) 	{		int curL2Cache;		dwAffinityMask <<= 1;		for (curL2Cache=0; curL2Cache < L2CachesFound; curL2Cache++)		{			if (LogIDs[curLogical].LLC_ID == L2CacheIDBucket[curL2Cache])			{				LogIDs[curLogical].L2CacheIndex = curL2Cache;				LogIDs[curLogical].CacheSharedIndex = LLCSharingBucket[curL2Cache]++;				break;			}		}		if (curL2Cache == L2CachesFound) 		{			// no match, found a new package			L2CacheIDBucket[curL2Cache] = LogIDs[curLogical].LLC_ID;			LogIDs[curLogical].L2CacheIndex = curL2Cache;			LogIDs[curLogical].CacheSharedIndex = LLCSharingBucket[curL2Cache]++;			L2CachesFound++;			curSharedIndex = 0;			LLCSharingAffinity |= dwAffinityMask;		}	}	// The rest of this is for translating the information found above into the format	// used by the WinCPUID API	pi->htInfo.nPhysicalProcs = nPackagesFound;	pi->htInfo.nCores = pi->htInfo.nCoresPerPackage * pi->htInfo.nPhysicalProcs;	pi->htInfo.nCoresAvailable = nCoresFound;	pi->htInfo.nLogicalProcs = nLogicalFound;	pi->htInfo.nLogicalPerCoreAvailable = nLogicalFound / nCoresFound;	pi->htInfo.dwPhysicalAffinity = PackagesAffinity;	pi->htInfo.CoreAffinity = CoresAffinity;	pi->htInfo.dwLogicalAffinity = dwProcessAffinity & ~PackagesAffinity;	pi->htInfo.CoreLogicalAffinity = dwProcessAffinity & ~CoresAffinity;	pi->htInfo.LLCDomainAffinity = LLCSharingAffinity;	pi->htInfo.nLastLevelCachesAvailable = L2CachesFound;	pi->htInfo.LLC_Level = LLC_Level;	MCorHT_Enabled = (nLogicalFound > nPackagesFound);	{		int nPhy;		for (nPhy = 0; pi->htInfo.pPhysProcAff && (nPhy < pi->htInfo.nMaxPhysGetProcAff) && (nPhy < pi->htInfo.nPhysicalProcs); nPhy++) {			int nCoreOnPhy=0;			pi->htInfo.pPhysProcAff[nPhy].physID = PackageIDBucket[nPhy];			pi->htInfo.pPhysProcAff[nPhy].dwPhysAffinity = PackageProcessorMask[nPhy] & PackagesAffinity;			pi->htInfo.pPhysProcAff[nPhy].dwLogAffinity = PackageProcessorMask[nPhy] & ~PackagesAffinity;			// Find all cores on this package			for (curLogical=0; curLogical < nLogicalFound; curLogical++)			{				if ((LogIDs[curLogical].packageIndex == nPhy) && (LogIDs[curLogical].bIsFirstSMTonCore == TRUE))				{					// curLogical belongs to core nCoreOnPhy on this package					if (pi->htInfo.pPhysProcAff[nPhy].pCoreProcAff && (nCoreOnPhy < pi->htInfo.nMaxCoreGetProcAff)) // check that pCoreProcAff is big enough					{						pi->htInfo.pPhysProcAff[nPhy].pCoreProcAff[nCoreOnPhy].coreID = LogIDs[curLogical].CORE_ID;						//pi->htInfo.pPhysProcAff[nPhy].pCoreProcAff[nCoreOnPhy].LLC_ID = LogIDs[curLogical].LLC_ID;						//pi->htInfo.pPhysProcAff[nPhy].pCoreProcAff[nCoreOnPhy].LLC_Index = LogIDs[curLogical].L2CacheIndex;						//pi->htInfo.pPhysProcAff[nPhy].pCoreProcAff[nCoreOnPhy].LLC_SharedIndex = LogIDs[curLogical].CacheSharedIndex;						pi->htInfo.pPhysProcAff[nPhy].pCoreProcAff[nCoreOnPhy].dwCoreAffinity = CoreProcessorMask[LogIDs[curLogical].coreIndex] & CoresAffinity;						pi->htInfo.pPhysProcAff[nPhy].pCoreProcAff[nCoreOnPhy].dwLogAffinity = CoreProcessorMask[LogIDs[curLogical].coreIndex] & ~CoresAffinity;					}					pi->htInfo.pPhysProcAff[nPhy].nCores++;					nCoreOnPhy++;				}			}		}	}	return MCorHT_Enabled;}static int testHT(CPUINFO_T *pi) {	int rval = 0;	int JT_Enabled = 0;	// Test number of procs first so it is consistent on P3/P4, DP/HT/non-HT	pi->htInfo.nLogicalPerPackage = WinCPUID_getLogicalPerPackage(pi);	JT_Enabled = getLogPhysProcs(pi);	if (!pi->bCloneFlag && (pi->coreInfo.dwCPUFeatures & HT_BIT) ) {		if (pi->htInfo.nLogicalPerPackage > 1) {			if (JT_Enabled) {				// Processors with HT enabled and available				pi->htInfo.htResultCode = htAvailable;				rval = 1;			}			else {				// Processors with HT enabled, but HT not available				pi->htInfo.htResultCode = htNotAvailable;			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -