203 lines
5.0 KiB
C++
203 lines
5.0 KiB
C++
|
/**************************************************************************\
|
||
|
*
|
||
|
* Copyright (c) 1999 Microsoft Corporation
|
||
|
*
|
||
|
* Module Name:
|
||
|
*
|
||
|
* OS information
|
||
|
*
|
||
|
* Abstract:
|
||
|
*
|
||
|
* Describes the OS that is running
|
||
|
*
|
||
|
* Revision History:
|
||
|
*
|
||
|
* 05/13/1999 davidx
|
||
|
* Created it.
|
||
|
* 09/08/1999 agodfrey
|
||
|
* Moved to Runtime\OSInfo.cpp
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
#include "precomp.hpp"
|
||
|
|
||
|
namespace GpRuntime {
|
||
|
|
||
|
DWORD OSInfo::VAllocChunk;
|
||
|
DWORD OSInfo::PageSize;
|
||
|
DWORD OSInfo::MajorVersion;
|
||
|
DWORD OSInfo::MinorVersion;
|
||
|
BOOL OSInfo::IsNT;
|
||
|
BOOL OSInfo::HasMMX;
|
||
|
|
||
|
BOOL DetectMMXProcessor();
|
||
|
|
||
|
}
|
||
|
|
||
|
#ifdef _X86_
|
||
|
|
||
|
/**************************************************************************\
|
||
|
*
|
||
|
* Function Description:
|
||
|
*
|
||
|
* Detect whether the processor supports MMX
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
* NONE
|
||
|
*
|
||
|
* Return Value:
|
||
|
*
|
||
|
* TRUE if the processor supports MMX
|
||
|
* FALSE otherwise
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
BOOL
|
||
|
GpRuntime::DetectMMXProcessor()
|
||
|
{
|
||
|
// NT 4.0 and up provide an API to check for MMX support; this handles
|
||
|
// floating-point emulation as well. We cannot implicitly reference this
|
||
|
// function because it's not exported by Windows 95 or NT < 4.0, so we
|
||
|
// must use GetProcAddress. Windows 98 and up do export the function, but
|
||
|
// it's stubbed, so we must also do an OS version check:
|
||
|
|
||
|
typedef BOOL (WINAPI *ISPROCESSORFEATUREPRESENTFUNCTION)(DWORD);
|
||
|
ISPROCESSORFEATUREPRESENTFUNCTION IsProcessorFeaturePresentFunction = NULL;
|
||
|
|
||
|
if ((OSInfo::IsNT) && (OSInfo::MajorVersion >= 4))
|
||
|
{
|
||
|
// LoadLibrary is not required since we're implicitly dependent on
|
||
|
// kernel32.dll, so just use GetModuleHandle:
|
||
|
|
||
|
HMODULE kernel32Handle = GetModuleHandle(TEXT("kernel32.dll"));
|
||
|
|
||
|
if (kernel32Handle != NULL)
|
||
|
{
|
||
|
IsProcessorFeaturePresentFunction =
|
||
|
(ISPROCESSORFEATUREPRESENTFUNCTION) GetProcAddress(
|
||
|
kernel32Handle, "IsProcessorFeaturePresent");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BOOL hasMMX;
|
||
|
|
||
|
if (IsProcessorFeaturePresentFunction != NULL)
|
||
|
{
|
||
|
hasMMX =
|
||
|
IsProcessorFeaturePresentFunction(PF_MMX_INSTRUCTIONS_AVAILABLE);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hasMMX = FALSE;
|
||
|
|
||
|
// IsProcessorFeaturePresent is unsupported on this OS, so we'll use
|
||
|
// CPUID to check for MMX support.
|
||
|
//
|
||
|
// If CPUID is unsupported on this processor, we'll take the
|
||
|
// exception. This will happen on most processors < Pentium, however
|
||
|
// some 486 processors support CPUID.
|
||
|
|
||
|
WARNING(("Executing processor detection; "
|
||
|
"benign first-change exception possible."));
|
||
|
|
||
|
__try
|
||
|
{
|
||
|
DWORD features;
|
||
|
|
||
|
// Get processor features using CPUID function 1:
|
||
|
|
||
|
__asm
|
||
|
{
|
||
|
push eax
|
||
|
push ebx
|
||
|
push ecx
|
||
|
push edx
|
||
|
|
||
|
mov eax, 1
|
||
|
cpuid
|
||
|
mov features, edx
|
||
|
|
||
|
pop edx
|
||
|
pop ecx
|
||
|
pop ebx
|
||
|
pop eax
|
||
|
}
|
||
|
|
||
|
// If bit 23 is set, MMX technology is supported by this
|
||
|
// processor, otherwise MMX is unsupported:
|
||
|
|
||
|
if (features & (1 << 23))
|
||
|
{
|
||
|
// Try executing an MMX instruction to make sure
|
||
|
// floating-point emulation is not on:
|
||
|
|
||
|
__asm emms
|
||
|
|
||
|
// If we made it this far, then MMX is available:
|
||
|
|
||
|
hasMMX = TRUE;
|
||
|
}
|
||
|
}
|
||
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
||
|
{
|
||
|
// We should only be here if (1) the processor does not support
|
||
|
// CPUID or (2) CPUID is supported, but floating-point emulation
|
||
|
// is enabled.
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return hasMMX;
|
||
|
}
|
||
|
|
||
|
#else // !_X86_
|
||
|
|
||
|
#define DetectMMXProcessor() FALSE
|
||
|
|
||
|
#endif // !_X86_
|
||
|
|
||
|
/**************************************************************************\
|
||
|
*
|
||
|
* Function Description:
|
||
|
*
|
||
|
* Static initialization function for OSInfo class.
|
||
|
* Called by GpRuntime::Initialize()
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
* NONE
|
||
|
*
|
||
|
* Return Value:
|
||
|
*
|
||
|
* NONE
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
VOID
|
||
|
GpRuntime::OSInfo::Initialize()
|
||
|
{
|
||
|
// Get VM information
|
||
|
|
||
|
SYSTEM_INFO sysinfo;
|
||
|
GetSystemInfo(&sysinfo);
|
||
|
|
||
|
VAllocChunk = sysinfo.dwAllocationGranularity;
|
||
|
PageSize = sysinfo.dwPageSize;
|
||
|
|
||
|
// Get operating system version information
|
||
|
|
||
|
OSVERSIONINFOA osver;
|
||
|
osver.dwOSVersionInfoSize = sizeof(osver);
|
||
|
|
||
|
if (GetVersionExA(&osver))
|
||
|
{
|
||
|
IsNT = (osver.dwPlatformId == VER_PLATFORM_WIN32_NT);
|
||
|
MajorVersion = osver.dwMajorVersion;
|
||
|
MinorVersion = osver.dwMinorVersion;
|
||
|
}
|
||
|
|
||
|
// Check to see if MMX is available
|
||
|
|
||
|
HasMMX = DetectMMXProcessor();
|
||
|
}
|