📄 lincpuid.c
字号:
} else { /// Processors with HT detected, but HT not enabled pi->htInfo.htResultCode = htNotEnabled; } } else { // HT Processors not detected pi->htInfo.htResultCode = htNotDetected; } return rval;}static int getFeatures8_1(CPUINFO_T *pi) { CPUID_ARGS ca; ca.eax = 0x80000000; CPUIDF(&ca); //maxb = ca.eax; if (ca.eax >= 0x80000001) { ca.eax = 0x80000001; CPUIDF(&ca); pi->coreInfo.dwFeatures8_1_edx = ca.edx; return TRUE; } else { return FALSE; }}static int getFeatures8_8(CPUINFO_T *pi) { CPUID_ARGS ca; ca.eax = 0x80000000; CPUIDF(&ca); //maxb = ca.eax; if (ca.eax >= 0x80000008) { ca.eax = 0x80000008; CPUIDF(&ca); pi->coreInfo.dwFeatures8_8_eax = ca.eax; return TRUE; } else { return FALSE; }}static int getProcStr(char *outStr) { DWORD maxb = 0; DWORD bri = 0; DWORD cpuid_arg = 0x80000000; DWORD brString[12]; CPUID_ARGS ca; if (!outStr) return FALSE; ca.eax = cpuid_arg; CPUIDF(&ca); maxb = ca.eax; if (maxb >= 0x80000004) { ca.eax = 0x80000002; CPUIDF(&ca); brString[0] = ca.eax; brString[1] = ca.ebx; brString[2] = ca.ecx; brString[3] = ca.edx; ca.eax = 0x80000003; CPUIDF(&ca); brString[4] = ca.eax; brString[5] = ca.ebx; brString[6] = ca.ecx; brString[7] = ca.edx; ca.eax = 0x80000004; CPUIDF(&ca); brString[8] = ca.eax; brString[9] = ca.ebx; brString[10] = ca.ecx; brString[11] = ca.edx; strcpy(outStr, (char *)brString); return TRUE; } else { return FALSE; }}__inline__ unsigned long long int rdtsc(){ unsigned long long int ret; __asm__ volatile (".byte 0x0f, 0x31" : "=A" (ret)); return ret;}static void GetSpeed(DWORD msTime){ struct timezone tz; struct timeval start, stop; unsigned long eax, ebx, ecx, edx; unsigned long freq = 1000; __int64 llStart, llStop, llFreq; unsigned long msecs; /* total time taken */ unsigned long long int cycles[2]; /* gotta be 64 bit */ /* Make sure we have a TSC (and hence RDTSC) */ /* cpuid (cpu->number, 1, &eax, &ebx, &ecx, &edx); if ((edx & (1<<4))==0) { printf ("No TSC, MHz calculation cannot be performed.\n"); cpu->MHz = 0; return; } */ memset(&tz, 0, sizeof(tz)); /* get this function in cached memory */ gettimeofday(&start, &tz); cycles[0] = rdtsc(); gettimeofday(&start, &tz); /* we don't trust that this is any specific length of time */ usleep(msTime * 1000); gettimeofday(&stop, &tz); cycles[1] = rdtsc(); gettimeofday(&stop, &tz); msecs = ((stop.tv_sec-start.tv_sec)*1000000) + (stop.tv_usec-start.tv_usec); llFreq = (__int64) (cycles[1]-cycles[0]) / (msecs/freq); if ((llFreq % 50) > 15) llFreq = ((llFreq / 50) * 50) + 50; else llFreq = ((llFreq / 50) * 50); g_WinCPUID_Info.llCPUFreq = llFreq;}eCacheID Exp2ImpCacheType(EXPCACHE_COMMON_T *pECC) { int cl, ct; assert(pECC); cl = pECC->CacheLevel; ct = pECC->CacheType; if (cl == 1) { if (ct == 1) return L1D; else if (ct == 2) return L1I; else return NULL_CACHE; } else if (cl == 2) { if (ct == 3) return L2; else return NULL_CACHE; } else if (cl == 3) { if (ct == 3) return L3; else return NULL_CACHE; } else return NULL_CACHE;}// pass in array of 16 bytes init'd to zero// ret val is number valid descriptorsstatic int getCacheInfo() { DWORD tDesc[4]; int i, nDesc = 16; eCacheID ecid; BYTE bdesc; DWORD tmp = 0; int bP4family = 0; if (g_WinCPUID_Info.eCPUVendor == VENDOR_INTEL) { CPUID_ARGS ca; int nExpCaches; EXPLICITCACHEINFO_T expCaches[NCACHETYPES]; // First, check for explicit cache desciption nExpCaches = MIN(WinCPUID_GetNumExplicitCaches(), NCACHETYPES); if (WinCPUID_GetExplicitCaches(expCaches, nExpCaches)) { EXPCACHE_COMMON_T expCC; for (i=0; i < nExpCaches; i++) { eCacheID ecid; WinCPUID_GetExpCacheCommonInfo(&expCC, &expCaches[i]); ecid = Exp2ImpCacheType(&expCC); if (ecid != NULL_CACHE) { g_WinCPUID_Info.pCacheInfo[ecid].sizeKB = expCC.SizeKB; g_WinCPUID_Info.pCacheInfo[ecid].setAssoc = expCC.Assoc; g_WinCPUID_Info.pCacheInfo[ecid].lineSize = expCC.LineBytes; g_WinCPUID_Info.pCacheInfo[ecid].ThreadsPerCache = expCC.ThreadsPerCache; g_WinCPUID_Info.pCacheInfo[ecid].bExpCache = TRUE; } } } // Note: In future, may have to check eax[7:0] for number of times to iterate on cpuid, for P4 it is 1 ca.eax = 2; CPUIDF(&ca); tDesc[0] = ca.eax; tDesc[1] = ca.ebx; tDesc[2] = ca.ecx; tDesc[3] = ca.edx; tDesc[0] &= 0xffffff00; // clear iteration indicator for (i=0; i<4; i++) { // Check for invalid regs if (tDesc[i] & 0x80000000) tDesc[i] = 0; } for (i=0; i < 16; i++) { bdesc = *(((BYTE*)tDesc)+i); ecid = g_ciTableLU[bdesc]; if (!g_WinCPUID_Info.pCacheInfo[ecid].bExpCache) // already filled in from explicit info g_WinCPUID_Info.pCacheInfo[ecid] = g_ciInfoLU[ecid][bdesc]; } } else {#ifdef WINCPUID_INTERNAL WinCPUID_Init_Alt_Cache_Info(&g_WinCPUID_Info);#endif } return nDesc;}// ITLB DTLB L1I L1D L2 TC// 0 1 2 3 4 5 static void initDescTable() { eCacheID ecid; memset(g_ciTableLU, 0, sizeof(int)*256); memset(g_ciInfoLU, 0, sizeof(CACHEINFO_T)*NCACHETYPES*256); ecid = ITLB; g_ciTableLU[0x01] = ecid; g_ciTableLU[0x02] = ecid; g_ciTableLU[0x50] = ecid; g_ciTableLU[0x51] = ecid; g_ciTableLU[0x52] = ecid; g_ciTableLU[0xB0] = ecid; g_ciInfoLU[ecid][0x01] = CI_01; g_ciInfoLU[ecid][0x02] = CI_02; g_ciInfoLU[ecid][0x50] = CI_50; g_ciInfoLU[ecid][0x51] = CI_51; g_ciInfoLU[ecid][0x52] = CI_52; g_ciInfoLU[ecid][0xB0] = CI_B0; // BANIAS ecid = DTLB; g_ciTableLU[0x03] = ecid; g_ciTableLU[0x04] = ecid; g_ciTableLU[0x5B] = ecid; g_ciTableLU[0x5C] = ecid; g_ciTableLU[0x5D] = ecid; g_ciTableLU[0xB3] = ecid; g_ciInfoLU[ecid][0x03] = CI_03; g_ciInfoLU[ecid][0x04] = CI_04; g_ciInfoLU[ecid][0x5B] = CI_5B; g_ciInfoLU[ecid][0x5C] = CI_5C; g_ciInfoLU[ecid][0x5D] = CI_5D; g_ciInfoLU[ecid][0xB3] = CI_B3; // BANIAS ecid = L1I; g_ciTableLU[0x06] = ecid; g_ciTableLU[0x08] = ecid; g_ciTableLU[0x30] = ecid; g_ciInfoLU[ecid][0x06] = CI_06; g_ciInfoLU[ecid][0x08] = CI_08; g_ciInfoLU[ecid][0x30] = CI_30; // BANIAS ecid = TC; g_ciTableLU[0x70] = ecid; g_ciTableLU[0x71] = ecid; g_ciTableLU[0x72] = ecid; g_ciInfoLU[ecid][0x70] = CI_70; g_ciInfoLU[ecid][0x71] = CI_71; g_ciInfoLU[ecid][0x72] = CI_72; ecid = L1D; g_ciTableLU[0x0A] = ecid; g_ciTableLU[0x0C] = ecid; g_ciTableLU[0x60] = ecid; g_ciTableLU[0x66] = ecid; g_ciTableLU[0x67] = ecid; g_ciTableLU[0x68] = ecid; g_ciTableLU[0x2C] = ecid; g_ciInfoLU[ecid][0x68] = CI_68; g_ciInfoLU[ecid][0x0A] = CI_0A; g_ciInfoLU[ecid][0x0C] = CI_0C; g_ciInfoLU[ecid][0x60] = CI_60; g_ciInfoLU[ecid][0x66] = CI_66; g_ciInfoLU[ecid][0x67] = CI_67; g_ciInfoLU[ecid][0x68] = CI_68; g_ciInfoLU[ecid][0x2C] = CI_2C; // BANIAS ecid = L2; //g_ciTableLU[0x40] = ecid; g_ciTableLU[0x41] = ecid; g_ciTableLU[0x42] = ecid; g_ciTableLU[0x43] = ecid; g_ciTableLU[0x44] = ecid; g_ciTableLU[0x45] = ecid; g_ciTableLU[0x78] = ecid; g_ciTableLU[0x79] = ecid; g_ciTableLU[0x7A] = ecid; g_ciTableLU[0x7B] = ecid; g_ciTableLU[0x7C] = ecid; g_ciTableLU[0x7D] = ecid; g_ciTableLU[0x82] = ecid; g_ciTableLU[0x84] = ecid; g_ciTableLU[0x85] = ecid; g_ciTableLU[0x86] = ecid; g_ciTableLU[0x87] = ecid; //g_ciInfoLU[ecid][0x40] = CI_40; g_ciInfoLU[ecid][0x41] = CI_41; g_ciInfoLU[ecid][0x42] = CI_42; g_ciInfoLU[ecid][0x43] = CI_43; g_ciInfoLU[ecid][0x44] = CI_44; g_ciInfoLU[ecid][0x45] = CI_45; g_ciInfoLU[ecid][0x78] = CI_78; // Dothan g_ciInfoLU[ecid][0x79] = CI_79; g_ciInfoLU[ecid][0x7A] = CI_7A; g_ciInfoLU[ecid][0x7B] = CI_7B; g_ciInfoLU[ecid][0x7C] = CI_7C; g_ciInfoLU[ecid][0x7D] = CI_7D; // Dothan g_ciInfoLU[ecid][0x82] = CI_82; g_ciInfoLU[ecid][0x84] = CI_84; g_ciInfoLU[ecid][0x85] = CI_85; g_ciInfoLU[ecid][0x86] = CI_86; // BANIAS g_ciInfoLU[ecid][0x87] = CI_87; // BANIAS ecid = L3; g_ciTableLU[0x22] = ecid; g_ciTableLU[0x23] = ecid; g_ciTableLU[0x25] = ecid; g_ciTableLU[0x29] = ecid; g_ciInfoLU[ecid][0x22] = CI_22; g_ciInfoLU[ecid][0x23] = CI_23; g_ciInfoLU[ecid][0x25] = CI_25; g_ciInfoLU[ecid][0x29] = CI_29;}static int WinCPUID_getLogicalPerPackage(CPUINFO_T *pi) { int nLPP; nLPP = (pi->coreInfo.dwCPUExtFeatures & NUM_LOGICAL_BITS) >> 16; if (nLPP == 0) nLPP = 1; // For non-HT machines // Remove P4 check for Yonah, etc. if ( pi->bCloneFlag ) { nLPP = 1; // Field only valid on Pentium 4 or newer } return nLPP;}static int WinCPUID_getAPIC_ID() { int reg_ebx = 0; int rval = -1; CPUID_ARGS ca; ca.eax = 1; CPUIDF(&ca); reg_ebx = ca.ebx; rval = (reg_ebx & INITIAL_APIC_ID_BITS) >> 24; return rval;}WINCPUID_API int WinCPUID_GetNumExplicitCaches() { int nCaches=0; DWORD t; int cacheIndex; CPUID_ARGS ca; ca.eax = 0; CPUIDF(&ca); t = ca.eax; if ((t >= 3) && (t < 0x80000000)) { for (cacheIndex=0; ; cacheIndex++) { ca.eax = 4; ca.ecx = cacheIndex; CPUIDF(&ca); t = ca.eax; if ((t & 0x1F) == 0) break; nCaches++; } } return nCaches;}WINCPUID_API BOOL WinCPUID_GetExpCacheCommonInfo(EXPCACHE_COMMON_T *pECCmn, EXPLICITCACHEINFO_T *pEC) { if (pECCmn && pEC) { DWORD L,P,W,S; pECCmn->CacheLevel = (pEC->expCI_eax >> 5) & 0x7; pECCmn->CacheType = pEC->expCI_eax & 0x1F; L = (pEC->expCI_ebx & 0xFFF) + 1; // 11:0 P = ((pEC->expCI_ebx >> 12) & 0x3FF) + 1; // 21:12 W = ((pEC->expCI_ebx >> 22) & 0x3FF) + 1; // 31:22 S = pEC->expCI_ecx + 1; pECCmn->SizeKB = L*P*W*S / 1024; pECCmn->Assoc = W; pECCmn->LineBytes = L; pECCmn->ThreadsPerCache = ((pEC->expCI_eax >> 14) & 0x3FF) + 1; // 25:14 pECCmn->CoresPerPackage = ((pEC->expCI_eax >> 26) & 0x3F) + 1; // 31:26 return TRUE; } else { return FALSE; }}WINCPUID_API BOOL WinCPUID_GetExplicitCache(EXPLICITCACHEINFO_T *expCache, int nExpCache) { DWORD t; BOOL bRet = FALSE; CPUID_ARGS ca; if (expCache) { ca.eax = 0; CPUIDF(&ca); t = ca.eax; if ((t > 3) && (t < 0x80000000)) { ca.eax = 4; ca.ecx = nExpCache; CPUIDF(&ca); expCache->expCI_eax = ca.eax; expCache->expCI_ebx = ca.ebx; expCache->expCI_ecx = ca.ecx; expCache->dwReserved1 = ca.edx; bRet = TRUE; } } return bRet;}WINCPUID_API BOOL WinCPUID_GetExplicitCaches(EXPLICITCACHEINFO_T *expCaches, int nExpCaches) { int curCache=0; DWORD t; BOOL bRet = FALSE; int cacheIndex; EXPLICITCACHEINFO_T *pCurCache; CPUID_ARGS ca; if (expCaches && (nExpCaches > 0)) { ca.eax = 0; CPUIDF(&ca); t = ca.eax; if ((t >= 3) && (t < 0x80000000)) { for (cacheIndex=0; cacheIndex < nExpCaches; cacheIndex++) { pCurCache = &expCaches[cacheIndex]; ca.eax = 4; ca.ecx = cacheIndex; CPUIDF(&ca); pCurCache->expCI_eax = ca.eax; pCurCache->expCI_ebx = ca.ebx; pCurCache->expCI_ecx = ca.ecx; pCurCache->dwReserved1 = ca.edx; } } bRet = TRUE; } return bRet;}WINCPUID_API BOOL WinCPUID_IsRunningExt64() { #ifdef _M_AMD64 return TRUE;#else return FALSE;#endif}WINCPUID_API BOOL WinCPUID_GetAddrBits(CPU_ADDR_BITS_T *pAddrBits, const CPUINFO_T *pi) { if (pAddrBits && pi && pi->bEM64T_Supported) { pAddrBits->PhysAddrBits = ((pi->coreInfo.dwFeatures8_8_eax & 0xFF)); pAddrBits->VirtAddrBits = (((pi->coreInfo.dwFeatures8_8_eax>>8) & 0xFF)); return TRUE; } return FALSE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -