]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Nt32Pkg/FvbServicesRuntimeDxe/FWBlockService.c
Add FvNameGuid for FV extension header.
[mirror_edk2.git] / Nt32Pkg / FvbServicesRuntimeDxe / FWBlockService.c
index b6f3e1500c61ebb9daf55e6c4e6d0d95d2223674..8d1b7e3c28818a7a44abf26e4fd149ed6d3e57dd 100644 (file)
@@ -28,7 +28,6 @@ Revision History
 // The protocols, PPI and GUID defintions for this module\r
 //\r
 #include <Guid/EventGroup.h>\r
-#include <Protocol/FvbExtension.h>\r
 #include <Protocol/FirmwareVolumeBlock.h>\r
 #include <Guid/AlternateFvBlock.h>\r
 #include <Protocol/DevicePath.h>\r
@@ -45,6 +44,7 @@ Revision History
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DevicePathLib.h>\r
 \r
 #include "FWBlockService.h"\r
 \r
@@ -52,31 +52,55 @@ Revision History
 \r
 ESAL_FWB_GLOBAL         *mFvbModuleGlobal;\r
 \r
-EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate = {\r
-  FVB_DEVICE_SIGNATURE,\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
-          sizeof (MEMMAP_DEVICE_PATH),\r
-          0\r
-        }\r
-      },\r
-      EfiMemoryMappedIO,\r
-      0,\r
-      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_TYPE,\r
-      END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+      END_DEVICE_PATH_LENGTH,\r
+      0\r
+    }\r
+  }\r
+};\r
+\r
+FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate = {\r
+  {\r
+    {\r
+      MEDIA_DEVICE_PATH,\r
+      MEDIA_PIWG_FW_VOL_DP,\r
       {\r
-        sizeof (EFI_DEVICE_PATH_PROTOCOL),\r
-        0\r
+        (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)),\r
+        (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8)\r
       }\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 mFvbDeviceTemplate = {\r
+  FVB_DEVICE_SIGNATURE,\r
+  NULL,\r
   0,\r
   {\r
     FvbProtocolGetAttributes,\r
@@ -87,9 +111,6 @@ EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate = {
     FvbProtocolWrite,\r
     FvbProtocolEraseBlocks,\r
     NULL\r
-  },\r
-  {\r
-    FvbExtendProtocolEraseCustomBlockRange\r
   }\r
 };\r
 \r
@@ -607,113 +628,6 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
-EFI_STATUS\r
-FvbEraseCustomBlockRange (\r
-  IN UINTN                                Instance,\r
-  IN EFI_LBA                              StartLba,\r
-  IN UINTN                                OffsetStartLba,\r
-  IN EFI_LBA                              LastLba,\r
-  IN UINTN                                OffsetLastLba,\r
-  IN ESAL_FWB_GLOBAL                      *Global,\r
-  IN BOOLEAN                              Virtual\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-  Erases and initializes a specified range of a firmware volume\r
-\r
-Arguments:\r
-  Instance              - The FV instance to be erased\r
-  StartLba              - The starting logical block index to be erased\r
-  OffsetStartLba        - Offset into the starting block at which to\r
-                          begin erasing\r
-  LastLba               - The last logical block index to be erased\r
-  OffsetStartLba        - Offset into the last block at which to end erasing\r
-  Global                - Pointer to ESAL_FWB_GLOBAL that contains all\r
-                          instance data\r
-  Virtual               - Whether CPU is in virtual or physical mode\r
-\r
-Returns:\r
-  EFI_SUCCESS           - The firmware volume was erased successfully\r
-  EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state\r
-  EFI_DEVICE_ERROR      - The block device is not functioning correctly and\r
-                          could not be written. Firmware device may have been\r
-                          partially erased\r
-  EFI_INVALID_PARAMETER - Instance not found\r
-\r
---*/\r
-{\r
-  EFI_LBA Index;\r
-  UINTN   LbaSize;\r
-  UINTN   ScratchLbaSizeData;\r
-  EFI_STATUS Status;\r
-\r
-  //\r
-  // First LBA\r
-  //\r
-  Status = FvbGetLbaAddress (Instance, StartLba, NULL, &LbaSize, NULL, Global, Virtual);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Use the scratch space as the intermediate buffer to transfer data\r
-  // Back up the first LBA in scratch space.\r
-  //\r
-  FvbReadBlock (Instance, StartLba, 0, &LbaSize, Global->FvbScratchSpace[Virtual], Global, Virtual);\r
-\r
-  //\r
-  // erase now\r
-  //\r
-  FvbEraseBlock (Instance, StartLba, Global, Virtual);\r
-  ScratchLbaSizeData = OffsetStartLba;\r
-\r
-  //\r
-  // write the data back to the first block\r
-  //\r
-  if (ScratchLbaSizeData > 0) {\r
-    Status = FvbWriteBlock (Instance, StartLba, 0, &ScratchLbaSizeData, Global->FvbScratchSpace[Virtual], Global, Virtual);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-  //\r
-  // Middle LBAs\r
-  //\r
-  if (LastLba > (StartLba + 1)) {\r
-    for (Index = (StartLba + 1); Index <= (LastLba - 1); Index++) {\r
-      FvbEraseBlock (Instance, Index, Global, Virtual);\r
-    }\r
-  }\r
-  //\r
-  // Last LBAs, the same as first LBAs\r
-  //\r
-  if (LastLba > StartLba) {\r
-    Status = FvbGetLbaAddress (Instance, LastLba, NULL, &LbaSize, NULL, Global, Virtual);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-    FvbReadBlock (Instance, LastLba, 0, &LbaSize, Global->FvbScratchSpace[Virtual], Global, Virtual);\r
-    FvbEraseBlock (Instance, LastLba, Global, Virtual);\r
-  }\r
-\r
-  ScratchLbaSizeData = LbaSize - (OffsetLastLba + 1);\r
-  \r
-  if (ScratchLbaSizeData > 0) {\r
-    Status = FvbWriteBlock (\r
-              Instance,\r
-              LastLba,\r
-              (OffsetLastLba + 1),\r
-              &ScratchLbaSizeData,\r
-              Global->FvbScratchSpace[Virtual] + OffsetLastLba + 1,\r
-              Global,\r
-              Virtual\r
-              );\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
 EFI_STATUS\r
 FvbSetVolumeAttributes (\r
   IN UINTN                                  Instance,\r
@@ -1080,10 +994,10 @@ EFI_STATUS
 EFIAPI\r
 FvbProtocolWrite (\r
   IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL           *This,\r
-  IN CONST EFI_LBA                                      Lba,\r
-  IN CONST UINTN                                        Offset,\r
-  IN OUT UINTN                                    *NumBytes,\r
-  IN CONST UINT8                                        *Buffer\r
+  IN       EFI_LBA                                      Lba,\r
+  IN       UINTN                                        Offset,\r
+  IN OUT   UINTN                                    *NumBytes,\r
+  IN       UINT8                                        *Buffer\r
   )\r
 /*++\r
 \r
@@ -1172,56 +1086,7 @@ Returns:
 \r
   return FvbReadBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer, mFvbModuleGlobal, EfiGoneVirtual ());\r
 }\r
-//\r
-// FVB Extension Protocols\r
-//\r
-EFI_STATUS\r
-EFIAPI\r
-FvbExtendProtocolEraseCustomBlockRange (\r
-  IN EFI_FVB_EXTENSION_PROTOCOL           *This,\r
-  IN EFI_LBA                              StartLba,\r
-  IN UINTN                                OffsetStartLba,\r
-  IN EFI_LBA                              LastLba,\r
-  IN UINTN                                OffsetLastLba\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-  Erases and initializes a specified range of a firmware volume\r
-\r
-Arguments:\r
-  This                  - Calling context\r
-  StartLba              - The starting logical block index to be erased\r
-  OffsetStartLba        - Offset into the starting block at which to\r
-                          begin erasing\r
-  LastLba               - The last logical block index to be erased\r
-  OffsetStartLba        - Offset into the last block at which to end erasing\r
 \r
-Returns:\r
-  EFI_SUCCESS           - The firmware volume was erased successfully\r
-  EFI_ACCESS_DENIED     - The firmware volume is in the WriteDisabled state\r
-  EFI_DEVICE_ERROR      - The block device is not functioning correctly and\r
-                          could not be written. Firmware device may have been\r
-                          partially erased\r
-\r
---*/\r
-{\r
-  EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
-\r
-  FvbDevice = FVB_EXTEND_DEVICE_FROM_THIS (This);\r
-\r
-  return FvbEraseCustomBlockRange (\r
-          FvbDevice->Instance,\r
-          StartLba,\r
-          OffsetStartLba,\r
-          LastLba,\r
-          OffsetLastLba,\r
-          mFvbModuleGlobal,\r
-          EfiGoneVirtual ()\r
-          );\r
-}\r
-\r
-STATIC\r
 EFI_STATUS\r
 ValidateFvHeader (\r
   EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader\r
@@ -1256,6 +1121,7 @@ Returns:
       ) {\r
     return EFI_NOT_FOUND;\r
   }\r
+  \r
   //\r
   // Verify the header checksum\r
   //\r
@@ -1263,7 +1129,7 @@ Returns:
   Ptr           = (UINT16 *) FwVolHeader;\r
   Checksum      = 0;\r
   while (HeaderLength > 0) {\r
-    Checksum = Checksum + (*Ptr);\r
+    Checksum = (UINT16)(Checksum + (*Ptr));\r
     HeaderLength--;\r
     Ptr++;\r
   }\r
@@ -1272,6 +1138,13 @@ Returns:
     return EFI_NOT_FOUND;\r
   }\r
 \r
+  //\r
+  // PI specification defines the name guid of FV exists in extension header.\r
+  //\r
+  if (FwVolHeader->ExtHeaderOffset == 0) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  \r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -1302,8 +1175,6 @@ Returns:
   EFI_HANDLE                          FwbHandle;\r
   EFI_FW_VOL_BLOCK_DEVICE             *FvbDevice;\r
   EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *OldFwbInterface;\r
-  EFI_DEVICE_PATH_PROTOCOL            *TempFwbDevicePath;\r
-  FV_DEVICE_PATH                      TempFvbDevicePathData;\r
   UINT32                              MaxLbaSize;\r
   EFI_PHYSICAL_ADDRESS                BaseAddress;\r
   UINT64                              Length;\r
@@ -1421,7 +1292,7 @@ Returns:
         FwVolHeader->HeaderLength\r
         );\r
     }\r
-\r
+    \r
     FwhInstance->FvBase[FVB_PHYSICAL] = (UINTN) BaseAddress;\r
     FwhInstance->FvBase[FVB_VIRTUAL]  = (UINTN) BaseAddress;\r
 \r
@@ -1433,9 +1304,7 @@ Returns:
 \r
     for (PtrBlockMapEntry = FwVolHeader->BlockMap; PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) {\r
       //\r
-      // Get the maximum size of a block. The size will be used to allocate\r
-      // buffer for Scratch space, the intermediate buffer for FVB extension\r
-      // protocol\r
+      // Get the maximum size of a block.\r
       //\r
       if (MaxLbaSize < PtrBlockMapEntry->Length) {\r
         MaxLbaSize = PtrBlockMapEntry->Length;\r
@@ -1458,19 +1327,29 @@ Returns:
 \r
     FvbDevice->Instance = mFvbModuleGlobal->NumFv;\r
     mFvbModuleGlobal->NumFv++;\r
-\r
+    \r
+    \r
     //\r
     // Set up the devicepath\r
     //\r
-    FvbDevice->DevicePath.MemMapDevPath.StartingAddress = BaseAddress;\r
-    FvbDevice->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
+      FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate);\r
+      ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.StartingAddress = BaseAddress;\r
+      ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.EndingAddress   = BaseAddress + FwVolHeader->FvLength - 1;\r
+    } else {\r
+      FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate);\r
+      CopyGuid (\r
+        &((FV_PIWG_DEVICE_PATH *)FvbDevice->DevicePath)->FvDevPath.FvName, \r
+        (GUID *)(UINTN)(BaseAddress + FwVolHeader->ExtHeaderOffset)\r
+        );\r
+    }\r
     //\r
     // Find a handle with a matching device path that has supports FW Block protocol\r
     //\r
-    TempFwbDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) &TempFvbDevicePathData;\r
-    CopyMem (TempFwbDevicePath, &FvbDevice->DevicePath, sizeof (FV_DEVICE_PATH));\r
-    Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &TempFwbDevicePath, &FwbHandle);\r
+    Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &FvbDevice->DevicePath, &FwbHandle);\r
     if (EFI_ERROR (Status)) {\r
       //\r
       // LocateDevicePath fails so install a new interface and device path\r
@@ -1485,14 +1364,14 @@ Returns:
                       NULL\r
                       );\r
       ASSERT_EFI_ERROR (Status);\r
-    } else if (EfiIsDevicePathEnd (TempFwbDevicePath)) {\r
+    } else if (IsDevicePathEnd (FvbDevice->DevicePath)) {\r
       //\r
       // Device allready exists, so reinstall the FVB protocol\r
       //\r
       Status = gBS->HandleProtocol (\r
                       FwbHandle,\r
                       &gEfiFirmwareVolumeBlockProtocolGuid,\r
-                      &OldFwbInterface\r
+                      (VOID**)&OldFwbInterface\r
                       );\r
       ASSERT_EFI_ERROR (Status);\r
 \r
@@ -1510,13 +1389,9 @@ Returns:
       //\r
       ASSERT (FALSE);\r
     }\r
-    //\r
-    // Install FVB Extension Protocol on the same handle\r
-    //\r
+\r
     Status = gBS->InstallMultipleProtocolInterfaces (\r
                     &FwbHandle,\r
-                    &gEfiFvbExtensionProtocolGuid,\r
-                    &FvbDevice->FvbExtension,\r
                     &gEfiAlternateFvBlockGuid,\r
                     NULL,\r
                     NULL\r
@@ -1533,13 +1408,5 @@ Returns:
     FvHob.Raw = GET_NEXT_HOB (FvHob);\r
   }\r
 \r
-  //\r
-  // Allocate for scratch space, an intermediate buffer for FVB extention\r
-  //\r
-  mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL] = AllocateRuntimePool (MaxLbaSize);\r
-  ASSERT (mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL] != NULL);\r
-\r
-  mFvbModuleGlobal->FvbScratchSpace[FVB_VIRTUAL] = mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL];\r
-\r
   return EFI_SUCCESS;\r
 }\r