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