mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-07 03:38:07 +00:00
wineboot: Initialize XState features in user_shared_data.
Signed-off-by: Paul Gofman <pgofman@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
0e544824f5
commit
97b5ad7597
|
@ -516,9 +516,34 @@ static void test_NtMapViewOfSection(void)
|
|||
CloseHandle(process);
|
||||
}
|
||||
|
||||
#define SUPPORTED_XSTATE_FEATURES ((1 << XSTATE_LEGACY_FLOATING_POINT) | (1 << XSTATE_LEGACY_SSE) | (1 << XSTATE_AVX))
|
||||
|
||||
static void test_user_shared_data(void)
|
||||
{
|
||||
struct old_xstate_configuration
|
||||
{
|
||||
ULONG64 EnabledFeatures;
|
||||
ULONG Size;
|
||||
ULONG OptimizedSave:1;
|
||||
ULONG CompactionEnabled:1;
|
||||
XSTATE_FEATURE Features[MAXIMUM_XSTATE_FEATURES];
|
||||
};
|
||||
|
||||
static const ULONG feature_offsets[] =
|
||||
{
|
||||
0,
|
||||
160, /*offsetof(XMM_SAVE_AREA32, XmmRegisters)*/
|
||||
512 /* sizeof(XMM_SAVE_AREA32) */ + offsetof(XSTATE, YmmContext),
|
||||
};
|
||||
static const ULONG feature_sizes[] =
|
||||
{
|
||||
160,
|
||||
256, /*sizeof(M128A) * 16 */
|
||||
sizeof(YMMCONTEXT),
|
||||
};
|
||||
const KSHARED_USER_DATA *user_shared_data = (void *)0x7ffe0000;
|
||||
XSTATE_CONFIGURATION xstate = user_shared_data->XState;
|
||||
unsigned int i;
|
||||
|
||||
ok(user_shared_data->NumberOfPhysicalPages == sbi.MmNumberOfPhysicalPages,
|
||||
"Got number of physical pages %#x, expected %#x.\n",
|
||||
|
@ -534,6 +559,48 @@ static void test_user_shared_data(void)
|
|||
ok(user_shared_data->ActiveGroupCount == 1
|
||||
|| broken(!user_shared_data->ActiveGroupCount) /* before Win7 */,
|
||||
"Got unexpected ActiveGroupCount %u.\n", user_shared_data->ActiveGroupCount);
|
||||
|
||||
if (!xstate.EnabledFeatures)
|
||||
{
|
||||
struct old_xstate_configuration *xs_old
|
||||
= (struct old_xstate_configuration *)((char *)user_shared_data + 0x3e0);
|
||||
|
||||
if (!xs_old->EnabledFeatures)
|
||||
{
|
||||
skip("XState features are not supported.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&xstate, 0, sizeof(xstate));
|
||||
xstate.EnabledFeatures = xstate.EnabledVolatileFeatures = xs_old->EnabledFeatures;
|
||||
memcpy(&xstate.Size, &xs_old->Size, sizeof(*xs_old) - offsetof(struct old_xstate_configuration, Size));
|
||||
for (i = 0; i < 3; ++i)
|
||||
xstate.AllFeatures[i] = xs_old->Features[i].Size;
|
||||
xstate.AllFeatureSize = 512 + sizeof(XSTATE);
|
||||
}
|
||||
|
||||
trace("XState EnabledFeatures %s.\n", wine_dbgstr_longlong(xstate.EnabledFeatures));
|
||||
ok((xstate.EnabledFeatures & SUPPORTED_XSTATE_FEATURES) == SUPPORTED_XSTATE_FEATURES,
|
||||
"Got unexpected EnabledFeatures %s.\n", wine_dbgstr_longlong(xstate.EnabledFeatures));
|
||||
ok((xstate.EnabledVolatileFeatures & SUPPORTED_XSTATE_FEATURES) == xstate.EnabledFeatures,
|
||||
"Got unexpected EnabledVolatileFeatures %s.\n", wine_dbgstr_longlong(xstate.EnabledVolatileFeatures));
|
||||
ok(xstate.Size >= 512 + sizeof(XSTATE), "Got unexpected Size %u.\n", xstate.Size);
|
||||
if (xstate.CompactionEnabled)
|
||||
ok(xstate.OptimizedSave, "Got zero OptimizedSave with compaction enabled.\n");
|
||||
ok(!xstate.AlignedFeatures, "Got unexpected AlignedFeatures %s.\n",
|
||||
wine_dbgstr_longlong(xstate.AlignedFeatures));
|
||||
ok(xstate.AllFeatureSize >= 512 + sizeof(XSTATE), "Got unexpected AllFeatureSize %u.\n",
|
||||
xstate.AllFeatureSize);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(feature_sizes); ++i)
|
||||
{
|
||||
ok(xstate.AllFeatures[i] == feature_sizes[i], "Got unexpected AllFeatures[%u] %u, expected %u.\n", i,
|
||||
xstate.AllFeatures[i], feature_sizes[i]);
|
||||
ok(xstate.Features[i].Size == feature_sizes[i], "Got unexpected Features[%u].Size %u, expected %u.\n", i,
|
||||
xstate.Features[i].Size, feature_sizes[i]);
|
||||
ok(xstate.Features[i].Offset == feature_offsets[i], "Got unexpected Features[%u].Offset %u, expected %u.\n",
|
||||
i, xstate.Features[i].Offset, feature_offsets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST(virtual)
|
||||
|
|
|
@ -191,6 +191,63 @@ static DWORD set_reg_value_dword( HKEY hkey, const WCHAR *name, DWORD value )
|
|||
return RegSetValueExW( hkey, name, 0, REG_DWORD, (const BYTE *)&value, sizeof(value) );
|
||||
}
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
|
||||
static void initialize_xstate_features(struct _KUSER_SHARED_DATA *data)
|
||||
{
|
||||
XSTATE_CONFIGURATION *xstate = &data->XState;
|
||||
unsigned int i;
|
||||
int regs[4];
|
||||
|
||||
if (!data->ProcessorFeatures[PF_AVX_INSTRUCTIONS_AVAILABLE])
|
||||
return;
|
||||
|
||||
__cpuidex(regs, 0, 0);
|
||||
|
||||
TRACE("Max cpuid level %#x.\n", regs[0]);
|
||||
if (regs[0] < 0xd)
|
||||
return;
|
||||
|
||||
__cpuidex(regs, 1, 0);
|
||||
TRACE("CPU features %#x, %#x, %#x, %#x.\n", regs[0], regs[1], regs[2], regs[3]);
|
||||
if (!(regs[2] & (0x1 << 27))) /* xsave OS enabled */
|
||||
return;
|
||||
|
||||
__cpuidex(regs, 0xd, 0);
|
||||
TRACE("XSAVE details %#x, %#x, %#x, %#x.\n", regs[0], regs[1], regs[2], regs[3]);
|
||||
if (!(regs[0] & XSTATE_AVX))
|
||||
return;
|
||||
|
||||
xstate->EnabledFeatures = (1 << XSTATE_LEGACY_FLOATING_POINT) | (1 << XSTATE_LEGACY_SSE) | (1 << XSTATE_AVX);
|
||||
xstate->EnabledVolatileFeatures = xstate->EnabledFeatures;
|
||||
xstate->Size = sizeof(XSAVE_FORMAT) + sizeof(XSTATE);
|
||||
xstate->AllFeatureSize = regs[1];
|
||||
xstate->AllFeatures[0] = offsetof(XSAVE_FORMAT, XmmRegisters);
|
||||
xstate->AllFeatures[1] = sizeof(M128A) * 16;
|
||||
xstate->AllFeatures[2] = sizeof(YMMCONTEXT);
|
||||
|
||||
for (i = 0; i < 3; ++i)
|
||||
xstate->Features[i].Size = xstate->AllFeatures[i];
|
||||
|
||||
xstate->Features[1].Offset = xstate->Features[0].Size;
|
||||
xstate->Features[2].Offset = sizeof(XSAVE_FORMAT) + offsetof(XSTATE, YmmContext);
|
||||
|
||||
__cpuidex(regs, 0xd, 1);
|
||||
xstate->OptimizedSave = regs[0] & 1;
|
||||
xstate->CompactionEnabled = !!(regs[0] & 2);
|
||||
|
||||
__cpuidex(regs, 0xd, 2);
|
||||
TRACE("XSAVE feature 2 %#x, %#x, %#x, %#x.\n", regs[0], regs[1], regs[2], regs[3]);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void initialize_xstate_features(struct _KUSER_SHARED_DATA *data)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void create_user_shared_data(void)
|
||||
{
|
||||
struct _KUSER_SHARED_DATA *data;
|
||||
|
@ -276,6 +333,8 @@ static void create_user_shared_data(void)
|
|||
data->ActiveProcessorCount = NtCurrentTeb()->Peb->NumberOfProcessors;
|
||||
data->ActiveGroupCount = 1;
|
||||
|
||||
initialize_xstate_features( data );
|
||||
|
||||
UnmapViewOfFile( data );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue