]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c
MdeModulePkg/DxeCapsuleLibFmp: Add progress bar support
[mirror_edk2.git] / MdeModulePkg / Library / DxeCapsuleLibFmp / DxeCapsuleLib.c
index 15dbc0021600c1c3e1ae968c1b9d2e2e3b6d07bb..f0226eafa57691be76e07cc1db6da36a5b716791 100644 (file)
@@ -45,6 +45,7 @@
 #include <Protocol/GraphicsOutput.h>\r
 #include <Protocol/EsrtManagement.h>\r
 #include <Protocol/FirmwareManagement.h>\r
+#include <Protocol/FirmwareManagementProgress.h>\r
 #include <Protocol/DevicePath.h>\r
 \r
 EFI_SYSTEM_RESOURCE_TABLE *mEsrtTable                  = NULL;\r
@@ -53,6 +54,8 @@ BOOLEAN                   mIsVirtualAddrConverted      = FALSE;
 BOOLEAN                   mDxeCapsuleLibEndOfDxe       = FALSE;\r
 EFI_EVENT                 mDxeCapsuleLibEndOfDxeEvent  = NULL;\r
 \r
+EDKII_FIRMWARE_MANAGEMENT_PROGRESS_PROTOCOL  *mFmpProgress = NULL;\r
+\r
 /**\r
   Initialize capsule related variables.\r
 **/\r
@@ -101,18 +104,17 @@ RecordFmpCapsuleStatusVariable (
   Function indicate the current completion progress of the firmware\r
   update. Platform may override with own specific progress function.\r
 \r
-  @param[in]  Completion    A value between 1 and 100 indicating the current completion progress of the firmware update\r
+  @param[in]  Completion  A value between 1 and 100 indicating the current\r
+                          completion progress of the firmware update\r
 \r
-  @retval EFI_SUCESS    Input capsule is a correct FMP capsule.\r
+  @retval EFI_SUCESS             The capsule update progress was updated.\r
+  @retval EFI_INVALID_PARAMETER  Completion is greater than 100%.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-Update_Image_Progress (\r
+UpdateImageProgress (\r
   IN UINTN  Completion\r
-  )\r
-{\r
-  return EFI_SUCCESS;\r
-}\r
+  );\r
 \r
 /**\r
   Return if this CapsuleGuid is a FMP capsule GUID or not.\r
@@ -250,7 +252,7 @@ ValidateFmpCapsule (
     //\r
     if (Index > 0) {\r
       if (ItemOffsetList[Index] <= ItemOffsetList[Index - 1]) {\r
-        DEBUG((DEBUG_ERROR, "ItemOffsetList[%d](0x%lx) < ItemOffsetList[%d](0x%x)\n", Index, ItemOffsetList[Index], Index, ItemOffsetList[Index - 1]));\r
+        DEBUG((DEBUG_ERROR, "ItemOffsetList[%d](0x%lx) < ItemOffsetList[%d](0x%x)\n", Index, ItemOffsetList[Index], Index - 1, ItemOffsetList[Index - 1]));\r
         return EFI_INVALID_PARAMETER;\r
       }\r
     }\r
@@ -330,8 +332,25 @@ DisplayCapsuleImage (
   UINTN                         Width;\r
   EFI_GRAPHICS_OUTPUT_PROTOCOL  *GraphicsOutput;\r
 \r
-  ImagePayload = (DISPLAY_DISPLAY_PAYLOAD *)(CapsuleHeader + 1);\r
-  PayloadSize = CapsuleHeader->CapsuleImageSize - sizeof(EFI_CAPSULE_HEADER);\r
+  //\r
+  // UX capsule doesn't have extended header entries.\r
+  //\r
+  if (CapsuleHeader->HeaderSize != sizeof (EFI_CAPSULE_HEADER)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  ImagePayload = (DISPLAY_DISPLAY_PAYLOAD *)((UINTN) CapsuleHeader + CapsuleHeader->HeaderSize);\r
+  //\r
+  // (CapsuleImageSize > HeaderSize) is guaranteed by IsValidCapsuleHeader().\r
+  //\r
+  PayloadSize = CapsuleHeader->CapsuleImageSize - CapsuleHeader->HeaderSize;\r
+\r
+  //\r
+  // Make sure the image payload at least contain the DISPLAY_DISPLAY_PAYLOAD header.\r
+  // Further size check is performed by the logic translating BMP to GOP BLT.\r
+  //\r
+  if (PayloadSize <= sizeof (DISPLAY_DISPLAY_PAYLOAD)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
 \r
   if (ImagePayload->Version != 1) {\r
     return EFI_UNSUPPORTED;\r
@@ -832,6 +851,19 @@ SetFmpImageData (
     return Status;\r
   }\r
 \r
+  //\r
+  // Lookup Firmware Management Progress Protocol before SetImage() is called\r
+  // This is an optional protocol that may not be present on Handle.\r
+  //\r
+  Status = gBS->HandleProtocol (\r
+                  Handle,\r
+                  &gEdkiiFirmwareManagementProgressProtocolGuid,\r
+                  (VOID **)&mFmpProgress\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    mFmpProgress = NULL;\r
+  }\r
+\r
   if (ImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {\r
     Image = (UINT8 *)(ImageHeader + 1);\r
   } else {\r
@@ -856,21 +888,37 @@ SetFmpImageData (
     DEBUG((DEBUG_INFO, "(UpdateHardwareInstance - 0x%x)", ImageHeader->UpdateHardwareInstance));\r
   }\r
   DEBUG((DEBUG_INFO, "\n"));\r
+\r
+  //\r
+  // Before calling SetImage(), reset the progress bar to 0%\r
+  //\r
+  UpdateImageProgress (0);\r
+\r
   Status = Fmp->SetImage(\r
                   Fmp,\r
                   ImageHeader->UpdateImageIndex,          // ImageIndex\r
                   Image,                                  // Image\r
                   ImageHeader->UpdateImageSize,           // ImageSize\r
                   VendorCode,                             // VendorCode\r
-                  Update_Image_Progress,                  // Progress\r
+                  UpdateImageProgress,                    // Progress\r
                   &AbortReason                            // AbortReason\r
                   );\r
+  //\r
+  // Set the progress bar to 100% after returning from SetImage()\r
+  //\r
+  UpdateImageProgress (100);\r
+\r
   DEBUG((DEBUG_INFO, "Fmp->SetImage - %r\n", Status));\r
   if (AbortReason != NULL) {\r
     DEBUG ((DEBUG_ERROR, "%s\n", AbortReason));\r
     FreePool(AbortReason);\r
   }\r
 \r
+  //\r
+  // Clear mFmpProgress after SetImage() returns\r
+  //\r
+  mFmpProgress = NULL;\r
+\r
   return Status;\r
 }\r
 \r