]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.c
Clean up DEC files:
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / FwVolBlock / FwVolBlock.c
index d35292899be034253db0c7a9fdb11095a0875bc2..27e9f9e0b1147a87c0c5f7bdb1ae0706e5667822 100644 (file)
@@ -1,11 +1,11 @@
 /** @file\r
-  Implementations for Firmware Volume Block protocol.  \r
-  \r
-  It consumes FV HOBs and creates read-lonly Firmare Volume Block protocol \r
+  Implementations for Firmware Volume Block protocol.\r
+\r
+  It consumes FV HOBs and creates read-only Firmare Volume Block protocol\r
   instances for each of them.\r
 \r
-Copyright (c) 2006 - 2008, Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2006 - 2008, 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
@@ -15,35 +15,59 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 \r
-#include <DxeMain.h>\r
-\r
+#include "DxeMain.h"\r
+#include "FwVolBlock.h"\r
 \r
-EFI_FW_VOL_BLOCK_DEVICE  mFwVolBlock = {\r
-  FVB_DEVICE_SIGNATURE,\r
-  NULL,\r
+FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate = {\r
   {\r
     {\r
+      HARDWARE_DEVICE_PATH,\r
+      HW_MEMMAP_DP,\r
       {\r
-        HARDWARE_DEVICE_PATH,\r
-        HW_MEMMAP_DP,\r
-        {\r
-          (UINT8)(sizeof (MEMMAP_DEVICE_PATH)),\r
-          (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8)\r
-        }\r
-      },\r
-      EfiMemoryMappedIO,\r
-      (EFI_PHYSICAL_ADDRESS) 0,\r
-      (EFI_PHYSICAL_ADDRESS) 0,\r
+        (UINT8)(sizeof (MEMMAP_DEVICE_PATH)),\r
+        (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8)\r
+      }\r
     },\r
+    EfiMemoryMappedIO,\r
+    (EFI_PHYSICAL_ADDRESS) 0,\r
+    (EFI_PHYSICAL_ADDRESS) 0,\r
+  },\r
+  {\r
+    END_DEVICE_PATH_TYPE,\r
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+    {\r
+      END_DEVICE_PATH_LENGTH,\r
+      0\r
+    }\r
+  }\r
+};\r
+\r
+FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate = {\r
+  {\r
     {\r
-      END_DEVICE_PATH_TYPE,\r
-      END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
-      { \r
-        END_DEVICE_PATH_LENGTH,\r
-        0\r
-      }      \r
+      MEDIA_DEVICE_PATH,\r
+      MEDIA_PIWG_FW_VOL_DP,\r
+      {\r
+        (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)),\r
+        (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8)\r
+      }\r
     },\r
+    { 0 }\r
   },\r
+  {\r
+    END_DEVICE_PATH_TYPE,\r
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+    {\r
+      END_DEVICE_PATH_LENGTH,\r
+      0\r
+    }\r
+  }\r
+};\r
+\r
+EFI_FW_VOL_BLOCK_DEVICE  mFwVolBlock = {\r
+  FVB_DEVICE_SIGNATURE,\r
+  NULL,\r
+  NULL,\r
   {\r
     FwVolBlockGetAttributes,\r
     (EFI_FVB_SET_ATTRIBUTES)FwVolBlockSetAttributes,\r
@@ -52,7 +76,7 @@ EFI_FW_VOL_BLOCK_DEVICE  mFwVolBlock = {
     FwVolBlockReadBlock,\r
     (EFI_FVB_WRITE)FwVolBlockWriteBlock,\r
     (EFI_FVB_ERASE_BLOCKS)FwVolBlockEraseBlock,\r
-    NULL      \r
+    NULL\r
   },\r
   0,\r
   NULL,\r
@@ -65,8 +89,8 @@ EFI_FW_VOL_BLOCK_DEVICE  mFwVolBlock = {
 /**\r
   Retrieves Volume attributes.  No polarity translations are done.\r
 \r
-  @param  This                   Calling context \r
-  @param  Attributes             output buffer which contains attributes \r
+  @param  This                   Calling context\r
+  @param  Attributes             output buffer which contains attributes\r
 \r
   @retval EFI_SUCCESS            The firmware volume attributes were returned.\r
 \r
@@ -75,17 +99,17 @@ EFI_STATUS
 EFIAPI\r
 FwVolBlockGetAttributes (\r
   IN CONST  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,\r
-  OUT       EFI_FVB_ATTRIBUTES                  *Attributes\r
+  OUT       EFI_FVB_ATTRIBUTES_2                *Attributes\r
   )\r
 {\r
   EFI_FW_VOL_BLOCK_DEVICE               *FvbDevice;\r
-  \r
+\r
   FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
 \r
   //\r
   // Since we are read only, it's safe to get attributes data from our in-memory copy.\r
   //\r
-  *Attributes = FvbDevice->FvbAttributes;\r
+  *Attributes = FvbDevice->FvbAttributes & ~EFI_FVB2_WRITE_STATUS;\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -95,13 +119,13 @@ FwVolBlockGetAttributes (
 /**\r
   Modifies the current settings of the firmware volume according to the input parameter.\r
 \r
-  @param  This                   Calling context \r
-  @param  Attributes             input buffer which contains attributes \r
+  @param  This                   Calling context\r
+  @param  Attributes             input buffer which contains attributes\r
 \r
-  @retval EFI_SUCCESS            The firmware volume attributes were returned. \r
-  @retval EFI_INVALID_PARAMETER  The attributes requested are in conflict with \r
-                                 the capabilities as declared in the firmware \r
-                                 volume header. \r
+  @retval EFI_SUCCESS            The firmware volume attributes were returned.\r
+  @retval EFI_INVALID_PARAMETER  The attributes requested are in conflict with\r
+                                 the capabilities as declared in the firmware\r
+                                 volume header.\r
   @retval EFI_UNSUPPORTED        Not supported.\r
 \r
 **/\r
