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

📄 cpuid.c

📁 270的linux说明
💻 C
📖 第 1 页 / 共 2 页
字号:
/*Copyright (c) 2008, Intel Corporation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.    * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*///#include <windows.h> #include "Cpuid.h"//#include "Opcodes_small.h"//#ifdef _M_AMD64//#pragma message("_M_AMD64 defined")//#endif//#ifdef _WIN64//#pragma message("_WIN64 defined")//#endif#ifdef _M_AMD64//extern "C"void __cpuid(int* CPUInfo, int InfoType);#pragma intrinsic(__cpuid)unsigned __int64 __rdtsc(void);#pragma intrinsic(__rdtsc)#endif// Global Variable /////////////////////////////////////////////int clone_flag;				// Flag to show whether processor							//   is an Intel clone// ELP#ifdef _M_AMD64// The MS intrinsic does not support the ecx input needed for implicit cache detectionvoid cpuid64i(CPUID_ARGS *p) {	__cpuid((int*)p, p->eax);}void rdtsc64(__int64 *p) {	*p = __rdtsc();}#else/*void cpuid32(CPUID_ARGS* p) {	__asm {		mov	edi, p		mov eax, [edi].eax		mov ecx, [edi].ecx // for functions such as eax=4		cpuid		mov [edi].eax, eax		mov [edi].ebx, ebx		mov [edi].ecx, ecx		mov [edi].edx, edx	}}*/void linux_cpuid(DWORD op, DWORD *eax, DWORD *ebx, DWORD *ecx, DWORD *edx){        __asm__("push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx"                : "=a" (*eax),                  "=D" (*ebx),                  "=c" (*ecx),                  "=d" (*edx)                : "0" (op));}void cpuid32(CPUID_ARGS* p) {	DWORD op;		op = p->eax;	linux_cpuid(op, &p->eax, &p->ebx, &p->ecx, &p->edx);}void rdtsc32(__int64 *p) {	__asm__("rdtsc;\                 movl %0, %%edi;\                 movl %%eax, (%%edi);\                 movl %%edx, 4(%%edi);"::"r"(p));}void execSSE_32() {	//__asm orps xmm0, xmm0	__asm__("orps %xmm0, %xmm0");}void execSSE2_32() {	//__asm orpd xmm0, xmm0	__asm__("orpd %xmm0, %xmm0");}#endif// Public DLL Functions /////////////////////////////////////////**************************************************************** JS - Added* int wincpuidven()* =================================* Wincpuidven() tells the caller what vendor the host processor* is.** Inputs: none** Returns:*  0 = GenuineIntel Process*  1 = AuthenticAMD processor*  2 = Other Vendor***************************************************************/int wincpuidven() {		int i=0;		BYTE vendor_id[12]="------------";		BYTE intel_id[12] ="GenuineIntel";		BYTE amd_id[12]  = "AuthenticAMD";		int vendorflag, intelFlag, amdFlag;		CPUID_ARGS ca;		ca.eax = 0;		CPUIDF(&ca);		((DWORD*)vendor_id)[0] = ca.ebx;		((DWORD*)vendor_id)[1] = ca.edx;		((DWORD*)vendor_id)[2] = ca.ecx;		intelFlag = amdFlag = 1;		for (i = 0; i < 12; i++)		{			if (vendor_id[i] != intel_id[i]) {				intelFlag = 0;				break;			}		}		for (i = 0; i < 12; i++)		{			if (vendor_id[i] != amd_id[i]) {				amdFlag = 0;				break;			}		}		clone_flag = !intelFlag;		vendorflag = intelFlag ? 0 : amdFlag ? 1 : 2;		return vendorflag;	}/**************************************************************** wincpuidsupport()** Inputs: none** Returns:*  1 = CPUID opcode is supported*  0 = CPUID opcode is not supported***************************************************************/WORD wincpuidsupport() {	int cpuid_support = 1;	 __asm__("pushf;\                 pop %%eax;\                 movl %%eax, %%ecx;\                 xorl $0x200000, %%eax;\                 pushl %%eax;\                 popf;\                 pushf;\                 popl %%eax;\                 xorl %%ecx, %%eax;\                 jnz support;\                 movl $0, %0;\                 support:;\                 movl $1, %0": "=r"(cpuid_support));	return cpuid_support;} // wincpuidsupport()/**************************************************************** wincpuid()** Inputs: none** Returns:*  0 = 8086/88*  2 = 80286*  3 = 80386*  4 = 80486*  5 = Pentium(R) Processor*  6 = PentiumPro(R) Processor*  7 or higher = Processor beyond the PentiumPro6(R) Processor**  Note: This function also sets the global variable clone_flag***************************************************************/WORD wincpuid() {	WORD cpuid;		if ( wincpuidsupport() ) {	// Determine whether CPUID 								//   opcode is supported		cpuid=check_IDProc();	}#ifndef _M_AMD64	else {				clone_flag=check_clone();		cpuid=check_8086();			// Will return FFFFh or 0		if (cpuid == 0) goto end;	    	cpuid=check_80286();       	// Will return FFFFh or 2		if (cpuid == 2) goto end;    	cpuid=check_80386();       	// Will return FFFFh or 3		if (cpuid == 3) goto end;    // temporarily commented out.                cpuid=4;		// If the processor does not support CPUID,        				//  is not an 8086, 80286, or 80386, assign        				//  processor to be an 80486	}end:	if (clone_flag)		cpuid = cpuid | CLONE_MASK;	// Signify that a clone has been									//   detected by setting MSB high #endif   	return cpuid;} // wincpuid ()/**************************************************************** wincpuidext()** Inputs: none** Returns:* AX(15:14) = Reserved (mask these off in the calling code *				before using)* AX(13:12) = Processor type (00=Standard OEM CPU, 01=OverDrive,*				10=Dual CPU, 11=Reserved)* AX(11:8)  = CPU Family (the same 4-bit quantity as wincpuid())* AX(7:4)   = CPU Model, if the processor supports the CPUID *				opcode; zero otherwise* AX(3:0)   = Stepping #, if the processor supports the CPUID *				opcode; zero otherwise** Returns 0000 if it is not an Intel processor**  Note: This function also sets the global variable clone_flag***************************************************************/DWORD wincpuidext(int *pbri, int *pscNew) {		int i=0;		WORD cpu_type=0x0000;		DWORD cpuidext=0x00000000;		DWORD bri = 0;		DWORD PSCNewFeatures = 0;		BYTE vendor_id[12]="------------";		BYTE intel_id[12]="GenuineIntel";	if ( wincpuidsupport() ) {		CPUID_ARGS ca;		ca.eax = 0;		CPUIDF(&ca);		*(DWORD*)vendor_id = ca.ebx;		*(DWORD*)(vendor_id+4) = ca.edx;		*(DWORD*)(vendor_id+8) = ca.ecx;#if 0		_asm {      			//push	ebx	// ELP			xor     eax, eax		// Set up for CPUID instruction        			//CPU_ID                  // Get and save vendor ID			cpuid			mov     dword ptr vendor_id, ebx			mov     dword ptr vendor_id[+4], edx			mov     dword ptr vendor_id[+8], ecx			//pop		ebx		}#endif		for (i=0;i<12;i++)		{			if (!(vendor_id[i]==intel_id[i])) {				clone_flag = 1;    			}		}		if (ca.eax >= 1) {			ca.eax = 1;			CPUIDF(&ca);			cpuidext = ca.eax;			bri = ca.ebx;			PSCNewFeatures = ca.ecx;		}#if 0		_asm {			//push	ebx // ELP        			cmp     eax, 1			// Make sure 1 is valid input         							//   for CPUID        			jl      end_cpuidext	// If not, jump to end			xor     eax, eax			inc		eax			cpuid			//CPU_ID					// Get family/model/stepping/        							//   features			mov		cpuidext,		eax			mov		bri,			ebx			mov		PSCNewFeatures, ecxend_cpuidext:			mov		eax, cpuidext			//pop		ebx		}#endif		if (pbri)			*pbri = bri; // pass back		if (pscNew)			*pscNew = PSCNewFeatures;	}	else {		cpu_type = wincpuid();		// If CPUID opcode is not		cpuidext = cpu_type << 8;	//   supported, put family									//   value in extensions and	}								//   return	if (clone_flag)		cpuidext |= DWCLONE_MASK;	return cpuidext;} // wincpuidext()/**************************************************************** wincpufeatures()** Inputs: none** Returns:*   0 = Processor which does not execute the CPUID instruction.*          This includes 8086, 8088, 80286, 80386, and some *		   older 80486 processors.                       ** Else*   Feature Flags (refer to App Note AP-485 for description).*      This DWORD was put into EDX by the CPUID instruction.**	Current flag assignment is as follows:**		bit31..10   reserved (=0)*		bit9=1      CPU contains a local APIC (iPentium-3V)*		bit8=1      CMPXCHG8B instruction supported*		bit7=1      machine check exception supported*		bit6=0      reserved (36bit-addressing & 2MB-paging)*		bit5=1      iPentium-style MSRs supported*		bit4=1      time stamp counter TSC supported*		bit3=1      page size extensions supported*		bit2=1      I/O breakpoints supported*		bit1=1      enhanced virtual 8086 mode supported*		bit0=1      CPU contains a floating-point unit (FPU)**	Note: New bits will be assigned on future processors... see*         processor data books for updated information**	Note: This function also sets the global variable clone_flag***************************************************************/DWORD wincpufeatures() {	int i=0;	DWORD cpuff=0x00000000;	BYTE vendor_id[12]="------------";	BYTE intel_id[12]="GenuineIntel";	CPUID_ARGS ca;	if ( wincpuidsupport() ) {		ca.eax = 0;		CPUIDF(&ca);		((DWORD*)vendor_id)[0] = ca.ebx;		((DWORD*)vendor_id)[1] = ca.edx;		((DWORD*)vendor_id)[2] = ca.ecx;#if 0		_asm {      			//push	ebx	// ELP			xor     eax, eax		// Set up for CPUID instruction        			//CPU_ID                  // Get and save vendor ID			cpuid			mov     dword ptr vendor_id, ebx			mov     dword ptr vendor_id[+4], edx			mov     dword ptr vendor_id[+8], ecx			//pop		ebx		}#endif		for (i=0;i<12;i++)		{			if (!(vendor_id[i]==intel_id[i])) {				clone_flag = 1;    			}		}		if (ca.eax >= 1) {			ca.eax = 1;			CPUIDF(&ca);			cpuff = ca.edx;		}#if 0	_asm {		//push	ebx // ELP		cmp     eax, 1			// Make sure 1 is valid input         						//   for CPUID                jl      end_cpuff		// If not, jump to end        xor     eax, eax        inc		eax		cpuid        //CPU_ID					// Get family/model/stepping/        						//   features		mov		cpuff, edxend_cpuff:		mov		eax, cpuff		//pop		ebx      }#endif	}	return cpuff;} // wincpufeatures()/**************************************************************** winknisupport()

⌨️ 快捷键说明

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