880f0922ab6116cad0701d898b138c685c8a46e1
[mirror_edk2.git] / UefiCpuPkg / Library / CpuCommonFeaturesLib / Aesni.c
1 /** @file
2 AESNI feature.
3
4 Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "CpuCommonFeatures.h"
16
17 /**
18 Prepares for the data used by CPU feature detection and initialization.
19
20 @param[in] NumberOfProcessors The number of CPUs in the platform.
21
22 @return Pointer to a buffer of CPU related configuration data.
23
24 @note This service could be called by BSP only.
25 **/
26 VOID *
27 EFIAPI
28 AesniGetConfigData (
29 IN UINTN NumberOfProcessors
30 )
31 {
32 UINT64 *ConfigData;
33
34 ConfigData = AllocateZeroPool (sizeof (UINT64) * NumberOfProcessors);
35 ASSERT (ConfigData != NULL);
36 return ConfigData;
37 }
38
39 /**
40 Detects if AESNI feature supported on current processor.
41
42 @param[in] ProcessorNumber The index of the CPU executing this function.
43 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION
44 structure for the CPU executing this function.
45 @param[in] ConfigData A pointer to the configuration buffer returned
46 by CPU_FEATURE_GET_CONFIG_DATA. NULL if
47 CPU_FEATURE_GET_CONFIG_DATA was not provided in
48 RegisterCpuFeature().
49
50 @retval TRUE AESNI feature is supported.
51 @retval FALSE AESNI feature is not supported.
52
53 @note This service could be called by BSP/APs.
54 **/
55 BOOLEAN
56 EFIAPI
57 AesniSupport (
58 IN UINTN ProcessorNumber,
59 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,
60 IN VOID *ConfigData OPTIONAL
61 )
62 {
63 MSR_SANDY_BRIDGE_FEATURE_CONFIG_REGISTER *MsrFeatureConfig;
64
65 if (IS_SANDY_BRIDGE_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||
66 IS_SILVERMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||
67 IS_XEON_5600_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||
68 IS_XEON_E7_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||
69 IS_XEON_PHI_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) {
70 MsrFeatureConfig = (MSR_SANDY_BRIDGE_FEATURE_CONFIG_REGISTER *) ConfigData;
71 ASSERT (MsrFeatureConfig != NULL);
72 MsrFeatureConfig[ProcessorNumber].Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_FEATURE_CONFIG);
73 return (CpuInfo->CpuIdVersionInfoEcx.Bits.AESNI == 1);
74 }
75 return FALSE;
76 }
77
78 /**
79 Initializes AESNI feature to specific state.
80
81 @param[in] ProcessorNumber The index of the CPU executing this function.
82 @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION
83 structure for the CPU executing this function.
84 @param[in] ConfigData A pointer to the configuration buffer returned
85 by CPU_FEATURE_GET_CONFIG_DATA. NULL if
86 CPU_FEATURE_GET_CONFIG_DATA was not provided in
87 RegisterCpuFeature().
88 @param[in] State If TRUE, then the AESNI feature must be enabled.
89 If FALSE, then the AESNI feature must be disabled.
90
91 @retval RETURN_SUCCESS AESNI feature is initialized.
92
93 @note This service could be called by BSP only.
94 **/
95 RETURN_STATUS
96 EFIAPI
97 AesniInitialize (
98 IN UINTN ProcessorNumber,
99 IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo,
100 IN VOID *ConfigData, OPTIONAL
101 IN BOOLEAN State
102 )
103 {
104 MSR_SANDY_BRIDGE_FEATURE_CONFIG_REGISTER *MsrFeatureConfig;
105
106 //
107 // SANDY_BRIDGE, SILVERMONT, XEON_5600, XEON_7, and XEON_PHI have the same MSR index,
108 // Simply use MSR_SANDY_BRIDGE_FEATURE_CONFIG here
109 //
110 // The scope of the MSR_SANDY_BRIDGE_FEATURE_CONFIG is Core, only program MSR_FEATURE_CONFIG for thread 0
111 // of each core. Otherwise, once a thread in the core disabled AES, the other thread will cause GP when
112 // programming it.
113 //
114 if (CpuInfo->ProcessorInfo.Location.Thread == 0) {
115 MsrFeatureConfig = (MSR_SANDY_BRIDGE_FEATURE_CONFIG_REGISTER *) ConfigData;
116 ASSERT (MsrFeatureConfig != NULL);
117 if ((MsrFeatureConfig[ProcessorNumber].Bits.AESConfiguration & BIT0) == 0) {
118 CPU_REGISTER_TABLE_WRITE_FIELD (
119 ProcessorNumber,
120 Msr,
121 MSR_SANDY_BRIDGE_FEATURE_CONFIG,
122 MSR_SANDY_BRIDGE_FEATURE_CONFIG_REGISTER,
123 Bits.AESConfiguration,
124 BIT1 | ((State) ? 0 : BIT0)
125 );
126 }
127 }
128 return RETURN_SUCCESS;
129 }