TianoCore EDK2 master
Loading...
Searching...
No Matches
DxeCapsuleLib.c
Go to the documentation of this file.
1
19#include <PiDxe.h>
20
22
23#include <Guid/FmpCapsule.h>
25#include <Guid/EventGroup.h>
26
27#include <Library/BaseLib.h>
28#include <Library/DebugLib.h>
34#include <Library/CapsuleLib.h>
36#include <Library/UefiLib.h>
38
43#include <Protocol/DevicePath.h>
44
46
47BOOLEAN mDxeCapsuleLibEndOfDxe = FALSE;
48EFI_EVENT mDxeCapsuleLibEndOfDxeEvent = NULL;
49
51
52BOOLEAN mDxeCapsuleLibIsExitBootService = FALSE;
53
57VOID
59 VOID
60 );
61
73 IN EFI_CAPSULE_HEADER *CapsuleHeader,
74 IN EFI_STATUS CapsuleStatus
75 );
76
92 IN EFI_CAPSULE_HEADER *CapsuleHeader,
93 IN EFI_STATUS CapsuleStatus,
94 IN UINTN PayloadIndex,
96 IN EFI_DEVICE_PATH_PROTOCOL *FmpDevicePath OPTIONAL,
97 IN CHAR16 *CapFileName OPTIONAL
98 );
99
111EFIAPI
113 IN UINTN Completion
114 );
115
124BOOLEAN
126 IN EFI_CAPSULE_HEADER *CapsuleHeader
127 )
128{
129 return CompareGuid (&CapsuleHeader->CapsuleGuid, &gEdkiiCapsuleOnDiskNameGuid);
130}
131
140BOOLEAN
142 IN EFI_GUID *CapsuleGuid
143 )
144{
145 if (CompareGuid (&gEfiFmpCapsuleGuid, CapsuleGuid)) {
146 return TRUE;
147 }
148
149 return FALSE;
150}
151
166BOOLEAN
168 IN EFI_CAPSULE_HEADER *CapsuleHeader,
169 IN UINT64 CapsuleSize
170 )
171{
172 if (CapsuleHeader->CapsuleImageSize != CapsuleSize) {
173 return FALSE;
174 }
175
176 if (CapsuleHeader->HeaderSize >= CapsuleHeader->CapsuleImageSize) {
177 return FALSE;
178 }
179
180 return TRUE;
181}
182
205 IN EFI_CAPSULE_HEADER *CapsuleHeader,
206 OUT UINT16 *EmbeddedDriverCount OPTIONAL
207 )
208{
210 UINT8 *EndOfCapsule;
212 UINT8 *EndOfPayload;
213 UINT64 *ItemOffsetList;
214 UINT32 ItemNum;
215 UINTN Index;
216 UINTN FmpCapsuleSize;
217 UINTN FmpCapsuleHeaderSize;
218 UINT64 FmpImageSize;
219 UINTN FmpImageHeaderSize;
220
221 if (!IsFmpCapsuleGuid (&CapsuleHeader->CapsuleGuid)) {
222 return ValidateFmpCapsule ((EFI_CAPSULE_HEADER *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize), EmbeddedDriverCount);
223 }
224
225 if (CapsuleHeader->HeaderSize >= CapsuleHeader->CapsuleImageSize) {
226 DEBUG ((DEBUG_ERROR, "HeaderSize(0x%x) >= CapsuleImageSize(0x%x)\n", CapsuleHeader->HeaderSize, CapsuleHeader->CapsuleImageSize));
227 return EFI_INVALID_PARAMETER;
228 }
229
230 FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);
231 EndOfCapsule = (UINT8 *)CapsuleHeader + CapsuleHeader->CapsuleImageSize;
232 FmpCapsuleSize = (UINTN)EndOfCapsule - (UINTN)FmpCapsuleHeader;
233
234 if (FmpCapsuleSize < sizeof (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER)) {
235 DEBUG ((DEBUG_ERROR, "FmpCapsuleSize(0x%x) < EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER\n", FmpCapsuleSize));
236 return EFI_INVALID_PARAMETER;
237 }
238
239 // Check EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER
240 if (FmpCapsuleHeader->Version != EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION) {
241 DEBUG ((DEBUG_ERROR, "FmpCapsuleHeader->Version(0x%x) != EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION\n", FmpCapsuleHeader->Version));
242 return EFI_INVALID_PARAMETER;
243 }
244
245 ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);
246
247 // No overflow
248 ItemNum = FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount;
249
250 if ((FmpCapsuleSize - sizeof (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER))/sizeof (UINT64) < ItemNum) {
251 DEBUG ((DEBUG_ERROR, "ItemNum(0x%x) too big\n", ItemNum));
252 return EFI_INVALID_PARAMETER;
253 }
254
255 FmpCapsuleHeaderSize = sizeof (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER) + sizeof (UINT64)*ItemNum;
256
257 // Check ItemOffsetList
258 for (Index = 0; Index < ItemNum; Index++) {
259 if (ItemOffsetList[Index] >= FmpCapsuleSize) {
260 DEBUG ((DEBUG_ERROR, "ItemOffsetList[%d](0x%lx) >= FmpCapsuleSize(0x%x)\n", Index, ItemOffsetList[Index], FmpCapsuleSize));
261 return EFI_INVALID_PARAMETER;
262 }
263
264 if (ItemOffsetList[Index] < FmpCapsuleHeaderSize) {
265 DEBUG ((DEBUG_ERROR, "ItemOffsetList[%d](0x%lx) < FmpCapsuleHeaderSize(0x%x)\n", Index, ItemOffsetList[Index], FmpCapsuleHeaderSize));
266 return EFI_INVALID_PARAMETER;
267 }
268
269 //
270 // All the address in ItemOffsetList must be stored in ascending order
271 //
272 if (Index > 0) {
273 if (ItemOffsetList[Index] <= ItemOffsetList[Index - 1]) {
274 DEBUG ((DEBUG_ERROR, "ItemOffsetList[%d](0x%lx) < ItemOffsetList[%d](0x%x)\n", Index, ItemOffsetList[Index], Index - 1, ItemOffsetList[Index - 1]));
275 return EFI_INVALID_PARAMETER;
276 }
277 }
278 }
279
280 // Check EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER
281 for (Index = FmpCapsuleHeader->EmbeddedDriverCount; Index < ItemNum; Index++) {
282 ImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);
283 if (Index == ItemNum - 1) {
284 EndOfPayload = (UINT8 *)((UINTN)EndOfCapsule - (UINTN)FmpCapsuleHeader);
285 } else {
286 EndOfPayload = (UINT8 *)(UINTN)ItemOffsetList[Index+1];
287 }
288
289 FmpImageSize = (UINTN)EndOfPayload - ItemOffsetList[Index];
290
291 FmpImageHeaderSize = sizeof (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER);
292 if ((ImageHeader->Version > EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) ||
293 (ImageHeader->Version < 1))
294 {
295 DEBUG ((DEBUG_ERROR, "ImageHeader->Version(0x%x) Unknown\n", ImageHeader->Version));
296 return EFI_INVALID_PARAMETER;
297 }
298
299 if (ImageHeader->Version == 1) {
300 FmpImageHeaderSize = OFFSET_OF (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, UpdateHardwareInstance);
301 } else if (ImageHeader->Version == 2) {
302 FmpImageHeaderSize = OFFSET_OF (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, ImageCapsuleSupport);
303 }
304
305 if (FmpImageSize < FmpImageHeaderSize) {
306 DEBUG ((DEBUG_ERROR, "FmpImageSize(0x%lx) < FmpImageHeaderSize(0x%x)\n", FmpImageSize, FmpImageHeaderSize));
307 return EFI_INVALID_PARAMETER;
308 }
309
310 // No overflow
311 if (FmpImageSize != (UINT64)FmpImageHeaderSize + (UINT64)ImageHeader->UpdateImageSize + (UINT64)ImageHeader->UpdateVendorCodeSize) {
312 DEBUG ((DEBUG_ERROR, "FmpImageSize(0x%lx) mismatch, UpdateImageSize(0x%x) UpdateVendorCodeSize(0x%x)\n", FmpImageSize, ImageHeader->UpdateImageSize, ImageHeader->UpdateVendorCodeSize));
313 return EFI_INVALID_PARAMETER;
314 }
315 }
316
317 if (ItemNum == 0) {
318 //
319 // No driver & payload element in FMP
320 //
321 EndOfPayload = (UINT8 *)(FmpCapsuleHeader + 1);
322 if (EndOfPayload != EndOfCapsule) {
323 DEBUG ((DEBUG_ERROR, "EndOfPayload(0x%x) mismatch, EndOfCapsule(0x%x)\n", EndOfPayload, EndOfCapsule));
324 return EFI_INVALID_PARAMETER;
325 }
326
327 return EFI_UNSUPPORTED;
328 }
329
330 if (EmbeddedDriverCount != NULL) {
331 *EmbeddedDriverCount = FmpCapsuleHeader->EmbeddedDriverCount;
332 }
333
334 return EFI_SUCCESS;
335}
336
349 IN EFI_CAPSULE_HEADER *CapsuleHeader
350 )
351{
352 DISPLAY_DISPLAY_PAYLOAD *ImagePayload;
353 UINTN PayloadSize;
354 EFI_STATUS Status;
356 UINTN BltSize;
357 UINTN Height;
358 UINTN Width;
359 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
360
361 //
362 // UX capsule doesn't have extended header entries.
363 //
364 if (CapsuleHeader->HeaderSize != sizeof (EFI_CAPSULE_HEADER)) {
365 return EFI_UNSUPPORTED;
366 }
367
368 ImagePayload = (DISPLAY_DISPLAY_PAYLOAD *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize);
369 //
370 // (CapsuleImageSize > HeaderSize) is guaranteed by IsValidCapsuleHeader().
371 //
372 PayloadSize = CapsuleHeader->CapsuleImageSize - CapsuleHeader->HeaderSize;
373
374 //
375 // Make sure the image payload at least contain the DISPLAY_DISPLAY_PAYLOAD header.
376 // Further size check is performed by the logic translating BMP to GOP BLT.
377 //
378 if (PayloadSize <= sizeof (DISPLAY_DISPLAY_PAYLOAD)) {
379 return EFI_INVALID_PARAMETER;
380 }
381
382 if (ImagePayload->Version != 1) {
383 return EFI_UNSUPPORTED;
384 }
385
386 if (CalculateCheckSum8 ((UINT8 *)CapsuleHeader, CapsuleHeader->CapsuleImageSize) != 0) {
387 return EFI_UNSUPPORTED;
388 }
389
390 //
391 // Only Support Bitmap by now
392 //
393 if (ImagePayload->ImageType != 0) {
394 return EFI_UNSUPPORTED;
395 }
396
397 //
398 // Try to open GOP
399 //
400 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **)&GraphicsOutput);
401 if (EFI_ERROR (Status)) {
402 Status = gBS->LocateProtocol (&gEfiGraphicsOutputProtocolGuid, NULL, (VOID **)&GraphicsOutput);
403 if (EFI_ERROR (Status)) {
404 return EFI_UNSUPPORTED;
405 }
406 }
407
408 if (GraphicsOutput->Mode->Mode != ImagePayload->Mode) {
409 return EFI_UNSUPPORTED;
410 }
411
412 Blt = NULL;
413 Width = 0;
414 Height = 0;
415 Status = TranslateBmpToGopBlt (
416 ImagePayload + 1,
417 PayloadSize - sizeof (DISPLAY_DISPLAY_PAYLOAD),
418 &Blt,
419 &BltSize,
420 &Height,
421 &Width
422 );
423
424 if (EFI_ERROR (Status)) {
425 return Status;
426 }
427
428 Status = GraphicsOutput->Blt (
429 GraphicsOutput,
430 Blt,
432 0,
433 0,
434 (UINTN)ImagePayload->OffsetX,
435 (UINTN)ImagePayload->OffsetY,
436 Width,
437 Height,
438 Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
439 );
440
441 FreePool (Blt);
442
443 return Status;
444}
445
457VOID
459 IN UINTN ImageInfoSize,
461 IN UINT32 DescriptorVersion,
462 IN UINT8 DescriptorCount,
463 IN UINTN DescriptorSize,
464 IN UINT32 PackageVersion,
465 IN CHAR16 *PackageVersionName
466 )
467{
468 EFI_FIRMWARE_IMAGE_DESCRIPTOR *CurrentImageInfo;
469 UINTN Index;
470
471 DEBUG ((DEBUG_VERBOSE, " DescriptorVersion - 0x%x\n", DescriptorVersion));
472 DEBUG ((DEBUG_VERBOSE, " DescriptorCount - 0x%x\n", DescriptorCount));
473 DEBUG ((DEBUG_VERBOSE, " DescriptorSize - 0x%x\n", DescriptorSize));
474 DEBUG ((DEBUG_VERBOSE, " PackageVersion - 0x%x\n", PackageVersion));
475 DEBUG ((DEBUG_VERBOSE, " PackageVersionName - %s\n\n", PackageVersionName));
476 CurrentImageInfo = ImageInfo;
477 for (Index = 0; Index < DescriptorCount; Index++) {
478 DEBUG ((DEBUG_VERBOSE, " ImageDescriptor (%d)\n", Index));
479 DEBUG ((DEBUG_VERBOSE, " ImageIndex - 0x%x\n", CurrentImageInfo->ImageIndex));
480 DEBUG ((DEBUG_VERBOSE, " ImageTypeId - %g\n", &CurrentImageInfo->ImageTypeId));
481 DEBUG ((DEBUG_VERBOSE, " ImageId - 0x%lx\n", CurrentImageInfo->ImageId));
482 DEBUG ((DEBUG_VERBOSE, " ImageIdName - %s\n", CurrentImageInfo->ImageIdName));
483 DEBUG ((DEBUG_VERBOSE, " Version - 0x%x\n", CurrentImageInfo->Version));
484 DEBUG ((DEBUG_VERBOSE, " VersionName - %s\n", CurrentImageInfo->VersionName));
485 DEBUG ((DEBUG_VERBOSE, " Size - 0x%x\n", CurrentImageInfo->Size));
486 DEBUG ((DEBUG_VERBOSE, " AttributesSupported - 0x%lx\n", CurrentImageInfo->AttributesSupported));
487 DEBUG ((DEBUG_VERBOSE, " AttributesSetting - 0x%lx\n", CurrentImageInfo->AttributesSetting));
488 DEBUG ((DEBUG_VERBOSE, " Compatibilities - 0x%lx\n", CurrentImageInfo->Compatibilities));
489 if (DescriptorVersion > 1) {
490 DEBUG ((DEBUG_VERBOSE, " LowestSupportedImageVersion - 0x%x\n", CurrentImageInfo->LowestSupportedImageVersion));
491 if (DescriptorVersion > 2) {
492 DEBUG ((DEBUG_VERBOSE, " LastAttemptVersion - 0x%x\n", CurrentImageInfo->LastAttemptVersion));
493 DEBUG ((DEBUG_VERBOSE, " LastAttemptStatus - 0x%x\n", CurrentImageInfo->LastAttemptStatus));
494 DEBUG ((DEBUG_VERBOSE, " HardwareInstance - 0x%lx\n", CurrentImageInfo->HardwareInstance));
495 }
496 }
497
498 //
499 // Use DescriptorSize to move ImageInfo Pointer to stay compatible with different ImageInfo version
500 //
501 CurrentImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)CurrentImageInfo + DescriptorSize);
502 }
503}
504
510VOID
512 IN EFI_CAPSULE_HEADER *CapsuleHeader
513 )
514{
517 UINTN Index;
518 UINT64 *ItemOffsetList;
519
520 FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);
521
522 DEBUG ((DEBUG_VERBOSE, "FmpCapsule:\n"));
523 DEBUG ((DEBUG_VERBOSE, " Version - 0x%x\n", FmpCapsuleHeader->Version));
524 DEBUG ((DEBUG_VERBOSE, " EmbeddedDriverCount - 0x%x\n", FmpCapsuleHeader->EmbeddedDriverCount));
525 DEBUG ((DEBUG_VERBOSE, " PayloadItemCount - 0x%x\n", FmpCapsuleHeader->PayloadItemCount));
526
527 ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);
528 for (Index = 0; Index < FmpCapsuleHeader->EmbeddedDriverCount; Index++) {
529 DEBUG ((DEBUG_VERBOSE, " ItemOffsetList[%d] - 0x%lx\n", Index, ItemOffsetList[Index]));
530 }
531
532 for ( ; Index < (UINT32)FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount; Index++) {
533 DEBUG ((DEBUG_VERBOSE, " ItemOffsetList[%d] - 0x%lx\n", Index, ItemOffsetList[Index]));
534 ImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);
535
536 DEBUG ((DEBUG_VERBOSE, " ImageHeader:\n"));
537 DEBUG ((DEBUG_VERBOSE, " Version - 0x%x\n", ImageHeader->Version));
538 DEBUG ((DEBUG_VERBOSE, " UpdateImageTypeId - %g\n", &ImageHeader->UpdateImageTypeId));
539 DEBUG ((DEBUG_VERBOSE, " UpdateImageIndex - 0x%x\n", ImageHeader->UpdateImageIndex));
540 DEBUG ((DEBUG_VERBOSE, " UpdateImageSize - 0x%x\n", ImageHeader->UpdateImageSize));
541 DEBUG ((DEBUG_VERBOSE, " UpdateVendorCodeSize - 0x%x\n", ImageHeader->UpdateVendorCodeSize));
542 if (ImageHeader->Version >= 2) {
543 DEBUG ((DEBUG_VERBOSE, " UpdateHardwareInstance - 0x%lx\n", ImageHeader->UpdateHardwareInstance));
544 if (ImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {
545 DEBUG ((DEBUG_VERBOSE, " ImageCapsuleSupport - 0x%lx\n", ImageHeader->ImageCapsuleSupport));
546 }
547 }
548 }
549}
550
554VOID
556 VOID
557 )
558{
559 EFI_STATUS Status;
560 EFI_HANDLE *HandleBuffer;
561 UINTN NumberOfHandles;
563 UINTN Index;
564 UINTN ImageInfoSize;
565 EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;
566 UINT32 FmpImageInfoDescriptorVer;
567 UINT8 FmpImageInfoCount;
568 UINTN DescriptorSize;
569 UINT32 PackageVersion;
570 CHAR16 *PackageVersionName;
571
572 Status = gBS->LocateHandleBuffer (
574 &gEfiFirmwareManagementProtocolGuid,
575 NULL,
576 &NumberOfHandles,
577 &HandleBuffer
578 );
579 if (EFI_ERROR (Status)) {
580 return;
581 }
582
583 for (Index = 0; Index < NumberOfHandles; Index++) {
584 Status = gBS->HandleProtocol (
585 HandleBuffer[Index],
586 &gEfiFirmwareManagementProtocolGuid,
587 (VOID **)&Fmp
588 );
589 if (EFI_ERROR (Status)) {
590 continue;
591 }
592
593 ImageInfoSize = 0;
594 Status = Fmp->GetImageInfo (
595 Fmp,
596 &ImageInfoSize,
597 NULL,
598 NULL,
599 NULL,
600 NULL,
601 NULL,
602 NULL
603 );
604 if (Status != EFI_BUFFER_TOO_SMALL) {
605 continue;
606 }
607
608 FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);
609 if (FmpImageInfoBuf == NULL) {
610 continue;
611 }
612
613 PackageVersionName = NULL;
614 Status = Fmp->GetImageInfo (
615 Fmp,
616 &ImageInfoSize, // ImageInfoSize
617 FmpImageInfoBuf, // ImageInfo
618 &FmpImageInfoDescriptorVer, // DescriptorVersion
619 &FmpImageInfoCount, // DescriptorCount
620 &DescriptorSize, // DescriptorSize
621 &PackageVersion, // PackageVersion
622 &PackageVersionName // PackageVersionName
623 );
624 if (EFI_ERROR (Status)) {
625 FreePool (FmpImageInfoBuf);
626 continue;
627 }
628
629 DEBUG ((DEBUG_INFO, "FMP (%d) ImageInfo:\n", Index));
631 ImageInfoSize, // ImageInfoSize
632 FmpImageInfoBuf, // ImageInfo
633 FmpImageInfoDescriptorVer, // DescriptorVersion
634 FmpImageInfoCount, // DescriptorCount
635 DescriptorSize, // DescriptorSize
636 PackageVersion, // PackageVersion
637 PackageVersionName // PackageVersionName
638 );
639
640 if (PackageVersionName != NULL) {
641 FreePool (PackageVersionName);
642 }
643
644 FreePool (FmpImageInfoBuf);
645 }
646
647 FreePool (HandleBuffer);
648
649 return;
650}
651
670 IN EFI_GUID *UpdateImageTypeId,
671 IN UINT64 UpdateHardwareInstance,
672 OUT UINTN *NoHandles OPTIONAL,
673 OUT EFI_HANDLE **HandleBuf OPTIONAL,
674 OUT BOOLEAN **ResetRequiredBuf OPTIONAL
675 )
676{
677 EFI_STATUS Status;
678 EFI_HANDLE *HandleBuffer;
679 UINTN NumberOfHandles;
680 EFI_HANDLE *MatchedHandleBuffer;
681 BOOLEAN *MatchedResetRequiredBuffer;
682 UINTN MatchedNumberOfHandles;
684 UINTN Index;
685 UINTN ImageInfoSize;
686 EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;
687 UINT32 FmpImageInfoDescriptorVer;
688 UINT8 FmpImageInfoCount;
689 UINTN DescriptorSize;
690 UINT32 PackageVersion;
691 CHAR16 *PackageVersionName;
692 UINTN Index2;
693 EFI_FIRMWARE_IMAGE_DESCRIPTOR *TempFmpImageInfo;
694
695 if (NoHandles != NULL) {
696 *NoHandles = 0;
697 }
698
699 if (HandleBuf != NULL) {
700 *HandleBuf = NULL;
701 }
702
703 if (ResetRequiredBuf != NULL) {
704 *ResetRequiredBuf = NULL;
705 }
706
707 Status = gBS->LocateHandleBuffer (
709 &gEfiFirmwareManagementProtocolGuid,
710 NULL,
711 &NumberOfHandles,
712 &HandleBuffer
713 );
714 if (EFI_ERROR (Status)) {
715 return Status;
716 }
717
718 MatchedNumberOfHandles = 0;
719
720 MatchedHandleBuffer = NULL;
721 if (HandleBuf != NULL) {
722 MatchedHandleBuffer = AllocateZeroPool (sizeof (EFI_HANDLE) * NumberOfHandles);
723 if (MatchedHandleBuffer == NULL) {
724 FreePool (HandleBuffer);
725 return EFI_OUT_OF_RESOURCES;
726 }
727 }
728
729 MatchedResetRequiredBuffer = NULL;
730 if (ResetRequiredBuf != NULL) {
731 MatchedResetRequiredBuffer = AllocateZeroPool (sizeof (BOOLEAN) * NumberOfHandles);
732 if (MatchedResetRequiredBuffer == NULL) {
733 if (MatchedHandleBuffer != NULL) {
734 FreePool (MatchedHandleBuffer);
735 }
736
737 FreePool (HandleBuffer);
738 return EFI_OUT_OF_RESOURCES;
739 }
740 }
741
742 for (Index = 0; Index < NumberOfHandles; Index++) {
743 Status = gBS->HandleProtocol (
744 HandleBuffer[Index],
745 &gEfiFirmwareManagementProtocolGuid,
746 (VOID **)&Fmp
747 );
748 if (EFI_ERROR (Status)) {
749 continue;
750 }
751
752 ImageInfoSize = 0;
753 Status = Fmp->GetImageInfo (
754 Fmp,
755 &ImageInfoSize,
756 NULL,
757 NULL,
758 NULL,
759 NULL,
760 NULL,
761 NULL
762 );
763 if (Status != EFI_BUFFER_TOO_SMALL) {
764 continue;
765 }
766
767 FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);
768 if (FmpImageInfoBuf == NULL) {
769 continue;
770 }
771
772 PackageVersionName = NULL;
773 Status = Fmp->GetImageInfo (
774 Fmp,
775 &ImageInfoSize, // ImageInfoSize
776 FmpImageInfoBuf, // ImageInfo
777 &FmpImageInfoDescriptorVer, // DescriptorVersion
778 &FmpImageInfoCount, // DescriptorCount
779 &DescriptorSize, // DescriptorSize
780 &PackageVersion, // PackageVersion
781 &PackageVersionName // PackageVersionName
782 );
783 if (EFI_ERROR (Status)) {
784 FreePool (FmpImageInfoBuf);
785 continue;
786 }
787
788 if (PackageVersionName != NULL) {
789 FreePool (PackageVersionName);
790 }
791
792 TempFmpImageInfo = FmpImageInfoBuf;
793 for (Index2 = 0; Index2 < FmpImageInfoCount; Index2++) {
794 //
795 // Check if this FMP instance matches
796 //
797 if (CompareGuid (UpdateImageTypeId, &TempFmpImageInfo->ImageTypeId)) {
798 if ((UpdateHardwareInstance == 0) ||
799 ((FmpImageInfoDescriptorVer >= EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION) &&
800 (UpdateHardwareInstance == TempFmpImageInfo->HardwareInstance)))
801 {
802 if (MatchedHandleBuffer != NULL) {
803 MatchedHandleBuffer[MatchedNumberOfHandles] = HandleBuffer[Index];
804 }
805
806 if (MatchedResetRequiredBuffer != NULL) {
807 MatchedResetRequiredBuffer[MatchedNumberOfHandles] = (((TempFmpImageInfo->AttributesSupported &
809 ((TempFmpImageInfo->AttributesSetting &
811 }
812
813 MatchedNumberOfHandles++;
814 break;
815 }
816 }
817
818 TempFmpImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)TempFmpImageInfo + DescriptorSize);
819 }
820
821 FreePool (FmpImageInfoBuf);
822 }
823
824 FreePool (HandleBuffer);
825
826 if (MatchedNumberOfHandles == 0) {
827 return EFI_NOT_FOUND;
828 }
829
830 if (NoHandles != NULL) {
831 *NoHandles = MatchedNumberOfHandles;
832 }
833
834 if (HandleBuf != NULL) {
835 *HandleBuf = MatchedHandleBuffer;
836 }
837
838 if (ResetRequiredBuf != NULL) {
839 *ResetRequiredBuf = MatchedResetRequiredBuffer;
840 }
841
842 return EFI_SUCCESS;
843}
844
852UINT32
854 IN EFI_HANDLE Handle
855 )
856{
857 EFI_STATUS Status;
859 UINTN ImageInfoSize;
860 EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;
861 UINT32 FmpImageInfoDescriptorVer;
862 UINT8 FmpImageInfoCount;
863 UINTN DescriptorSize;
864 UINT32 PackageVersion;
865 CHAR16 *PackageVersionName;
866
867 Status = gBS->HandleProtocol (
868 Handle,
869 &gEfiFirmwareManagementProtocolGuid,
870 (VOID **)&Fmp
871 );
872 if (EFI_ERROR (Status)) {
873 return 0;
874 }
875
876 ImageInfoSize = 0;
877 Status = Fmp->GetImageInfo (
878 Fmp,
879 &ImageInfoSize,
880 NULL,
881 NULL,
882 NULL,
883 NULL,
884 NULL,
885 NULL
886 );
887 if (Status != EFI_BUFFER_TOO_SMALL) {
888 return 0;
889 }
890
891 FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);
892 if (FmpImageInfoBuf == NULL) {
893 return 0;
894 }
895
896 PackageVersionName = NULL;
897 Status = Fmp->GetImageInfo (
898 Fmp,
899 &ImageInfoSize, // ImageInfoSize
900 FmpImageInfoBuf, // ImageInfo
901 &FmpImageInfoDescriptorVer, // DescriptorVersion
902 &FmpImageInfoCount, // DescriptorCount
903 &DescriptorSize, // DescriptorSize
904 &PackageVersion, // PackageVersion
905 &PackageVersionName // PackageVersionName
906 );
907 if (EFI_ERROR (Status)) {
908 FreePool (FmpImageInfoBuf);
909 return 0;
910 }
911
912 return FmpImageInfoDescriptorVer;
913}
914
926 IN EFI_HANDLE Handle,
928 IN UINTN PayloadIndex
929 )
930{
931 EFI_STATUS Status;
933 UINT8 *Image;
934 VOID *VendorCode;
935 CHAR16 *AbortReason;
937
938 Status = gBS->HandleProtocol (
939 Handle,
940 &gEfiFirmwareManagementProtocolGuid,
941 (VOID **)&Fmp
942 );
943 if (EFI_ERROR (Status)) {
944 return Status;
945 }
946
947 //
948 // Lookup Firmware Management Progress Protocol before SetImage() is called
949 // This is an optional protocol that may not be present on Handle.
950 //
951 Status = gBS->HandleProtocol (
952 Handle,
954 (VOID **)&mFmpProgress
955 );
956 if (EFI_ERROR (Status)) {
958 }
959
960 if (ImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {
961 Image = (UINT8 *)(ImageHeader + 1);
962 } else {
963 //
964 // If the EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER is version 1,
965 // Header should exclude UpdateHardwareInstance field, and
966 // ImageCapsuleSupport field if version is 2.
967 //
968 if (ImageHeader->Version == 1) {
969 Image = (UINT8 *)ImageHeader + OFFSET_OF (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, UpdateHardwareInstance);
970 } else {
971 Image = (UINT8 *)ImageHeader + OFFSET_OF (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER, ImageCapsuleSupport);
972 }
973 }
974
975 if (ImageHeader->UpdateVendorCodeSize == 0) {
976 VendorCode = NULL;
977 } else {
978 VendorCode = Image + ImageHeader->UpdateImageSize;
979 }
980
981 AbortReason = NULL;
982 DEBUG ((DEBUG_INFO, "Fmp->SetImage ...\n"));
983 DEBUG ((DEBUG_INFO, "ImageTypeId - %g, ", &ImageHeader->UpdateImageTypeId));
984 DEBUG ((DEBUG_INFO, "PayloadIndex - 0x%x, ", PayloadIndex));
985 DEBUG ((DEBUG_INFO, "ImageIndex - 0x%x ", ImageHeader->UpdateImageIndex));
986 if (ImageHeader->Version >= 2) {
987 DEBUG ((DEBUG_INFO, "(UpdateHardwareInstance - 0x%x)", ImageHeader->UpdateHardwareInstance));
988 if (ImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {
989 DEBUG ((DEBUG_INFO, "(ImageCapsuleSupport - 0x%x)", ImageHeader->ImageCapsuleSupport));
990 }
991 }
992
993 DEBUG ((DEBUG_INFO, "\n"));
994
995 //
996 // Before calling SetImage(), reset the progress bar to 0%
997 //
998 ProgressCallback = UpdateImageProgress;
999 Status = UpdateImageProgress (0);
1000 if (EFI_ERROR (Status)) {
1001 ProgressCallback = NULL;
1002 }
1003
1004 Status = Fmp->SetImage (
1005 Fmp,
1006 ImageHeader->UpdateImageIndex, // ImageIndex
1007 Image, // Image
1008 ImageHeader->UpdateImageSize, // ImageSize
1009 VendorCode, // VendorCode
1010 ProgressCallback, // Progress
1011 &AbortReason // AbortReason
1012 );
1013 //
1014 // Set the progress bar to 100% after returning from SetImage()
1015 //
1016 if (ProgressCallback != NULL) {
1017 UpdateImageProgress (100);
1018 }
1019
1020 DEBUG ((DEBUG_INFO, "Fmp->SetImage - %r\n", Status));
1021 if (AbortReason != NULL) {
1022 DEBUG ((DEBUG_ERROR, "%s\n", AbortReason));
1023 FreePool (AbortReason);
1024 }
1025
1026 //
1027 // Clear mFmpProgress after SetImage() returns
1028 //
1030
1031 return Status;
1032}
1033
1044 IN VOID *ImageBuffer,
1045 IN UINTN ImageSize
1046 )
1047{
1048 MEMMAP_DEVICE_PATH MemMapNode;
1049 EFI_STATUS Status;
1050 EFI_HANDLE ImageHandle;
1051 EFI_DEVICE_PATH_PROTOCOL *DriverDevicePath;
1052 UINTN ExitDataSize;
1053
1054 SetDevicePathNodeLength (&MemMapNode.Header, sizeof (MemMapNode));
1055 MemMapNode.Header.Type = HARDWARE_DEVICE_PATH;
1056 MemMapNode.Header.SubType = HW_MEMMAP_DP;
1057 MemMapNode.MemoryType = EfiBootServicesCode;
1058 MemMapNode.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)ImageBuffer;
1059 MemMapNode.EndingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)((UINT8 *)ImageBuffer + ImageSize - 1);
1060
1061 DriverDevicePath = AppendDevicePathNode (NULL, &MemMapNode.Header);
1062 if (DriverDevicePath == NULL) {
1063 return EFI_OUT_OF_RESOURCES;
1064 }
1065
1066 DEBUG ((DEBUG_INFO, "FmpCapsule: LoadImage ...\n"));
1067 Status = gBS->LoadImage (
1068 FALSE,
1070 DriverDevicePath,
1071 ImageBuffer,
1072 ImageSize,
1073 &ImageHandle
1074 );
1075 DEBUG ((DEBUG_INFO, "FmpCapsule: LoadImage - %r\n", Status));
1076 if (EFI_ERROR (Status)) {
1077 //
1078 // With EFI_SECURITY_VIOLATION retval, the Image was loaded and an ImageHandle was created
1079 // with a valid EFI_LOADED_IMAGE_PROTOCOL, but the image can not be started right now.
1080 // If the caller doesn't have the option to defer the execution of an image, we should
1081 // unload image for the EFI_SECURITY_VIOLATION to avoid resource leak.
1082 //
1083 if (Status == EFI_SECURITY_VIOLATION) {
1084 gBS->UnloadImage (ImageHandle);
1085 }
1086
1087 FreePool (DriverDevicePath);
1088 return Status;
1089 }
1090
1091 DEBUG ((DEBUG_INFO, "FmpCapsule: StartImage ...\n"));
1092 Status = gBS->StartImage (
1093 ImageHandle,
1094 &ExitDataSize,
1095 NULL
1096 );
1097 DEBUG ((DEBUG_INFO, "FmpCapsule: StartImage - %r\n", Status));
1098 if (EFI_ERROR (Status)) {
1099 DEBUG ((DEBUG_ERROR, "Driver Return Status = %r\n", Status));
1100 }
1101
1102 FreePool (DriverDevicePath);
1103 return Status;
1104}
1105
1116VOID
1118 IN EFI_HANDLE Handle OPTIONAL,
1119 IN EFI_CAPSULE_HEADER *CapsuleHeader,
1120 IN EFI_STATUS CapsuleStatus,
1121 IN UINTN PayloadIndex,
1123 IN CHAR16 *CapFileName OPTIONAL
1124 )
1125{
1126 EFI_STATUS Status;
1127 EFI_DEVICE_PATH_PROTOCOL *FmpDevicePath;
1128 UINT32 FmpImageInfoDescriptorVer;
1129 EFI_STATUS StatusEsrt;
1130 ESRT_MANAGEMENT_PROTOCOL *EsrtProtocol;
1131 EFI_SYSTEM_RESOURCE_ENTRY EsrtEntry;
1132
1133 FmpDevicePath = NULL;
1134 if (Handle != NULL) {
1135 gBS->HandleProtocol (
1136 Handle,
1137 &gEfiDevicePathProtocolGuid,
1138 (VOID **)&FmpDevicePath
1139 );
1140 }
1141
1143 CapsuleHeader,
1144 CapsuleStatus,
1145 PayloadIndex,
1146 ImageHeader,
1147 FmpDevicePath,
1148 CapFileName
1149 );
1150
1151 //
1152 // Update corresponding ESRT entry LastAttemp Status
1153 //
1154 Status = gBS->LocateProtocol (&gEsrtManagementProtocolGuid, NULL, (VOID **)&EsrtProtocol);
1155 if (EFI_ERROR (Status)) {
1156 return;
1157 }
1158
1159 if (Handle == NULL) {
1160 return;
1161 }
1162
1163 //
1164 // Update EsrtEntry For V1, V2 FMP instance.
1165 // V3 FMP ESRT cache will be synced up through SyncEsrtFmp interface
1166 //
1167 FmpImageInfoDescriptorVer = GetFmpImageInfoDescriptorVer (Handle);
1168 if (FmpImageInfoDescriptorVer < EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION) {
1169 StatusEsrt = EsrtProtocol->GetEsrtEntry (&ImageHeader->UpdateImageTypeId, &EsrtEntry);
1170 if (!EFI_ERROR (StatusEsrt)) {
1171 if (!EFI_ERROR (CapsuleStatus)) {
1173 } else {
1174 EsrtEntry.LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
1175 }
1176
1177 EsrtEntry.LastAttemptVersion = 0;
1178 EsrtProtocol->UpdateEsrtEntry (&EsrtEntry);
1179 }
1180 }
1181}
1182
1205 IN EFI_CAPSULE_HEADER *CapsuleHeader,
1206 IN CHAR16 *CapFileName OPTIONAL,
1207 OUT BOOLEAN *ResetRequired OPTIONAL
1208 )
1209{
1210 EFI_STATUS Status;
1213 UINT64 *ItemOffsetList;
1214 UINT32 ItemNum;
1215 UINTN Index;
1216 EFI_HANDLE *HandleBuffer;
1217 BOOLEAN *ResetRequiredBuffer;
1218 UINTN NumberOfHandles;
1219 UINTN DriverLen;
1220 UINT64 UpdateHardwareInstance;
1221 UINTN Index2;
1222 BOOLEAN NotReady;
1223 BOOLEAN Abort;
1224
1225 if (!IsFmpCapsuleGuid (&CapsuleHeader->CapsuleGuid)) {
1226 return ProcessFmpCapsuleImage ((EFI_CAPSULE_HEADER *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize), CapFileName, ResetRequired);
1227 }
1228
1229 NotReady = FALSE;
1230 Abort = FALSE;
1231
1232 DumpFmpCapsule (CapsuleHeader);
1233
1234 FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);
1235
1236 if (FmpCapsuleHeader->Version > EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION) {
1237 return EFI_INVALID_PARAMETER;
1238 }
1239
1240 ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);
1241
1242 ItemNum = FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount;
1243
1244 //
1245 // capsule in which driver count and payload count are both zero is not processed.
1246 //
1247 if (ItemNum == 0) {
1248 return EFI_SUCCESS;
1249 }
1250
1251 //
1252 // 1. Try to load & start all the drivers within capsule
1253 //
1254 for (Index = 0; Index < FmpCapsuleHeader->EmbeddedDriverCount; Index++) {
1255 if ((FmpCapsuleHeader->PayloadItemCount == 0) &&
1256 (Index == (UINTN)FmpCapsuleHeader->EmbeddedDriverCount - 1))
1257 {
1258 //
1259 // When driver is last element in the ItemOffsetList array, the driver size is calculated by reference CapsuleImageSize in EFI_CAPSULE_HEADER
1260 //
1261 DriverLen = CapsuleHeader->CapsuleImageSize - CapsuleHeader->HeaderSize - (UINTN)ItemOffsetList[Index];
1262 } else {
1263 DriverLen = (UINTN)ItemOffsetList[Index + 1] - (UINTN)ItemOffsetList[Index];
1264 }
1265
1266 Status = StartFmpImage (
1267 (UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index],
1268 DriverLen
1269 );
1270 if (EFI_ERROR (Status)) {
1271 DEBUG ((DEBUG_ERROR, "Driver Return Status = %r\n", Status));
1272 return Status;
1273 }
1274 }
1275
1276 //
1277 // 2. Route payload to right FMP instance
1278 //
1279 DEBUG ((DEBUG_INFO, "FmpCapsule: route payload to right FMP instance ...\n"));
1280
1281 DumpAllFmpInfo ();
1282
1283 //
1284 // Check all the payload entry in capsule payload list
1285 //
1286 for (Index = FmpCapsuleHeader->EmbeddedDriverCount; Index < ItemNum; Index++) {
1287 ImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);
1288
1289 UpdateHardwareInstance = 0;
1293 if (ImageHeader->Version >= 2) {
1294 UpdateHardwareInstance = ImageHeader->UpdateHardwareInstance;
1295 }
1296
1297 Status = GetFmpHandleBufferByType (
1298 &ImageHeader->UpdateImageTypeId,
1299 UpdateHardwareInstance,
1300 &NumberOfHandles,
1301 &HandleBuffer,
1302 &ResetRequiredBuffer
1303 );
1304 if (EFI_ERROR (Status) ||
1305 (HandleBuffer == NULL) ||
1306 (ResetRequiredBuffer == NULL))
1307 {
1308 NotReady = TRUE;
1310 NULL,
1311 CapsuleHeader,
1312 EFI_NOT_READY,
1313 Index - FmpCapsuleHeader->EmbeddedDriverCount,
1314 ImageHeader,
1315 CapFileName
1316 );
1317 continue;
1318 }
1319
1320 for (Index2 = 0; Index2 < NumberOfHandles; Index2++) {
1321 if (Abort) {
1323 HandleBuffer[Index2],
1324 CapsuleHeader,
1325 EFI_ABORTED,
1326 Index - FmpCapsuleHeader->EmbeddedDriverCount,
1327 ImageHeader,
1328 CapFileName
1329 );
1330 continue;
1331 }
1332
1333 Status = SetFmpImageData (
1334 HandleBuffer[Index2],
1335 ImageHeader,
1336 Index - FmpCapsuleHeader->EmbeddedDriverCount
1337 );
1338 if (Status != EFI_SUCCESS) {
1339 Abort = TRUE;
1340 } else {
1341 if (ResetRequired != NULL) {
1342 *ResetRequired |= ResetRequiredBuffer[Index2];
1343 }
1344 }
1345
1347 HandleBuffer[Index2],
1348 CapsuleHeader,
1349 Status,
1350 Index - FmpCapsuleHeader->EmbeddedDriverCount,
1351 ImageHeader,
1352 CapFileName
1353 );
1354 }
1355
1356 if (HandleBuffer != NULL) {
1357 FreePool (HandleBuffer);
1358 }
1359
1360 if (ResetRequiredBuffer != NULL) {
1361 FreePool (ResetRequiredBuffer);
1362 }
1363 }
1364
1365 if (NotReady) {
1366 return EFI_NOT_READY;
1367 }
1368
1369 //
1370 // always return SUCCESS to indicate this capsule is processed.
1371 // The status of SetImage is recorded in capsule result variable.
1372 //
1373 return EFI_SUCCESS;
1374}
1375
1384BOOLEAN
1386 IN EFI_CAPSULE_HEADER *CapsuleHeader
1387 )
1388{
1389 EFI_STATUS Status;
1390 EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry;
1391 UINTN Index;
1392 BOOLEAN EsrtGuidFound;
1393 EFI_CAPSULE_HEADER *NestedCapsuleHeader;
1394 UINTN NestedCapsuleSize;
1395 ESRT_MANAGEMENT_PROTOCOL *EsrtProtocol;
1397
1398 EsrtGuidFound = FALSE;
1399 if (mDxeCapsuleLibIsExitBootService) {
1400 if (mEsrtTable != NULL) {
1401 EsrtEntry = (EFI_SYSTEM_RESOURCE_ENTRY *)(mEsrtTable + 1);
1402 for (Index = 0; Index < mEsrtTable->FwResourceCount; Index++, EsrtEntry++) {
1403 if (CompareGuid (&EsrtEntry->FwClass, &CapsuleHeader->CapsuleGuid)) {
1404 EsrtGuidFound = TRUE;
1405 break;
1406 }
1407 }
1408 }
1409 } else {
1410 //
1411 // Check ESRT protocol
1412 //
1413 Status = gBS->LocateProtocol (&gEsrtManagementProtocolGuid, NULL, (VOID **)&EsrtProtocol);
1414 if (!EFI_ERROR (Status)) {
1415 Status = EsrtProtocol->GetEsrtEntry (&CapsuleHeader->CapsuleGuid, &Entry);
1416 if (!EFI_ERROR (Status)) {
1417 EsrtGuidFound = TRUE;
1418 }
1419 }
1420
1421 //
1422 // Check Firmware Management Protocols
1423 //
1424 if (!EsrtGuidFound) {
1425 Status = GetFmpHandleBufferByType (
1426 &CapsuleHeader->CapsuleGuid,
1427 0,
1428 NULL,
1429 NULL,
1430 NULL
1431 );
1432 if (!EFI_ERROR (Status)) {
1433 EsrtGuidFound = TRUE;
1434 }
1435 }
1436 }
1437
1438 if (!EsrtGuidFound) {
1439 return FALSE;
1440 }
1441
1442 //
1443 // Check nested capsule header
1444 // FMP GUID after ESRT one
1445 //
1446 NestedCapsuleHeader = (EFI_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);
1447 NestedCapsuleSize = (UINTN)CapsuleHeader + CapsuleHeader->CapsuleImageSize - (UINTN)NestedCapsuleHeader;
1448 if (NestedCapsuleSize < sizeof (EFI_CAPSULE_HEADER)) {
1449 return FALSE;
1450 }
1451
1452 if (!IsValidCapsuleHeader (NestedCapsuleHeader, NestedCapsuleSize)) {
1453 return FALSE;
1454 }
1455
1456 if (!IsFmpCapsuleGuid (&NestedCapsuleHeader->CapsuleGuid)) {
1457 return FALSE;
1458 }
1459
1460 DEBUG ((DEBUG_INFO, "IsNestedFmpCapsule\n"));
1461 return TRUE;
1462}
1463
1472BOOLEAN
1474 IN EFI_CAPSULE_HEADER *CapsuleHeader
1475 )
1476{
1477 if (IsFmpCapsuleGuid (&CapsuleHeader->CapsuleGuid)) {
1478 return TRUE;
1479 }
1480
1481 if (IsNestedFmpCapsule (CapsuleHeader)) {
1482 return TRUE;
1483 }
1484
1485 return FALSE;
1486}
1487
1500EFIAPI
1502 IN EFI_CAPSULE_HEADER *CapsuleHeader
1503 )
1504{
1505 //
1506 // check Display Capsule Guid
1507 //
1508 if (CompareGuid (&gWindowsUxCapsuleGuid, &CapsuleHeader->CapsuleGuid)) {
1509 return EFI_SUCCESS;
1510 }
1511
1512 //
1513 // Check capsule file name capsule
1514 //
1515 if (IsCapsuleNameCapsule (CapsuleHeader)) {
1516 return EFI_SUCCESS;
1517 }
1518
1519 if (IsFmpCapsule (CapsuleHeader)) {
1520 //
1521 // Fake capsule header is valid case in QueryCapsuleCpapbilities().
1522 //
1523 if (CapsuleHeader->HeaderSize == CapsuleHeader->CapsuleImageSize) {
1524 return EFI_SUCCESS;
1525 }
1526
1527 //
1528 // Check layout of FMP capsule
1529 //
1530 return ValidateFmpCapsule (CapsuleHeader, NULL);
1531 }
1532
1533 DEBUG ((DEBUG_ERROR, "Unknown Capsule Guid - %g\n", &CapsuleHeader->CapsuleGuid));
1534 return EFI_UNSUPPORTED;
1535}
1536
1552EFIAPI
1554 IN EFI_CAPSULE_HEADER *CapsuleHeader,
1555 IN CHAR16 *CapFileName OPTIONAL,
1556 OUT BOOLEAN *ResetRequired OPTIONAL
1557 )
1558{
1559 EFI_STATUS Status;
1560
1561 if (SupportCapsuleImage (CapsuleHeader) != EFI_SUCCESS) {
1562 RecordCapsuleStatusVariable (CapsuleHeader, EFI_UNSUPPORTED);
1563 return EFI_UNSUPPORTED;
1564 }
1565
1566 //
1567 // Display image in firmware update display capsule
1568 //
1569 if (CompareGuid (&gWindowsUxCapsuleGuid, &CapsuleHeader->CapsuleGuid)) {
1570 DEBUG ((DEBUG_INFO, "ProcessCapsuleImage for WindowsUxCapsule ...\n"));
1571 Status = DisplayCapsuleImage (CapsuleHeader);
1572 RecordCapsuleStatusVariable (CapsuleHeader, Status);
1573 return Status;
1574 }
1575
1576 //
1577 // Check FMP capsule layout
1578 //
1579 if (IsFmpCapsule (CapsuleHeader)) {
1580 DEBUG ((DEBUG_INFO, "ProcessCapsuleImage for FmpCapsule ...\n"));
1581 DEBUG ((DEBUG_INFO, "ValidateFmpCapsule ...\n"));
1582 Status = ValidateFmpCapsule (CapsuleHeader, NULL);
1583 DEBUG ((DEBUG_INFO, "ValidateFmpCapsule - %r\n", Status));
1584 if (EFI_ERROR (Status)) {
1585 RecordCapsuleStatusVariable (CapsuleHeader, Status);
1586 return Status;
1587 }
1588
1589 //
1590 // Process EFI FMP Capsule
1591 //
1592 DEBUG ((DEBUG_INFO, "ProcessFmpCapsuleImage ...\n"));
1593 Status = ProcessFmpCapsuleImage (CapsuleHeader, CapFileName, ResetRequired);
1594 DEBUG ((DEBUG_INFO, "ProcessFmpCapsuleImage - %r\n", Status));
1595
1596 return Status;
1597 }
1598
1599 return EFI_UNSUPPORTED;
1600}
1601
1615EFIAPI
1617 IN EFI_CAPSULE_HEADER *CapsuleHeader
1618 )
1619{
1620 return ProcessThisCapsuleImage (CapsuleHeader, NULL, NULL);
1621}
1622
1630VOID
1631EFIAPI
1633 IN EFI_EVENT Event,
1634 IN VOID *Context
1635 )
1636{
1637 mDxeCapsuleLibEndOfDxe = TRUE;
1638}
1639
1649EFIAPI
1651 IN EFI_HANDLE ImageHandle,
1652 IN EFI_SYSTEM_TABLE *SystemTable
1653 )
1654{
1655 EFI_STATUS Status;
1656
1657 Status = gBS->CreateEventEx (
1658 EVT_NOTIFY_SIGNAL,
1659 TPL_CALLBACK,
1661 NULL,
1662 &gEfiEndOfDxeEventGroupGuid,
1663 &mDxeCapsuleLibEndOfDxeEvent
1664 );
1665 ASSERT_EFI_ERROR (Status);
1666
1668
1669 return EFI_SUCCESS;
1670}
1671
1681EFIAPI
1683 IN EFI_HANDLE ImageHandle,
1684 IN EFI_SYSTEM_TABLE *SystemTable
1685 )
1686{
1687 EFI_STATUS Status;
1688
1689 //
1690 // Close the End of DXE event.
1691 //
1692 Status = gBS->CloseEvent (mDxeCapsuleLibEndOfDxeEvent);
1693 ASSERT_EFI_ERROR (Status);
1694
1695 return EFI_SUCCESS;
1696}
UINT64 UINTN
UINT8 EFIAPI CalculateCheckSum8(IN CONST UINT8 *Buffer, IN UINTN Length)
Definition: CheckSum.c:71
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
RETURN_STATUS EFIAPI TranslateBmpToGopBlt(IN VOID *BmpImage, IN UINTN BmpImageSize, IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **GopBlt, IN OUT UINTN *GopBltSize, OUT UINTN *PixelHeight, OUT UINTN *PixelWidth)
Definition: BmpSupportLib.c:80
#define HARDWARE_DEVICE_PATH
Definition: DevicePath.h:68
#define HW_MEMMAP_DP
Definition: DevicePath.h:109
UINT16 EFIAPI SetDevicePathNodeLength(IN OUT VOID *Node, IN UINTN Length)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePathNode(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL)
EFI_STATUS ValidateFmpCapsule(IN EFI_CAPSULE_HEADER *CapsuleHeader, OUT UINT16 *EmbeddedDriverCount OPTIONAL)
BOOLEAN IsFmpCapsuleGuid(IN EFI_GUID *CapsuleGuid)
EFI_STATUS StartFmpImage(IN VOID *ImageBuffer, IN UINTN ImageSize)
EFI_STATUS EFIAPI DxeCapsuleLibDestructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
UINT32 GetFmpImageInfoDescriptorVer(IN EFI_HANDLE Handle)
EFI_STATUS EFIAPI ProcessCapsuleImage(IN EFI_CAPSULE_HEADER *CapsuleHeader)
VOID EFIAPI DxeCapsuleLibEndOfDxe(IN EFI_EVENT Event, IN VOID *Context)
BOOLEAN IsFmpCapsule(IN EFI_CAPSULE_HEADER *CapsuleHeader)
VOID DumpFmpCapsule(IN EFI_CAPSULE_HEADER *CapsuleHeader)
EDKII_FIRMWARE_MANAGEMENT_PROGRESS_PROTOCOL * mFmpProgress
Definition: DxeCapsuleLib.c:50
BOOLEAN IsCapsuleNameCapsule(IN EFI_CAPSULE_HEADER *CapsuleHeader)
EFI_STATUS RecordCapsuleStatusVariable(IN EFI_CAPSULE_HEADER *CapsuleHeader, IN EFI_STATUS CapsuleStatus)
EFI_STATUS EFIAPI ProcessThisCapsuleImage(IN EFI_CAPSULE_HEADER *CapsuleHeader, IN CHAR16 *CapFileName OPTIONAL, OUT BOOLEAN *ResetRequired OPTIONAL)
BOOLEAN IsNestedFmpCapsule(IN EFI_CAPSULE_HEADER *CapsuleHeader)
EFI_STATUS EFIAPI DxeCapsuleLibConstructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
VOID RecordFmpCapsuleStatus(IN EFI_HANDLE Handle OPTIONAL, IN EFI_CAPSULE_HEADER *CapsuleHeader, IN EFI_STATUS CapsuleStatus, IN UINTN PayloadIndex, IN EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *ImageHeader, IN CHAR16 *CapFileName OPTIONAL)
EFI_STATUS SetFmpImageData(IN EFI_HANDLE Handle, IN EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *ImageHeader, IN UINTN PayloadIndex)
EFI_STATUS EFIAPI UpdateImageProgress(IN UINTN Completion)
EFI_STATUS GetFmpHandleBufferByType(IN EFI_GUID *UpdateImageTypeId, IN UINT64 UpdateHardwareInstance, OUT UINTN *NoHandles OPTIONAL, OUT EFI_HANDLE **HandleBuf OPTIONAL, OUT BOOLEAN **ResetRequiredBuf OPTIONAL)
EFI_STATUS ProcessFmpCapsuleImage(IN EFI_CAPSULE_HEADER *CapsuleHeader, IN CHAR16 *CapFileName OPTIONAL, OUT BOOLEAN *ResetRequired OPTIONAL)
EFI_STATUS RecordFmpCapsuleStatusVariable(IN EFI_CAPSULE_HEADER *CapsuleHeader, IN EFI_STATUS CapsuleStatus, IN UINTN PayloadIndex, IN EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *ImageHeader, IN EFI_DEVICE_PATH_PROTOCOL *FmpDevicePath OPTIONAL, IN CHAR16 *CapFileName OPTIONAL)
BOOLEAN IsValidCapsuleHeader(IN EFI_CAPSULE_HEADER *CapsuleHeader, IN UINT64 CapsuleSize)
VOID DumpAllFmpInfo(VOID)
EFI_STATUS EFIAPI SupportCapsuleImage(IN EFI_CAPSULE_HEADER *CapsuleHeader)
EFI_STATUS DisplayCapsuleImage(IN EFI_CAPSULE_HEADER *CapsuleHeader)
VOID InitCapsuleVariable(VOID)
VOID DumpFmpImageInfo(IN UINTN ImageInfoSize, IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo, IN UINT32 DescriptorVersion, IN UINT8 DescriptorCount, IN UINTN DescriptorSize, IN UINT32 PackageVersion, IN CHAR16 *PackageVersionName)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define IMAGE_ATTRIBUTE_RESET_REQUIRED
#define EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION
EFI_STATUS(EFIAPI * EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS)(IN UINTN Completion)
EFI_GUID gEdkiiFirmwareManagementProgressProtocolGuid
#define NULL
Definition: Base.h:319
#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
@ EfiBltBufferToVideo
#define LAST_ATTEMPT_STATUS_SUCCESS
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_SYSTEM_TABLE * gST
EFI_HANDLE gImageHandle
EFI_BOOT_SERVICES * gBS
@ EfiBootServicesCode
@ ByProtocol
Definition: UefiSpec.h:1518
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE * Mode
UINT32 CapsuleImageSize
Definition: UefiSpec.h:1698
EFI_GUID CapsuleGuid
Definition: UefiSpec.h:1682
EFI_HANDLE ConsoleOutHandle
Definition: UefiSpec.h:2059
Definition: Base.h:213
EFI_PHYSICAL_ADDRESS StartingAddress
Definition: DevicePath.h:123
EFI_PHYSICAL_ADDRESS EndingAddress
Definition: DevicePath.h:127