]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Enable UEFI firmware to support FMP capsule format.
authorczhang46 <czhang46>
Tue, 15 Oct 2013 01:31:49 +0000 (01:31 +0000)
committerczhang46 <czhang46@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 15 Oct 2013 01:31:49 +0000 (01:31 +0000)
signed-off-by : Chao Zhang <chao.b.zhang@intel.com>
reviewed-by   : Gao Liming <liming.gao@intel.com>
reviewed-by   : Yao Jiewen <Jiewen.yao@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14773 6f19259b-4bc3-4df7-8a09-765794883524

12 files changed:
IntelFrameworkModulePkg/Library/DxeCapsuleLib/DxeCapsuleLib.c
IntelFrameworkModulePkg/Library/DxeCapsuleLib/DxeCapsuleLib.inf
IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
IntelFrameworkModulePkg/Universal/BdsDxe/Bds.h
IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
IntelFrameworkModulePkg/Universal/BdsDxe/BdsEntry.c
IntelFrameworkModulePkg/Universal/BdsDxe/Capsules.c
MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c
MdePkg/Include/Guid/FmpCapsule.h [new file with mode: 0644]
MdePkg/Include/Uefi/UefiSpec.h
MdePkg/MdePkg.dec

index 6f5ab5b0f55e5ea7c0c6f7b14d746b66bf2b3420..104b1943697d1d555a09e1e21c9305d0bc413bbc 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
-  Capsule Library instance to update capsule image to flash.\r
+  Capsule Library instance to process capsule images.\r
 \r
-  Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2007 - 2013, 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
 \r
 **/\r
 #include <PiDxe.h>\r
+\r
 #include <Guid/Capsule.h>\r
