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

📄 cpu.c

📁 小型操作系统,以VC为开发环境,需要boachs调试
💻 C
📖 第 1 页 / 共 2 页
字号:
		"popfl\n"
		: "=r"(iFlag1), "=r"(iFlag2) : "i"(EFLAGS_ID)
	);
	return( (iFlag1^iFlag2) & EFLAGS_ID );
}

/************************************************************
*************************************************************
**      Function Name:			iCpuIs486
**      Author:                 x.cheng
**
**      Comment:
**			Check if the processor is a 486 or higher.
**		  This is true if the alignement check bit in  
**		  EFLAGS register is changeable.
**
**      List of parameters:
**			pstCpuInfo - 
**
**      Return value:   
**          no
**
**      Revisions:
**
*************************************************************
*************************************************************/
static inline int iCpuIs486()
{
	int iFlag1, iFlag2;

	__asm__ __volatile__ (
		"pushfl\n"
		"pushfl\n"
		"popl %0\n"
		"movl %0, %1\n"
		"xorl %2, %0\n"
		"pushl %0\n"
		"popfl\n"
		"pushfl\n"
		"popl %0\n"
		"popfl\n"
		: "=r"(iFlag1), "=r"(iFlag2) : "i"(EFLAGS_AC)
	);

	return( (iFlag1^iFlag2) & EFLAGS_AC );
}

/************************************************************
*************************************************************
**      Function Name:			CpuEvaluateFrequency
**      Author:                 x.cheng
**
**      Comment:
**			Evaluate and return the CPU frequency in kHz.
**
**      List of parameters:
**			pstCpuInfo - 
**
**      Return value:   
**          no
**
**      Revisions:
**
*************************************************************
*************************************************************/
void CpuEvaluateFrequency( ts_CpuInfo* pstCpuInfo )
{
	unsigned long long ullTimeStamp1, ullTimeStamp2;	// 64 bit...
	unsigned long ulFlags;

	if( !pstCpuInfo->unFeature.stFlags.stEdx.tsc ) {
		// CPU doesn't support Time Stamp Counter!
		// Cannot evaluate the frequency.
		pstCpuInfo->ulFrequency = 0;
		return;
	}

	SaveEflagsAndCli( ulFlags );

	// Wait until the second has precisely just started.
//	(void)sys_time( NULL );
	// Read the value of the current time-stamp counter (64-bit).
	RDTSCLL( ullTimeStamp1 );
	// Wait exactly one second.
//	(void)sys_time( NULL );
	// Read the value of the current time-stamp counter again.
	RDTSCLL( ullTimeStamp2 );

	// Now we can estimate the CPU frequency as follows.
	pstCpuInfo->ulFrequency = ( (unsigned long)(ullTimeStamp2 - ullTimeStamp1)/1000);
	
	RestoreEflags( ulFlags );

}