@@ -109,7 +133,7 @@ EFI_STATUS
 EFIAPI\r
 FwVolBlockSetAttributes (\r
   IN CONST  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,\r
-  IN CONST  EFI_FVB_ATTRIBUTES                  *Attributes\r
+  IN CONST  EFI_FVB_ATTRIBUTES_2                *Attributes\r
   )\r
 {\r
   return EFI_UNSUPPORTED;\r
@@ -125,18 +149,18 @@ FwVolBlockSetAttributes (
   block of the firmware volume), the EraseBlock() function must return\r
   EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.\r
 \r
-  @param  This                   Calling context \r
-  @param  ...                    Starting LBA followed by Number of Lba to erase. \r
-                                 a -1 to terminate the list. \r
-\r
-  @retval EFI_SUCCESS            The erase request was successfully completed. \r
-  @retval EFI_ACCESS_DENIED      The firmware volume is in the WriteDisabled \r
-                                 state. \r
-  @retval EFI_DEVICE_ERROR       The block device is not functioning correctly \r
-                                 and could not be written. The firmware device \r
-                                 may have been partially erased. \r
-  @retval EFI_INVALID_PARAMETER  One or more of the LBAs listed in the variable \r
-                                 argument list do \r
+  @param  This                   Calling context\r
+  @param  ...                    Starting LBA followed by Number of Lba to erase.\r
+                                 a -1 to terminate the list.\r
+\r
+  @retval EFI_SUCCESS            The erase request was successfully completed.\r
+  @retval EFI_ACCESS_DENIED      The firmware volume is in the WriteDisabled\r
+                                 state.\r
+  @retval EFI_DEVICE_ERROR       The block device is not functioning correctly\r
+                                 and could not be written. The firmware device\r
+                                 may have been partially erased.\r
+  @retval EFI_INVALID_PARAMETER  One or more of the LBAs listed in the variable\r
+                                 argument list do\r
   @retval EFI_UNSUPPORTED        Not supported.\r
 \r
 **/\r
@@ -155,20 +179,20 @@ FwVolBlockEraseBlock (
 /**\r
   Read the specified number of bytes from the block to the input buffer.\r
 \r
-  @param  This                   Indicates the calling context. \r
-  @param  Lba                    The starting logical block index to read. \r
-  @param  Offset                 Offset into the block at which to begin reading. \r
-  @param  NumBytes               Pointer to a UINT32. At entry, *NumBytes \r
-                                 contains the total size of the buffer. At exit, \r
-                                 *NumBytes contains the total number of bytes \r
-                                 actually read. \r
-  @param  Buffer                 Pinter to a caller-allocated buffer that \r
-                                 contains the destine for the read. \r
-\r
-  @retval EFI_SUCCESS            The firmware volume was read successfully. \r
-  @retval EFI_BAD_BUFFER_SIZE    The read was attempted across an LBA boundary. \r
-  @retval EFI_ACCESS_DENIED      Access denied. \r
-  @retval EFI_DEVICE_ERROR       The block device is malfunctioning and could not \r
+  @param  This                   Indicates the calling context.\r
+  @param  Lba                    The starting logical block index to read.\r
+  @param  Offset                 Offset into the block at which to begin reading.\r
+  @param  NumBytes               Pointer to a UINT32. At entry, *NumBytes\r
+                                 contains the total size of the buffer. At exit,\r
+                                 *NumBytes contains the total number of bytes\r
+                                 actually read.\r
+  @param  Buffer                 Pinter to a caller-allocated buffer that\r
+                                 contains the destine for the read.\r
+\r
+  @retval EFI_SUCCESS            The firmware volume was read successfully.\r
+  @retval EFI_BAD_BUFFER_SIZE    The read was attempted across an LBA boundary.\r
+  @retval EFI_ACCESS_DENIED      Access denied.\r
+  @retval EFI_DEVICE_ERROR       The block device is malfunctioning and could not\r
                                  be read.\r
 \r
 **/\r
@@ -188,7 +212,7 @@ FwVolBlockReadBlock (
   UINTN                                 LbaStart;\r
   UINTN                                 NumOfBytesRead;\r
   UINTN                                 LbaIndex;\r
-  \r
+\r
   FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
 \r
   //\r
@@ -197,7 +221,7 @@ FwVolBlockReadBlock (
   if ((FvbDevice->FvbAttributes & EFI_FVB2_READ_STATUS) == 0) {\r
     return EFI_ACCESS_DENIED;\r
   }\r
-  \r
+\r
   LbaIndex = (UINTN) Lba;\r
   if (LbaIndex >= FvbDevice->NumBlocks) {\r
     //\r
@@ -206,7 +230,7 @@ FwVolBlockReadBlock (
     *NumBytes = 0;\r
     return EFI_BAD_BUFFER_SIZE;\r
   }\r
-  \r
+\r
   if (Offset > FvbDevice->LbaCache[LbaIndex].Length) {\r
     //\r
     // all exceed boundry, read nothing.\r
@@ -214,7 +238,7 @@ FwVolBlockReadBlock (
     *NumBytes = 0;\r
     return EFI_BAD_BUFFER_SIZE;\r
   }\r
-  \r
+\r
   NumOfBytesRead = *NumBytes;\r
   if (Offset + NumOfBytesRead > FvbDevice->LbaCache[LbaIndex].Length) {\r
     //\r
@@ -222,7 +246,7 @@ FwVolBlockReadBlock (
     //\r
     NumOfBytesRead = FvbDevice->LbaCache[LbaIndex].Length - Offset;\r
   }\r
-  \r
+\r
   LbaStart = FvbDevice->LbaCache[LbaIndex].Base;\r
   FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN) FvbDevice->BaseAddress);\r
   LbaOffset = (UINT8 *) FwVolHeader + LbaStart + Offset;\r
@@ -231,38 +255,38 @@ FwVolBlockReadBlock (
   // Perform read operation\r
   //\r
   CopyMem (Buffer, LbaOffset, NumOfBytesRead);\r
-  \r
+\r
   if (NumOfBytesRead == *NumBytes) {\r
     return EFI_SUCCESS;\r
   }\r
-    \r
+\r
   *NumBytes = NumOfBytesRead;\r
   return EFI_BAD_BUFFER_SIZE;\r
 }\r
-  \r
+\r
 \r
 \r
 /**\r
   Writes the specified number of bytes from the input buffer to the block.\r
 \r
-  @param  This                   Indicates the calling context. \r
-  @param  Lba                    The starting logical block index to write to. \r
-  @param  Offset                 Offset into the block at which to begin writing. \r
-  @param  NumBytes               Pointer to a UINT32. At entry, *NumBytes \r
-                                 contains the total size of the buffer. At exit, \r
-                                 *NumBytes contains the total number of bytes \r
-                                 actually written. \r
-  @param  Buffer                 Pinter to a caller-allocated buffer that \r
-                                 contains the source for the write. \r
-\r
-  @retval EFI_SUCCESS            The firmware volume was written successfully. \r
-  @retval EFI_BAD_BUFFER_SIZE    The write was attempted across an LBA boundary. \r
-                                 On output, NumBytes contains the total number of \r
-                                 bytes actually written. \r
-  @retval EFI_ACCESS_DENIED      The firmware volume is in the WriteDisabled \r
-                                 state. \r
-  @retval EFI_DEVICE_ERROR       The block device is malfunctioning and could not \r
-                                 be written. \r
+  @param  This                   Indicates the calling context.\r
+  @param  Lba                    The starting logical block index to write to.\r
+  @param  Offset                 Offset into the block at which to begin writing.\r
+  @param  NumBytes               Pointer to a UINT32. At entry, *NumBytes\r
+                                 contains the total size of the buffer. At exit,\r
+                                 *NumBytes contains the total number of bytes\r
+                                 actually written.\r
+  @param  Buffer                 Pinter to a caller-allocated buffer that\r
+                                 contains the source for the write.\r
+\r
+  @retval EFI_SUCCESS            The firmware volume was written successfully.\r
+  @retval EFI_BAD_BUFFER_SIZE    The write was attempted across an LBA boundary.\r
+                                 On output, NumBytes contains the total number of\r
+                                 bytes actually written.\r
+  @retval EFI_ACCESS_DENIED      The firmware volume is in the WriteDisabled\r
+                                 state.\r
+  @retval EFI_DEVICE_ERROR       The block device is malfunctioning and could not\r
+                                 be written.\r
   @retval EFI_UNSUPPORTED        Not supported.\r
 \r
 **/\r
@@ -278,16 +302,16 @@ FwVolBlockWriteBlock (
 {\r
   return EFI_UNSUPPORTED;\r
 }\r
\r
+\r
 \r
 \r
 /**\r
   Get Fvb's base address.\r
 \r
-  @param  This                   Indicates the calling context. \r
-  @param  Address                Fvb device base address. \r
+  @param  This                   Indicates the calling context.\r
+  @param  Address                Fvb device base address.\r
 \r
-  @retval EFI_SUCCESS            Successfully got Fvb's base address. \r
+  @retval EFI_SUCCESS            Successfully got Fvb's base address.\r
   @retval EFI_UNSUPPORTED        Not supported.\r
 \r
 **/\r
@@ -299,14 +323,14 @@ FwVolBlockGetPhysicalAddress (
   )\r
 {\r
   EFI_FW_VOL_BLOCK_DEVICE               *FvbDevice;\r
-  \r
+\r
   FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
-  \r
-  if (FvbDevice->FvbAttributes & EFI_FVB2_MEMORY_MAPPED) {\r
+\r
+  if ((FvbDevice->FvbAttributes & EFI_FVB2_MEMORY_MAPPED) != 0) {\r
     *Address = FvbDevice->BaseAddress;\r
     return EFI_SUCCESS;\r
   }\r
-  \r
+\r
   return EFI_UNSUPPORTED;\r
 }\r
 \r
@@ -315,17 +339,17 @@ FwVolBlockGetPhysicalAddress (
 /**\r
   Retrieves the size in bytes of a specific block within a firmware volume.\r
 \r
-  @param  This                   Indicates the calling context. \r
-  @param  Lba                    Indicates the block for which to return the \r
-                                 size. \r
-  @param  BlockSize              Pointer to a caller-allocated UINTN in which the \r
-                                 size of the block is returned. \r
-  @param  NumberOfBlocks         Pointer to a caller-allocated UINTN in which the \r
-                                 number of consecutive blocks starting with Lba \r
-                                 is returned. All blocks in this range have a \r
-                                 size of BlockSize. \r
-\r
-  @retval EFI_SUCCESS            The firmware volume base address is returned. \r
+  @param  This                   Indicates the calling context.\r
+  @param  Lba                    Indicates the block for which to return the\r
+                                 size.\r
+  @param  BlockSize              Pointer to a caller-allocated UINTN in which the\r
+                                 size of the block is returned.\r
+  @param  NumberOfBlocks         Pointer to a caller-allocated UINTN in which the\r
+                                 number of consecutive blocks starting with Lba\r
+                                 is returned. All blocks in this range have a\r
+                                 size of BlockSize.\r
+\r
+  @retval EFI_SUCCESS            The firmware volume base address is returned.\r
   @retval EFI_INVALID_PARAMETER  The requested LBA is out of range.\r
 \r
 **/\r
@@ -342,20 +366,20 @@ FwVolBlockGetBlockSize (
   EFI_FW_VOL_BLOCK_DEVICE               *FvbDevice;\r
   EFI_FV_BLOCK_MAP_ENTRY                *PtrBlockMapEntry;\r
   EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;\r
-  \r
+\r
   FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
-  \r
+\r
   //\r
   // Do parameter checking\r
   //\r
   if (Lba >= FvbDevice->NumBlocks) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+\r
   FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN)FvbDevice->BaseAddress);\r
-  \r
+\r
   PtrBlockMapEntry = FwVolHeader->BlockMap;\r
-  \r
+\r
   //\r
   // Search the block map for the given block\r
   //\r
@@ -368,13 +392,13 @@ FwVolBlockGetBlockSize (
       //\r
       break;\r
     }\r
-    \r
+\r
     PtrBlockMapEntry++;\r
   }\r
-  \r
+\r
   *BlockSize = PtrBlockMapEntry->Length;\r
   *NumberOfBlocks = TotalBlocks - (UINTN)Lba;\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -384,16 +408,16 @@ FwVolBlockGetBlockSize (
   This routine produces a firmware volume block protocol on a given\r
   buffer.\r
 \r
-  @param  BaseAddress            base address of the firmware volume image \r
-  @param  Length                 length of the firmware volume image \r
-  @param  ParentHandle           handle of parent firmware volume, if this image \r
-                                 came from an FV image file in another firmware \r
-                                 volume (ala capsules) \r
-  @param  FvProtocol             Firmware volume block protocol produced. \r
+  @param  BaseAddress            base address of the firmware volume image\r
+  @param  Length                 length of the firmware volume image\r
+  @param  ParentHandle           handle of parent firmware volume, if this image\r
+                                 came from an FV image file in another firmware\r
+                                 volume (ala capsules)\r
+  @param  FvProtocol             Firmware volume block protocol produced.\r
 \r
-  @retval EFI_VOLUME_CORRUPTED   Volume corrupted. \r
-  @retval EFI_OUT_OF_RESOURCES   No enough buffer to be allocated. \r
-  @retval EFI_SUCCESS            Successfully produced a FVB protocol on given \r
+  @retval EFI_VOLUME_CORRUPTED   Volume corrupted.\r
+  @retval EFI_OUT_OF_RESOURCES   No enough buffer to be allocated.\r
+  @retval EFI_SUCCESS            Successfully produced a FVB protocol on given\r
                                  buffer.\r
 \r
 **/\r
@@ -413,7 +437,7 @@ ProduceFVBProtocolOnBuffer (
   UINTN                         LinearOffset;\r
   UINT32                        FvAlignment;\r
   EFI_FV_BLOCK_MAP_ENTRY        *PtrBlockMapEntry;\r
-  \r
+\r
   FvAlignment = 0;\r
   FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN) BaseAddress;\r
   //\r
@@ -426,6 +450,9 @@ ProduceFVBProtocolOnBuffer (
   // Get FvHeader alignment\r
   //\r
   FvAlignment = 1 << ((FwVolHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
+  //\r
+  // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value. \r
+  //\r
   if (FvAlignment < 8) {\r
     FvAlignment = 8;\r
   }\r
@@ -436,9 +463,9 @@ ProduceFVBProtocolOnBuffer (
     return EFI_VOLUME_CORRUPTED;\r
   }\r
   //\r
-  // Allocate EFI_FW_VOL_BLOCK_DEVICE \r
+  // Allocate EFI_FW_VOL_BLOCK_DEVICE\r
   //\r
-  FvbDev = CoreAllocateCopyPool (sizeof (EFI_FW_VOL_BLOCK_DEVICE), &mFwVolBlock);\r
+  FvbDev = AllocateCopyPool (sizeof (EFI_FW_VOL_BLOCK_DEVICE), &mFwVolBlock);\r
   if (FvbDev == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
@@ -460,11 +487,12 @@ ProduceFVBProtocolOnBuffer (
   //\r
   // Second, allocate the cache\r
   //\r
-  FvbDev->LbaCache = CoreAllocateBootServicesPool (FvbDev->NumBlocks * sizeof (LBA_CACHE));\r
+  FvbDev->LbaCache = AllocatePool (FvbDev->NumBlocks * sizeof (LBA_CACHE));\r
   if (FvbDev->LbaCache == NULL) {\r
     CoreFreePool (FvbDev);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
+  \r
   //\r
   // Last, fill in the cache with the linear address of the blocks\r
   //\r
@@ -481,11 +509,34 @@ ProduceFVBProtocolOnBuffer (
   }\r
 \r
   //\r
-  // Set up the devicepath\r
+  // Judget whether FV name guid is produced in Fv extension header\r
   //\r
-  FvbDev->DevicePath.MemMapDevPath.StartingAddress = BaseAddress;\r
-  FvbDev->DevicePath.MemMapDevPath.EndingAddress = BaseAddress + FwVolHeader->FvLength - 1;\r
-\r
+  if (FwVolHeader->ExtHeaderOffset == 0) {\r
+    //\r
+    // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH\r
+    //\r
+    FvbDev->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate);\r
+    if (FvbDev->DevicePath == NULL) {\r
+      FreePool (FvbDev);\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    ((FV_MEMMAP_DEVICE_PATH *) FvbDev->DevicePath)->MemMapDevPath.StartingAddress = BaseAddress;\r
+    ((FV_MEMMAP_DEVICE_PATH *) FvbDev->DevicePath)->MemMapDevPath.EndingAddress   = BaseAddress + FwVolHeader->FvLength - 1;\r
+  } else {\r
+    //\r
+    // FV contains extension header, then produce MEDIA_FW_VOL_DEVICE_PATH\r
+    //\r
+    FvbDev->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate);\r
+    if (FvbDev->DevicePath == NULL) {\r
+      FreePool (FvbDev);\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    CopyGuid (\r
+      &((FV_PIWG_DEVICE_PATH *)FvbDev->DevicePath)->FvDevPath.FvName, \r
+      (GUID *)(UINTN)(BaseAddress + FwVolHeader->ExtHeaderOffset)\r
+      );\r
+  }\r
+  \r
   //\r
   //\r
   // Attach FvVolBlock Protocol to new handle\r
@@ -493,8 +544,7 @@ ProduceFVBProtocolOnBuffer (
   Status = CoreInstallMultipleProtocolInterfaces (\r
              &FvbDev->Handle,\r
              &gEfiFirmwareVolumeBlockProtocolGuid,     &FvbDev->FwVolBlockInstance,\r
-             &gEfiDevicePathProtocolGuid,              &FvbDev->DevicePath,\r
-             &gEfiFirmwareVolumeDispatchProtocolGuid,  NULL,\r
+             &gEfiDevicePathProtocolGuid,              FvbDev->DevicePath,\r
              NULL\r
              );\r
 \r
@@ -511,14 +561,12 @@ ProduceFVBProtocolOnBuffer (
 \r
 \r
 /**\r
-  This routine is the driver initialization entry point.  It initializes the\r
-  libraries, consumes FV hobs and NT_NON_MM_FV environment variable and\r
-  produces instances of FW_VOL_BLOCK_PROTOCOL as appropriate.\r
+  This routine consumes FV hobs and produces instances of FW_VOL_BLOCK_PROTOCOL as appropriate.\r
 \r
-  @param  ImageHandle            The image handle. \r
-  @param  SystemTable            The system table. \r
+  @param  ImageHandle            The image handle.\r
+  @param  SystemTable            The system table.\r
 \r
-  @retval EFI_SUCCESS            Successfully initialized firmware volume block \r
+  @retval EFI_SUCCESS            Successfully initialized firmware volume block\r
                                  driver.\r
 \r
 **/\r
@@ -539,7 +587,7 @@ FwVolBlockDriverInit (
     //\r
     // Produce an FVB protocol for it\r
     //\r
-    ProduceFVBProtocolOnBuffer (FvHob.FirmwareVolume->BaseAddress, FvHob.FirmwareVolume->Length, NULL, NULL);    \r
+    ProduceFVBProtocolOnBuffer (FvHob.FirmwareVolume->BaseAddress, FvHob.FirmwareVolume->Length, NULL, NULL);\r
     FvHob.Raw = GET_NEXT_HOB (FvHob);\r
   }\r
 \r
@@ -553,22 +601,23 @@ FwVolBlockDriverInit (
   particular, it can be called by BDS to process a single firmware\r
   volume found in a capsule.\r
 \r
-  @param  FvHeader               pointer to a firmware volume header \r
-  @param  Size                   the size of the buffer pointed to by FvHeader \r
-  @param  FVProtocolHandle       the handle on which a firmware volume protocol \r
-                                 was produced for the firmware volume passed in. \r
+  @param  FvHeader               pointer to a firmware volume header\r
+  @param  Size                   the size of the buffer pointed to by FvHeader\r
+  @param  FVProtocolHandle       the handle on which a firmware volume protocol\r
+                                 was produced for the firmware volume passed in.\r
 \r
-  @retval EFI_OUT_OF_RESOURCES   if an FVB could not be produced due to lack of  \r
-                                 system resources \r
-  @retval EFI_VOLUME_CORRUPTED   if the volume was corrupted \r
-  @retval EFI_SUCCESS            a firmware volume protocol was produced for the \r
+  @retval EFI_OUT_OF_RESOURCES   if an FVB could not be produced due to lack of\r
+                                 system resources\r
+  @retval EFI_VOLUME_CORRUPTED   if the volume was corrupted\r
+  @retval EFI_SUCCESS            a firmware volume protocol was produced for the\r
                                  firmware volume\r
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 CoreProcessFirmwareVolume (\r
   IN VOID                             *FvHeader,\r
-  IN UINTN                            Size, \r
+  IN UINTN                            Size,\r
   OUT EFI_HANDLE                      *FVProtocolHandle\r
   )\r
 {\r
@@ -576,18 +625,18 @@ CoreProcessFirmwareVolume (
   EFI_STATUS  Status;\r
 \r
   *FVProtocolHandle = NULL;\r
-  Status = ProduceFVBProtocolOnBuffer ( \r
-            (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, \r
-            (UINT64)Size, \r
-            NULL, \r
+  Status = ProduceFVBProtocolOnBuffer (\r
+            (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
+            (UINT64)Size,\r
+            NULL,\r
             FVProtocolHandle\r
             );\r
   //\r
   // Since in our implementation we use register-protocol-notify to put a\r
   // FV protocol on the FVB protocol handle, we can't directly verify that\r
   // the FV protocol was produced. Therefore here we will check the handle\r
-  // and make sure an FV protocol is on it. This indicates that all went \r
-  // well. Otherwise we have to assume that the volume was corrupted \r
+  // and make sure an FV protocol is on it. This indicates that all went\r
+  // well. Otherwise we have to assume that the volume was corrupted\r
   // somehow.\r
   //\r
   if (!EFI_ERROR(Status)) {\r