Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/symcrypt/lib/cpuid_um.c
15010 views
1
//
2
// cpuid_um.c code for CPU feature detection based on OS features available in user-mode
3
//
4
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5
//
6
// This file contains the feature detection code that is only compiled for user-mode.
7
// The IsProcessorFeaturePresent API is only in UM, so linking any code out of
8
// a source file that contains a call to it doesn't work for KM code.
9
// By splitting it into a separate file, the code is ignored by KM callers because
10
// they never reference anything in this file.
11
//
12
13
14
15
#include "precomp.h"
16
17
#if SYMCRYPT_CPU_ARM64 && SYMCRYPT_PLATFORM_WINDOWS
18
#undef UNREFERENCED_PARAMETER
19
#include <processthreadsapi.h>
20
21
// From winnt.h
22
#define PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE 30
23
24
VOID
25
SYMCRYPT_CALL
26
SymCryptDetectCpuFeaturesFromIsProcessorFeaturePresent(void)
27
{
28
if( IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) )
29
{
30
g_SymCryptCpuFeaturesNotPresent = (SYMCRYPT_CPU_FEATURES) ~(
31
SYMCRYPT_CPU_FEATURE_NEON |
32
SYMCRYPT_CPU_FEATURE_NEON_AES |
33
SYMCRYPT_CPU_FEATURE_NEON_PMULL |
34
SYMCRYPT_CPU_FEATURE_NEON_SHA256
35
);
36
} else {
37
g_SymCryptCpuFeaturesNotPresent = (SYMCRYPT_CPU_FEATURES) ~SYMCRYPT_CPU_FEATURE_NEON;
38
}
39
}
40
41
#elif SYMCRYPT_CPU_ARM64 && SYMCRYPT_GNUC
42
43
#if SYMCRYPT_PLATFORM_APPLE
44
#include <sys/sysctl.h>
45
46
VOID
47
SYMCRYPT_CALL
48
SymCryptDetectCpuFeaturesFromIsProcessorFeaturePresent(void)
49
{
50
// Arm64 code relies on presence of ASIMD everywhere (it is always present with Armv8); the
51
// compiler is permitted to generate ASIMD instructions anywhere
52
// The SYMCRYPT_CPU_FEATURE_NEON is currently always present and never checked
53
SYMCRYPT_CPU_FEATURES result = ~SYMCRYPT_CPU_FEATURE_NEON;
54
55
// On macOS ARM64, we use sysctl to query CPU features
56
// All Apple Silicon Macs support AES, PMULL, and SHA2 instructions
57
uint32_t has_feature = 0;
58
size_t len = sizeof(has_feature);
59
60
// Check for AES support
61
if( sysctlbyname("hw.optional.arm.FEAT_AES", &has_feature, &len, NULL, 0) == 0 && has_feature )
62
{
63
result &= ~SYMCRYPT_CPU_FEATURE_NEON_AES;
64
}
65
66
// Check for PMULL support
67
has_feature = 0;
68
len = sizeof(has_feature);
69
if( sysctlbyname("hw.optional.arm.FEAT_PMULL", &has_feature, &len, NULL, 0) == 0 && has_feature )
70
{
71
result &= ~SYMCRYPT_CPU_FEATURE_NEON_PMULL;
72
}
73
74
// Check for SHA2 support
75
has_feature = 0;
76
len = sizeof(has_feature);
77
if( sysctlbyname("hw.optional.arm.FEAT_SHA256", &has_feature, &len, NULL, 0) == 0 && has_feature )
78
{
79
result &= ~SYMCRYPT_CPU_FEATURE_NEON_SHA256;
80
}
81
82
g_SymCryptCpuFeaturesNotPresent = result;
83
}
84
85
#else // Linux and other Unix platforms
86
87
#include <sys/auxv.h>
88
89
// #include <asm/hwcap.h>
90
#define HWCAP_AES (1 << 3)
91
#define HWCAP_PMULL (1 << 4)
92
#define HWCAP_SHA2 (1 << 6)
93
94
VOID
95
SYMCRYPT_CALL
96
SymCryptDetectCpuFeaturesFromIsProcessorFeaturePresent(void)
97
{
98
unsigned long hwcaps = getauxval( AT_HWCAP );
99
100
SYMCRYPT_CPU_FEATURES result = ~(
101
SYMCRYPT_CPU_FEATURE_NEON |
102
SYMCRYPT_CPU_FEATURE_NEON_AES |
103
SYMCRYPT_CPU_FEATURE_NEON_PMULL |
104
SYMCRYPT_CPU_FEATURE_NEON_SHA256
105
);
106
107
// Arm64 code relies on presence of ASIMD everywhere (it is always present with Armv8); the
108
// compiler is permitted to generate ASIMD instructions anywhere
109
// The SYMCRYPT_CPU_FEATURE_NEON is currently always present and never checked
110
111
if( !(hwcaps & HWCAP_AES) )
112
{
113
result |= SYMCRYPT_CPU_FEATURE_NEON_AES;
114
}
115
116
if( !(hwcaps & HWCAP_PMULL) )
117
{
118
result |= SYMCRYPT_CPU_FEATURE_NEON_PMULL;
119
}
120
121
if( !(hwcaps & HWCAP_SHA2) )
122
{
123
result |= SYMCRYPT_CPU_FEATURE_NEON_SHA256;
124
}
125
126
g_SymCryptCpuFeaturesNotPresent = result;
127
}
128
129
#endif // SYMCRYPT_PLATFORM_APPLE
130
131
#endif
132
133