/************************************************************
*************************************************************
**      Function Name:			iCpuGetModelName
**      Author:                 x.cheng
**
**      Comment:
**			Get the cpu model name.
**
**      List of parameters:
**			pstCpuInfo - 
**
**      Return value:   
**          no
**
**      Revisions:
**
*************************************************************
*************************************************************/
static int iCpuGetModelName( ts_CpuInfo* pstCpuInfo) 
{
	ts_CpuName* pstNames;
	int iCnt, i;

	// First of all try to get the brand string.
	if( iCpuGetBandString(pstCpuInfo)==0 )
	{
		// Well done, brand string supported.
		return( 0 );
	}

	// Find the vendor of the CPU.
	if( strcmp(pstCpuInfo->unVendor.szString, "GenuineIntel")==0 ) {
		// Intel CPU name.
		// Try to identify the cpu name with the brand ID.
		// This is useful to identify Celeron and Xeon
		// processor.
		switch( pstCpuInfo->unBrand.ulId ) 	
		{
			case 1:
			case 10:
				strncpy( pstCpuInfo->szName,
					"Intel(R) Celeron(R)",
					sizeof(pstCpuInfo->szName) );
				return( 0 );
			break;

			case 3:
				if( pstCpuInfo->unSignature.ulNum==0x6b1 )
					strncpy( pstCpuInfo->szName,
						"Intel(R) Celeron(R)",
						sizeof(pstCpuInfo->szName) );
				else
					strncpy( pstCpuInfo->szName,
						"Intel(R) Pentium(R) Xeon",
						sizeof(pstCpuInfo->szName) );
				return( 0 );
			break;

			case 6:
				strncpy( pstCpuInfo->szName,
					"Mobile Intel(R) Pentium(R) III",
					sizeof(pstCpuInfo->szName) );
				return( 0 );
			break;

			case 7:
			case 15:
				strncpy( pstCpuInfo->szName,
					"Mobile Intel(R) Celeron(R)",
					sizeof(pstCpuInfo->szName) );
				return( 0 );
			break;

			case 11:
				if( pstCpuInfo->unSignature.ulNum<0xf13 )
					strncpy( pstCpuInfo->szName,
						"Intel(R) Xeon MP",
						sizeof(pstCpuInfo->szName) );
				else
					strncpy( pstCpuInfo->szName,
						"Intel(R) Xeon",
						sizeof(pstCpuInfo->szName) );
				return( 0 );
			break;

			case 12:
				strncpy( pstCpuInfo->szName,
					"Intel(R) Xeon MP",
					sizeof(pstCpuInfo->szName) );
				return( 0 );
			break;

			case 13:
				if( pstCpuInfo->unSignature.ulNum<0xf13 )
					strncpy( pstCpuInfo->szName,
						"Intel(R) Xeon",
						sizeof(pstCpuInfo->szName) );
				else
					strncpy( pstCpuInfo->szName,
						"Mobile Intel(R) Pentium 4",
						sizeof(pstCpuInfo->szName) );
			break;
		}
		// Find the cpu name in the intel list.
		pstNames = g_astIntelCpuNames;
		iCnt = CountOfArray( g_astIntelCpuNames );
	}
	else if( strcmp(pstCpuInfo->unVendor.szString, "AuthenticAMD")==0 )
	{
		// AMD CPU name.
		// Find the cpu name in the amd list.
		pstNames = g_astAmdCpuNames;
		iCnt = CountOfArray( g_astAmdCpuNames );
	}
	else
	{
		// Copy the unknown string to the cpu name and vendor string.
		strncpy( pstCpuInfo->unVendor.szString, "Unknown", sizeof(pstCpuInfo->unVendor.szString) );
		switch( pstCpuInfo->unSignature.stFlags.family )
		{
			case 3:
			strncpy( pstCpuInfo->szName, "386", sizeof(pstCpuInfo->szName) );
			break;

			case 4:
			strncpy( pstCpuInfo->szName, "486", sizeof(pstCpuInfo->szName) );
			break;

			default:
			strncpy( pstCpuInfo->szName, "Unknown", sizeof(pstCpuInfo->szName) );
			break;
		}
		return( -1 );
	}

	// Get the right CPU model name.
	for( i=0; i<iCnt; i++ )
	{
		if( pstCpuInfo->unSignature.stFlags.family==pstNames[i].iFamily )
		{
			int id = pstCpuInfo->unSignature.stFlags.model;
			// Copy the cpu name.
			strncpy( pstCpuInfo->szName,
				pstNames[i].aszModelNames[ id ],
				sizeof(pstCpuInfo->szName) );
		}
	}

	return( 0 );
}

