int _cpufeature(int cpufeature) { u32_t cpuid_feature_edx = 0; int proc; proc = getprocessor(); /* If processor supports CPUID and its CPUID supports enough * parameters, retrieve EDX feature flags to test against. */ if(proc >= 586) { u32_t params, a, b, c, d; _cpuid(0, ¶ms, &b, &c, &d); if(params > 0) { _cpuid(1, &a, &b, &c, &cpuid_feature_edx); } } switch(cpufeature) { case _CPUF_I386_PSE: return cpuid_feature_edx & CPUID1_EDX_PSE; case _CPUF_I386_PGE: return cpuid_feature_edx & CPUID1_EDX_PGE; } return 0; }
PUBLIC void cpu_identify(void) { u32_t eax, ebx, ecx, edx; unsigned cpu = cpuid; eax = 0; _cpuid(&eax, &ebx, &ecx, &edx); if (ebx == INTEL_CPUID_GEN_EBX && ecx == INTEL_CPUID_GEN_ECX && edx == INTEL_CPUID_GEN_EDX) { cpu_info[cpu].vendor = CPU_VENDOR_INTEL; } else if (ebx == AMD_CPUID_GEN_EBX && ecx == AMD_CPUID_GEN_ECX && edx == AMD_CPUID_GEN_EDX) { cpu_info[cpu].vendor = CPU_VENDOR_AMD; } else cpu_info[cpu].vendor = CPU_VENDOR_UNKNOWN; if (eax == 0) return; eax = 1; _cpuid(&eax, &ebx, &ecx, &edx); cpu_info[cpu].family = (eax >> 8) & 0xf; if (cpu_info[cpu].family == 0xf) cpu_info[cpu].family += (eax >> 20) & 0xff; cpu_info[cpu].model = (eax >> 4) & 0xf; if (cpu_info[cpu].model == 0xf || cpu_info[cpu].model == 0x6) cpu_info[cpu].model += ((eax >> 16) & 0xf) << 4 ; cpu_info[cpu].stepping = eax & 0xf; cpu_info[cpu].flags[0] = ecx; cpu_info[cpu].flags[1] = edx; }
int _cpufeature(int cpufeature) { u32_t eax, ebx, ecx, edx; int proc; eax = ebx = ecx = edx = 0; proc = getprocessor(); /* If processor supports CPUID and its CPUID supports enough * parameters, retrieve EDX feature flags to test against. */ if(proc >= 586) { eax = 0; _cpuid(&eax, &ebx, &ecx, &edx); if(eax > 0) { eax = 1; _cpuid(&eax, &ebx, &ecx, &edx); } } switch(cpufeature) { case _CPUF_I386_PSE: return edx & CPUID1_EDX_PSE; case _CPUF_I386_PGE: return edx & CPUID1_EDX_PGE; case _CPUF_I386_APIC_ON_CHIP: return edx & CPUID1_EDX_APIC_ON_CHIP; case _CPUF_I386_TSC: return edx & CPUID1_EDX_TSC; case _CPUF_I386_FPU: return edx & CPUID1_EDX_FPU; #define SSE_FULL_EDX (CPUID1_EDX_FXSR | CPUID1_EDX_SSE | CPUID1_EDX_SSE2) #define SSE_FULL_ECX (CPUID1_ECX_SSE3 | CPUID1_ECX_SSSE3 | \ CPUID1_ECX_SSE4_1 | CPUID1_ECX_SSE4_2) case _CPUF_I386_SSE1234_12: return (edx & SSE_FULL_EDX) == SSE_FULL_EDX && (ecx & SSE_FULL_ECX) == SSE_FULL_ECX; case _CPUF_I386_FXSR: return edx & CPUID1_EDX_FXSR; case _CPUF_I386_SSE: return edx & CPUID1_EDX_SSE; case _CPUF_I386_SSE2: return edx & CPUID1_EDX_SSE2; case _CPUF_I386_SSE3: return ecx & CPUID1_ECX_SSE3; case _CPUF_I386_SSSE3: return ecx & CPUID1_ECX_SSSE3; case _CPUF_I386_SSE4_1: return ecx & CPUID1_ECX_SSE4_1; case _CPUF_I386_SSE4_2: return ecx & CPUID1_ECX_SSE4_2; case _CPUF_I386_HTT: return edx & CPUID1_EDX_HTT; case _CPUF_I386_HTT_MAX_NUM: return (ebx >> 16) & 0xff; } return 0; }
BOOLEAN CheckXenHypervisor(void) { ULONG eax, ebx ='fool', ecx = 'beef', edx = 'dead'; char signature[13]; // // Check that we're running on Xen and that CPUID supports leaves up to // at least 0x40000002 which we need to get the hypercall page info. // // Note: The Xen CPUID leaves may have been shifted upwards by a // multiple of 0x100. // for (; XenCPUIDBaseLeaf <= 0x40000100; XenCPUIDBaseLeaf += 0x100) { _cpuid(XenCPUIDBaseLeaf, &eax, &ebx, &ecx, &edx); *(ULONG*)(signature + 0) = ebx; *(ULONG*)(signature + 4) = ecx; *(ULONG*)(signature + 8) = edx; signature[12] = 0; if ( ((strcmp("XenVMMXenVMM", signature) == 0)|| (strcmp("XciVMMXciVMM", signature) == 0))&& (eax >= (XenCPUIDBaseLeaf + 2))) { return TRUE; } } return FALSE; }
void Detect () { // General CPU identification if (!_cpuid (&ID)) { // Core.Fatal ("Fatal error: can't detect CPU/FPU."); abort (); } // Timers & frequency u64 start,end; u32 dwStart,dwTest; SetPriorityClass (GetCurrentProcess(),REALTIME_PRIORITY_CLASS); // Detect Freq dwTest = timeGetTime(); do { dwStart = timeGetTime(); } while (dwTest==dwStart); start = GetCLK(); while (timeGetTime()-dwStart<1000) ; end = GetCLK(); clk_per_second = end-start; // Detect RDTSC Overhead clk_overhead = 0; u64 dummy = 0; for (int i=0; i<256; i++) { start = GetCLK(); clk_overhead += GetCLK()-start-dummy; } clk_overhead /= 256; // Detect QPC Overhead QueryPerformanceFrequency ((PLARGE_INTEGER)&qpc_freq) ; qpc_overhead = 0; for (int i=0; i<256; i++) { start = QPC(); qpc_overhead += QPC()-start-dummy; } qpc_overhead /= 256; SetPriorityClass (GetCurrentProcess(),NORMAL_PRIORITY_CLASS); clk_per_second -= clk_overhead; clk_per_milisec = clk_per_second/1000; clk_per_microsec = clk_per_milisec/1000; _control87 ( _PC_64, MCW_PC ); // _control87 ( _RC_CHOP, MCW_RC ); double a,b; a = 1; b = double(clk_per_second); clk_to_seconds = float(double(a/b)); a = 1000; b = double(clk_per_second); clk_to_milisec = float(double(a/b)); a = 1000000;b = double(clk_per_second); clk_to_microsec = float(double(a/b)); }
void _cpu_info(void) { unsigned int *istr; int oldbrand; struct cpuid_result cpuid_r; mem_zero(&cpu_i, sizeof(struct cpu_info)); _cpuid(CPUID_BASIC ,&cpuid_r); istr = (unsigned int *) cpu_i.vendor_string; istr[0] = cpuid_r.r_ebx; istr[1] = cpuid_r.r_edx; istr[2] = cpuid_r.r_ecx; _cpuid(CPUID_FEATURE ,&cpuid_r); cpu_i.version_information = cpuid_r.r_eax; oldbrand = cpuid_r.r_ebx & 0x8; cpu_i.feature_ecx = cpuid_r.r_ecx; cpu_i.feature_edx = cpuid_r.r_edx; _cpuid(CPUID_EXT_MAX, &cpuid_r); if (cpuid_r.r_eax >= CPUID_EXT_BRAND3) { int i = 0; istr = (unsigned int *) cpu_i.brand_string; _cpuid(CPUID_EXT_BRAND1, &cpuid_r); istr[i++] = cpuid_r.r_eax; istr[i++] = cpuid_r.r_ebx; istr[i++] = cpuid_r.r_ecx; istr[i++] = cpuid_r.r_edx; _cpuid(CPUID_EXT_BRAND2, &cpuid_r); istr[i++] = cpuid_r.r_eax; istr[i++] = cpuid_r.r_ebx; istr[i++] = cpuid_r.r_ecx; istr[i++] = cpuid_r.r_edx; _cpuid(CPUID_EXT_BRAND3, &cpuid_r); istr[i++] = cpuid_r.r_eax; istr[i++] = cpuid_r.r_ebx; istr[i++] = cpuid_r.r_ecx; istr[i++] = cpuid_r.r_edx; } else { if (oldbrand == 0 || oldbrand > 0x18) { snprintf(cpu_i.brand_string, 54, "brand id %u", oldbrand); } else { str_ncpy(cpu_i.brand_string, cpu_old_brands[oldbrand], 54); } } }
VOID XenCpuid(ULONG leaf, ULONG *peax, ULONG *pebx, ULONG *pecx, ULONG *pedx) { _cpuid(leaf + XenCPUIDBaseLeaf, peax, pebx, pecx, pedx); }