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