+#include <Guid/FmpCapsule.h>\r
+\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
+#include <Library/GenericBdsLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DevicePathLib.h>\r
+\r
+#include <Protocol/FirmwareManagement.h>\r
+#include <Protocol/DevicePath.h>\r
+\r
+\r
+/**\r
+  Function indicate the current completion progress of the firmware\r
+  update. Platform may override with own specific progress function.\r
+\r
+  @param  Completion    A value between 1 and 100 indicating the current completion progress of the firmware update\r
+\r
+  @retval EFI_SUCESS    Input capsule is a correct FMP capsule.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Update_Image_Progress (\r
+   IN UINTN Completion\r
+)\r
+{\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Validate Fmp capsules layout.\r
+\r
+  @param  CapsuleHeader    Points to a capsule header.\r
+\r
+  @retval EFI_SUCESS                     Input capsule is a correct FMP capsule.\r
+  @retval EFI_INVALID_PARAMETER  Input capsule is not a correct FMP capsule.\r
+**/\r
+EFI_STATUS\r
+ValidateFmpCapsule (\r
+  IN EFI_CAPSULE_HEADER *CapsuleHeader\r
+  )\r
+{\r
+  EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER       *FmpCapsuleHeader;\r
+  UINT8                                        *EndOfCapsule;\r
+  EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *ImageHeader;\r
+  UINT8                                        *EndOfPayload;\r
+  UINT64                                       *ItemOffsetList;\r
+  UINT32                                       ItemNum;\r
+  UINTN                                        Index;\r
+\r
+  FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *) ((UINT8 *) CapsuleHeader + CapsuleHeader->HeaderSize);\r
+  EndOfCapsule     = (UINT8 *) CapsuleHeader + CapsuleHeader->CapsuleImageSize;\r
+\r
+  if (FmpCapsuleHeader->Version > EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);\r
+\r
+  ItemNum = FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount;\r
+\r
+  if (ItemNum == FmpCapsuleHeader->EmbeddedDriverCount) {\r
+    //\r
+    // No payload element \r
+    //\r
+    if (((UINT8 *)FmpCapsuleHeader + ItemOffsetList[ItemNum - 1]) < EndOfCapsule) {\r
+      return EFI_SUCCESS;\r
+    } else {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+\r
+  if (FmpCapsuleHeader->PayloadItemCount != 0) {\r
+    //\r
+    // Check if the last payload is within capsule image range\r
+    //\r
+    ImageHeader  = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[ItemNum - 1]);\r
+    EndOfPayload = (UINT8 *)(ImageHeader + 1) + ImageHeader->UpdateImageSize + ImageHeader->UpdateVendorCodeSize;\r
+  } else {\r
+    //\r
+    // No driver & payload element in FMP\r
+    //\r
+    EndOfPayload = (UINT8 *)(FmpCapsuleHeader + 1);\r
+  }\r
+\r
+  if (EndOfPayload != EndOfCapsule) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // All the address in ItemOffsetList must be stored in ascending order\r
+  //\r
+  if (ItemNum >= 2) {\r
+    for (Index = 0; Index < ItemNum - 1; Index++) {\r
+      if (ItemOffsetList[Index] >= ItemOffsetList[Index + 1]) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Process Firmware management protocol data capsule.  \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
+ProcessFmpCapsuleImage (\r
+  IN EFI_CAPSULE_HEADER *CapsuleHeader\r
+  )\r
+{\r
+  EFI_STATUS                                    Status;\r
+  EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER        *FmpCapsuleHeader;\r
+  UINT8                                         *EndOfCapsule;\r
+  EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER  *ImageHeader;\r
+  EFI_HANDLE                                    ImageHandle;\r
+  UINT64                                        *ItemOffsetList;\r
+  UINT32                                        ItemNum;\r
+  UINTN                                         Index;\r
+  UINTN                                         ExitDataSize;\r
+  EFI_HANDLE                                    *HandleBuffer;\r
+  EFI_FIRMWARE_MANAGEMENT_PROTOCOL              *Fmp;\r
+  UINTN                                         NumberOfHandles;\r
+  UINTN                                         DescriptorSize;\r
+  UINT8                                         FmpImageInfoCount;\r
+  UINT32                                        FmpImageInfoDescriptorVer;\r
+  UINTN                                         ImageInfoSize;\r
+  UINT32                                        PackageVersion;\r
+  CHAR16                                        *PackageVersionName;\r
+  CHAR16                                        *AbortReason;\r
+  EFI_FIRMWARE_IMAGE_DESCRIPTOR                 *FmpImageInfoBuf;\r
+  EFI_FIRMWARE_IMAGE_DESCRIPTOR                 *TempFmpImageInfo;\r
+  UINTN                                         DriverLen;\r
+  UINTN                                         Index1;\r
+  UINTN                                         Index2;\r
+  MEMMAP_DEVICE_PATH                            MemMapNode;\r
+  EFI_DEVICE_PATH_PROTOCOL                      *DriverDevicePath;\r
+\r
+  Status           = EFI_SUCCESS;\r
+  HandleBuffer     = NULL;\r
+  ExitDataSize     = 0;\r
+  DriverDevicePath = NULL;\r
+\r
+  FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *) ((UINT8 *) CapsuleHeader + CapsuleHeader->HeaderSize);\r
+  EndOfCapsule     = (UINT8 *) CapsuleHeader + CapsuleHeader->CapsuleImageSize;\r
+\r
+  if (FmpCapsuleHeader->Version > EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);\r
+\r
+  ItemNum = FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount;\r
+\r
+  //\r
+  // capsule in which driver count and payload count are both zero is not processed.\r
+  //\r
+  if (ItemNum == 0) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // 1. ConnectAll to ensure \r
+  //    All the communication protocol required by driver in capsule installed \r
+  //    All FMP protocols are installed\r
+  //\r
+  BdsLibConnectAll();\r
+\r
+\r
+  //\r
+  // 2. Try to load & start all the drivers within capsule \r
+  //\r
+  SetDevicePathNodeLength (&MemMapNode.Header, sizeof (MemMapNode));\r
+  MemMapNode.Header.Type     = HARDWARE_DEVICE_PATH;\r
+  MemMapNode.Header.SubType  = HW_MEMMAP_DP;\r
+  MemMapNode.MemoryType      = EfiBootServicesCode;\r
+  MemMapNode.StartingAddress = (EFI_PHYSICAL_ADDRESS)CapsuleHeader;\r
+  MemMapNode.EndingAddress   = (EFI_PHYSICAL_ADDRESS)((UINT8 *)CapsuleHeader + CapsuleHeader->CapsuleImageSize - 1);\r
+\r
+  DriverDevicePath = AppendDevicePathNode (NULL, &MemMapNode.Header);\r
+  if (DriverDevicePath == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  for (Index = 0; Index < FmpCapsuleHeader->EmbeddedDriverCount; Index++) {\r
+    if (FmpCapsuleHeader->PayloadItemCount == 0 && Index == FmpCapsuleHeader->EmbeddedDriverCount - 1) {\r
+      //\r
+      // When driver is last element in the ItemOffsetList array, the driver size is calculated by reference CapsuleImageSize in EFI_CAPSULE_HEADER\r
+      //\r
+      DriverLen = CapsuleHeader->CapsuleImageSize - CapsuleHeader->HeaderSize - ItemOffsetList[Index];\r
+    } else {\r
+      DriverLen = ItemOffsetList[Index + 1] - ItemOffsetList[Index];\r
+    }\r
+\r
+    Status = gBS->LoadImage(\r
+                    FALSE,\r
+                    gImageHandle,\r
+                    DriverDevicePath,\r
+                    (UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index],\r
+                    DriverLen,\r
+                    &ImageHandle\r
+                    );\r
+    if (EFI_ERROR(Status)) {\r
+      goto EXIT;\r
+    }\r
+\r
+    Status = gBS->StartImage(\r
+                    ImageHandle, \r
+                    &ExitDataSize, \r
+                    NULL\r
+                    );\r
+    if (EFI_ERROR(Status)) {\r
+      DEBUG ((DEBUG_ERROR, "Driver Return Status = %r\n", Status));\r
+      goto EXIT;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Connnect all again to connect drivers within capsule \r
+  //\r
+  if (FmpCapsuleHeader->EmbeddedDriverCount > 0) {\r
+    BdsLibConnectAll();\r
+  }\r
+\r
+  //\r
+  // 3. Route payload to right FMP instance\r
+  //\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiFirmwareManagementProtocolGuid,\r
+                  NULL,\r
+                  &NumberOfHandles,\r
+                  &HandleBuffer\r
+                  );\r
+\r
+  if (!EFI_ERROR(Status)) {\r
+    for(Index1 = 0; Index1 < NumberOfHandles; Index1++) {\r
+      Status = gBS->HandleProtocol(\r
+                      HandleBuffer[Index1],\r
+                      &gEfiFirmwareManagementProtocolGuid,\r
+                      &Fmp\r
+                      );\r
+      if (EFI_ERROR(Status)) {\r
+        continue;\r
+      }\r
+\r
+      ImageInfoSize = 0;\r
+      Status = Fmp->GetImageInfo (\r
+                      Fmp,\r
+                      &ImageInfoSize,\r
+                      NULL,\r
+                      NULL,\r
+                      NULL,\r
+                      NULL,\r
+                      NULL,\r
+                      NULL\r
+                      );\r
+      if (Status != EFI_BUFFER_TOO_SMALL) {\r
+        continue;\r
+      }\r
+\r
+      FmpImageInfoBuf = NULL;\r
+      FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);\r
+      if (FmpImageInfoBuf == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto EXIT;\r
+      }\r
+\r
+      PackageVersionName = NULL;\r
+      Status = Fmp->GetImageInfo (\r
+                      Fmp,\r
+                      &ImageInfoSize,               // ImageInfoSize\r
+                      FmpImageInfoBuf,              // ImageInfo\r
+                      &FmpImageInfoDescriptorVer,   // DescriptorVersion\r
+                      &FmpImageInfoCount,           // DescriptorCount\r
+                      &DescriptorSize,              // DescriptorSize\r
+                      &PackageVersion,              // PackageVersion\r
+                      &PackageVersionName           // PackageVersionName\r
+                      );\r
+\r
+      //\r
+      // If FMP GetInformation interface failed, skip this resource\r
+      //\r
+      if (EFI_ERROR(Status)) {\r
+        FreePool(FmpImageInfoBuf);\r
+        continue;\r
+      }\r
+\r
+      if (PackageVersionName != NULL) {\r
+        FreePool(PackageVersionName);\r
+      }\r
+\r
+      TempFmpImageInfo = FmpImageInfoBuf;\r
+      for (Index2 = 0; Index2 < FmpImageInfoCount; Index2++) {\r
+        //\r
+        // Check all the payload entry in capsule payload list \r
+        //\r
+        for (Index = FmpCapsuleHeader->EmbeddedDriverCount; Index < ItemNum; Index++) {\r
+          ImageHeader  = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);\r
+          if (CompareGuid(&ImageHeader->UpdateImageTypeId, &TempFmpImageInfo->ImageTypeId) &&\r
+              ImageHeader->UpdateImageIndex == TempFmpImageInfo->ImageIndex) {\r
+            AbortReason = NULL;\r
+            if (ImageHeader->UpdateVendorCodeSize == 0) {\r
+              Status = Fmp->SetImage(\r
+                              Fmp,\r
+                              TempFmpImageInfo->ImageIndex,           // ImageIndex\r
+                              (UINT8 *)(ImageHeader + 1),             // Image\r
+                              ImageHeader->UpdateImageSize,           // ImageSize\r
+                              NULL,                                   // VendorCode\r
+                              Update_Image_Progress,                  // Progress\r
+                              &AbortReason                            // AbortReason\r
+                              );\r
+            } else {\r
+              Status = Fmp->SetImage(\r
+                              Fmp,\r
+                              TempFmpImageInfo->ImageIndex,                                          // ImageIndex\r
+                              (UINT8 *)(ImageHeader + 1),                                            // Image\r
+                              ImageHeader->UpdateImageSize,                                          // ImageSize\r
+                              (UINT8 *)((UINT8 *) (ImageHeader + 1) + ImageHeader->UpdateImageSize), // VendorCode\r
+                              Update_Image_Progress,                                                 // Progress\r
+                              &AbortReason                                                           // AbortReason\r
+                              );\r
+            }\r
+            if (AbortReason != NULL) {\r
+              DEBUG ((EFI_D_ERROR, "%s\n", AbortReason));\r
+              FreePool(AbortReason);\r
+            }\r
+          }\r
+        }\r
+        //\r
+        // Use DescriptorSize to move ImageInfo Pointer to stay compatible with different ImageInfo version\r
+        //\r
+        TempFmpImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)TempFmpImageInfo + DescriptorSize);\r
+      }\r
+      FreePool(FmpImageInfoBuf);\r
+    }\r
+  }\r
+\r
+EXIT:\r
+\r
+  if (HandleBuffer != NULL) {\r
+    FreePool(HandleBuffer);\r
+  }\r
+\r
+  if (DriverDevicePath != NULL) {\r
+    FreePool(DriverDevicePath);\r
+  }\r
+\r
+  return Status;\r
+}\r
 \r
 /**\r
   Those capsules supported by the firmwares.\r
 \r
   @retval EFI_SUCESS       Input capsule is supported by firmware.\r
   @retval EFI_UNSUPPORTED  Input capsule is not supported by the firmware.\r
+  @retval EFI_INVALID_PARAMETER Input capsule layout is not correct\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -38,6 +395,13 @@ SupportCapsuleImage (
     return EFI_SUCCESS;\r
   }\r
 \r
+  if (CompareGuid (&gEfiFmpCapsuleGuid, &CapsuleHeader->CapsuleGuid)) {\r
+    //\r
+    // Check layout of FMP capsule\r
+    //\r
+    return ValidateFmpCapsule(CapsuleHeader);\r
+  }\r
+\r
   return EFI_UNSUPPORTED;\r
 }\r
 \r
@@ -72,6 +436,21 @@ ProcessCapsuleImage (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
+  //\r
+  // Check FMP capsule layout\r
+  //\r
+  if (CompareGuid (&gEfiFmpCapsuleGuid, &CapsuleHeader->CapsuleGuid)){\r
+    Status = ValidateFmpCapsule(CapsuleHeader);\r
+    if (EFI_ERROR(Status)) {\r
+      return Status;\r
+    }\r
+\r
+    //\r
+    // Press EFI FMP Capsule\r
+    //\r
+    return ProcessFmpCapsuleImage(CapsuleHeader);\r
+  }\r
+\r
   //\r
   // Skip the capsule header, move to the Firware Volume\r
   //\r
index c11d8f7628e021fd96b8c9bb60266957665d9758..ab66a6814461870d1c6aad950cf7b0c4ca817999 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # Capsule library instance for DXE_DRIVER, DXE_RUNTIME_DRIVER\r
 #\r
-# Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2013, 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
 \r
 [Packages]\r
   MdePkg/MdePkg.dec\r
-  IntelFrameworkPkg/IntelFrameworkPkg.dec\r
   MdeModulePkg/MdeModulePkg.dec\r
+  IntelFrameworkPkg/IntelFrameworkPkg.dec\r
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec\r
 \r
 [LibraryClasses]\r
   BaseMemoryLib\r
   DebugLib\r
   MemoryAllocationLib\r
   DxeServicesTableLib\r
+  GenericBdsLib\r
+  UefiBootServicesTableLib\r
+  DevicePathLib\r
+\r
+[Protocols]\r
+  gEfiFirmwareManagementProtocolGuid      # CONSUMES\r
 \r
 [Guids]\r
   gEfiCapsuleGuid                         # SOMETIMES_CONSUMED\r
-  
\ No newline at end of file
+  gEfiFmpCapsuleGuid                      # SOMETIMES_CONSUMED\r
index 545709c6eb35db74ef90be92717ad0cd89784740..2fb9916aa5334c2913611033ca4a5db9cf916e28 100644 (file)
@@ -22,7 +22,7 @@
   FILE_GUID                      = e405ec31-ccaa-4dd4-83e8-0aec01703f7e\r
   MODULE_TYPE                    = DXE_DRIVER\r
   VERSION_STRING                 = 1.0\r
-  LIBRARY_CLASS                  = GenericBdsLib|DXE_DRIVER UEFI_APPLICATION \r
+  LIBRARY_CLASS                  = GenericBdsLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION \r
   CONSTRUCTOR                    = GenericBdsLibConstructor\r
 \r
 #\r
@@ -78,6 +78,7 @@
   gLastEnumLangGuid                             ## SOMETIMES_PRODUCES ## Variable:L"LastEnumLang" (Platform language at last time enumeration.)\r
   gHdBootDevicePathVariablGuid                  ## SOMETIMES_PRODUCES ## Variable:L"HDDP" (The device path of Boot file on Hard device.)\r
   gBdsLibStringPackageGuid                      ## PRODUCES ## GUID (HII String PackageList Guid)\r
+  gEfiLegacyDevOrderVariableGuid                ## CONSUMES ## GUID\r
 \r
 [Protocols]\r
   gEfiSimpleFileSystemProtocolGuid              # PROTOCOL CONSUMES\r
index 0aba09c1bfb6db942eb3ca58a61ef1261095d759..e535bc21dadeeba8de60cecba69bc3729cef85e3 100644 (file)
@@ -36,6 +36,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Guid/BdsHii.h>\r
 #include <Guid/ConnectConInEvent.h>\r
 #include <Guid/Performance.h>\r
+#include <Guid/FmpCapsule.h>\r
 #include <Protocol/GenericMemoryTest.h>\r
 #include <Protocol/FormBrowser2.h>\r
 #include <Protocol/HiiConfigAccess.h>\r
index 2424a8a842636a093d773e286c625c801bf4fbd3..b10056491ef3eede047d17a3f809d9115f9e5d26 100644 (file)
   gDeviceManagerFormSetGuid                     ## SOMETIMES_PRODUCES ## DeviceManager HII Package\r
   gDriverHealthFormSetGuid                      ## SOMETIMES_PRODUCES ## DriverHealth HII Package\r
   gConnectConInEventGuid                        ## CONSUMES ## GUID (Connect ConIn Event)\r
+  gEfiFmpCapsuleGuid                            ## CONSUMES ## GUID (FMP Capsule)\r
 \r
 [Protocols]\r
   gEfiSimpleFileSystemProtocolGuid              ## PROTOCOL CONSUMES\r
index 77c88b0d241a5b77b5e609e44a04bb0d49b40968..33b3cc2dc4e4f46db244c64bb2e1b1c6aeb535c0 100644 (file)
@@ -403,7 +403,9 @@ BdsFormalizeEfiGlobalVariable (
   //\r
   // OS indicater support variable\r
   //\r
-  OsIndicationSupport = EFI_OS_INDICATIONS_BOOT_TO_FW_UI;\r
+  OsIndicationSupport = EFI_OS_INDICATIONS_BOOT_TO_FW_UI \\r
+                      | EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED;\r
+\r
   Status = gRT->SetVariable (\r
                   L"OsIndicationsSupported",\r
                   &gEfiGlobalVariableGuid,\r
index 07c12195fcf09c5f079eb5a64bf12d1c31dfb48a..6c7fc7ced4c996ebe3bef5449a36b26d4b8002fb 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   BDS routines to handle capsules.\r
 \r
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>\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
@@ -52,14 +52,16 @@ BdsProcessCapsules (
   VOID                        **CapsulePtr;\r
   VOID                        **CapsulePtrCache;\r
   EFI_GUID                    *CapsuleGuidCache; \r
+  BOOLEAN                     NeedReset;\r
 \r
-  CapsuleNumber = 0;\r
+  CapsuleNumber      = 0;\r
   CapsuleTotalNumber = 0;\r
-  CacheIndex   = 0;\r
-  CacheNumber  = 0;\r
-  CapsulePtr        = NULL;\r
-  CapsulePtrCache   = NULL;\r
-  CapsuleGuidCache  = NULL;\r
+  CacheIndex         = 0;\r
+  CacheNumber        = 0;\r
+  CapsulePtr         = NULL;\r
+  CapsulePtrCache    = NULL;\r
+  CapsuleGuidCache   = NULL;\r
+  NeedReset          = FALSE;\r
 \r
   //\r
   // We don't do anything else if the boot mode is not flash-update\r
@@ -190,6 +192,13 @@ BdsProcessCapsules (
   for (Index = 0; Index < CapsuleTotalNumber; Index++) {\r
     CapsuleHeader = (EFI_CAPSULE_HEADER*) CapsulePtr [Index];\r
     if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {\r
+      //\r
+      // Always reset system after all capsule processed if FMP capsule exist\r
+      //\r
+      if (CompareGuid (&gEfiFmpCapsuleGuid, &CapsuleHeader->CapsuleGuid)){\r
+        NeedReset = TRUE;\r
+      }\r
+\r
       //\r
       // Call capsule library to process capsule image.\r
       //\r
@@ -197,6 +206,19 @@ BdsProcessCapsules (
     }\r
   }\r
 \r
+  if (NeedReset) {\r
+    Print(L"Capsule Request Cold Reboot.\n");\r
+\r
+    for (Index = 5; Index > 0; Index--) {\r
+      Print(L"\rResetting system in %d seconds ...", Index);\r
+      gBS->Stall (1000000);\r
+    }\r
+\r
+    gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
+\r
+    CpuDeadLoop ();\r
+  }\r
+\r
   PlatformBdsLockNonUpdatableFlash ();\r
   \r
   //\r
index 3354fb7fc6ded946bc7a5a6af0febc28e6b725c3..7767e68345d66b60720eed2c0d557be42085650d 100644 (file)
@@ -5,7 +5,7 @@
 #  It installs the Capsule Architectural Protocol defined in PI1.0a to signify \r
 #  the capsule runtime services are ready.\r
 #  \r
-#  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\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
@@ -53,7 +53,8 @@
   UefiRuntimeLib\r
   BaseLib\r
   PrintLib\r
-  \r
+  BaseMemoryLib\r
+\r
 [LibraryClasses.X64]\r
   LockBoxLib\r
   UefiLib\r
@@ -62,6 +63,7 @@
 \r
 [Guids]\r
   gEfiCapsuleVendorGuid                         ## SOMETIMES_PRODUCED (Process across reset capsule image) ## Variable:L"CapsuleUpdateData" for capsule updated data\r
+  gEfiFmpCapsuleGuid                            ## FMP capsule GUID\r
 \r
 [Guids.X64]\r
   gEfiAcpiVariableGuid                          # ALWAYS_CONSUMED\r
index 190127693df6c2598215d980903deeffba7912fc..0861a64778db48abc97ad9354150a36d88f958a9 100644 (file)
@@ -19,6 +19,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include <Protocol/Capsule.h>\r
 #include <Guid/CapsuleVendor.h>\r
+#include <Guid/FmpCapsule.h>\r
 \r
 #include <Library/DebugLib.h>\r
 #include <Library/PcdLib.h>\r
@@ -29,7 +30,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/UefiRuntimeLib.h>\r
 #include <Library/BaseLib.h>\r
 #include <Library/PrintLib.h>\r
-\r
+#include <Library/BaseMemoryLib.h>\r
 //\r
 // Handle for the installation of Capsule Architecture Protocol.\r
 //\r
@@ -124,12 +125,23 @@ UpdateCapsule (
     if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET)) == CAPSULE_FLAGS_INITIATE_RESET) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
+\r
+    //\r
+    // Check FMP capsule flag \r
+    //\r
+    if (CompareGuid(&CapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)\r
+     && (CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0 ) {\r
+       return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
     //\r
     // Check Capsule image without populate flag by firmware support capsule function  \r
     //\r
-    if (((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) && \r
-        (SupportCapsuleImage (CapsuleHeader) != EFI_SUCCESS)) {\r
-      return EFI_UNSUPPORTED;\r
+    if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {\r
+      Status = SupportCapsuleImage (CapsuleHeader);\r
+      if (EFI_ERROR(Status)) {\r
+        return Status;\r
+      }\r
     }\r
   }\r
 \r
@@ -250,6 +262,7 @@ QueryCapsuleCapabilities (
   OUT EFI_RESET_TYPE       *ResetType\r
   )\r
 {\r
+  EFI_STATUS                Status;\r
   UINTN                     ArrayNumber;\r
   EFI_CAPSULE_HEADER        *CapsuleHeader;\r
   BOOLEAN                   NeedReset;\r
@@ -287,12 +300,23 @@ QueryCapsuleCapabilities (
     if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET)) == CAPSULE_FLAGS_INITIATE_RESET) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
+\r
+    //\r
+    // Check FMP capsule flag \r
+    //\r
+    if (CompareGuid(&CapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)\r
+     && (CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0 ) {\r
+       return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
     //\r
     // Check Capsule image without populate flag is supported by firmware\r
     //\r
-    if (((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) && \r
-        (SupportCapsuleImage (CapsuleHeader) != EFI_SUCCESS)) {\r
-      return EFI_UNSUPPORTED;\r
+    if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {\r
+      Status = SupportCapsuleImage (CapsuleHeader);\r
+      if (EFI_ERROR(Status)) {\r
+        return Status;\r
+      }\r
     }\r
   }\r
 \r
@@ -306,7 +330,7 @@ QueryCapsuleCapabilities (
       break;\r
     }\r
   }\r
-  \r
+\r
   if (NeedReset) {\r
     //\r
     //Check if the platform supports update capsule across a system reset\r
diff --git a/MdePkg/Include/Guid/FmpCapsule.h b/MdePkg/Include/Guid/FmpCapsule.h
new file mode 100644 (file)
index 0000000..ccc6b10
--- /dev/null
@@ -0,0 +1,89 @@
+/** @file\r
+  Guid & data structure used for Delivering Capsules Containing Updates to Firmware\r
+  Managment Protocol\r
+\r
+  Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\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
+  @par Revision Reference:\r
+  GUIDs defined in UEFI 2.4 spec.\r
+\r
+**/\r
+\r
+\r
+#ifndef _FMP_CAPSULE_GUID_H__\r
+#define _FMP_CAPSULE_GUID_H__\r
+\r
+//\r
+// This is the GUID of the capsule for Firmware Management Protocol.\r
+//\r
+#define EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID \\r
+  { \\r
+    0x6dcbd5ed, 0xe82d, 0x4c44, {0xbd, 0xa1, 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a } \\r
+  }\r
+\r
+#pragma pack(1)\r
+\r
+typedef struct {\r
+  UINT32 Version;\r
+\r
+  ///\r
+  /// The number of drivers included in the capsule and the number of corresponding\r
+  /// offsets stored in ItemOffsetList array. \r
+  ///\r
+  UINT16 EmbeddedDriverCount;\r
+\r
+  ///\r
+  /// The number of payload items included in the capsule and the number of\r
+  /// corresponding offsets stored in the ItemOffsetList array.\r
+  ///\r
+  UINT16 PayloadItemCount;\r
+\r
+  ///\r
+  /// Variable length array of dimension [EmbeddedDriverCount + PayloadItemCount]\r
+  /// containing offsets of each of the drivers and payload items contained within the capsule\r
+  ///\r
+  // UINT64 ItemOffsetList[];\r
+} EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER;\r
+\r
+typedef struct {\r
+  UINT32   Version;\r
+\r
+  ///\r
+  /// Used to identifiy device firmware targeted by this update. This guid is matched by\r
+  /// system firmware against ImageTypeId field within a EFI_FIRMWARE_IMAGE_DESCRIPTOR\r
+  ///\r
+  EFI_GUID UpdateImageTypeId;\r
+\r
+  ///\r
+  /// Passed as ImageIndex in call to EFI_FIRMWARE_MANAGEMENT_PROTOCOL.SetImage()\r
+  ///\r
+  UINT8    UpdateImageIndex;\r
+  UINT8    reserved_bytes[3];\r
+\r
+  ///\r
+  /// Size of the binary update image which immediately follows this structure\r
+  ///\r
+  UINT32   UpdateImageSize;\r
+\r
+  ///\r
+  ///Size of the VendorCode bytes which optionally immediately follow binary update image in the capsule\r
+  ///\r
+  UINT32   UpdateVendorCodeSize;\r
+} EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER;\r
+\r
+#pragma pack()\r
+\r
+\r
+#define EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION       0x00000001  \r
+#define EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION 0x00000001\r
+\r
+extern EFI_GUID gEfiFmpCapsuleGuid;\r
+\r
+#endif\r
index 45c3186fc284c75ee0531dc5ca241f7bedaa7e76..619246b614ff6f77019ced266f2cd36ce675f133 100644 (file)
@@ -1752,7 +1752,11 @@ EFI_STATUS
 //\r
 // Firmware should stop at a firmware user interface on next boot\r
 //\r
