]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c
IntelFsp2WrapperPkg: Support 64bit FspResetType for X64 build.
[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 - 2021, 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 (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 (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 (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 Get the FSP S UPD Data address
186
187 @return FSP-S UPD Data Address
188 **/
189 UINTN
190 GetFspsUpdDataAddress (
191 VOID
192 )
193 {
194 if (PcdGet64 (PcdFspsUpdDataAddress64) != 0) {
195 return (UINTN)PcdGet64 (PcdFspsUpdDataAddress64);
196 } else {
197 return (UINTN)PcdGet32 (PcdFspsUpdDataAddress);
198 }
199 }
200
201 /**
202 This function is for FSP dispatch mode to perform post FSP-S process.
203
204 @param[in] PeiServices Pointer to PEI Services Table.
205 @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
206 caused this function to execute.
207 @param[in] Ppi Pointer to the PPI data associated with this function.
208
209 @retval EFI_STATUS Status returned by PeiServicesInstallPpi ()
210 **/
211 EFI_STATUS
212 EFIAPI
213 FspsWrapperEndOfPeiNotify (
214 IN EFI_PEI_SERVICES **PeiServices,
215 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
216 IN VOID *Ppi
217 )
218 {
219 EFI_STATUS Status;
220
221 //
222 // This step may include platform specific process in some boot loaders so
223 // aligning the same behavior between API and Dispatch modes.
224 // Note: In Dispatch mode no FspHobList so passing NULL to function and
225 // expecting function will handle it.
226 //
227 PostFspsHobProcess (NULL);
228
229 //
230 // Install FspSiliconInitDonePpi so that any other driver can consume this info.
231 //
232 Status = PeiServicesInstallPpi (&mPeiFspSiliconInitDonePpi);
233 ASSERT_EFI_ERROR (Status);
234
235 return Status;
236 }
237
238 EFI_PEI_NOTIFY_DESCRIPTOR mFspsWrapperEndOfPeiNotifyDesc = {
239 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
240 &gEfiEndOfPeiSignalPpiGuid,
241 FspsWrapperEndOfPeiNotify
242 };
243
244 /**
245 This function is called after PEI core discover memory and finish migration.
246
247 @param[in] PeiServices Pointer to PEI Services Table.
248 @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
249 caused this function to execute.
250 @param[in] Ppi Pointer to the PPI data associated with this function.
251
252 @retval EFI_STATUS Always return EFI_SUCCESS
253 **/
254 EFI_STATUS
255 EFIAPI
256 PeiMemoryDiscoveredNotify (
257 IN EFI_PEI_SERVICES **PeiServices,
258 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
259 IN VOID *Ppi
260 );
261
262 EFI_PEI_NOTIFY_DESCRIPTOR mPeiMemoryDiscoveredNotifyDesc = {
263 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
264 &gEfiPeiMemoryDiscoveredPpiGuid,
265 PeiMemoryDiscoveredNotify
266 };
267
268 /**
269 This function is called after PEI core discover memory and finish migration.
270
271 @param[in] PeiServices Pointer to PEI Services Table.
272 @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
273 caused this function to execute.
274 @param[in] Ppi Pointer to the PPI data associated with this function.
275
276 @retval EFI_STATUS Always return EFI_SUCCESS
277 **/
278 EFI_STATUS
279 EFIAPI
280 PeiMemoryDiscoveredNotify (
281 IN EFI_PEI_SERVICES **PeiServices,
282 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
283 IN VOID *Ppi
284 )
285 {
286 FSP_INFO_HEADER *FspsHeaderPtr;
287 UINT64 TimeStampCounterStart;
288 EFI_STATUS Status;
289 VOID *FspHobListPtr;
290 EFI_HOB_GUID_TYPE *GuidHob;
291 FSPS_UPD_COMMON *FspsUpdDataPtr;
292 UINTN *SourceData;
293
294 DEBUG ((DEBUG_INFO, "PeiMemoryDiscoveredNotify enter\n"));
295 FspsUpdDataPtr = NULL;
296
297 FspsHeaderPtr = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress));
298 DEBUG ((DEBUG_INFO, "FspsHeaderPtr - 0x%x\n", FspsHeaderPtr));
299 if (FspsHeaderPtr == NULL) {
300 return EFI_DEVICE_ERROR;
301 }
302
303 if ((GetFspsUpdDataAddress () == 0) && (FspsHeaderPtr->CfgRegionSize != 0) && (FspsHeaderPtr->CfgRegionOffset != 0)) {
304 //
305 // Copy default FSP-S UPD data from Flash
306 //
307 FspsUpdDataPtr = (FSPS_UPD_COMMON *)AllocateZeroPool ((UINTN)FspsHeaderPtr->CfgRegionSize);
308 ASSERT (FspsUpdDataPtr != NULL);
309 SourceData = (UINTN *)((UINTN)FspsHeaderPtr->ImageBase + (UINTN)FspsHeaderPtr->CfgRegionOffset);
310 CopyMem (FspsUpdDataPtr, SourceData, (UINTN)FspsHeaderPtr->CfgRegionSize);
311 } else {
312 FspsUpdDataPtr = (FSPS_UPD_COMMON *)GetFspsUpdDataAddress ();
313 ASSERT (FspsUpdDataPtr != NULL);
314 }
315
316 UpdateFspsUpdData ((VOID *)FspsUpdDataPtr);
317
318 TimeStampCounterStart = AsmReadTsc ();
319 PERF_START_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
320 Status = CallFspSiliconInit ((VOID *)FspsUpdDataPtr);
321 PERF_END_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
322 DEBUG ((DEBUG_INFO, "Total time spent executing FspSiliconInitApi: %d millisecond\n", DivU64x32 (GetTimeInNanoSecond (AsmReadTsc () - TimeStampCounterStart), 1000000)));
323
324 //
325 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
326 //
327 if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {
328 DEBUG ((DEBUG_INFO, "FspSiliconInitApi requested reset 0x%x\n", Status));
329 CallFspWrapperResetSystem (Status);
330 }
331
332 if (EFI_ERROR (Status)) {
333 DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspSiliconInitApi(), Status = %r\n", Status));
334 }
335
336 DEBUG ((DEBUG_INFO, "FspSiliconInit status: 0x%x\n", Status));
337 ASSERT_EFI_ERROR (Status);
338
339 Status = TestFspSiliconInitApiOutput ((VOID *)NULL);
340 if (RETURN_ERROR (Status)) {
341 DEBUG ((DEBUG_ERROR, "ERROR - TestFspSiliconInitApiOutput () fail, Status = %r\n", Status));
342 }
343
344 //
345 // Now FspHobList complete, process it
346 //
347 GuidHob = GetFirstGuidHob (&gFspHobGuid);
348 ASSERT (GuidHob != NULL);
349 FspHobListPtr = *(VOID **)GET_GUID_HOB_DATA (GuidHob);
350 DEBUG ((DEBUG_INFO, "FspHobListPtr - 0x%x\n", FspHobListPtr));
351 PostFspsHobProcess (FspHobListPtr);
352
353 //
354 // Install FspSiliconInitDonePpi so that any other driver can consume this info.
355 //
356 Status = PeiServicesInstallPpi (&mPeiFspSiliconInitDonePpi);
357 ASSERT_EFI_ERROR (Status);
358
359 return Status;
360 }
361
362 /**
363 Do FSP initialization in API mode.
364
365 @retval EFI_STATUS Always return EFI_SUCCESS
366 **/
367 EFI_STATUS
368 FspsWrapperInitApiMode (
369 VOID
370 )
371 {
372 EFI_STATUS Status;
373 EFI_BOOT_MODE BootMode;
374
375 //
376 // Register MemoryDiscovered Notify to run FspSiliconInit
377 //
378 Status = PeiServicesNotifyPpi (&mPeiMemoryDiscoveredNotifyDesc);
379 ASSERT_EFI_ERROR (Status);
380
381 //
382 // Register EndOfPei Notify for S3 to run FSP NotifyPhase
383 //
384 PeiServicesGetBootMode (&BootMode);
385 if (BootMode == BOOT_ON_S3_RESUME) {
386 Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc);
387 ASSERT_EFI_ERROR (Status);
388 }
389
390 return EFI_SUCCESS;
391 }
392
393 /**
394 Do FSP initialization in Dispatch mode.
395
396 @retval FSP initialization status.
397 **/
398 EFI_STATUS
399 FspsWrapperInitDispatchMode (
400 VOID
401 )
402 {
403 EFI_STATUS Status;
404 EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *MeasurementExcludedFvPpi;
405 EFI_PEI_PPI_DESCRIPTOR *MeasurementExcludedPpiList;
406
407 MeasurementExcludedFvPpi = AllocatePool (sizeof (*MeasurementExcludedFvPpi));
408 ASSERT (MeasurementExcludedFvPpi != NULL);
409 MeasurementExcludedFvPpi->Count = 1;
410 MeasurementExcludedFvPpi->Fv[0].FvBase = PcdGet32 (PcdFspsBaseAddress);
411 MeasurementExcludedFvPpi->Fv[0].FvLength = ((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdFspsBaseAddress))->FvLength;
412
413 MeasurementExcludedPpiList = AllocatePool (sizeof (*MeasurementExcludedPpiList));
414 ASSERT (MeasurementExcludedPpiList != NULL);
415 MeasurementExcludedPpiList->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
416 MeasurementExcludedPpiList->Guid = &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid;
417 MeasurementExcludedPpiList->Ppi = MeasurementExcludedFvPpi;
418
419 Status = PeiServicesInstallPpi (MeasurementExcludedPpiList);
420 ASSERT_EFI_ERROR (Status);
421
422 //
423 // FSP-S Wrapper running in Dispatch mode and reports FSP-S FV to PEI dispatcher.
424 //
425 PeiServicesInstallFvInfoPpi (
426 NULL,
427 (VOID *)(UINTN)PcdGet32 (PcdFspsBaseAddress),
428 (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdFspsBaseAddress))->FvLength,
429 NULL,
430 NULL
431 );
432 //
433 // Register EndOfPei Nofity to run post FSP-S process.
434 //
435 Status = PeiServicesNotifyPpi (&mFspsWrapperEndOfPeiNotifyDesc);
436 ASSERT_EFI_ERROR (Status);
437 return Status;
438 }
439
440 /**
441 This function is called after TCG installed PPI.
442
443 @param[in] PeiServices Pointer to PEI Services Table.
444 @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
445 caused this function to execute.
446 @param[in] Ppi Pointer to the PPI data associated with this function.
447
448 @retval EFI_STATUS Always return EFI_SUCCESS
449 **/
450 EFI_STATUS
451 EFIAPI
452 TcgPpiNotify (
453 IN EFI_PEI_SERVICES **PeiServices,
454 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
455 IN VOID *Ppi
456 );
457
458 EFI_PEI_NOTIFY_DESCRIPTOR mTcgPpiNotifyDesc = {
459 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
460 &gEdkiiTcgPpiGuid,
461 TcgPpiNotify
462 };
463
464 /**
465 This function is called after TCG installed PPI.
466
467 @param[in] PeiServices Pointer to PEI Services Table.
468 @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
469 caused this function to execute.
470 @param[in] Ppi Pointer to the PPI data associated with this function.
471
472 @retval EFI_STATUS Always return EFI_SUCCESS
473 **/
474 EFI_STATUS
475 EFIAPI
476 TcgPpiNotify (
477 IN EFI_PEI_SERVICES **PeiServices,
478 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
479 IN VOID *Ppi
480 )
481 {
482 UINT32 FspMeasureMask;
483
484 DEBUG ((DEBUG_INFO, "TcgPpiNotify FSPS\n"));
485
486 FspMeasureMask = PcdGet32 (PcdFspMeasurementConfig);
487
488 if ((FspMeasureMask & FSP_MEASURE_FSPS) != 0) {
489 MeasureFspFirmwareBlob (
490 0,
491 "FSPS",
492 PcdGet32 (PcdFspsBaseAddress),
493 (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdFspsBaseAddress))->FvLength
494 );
495 }
496
497 return EFI_SUCCESS;
498 }
499
500 /**
501 This is the entrypoint of PEIM.
502
503 @param[in] FileHandle Handle of the file being invoked.
504 @param[in] PeiServices Describes the list of possible PEI Services.
505
506 @retval EFI_SUCCESS if it completed successfully.
507 **/
508 EFI_STATUS
509 EFIAPI
510 FspsWrapperPeimEntryPoint (
511 IN EFI_PEI_FILE_HANDLE FileHandle,
512 IN CONST EFI_PEI_SERVICES **PeiServices
513 )
514 {
515 EFI_STATUS Status;
516
517 DEBUG ((DEBUG_INFO, "FspsWrapperPeimEntryPoint\n"));
518
519 Status = PeiServicesNotifyPpi (&mTcgPpiNotifyDesc);
520 ASSERT_EFI_ERROR (Status);
521
522 if (PcdGet8 (PcdFspModeSelection) == 1) {
523 FspsWrapperInitApiMode ();
524 } else {
525 FspsWrapperInitDispatchMode ();
526 }
527
528 return EFI_SUCCESS;
529 }