]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/Library/RegisterCpuFeaturesLib/PeiRegisterCpuFeaturesLib.c
UefiCpuPkg/RegisterCpuFeaturesLib: Replace AcquireSpinLock.
[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 MP_SERVICES variable.
72 **/
73 MP_SERVICES
74 GetMpService (
75 VOID
76 )
77 {
78 EFI_STATUS Status;
79 MP_SERVICES MpService;
80
81 //
82 // Get MP Services Protocol
83 //
84 Status = PeiServicesLocatePpi (
85 &gEfiPeiMpServicesPpiGuid,
86 0,
87 NULL,
88 (VOID **)&MpService.Ppi
89 );
90 ASSERT_EFI_ERROR (Status);
91 return MpService;
92 }
93
94 /**
95 Worker function to return processor index.
96
97 @param CpuFeaturesData Cpu Feature Data structure.
98
99 @return The processor index.
100 **/
101 UINTN
102 GetProcessorIndex (
103 IN CPU_FEATURES_DATA *CpuFeaturesData
104 )
105 {
106 EFI_STATUS Status;
107 EFI_PEI_MP_SERVICES_PPI *CpuMpPpi;
108 UINTN ProcessorIndex;
109
110 CpuMpPpi = CpuFeaturesData->MpService.Ppi;
111
112 //
113 // For two reasons which use NULL for WhoAmI:
114 // 1. This function will be called by APs and AP should not use PeiServices Table
115 // 2. Check WhoAmI implementation, this parameter will not be used.
116 //
117 Status = CpuMpPpi->WhoAmI(NULL, CpuMpPpi, &ProcessorIndex);
118 ASSERT_EFI_ERROR (Status);
119 return ProcessorIndex;
120 }
121
122 /**
123 Worker function to MP-related information on the requested processor at the
124 instant this call is made.
125
126 @param[in] ProcessorNumber The handle number of processor.
127 @param[out] ProcessorInfoBuffer A pointer to the buffer where information for
128 the requested processor is deposited.
129
130 @return Status of MpServices->GetProcessorInfo().
131 **/
132 EFI_STATUS
133 GetProcessorInformation (
134 IN UINTN ProcessorNumber,
135 OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
136 )
137 {
138 EFI_PEI_MP_SERVICES_PPI *CpuMpPpi;
139 EFI_STATUS Status;
140 CPU_FEATURES_DATA *CpuFeaturesData;
141
142 CpuFeaturesData = GetCpuFeaturesData ();
143 CpuMpPpi = CpuFeaturesData->MpService.Ppi;
144
145 Status = CpuMpPpi->GetProcessorInfo (
146 GetPeiServicesTablePointer(),
147 CpuMpPpi,
148 ProcessorNumber,
149 ProcessorInfoBuffer
150 );
151 return Status;
152 }
153
154 /**
155 Worker function to execute a caller provided function on all enabled APs.
156
157 @param[in] Procedure A pointer to the function to be run on
158 enabled APs of the system.
159 @param[in] MpEvent The Event used to sync the result.
160
161 **/
162 VOID
163 StartupAPsWorker (
164 IN EFI_AP_PROCEDURE Procedure,
165 IN EFI_EVENT MpEvent
166 )
167 {
168 EFI_STATUS Status;
169 EFI_PEI_MP_SERVICES_PPI *CpuMpPpi;
170 CPU_FEATURES_DATA *CpuFeaturesData;
171
172 CpuFeaturesData = GetCpuFeaturesData ();
173 CpuMpPpi = CpuFeaturesData->MpService.Ppi;
174
175 //
176 // Wakeup all APs for data collection.
177 //
178 Status = CpuMpPpi->StartupAllAPs (
179 GetPeiServicesTablePointer (),
180 CpuMpPpi,
181 Procedure,
182 FALSE,
183 0,
184 CpuFeaturesData
185 );
186 ASSERT_EFI_ERROR (Status);
187 }
188
189 /**
190 Worker function to switch the requested AP to be the BSP from that point onward.
191
192 @param[in] ProcessorNumber The handle number of AP that is to become the new BSP.
193 **/
194 VOID
195 SwitchNewBsp (
196 IN UINTN ProcessorNumber
197 )
198 {
199 EFI_STATUS Status;
200 EFI_PEI_MP_SERVICES_PPI *CpuMpPpi;
201 CPU_FEATURES_DATA *CpuFeaturesData;
202
203 CpuFeaturesData = GetCpuFeaturesData ();
204 CpuMpPpi = CpuFeaturesData->MpService.Ppi;
205
206 //
207 // Wakeup all APs for data collection.
208 //
209 Status = CpuMpPpi->SwitchBSP (
210 GetPeiServicesTablePointer (),
211 CpuMpPpi,
212 ProcessorNumber,
213 TRUE
214 );
215 ASSERT_EFI_ERROR (Status);
216 }
217
218 /**
219 Worker function to retrieve the number of logical processor in the platform.
220
221 @param[out] NumberOfCpus Pointer to the total number of logical
222 processors in the system, including the BSP
223 and disabled APs.
224 @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical
225 processors that exist in system, including
226 the BSP.
227 **/
228 VOID
229 GetNumberOfProcessor (
230 OUT UINTN *NumberOfCpus,
231 OUT UINTN *NumberOfEnabledProcessors
232 )
233 {
234 EFI_STATUS Status;
235 EFI_PEI_MP_SERVICES_PPI *CpuMpPpi;
236 CPU_FEATURES_DATA *CpuFeaturesData;
237
238 CpuFeaturesData = GetCpuFeaturesData ();
239 CpuMpPpi = CpuFeaturesData->MpService.Ppi;
240
241 //
242 // Get the number of CPUs
243 //
244 Status = CpuMpPpi->GetNumberOfProcessors (
245 GetPeiServicesTablePointer (),
246 CpuMpPpi,
247 NumberOfCpus,
248 NumberOfEnabledProcessors
249 );
250 ASSERT_EFI_ERROR (Status);
251 }
252
253 /**
254 Performs CPU features Initialization.
255
256 This service will invoke MP service to perform CPU features
257 initialization on BSP/APs per user configuration.
258
259 @note This service could be called by BSP only.
260 **/
261 VOID
262 EFIAPI
263 CpuFeaturesInitialize (
264 VOID
265 )
266 {
267 CPU_FEATURES_DATA *CpuFeaturesData;
268 UINTN OldBspNumber;
269
270 CpuFeaturesData = GetCpuFeaturesData ();
271
272 OldBspNumber = GetProcessorIndex (CpuFeaturesData);
273 CpuFeaturesData->BspNumber = OldBspNumber;
274
275 //
276 // Known limitation: In PEI phase, CpuFeatures driver not
277 // support async mode execute tasks. So semaphore type
278 // register can't been used for this instance, must use
279 // DXE type instance.
280 //
281
282 //
283 // Wakeup all APs for programming.
284 //
285 StartupAPsWorker (SetProcessorRegister, NULL);
286 //
287 // Programming BSP
288 //
289 SetProcessorRegister (CpuFeaturesData);
290
291 //
292 // Switch to new BSP if required
293 //
294 if (CpuFeaturesData->BspNumber != OldBspNumber) {
295 SwitchNewBsp (CpuFeaturesData->BspNumber);
296 }
297 }
298