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