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