ntdll: Implement the SystemProcessorFeaturesInformation query.

This commit is contained in:
Alexandre Julliard 2023-03-14 17:37:33 +01:00
parent 72422be6d2
commit c44e58c88b
4 changed files with 59 additions and 31 deletions

View file

@ -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)

View file

@ -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);

View file

@ -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 );

View file

@ -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. */