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

📄 cpuinfo.c

📁 BIOS emulator and interface to Realmode X86 Emulator Library Can emulate a PCI Graphic Controller V
💻 C
📖 第 1 页 / 共 2 页
字号:
{#ifdef	__INTEL__	if (_CPU_haveCPUID())		return (_CPU_getCPUIDFeatures() & CPU_HaveMMX) != 0;	return false;#else	return false;#endif}/****************************************************************************DESCRIPTION:Returns true if the processor supports AMD 3DNow! extensions.HEADER:ztimer.hRETURNS:True if 3DNow! is available, false if not.REMARKS:This function determines if the processor supports the AMD 3DNow! extendedinstruction set.SEE ALSO:CPU_getProcessorType, CPU_getProcessorSpeed, CPU_haveMMX, CPU_haveKNI****************************************************************************/ibool ZAPI CPU_have3DNow(void){#ifdef	__INTEL__	if (_CPU_haveCPUID())		return _CPU_have3DNow();	return false;#else	return false;#endif}/****************************************************************************DESCRIPTION:Returns true if the processor supports Intel KNI extensions.HEADER:ztimer.hRETURNS:True if Intel KNI is available, false if not.REMARKS:This function determines if the processor supports the Intel KNI extendedinstruction set.SEE ALSO:CPU_getProcessorType, CPU_getProcessorSpeed, CPU_haveMMX, CPU_have3DNow****************************************************************************/ibool ZAPI CPU_haveKNI(void){#ifdef	__INTEL__	/* TODO: This needs to be implemented for the Pentium III */	return false;#else	return false;#endif}/****************************************************************************RETURNS:True if the RTSC instruction is available, false if not.REMARKS:This function determines if the processor supports the Intel RDTSCinstruction, for high precision timing. If the processor is not an Intel orIntel clone CPU, this function will always return false.DESCRIPTION:Returns true if the processor supports RDTSC extensions.HEADER:ztimer.hRETURNS:True if RTSC is available, false if not.REMARKS:This function determines if the processor supports the RDTSC instructionfor reading the processor time stamp counter.SEE ALSO:CPU_getProcessorType, CPU_getProcessorSpeed, CPU_haveMMX, CPU_have3DNow****************************************************************************/ibool ZAPI CPU_haveRDTSC(void){#ifdef	__INTEL__	if (_CPU_haveCPUID())		return (_CPU_getCPUIDFeatures() & CPU_HaveRDTSC) != 0;	return false;#else	return false;#endif}#ifdef	__INTEL__#define ITERATIONS		16000#define	SAMPLINGS		2#define	INNER_LOOPS		500/****************************************************************************REMARKS:If processor does not support time stamp reading, but is at least a 386 orabove, utilize method of timing a loop of BSF instructions which take aknown number of cycles to run on i386(tm), i486(tm), and Pentium(R)processors.****************************************************************************/static ulong GetBSFCpuSpeed(	ulong cycles){	CPU_largeInteger t0,t1,count_freq;	ulong	ticks;				/* Microseconds elapsed during test		*/	ulong 	current;      		/* Variable to store time elapsed		*/	int 	i,j,iPriority;	ulong 	lowest  = (ulong)-1;	iPriority = SetMaxThreadPriority();	GetCounterFrequency(&count_freq);	for (i = 0; i < SAMPLINGS; i++) {		GetCounter(&t0);		for (j = 0; j < INNER_LOOPS; j++)			_CPU_runBSFLoop(ITERATIONS);		GetCounter(&t1);		current = t1.low - t0.low;		if (current < lowest)			lowest = current;		}	RestoreThreadPriority(iPriority);	/* Compute frequency */	ticks = (ulong)((lowest * 1000000.0) / (float)(count_freq.low));	if ((ticks % count_freq.low) > (count_freq.low/2))		ticks++;			/* Round up if necessary */	if (ticks == 0)		return 0;	return ((cycles*INNER_LOOPS)/ticks);}/****************************************************************************REMARKS:Utility function to return the absolute value of a number****************************************************************************/static long _abs(long a){	return (a >= 0 ? a : -a);}#define TOLERANCE		1/****************************************************************************REMARKS:On processors supporting the Read Time Stamp opcode, compare elapsedtime on the High-Resolution Counter with elapsed cycles on the TimeStamp Register.The inner loop runs up to 20 times oruntil the average of the previousthree calculated frequencies is within 1 MHz of each of the individualcalculated frequencies. This resampling increases the accuracy of theresults since outside factors could affect this calculation.****************************************************************************/static ulong GetRDTSCCpuSpeed(void){	CPU_largeInteger	t0,t1,count_freq;	ulong 	freq=0;					/* Most current frequ. calculation                      */	ulong 	freq2=0;				/* 2nd most current frequ. calc.                        */	ulong	freq3;					/* 3rd most current frequ. calc.                        */	ulong 	total;					/* Sum of previous three frequency calculations         */	int    	tries=0;				/* Number of times a calculation has been made          */	ulong  	total_cycles=0, cycles;	/* Clock cycles elapsed during test                     */	ulong  	stamp0, stamp1;			/* Time Stamp Variable for beginning and end of test    */	ulong  	total_ticks=0, ticks;	/* Microseconds elapsed during test                     */	int		iPriority;	iPriority = SetMaxThreadPriority();	GetCounterFrequency(&count_freq);	do {		tries++;		/* Increment number of times sampled */		freq3 = freq2;	/* Shift frequencies back */		freq2 = freq;		/* Loop until 100 ticks have passed since last read of hi-res		 * counter. This accounts for overhead later.		 */		GetCounter(&t0);		t1.low = t0.low;		t1.high = t0.high;		while ((t1.low - t0.low) < 100) {			GetCounter(&t1);			stamp0 = _CPU_quickRDTSC();			}		/* Loop until 30000 ticks have passed since last read of hi-res counter.		 * This allows for elapsed time for sampling. For a hi-res frequency		 * of 1Mhz, this is about 0.03 of a second. The frequency reported		 * by the OS dependent code should be tuned to provide a good		 * sample period depending on the accuracy of the OS timers (ie:		 * if the accuracy is lower, lower the frequency to spend more time		 * in the inner loop to get better accuracy).		 */		t0.low = t1.low;		t0.high = t1.high;		while ((t1.low - t0.low) < 30000) {			GetCounter(&t1);			stamp1 = _CPU_quickRDTSC();			}		/* Find the difference during the timing loop */		cycles = stamp1 - stamp0;		ticks = t1.low - t0.low;		/* Compute the CPU frequency */		ticks = (ulong)((ticks * 1000000.0) / count_freq.low);		total_ticks += ticks;		total_cycles += cycles;		if ((ticks % count_freq.low) > (count_freq.low/2))			ticks++;			/* Round up if necessary 					*/		freq = cycles/ticks;	/* Cycles / us  = MHz 						*/		if ((cycles % ticks) > (ticks/2))			freq++;				/* Round up if necessary					*/		total = (freq + freq2 + freq3);								/* Total last three frequency calculations	*/		} while ( (tries < 3 ) ||				  ((tries < 20) &&				   ((_abs(3 * freq -total) > (3*TOLERANCE)) ||					(_abs(3 * freq2-total) > (3*TOLERANCE)) ||					(_abs(3 * freq3-total) > (3*TOLERANCE)))));	RestoreThreadPriority(iPriority);	return (total_cycles / total_ticks);}#endif	/* __INTEL__ *//****************************************************************************DESCRIPTION:Returns the speed of the processor in Mhz.HEADER:ztimer.hRETURNS:Processor speed in Mhz.REMARKS:This function returns the speed of the CPU in Mhz. Note that if the speedcannot be determined, this function will return 0.SEE ALSO:CPU_getProcessorType, CPU_haveMMX****************************************************************************/ulong ZAPI CPU_getProcessorSpeed(void){#if defined(__INTEL__)	/* Number of cycles needed to execute a single BSF instruction on i386+	 * processors.	 */	ulong	cpuSpeed;	uint	i;	static 	ulong intel_cycles[] = {		115,47,43,		};	static 	ulong cyrix_cycles[] = {		38,38,52,52,		};	static 	ulong known_speeds[] = {		650,600,550,500,450,400,350,333,300,266,233,200,166,150,133,120,100,90,75,66,60,50,33,20,0,		};	if (CPU_haveRDTSC()) {		cpuSpeed = GetRDTSCCpuSpeed();		}	else {		int processor = CPU_getProcessorType() & CPU_mask;		uint vendor = CPU_getProcessorType() & ~CPU_mask;		if (vendor == CPU_Intel)			cpuSpeed = GetBSFCpuSpeed(ITERATIONS * intel_cycles[processor - CPU_i386]);		else if (vendor == CPU_Cyrix)			cpuSpeed = GetBSFCpuSpeed(ITERATIONS * cyrix_cycles[processor - CPU_Cyrix6x86]);		else			return 0;		}	/* Now normalise the results given known processors speeds, if the	 * speed we measure is within 2Mhz of the expected values	 */	for (i = 0; known_speeds[i] != 0; i++) {		if (cpuSpeed >= (known_speeds[i]-2) && cpuSpeed <= (known_speeds[i]+2)) {			return known_speeds[i];			}		}	return cpuSpeed;#else	return 0;#endif}

⌨️ 快捷键说明

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