TianoCore EDK2 master
Loading...
Searching...
No Matches
RecoveryModuleLoadPei.c
Go to the documentation of this file.
1
17//
18// The package level header files this module uses
19//
20#include <Uefi.h>
21#include <PiPei.h>
22//
23// The protocols, PPI and GUID definitions for this module
24//
25#include <Ppi/MasterBootMode.h>
27#include <Ppi/RecoveryModule.h>
31#include <Guid/FmpCapsule.h>
33
34//
35// The Library classes this module consumes
36//
37#include <Library/DebugLib.h>
40#include <Library/HobLib.h>
43#include <Library/PcdLib.h>
44
46
60EFIAPI
62 IN EFI_PEI_SERVICES **PeiServices,
64 );
65
66EFI_PEI_RECOVERY_MODULE_PPI mRecoveryPpi = {
68};
69
70EFI_PEI_PPI_DESCRIPTOR mRecoveryPpiList = {
71 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
72 &gEfiPeiRecoveryModulePpiGuid,
73 &mRecoveryPpi
74};
75
91 IN UINT8 *DataBuffer,
92 IN UINTN BufferSize,
93 IN OUT CONFIG_HEADER *ConfigHeader,
94 IN OUT RECOVERY_CONFIG_DATA **RecoveryArray
95 );
96
105BOOLEAN
108 )
109{
110 GUID *Guid;
111 UINTN Count;
112 UINTN Index;
113
114 Guid = PcdGetPtr (PcdSystemFmpCapsuleImageTypeIdGuid);
115 Count = PcdGetSize (PcdSystemFmpCapsuleImageTypeIdGuid) / sizeof (GUID);
116
117 for (Index = 0; Index < Count; Index++, Guid++) {
118 if (CompareGuid (&FmpImageHeader->UpdateImageTypeId, Guid)) {
119 return TRUE;
120 }
121 }
122
123 return FALSE;
124}
125
134BOOLEAN
136 IN EFI_GUID *CapsuleGuid
137 )
138{
139 if (CompareGuid (&gEfiFmpCapsuleGuid, CapsuleGuid)) {
140 return TRUE;
141 }
142
143 return FALSE;
144}
145
160BOOLEAN
162 IN EFI_CAPSULE_HEADER *CapsuleHeader
163 )
164{
167 UINT64 *ItemOffsetList;
168 UINT32 ItemNum;
169 UINTN Index;
170
171 FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);
172
173 if (FmpCapsuleHeader->EmbeddedDriverCount != 0) {
174 return FALSE;
175 }
176
177 if (FmpCapsuleHeader->PayloadItemCount == 0) {
178 return FALSE;
179 }
180
181 ItemNum = FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount;
182
183 ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);
184
185 for (Index = 0; Index < ItemNum; Index++) {
186 ImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);
187 if (!IsSystemFmpImage (ImageHeader)) {
188 return FALSE;
189 }
190 }
191
192 return TRUE;
193}
194
207BOOLEAN
209 IN EFI_CAPSULE_HEADER *CapsuleHeader,
210 IN UINT64 CapsuleSize
211 )
212{
213 if (CapsuleHeader->CapsuleImageSize != CapsuleSize) {
214 return FALSE;
215 }
216
217 if (CapsuleHeader->HeaderSize >= CapsuleHeader->CapsuleImageSize) {
218 return FALSE;
219 }
220
221 return TRUE;
222}
223
245 IN EFI_CAPSULE_HEADER *CapsuleHeader,
246 OUT BOOLEAN *IsSystemFmp OPTIONAL,
247 OUT UINT16 *EmbeddedDriverCount OPTIONAL
248 )
249{
251 UINT8 *EndOfCapsule;
253 UINT8 *EndOfPayload;
254 UINT64 *ItemOffsetList;
255 UINT32 ItemNum;
256 UINTN Index;
257 UINTN FmpCapsuleSize;
258 UINTN FmpCapsuleHeaderSize;
259 UINT64 FmpImageSize;
260 UINTN FmpImageHeaderSize;
261
262 if (CapsuleHeader->HeaderSize >= CapsuleHeader->CapsuleImageSize) {
263 DEBUG ((DEBUG_ERROR, "HeaderSize(0x%x) >= CapsuleImageSize(0x%x)\n", CapsuleHeader->HeaderSize, CapsuleHeader->CapsuleImageSize));
264 return EFI_INVALID_PARAMETER;
265 }
266
267 FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);
268 EndOfCapsule = (UINT8 *)CapsuleHeader + CapsuleHeader->CapsuleImageSize;
269 FmpCapsuleSize = (UINTN)EndOfCapsule - (UINTN)FmpCapsuleHeader;
270
271 if (FmpCapsuleSize < sizeof (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER)) {
272 DEBUG ((DEBUG_ERROR, "FmpCapsuleSize(0x%x) < EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER\n", FmpCapsuleSize));
273 return EFI_INVALID_PARAMETER;
274 }
275
276 // Check EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER
277 if (FmpCapsuleHeader->Version != EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION) {
278 DEBUG ((DEBUG_ERROR, "FmpCapsuleHeader->Version(0x%x) != EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION\n", FmpCapsuleHeader->Version));
279 return EFI_INVALID_PARAMETER;
280 }
281
282 ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);
283
284 // No overflow
285 ItemNum = FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount;
286
287 if ((FmpCapsuleSize - sizeof (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER))/sizeof (UINT64) < ItemNum) {
288 DEBUG ((DEBUG_ERROR, "ItemNum(0x%x) too big\n", ItemNum));
289 return EFI_INVALID_PARAMETER;
290 }
291
292 FmpCapsuleHeaderSize = sizeof (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER) + sizeof (UINT64)*ItemNum;
293
294 // Check ItemOffsetList
295 for (Index = 0; Index < ItemNum; Index++) {
296 if (ItemOffsetList[Index] >= FmpCapsuleSize) {
297 DEBUG ((DEBUG_ERROR, "ItemOffsetList[%d](0x%lx) >= FmpCapsuleSize(0x%x)\n", Index, ItemOffsetList[Index], FmpCapsuleSize));
298 return EFI_INVALID_PARAMETER;
299 }
300
301 if (ItemOffsetList[Index] < FmpCapsuleHeaderSize) {
302 DEBUG ((DEBUG_ERROR, "ItemOffsetList[%d](0x%lx) < FmpCapsuleHeaderSize(0x%x)\n", Index, ItemOffsetList[Index], FmpCapsuleHeaderSize));
303 return EFI_INVALID_PARAMETER;
304 }
305
306 //
307 // All the address in ItemOffsetList must be stored in ascending order
308 //
309 if (Index > 0) {
310 if (ItemOffsetList[Index] <= ItemOffsetList[Index - 1]) {
311 DEBUG ((DEBUG_ERROR, "ItemOffsetList[%d](0x%lx) < ItemOffsetList[%d](0x%x)\n", Index, ItemOffsetList[Index], Index, ItemOffsetList[Index - 1]));
312 return EFI_INVALID_PARAMETER;
313 }
314 }
315 }
316
317 // Check EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER
318 for (Index = FmpCapsuleHeader->EmbeddedDriverCount; Index < ItemNum; Index++) {
319 ImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);
320 if (Index == ItemNum - 1) {
321 EndOfPayload = (UINT8 *)((UINTN)EndOfCapsule - (UINTN)FmpCapsuleHeader);
322 } else {
323 EndOfPayload = (UINT8 *)(UINTN)ItemOffsetList[Index+1];
324 }
325
326 FmpImageSize = (UINTN)EndOfPayload - ItemOffsetList[Index];
327
328 if (FmpImageSize < OFFSET_OF (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, UpdateHardwareInstance)) {
329 DEBUG ((DEBUG_ERROR, "FmpImageSize(0x%lx) < EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER\n", FmpImageSize));
330 return EFI_INVALID_PARAMETER;
331 }
332
333 FmpImageHeaderSize = sizeof (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER);
334 if ((ImageHeader->Version > EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) ||
335 (ImageHeader->Version < 1))
336 {
337 DEBUG ((DEBUG_ERROR, "ImageHeader->Version(0x%x) Unknown\n", ImageHeader->Version));
338 return EFI_INVALID_PARAMETER;
339 }
340
345 if (ImageHeader->Version == 1) {
346 FmpImageHeaderSize = OFFSET_OF (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, UpdateHardwareInstance);
347 } else if (ImageHeader->Version == 2) {
348 FmpImageHeaderSize = OFFSET_OF (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, ImageCapsuleSupport);
349 }
350
351 // No overflow
352 if (FmpImageSize != (UINT64)FmpImageHeaderSize + (UINT64)ImageHeader->UpdateImageSize + (UINT64)ImageHeader->UpdateVendorCodeSize) {
353 DEBUG ((DEBUG_ERROR, "FmpImageSize(0x%lx) mismatch, UpdateImageSize(0x%x) UpdateVendorCodeSize(0x%x)\n", FmpImageSize, ImageHeader->UpdateImageSize, ImageHeader->UpdateVendorCodeSize));
354 return EFI_INVALID_PARAMETER;
355 }
356 }
357
358 if (ItemNum == 0) {
359 //
360 // No driver & payload element in FMP
361 //
362 EndOfPayload = (UINT8 *)(FmpCapsuleHeader + 1);
363 if (EndOfPayload != EndOfCapsule) {
364 DEBUG ((DEBUG_ERROR, "EndOfPayload(0x%x) mismatch, EndOfCapsule(0x%x)\n", EndOfPayload, EndOfCapsule));
365 return EFI_INVALID_PARAMETER;
366 }
367
368 return EFI_UNSUPPORTED;
369 }
370
371 //
372 // Check in system FMP capsule
373 //
374 if (IsSystemFmp != NULL) {
375 *IsSystemFmp = IsSystemFmpCapsuleImage (CapsuleHeader);
376 }
377
378 if (EmbeddedDriverCount != NULL) {
379 *EmbeddedDriverCount = FmpCapsuleHeader->EmbeddedDriverCount;
380 }
381
382 return EFI_SUCCESS;
383}
384
394EFIAPI
396 IN EFI_PEI_FILE_HANDLE FileHandle,
397 IN CONST EFI_PEI_SERVICES **PeiServices
398 )
399{
400 EFI_STATUS Status;
401 UINTN BootMode;
402
403 BootMode = GetBootModeHob ();
404 ASSERT (BootMode == BOOT_IN_RECOVERY_MODE);
405
406 Status = (**PeiServices).InstallPpi (PeiServices, &mRecoveryPpiList);
407 ASSERT_EFI_ERROR (Status);
408
409 return Status;
410}
411
423EFIAPI
425 IN VOID *FvImage,
426 IN UINTN FvImageSize
427 )
428{
430 UINT32 FvAlignment;
431 UINT64 FvLength;
432 VOID *NewFvBuffer;
433
434 //
435 // FvImage should be at its required alignment.
436 //
437 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FvImage;
438 //
439 // Validate FV Header, if not as expected, return
440 //
441 if (ReadUnaligned32 (&FvHeader->Signature) != EFI_FVH_SIGNATURE) {
442 DEBUG ((DEBUG_ERROR, "CreateHobForRecoveryCapsule (Fv Signature Error)\n"));
443 return EFI_VOLUME_CORRUPTED;
444 }
445
446 //
447 // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume
448 // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from
449 // its initial linked location and maintain its alignment.
450 //
451 if ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) {
452 //
453 // Get FvHeader alignment
454 //
455 FvAlignment = 1 << ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_ALIGNMENT) >> 16);
456 //
457 // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.
458 //
459 if (FvAlignment < 8) {
460 FvAlignment = 8;
461 }
462
463 //
464 // Allocate the aligned buffer for the FvImage.
465 //
466 if ((UINTN)FvHeader % FvAlignment != 0) {
467 DEBUG ((DEBUG_INFO, "CreateHobForRecoveryCapsule (FvHeader 0x%lx is not aligned)\n", (UINT64)(UINTN)FvHeader));
468 FvLength = ReadUnaligned64 (&FvHeader->FvLength);
469 NewFvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN)FvLength), FvAlignment);
470 if (NewFvBuffer == NULL) {
471 DEBUG ((DEBUG_ERROR, "CreateHobForRecoveryCapsule (Not enough resource to allocate 0x%lx bytes)\n", FvLength));
472 return EFI_OUT_OF_RESOURCES;
473 }
474
475 CopyMem (NewFvBuffer, FvHeader, (UINTN)FvLength);
476 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)NewFvBuffer;
477 }
478 }
479
480 BuildFvHob ((UINT64)(UINTN)FvHeader, FvHeader->FvLength);
481 DEBUG ((DEBUG_INFO, "BuildFvHob (FV in recovery) - 0x%lx - 0x%lx\n", (UINT64)(UINTN)FvHeader, FvHeader->FvLength));
482
484 &FvHeader->FileSystemGuid,
485 (VOID *)FvHeader,
486 (UINT32)FvHeader->FvLength,
487 NULL,
488 NULL
489 );
490
491 return EFI_SUCCESS;
492}
493
506 IN VOID *SystemFirmwareImage,
507 IN UINTN SystemFirmwareImageSize,
508 IN VOID *ConfigImage,
509 IN UINTN ConfigImageSize
510 )
511{
512 EFI_STATUS Status;
513 RECOVERY_CONFIG_DATA *ConfigData;
514 RECOVERY_CONFIG_DATA *RecoveryConfigData;
515 CONFIG_HEADER ConfigHeader;
516 UINTN Index;
517
518 if (ConfigImage == NULL) {
519 DEBUG ((DEBUG_INFO, "RecoverImage (NoConfig)\n"));
521 SystemFirmwareImage,
522 SystemFirmwareImageSize
523 );
524 return Status;
525 }
526
527 ConfigData = NULL;
528 ZeroMem (&ConfigHeader, sizeof (ConfigHeader));
529 Status = ParseRecoveryDataFile (
530 ConfigImage,
531 ConfigImageSize,
532 &ConfigHeader,
533 &ConfigData
534 );
535 DEBUG ((DEBUG_INFO, "ParseRecoveryDataFile - %r\n", Status));
536 if (EFI_ERROR (Status)) {
537 return Status;
538 }
539
540 DEBUG ((DEBUG_INFO, "ConfigHeader.NumOfRecovery - 0x%x\n", ConfigHeader.NumOfRecovery));
541 DEBUG ((DEBUG_INFO, "PcdEdkiiSystemFirmwareFileGuid - %g\n", PcdGetPtr (PcdEdkiiSystemFirmwareFileGuid)));
542
543 Index = 0;
544 RecoveryConfigData = ConfigData;
545 while (Index < ConfigHeader.NumOfRecovery) {
546 if (CompareGuid (&RecoveryConfigData->FileGuid, PcdGetPtr (PcdEdkiiSystemFirmwareFileGuid))) {
547 DEBUG ((DEBUG_INFO, "FileGuid - %g (processing)\n", &RecoveryConfigData->FileGuid));
549 (UINT8 *)SystemFirmwareImage + RecoveryConfigData->ImageOffset,
550 RecoveryConfigData->Length
551 );
552 //
553 // Shall updates be serialized so that if a recovery FV is not successfully completed,
554 // the remaining updates won't be performed.
555 //
556 if (EFI_ERROR (Status)) {
557 break;
558 }
559 } else {
560 DEBUG ((DEBUG_INFO, "FileGuid - %g (ignored)\n", &RecoveryConfigData->FileGuid));
561 }
562
563 Index++;
564 RecoveryConfigData++;
565 }
566
567 return Status;
568}
569
583 IN VOID *Image,
584 IN UINTN Length
585 )
586{
587 UINT32 LastAttemptVersion;
588 UINT32 LastAttemptStatus;
589 EFI_STATUS Status;
590 VOID *SystemFirmwareImage;
591 UINTN SystemFirmwareImageSize;
592 VOID *ConfigImage;
593 UINTN ConfigImageSize;
594 VOID *AuthenticatedImage;
595 UINTN AuthenticatedImageSize;
596
597 AuthenticatedImage = NULL;
598 AuthenticatedImageSize = 0;
599
600 Status = CapsuleAuthenticateSystemFirmware (Image, Length, TRUE, &LastAttemptVersion, &LastAttemptStatus, &AuthenticatedImage, &AuthenticatedImageSize);
601 if (EFI_ERROR (Status)) {
602 DEBUG ((DEBUG_INFO, "CapsuleAuthenticateSystemFirmware - %r\n", Status));
603 return Status;
604 }
605
606 ExtractSystemFirmwareImage (AuthenticatedImage, AuthenticatedImageSize, &SystemFirmwareImage, &SystemFirmwareImageSize);
607 ExtractConfigImage (AuthenticatedImage, AuthenticatedImageSize, &ConfigImage, &ConfigImageSize);
608
609 Status = RecoverImage (SystemFirmwareImage, SystemFirmwareImageSize, ConfigImage, ConfigImageSize);
610 if (EFI_ERROR (Status)) {
611 DEBUG ((DEBUG_INFO, "RecoverImage - %r\n", Status));
612 return Status;
613 }
614
615 return EFI_SUCCESS;
616}
617
638 IN EFI_CAPSULE_HEADER *CapsuleHeader,
639 IN BOOLEAN IsSystemFmp
640 )
641{
642 EFI_STATUS Status;
645 UINT8 *Image;
646 UINT64 *ItemOffsetList;
647 UINTN ItemIndex;
648
649 if (!IsSystemFmp) {
650 return EFI_UNSUPPORTED;
651 }
652
653 FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);
654 ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);
655
656 for (ItemIndex = 0; ItemIndex < FmpCapsuleHeader->PayloadItemCount; ItemIndex++) {
657 ImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[ItemIndex]);
658 if (ImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {
659 Image = (UINT8 *)(ImageHeader + 1);
660 } else {
661 //
662 // If the EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER is version 1, only match ImageTypeId.
663 // Header should exclude UpdateHardwareInstance field.
664 // If version is 2 Header should exclude ImageCapsuleSupport field.
665 //
666 if (ImageHeader->Version == 1) {
667 Image = (UINT8 *)ImageHeader + OFFSET_OF (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, UpdateHardwareInstance);
668 } else {
669 Image = (UINT8 *)ImageHeader + OFFSET_OF (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, ImageCapsuleSupport);
670 }
671 }
672
673 Status = ProcessRecoveryImage (Image, ImageHeader->UpdateImageSize);
674 if (EFI_ERROR (Status)) {
675 return Status;
676 }
677 }
678
679 return EFI_SUCCESS;
680}
681
695EFIAPI
697 IN VOID *CapsuleBuffer,
698 IN UINTN CapsuleSize
699 )
700{
701 EFI_STATUS Status;
702 BOOLEAN IsSystemFmp;
703 EFI_CAPSULE_HEADER *CapsuleHeader;
704
705 CapsuleHeader = CapsuleBuffer;
706 if (!IsValidCapsuleHeader (CapsuleHeader, CapsuleSize)) {
707 DEBUG ((DEBUG_ERROR, "CapsuleImageSize incorrect\n"));
708 return EFI_SECURITY_VIOLATION;
709 }
710
711 //
712 // Check FMP capsule layout
713 //
714 if (IsFmpCapsuleGuid (&CapsuleHeader->CapsuleGuid)) {
715 DEBUG ((DEBUG_INFO, "CreateHobForRecoveryCapsule\n"));
716
717 DEBUG ((DEBUG_INFO, "ProcessCapsuleImage for FmpCapsule ...\n"));
718 DEBUG ((DEBUG_INFO, "ValidateFmpCapsule ...\n"));
719 Status = ValidateFmpCapsule (CapsuleHeader, &IsSystemFmp, NULL);
720 DEBUG ((DEBUG_INFO, "ValidateFmpCapsule - %r\n", Status));
721 if (EFI_ERROR (Status)) {
722 return Status;
723 }
724
725 //
726 // Process EFI FMP Capsule
727 //
728 DEBUG ((DEBUG_INFO, "ProcessFmpCapsuleImage ...\n"));
729 Status = ProcessFmpCapsuleImage (CapsuleHeader, IsSystemFmp);
730 DEBUG ((DEBUG_INFO, "ProcessFmpCapsuleImage - %r\n", Status));
731
732 DEBUG ((DEBUG_INFO, "CreateHobForRecoveryCapsule Done\n"));
733 return Status;
734 }
735
736 return EFI_UNSUPPORTED;
737}
738
752EFIAPI
754 IN EFI_PEI_SERVICES **PeiServices,
756 )
757{
758 EFI_STATUS Status;
759 EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *DeviceRecoveryPpi;
760 UINTN NumberRecoveryCapsules;
761 UINTN Instance;
762 UINTN CapsuleInstance;
763 UINTN CapsuleSize;
764 EFI_GUID CapsuleType;
765 VOID *CapsuleBuffer;
766
767 DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Recovery Entry\n"));
768
769 for (Instance = 0; ; Instance++) {
770 Status = PeiServicesLocatePpi (
771 &gEfiPeiDeviceRecoveryModulePpiGuid,
772 Instance,
773 NULL,
774 (VOID **)&DeviceRecoveryPpi
775 );
776 DEBUG ((DEBUG_ERROR, "LoadRecoveryCapsule - LocateRecoveryPpi (%d) - %r\n", Instance, Status));
777 if (EFI_ERROR (Status)) {
778 break;
779 }
780
781 NumberRecoveryCapsules = 0;
782 Status = DeviceRecoveryPpi->GetNumberRecoveryCapsules (
783 (EFI_PEI_SERVICES **)PeiServices,
784 DeviceRecoveryPpi,
785 &NumberRecoveryCapsules
786 );
787 DEBUG ((DEBUG_ERROR, "LoadRecoveryCapsule - GetNumberRecoveryCapsules (%d) - %r\n", NumberRecoveryCapsules, Status));
788 if (EFI_ERROR (Status)) {
789 continue;
790 }
791
792 for (CapsuleInstance = 1; CapsuleInstance <= NumberRecoveryCapsules; CapsuleInstance++) {
793 CapsuleSize = 0;
794 Status = DeviceRecoveryPpi->GetRecoveryCapsuleInfo (
795 (EFI_PEI_SERVICES **)PeiServices,
796 DeviceRecoveryPpi,
797 CapsuleInstance,
798 &CapsuleSize,
799 &CapsuleType
800 );
801 DEBUG ((DEBUG_ERROR, "LoadRecoveryCapsule - GetRecoveryCapsuleInfo (%d - %x) - %r\n", CapsuleInstance, CapsuleSize, Status));
802 if (EFI_ERROR (Status)) {
803 break;
804 }
805
806 CapsuleBuffer = AllocatePages (EFI_SIZE_TO_PAGES (CapsuleSize));
807 if (CapsuleBuffer == NULL) {
808 DEBUG ((DEBUG_ERROR, "LoadRecoveryCapsule - AllocatePool fail\n"));
809 continue;
810 }
811
812 Status = DeviceRecoveryPpi->LoadRecoveryCapsule (
813 (EFI_PEI_SERVICES **)PeiServices,
814 DeviceRecoveryPpi,
815 CapsuleInstance,
816 CapsuleBuffer
817 );
818 DEBUG ((DEBUG_ERROR, "LoadRecoveryCapsule - LoadRecoveryCapsule (%d) - %r\n", CapsuleInstance, Status));
819 if (EFI_ERROR (Status)) {
820 FreePages (CapsuleBuffer, EFI_SIZE_TO_PAGES (CapsuleSize));
821 break;
822 }
823
824 //
825 // good, load capsule buffer
826 //
827 Status = ProcessRecoveryCapsule (CapsuleBuffer, CapsuleSize);
828 return Status;
829 }
830 }
831
832 return EFI_NOT_FOUND;
833}
UINT64 UINTN
VOID EFIAPI BuildFvHob(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
Definition: HobLib.c:404
EFI_BOOT_MODE EFIAPI GetBootModeHob(VOID)
Definition: HobLib.c:240
UINT64 EFIAPI ReadUnaligned64(IN CONST UINT64 *Buffer)
Definition: Unaligned.c:204
UINT32 EFIAPI ReadUnaligned32(IN CONST UINT32 *Buffer)
Definition: Unaligned.c:145
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
BOOLEAN EFIAPI ExtractSystemFirmwareImage(IN VOID *AuthenticatedImage, IN UINTN AuthenticatedImageSize, OUT VOID **SystemFirmwareImage, OUT UINTN *SystemFirmwareImageSize)
EFI_STATUS EFIAPI CapsuleAuthenticateSystemFirmware(IN VOID *Image, IN UINTN ImageSize, IN BOOLEAN ForceVersionMatch, OUT UINT32 *LastAttemptVersion, OUT UINT32 *LastAttemptStatus, OUT VOID **AuthenticatedImage, OUT UINTN *AuthenticatedImageSize)
BOOLEAN EFIAPI ExtractConfigImage(IN VOID *AuthenticatedImage, IN UINTN AuthenticatedImageSize, OUT VOID **ConfigImage, OUT UINTN *ConfigImageSize)
VOID EFIAPI FreePages(IN VOID *Buffer, IN UINTN Pages)
VOID EFIAPI PeiServicesInstallFvInfoPpi(IN CONST EFI_GUID *FvFormat OPTIONAL, IN CONST VOID *FvInfo, IN UINT32 FvInfoSize, IN CONST EFI_GUID *ParentFvName OPTIONAL, IN CONST EFI_GUID *ParentFileName OPTIONAL)
EFI_STATUS EFIAPI PeiServicesLocatePpi(IN CONST EFI_GUID *Guid, IN UINTN Instance, IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, IN OUT VOID **Ppi)
BOOLEAN IsSystemFmp(IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfo)
Definition: EsrtImpl.c:405
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OFFSET_OF(TYPE, Field)
Definition: Base.h:758
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define PcdGetSize(TokenName)
Definition: PcdLib.h:440
#define PcdGetPtr(TokenName)
Definition: PcdLib.h:388
VOID * EFI_PEI_FILE_HANDLE
Definition: PiPeiCis.h:26
VOID *EFIAPI AllocateAlignedPages(IN UINTN Pages, IN UINTN Alignment)
VOID *EFIAPI AllocatePages(IN UINTN Pages)
BOOLEAN IsFmpCapsuleGuid(IN EFI_GUID *CapsuleGuid)
EFI_STATUS ProcessRecoveryImage(IN VOID *Image, IN UINTN Length)
EFI_STATUS ParseRecoveryDataFile(IN UINT8 *DataBuffer, IN UINTN BufferSize, IN OUT CONFIG_HEADER *ConfigHeader, IN OUT RECOVERY_CONFIG_DATA **RecoveryArray)
EFI_STATUS EFIAPI LoadRecoveryCapsule(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_RECOVERY_MODULE_PPI *This)
EFI_STATUS ProcessFmpCapsuleImage(IN EFI_CAPSULE_HEADER *CapsuleHeader, IN BOOLEAN IsSystemFmp)
EFI_STATUS EFIAPI CreateHobForRecoveryCapsule(IN VOID *FvImage, IN UINTN FvImageSize)
EFI_STATUS EFIAPI ProcessRecoveryCapsule(IN VOID *CapsuleBuffer, IN UINTN CapsuleSize)
EFI_STATUS EFIAPI InitializeRecoveryModule(IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices)
EFI_STATUS ValidateFmpCapsule(IN EFI_CAPSULE_HEADER *CapsuleHeader, OUT BOOLEAN *IsSystemFmp OPTIONAL, OUT UINT16 *EmbeddedDriverCount OPTIONAL)
BOOLEAN IsSystemFmpCapsuleImage(IN EFI_CAPSULE_HEADER *CapsuleHeader)
BOOLEAN IsValidCapsuleHeader(IN EFI_CAPSULE_HEADER *CapsuleHeader, IN UINT64 CapsuleSize)
BOOLEAN IsSystemFmpImage(IN EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *FmpImageHeader)
EFI_STATUS RecoverImage(IN VOID *SystemFirmwareImage, IN UINTN SystemFirmwareImageSize, IN VOID *ConfigImage, IN UINTN ConfigImageSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_GUID CapsuleGuid
Definition: UefiSpec.h:1682
EFI_FVB_ATTRIBUTES_2 Attributes
Definition: Base.h:213