Exemplo n.º 1
0
SIMDCapability DetectSIMDCapability()
{
#ifdef WIN32 ///\todo SIMD detection for other x86 platforms.

#ifdef MATH_SSE
	int CPUInfo[4] = {-1};

	unsigned    nIds;//, nExIds, i;
	int nFeatureInfo = 0;
//	bool    bSSE3Instructions = false;
//	bool    bSupplementalSSE3 = false;
//	bool    bCMPXCHG16B = false;
#ifdef MATH_SSE41
	bool    bSSE41Extensions = false;
#endif
//	bool    bSSE42Extensions = false;
//	bool    bPOPCNT = false;

//	bool    bLAHF_SAHFAvailable = false;
//	bool    bCmpLegacy = false;
//	bool    bLZCNT = false;
//	bool    bSSE4A = false;
//	bool    bMisalignedSSE = false;
//	bool    bPREFETCH = false;
//	bool    bMMXExtensions = false;
//	bool    b3DNowExt = false;
//	bool    b3DNow = false;
//	bool    bFP128 = false;
#ifdef MATH_AVX
	bool    hasAVX = false;
#endif
//	bool    bMOVOptimization = false;

	CpuId(CPUInfo, 0);
	nIds = CPUInfo[0];

	// Get the information associated with each valid Id
//	for (i=0; i<=nIds; ++i)
	if (nIds >= 1)
	{
	//	__cpuid(CPUInfo, i);

		CpuId(CPUInfo, 1);
		// Interpret CPU feature information.
//		if  (i == 1)
		{
//			bSSE3Instructions = (CPUInfo[2] & 0x1) || false;
//			bSupplementalSSE3 = (CPUInfo[2] & 0x200) || false;
//			bCMPXCHG16B= (CPUInfo[2] & 0x2000) || false;
//			bSSE41Extensions = (CPUInfo[2] & 0x80000) || false;
//			bSSE42Extensions = (CPUInfo[2] & 0x100000) || false;
//			bPOPCNT= (CPUInfo[2] & 0x800000) || false;
#ifdef MATH_AVX
			hasAVX = (CPUInfo[2] & 0x10000000) || false;
#endif
			nFeatureInfo = CPUInfo[3];
		}
	}

//	const bool hasMMX = (nFeatureInfo & (1 << 23)) != 0;

	// Calling __cpuid with 0x80000000 as the InfoType argument
	// gets the number of valid extended IDs.
//	__cpuid(CPUInfo, 0x80000000);
//	nExIds = CPUInfo[0];
/*
	// Get the information associated with each extended ID.
	for (i=0x80000000; i<=nExIds; ++i)
	{
		__cpuid(CPUInfo, i);

		if  (i == 0x80000001)
		{
			bLAHF_SAHFAvailable = (CPUInfo[2] & 0x1) || false;
			bCmpLegacy = (CPUInfo[2] & 0x2) || false;
			bLZCNT = (CPUInfo[2] & 0x20) || false;
			bSSE4A = (CPUInfo[2] & 0x40) || false;
			bMisalignedSSE = (CPUInfo[2] & 0x80) || false;
			bPREFETCH = (CPUInfo[2] & 0x100) || false;
			bMMXExtensions = (CPUInfo[3] & 0x40000) || false;
			b3DNowExt = (CPUInfo[3] & 0x40000000) || false;
			b3DNow = (CPUInfo[3] & 0x80000000) || false;
		}

		if  (i == 0x8000001A)
		{
			bFP128 = (CPUInfo[0] & 0x1) || false;
			bMOVOptimization = (CPUInfo[0] & 0x2) || false;
		}
	}
*/
#ifdef MATH_AVX
	if (hasAVX)
		return SIMD_AVX;
#endif
#ifdef MATH_SSE41
	if (bSSE41Extensions)
		return SIMD_SSE41;
#endif
#ifdef MATH_SSE2
	const bool hasSSE2 = (nFeatureInfo & (1 << 26)) != 0;
	if (hasSSE2)
		return SIMD_SSE2;
#endif
#ifdef MATH_SSE
	const bool hasSSE = (nFeatureInfo & (1 << 25)) != 0;
	if (hasSSE)
		return SIMD_SSE;
#endif

#endif // ~ MATH_SSE not defined.
#endif
	return SIMD_NONE;
}
Exemplo n.º 2
0
static FORCEINLINE NTSTATUS
__InitHypercallPage()
{
    ULONG   eax = 'DEAD';
    ULONG   ebx = 'DEAD';
    ULONG   ecx = 'DEAD';
    ULONG   edx = 'DEAD';
    ULONG   Index;
    ULONG   HypercallMsr;

    NTSTATUS    Status;

    Status = STATUS_UNSUCCESSFUL;
    for (;;) {
        CHAR Signature[13] = { 0 };

        CpuId(__BaseLeaf, &eax, &ebx, &ecx, &edx);
        *((PULONG)(Signature + 0)) = ebx;
        *((PULONG)(Signature + 4)) = ecx;
        *((PULONG)(Signature + 8)) = edx;

        if (strcmp(Signature, XEN_SIGNATURE) == 0 &&
            eax >= __BaseLeaf + 2)
            break;

        __BaseLeaf += 0x100;

        if (__BaseLeaf > 0x40000100)
            goto fail1;
    }

    CpuId(__BaseLeaf + 1, &eax, NULL, NULL, NULL);
    __MajorVersion = (USHORT)(eax >> 16);
    __MinorVersion = (USHORT)(eax & 0xFFFF);

    LogVerbose("XEN %d.%d\n", __MajorVersion, __MinorVersion);
    LogVerbose("INTERFACE 0x%08x\n", __XEN_INTERFACE_VERSION__);

    if ((ULONG_PTR)__HypercallSection & (PAGE_SIZE - 1))
        Hypercall = (PVOID)(((ULONG_PTR)__HypercallSection + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
    else
        Hypercall = (PVOID)__HypercallSection;

    ASSERT3U(((ULONG_PTR)Hypercall & (PAGE_SIZE - 1)), ==, 0);

    for (Index = 0; Index < MAXIMUM_HYPERCALL_PFN_COUNT; Index++) {
        PHYSICAL_ADDRESS    PhysicalAddress;

        PhysicalAddress = MmGetPhysicalAddress((PUCHAR)Hypercall + (Index << PAGE_SHIFT));
        __Pfn[Index] = (PFN_NUMBER)(PhysicalAddress.QuadPart >> PAGE_SHIFT);
    }

    CpuId(__BaseLeaf + 2, &eax, &ebx, NULL, NULL);
    __PfnCount = eax;
    ASSERT(__PfnCount <= MAXIMUM_HYPERCALL_PFN_COUNT);
    HypercallMsr = ebx;

    for (Index = 0; Index < __PfnCount; Index++) {
        LogVerbose("HypercallPfn[%d]: %p\n", Index, (PVOID)__Pfn[Index]);
        __writemsr(HypercallMsr, (ULONG64)__Pfn[Index] << PAGE_SHIFT);
    }

    return STATUS_SUCCESS;

fail1:
    LogError("fail1 (%08x)", Status);

    return Status;
}