ReactOS 0.4.17-dev-1005-g171e1de
cpuid_um.c
Go to the documentation of this file.
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
24VOID
27{
29 {
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
46VOID
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
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
94VOID
97{
98 unsigned long hwcaps = getauxval( AT_HWCAP );
99
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
127}
128
129#endif // SYMCRYPT_PLATFORM_APPLE
130
131#endif
#define NULL
Definition: types.h:112
UINT32 uint32_t
Definition: types.h:75
BOOL WINAPI IsProcessorFeaturePresent(IN DWORD ProcessorFeature)
Definition: sysinfo.c:169
GLuint64EXT * result
Definition: glext.h:11304
GLenum GLsizei len
Definition: glext.h:6722
VOID SYMCRYPT_CALL SymCryptDetectCpuFeaturesFromIsProcessorFeaturePresent(void)
#define SYMCRYPT_CALL
UINT32 SYMCRYPT_CPU_FEATURES
SYMCRYPT_CPU_FEATURES g_SymCryptCpuFeaturesNotPresent
Definition: libmain.c:20
#define PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE
Definition: ketypes.h:206