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