]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c
IntelFsp2WrapperPkg: remove gPeiTpmInitializationDonePpiGuid from Depex
[mirror_edk2.git] / IntelFsp2WrapperPkg / FspsWrapperPeim / FspsWrapperPeim.c
1 /** @file
2 This will be invoked only once. It will call FspMemoryInit API,
3 register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi
4 notify to call FspSiliconInit API.
5
6 Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9 **/
10
11 #include <PiPei.h>
12
13 #include <Library/PeimEntryPoint.h>
14 #include <Library/PeiServicesLib.h>
15 #include <Library/PeiServicesTablePointerLib.h>
16 #include <Library/BaseLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/HobLib.h>
20 #include <Library/PcdLib.h>
21 #include <Library/MemoryAllocationLib.h>
22 #include <Library/FspWrapperPlatformLib.h>
23 #include <Library/FspWrapperHobProcessLib.h>
24 #include <Library/TimerLib.h>
25 #include <Library/PerformanceLib.h>
26 #include <Library/FspWrapperApiLib.h>
27 #include <Library/FspMeasurementLib.h>
28
29 #include <Ppi/FspSiliconInitDone.h>
30 #include <Ppi/EndOfPeiPhase.h>
31 #include <Ppi/MemoryDiscovered.h>
32 #include <Ppi/TemporaryRamDone.h>
33 #include <Ppi/SecPlatformInformation.h>
34 #include <Ppi/Tcg.h>
35 #include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>
36 #include <Library/FspWrapperApiTestLib.h>
37 #include <FspEas.h>
38 #include <FspStatusCode.h>
39
40 extern EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc;
41 extern EFI_GUID gFspHobGuid;
42
43 /**
44 This function handles S3 resume task at the end of PEI.
45
46 @param[in] PeiServices Pointer to PEI Services Table.
47 @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
48 caused this function to execute.
49 @param[in] Ppi Pointer to the PPI data associated with this function.
50
51 @retval EFI_STATUS Always return EFI_SUCCESS
52 **/
53 EFI_STATUS
54 EFIAPI
55 S3EndOfPeiNotify(
56 IN EFI_PEI_SERVICES **PeiServices,
57 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
58 IN VOID *Ppi
59 );
60
61 EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc = {
62 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
63 &gEfiEndOfPeiSignalPpiGuid,
64 S3EndOfPeiNotify
65 };
66
67 /**
68 This function handles S3 resume task at the end of PEI.
69
70 @param[in] PeiServices Pointer to PEI Services Table.
71 @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
72 caused this function to execute.
73 @param[in] Ppi Pointer to the PPI data associated with this function.
74
75 @retval EFI_STATUS Always return EFI_SUCCESS
76 **/
77 EFI_STATUS
78 EFIAPI
79 S3EndOfPeiNotify(
80 IN EFI_PEI_SERVICES **PeiServices,
81 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
82 IN VOID *Ppi
83 )
84 {
85 NOTIFY_PHASE_PARAMS NotifyPhaseParams;
86 EFI_STATUS Status;
87
88 DEBUG((DEBUG_INFO, "S3EndOfPeiNotify enter\n"));
89
90 NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration;
91 Status = CallFspNotifyPhase (&NotifyPhaseParams);
92 DEBUG((DEBUG_INFO, "FSP S3NotifyPhase AfterPciEnumeration status: 0x%x\n", Status));
93
94 //
95 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
96 //
97 if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {
98 DEBUG((DEBUG_INFO, "FSP S3NotifyPhase AfterPciEnumeration requested reset 0x%x\n", Status));
99 CallFspWrapperResetSystem ((UINT32)Status);
100 }
101
102 NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot;
103 Status = CallFspNotifyPhase (&NotifyPhaseParams);
104 DEBUG((DEBUG_INFO, "FSP S3NotifyPhase ReadyToBoot status: 0x%x\n", Status));
105
106 //
107 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
108 //
109 if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {
110 DEBUG((DEBUG_INFO, "FSP S3NotifyPhase ReadyToBoot requested reset 0x%x\n", Status));
111 CallFspWrapperResetSystem ((UINT32)Status);
112 }
113
114 NotifyPhaseParams.Phase = EnumInitPhaseEndOfFirmware;
115 Status = CallFspNotifyPhase (&NotifyPhaseParams);
116 DEBUG((DEBUG_INFO, "FSP S3NotifyPhase EndOfFirmware status: 0x%x\n", Status));
117
118 //
119 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
120 //
121 if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {
122 DEBUG((DEBUG_INFO, "FSP S3NotifyPhase EndOfFirmware requested reset 0x%x\n", Status));
123 CallFspWrapperResetSystem ((UINT32)Status);
124 }
125
126 return EFI_SUCCESS;
127 }
128
129 /**
130 Return Hob list produced by FSP.
131
132 @param[in] PeiServices The pointer to the PEI Services Table.
133 @param[in] This The pointer to this instance of this PPI.
134 @param[out] FspHobList The pointer to Hob list produced by FSP.
135
136 @return EFI_SUCCESS Return Hob list produced by FSP successfully.
137 **/
138 EFI_STATUS
139 EFIAPI
140 FspSiliconInitDoneGetFspHobList (
141 IN CONST EFI_PEI_SERVICES **PeiServices,
142 IN FSP_SILICON_INIT_DONE_PPI *This,
143 OUT VOID **FspHobList
144 );
145
146 FSP_SILICON_INIT_DONE_PPI mFspSiliconInitDonePpi = {
147 FspSiliconInitDoneGetFspHobList
148 };
149
150 EFI_PEI_PPI_DESCRIPTOR mPeiFspSiliconInitDonePpi = {
151 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
152 &gFspSiliconInitDonePpiGuid,
153 &mFspSiliconInitDonePpi
154 };
155
156 /**
157 Return Hob list produced by FSP.
158
159 @param[in] PeiServices The pointer to the PEI Services Table.
160 @param[in] This The pointer to this instance of this PPI.
161 @param[out] FspHobList The pointer to Hob list produced by FSP.
162
163 @return EFI_SUCCESS Return Hob list produced by FSP successfully.
164 **/
165 EFI_STATUS
166 EFIAPI
167 FspSiliconInitDoneGetFspHobList (
168 IN CONST EFI_PEI_SERVICES **PeiServices,
169 IN FSP_SILICON_INIT_DONE_PPI *This,
170 OUT VOID **FspHobList
171 )
172 {
173 EFI_HOB_GUID_TYPE *GuidHob;
174
175 GuidHob = GetFirstGuidHob (&gFspHobGuid);
176 if (GuidHob != NULL) {
177 *FspHobList = *(VOID **)GET_GUID_HOB_DATA(GuidHob);
178 return EFI_SUCCESS;
179 } else {
180 return EFI_NOT_FOUND;
181 }
182 }
183
184 /**
185 This function is for FSP dispatch mode to perform post FSP-S process.
186
187 @param[in] PeiServices Pointer to PEI Services Table.
188 @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
189 caused this function to execute.
190 @param[in] Ppi Pointer to the PPI data associated with this function.
191
192 @retval EFI_STATUS Status returned by PeiServicesInstallPpi ()
193 **/
194 EFI_STATUS
195 EFIAPI
196 FspsWrapperEndOfPeiNotify (
197 IN EFI_PEI_SERVICES **PeiServices,
198 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
199 IN VOID *Ppi
200 )
201 {
202 EFI_STATUS Status;
203
204 //
205 // This step may include platform specific process in some boot loaders so
206 // aligning the same behavior between API and Dispatch modes.
207 // Note: In Dispatch mode no FspHobList so passing NULL to function and
208 // expecting function will handle it.
209 //
210 PostFspsHobProcess (NULL);
211
212 //
213 // Install FspSiliconInitDonePpi so that any other driver can consume this info.
214 //
215 Status = PeiServicesInstallPpi (&mPeiFspSiliconInitDonePpi);
216 ASSERT_EFI_ERROR(Status);
217
218 return Status;
219 }
220
221 EFI_PEI_NOTIFY_DESCRIPTOR mFspsWrapperEndOfPeiNotifyDesc = {
222 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
223 &gEfiEndOfPeiSignalPpiGuid,
224 FspsWrapperEndOfPeiNotify
225 };
226
227 /**
228 This function is called after PEI core discover memory and finish migration.
229
230 @param[in] PeiServices Pointer to PEI Services Table.
231 @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
232 caused this function to execute.
233 @param[in] Ppi Pointer to the PPI data associated with this function.
234
235 @retval EFI_STATUS Always return EFI_SUCCESS
236 **/
237 EFI_STATUS
238 EFIAPI
239 PeiMemoryDiscoveredNotify (
240 IN EFI_PEI_SERVICES **PeiServices,
241 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
242 IN VOID *Ppi
243 );
244
245 EFI_PEI_NOTIFY_DESCRIPTOR mPeiMemoryDiscoveredNotifyDesc = {
246 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
247 &gEfiPeiMemoryDiscoveredPpiGuid,
248 PeiMemoryDiscoveredNotify
249 };
250
251 /**
252 This function is called after PEI core discover memory and finish migration.
253
254 @param[in] PeiServices Pointer to PEI Services Table.
255 @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
256 caused this function to execute.
257 @param[in] Ppi Pointer to the PPI data associated with this function.
258
259 @retval EFI_STATUS Always return EFI_SUCCESS
260 **/
261 EFI_STATUS
262 EFIAPI
263 PeiMemoryDiscoveredNotify (
264 IN EFI_PEI_SERVICES **PeiServices,
265 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
266 IN VOID *Ppi
267 )
268 {
269 FSP_INFO_HEADER *FspsHeaderPtr;
270 UINT64 TimeStampCounterStart;
271 EFI_STATUS Status;
272 VOID *FspHobListPtr;
273 EFI_HOB_GUID_TYPE *GuidHob;
274 FSPS_UPD_COMMON *FspsUpdDataPtr;
275 UINTN *SourceData;
276
277 DEBUG ((DEBUG_INFO, "PeiMemoryDiscoveredNotify enter\n"));
278 FspsUpdDataPtr = NULL;
279
280 FspsHeaderPtr = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress));
281 DEBUG ((DEBUG_INFO, "FspsHeaderPtr - 0x%x\n", FspsHeaderPtr));
282 if (FspsHeaderPtr == NULL) {
283 return EFI_DEVICE_ERROR;
284 }
285
286 if (PcdGet32 (PcdFspsUpdDataAddress) == 0 && (FspsHeaderPtr->CfgRegionSize != 0) && (FspsHeaderPtr->CfgRegionOffset != 0)) {
287 //
288 // Copy default FSP-S UPD data from Flash
289 //
290 FspsUpdDataPtr = (FSPS_UPD_COMMON *)AllocateZeroPool ((UINTN)FspsHeaderPtr->CfgRegionSize);
291 ASSERT (FspsUpdDataPtr != NULL);
292 SourceData = (UINTN *)((UINTN)FspsHeaderPtr->ImageBase + (UINTN)FspsHeaderPtr->CfgRegionOffset);
293 CopyMem (FspsUpdDataPtr, SourceData, (UINTN)FspsHeaderPtr->CfgRegionSize);
294 } else {
295 FspsUpdDataPtr = (FSPS_UPD_COMMON *)PcdGet32 (PcdFspsUpdDataAddress);
296 ASSERT (FspsUpdDataPtr != NULL);
297 }
298
299 UpdateFspsUpdData ((VOID *)FspsUpdDataPtr);
300
301 TimeStampCounterStart = AsmReadTsc ();
302 PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
303 Status = CallFspSiliconInit ((VOID *)FspsUpdDataPtr);
304 PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
305 DEBUG ((DEBUG_INFO, "Total time spent executing FspSiliconInitApi: %d millisecond\n", DivU64x32 (GetTimeInNanoSecond (AsmReadTsc () - TimeStampCounterStart), 1000000)));
306
307 //
308 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
309 //
310 if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {
311 DEBUG((DEBUG_INFO, "FspSiliconInitApi requested reset 0x%x\n", Status));
312 CallFspWrapperResetSystem ((UINT32)Status);
313 }
314
315 if (EFI_ERROR(Status)) {
316 DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspSiliconInitApi(), Status = %r\n", Status));
317 }
318 DEBUG((DEBUG_INFO, "FspSiliconInit status: 0x%x\n", Status));
319 ASSERT_EFI_ERROR (Status);
320
321 Status = TestFspSiliconInitApiOutput ((VOID *)NULL);
322 if (RETURN_ERROR (Status)) {
323 DEBUG ((DEBUG_ERROR, "ERROR - TestFspSiliconInitApiOutput () fail, Status = %r\n", Status));
324 }
325
326 //
327 // Now FspHobList complete, process it
328 //
329 GuidHob = GetFirstGuidHob (&gFspHobGuid);
330 ASSERT (GuidHob != NULL);
331 FspHobListPtr = *(VOID **)GET_GUID_HOB_DATA (GuidHob);
332 DEBUG ((DEBUG_INFO, "FspHobListPtr - 0x%x\n", FspHobListPtr));
333 PostFspsHobProcess (FspHobListPtr);
334
335 //
336 // Install FspSiliconInitDonePpi so that any other driver can consume this info.
337 //
338 Status = PeiServicesInstallPpi (&mPeiFspSiliconInitDonePpi);
339 ASSERT_EFI_ERROR(Status);
340
341 return Status;
342 }
343
344 /**
345 Do FSP initialization in API mode.
346
347 @retval EFI_STATUS Always return EFI_SUCCESS
348 **/
349 EFI_STATUS
350 FspsWrapperInitApiMode (
351 VOID
352 )
353 {
354 EFI_STATUS Status;
355 EFI_BOOT_MODE BootMode;
356
357 //
358 // Register MemoryDiscovered Notify to run FspSiliconInit
359 //
360 Status = PeiServicesNotifyPpi (&mPeiMemoryDiscoveredNotifyDesc);
361 ASSERT_EFI_ERROR (Status);
362
363 //
364 // Register EndOfPei Notify for S3 to run FSP NotifyPhase
365 //
366 PeiServicesGetBootMode (&BootMode);
367 if (BootMode == BOOT_ON_S3_RESUME) {
368 Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc);
369 ASSERT_EFI_ERROR (Status);
370 }
371
372 return EFI_SUCCESS;
373 }
374
375 /**
376 Do FSP initialization in Dispatch mode.
377
378 @retval FSP initialization status.
379 **/
380 EFI_STATUS
381 FspsWrapperInitDispatchMode (
382 VOID
383 )
384 {
385 EFI_STATUS Status;
386 EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *MeasurementExcludedFvPpi;
387 EFI_PEI_PPI_DESCRIPTOR *MeasurementExcludedPpiList;
388
389 MeasurementExcludedFvPpi = AllocatePool (sizeof(*MeasurementExcludedFvPpi));
390 ASSERT(MeasurementExcludedFvPpi != NULL);
391 MeasurementExcludedFvPpi->Count = 1;
392 MeasurementExcludedFvPpi->Fv[0].FvBase = PcdGet32 (PcdFspsBaseAddress);
393 MeasurementExcludedFvPpi->Fv[0].FvLength = ((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFspsBaseAddress))->FvLength;
394
395 MeasurementExcludedPpiList = AllocatePool (sizeof(*MeasurementExcludedPpiList));
396 ASSERT(MeasurementExcludedPpiList != NULL);
397 MeasurementExcludedPpiList->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
398 MeasurementExcludedPpiList->Guid = &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid;
399 MeasurementExcludedPpiList->Ppi = MeasurementExcludedFvPpi;
400
401 Status = PeiServicesInstallPpi (MeasurementExcludedPpiList);
402 ASSERT_EFI_ERROR (Status);
403
404 //
405 // FSP-S Wrapper running in Dispatch mode and reports FSP-S FV to PEI dispatcher.
406 //
407 PeiServicesInstallFvInfoPpi (
408 NULL,
409 (VOID *)(UINTN) PcdGet32 (PcdFspsBaseAddress),
410 (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFspsBaseAddress))->FvLength,
411 NULL,
412 NULL
413 );
414 //
415 // Register EndOfPei Nofity to run post FSP-S process.
416 //
417 Status = PeiServicesNotifyPpi (&mFspsWrapperEndOfPeiNotifyDesc);
418 ASSERT_EFI_ERROR (Status);
419 return Status;
420 }
421
422 /**
423 This function is called after TCG installed PPI.
424
425 @param[in] PeiServices Pointer to PEI Services Table.
426 @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
427 caused this function to execute.
428 @param[in] Ppi Pointer to the PPI data associated with this function.
429
430 @retval EFI_STATUS Always return EFI_SUCCESS
431 **/
432 EFI_STATUS
433 EFIAPI
434 TcgPpiNotify (
435 IN EFI_PEI_SERVICES **PeiServices,
436 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
437 IN VOID *Ppi
438 );
439
440 EFI_PEI_NOTIFY_DESCRIPTOR mTcgPpiNotifyDesc = {
441 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
442 &gEdkiiTcgPpiGuid,
443 TcgPpiNotify
444 };
445
446 /**
447 This function is called after TCG installed PPI.
448
449 @param[in] PeiServices Pointer to PEI Services Table.
450 @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
451 caused this function to execute.
452 @param[in] Ppi Pointer to the PPI data associated with this function.
453
454 @retval EFI_STATUS Always return EFI_SUCCESS
455 **/
456 EFI_STATUS
457 EFIAPI
458 TcgPpiNotify (
459 IN EFI_PEI_SERVICES **PeiServices,
460 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
461 IN VOID *Ppi
462 )
463 {
464 UINT32 FspMeasureMask;
465
466 DEBUG ((DEBUG_INFO, "TcgPpiNotify FSPS\n"));
467
468 FspMeasureMask = PcdGet32 (PcdFspMeasurementConfig);
469
470 if ((FspMeasureMask & FSP_MEASURE_FSPS) != 0) {
471 MeasureFspFirmwareBlob (0, "FSPS", PcdGet32(PcdFspsBaseAddress),
472 (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFspsBaseAddress))->FvLength);
473 }
474
475 return EFI_SUCCESS;
476 }
477
478 /**
479 This is the entrypoint of PEIM.
480
481 @param[in] FileHandle Handle of the file being invoked.
482 @param[in] PeiServices Describes the list of possible PEI Services.
483
484 @retval EFI_SUCCESS if it completed successfully.
485 **/
486 EFI_STATUS
487 EFIAPI
488 FspsWrapperPeimEntryPoint (
489 IN EFI_PEI_FILE_HANDLE FileHandle,
490 IN CONST EFI_PEI_SERVICES **PeiServices
491 )
492 {
493 EFI_STATUS Status;
494
495 DEBUG ((DEBUG_INFO, "FspsWrapperPeimEntryPoint\n"));
496
497 Status = PeiServicesNotifyPpi (&mTcgPpiNotifyDesc);
498 ASSERT_EFI_ERROR (Status);
499
500 if (PcdGet8 (PcdFspModeSelection) == 1) {
501 FspsWrapperInitApiMode ();
502 } else {
503 FspsWrapperInitDispatchMode ();
504 }
505
506 return EFI_SUCCESS;
507 }