]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Library/DxeCapsuleLib/DxeCapsuleLib.c
IntelFrameworkModulePkg: Add DxeCapsuleLib
[mirror_edk2.git] / IntelFrameworkModulePkg / Library / DxeCapsuleLib / DxeCapsuleLib.c
diff --git a/IntelFrameworkModulePkg/Library/DxeCapsuleLib/DxeCapsuleLib.c b/IntelFrameworkModulePkg/Library/DxeCapsuleLib/DxeCapsuleLib.c
new file mode 100644 (file)
index 0000000..12c7272
--- /dev/null
@@ -0,0 +1,141 @@
+/** @file\r
+  Capsule Library instance to update capsule image to flash.\r
+\r
+  Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
+\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+#include <PiDxe.h>\r
+#include <Guid/Capsule.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DxeServicesTableLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/CapsuleLib.h>\r
+\r
+/**\r
+  Those capsules supported by the firmwares.\r
+\r
+  @param  CapsuleHeader    Points to a capsule header.\r
+\r
+  @retval EFI_SUCESS       Input capsule is supported by firmware.\r
+  @retval EFI_UNSUPPORTED  Input capsule is not supported by the firmware.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SupportCapsuleImage (\r
+  IN EFI_CAPSULE_HEADER *CapsuleHeader\r
+  )\r
+{\r
+  if (CompareGuid (&gEfiCapsuleGuid, &CapsuleHeader->CapsuleGuid)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  return EFI_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+  The firmware implements to process the capsule image.\r
+\r
+  @param  CapsuleHeader         Points to a capsule header.\r
+\r
+  @retval EFI_SUCESS            Process Capsule Image successfully.\r
+  @retval EFI_UNSUPPORTED       Capsule image is not supported by the firmware.\r
+  @retval EFI_VOLUME_CORRUPTED  FV volume in the capsule is corrupted.\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough memory.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ProcessCapsuleImage (\r
+  IN EFI_CAPSULE_HEADER *CapsuleHeader\r
+  )\r
+{\r
+  UINT32                       Length;\r
+  EFI_FIRMWARE_VOLUME_HEADER   *FvImage;\r
+  EFI_FIRMWARE_VOLUME_HEADER   *ProcessedFvImage;\r
+  EFI_STATUS                   Status;\r
+  EFI_HANDLE                   FvProtocolHandle;\r
+  UINT32                       FvAlignment;\r
+\r
+  FvImage = NULL;\r
+  ProcessedFvImage = NULL;\r
+  Status  = EFI_SUCCESS;\r
+\r
+  if (SupportCapsuleImage (CapsuleHeader) != EFI_SUCCESS) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Skip the capsule header, move to the Firware Volume\r
+  //\r
+  FvImage = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINT8 *) CapsuleHeader + CapsuleHeader->HeaderSize);\r
+  Length  = CapsuleHeader->CapsuleImageSize - CapsuleHeader->HeaderSize;\r
+\r
+  while (Length != 0) {\r
+    //\r
+    // Point to the next firmware volume header, and then\r
+    // call the DXE service to process it.\r
+    //\r
+    if (FvImage->FvLength > (UINTN) Length) {\r
+      //\r
+      // Notes: need to stuff this status somewhere so that the\r
+      // error can be detected at OS runtime\r
+      //\r
+      Status = EFI_VOLUME_CORRUPTED;\r
+      break;\r
+    }\r
+\r
+    FvAlignment = 1 << ((FvImage->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
+    //\r
+    // FvAlignment must be more than 8 bytes required by FvHeader structure.\r
+    //\r
+    if (FvAlignment < 8) {\r
+      FvAlignment = 8;\r
+    }\r
+    //\r
+    // Check FvImage Align is required.\r
+    //\r
+    if (((UINTN) FvImage % FvAlignment) == 0) {\r
+      ProcessedFvImage = FvImage;\r
+    } else {\r
+      //\r
+      // Allocate new aligned buffer to store FvImage.\r
+      //\r
+      ProcessedFvImage = (EFI_FIRMWARE_VOLUME_HEADER *) AllocateAlignedPages ((UINTN) EFI_SIZE_TO_PAGES (FvImage->FvLength), (UINTN) FvAlignment);\r
+      if (ProcessedFvImage == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        break;\r
+      }\r
+      CopyMem (ProcessedFvImage, FvImage, (UINTN) FvImage->FvLength);\r
+    }\r
+\r
+    Status = gDS->ProcessFirmwareVolume (\r
+                  (VOID *) ProcessedFvImage,\r
+                  (UINTN) ProcessedFvImage->FvLength,\r
+                  &FvProtocolHandle\r
+                  );\r
+    if (EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+    //\r
+    // Call the dispatcher to dispatch any drivers from the produced firmware volume\r
+    //\r
+    gDS->Dispatch ();\r
+    //\r
+    // On to the next FV in the capsule\r
+    //\r
+    Length -= (UINT32) FvImage->FvLength;\r
+    FvImage = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINT8 *) FvImage + FvImage->FvLength);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r