/************************************************************
*************************************************************
**      Function Name:			iCpuGetBandString
**      Author:                 x.cheng
**
**      Comment:
**			Get the cpu brand string if it is available.
**
**      List of parameters:
**			pstCpuInfo - 
**
**      Return value:   
**          no
**
**      Revisions:
**
*************************************************************
*************************************************************/
static int iCpuGetBandString( ts_CpuInfo* pstCpuInfo )
{
	unsigned long* pulName = (unsigned long*)pstCpuInfo->szName;
	char *p, *q;
	unsigned long ulDummy, ulEax;

	// Check if brand string is available.
	CPUID( CPU_BRAND_STRING_IS_AVAILABLE,
		&ulEax, &ulDummy, &ulDummy, &ulDummy );

	if( ulEax<0x80000004 ) {
		// Brand string not supported! Zero the cpu name.
		memset( pstCpuInfo->szName, 0, sizeof(pstCpuInfo->szName) );
		return( -1 );
	}

	// Get the cpu brand string.
	CPUID( CPU_GET_BRAND_STRING1, &pulName[0], &pulName[1], &pulName[2], &pulName[3] );
	CPUID( CPU_GET_BRAND_STRING2, &pulName[4], &pulName[5], &pulName[6], &pulName[7] );
	CPUID( CPU_GET_BRAND_STRING3, &pulName[8], &pulName[9], &pulName[10], &pulName[11] );
	pstCpuInfo->szName[48] = '\0';

	// Intel chips right justify the string.
	// Left justify this string.
	p = q = &pstCpuInfo->szName[0];
	while ( *p == ' ' )
		p++;
	if ( p != q )
	{
		while ( *p )
			*q++ = *p++;
		// Zero pad the rest.
		while ( q <= &pstCpuInfo->szName[48] )
			*q++ = '\0';
	}

	// Well done.
	return( 0 );
}

/************************************************************
*************************************************************
**      Function Name:			CpuShowBriefInfo
**      Author:                 x.cheng
**
**      Comment:
**			Show a brief description of the cpu.
**
**      List of parameters:
**			no
**
**      Return value:   
**          no
**
**      Revisions:
**
*************************************************************
*************************************************************/
static void CpuShowBriefInfo()
{
	kprintf( "Vender ID          : %s\n", g_stCpuInfo.unVendor.szString );
	kprintf( "Name               : %s\n", g_stCpuInfo.szName );

	if ( g_stCpuInfo.ulFrequency ) {
		kprintf( "Frequency          : %u.%u MHz\n",
			g_stCpuInfo.ulFrequency/1000, g_stCpuInfo.ulFrequency%1000 );
	} else {
		kprintf( "Frequency          : ???? MHz\n" );
	}
	kprintf( "Family             : %u\n"
			 "Model              : %u\n"
			 "Stepping ID        : %u\n"
			 "Extended Family    : %u\n"
			 "Extended Model     : %u\n",
			 g_stCpuInfo.unSignature.stFlags.family,
			 g_stCpuInfo.unSignature.stFlags.model,
			 g_stCpuInfo.unSignature.stFlags.stepping,
			 g_stCpuInfo.unSignature.stFlags.ext_family,
			 g_stCpuInfo.unSignature.stFlags.ext_model );

}

/************************************************************
*************************************************************
**      Function Name:			CpuDumpCacheInfo
**      Author:                 x.cheng
**
**      Comment:
**			Dump CPU internal cache informations.
**
**      List of parameters:
**			no
**
**      Return value:   
**          no
**
**      Revisions:
**
*************************************************************
*************************************************************/
static void CpuDumpCacheInfo ()
{
	unsigned long aulCacheInfo[4];
	char* szDescription;
	unsigned long ulDummy;
	int i, j, n;

	// Get the number of times to iterate (lower 8-bits).
	CPUID( GET_CPU_CACHE, (unsigned long*)&n, &ulDummy, &ulDummy, &ulDummy );
	n &= 0xff;
	for( i=0; i<n; i++ )
	{
		CPUID( GET_CPU_CACHE,
			&aulCacheInfo[0], &aulCacheInfo[1],
			&aulCacheInfo[2], &aulCacheInfo[3] );
	}

	// If bit 31 is set this is an unknown format.
	for( i=0; i<3; i++ )
		if ( (aulCacheInfo[i] & 0x80000000) )
			aulCacheInfo[i] = 0;

	// Look up in the cache strings table.
	szDescription = (char *)aulCacheInfo;
	//HexDump(szDescription, 16);
	// Byte 0 is the level count, not a descriptor.
	for( i=1; i<4*sizeof(unsigned long); i++ )
	{
		if ( szDescription[i] )
		{
			for( j = 0; j < CountOfArray(g_astCacheString); j++ )
			{
				if ( szDescription[i]==g_astCacheString[j].ucIndex )
				{
					kprintf( "%s\n", g_astCacheString[j].szString );
					break;
				}
			}
		}
	}
	kprintf("\n");
}

⌨️ 快捷键说明

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