]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/Library/RegisterCpuFeaturesLib/PeiRegisterCpuFeaturesLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / UefiCpuPkg / Library / RegisterCpuFeaturesLib / PeiRegisterCpuFeaturesLib.c
1 /** @file
2 CPU Register Table Library functions.
3
4 Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <PiPei.h>
10
11 #include <Library/HobLib.h>
12 #include <Library/PeiServicesLib.h>
13 #include <Library/PeiServicesTablePointerLib.h>
14 #include <Ppi/MpServices2.h>
15
16 #include "RegisterCpuFeatures.h"
17
18 #define REGISTER_CPU_FEATURES_GUID \
19 { \
20 0xa694c467, 0x697a, 0x446b, { 0xb9, 0x29, 0x5b, 0x14, 0xa0, 0xcf, 0x39, 0xf } \
21 }
22
23 EFI_GUID mRegisterCpuFeaturesHobGuid = REGISTER_CPU_FEATURES_GUID;
24
25 /**
26 Worker function to get CPU_FEATURES_DATA pointer.
27
28 @return Pointer to CPU_FEATURES_DATA.
29 **/
30 CPU_FEATURES_DATA *
31 GetCpuFeaturesData (
32 VOID
33 )
34 {
35 CPU_FEATURES_DATA *CpuInitData;
36 EFI_HOB_GUID_TYPE *GuidHob;
37 VOID *DataInHob;
38 UINT64 Data64;
39
40 CpuInitData = NULL;
41 GuidHob = GetFirstGuidHob (&mRegisterCpuFeaturesHobGuid);
42 if (GuidHob != NULL) {
43 DataInHob = GET_GUID_HOB_DATA (GuidHob);
44 CpuInitData = (CPU_FEATURES_DATA *)(*(UINTN *)DataInHob);
45 ASSERT (CpuInitData != NULL);
46 } else {
47 CpuInitData = AllocateZeroPool (sizeof (CPU_FEATURES_DATA));
48 ASSERT (CpuInitData != NULL);
49 //
50 // Build location of CPU MP DATA buffer in HOB
51 //
52 Data64 = (UINT64)(UINTN)CpuInitData;
53 BuildGuidDataHob (
54 &mRegisterCpuFeaturesHobGuid,
55 (VOID *)&Data64,
56 sizeof (UINT64)
57 );
58 }
59
60 return CpuInitData;
61 }
62
63 /**
64 Worker function to get MP PPI service pointer.
65
66 @return MP_SERVICES variable.
67 **/
68 MP_SERVICES
69 GetMpService (
70 VOID
71 )
72 {
73 EFI_STATUS Status;
74 MP_SERVICES MpService;
75
76 //
77 // Get MP Services2 Ppi
78 //
79 Status = PeiServicesLocatePpi (
80 &gEdkiiPeiMpServices2PpiGuid,
81 0,
82 NULL,
83 (VOID **)&MpService.Ppi
84 );
85 ASSERT_EFI_ERROR (Status);
86 return MpService;
87 }
88
89 /**
90 Worker function to return processor index.
91
92 @param CpuFeaturesData Cpu Feature Data structure.
93
94 @return The processor index.
95 **/
96 UINTN
97 GetProcessorIndex (
98 IN CPU_FEATURES_DATA *CpuFeaturesData
99 )
100 {
101 EFI_STATUS Status;
102 EDKII_PEI_MP_SERVICES2_PPI *CpuMp2Ppi;
103 UINTN ProcessorIndex;
104
105 CpuMp2Ppi = CpuFeaturesData->MpService.Ppi;
106
107 //
108 // For two reasons which use NULL for WhoAmI:
109 // 1. This function will be called by APs and AP should not use PeiServices Table
110 // 2. Check WhoAmI implementation, this parameter will not be used.
111 //
112 Status = CpuMp2Ppi->WhoAmI (CpuMp2Ppi, &ProcessorIndex);
113 ASSERT_EFI_ERROR (Status);
114 return ProcessorIndex;
115 }
116
117 /**
118 Worker function to MP-related information on the requested processor at the
119 instant this call is made.
120
121 @param[in] ProcessorNumber The handle number of processor.
122 @param[out] ProcessorInfoBuffer A pointer to the buffer where information for
123 the requested processor is deposited.
124
125 @return Status of MpServices->GetProcessorInfo().
126 **/
127 EFI_STATUS
128 GetProcessorInformation (
129 IN UINTN ProcessorNumber,
130 OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
131 )
132 {
133 EDKII_PEI_MP_SERVICES2_PPI *CpuMp2Ppi;
134 EFI_STATUS Status;
135 CPU_FEATURES_DATA *CpuFeaturesData;
136
137 CpuFeaturesData = GetCpuFeaturesData ();
138 CpuMp2Ppi = CpuFeaturesData->MpService.Ppi;
139
140 Status = CpuMp2Ppi->GetProcessorInfo (
141 CpuMp2Ppi,
142 ProcessorNumber,
143 ProcessorInfoBuffer
144 );
145 return Status;
146 }
147
148 /**
149 Worker function to execute a caller provided function on all enabled APs.
150
151 @param[in] Procedure A pointer to the function to be run on
152 enabled APs of the system.
153 @param[in] MpEvent The Event used to sync the result.
154
155 **/
156 VOID
157 StartupAllAPsWorker (
158 IN EFI_AP_PROCEDURE Procedure,
159 IN EFI_EVENT MpEvent
160 )
161 {
162 EFI_STATUS Status;
163 EDKII_PEI_MP_SERVICES2_PPI *CpuMp2Ppi;
164 CPU_FEATURES_DATA *CpuFeaturesData;
165
166 CpuFeaturesData = GetCpuFeaturesData ();
167 CpuMp2Ppi = CpuFeaturesData->MpService.Ppi;
168
169 //
170 // Wakeup all APs for data collection.
171 //
172 Status = CpuMp2Ppi->StartupAllAPs (
173 CpuMp2Ppi,
174 Procedure,
175 FALSE,
176 0,
177 CpuFeaturesData
178 );
179 ASSERT_EFI_ERROR (Status);
180 }
181
182 /**
183 Worker function to execute a caller provided function on all enabled CPUs.
184
185 @param[in] Procedure A pointer to the function to be run on
186 enabled CPUs of the system.
187
188 **/
189 VOID
190 StartupAllCPUsWorker (
191 IN EFI_AP_PROCEDURE Procedure
192 )
193 {
194 EFI_STATUS Status;
195 EDKII_PEI_MP_SERVICES2_PPI *CpuMp2Ppi;
196 CPU_FEATURES_DATA *CpuFeaturesData;
197
198 CpuFeaturesData = GetCpuFeaturesData ();
199
200 //
201 // Get MP Services2 Ppi
202 //
203 CpuMp2Ppi = CpuFeaturesData->MpService.Ppi;
204 Status = CpuMp2Ppi->StartupAllCPUs (
205 CpuMp2Ppi,
206 Procedure,
207 0,
208 CpuFeaturesData
209 );
210 ASSERT_EFI_ERROR (Status);
211 }
212
213 /**
214 Worker function to switch the requested AP to be the BSP from that point onward.
215
216 @param[in] ProcessorNumber The handle number of AP that is to become the new BSP.
217 **/
218 VOID
219 SwitchNewBsp (
220 IN UINTN ProcessorNumber
221 )
222 {
223 EFI_STATUS Status;
224 EDKII_PEI_MP_SERVICES2_PPI *CpuMp2Ppi;
225 CPU_FEATURES_DATA *CpuFeaturesData;
226
227 CpuFeaturesData = GetCpuFeaturesData ();
228 CpuMp2Ppi = CpuFeaturesData->MpService.Ppi;
229
230 //
231 // Wakeup all APs for data collection.
232 //
233 Status = CpuMp2Ppi->SwitchBSP (
234 CpuMp2Ppi,
235 ProcessorNumber,
236 TRUE
237 );
238 ASSERT_EFI_ERROR (Status);
239 }
240
241 /**
242 Worker function to retrieve the number of logical processor in the platform.
243
244 @param[out] NumberOfCpus Pointer to the total number of logical
245 processors in the system, including the BSP
246 and disabled APs.
247 @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical
248 processors that exist in system, including
249 the BSP.
250 **/
251 VOID
252 GetNumberOfProcessor (
253 OUT UINTN *NumberOfCpus,
254 OUT UINTN *NumberOfEnabledProcessors
255 )
256 {
257 EFI_STATUS Status;
258 EDKII_PEI_MP_SERVICES2_PPI *CpuMp2Ppi;
259 CPU_FEATURES_DATA *CpuFeaturesData;
260
261 CpuFeaturesData = GetCpuFeaturesData ();
262 CpuMp2Ppi = CpuFeaturesData->MpService.Ppi;
263
264 //
265 // Get the number of CPUs
266 //
267 Status = CpuMp2Ppi->GetNumberOfProcessors (
268 CpuMp2Ppi,
269 NumberOfCpus,
270 NumberOfEnabledProcessors
271 );
272 ASSERT_EFI_ERROR (Status);
273 }
274
275 /**
276 Performs CPU features Initialization.
277
278 This service will invoke MP service to perform CPU features
279 initialization on BSP/APs per user configuration.
280
281 @note This service could be called by BSP only.
282 **/
283 VOID
284 EFIAPI
285 CpuFeaturesInitialize (
286 VOID
287 )
288 {
289 CPU_FEATURES_DATA *CpuFeaturesData;
290 UINTN OldBspNumber;
291
292 CpuFeaturesData = GetCpuFeaturesData ();
293
294 OldBspNumber = GetProcessorIndex (CpuFeaturesData);
295 CpuFeaturesData->BspNumber = OldBspNumber;
296
297 //
298 // Start to program register for all CPUs.
299 //
300 StartupAllCPUsWorker (SetProcessorRegister);
301
302 //
303 // Switch to new BSP if required
304 //
305 if (CpuFeaturesData->BspNumber != OldBspNumber) {
306 SwitchNewBsp (CpuFeaturesData->BspNumber);
307 }
308 }