-#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI    0x0000000000000001\r
+#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI                    0x0000000000000001\r
+#define EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION             0x0000000000000002\r
+#define EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED  0x0000000000000004\r
+#define EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED            0x0000000000000008\r
+#define EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED     0x0000000000000010\r
 \r
 //\r
 // EFI Runtime Services Table\r
index 6f9dcf955081d4f62cda8cc6f1458ee3da172dc0..7c85b2804e17cd2f780778acfcdf4000ac87e0d6 100644 (file)
   gEfiHashAlgorithmSha1NoPadGuid = { 0x24c5dc2f, 0x53e2, 0x40ca, { 0x9e, 0xd6, 0xa5, 0xd9, 0xa4, 0x9f, 0x46, 0x3b }}\r
   gEfiHashAlgorithmSha256NoPadGuid = { 0x8628752a, 0x6cb7, 0x4814, { 0x96, 0xfc, 0x24, 0xa8, 0x15, 0xac, 0x22, 0x26 }}\r
 \r
+  #\r
+  # GUIDs defined in UEFI2.4\r
+  #\r
+  ## Include/Guid/FmpCapsule.h\r
+  gEfiFmpCapsuleGuid             =  { 0x6dcbd5ed, 0xe82d, 0x4c44, {0xbd, 0xa1, 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a }}\r
+\r
   #\r
   # GUID defined in PI1.0\r
   #\r