Module: wine Branch: master Commit: 9e8fbdab722c9af1feec3f393a6303e69ce91edb URL: https://gitlab.winehq.org/wine/wine/-/commit/9e8fbdab722c9af1feec3f393a6303e...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Mar 15 14:21:41 2023 +0100
wineboot: Add processor features for supported WoW64 architectures on ARM64.
---
dlls/ntdll/rtl.c | 24 +++++++++++++++++++++++- dlls/ntdll/tests/wow64.c | 5 +++++ programs/wineboot/wineboot.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c index 3305d770c13..e0f5dab2732 100644 --- a/dlls/ntdll/rtl.c +++ b/dlls/ntdll/rtl.c @@ -2128,7 +2128,29 @@ void WINAPI RtlGetCurrentProcessorNumberEx(PROCESSOR_NUMBER *processor) */ BOOLEAN WINAPI RtlIsProcessorFeaturePresent( UINT feature ) { -#ifdef _WIN64 +#ifdef __aarch64__ + static const ULONGLONG arm64_features = + (1ull << PF_COMPARE_EXCHANGE_DOUBLE) | + (1ull << PF_NX_ENABLED) | + (1ull << PF_ARM_VFP_32_REGISTERS_AVAILABLE) | + (1ull << PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) | + (1ull << PF_SECOND_LEVEL_ADDRESS_TRANSLATION) | + (1ull << PF_FASTFAIL_AVAILABLE) | + (1ull << PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE) | + (1ull << PF_ARM_64BIT_LOADSTORE_ATOMIC) | + (1ull << PF_ARM_EXTERNAL_CACHE_AVAILABLE) | + (1ull << PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE) | + (1ull << PF_ARM_V8_INSTRUCTIONS_AVAILABLE) | + (1ull << PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) | + (1ull << PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) | + (1ull << PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE) | + (1ull << PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE) | + (1ull << PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE) | + (1ull << PF_ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE); + + return (feature < PROCESSOR_FEATURE_MAX && (arm64_features & (1ull << feature)) && + user_shared_data->ProcessorFeatures[feature]); +#elif defined _WIN64 return feature < PROCESSOR_FEATURE_MAX && user_shared_data->ProcessorFeatures[feature]; #else return NtWow64IsProcessorFeaturePresent( feature ); diff --git a/dlls/ntdll/tests/wow64.c b/dlls/ntdll/tests/wow64.c index 111ea4ffa96..eff3ff59dc2 100644 --- a/dlls/ntdll/tests/wow64.c +++ b/dlls/ntdll/tests/wow64.c @@ -21,6 +21,7 @@
#include "ntdll_test.h" #include "winioctl.h" +#include "ddk/wdm.h"
static NTSTATUS (WINAPI *pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS,void*,ULONG,ULONG*); static NTSTATUS (WINAPI *pNtQuerySystemInformationEx)(SYSTEM_INFORMATION_CLASS,void*,ULONG,void*,ULONG,ULONG*); @@ -1003,6 +1004,10 @@ static void test_nt_wow64(void)
if (native_machine == IMAGE_FILE_MACHINE_ARM64) { + KSHARED_USER_DATA *user_shared_data = ULongToPtr( 0x7ffe0000 ); + + ok( user_shared_data->ProcessorFeatures[PF_ARM_V8_INSTRUCTIONS_AVAILABLE], "no ARM_V8\n" ); + ok( user_shared_data->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE], "no MMX\n" ); ok( !pNtWow64IsProcessorFeaturePresent( PF_ARM_V8_INSTRUCTIONS_AVAILABLE ), "ARM_V8 present\n" ); ok( pNtWow64IsProcessorFeaturePresent( PF_MMX_INSTRUCTIONS_AVAILABLE ), "MMX not present\n" ); } diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c index f89852e3f17..c05ce580298 100644 --- a/programs/wineboot/wineboot.c +++ b/programs/wineboot/wineboot.c @@ -260,6 +260,8 @@ static void create_user_shared_data(void) UNICODE_STRING name = RTL_CONSTANT_STRING( L"\KernelObjects\__wine_user_shared_data" ); NTSTATUS status; HANDLE handle; + ULONG i, machines[8]; + HANDLE process = 0;
InitializeObjectAttributes( &attr, &name, OBJ_OPENIF, NULL, NULL ); if ((status = NtOpenSection( &handle, SECTION_ALL_ACCESS, &attr ))) @@ -320,15 +322,46 @@ static void create_user_shared_data(void) features[PF_AVX_INSTRUCTIONS_AVAILABLE] = !!(sci.ProcessorFeatureBits & CPU_FEATURE_AVX); features[PF_AVX2_INSTRUCTIONS_AVAILABLE] = !!(sci.ProcessorFeatureBits & CPU_FEATURE_AVX2); break; + case PROCESSOR_ARCHITECTURE_ARM: features[PF_ARM_VFP_32_REGISTERS_AVAILABLE] = !!(sci.ProcessorFeatureBits & CPU_FEATURE_ARM_VFP_32); features[PF_ARM_NEON_INSTRUCTIONS_AVAILABLE] = !!(sci.ProcessorFeatureBits & CPU_FEATURE_ARM_NEON); features[PF_ARM_V8_INSTRUCTIONS_AVAILABLE] = (sci.ProcessorLevel >= 8); break; + case PROCESSOR_ARCHITECTURE_ARM64: features[PF_ARM_V8_INSTRUCTIONS_AVAILABLE] = TRUE; features[PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE] = !!(sci.ProcessorFeatureBits & CPU_FEATURE_ARM_V8_CRC32); features[PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE] = !!(sci.ProcessorFeatureBits & CPU_FEATURE_ARM_V8_CRYPTO); + features[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE; + features[PF_NX_ENABLED] = TRUE; + features[PF_FASTFAIL_AVAILABLE] = TRUE; + /* add features for other architectures supported by wow64 */ + if (!NtQuerySystemInformationEx( SystemSupportedProcessorArchitectures, &process, sizeof(process), + machines, sizeof(machines), NULL )) + { + for (i = 0; machines[i]; i++) + { + switch (LOWORD(machines[i])) + { + case IMAGE_FILE_MACHINE_ARMNT: + features[PF_ARM_VFP_32_REGISTERS_AVAILABLE] = TRUE; + features[PF_ARM_NEON_INSTRUCTIONS_AVAILABLE] = TRUE; + break; + case IMAGE_FILE_MACHINE_I386: + features[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE; + features[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE; + features[PF_RDTSC_INSTRUCTION_AVAILABLE] = TRUE; + features[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = TRUE; + features[PF_SSE3_INSTRUCTIONS_AVAILABLE] = TRUE; + features[PF_RDTSCP_INSTRUCTION_AVAILABLE] = TRUE; + features[PF_SSSE3_INSTRUCTIONS_AVAILABLE] = TRUE; + features[PF_SSE4_1_INSTRUCTIONS_AVAILABLE] = TRUE; + features[PF_SSE4_2_INSTRUCTIONS_AVAILABLE] = TRUE; + break; + } + } + } break; } data->ActiveProcessorCount = NtCurrentTeb()->Peb->NumberOfProcessors;