ntdll: Implement the SystemProcessorFeaturesInformation query.
This commit is contained in:
parent
72422be6d2
commit
c44e58c88b
4 changed files with 59 additions and 31 deletions
|
@ -305,6 +305,7 @@ static void test_query_cpu(void)
|
|||
{
|
||||
NTSTATUS status;
|
||||
ULONG len, buffer[16];
|
||||
SYSTEM_PROCESSOR_FEATURES_INFORMATION features;
|
||||
SYSTEM_CPU_INFORMATION sci, sci2, sci3;
|
||||
|
||||
memset(&sci, 0xcc, sizeof(sci));
|
||||
|
@ -374,6 +375,17 @@ static void test_query_cpu(void)
|
|||
ok( sci.ProcessorFeatureBits == sci3.ProcessorFeatureBits, "ProcessorFeatureBits differs %lx / %lx\n",
|
||||
sci.ProcessorFeatureBits, sci3.ProcessorFeatureBits );
|
||||
|
||||
len = 0xdeadbeef;
|
||||
status = pNtQuerySystemInformation( SystemProcessorFeaturesInformation, &features, sizeof(features), &len );
|
||||
if (status != STATUS_NOT_SUPPORTED)
|
||||
{
|
||||
ok( !status, "SystemProcessorFeaturesInformation failed %lx\n", status );
|
||||
ok( len == sizeof(features), "wrong len %lu\n", len );
|
||||
ok( (ULONG)features.ProcessorFeatureBits == sci.ProcessorFeatureBits, "wrong bits %I64x / %lx\n",
|
||||
features.ProcessorFeatureBits, sci.ProcessorFeatureBits );
|
||||
}
|
||||
else skip( "SystemProcessorFeaturesInformation is not supported\n" );
|
||||
|
||||
len = 0xdeadbeef;
|
||||
status = pNtQuerySystemInformation( SystemProcessorBrandString, buffer, sizeof(buffer), &len );
|
||||
if (status != STATUS_NOT_SUPPORTED)
|
||||
|
|
|
@ -229,6 +229,7 @@ struct smbios_chassis_args
|
|||
#define RSMB 0x52534D42
|
||||
|
||||
SYSTEM_CPU_INFORMATION cpu_info = { 0 };
|
||||
static SYSTEM_PROCESSOR_FEATURES_INFORMATION cpu_features;
|
||||
static char cpu_name[49];
|
||||
static SYSTEM_LOGICAL_PROCESSOR_INFORMATION *logical_proc_info;
|
||||
static unsigned int logical_proc_info_len, logical_proc_info_alloc_len;
|
||||
|
@ -345,6 +346,7 @@ static void get_cpuid_name( char *buffer )
|
|||
static void get_cpuinfo( SYSTEM_CPU_INFORMATION *info )
|
||||
{
|
||||
unsigned int regs[4], regs2[4], regs3[4];
|
||||
ULONGLONG features;
|
||||
|
||||
#if defined(__i386__)
|
||||
info->ProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
|
||||
|
@ -353,7 +355,7 @@ static void get_cpuinfo( SYSTEM_CPU_INFORMATION *info )
|
|||
#endif
|
||||
|
||||
/* We're at least a 386 */
|
||||
info->ProcessorFeatureBits = CPU_FEATURE_VME | CPU_FEATURE_X86 | CPU_FEATURE_PGE;
|
||||
features = CPU_FEATURE_VME | CPU_FEATURE_X86 | CPU_FEATURE_PGE;
|
||||
info->ProcessorLevel = 3;
|
||||
|
||||
if (!have_cpuid()) return;
|
||||
|
@ -362,35 +364,35 @@ static void get_cpuinfo( SYSTEM_CPU_INFORMATION *info )
|
|||
if (regs[0]>=0x00000001) /* Check for supported cpuid version */
|
||||
{
|
||||
do_cpuid( 0x00000001, 0, regs2 ); /* get cpu features */
|
||||
if (regs2[3] & (1 << 3 )) info->ProcessorFeatureBits |= CPU_FEATURE_PSE;
|
||||
if (regs2[3] & (1 << 4 )) info->ProcessorFeatureBits |= CPU_FEATURE_TSC;
|
||||
if (regs2[3] & (1 << 6 )) info->ProcessorFeatureBits |= CPU_FEATURE_PAE;
|
||||
if (regs2[3] & (1 << 8 )) info->ProcessorFeatureBits |= CPU_FEATURE_CX8;
|
||||
if (regs2[3] & (1 << 11)) info->ProcessorFeatureBits |= CPU_FEATURE_SEP;
|
||||
if (regs2[3] & (1 << 12)) info->ProcessorFeatureBits |= CPU_FEATURE_MTRR;
|
||||
if (regs2[3] & (1 << 15)) info->ProcessorFeatureBits |= CPU_FEATURE_CMOV;
|
||||
if (regs2[3] & (1 << 16)) info->ProcessorFeatureBits |= CPU_FEATURE_PAT;
|
||||
if (regs2[3] & (1 << 23)) info->ProcessorFeatureBits |= CPU_FEATURE_MMX;
|
||||
if (regs2[3] & (1 << 24)) info->ProcessorFeatureBits |= CPU_FEATURE_FXSR;
|
||||
if (regs2[3] & (1 << 25)) info->ProcessorFeatureBits |= CPU_FEATURE_SSE;
|
||||
if (regs2[3] & (1 << 26)) info->ProcessorFeatureBits |= CPU_FEATURE_SSE2;
|
||||
if (regs2[2] & (1 << 0 )) info->ProcessorFeatureBits |= CPU_FEATURE_SSE3;
|
||||
if (regs2[2] & (1 << 9 )) info->ProcessorFeatureBits |= CPU_FEATURE_SSSE3;
|
||||
if (regs2[2] & (1 << 13)) info->ProcessorFeatureBits |= CPU_FEATURE_CX128;
|
||||
if (regs2[2] & (1 << 19)) info->ProcessorFeatureBits |= CPU_FEATURE_SSE41;
|
||||
if (regs2[2] & (1 << 20)) info->ProcessorFeatureBits |= CPU_FEATURE_SSE42;
|
||||
if (regs2[2] & (1 << 27)) info->ProcessorFeatureBits |= CPU_FEATURE_XSAVE;
|
||||
if (regs2[2] & (1 << 28)) info->ProcessorFeatureBits |= CPU_FEATURE_AVX;
|
||||
if (regs2[3] & (1 << 3 )) features |= CPU_FEATURE_PSE;
|
||||
if (regs2[3] & (1 << 4 )) features |= CPU_FEATURE_TSC;
|
||||
if (regs2[3] & (1 << 6 )) features |= CPU_FEATURE_PAE;
|
||||
if (regs2[3] & (1 << 8 )) features |= CPU_FEATURE_CX8;
|
||||
if (regs2[3] & (1 << 11)) features |= CPU_FEATURE_SEP;
|
||||
if (regs2[3] & (1 << 12)) features |= CPU_FEATURE_MTRR;
|
||||
if (regs2[3] & (1 << 15)) features |= CPU_FEATURE_CMOV;
|
||||
if (regs2[3] & (1 << 16)) features |= CPU_FEATURE_PAT;
|
||||
if (regs2[3] & (1 << 23)) features |= CPU_FEATURE_MMX;
|
||||
if (regs2[3] & (1 << 24)) features |= CPU_FEATURE_FXSR;
|
||||
if (regs2[3] & (1 << 25)) features |= CPU_FEATURE_SSE;
|
||||
if (regs2[3] & (1 << 26)) features |= CPU_FEATURE_SSE2;
|
||||
if (regs2[2] & (1 << 0 )) features |= CPU_FEATURE_SSE3;
|
||||
if (regs2[2] & (1 << 9 )) features |= CPU_FEATURE_SSSE3;
|
||||
if (regs2[2] & (1 << 13)) features |= CPU_FEATURE_CX128;
|
||||
if (regs2[2] & (1 << 19)) features |= CPU_FEATURE_SSE41;
|
||||
if (regs2[2] & (1 << 20)) features |= CPU_FEATURE_SSE42;
|
||||
if (regs2[2] & (1 << 27)) features |= CPU_FEATURE_XSAVE;
|
||||
if (regs2[2] & (1 << 28)) features |= CPU_FEATURE_AVX;
|
||||
if((regs2[3] & (1 << 26)) && (regs2[3] & (1 << 24)) && have_sse_daz_mode()) /* has SSE2 and FXSAVE/FXRSTOR */
|
||||
info->ProcessorFeatureBits |= CPU_FEATURE_DAZ;
|
||||
features |= CPU_FEATURE_DAZ;
|
||||
|
||||
if (regs[0] >= 0x00000007)
|
||||
{
|
||||
do_cpuid( 0x00000007, 0, regs3 ); /* get extended features */
|
||||
if (regs3[1] & (1 << 5)) info->ProcessorFeatureBits |= CPU_FEATURE_AVX2;
|
||||
if (regs3[1] & (1 << 5)) features |= CPU_FEATURE_AVX2;
|
||||
}
|
||||
|
||||
if (info->ProcessorFeatureBits & CPU_FEATURE_XSAVE)
|
||||
if (features & CPU_FEATURE_XSAVE)
|
||||
{
|
||||
do_cpuid( 0x0000000d, 1, regs3 ); /* get XSAVE details */
|
||||
if (regs3[0] & 2) xstate_compaction_enabled = TRUE;
|
||||
|
@ -411,10 +413,10 @@ static void get_cpuinfo( SYSTEM_CPU_INFORMATION *info )
|
|||
if (regs[0] >= 0x80000001)
|
||||
{
|
||||
do_cpuid( 0x80000001, 0, regs2 ); /* get vendor features */
|
||||
if (regs2[2] & (1 << 2)) info->ProcessorFeatureBits |= CPU_FEATURE_VIRT;
|
||||
if (regs2[3] & (1 << 20)) info->ProcessorFeatureBits |= CPU_FEATURE_NX;
|
||||
if (regs2[3] & (1 << 27)) info->ProcessorFeatureBits |= CPU_FEATURE_TSC;
|
||||
if (regs2[3] & (1u << 31)) info->ProcessorFeatureBits |= CPU_FEATURE_3DNOW;
|
||||
if (regs2[2] & (1 << 2)) features |= CPU_FEATURE_VIRT;
|
||||
if (regs2[3] & (1 << 20)) features |= CPU_FEATURE_NX;
|
||||
if (regs2[3] & (1 << 27)) features |= CPU_FEATURE_TSC;
|
||||
if (regs2[3] & (1u << 31)) features |= CPU_FEATURE_3DNOW;
|
||||
}
|
||||
if (regs[0] >= 0x80000004) get_cpuid_name( cpu_name );
|
||||
}
|
||||
|
@ -428,15 +430,15 @@ static void get_cpuinfo( SYSTEM_CPU_INFORMATION *info )
|
|||
info->ProcessorRevision |= ((regs2[0] >> 4 ) & 0xf) << 8; /* model */
|
||||
info->ProcessorRevision |= regs2[0] & 0xf; /* stepping */
|
||||
|
||||
if(regs2[2] & (1 << 5)) info->ProcessorFeatureBits |= CPU_FEATURE_VIRT;
|
||||
if(regs2[3] & (1 << 21)) info->ProcessorFeatureBits |= CPU_FEATURE_DS;
|
||||
if(regs2[2] & (1 << 5)) features |= CPU_FEATURE_VIRT;
|
||||
if(regs2[3] & (1 << 21)) features |= CPU_FEATURE_DS;
|
||||
|
||||
do_cpuid( 0x80000000, 0, regs ); /* get vendor cpuid level */
|
||||
if (regs[0] >= 0x80000001)
|
||||
{
|
||||
do_cpuid( 0x80000001, 0, regs2 ); /* get vendor features */
|
||||
if (regs2[3] & (1 << 20)) info->ProcessorFeatureBits |= CPU_FEATURE_NX;
|
||||
if (regs2[3] & (1 << 27)) info->ProcessorFeatureBits |= CPU_FEATURE_TSC;
|
||||
if (regs2[3] & (1 << 20)) features |= CPU_FEATURE_NX;
|
||||
if (regs2[3] & (1 << 27)) features |= CPU_FEATURE_TSC;
|
||||
}
|
||||
if (regs[0] >= 0x80000004) get_cpuid_name( cpu_name );
|
||||
}
|
||||
|
@ -449,6 +451,7 @@ static void get_cpuinfo( SYSTEM_CPU_INFORMATION *info )
|
|||
info->ProcessorRevision |= regs2[0] & 0xf; /* stepping */
|
||||
}
|
||||
}
|
||||
info->ProcessorFeatureBits = cpu_features.ProcessorFeatureBits = features;
|
||||
}
|
||||
|
||||
#elif defined(__arm__)
|
||||
|
@ -3204,6 +3207,12 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
|
|||
break;
|
||||
}
|
||||
|
||||
case SystemProcessorFeaturesInformation: /* 154 */
|
||||
len = sizeof(cpu_features);
|
||||
if (size >= len) memcpy( info, &cpu_features, len );
|
||||
else ret = STATUS_INFO_LENGTH_MISMATCH;
|
||||
break;
|
||||
|
||||
case SystemCpuSetInformation: /* 175 */
|
||||
return NtQuerySystemInformationEx(class, NULL, 0, info, size, ret_size);
|
||||
|
||||
|
|
|
@ -331,6 +331,7 @@ NTSTATUS WINAPI wow64_NtQuerySystemInformation( UINT *args )
|
|||
case SystemKernelDebuggerInformationEx: /* SYSTEM_KERNEL_DEBUGGER_INFORMATION_EX */
|
||||
case SystemCpuSetInformation: /* SYSTEM_CPU_SET_INFORMATION */
|
||||
case SystemProcessorBrandString: /* char[] */
|
||||
case SystemProcessorFeaturesInformation: /* SYSTEM_PROCESSOR_FEATURES_INFORMATION */
|
||||
case SystemWineVersionInformation: /* char[] */
|
||||
return NtQuerySystemInformation( class, ptr, len, retlen );
|
||||
|
||||
|
|
|
@ -2389,6 +2389,12 @@ typedef struct _SYSTEM_CPU_INFORMATION {
|
|||
#define CPU_FEATURE_ARM_V8_CRC32 0x00000004
|
||||
#define CPU_FEATURE_ARM_V8_CRYPTO 0x00000008
|
||||
|
||||
typedef struct _SYSTEM_PROCESSOR_FEATURES_INFORMATION
|
||||
{
|
||||
ULONGLONG ProcessorFeatureBits;
|
||||
ULONGLONG Reserved[3];
|
||||
} SYSTEM_PROCESSOR_FEATURES_INFORMATION, *PSYSTEM_PROCESSOR_FEATURES_INFORMATION;
|
||||
|
||||
/* System Information Class 0x02 */
|
||||
|
||||
/* Documented in "Windows NT/2000 Native API Reference" by Gary Nebbett. */
|
||||
|
|
Loading…
Add table
Reference in a new issue