// 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
//\r
// The Library classes this module consumes\r
#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
\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_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
+ 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
FvbProtocolWrite,\r
FvbProtocolEraseBlocks,\r
NULL\r
- },\r
- {\r
- FvbExtendProtocolEraseCustomBlockRange\r
}\r
};\r
\r
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
\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
\r
--*/\r
{\r
- UINT16 *Ptr;\r
- UINT16 HeaderLength;\r
- UINT16 Checksum;\r
-\r
//\r
// Verify the header revision, header signature, length\r
// Length of FvBlock cannot be 2**64-1\r
) {\r
return EFI_NOT_FOUND;\r
}\r
+ \r
//\r
// Verify the header checksum\r
//\r
- HeaderLength = (UINT16) (FwVolHeader->HeaderLength / 2);\r
- Ptr = (UINT16 *) FwVolHeader;\r
- Checksum = 0;\r
- while (HeaderLength > 0) {\r
- Checksum = (UINT16)(Checksum + (*Ptr));\r
- HeaderLength--;\r
- Ptr++;\r
- }\r
-\r
- if (Checksum != 0) {\r
+ if (CalculateCheckSum16 ((UINT16 *) FwVolHeader, FwVolHeader->HeaderLength) != 0) {\r
return EFI_NOT_FOUND;\r
}\r
\r
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
UINTN NumOfBlocks;\r
EFI_PEI_HOB_POINTERS FvHob;\r
\r
- //\r
+ //\r
// Get the DXE services table\r
//\r
DxeServices = gDS;\r
FwVolHeader->HeaderLength\r
);\r
}\r
-\r
+ \r
FwhInstance->FvBase[FVB_PHYSICAL] = (UINTN) BaseAddress;\r
FwhInstance->FvBase[FVB_VIRTUAL] = (UINTN) BaseAddress;\r
\r
\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
\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
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
//\r
ASSERT (FALSE);\r
}\r
- //\r
- // Install FVB Extension Protocol on the same handle\r
- //\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &FwbHandle,\r
- &gEfiFvbExtensionProtocolGuid,\r
- &FvbDevice->FvbExtension,\r
- &gEfiAlternateFvBlockGuid,\r
- NULL,\r
- NULL\r
- );\r
-\r
- ASSERT_EFI_ERROR (Status);\r
\r
FwhInstance = (EFI_FW_VOL_INSTANCE *)\r
(\r
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