+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. 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
-Module Name:\r
-\r
- FWBlockService.c\r
- \r
-Abstract:\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include "FWBlockService.h"\r
-#include "EfiFlashMap.h"\r
-#include EFI_GUID_DEFINITION (FlashMapHob)\r
-\r
-ESAL_FWB_GLOBAL *mFvbModuleGlobal;\r
-\r
-EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate = {\r
- FVB_DEVICE_SIGNATURE,\r
- {\r
- {\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
- },\r
- {\r
- END_DEVICE_PATH_TYPE,\r
- END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
- {\r
- sizeof (EFI_DEVICE_PATH_PROTOCOL),\r
- 0\r
- }\r
- }\r
- },\r
- 0,\r
- {\r
- FvbProtocolGetAttributes,\r
- FvbProtocolSetAttributes,\r
- FvbProtocolGetPhysicalAddress,\r
- FvbProtocolGetBlockSize,\r
- FvbProtocolRead,\r
- FvbProtocolWrite,\r
- FvbProtocolEraseBlocks,\r
- NULL\r
- },\r
- {\r
- FvbExtendProtocolEraseCustomBlockRange\r
- }\r
-};\r
-\r
-EFI_DRIVER_ENTRY_POINT (FvbInitialize)\r
-\r
-\r
-VOID\r
-EFIAPI\r
-FvbVirtualddressChangeEvent (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Fixup internal data so that EFI and SAL can be call in virtual mode.\r
- Call the passed in Child Notify event and convert the mFvbModuleGlobal\r
- date items to there virtual address.\r
-\r
- mFvbModuleGlobal->FvInstance[FVB_PHYSICAL] - Physical copy of instance data\r
- mFvbModuleGlobal->FvInstance[FVB_VIRTUAL] - Virtual pointer to common \r
- instance data.\r
-\r
-Arguments:\r
-\r
- (Standard EFI notify event - EFI_EVENT_NOTIFY)\r
-\r
-Returns: \r
-\r
- None\r
-\r
---*/\r
-{\r
- EFI_FW_VOL_INSTANCE *FwhInstance;\r
- UINTN Index;\r
-\r
- EfiConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &mFvbModuleGlobal->FvInstance[FVB_VIRTUAL]);\r
-\r
- //\r
- // Convert the base address of all the instances\r
- //\r
- Index = 0;\r
- FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];\r
- while (Index < mFvbModuleGlobal->NumFv) {\r
- EfiConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &FwhInstance->FvBase[FVB_VIRTUAL]);\r
- EfiConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &FwhInstance->FvWriteBase[FVB_VIRTUAL]);\r
- FwhInstance = (EFI_FW_VOL_INSTANCE *) ((UINTN)((UINT8 *)FwhInstance) + FwhInstance->VolumeHeader.HeaderLength\r
- + (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER)));\r
- Index++;\r
- }\r
-\r
- EfiConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &mFvbModuleGlobal->FvbScratchSpace[FVB_VIRTUAL]);\r
- EfiConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &mFvbModuleGlobal);\r
-}\r
-\r
-VOID\r
-FvbMemWrite8 (\r
- IN UINT64 Dest,\r
- IN UINT8 Byte\r
- )\r
-{\r
- EfiMemWrite (EfiCpuIoWidthUint8, Dest, 1, &Byte);\r
-\r
- return ;\r
-}\r
-\r
-EFI_STATUS\r
-GetFvbInstance (\r
- IN UINTN Instance,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- OUT EFI_FW_VOL_INSTANCE **FwhInstance,\r
- IN BOOLEAN Virtual\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Retrieves the physical address of a memory mapped FV\r
-\r
-Arguments:\r
- Instance - The FV instance whose base address is going to be\r
- returned\r
- Global - Pointer to ESAL_FWB_GLOBAL that contains all\r
- instance data\r
- FwhInstance - The EFI_FW_VOL_INSTANCE fimrware instance structure\r
- Virtual - Whether CPU is in virtual or physical mode\r
-\r
-Returns: \r
- EFI_SUCCESS - Successfully returns\r
- EFI_INVALID_PARAMETER - Instance not found\r
-\r
---*/\r
-{\r
- EFI_FW_VOL_INSTANCE *FwhRecord;\r
-\r
- if (Instance >= Global->NumFv) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Find the right instance of the FVB private data\r
- //\r
- FwhRecord = Global->FvInstance[Virtual];\r
- while (Instance > 0) {\r
- FwhRecord = (EFI_FW_VOL_INSTANCE *) ((UINTN)((UINT8 *)FwhRecord) + FwhRecord->VolumeHeader.HeaderLength \r
- + (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER)));\r
- Instance--;\r
- }\r
-\r
- *FwhInstance = FwhRecord;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-FvbGetPhysicalAddress (\r
- IN UINTN Instance,\r
- OUT EFI_PHYSICAL_ADDRESS *Address,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Retrieves the physical address of a memory mapped FV\r
-\r
-Arguments:\r
- Instance - The FV instance whose base address is going to be\r
- returned\r
- Address - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS \r
- that on successful return, contains the base address\r
- of the firmware volume. \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 - Successfully returns\r
- EFI_INVALID_PARAMETER - Instance not found\r
-\r
---*/\r
-{\r
- EFI_FW_VOL_INSTANCE *FwhInstance;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Find the right instance of the FVB private data\r
- //\r
- Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);\r
- ASSERT_EFI_ERROR (Status);\r
- *Address = FwhInstance->FvBase[Virtual];\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-FvbGetVolumeAttributes (\r
- IN UINTN Instance,\r
- OUT EFI_FVB_ATTRIBUTES *Attributes,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Retrieves attributes, insures positive polarity of attribute bits, returns\r
- resulting attributes in output parameter\r
-\r
-Arguments:\r
- Instance - The FV instance whose attributes is going to be \r
- returned\r
- Attributes - Output buffer which contains attributes\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 - Successfully returns\r
- EFI_INVALID_PARAMETER - Instance not found\r
-\r
---*/\r
-{\r
- EFI_FW_VOL_INSTANCE *FwhInstance;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Find the right instance of the FVB private data\r
- //\r
- Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);\r
- ASSERT_EFI_ERROR (Status);\r
- *Attributes = FwhInstance->VolumeHeader.Attributes;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-FvbGetLbaAddress (\r
- IN UINTN Instance,\r
- IN EFI_LBA Lba,\r
- OUT UINTN *LbaAddress,\r
- OUT UINTN *LbaWriteAddress,\r
- OUT UINTN *LbaLength,\r
- OUT UINTN *NumOfBlocks,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Retrieves the starting address of an LBA in an FV\r
-\r
-Arguments:\r
- Instance - The FV instance which the Lba belongs to\r
- Lba - The logical block address\r
- LbaAddress - On output, contains the physical starting address \r
- of the Lba\r
- LbaWriteAddress - On output, contains the physical starting address\r
- of the Lba for writing\r
- LbaLength - On output, contains the length of the block\r
- NumOfBlocks - A pointer to a caller allocated UINTN in which the\r
- number of consecutive blocks starting with Lba is\r
- returned. All blocks in this range have a size of\r
- BlockSize\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 - Successfully returns\r
- EFI_INVALID_PARAMETER - Instance not found\r
-\r
---*/\r
-{\r
- UINT32 NumBlocks;\r
- UINT32 BlockLength;\r
- UINTN Offset;\r
- EFI_LBA StartLba;\r
- EFI_LBA NextLba;\r
- EFI_FW_VOL_INSTANCE *FwhInstance;\r
- EFI_FV_BLOCK_MAP_ENTRY *BlockMap;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Find the right instance of the FVB private data\r
- //\r
- Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- StartLba = 0;\r
- Offset = 0;\r
- BlockMap = &(FwhInstance->VolumeHeader.FvBlockMap[0]);\r
-\r
- //\r
- // Parse the blockmap of the FV to find which map entry the Lba belongs to\r
- //\r
- while (TRUE) {\r
- NumBlocks = BlockMap->NumBlocks;\r
- BlockLength = BlockMap->BlockLength;\r
-\r
- if (NumBlocks == 0 || BlockLength == 0) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- NextLba = StartLba + NumBlocks;\r
-\r
- //\r
- // The map entry found\r
- //\r
- if (Lba >= StartLba && Lba < NextLba) {\r
- Offset = Offset + (UINTN) MultU64x32 ((Lba - StartLba), BlockLength);\r
- if (LbaAddress) {\r
- *LbaAddress = FwhInstance->FvBase[Virtual] + Offset;\r
- }\r
-\r
- if (LbaWriteAddress) {\r
- *LbaWriteAddress = FwhInstance->FvWriteBase[Virtual] + Offset;\r
- }\r
-\r
- if (LbaLength) {\r
- *LbaLength = BlockLength;\r
- }\r
-\r
- if (NumOfBlocks) {\r
- *NumOfBlocks = (UINTN) (NextLba - Lba);\r
- }\r
-\r
- return EFI_SUCCESS;\r
- }\r
-\r
- StartLba = NextLba;\r
- Offset = Offset + NumBlocks * BlockLength;\r
- BlockMap++;\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-FvbReadBlock (\r
- IN UINTN Instance,\r
- IN EFI_LBA Lba,\r
- IN UINTN BlockOffset,\r
- IN OUT UINTN *NumBytes,\r
- IN UINT8 *Buffer,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Reads specified number of bytes into a buffer from the specified block\r
-\r
-Arguments:\r
- Instance - The FV instance to be read from\r
- Lba - The logical block address to be read from\r
- BlockOffset - Offset into the block at which to begin reading\r
- NumBytes - Pointer that on input contains the total size of\r
- the buffer. On output, it contains the total number\r
- of bytes read\r
- Buffer - Pointer to a caller allocated buffer that will be\r
- used to hold the data read\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 read successfully and \r
- contents are in Buffer\r
- EFI_BAD_BUFFER_SIZE - Read attempted across a LBA boundary. On output,\r
- NumBytes contains the total number of bytes returned\r
- in Buffer\r
- EFI_ACCESS_DENIED - The firmware volume is in the ReadDisabled state\r
- EFI_DEVICE_ERROR - The block device is not functioning correctly and \r
- could not be read\r
- EFI_INVALID_PARAMETER - Instance not found, or NumBytes, Buffer are NULL\r
-\r
---*/\r
-{\r
- EFI_FVB_ATTRIBUTES Attributes;\r
- UINTN LbaAddress;\r
- UINTN LbaLength;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Check for invalid conditions\r
- //\r
- if ((NumBytes == NULL) || (Buffer == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (*NumBytes == 0) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, NULL, &LbaLength, NULL, Global, Virtual);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Check if the FV is read enabled\r
- //\r
- FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);\r
-\r
- if ((Attributes & EFI_FVB_READ_STATUS) == 0) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- //\r
- // Perform boundary checks and adjust NumBytes\r
- //\r
- if (BlockOffset > LbaLength) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (LbaLength < (*NumBytes + BlockOffset)) {\r
- *NumBytes = (UINT32) (LbaLength - BlockOffset);\r
- Status = EFI_BAD_BUFFER_SIZE;\r
- }\r
-\r
- EfiMemRead (EfiCpuIoWidthUint8, LbaAddress + BlockOffset, (UINTN) *NumBytes, Buffer);\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-FlashFdWrite (\r
- IN UINTN WriteAddress,\r
- IN UINTN Address,\r
- IN OUT UINTN *NumBytes,\r
- IN UINT8 *Buffer,\r
- IN UINTN LbaLength\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Writes specified number of bytes from the input buffer to the address\r
-\r
-Arguments:\r
-\r
-Returns: \r
-\r
---*/\r
-{\r
- UINT8 *Src;\r
- UINT8 *Dest;\r
- UINTN Count;\r
- EFI_STATUS Status;\r
- UINT8 HubCommand;\r
- UINT8 HubData;\r
- UINTN RetryTimes;\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- EnableFvbWrites (TRUE);\r
-\r
- //\r
- // Grab the lock before entering critical code section\r
- //\r
- // bugbug\r
- // Commented out since locking mechanisium is not correctly implemented\r
- // on IA32 so that it will assert in runtime environment.\r
- //\r
- // EfiAcquireLock(&(FwhInstance->FvbDevLock));\r
- //\r
- // Write data one byte at a time, don't write if the src and dest bytes match\r
- //\r
- Dest = (UINT8 *) WriteAddress;\r
- Src = Buffer;\r
-\r
- for (Count = 0; Count < *NumBytes; Count++, Dest++, Src++) {\r
-\r
- HubCommand = FWH_WRITE_SETUP_COMMAND;\r
- FvbMemWrite8 ((UINT64) ((UINTN) Dest), HubCommand);\r
- FvbMemWrite8 ((UINT64) ((UINTN) Dest), *Src);\r
- HubCommand = FWH_READ_STATUS_COMMAND;\r
- FvbMemWrite8 ((UINT64) ((UINTN) Dest), HubCommand);\r
-\r
- //\r
- // Device error if time out occurs\r
- //\r
- RetryTimes = 0;\r
- while (RetryTimes < FVB_MAX_RETRY_TIMES) {\r
- EfiMemRead (EfiCpuIoWidthUint8, (UINT64) ((UINTN) Dest), 0x1, &HubData);\r
- if (HubData & FWH_WRITE_STATE_STATUS) {\r
- break;\r
- }\r
-\r
- RetryTimes++;\r
- }\r
-\r
- if (RetryTimes >= FVB_MAX_RETRY_TIMES) {\r
- *NumBytes = Count;\r
- Status = EFI_DEVICE_ERROR;\r
- break;\r
- }\r
- }\r
- //\r
- // Clear status register\r
- //\r
- HubCommand = FWH_CLEAR_STATUS_COMMAND;\r
- FvbMemWrite8 ((UINT64) ((UINTN) Dest), HubCommand);\r
-\r
- //\r
- // Issue read array command to return the FWH state machine to the\r
- // normal operational state\r
- //\r
- HubCommand = FWH_READ_ARRAY_COMMAND;\r
- FvbMemWrite8 ((UINT64) ((UINTN) WriteAddress), HubCommand);\r
- //\r
- // Flush the changed area to make the cache consistent\r
- //\r
- EfiCpuFlushCache (WriteAddress, *NumBytes);\r
-\r
- //\r
- // End of critical code section, release lock.\r
- //\r
- // EfiReleaseLock(&(FwhInstance->FvbDevLock));\r
- //\r
- EnableFvbWrites (FALSE);\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-FlashFdErase (\r
- IN UINTN WriteAddress,\r
- IN UINTN Address,\r
- IN UINTN LbaLength\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Erase a certain block from address LbaWriteAddress\r
-\r
-Arguments:\r
-\r
-Returns: \r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- UINT8 HubCommand;\r
- UINT8 HubData;\r
- UINTN RetryTimes;\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- EnableFvbWrites (TRUE);\r
-\r
- //\r
- // Grab the lock before entering critical code section\r
- //\r
- // EfiAcquireLock(&(FwhInstance->FvbDevLock));\r
- //\r
- // Send erase commands to FWH\r
- //\r
- HubCommand = FWH_BLOCK_ERASE_SETUP_COMMAND;\r
- FvbMemWrite8 ((UINT64) WriteAddress, HubCommand);\r
- HubCommand = FWH_BLOCK_ERASE_CONFIRM_COMMAND;\r
- FvbMemWrite8 ((UINT64) WriteAddress, HubCommand);\r
- HubCommand = FWH_READ_STATUS_COMMAND;\r
- FvbMemWrite8 ((UINT64) WriteAddress, HubCommand);\r
-\r
- //\r
- // Wait for completion. Indicated by FWH_WRITE_STATE_STATUS bit becoming 0\r
- // Device error if time out occurs\r
- //\r
- RetryTimes = 0;\r
- while (RetryTimes < FVB_MAX_RETRY_TIMES) {\r
- EfiMemRead (EfiCpuIoWidthUint8, (UINT64) WriteAddress, 0x1, &HubData);\r
- if (HubData & FWH_WRITE_STATE_STATUS) {\r
- break;\r
- }\r
-\r
- RetryTimes++;\r
- }\r
-\r
- if (RetryTimes >= FVB_MAX_RETRY_TIMES) {\r
- Status = EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // Clear status register\r
- //\r
- HubCommand = FWH_CLEAR_STATUS_COMMAND;\r
- FvbMemWrite8 ((UINT64) WriteAddress, HubCommand);\r
-\r
- //\r
- // Issue read array command to return the FWH state machine to the normal op state\r
- //\r
- HubCommand = FWH_READ_ARRAY_COMMAND;\r
- FvbMemWrite8 ((UINT64) ((UINTN) WriteAddress), HubCommand);\r
-\r
- EfiCpuFlushCache (Address, LbaLength);\r
-\r
- //\r
- // End of critical code section, release lock.\r
- //\r
- // EfiReleaseLock(&(FwhInstance->FvbDevLock));\r
- //\r
- EnableFvbWrites (FALSE);\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-FvbWriteBlock (\r
- IN UINTN Instance,\r
- IN EFI_LBA Lba,\r
- IN UINTN BlockOffset,\r
- IN OUT UINTN *NumBytes,\r
- IN UINT8 *Buffer,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Writes specified number of bytes from the input buffer to the block\r
-\r
-Arguments:\r
- Instance - The FV instance to be written to\r
- Lba - The starting logical block index to write to\r
- BlockOffset - Offset into the block at which to begin writing\r
- NumBytes - Pointer that on input contains the total size of\r
- the buffer. On output, it contains the total number\r
- of bytes actually written\r
- Buffer - Pointer to a caller allocated buffer that contains\r
- the source for the write\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 written successfully\r
- EFI_BAD_BUFFER_SIZE - Write attempted across a LBA boundary. On output,\r
- NumBytes contains the total number of bytes\r
- actually written\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\r
- EFI_INVALID_PARAMETER - Instance not found, or NumBytes, Buffer are NULL\r
-\r
---*/\r
-{\r
- EFI_FVB_ATTRIBUTES Attributes;\r
- UINTN LbaAddress;\r
- UINTN LbaWriteAddress;\r
- UINTN LbaLength;\r
- EFI_FW_VOL_INSTANCE *FwhInstance;\r
- EFI_STATUS Status;\r
- EFI_STATUS ReturnStatus;\r
-\r
- //\r
- // Find the right instance of the FVB private data\r
- //\r
- Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Writes are enabled in the init routine itself\r
- //\r
- if (!FwhInstance->WriteEnabled) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- //\r
- // Check for invalid conditions\r
- //\r
- if ((NumBytes == NULL) || (Buffer == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (*NumBytes == 0) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaWriteAddress, &LbaLength, NULL, Global, Virtual);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Check if the FV is write enabled\r
- //\r
- FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);\r
-\r
- if ((Attributes & EFI_FVB_WRITE_STATUS) == 0) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- //\r
- // Perform boundary checks and adjust NumBytes\r
- //\r
- if (BlockOffset > LbaLength) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (LbaLength < (*NumBytes + BlockOffset)) {\r
- *NumBytes = (UINT32) (LbaLength - BlockOffset);\r
- Status = EFI_BAD_BUFFER_SIZE;\r
- }\r
-\r
- ReturnStatus = FlashFdWrite (\r
- LbaWriteAddress + BlockOffset,\r
- LbaAddress,\r
- NumBytes,\r
- Buffer,\r
- LbaLength\r
- );\r
- if (EFI_ERROR (ReturnStatus)) {\r
- return ReturnStatus;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-FvbEraseBlock (\r
- IN UINTN Instance,\r
- IN EFI_LBA Lba,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Erases and initializes a firmware volume block\r
-\r
-Arguments:\r
- Instance - The FV instance to be erased\r
- Lba - The logical block index to be erased\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 erase request was successfully completed\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
-\r
- EFI_FVB_ATTRIBUTES Attributes;\r
- UINTN LbaAddress;\r
- UINTN LbaWriteAddress;\r
- EFI_FW_VOL_INSTANCE *FwhInstance;\r
- UINTN LbaLength;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Find the right instance of the FVB private data\r
- //\r
- Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Writes are enabled in the init routine itself\r
- //\r
- if (!FwhInstance->WriteEnabled) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- //\r
- // Check if the FV is write enabled\r
- //\r
- FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);\r
-\r
- if ((Attributes & EFI_FVB_WRITE_STATUS) == 0) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- //\r
- // Get the starting address of the block for erase. For debug reasons,\r
- // LbaWriteAddress may not be the same as LbaAddress.\r
- //\r
- Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaWriteAddress, &LbaLength, NULL, Global, Virtual);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- return FlashFdErase (\r
- LbaWriteAddress,\r
- LbaAddress,\r
- LbaLength\r
- );\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
-\r
- //\r
- // First LBA.\r
- //\r
- FvbGetLbaAddress (Instance, StartLba, NULL, NULL, &LbaSize, NULL, Global, Virtual);\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
- FvbWriteBlock (Instance, StartLba, 0, &ScratchLbaSizeData, Global->FvbScratchSpace[Virtual], Global, Virtual);\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
- FvbGetLbaAddress (Instance, LastLba, NULL, NULL, &LbaSize, NULL, Global, Virtual);\r
- FvbReadBlock (Instance, LastLba, 0, &LbaSize, Global->FvbScratchSpace[Virtual], Global, Virtual);\r
- FvbEraseBlock (Instance, LastLba, Global, Virtual);\r
- }\r
-\r
- ScratchLbaSizeData = LbaSize - (OffsetStartLba + 1);\r
-\r
- return FvbWriteBlock (\r
- Instance,\r
- LastLba,\r
- (OffsetLastLba + 1),\r
- &ScratchLbaSizeData,\r
- Global->FvbScratchSpace[Virtual],\r
- Global,\r
- Virtual\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-FvbSetVolumeAttributes (\r
- IN UINTN Instance,\r
- IN OUT EFI_FVB_ATTRIBUTES *Attributes,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Modifies the current settings of the firmware volume according to the \r
- input parameter, and returns the new setting of the volume\r
-\r
-Arguments:\r
- Instance - The FV instance whose attributes is going to be \r
- modified\r
- Attributes - On input, it is a pointer to EFI_FVB_ATTRIBUTES \r
- containing the desired firmware volume settings.\r
- On successful return, it contains the new settings\r
- of the firmware volume\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 - Successfully returns\r
- EFI_ACCESS_DENIED - The volume setting is locked and cannot be modified\r
- EFI_INVALID_PARAMETER - Instance not found, or The attributes requested are\r
- in conflict with the capabilities as declared in the\r
- firmware volume header\r
-\r
---*/\r
-{\r
- EFI_FW_VOL_INSTANCE *FwhInstance;\r
- EFI_FVB_ATTRIBUTES OldAttributes;\r
- EFI_FVB_ATTRIBUTES *AttribPtr;\r
- UINT32 Capabilities;\r
- UINT32 OldStatus;\r
- UINT32 NewStatus;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Find the right instance of the FVB private data\r
- //\r
- Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- AttribPtr = (EFI_FVB_ATTRIBUTES *) &(FwhInstance->VolumeHeader.Attributes);\r
- OldAttributes = *AttribPtr;\r
- Capabilities = OldAttributes & EFI_FVB_CAPABILITIES;\r
- OldStatus = OldAttributes & EFI_FVB_STATUS;\r
- NewStatus = *Attributes & EFI_FVB_STATUS;\r
-\r
- //\r
- // If firmware volume is locked, no status bit can be updated\r
- //\r
- if (OldAttributes & EFI_FVB_LOCK_STATUS) {\r
- if (OldStatus ^ NewStatus) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- }\r
- //\r
- // Test read disable\r
- //\r
- if ((Capabilities & EFI_FVB_READ_DISABLED_CAP) == 0) {\r
- if ((NewStatus & EFI_FVB_READ_STATUS) == 0) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
- //\r
- // Test read enable\r
- //\r
- if ((Capabilities & EFI_FVB_READ_ENABLED_CAP) == 0) {\r
- if (NewStatus & EFI_FVB_READ_STATUS) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
- //\r
- // Test write disable\r
- //\r
- if ((Capabilities & EFI_FVB_WRITE_DISABLED_CAP) == 0) {\r
- if ((NewStatus & EFI_FVB_WRITE_STATUS) == 0) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
- //\r
- // Test write enable\r
- //\r
- if ((Capabilities & EFI_FVB_WRITE_ENABLED_CAP) == 0) {\r
- if (NewStatus & EFI_FVB_WRITE_STATUS) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
- //\r
- // Test lock\r
- //\r
- if ((Capabilities & EFI_FVB_LOCK_CAP) == 0) {\r
- if (NewStatus & EFI_FVB_LOCK_STATUS) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
-\r
- *AttribPtr = (*AttribPtr) & (0xFFFFFFFF & (~EFI_FVB_STATUS));\r
- *AttribPtr = (*AttribPtr) | NewStatus;\r
- *Attributes = *AttribPtr;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-//\r
-// FVB protocol APIs\r
-//\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolGetPhysicalAddress (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- OUT EFI_PHYSICAL_ADDRESS *Address\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Retrieves the physical address of the device.\r
-\r
-Arguments:\r
-\r
- This - Calling context\r
- Address - Output buffer containing the address.\r
-\r
-Returns:\r
-\r
-Returns: \r
- EFI_SUCCESS - Successfully returns\r
-\r
---*/\r
-{\r
- EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
-\r
- FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
-\r
- return FvbGetPhysicalAddress (FvbDevice->Instance, Address, mFvbModuleGlobal, EfiGoneVirtual ());\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolGetBlockSize (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- IN EFI_LBA Lba,\r
- OUT UINTN *BlockSize,\r
- OUT UINTN *NumOfBlocks\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Retrieve the size of a logical block\r
-\r
-Arguments:\r
- This - Calling context\r
- Lba - Indicates which block to return the size for.\r
- BlockSize - A pointer to a caller allocated UINTN in which\r
- the size of the block is returned\r
- NumOfBlocks - a pointer to a caller allocated UINTN in which the\r
- number of consecutive blocks starting with Lba is\r
- returned. All blocks in this range have a size of\r
- BlockSize\r
-\r
-Returns: \r
- EFI_SUCCESS - The firmware volume was read successfully and \r
- contents are in Buffer\r
-\r
---*/\r
-{\r
- EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
-\r
- FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
-\r
- return FvbGetLbaAddress (\r
- FvbDevice->Instance,\r
- Lba,\r
- NULL,\r
- NULL,\r
- BlockSize,\r
- NumOfBlocks,\r
- mFvbModuleGlobal,\r
- EfiGoneVirtual ()\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolGetAttributes (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- OUT EFI_FVB_ATTRIBUTES *Attributes\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Retrieves Volume attributes. No polarity translations are done.\r
-\r
-Arguments:\r
- This - Calling context\r
- Attributes - output buffer which contains attributes\r
-\r
-Returns: \r
- EFI_SUCCESS - Successfully returns\r
-\r
---*/\r
-{\r
- EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
-\r
- FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
-\r
- return FvbGetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ());\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolSetAttributes (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- IN OUT EFI_FVB_ATTRIBUTES *Attributes\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Sets Volume attributes. No polarity translations are done.\r
-\r
-Arguments:\r
- This - Calling context\r
- Attributes - output buffer which contains attributes\r
-\r
-Returns: \r
- EFI_SUCCESS - Successfully returns\r
-\r
---*/\r
-{\r
- EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
-\r
- FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
-\r
- return FvbSetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ());\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolEraseBlocks (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- ... \r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- The EraseBlock() function erases one or more blocks as denoted by the \r
- variable argument list. The entire parameter list of blocks must be verified\r
- prior to erasing any blocks. If a block is requested that does not exist \r
- within the associated firmware volume (it has a larger index than the last \r
- block of the firmware volume), the EraseBlock() function must return\r
- EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.\r
-\r
-Arguments:\r
- This - Calling context\r
- ... - Starting LBA followed by Number of Lba to erase. \r
- a -1 to terminate the list.\r
-\r
-Returns: \r
- EFI_SUCCESS - The erase request was successfully completed\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
- EFI_FW_VOL_INSTANCE *FwhInstance;\r
- UINTN NumOfBlocks;\r
- VA_LIST args;\r
- EFI_LBA StartingLba;\r
- UINTN NumOfLba;\r
- EFI_STATUS Status;\r
-\r
- FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
-\r
- Status = GetFvbInstance (FvbDevice->Instance, mFvbModuleGlobal, &FwhInstance, EfiGoneVirtual ());\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- NumOfBlocks = FwhInstance->NumOfBlocks;\r
-\r
- VA_START (args, This);\r
-\r
- do {\r
- StartingLba = VA_ARG (args, EFI_LBA);\r
- if (StartingLba == EFI_LBA_LIST_TERMINATOR) {\r
- break;\r
- }\r
-\r
- NumOfLba = VA_ARG (args, UINT32);\r
-\r
- //\r
- // Check input parameters\r
- //\r
- if ((NumOfLba == 0) || ((StartingLba + NumOfLba) > NumOfBlocks)) {\r
- VA_END (args);\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- } while (1);\r
-\r
- VA_END (args);\r
-\r
- VA_START (args, This);\r
- do {\r
- StartingLba = VA_ARG (args, EFI_LBA);\r
- if (StartingLba == EFI_LBA_LIST_TERMINATOR) {\r
- break;\r
- }\r
-\r
- NumOfLba = VA_ARG (args, UINT32);\r
-\r
- while (NumOfLba > 0) {\r
- Status = FvbEraseBlock (FvbDevice->Instance, StartingLba, mFvbModuleGlobal, EfiGoneVirtual ());\r
- if (EFI_ERROR (Status)) {\r
- VA_END (args);\r
- return Status;\r
- }\r
-\r
- StartingLba++;\r
- NumOfLba--;\r
- }\r
-\r
- } while (1);\r
-\r
- VA_END (args);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolWrite (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- IN EFI_LBA Lba,\r
- IN UINTN Offset,\r
- IN OUT UINTN *NumBytes,\r
- IN UINT8 *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Writes data beginning at Lba:Offset from FV. The write terminates either\r
- when *NumBytes of data have been written, or when a block boundary is\r
- reached. *NumBytes is updated to reflect the actual number of bytes\r
- written. The write opertion does not include erase. This routine will\r
- attempt to write only the specified bytes. If the writes do not stick,\r
- it will return an error.\r
-\r
-Arguments:\r
- This - Calling context\r
- Lba - Block in which to begin write\r
- Offset - Offset in the block at which to begin write\r
- NumBytes - On input, indicates the requested write size. On\r
- output, indicates the actual number of bytes written\r
- Buffer - Buffer containing source data for the write.\r
-\r
-Returns: \r
- EFI_SUCCESS - The firmware volume was written successfully\r
- EFI_BAD_BUFFER_SIZE - Write attempted across a LBA boundary. On output,\r
- NumBytes contains the total number of bytes\r
- actually written\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\r
- EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL\r
-\r
---*/\r
-{\r
-\r
- EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
-\r
- FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
-\r
- return FvbWriteBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer, mFvbModuleGlobal, EfiGoneVirtual ());\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolRead (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- IN EFI_LBA Lba,\r
- IN UINTN Offset,\r
- IN OUT UINTN *NumBytes,\r
- IN UINT8 *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Reads data beginning at Lba:Offset from FV. The Read terminates either\r
- when *NumBytes of data have been read, or when a block boundary is\r
- reached. *NumBytes is updated to reflect the actual number of bytes\r
- written. The write opertion does not include erase. This routine will\r
- attempt to write only the specified bytes. If the writes do not stick,\r
- it will return an error.\r
-\r
-Arguments:\r
- This - Calling context\r
- Lba - Block in which to begin Read\r
- Offset - Offset in the block at which to begin Read\r
- NumBytes - On input, indicates the requested write size. On\r
- output, indicates the actual number of bytes Read\r
- Buffer - Buffer containing source data for the Read.\r
-\r
-Returns: \r
- EFI_SUCCESS - The firmware volume was read successfully and \r
- contents are in Buffer\r
- EFI_BAD_BUFFER_SIZE - Read attempted across a LBA boundary. On output,\r
- NumBytes contains the total number of bytes returned\r
- in Buffer\r
- EFI_ACCESS_DENIED - The firmware volume is in the ReadDisabled state\r
- EFI_DEVICE_ERROR - The block device is not functioning correctly and \r
- could not be read\r
- EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL\r
-\r
---*/\r
-{\r
-\r
- EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
-\r
- FvbDevice = FVB_DEVICE_FROM_THIS (This);\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
-Routine Description:\r
- Check the integrity of firmware volume header\r
-\r
-Arguments:\r
- FwVolHeader - A pointer to a firmware volume header\r
-\r
-Returns: \r
- EFI_SUCCESS - The firmware volume is consistent\r
- EFI_NOT_FOUND - The firmware volume has corrupted. So it is not an FV\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
- // HeaderLength cannot be an odd number\r
- //\r
- if ((FwVolHeader->Revision != EFI_FVH_REVISION) ||\r
- (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||\r
- (FwVolHeader->FvLength == ((UINTN) -1)) ||\r
- ((FwVolHeader->HeaderLength & 0x01) != 0)\r
- ) {\r
- return EFI_NOT_FOUND;\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 = *Ptr++;\r
- HeaderLength--;\r
- }\r
-\r
- if (Checksum != 0) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-BOOLEAN\r
-FvbGetCfiSupported (\r
- IN UINTN LbaAddress\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Check if the firmware volume is CFI typed flash\r
-\r
-Arguments:\r
- LbaAddress - The physical address of the firmware volume\r
-\r
-Returns: \r
- TRUE - CFI supported\r
- FALSE - CFI un-supported\r
-\r
---*/\r
-{\r
- UINT8 HubData[8];\r
- UINT8 HubCommand;\r
- BOOLEAN Supported;\r
-\r
- Supported = TRUE;\r
-\r
- //\r
- // Issue CFI Query (98h) to address 55h\r
- //\r
- HubCommand = CFI_QUERY;\r
- FvbMemWrite8 ((LbaAddress + 0x55), HubCommand);\r
- //\r
- // x8 device in 8-bit mode?\r
- //\r
- EfiMemRead (EfiCpuIoWidthUint8, (LbaAddress + 0x10), 0x3, &HubData);\r
- if (!EfiCompareMem (HubData, "QRY", 3)) {\r
- goto Done;\r
- }\r
- //\r
- // paired x8 devices?\r
- //\r
- EfiMemRead (EfiCpuIoWidthUint8, (LbaAddress + 0x20), 0x6, &HubData);\r
- if (!EfiCompareMem (HubData, "QQRRYY", 6)) {\r
- goto Done;\r
- }\r
- //\r
- // x16 device in 16-bit mode?\r
- //\r
- EfiMemRead (EfiCpuIoWidthUint8, (LbaAddress + 0x20), 0x4, &HubData);\r
- if ((!EfiCompareMem (&HubData[0], "R", 2)) && (!EfiCompareMem (&HubData[2], "Q", 2))) {\r
- goto Done;\r
- }\r
- //\r
- // x16 device in 8-bit mode?\r
- //\r
- EfiMemRead (EfiCpuIoWidthUint8, (LbaAddress + 0x20), 0x3, &HubData);\r
- if (!EfiCompareMem (HubData, "QQR", 3)) {\r
- goto Done;\r
- }\r
- //\r
- // 2 x16 devices in 8-bit mode (paired chip configuration)?\r
- //\r
- EfiMemRead (EfiCpuIoWidthUint8, (LbaAddress + 0x40), 0x6, &HubData);\r
- if (!EfiCompareMem (HubData, "QQQQRR", 6)) {\r
- goto Done;\r
- }\r
- //\r
- // x32 device in 8-bit mode\r
- //\r
- EfiMemRead (EfiCpuIoWidthUint8, (LbaAddress + 0x40), 0x5, &HubData);\r
- if (!EfiCompareMem (HubData, "QQQQR", 5)) {\r
- goto Done;\r
- }\r
- //\r
- // x32 device in 32-bit mode\r
- //\r
- if ((!EfiCompareMem (&HubData[0], "R", 2)) && (((UINT16) HubData[2]) == 0) && (HubData[4] == 'Q')) {\r
- goto Done;\r
- }\r
- //\r
- // If it got to here, CFI is not supported\r
- //\r
- Supported = FALSE;\r
-\r
-Done:\r
- //\r
- // Bug Fix #4071:\r
- // Issue command FWH_READ_ARRAY_COMMAND (0xff) at the end of this service to\r
- // guarantee that the FWH is back in read mode again\r
- //\r
- HubCommand = FWH_READ_ARRAY_COMMAND;\r
- FvbMemWrite8 (LbaAddress, HubCommand);\r
-\r
- return Supported;\r
-}\r
-\r
-EFI_STATUS\r
-GetFvbHeader (\r
- VOID **HobList,\r
- EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader,\r
- EFI_PHYSICAL_ADDRESS *BaseAddress,\r
- BOOLEAN *WriteBack\r
- )\r
-{\r
- EFI_STATUS Status;\r
- VOID *Buffer;\r
- EFI_FLASH_MAP_ENTRY_DATA *FlashMapEntry;\r
- EFI_FLASH_SUBAREA_ENTRY *FlashMapSubEntry;\r
-\r
- Status = EFI_SUCCESS;\r
- *FwVolHeader = NULL;\r
- *WriteBack = FALSE;\r
-\r
- Status = GetNextGuidHob (HobList, &gEfiFlashMapHobGuid, &Buffer, NULL);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- FlashMapEntry = (EFI_FLASH_MAP_ENTRY_DATA *) Buffer;\r
- FlashMapSubEntry = &FlashMapEntry->Entries[0];\r
- //\r
- // Check if it is a "FVB" area\r
- //\r
- if (!EfiCompareGuid (&FlashMapSubEntry->FileSystem, &gEfiFirmwareVolumeBlockProtocolGuid)) {\r
- return Status;\r
- }\r
- //\r
- // Check if it is a "real" flash\r
- //\r
- if (FlashMapSubEntry->Attributes != (EFI_FLASH_AREA_FV | EFI_FLASH_AREA_MEMMAPPED_FV)) {\r
- return Status;\r
- }\r
-\r
- *BaseAddress = FlashMapSubEntry->Base;\r
- DEBUG ((EFI_D_ERROR, "FlashMap HOB: BaseAddress = 0x%lx\n", *BaseAddress));\r
-\r
- *FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (*BaseAddress);\r
- Status = ValidateFvHeader (*FwVolHeader);\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Get FvbInfo\r
- //\r
- *WriteBack = TRUE;\r
- DEBUG ((EFI_D_ERROR, "BaseAddress = 0x%lx\n", BaseAddress));\r
- Status = GetFvbInfo (*BaseAddress, FwVolHeader);\r
- DEBUG ((EFI_D_ERROR, "Fvb: FV header invalid, GetFvbInfo - %r\n", Status));\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbInitialize (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- This function does common initialization for FVB services\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_FW_VOL_INSTANCE *FwhInstance;\r
- EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
- VOID *HobList;\r
- VOID *FirmwareVolumeHobList;\r
- UINT32 BufferSize;\r
- EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry;\r
- UINTN LbaAddress;\r
- UINT8 Data;\r
- UINTN BlockIndex2;\r
- BOOLEAN WriteEnabled;\r
- BOOLEAN WriteLocked;\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
- BOOLEAN CfiEnabled;\r
- EFI_PHYSICAL_ADDRESS BaseAddress;\r
- BOOLEAN WriteBack;\r
- UINTN NumOfBlocks;\r
- UINTN HeaderLength;\r
-\r
- INITIALIZE_SCRIPT (ImageHandle, SystemTable);\r
-\r
- EfiInitializeRuntimeDriverLib (ImageHandle, SystemTable, FvbVirtualddressChangeEvent);\r
-\r
- Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);\r
- HeaderLength = 0;\r
- //\r
- // No FV HOBs found\r
- //\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Allocate runtime services data for global variable, which contains\r
- // the private data of all firmware volume block instances\r
- //\r
- Status = gBS->AllocatePool (\r
- EfiRuntimeServicesData,\r
- sizeof (ESAL_FWB_GLOBAL),\r
- &mFvbModuleGlobal\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- EnablePlatformFvb ();\r
- EnableFvbWrites (TRUE);\r
-\r
- //\r
- // Calculate the total size for all firmware volume block instances\r
- //\r
- BufferSize = 0;\r
- FirmwareVolumeHobList = HobList;\r
- do {\r
- Status = GetFvbHeader (&FirmwareVolumeHobList, &FwVolHeader, &BaseAddress, &WriteBack);\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
-\r
- if (FwVolHeader) {\r
- BufferSize += (FwVolHeader->HeaderLength + sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER));\r
- }\r
- } while (TRUE);\r
-\r
- //\r
- // Only need to allocate once. There is only one copy of physical memory for\r
- // the private data of each FV instance. But in virtual mode or in physical\r
- // mode, the address of the the physical memory may be different.\r
- //\r
- Status = gBS->AllocatePool (\r
- EfiRuntimeServicesData,\r
- BufferSize,\r
- &mFvbModuleGlobal->FvInstance[FVB_PHYSICAL]\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Make a virtual copy of the FvInstance pointer.\r
- //\r
- FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];\r
- mFvbModuleGlobal->FvInstance[FVB_VIRTUAL] = FwhInstance;\r
-\r
- mFvbModuleGlobal->NumFv = 0;\r
- FirmwareVolumeHobList = HobList;\r
-\r
- MaxLbaSize = 0;\r
-\r
- //\r
- // Fill in the private data of each firmware volume block instance\r
- //\r
- do {\r
- Status = GetFvbHeader (&FirmwareVolumeHobList, &FwVolHeader, &BaseAddress, &WriteBack);\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
-\r
- if (!FwVolHeader) {\r
- continue;\r
- }\r
-\r
- EfiCopyMem ((UINTN *) &(FwhInstance->VolumeHeader), (UINTN *) FwVolHeader, FwVolHeader->HeaderLength);\r
- FwVolHeader = &(FwhInstance->VolumeHeader);\r
-\r
- FwhInstance->FvBase[FVB_PHYSICAL] = (UINTN) BaseAddress;\r
- FwhInstance->FvBase[FVB_VIRTUAL] = (UINTN) BaseAddress;\r
-\r
- //\r
- // FwhInstance->FvWriteBase may not be the same as FwhInstance->FvBase\r
- //\r
- PlatformGetFvbWriteBase (\r
- (UINTN) BaseAddress,\r
- (UINTN *) &(FwhInstance->FvWriteBase[FVB_PHYSICAL]),\r
- &WriteEnabled\r
- );\r
- //\r
- // Every pointer should have a virtual copy.\r
- //\r
- FwhInstance->FvWriteBase[FVB_VIRTUAL] = FwhInstance->FvWriteBase[FVB_PHYSICAL];\r
-\r
- FwhInstance->WriteEnabled = WriteEnabled;\r
- EfiInitializeLock (&(FwhInstance->FvbDevLock), EFI_TPL_HIGH_LEVEL);\r
-\r
- LbaAddress = (UINTN) FwhInstance->FvWriteBase[0];\r
- NumOfBlocks = 0;\r
- WriteLocked = FALSE;\r
-\r
- if (WriteEnabled) {\r
- CfiEnabled = FvbGetCfiSupported (LbaAddress);\r
- for (PtrBlockMapEntry = FwVolHeader->FvBlockMap; PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) {\r
-\r
- for (BlockIndex2 = 0; BlockIndex2 < PtrBlockMapEntry->NumBlocks; BlockIndex2++) {\r
-\r
- if (SetPlatformFvbLock (LbaAddress)) {\r
- //\r
- // Clear all write-lock and read-lock HW bits\r
- // For sync3, the software will enforce the protection\r
- //\r
- if (CfiEnabled) {\r
- Data = CFI_BLOCK_LOCK_UNLOCK;\r
- FvbMemWrite8 (LbaAddress, Data);\r
- Data = CFI_BLOCK_UNLOCK_CONFIRM;\r
- FvbMemWrite8 (LbaAddress, Data);\r
- while (TRUE) {\r
- EfiMemRead (EfiCpuIoWidthUint8, (LbaAddress + 2), 1, &Data);\r
- if (Data & 0x80) {\r
- break;\r
- }\r
- }\r
-\r
- Data = FWH_READ_ARRAY_COMMAND;\r
- FvbMemWrite8 (LbaAddress, Data);\r
- } else {\r
- EfiMemRead (EfiCpuIoWidthUint8, (LbaAddress - 0x400000 + 2), 0x1, &Data);\r
- //\r
- // bugbug: lock down is block based, not FV based. Here we assume that\r
- // the FV is locked if one of its block is locked\r
- //\r
- if ((Data & FWH_WRITE_LOCK) && (Data & FWH_LOCK_DOWN)) {\r
- //\r
- // the flash is locked and locked down\r
- //\r
- WriteLocked = TRUE;\r
- } else {\r
- Data &= ~(FWH_WRITE_LOCK | FWH_READ_LOCK | FWH_LOCK_DOWN);\r
-\r
- //\r
- // Save boot script for S3 resume\r
- //\r
- SCRIPT_MEM_WRITE (\r
- EFI_ACPI_S3_RESUME_SCRIPT_TABLE,\r
- EfiBootScriptWidthUint8,\r
- (UINT64) (LbaAddress - 0x400000 + 2),\r
- 1,\r
- &Data\r
- );\r
-\r
- FvbMemWrite8 ((LbaAddress - 0x400000 + 2), Data);\r
- }\r
- }\r
- }\r
-\r
- LbaAddress += PtrBlockMapEntry->BlockLength;\r
- }\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
- //\r
- if (MaxLbaSize < PtrBlockMapEntry->BlockLength) {\r
- MaxLbaSize = PtrBlockMapEntry->BlockLength;\r
- }\r
-\r
- NumOfBlocks = NumOfBlocks + PtrBlockMapEntry->NumBlocks;\r
- }\r
- //\r
- // Write back a healthy FV header\r
- //\r
- if (WriteBack && (!WriteLocked)) {\r
- Status = FlashFdErase (\r
- (UINTN) FwhInstance->FvWriteBase[0],\r
- (UINTN) BaseAddress,\r
- FwVolHeader->FvBlockMap->BlockLength\r
- );\r
-\r
- HeaderLength = (UINTN) FwVolHeader->HeaderLength;\r
- Status = FlashFdWrite (\r
- (UINTN) FwhInstance->FvWriteBase[0],\r
- (UINTN) BaseAddress,\r
- (UINTN *) &HeaderLength,\r
- (UINT8 *) FwVolHeader,\r
- FwVolHeader->FvBlockMap->BlockLength\r
- );\r
- \r
- FwVolHeader->HeaderLength = (UINT16) HeaderLength; \r
- DEBUG ((EFI_D_ERROR, "Fvb: FV header invalid, write back - %r\n", Status));\r
- }\r
- }\r
- //\r
- // The total number of blocks in the FV.\r
- //\r
- FwhInstance->NumOfBlocks = NumOfBlocks;\r
-\r
- //\r
- // If the FV is write locked, set the appropriate attributes\r
- //\r
- if (WriteLocked) {\r
- //\r
- // write disabled\r
- //\r
- FwhInstance->VolumeHeader.Attributes &= ~EFI_FVB_WRITE_STATUS;\r
- //\r
- // lock enabled\r
- //\r
- FwhInstance->VolumeHeader.Attributes |= EFI_FVB_LOCK_STATUS;\r
- }\r
- //\r
- // Add a FVB Protocol Instance\r
- //\r
- Status = gBS->AllocatePool (\r
- EfiRuntimeServicesData,\r
- sizeof (EFI_FW_VOL_BLOCK_DEVICE),\r
- &FvbDevice\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- EfiCopyMem (FvbDevice, &mFvbDeviceTemplate, sizeof (EFI_FW_VOL_BLOCK_DEVICE));\r
-\r
- FvbDevice->Instance = mFvbModuleGlobal->NumFv;\r
- mFvbModuleGlobal->NumFv++;\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
- //\r
- // Find a handle with a matching device path that has supports FW Block protocol\r
- //\r
- TempFwbDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) &TempFvbDevicePathData;\r
- EfiCopyMem (TempFwbDevicePath, &FvbDevice->DevicePath, sizeof (FV_DEVICE_PATH));\r
- Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &TempFwbDevicePath, &FwbHandle);\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // LocateDevicePath fails so install a new interface and device path\r
- //\r
- FwbHandle = NULL;\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &FwbHandle,\r
- &gEfiFirmwareVolumeBlockProtocolGuid,\r
- &FvbDevice->FwVolBlockInstance,\r
- &gEfiDevicePathProtocolGuid,\r
- &FvbDevice->DevicePath,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- } else if (EfiIsDevicePathEnd (TempFwbDevicePath)) {\r
- //\r
- // Device allready exists, so reinstall the FVB protocol\r
- //\r
- Status = gBS->HandleProtocol (\r
- FwbHandle,\r
- &gEfiFirmwareVolumeBlockProtocolGuid,\r
- &OldFwbInterface\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Status = gBS->ReinstallProtocolInterface (\r
- FwbHandle,\r
- &gEfiFirmwareVolumeBlockProtocolGuid,\r
- OldFwbInterface,\r
- &FvbDevice->FwVolBlockInstance\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- } else {\r
- //\r
- // There was a FVB protocol on an End Device Path node\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
- (UINTN) ((UINT8 *) FwhInstance) + FwVolHeader->HeaderLength +\r
- (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))\r
- );\r
- } while (TRUE);\r
-\r
- //\r
- // Allocate for scratch space, an intermediate buffer for FVB extention\r
- //\r
- Status = gBS->AllocatePool (\r
- EfiRuntimeServicesData,\r
- MaxLbaSize,\r
- &mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL]\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- mFvbModuleGlobal->FvbScratchSpace[FVB_VIRTUAL] = mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL];\r
-\r
- FvbSpecificInitialize (mFvbModuleGlobal);\r
-\r
- return EnableFvbWrites (FALSE);\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. 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
-Module Name:\r
-\r
- FwBlockService.h\r
- \r
-Abstract:\r
-\r
- Firmware volume block driver for Intel Firmware Hub (FWH) device\r
-\r
---*/\r
-\r
-#ifndef _FW_BLOCK_SERVICE_H\r
-#define _FW_BLOCK_SERVICE_H\r
-\r
-//\r
-// Statements that include other header files\r
-//\r
-#include "Tiano.h"\r
-#include "EfiFirmwareVolumeHeader.h"\r
-#include "EfiRuntimeLib.h"\r
-#include "EfiHobLib.h"\r
-#include "EfiScriptLib.h"\r
-\r
-#include EFI_PROTOCOL_PRODUCER (FirmwareVolumeBlock)\r
-#include EFI_PROTOCOL_PRODUCER (FvbExtension)\r
-#include EFI_GUID_DEFINITION (AlternateFvBlock)\r
-#include EFI_GUID_DEFINITION (Hob)\r
-#include EFI_GUID_DEFINITION (DxeServices)\r
-#include EFI_PROTOCOL_CONSUMER (CpuIo)\r
-\r
-#define FVB_MAX_RETRY_TIMES 10000000\r
-#define FWH_BLOCK_ERASE_SETUP_COMMAND 0x20\r
-#define FWH_BLOCK_ERASE_CONFIRM_COMMAND 0xd0\r
-#define FWH_READ_STATUS_COMMAND 0x70\r
-#define FWH_CLEAR_STATUS_COMMAND 0x50\r
-#define FWH_READ_ARRAY_COMMAND 0xff\r
-#define FWH_WRITE_SETUP_COMMAND 0x40\r
-#define FWH_OPEN_FEATURE_SPACE_COMMAND 0x91\r
-#define FWH_READ_LOCK (1 << 2)\r
-#define FWH_WRITE_LOCK (1 << 1)\r
-#define FWH_LOCK_DOWN 1\r
-#define FWH_WRITE_STATE_STATUS (1 << 7)\r
-#define FWH_ERASE_STATUS (1 << 5)\r
-#define FWH_PROGRAM_STATUS (1 << 4)\r
-#define FWH_VPP_STATUS (1 << 3)\r
-#define STALL_TIME 5\r
-#define FWH_ERASE_STATUS_BITS (FWH_ERASE_STATUS || FWH_VPP_STATUS)\r
-#define FWH_WRITE_STATUS_BITS (FWH_WRITE_STATUS || FWH_VPP_STATUS)\r
-#define CFI_BLOCK_LOCK_UNLOCK 0x60\r
-#define CFI_BLOCK_LOCK_CONFIRM 1\r
-#define CFI_BLOCK_UNLOCK_CONFIRM 0xD0\r
-#define CFI_QUERY 0x98\r
-\r
-//\r
-// BugBug: Add documentation here for data structure!!!!\r
-//\r
-#define FVB_PHYSICAL 0\r
-#define FVB_VIRTUAL 1\r
-\r
-typedef struct {\r
- EFI_LOCK FvbDevLock;\r
- UINTN FvBase[2];\r
- UINTN FvWriteBase[2];\r
- UINTN NumOfBlocks;\r
- BOOLEAN WriteEnabled;\r
- EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;\r
-} EFI_FW_VOL_INSTANCE;\r
-\r
-typedef struct {\r
- UINT32 NumFv;\r
- EFI_FW_VOL_INSTANCE *FvInstance[2];\r
- UINT8 *FvbScratchSpace[2];\r
-} ESAL_FWB_GLOBAL;\r
-\r
-//\r
-// Fvb Protocol instance data\r
-//\r
-#define FVB_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE)\r
-#define FVB_EXTEND_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, FvbExtension, FVB_DEVICE_SIGNATURE)\r
-#define FVB_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('F', 'V', 'B', 'C')\r
-\r
-typedef struct {\r
- MEMMAP_DEVICE_PATH MemMapDevPath;\r
- EFI_DEVICE_PATH_PROTOCOL EndDevPath;\r
-} FV_DEVICE_PATH;\r
-\r
-typedef struct {\r
- UINTN Signature;\r
- FV_DEVICE_PATH DevicePath;\r
- UINTN Instance;\r
- EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FwVolBlockInstance;\r
- EFI_FVB_EXTENSION_PROTOCOL FvbExtension;\r
-} EFI_FW_VOL_BLOCK_DEVICE;\r
-\r
-EFI_STATUS\r
-GetFvbInfo (\r
- IN EFI_PHYSICAL_ADDRESS FvBaseAddress,\r
- OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-EnableFvbWrites (\r
- IN BOOLEAN EnableWrites\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-PlatformGetFvbWriteBase (\r
- IN UINTN CurrentBaseAddress,\r
- IN UINTN *NewBaseAddress,\r
- IN BOOLEAN *WriteEnabled\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-EnablePlatformFvb (\r
- VOID\r
- )\r
-;\r
-\r
-BOOLEAN\r
-SetPlatformFvbLock (\r
- IN UINTN LbaAddress\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-FvbReadBlock (\r
- IN UINTN Instance,\r
- IN EFI_LBA Lba,\r
- IN UINTN BlockOffset,\r
- IN OUT UINTN *NumBytes,\r
- IN UINT8 *Buffer,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-FvbWriteBlock (\r
- IN UINTN Instance,\r
- IN EFI_LBA Lba,\r
- IN UINTN BlockOffset,\r
- IN OUT UINTN *NumBytes,\r
- IN UINT8 *Buffer,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-FvbEraseBlock (\r
- IN UINTN Instance,\r
- IN EFI_LBA Lba,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-FvbSetVolumeAttributes (\r
- IN UINTN Instance,\r
- IN OUT EFI_FVB_ATTRIBUTES *Attributes,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-FvbGetVolumeAttributes (\r
- IN UINTN Instance,\r
- OUT EFI_FVB_ATTRIBUTES *Attributes,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-FvbGetPhysicalAddress (\r
- IN UINTN Instance,\r
- OUT EFI_PHYSICAL_ADDRESS *Address,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbInitialize (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-;\r
-\r
-\r
-VOID\r
-EFIAPI\r
-FvbClassAddressChangeEvent (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-FvbSpecificInitialize (\r
- IN ESAL_FWB_GLOBAL *mFvbModuleGlobal\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-FvbGetLbaAddress (\r
- IN UINTN Instance,\r
- IN EFI_LBA Lba,\r
- OUT UINTN *LbaAddress,\r
- OUT UINTN *LbaWriteAddress,\r
- OUT UINTN *LbaLength,\r
- OUT UINTN *NumOfBlocks,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\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
-//\r
-// Protocol APIs\r
-//\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolGetAttributes (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- OUT EFI_FVB_ATTRIBUTES *Attributes\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolSetAttributes (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- IN OUT EFI_FVB_ATTRIBUTES *Attributes\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolGetPhysicalAddress (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- OUT EFI_PHYSICAL_ADDRESS *Address\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolGetBlockSize (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- IN EFI_LBA Lba,\r
- OUT UINTN *BlockSize,\r
- OUT UINTN *NumOfBlocks\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolRead (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- IN EFI_LBA Lba,\r
- IN UINTN Offset,\r
- IN OUT UINTN *NumBytes,\r
- IN UINT8 *Buffer\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolWrite (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- IN EFI_LBA Lba,\r
- IN UINTN Offset,\r
- IN OUT UINTN *NumBytes,\r
- IN UINT8 *Buffer\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolEraseBlocks (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- ...\r
- )\r
-;\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
-#endif\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. 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
-Module Name:\r
-\r
- Ia32Fwh.c\r
- \r
-Abstract:\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include "FWBlockService.h"\r
-\r
-EFI_STATUS\r
-FvbSpecificInitialize (\r
- IN ESAL_FWB_GLOBAL *mFvbModuleGlobal\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Additional initialize code for IA32 platform.\r
-\r
-Arguments:\r
- ESAL_FWB_GLOBAL - Global pointer that points to the instance data\r
-\r
-Returns: \r
- EFI_SUCCESS\r
-\r
---*/\r
-{\r
- return EFI_SUCCESS;\r
-}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. 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
+Module Name:\r
+\r
+ FWBlockService.c\r
+ \r
+Abstract:\r
+\r
+Revision History\r
+\r
+--*/\r
+\r
+#include "FWBlockService.h"\r
+\r
+ESAL_FWB_GLOBAL *mFvbModuleGlobal;\r
+\r
+EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate = {\r
+ FVB_DEVICE_SIGNATURE,\r
+ {\r
+ {\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
+ },\r
+ {\r
+ END_DEVICE_PATH_TYPE,\r
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+ {\r
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),\r
+ 0\r
+ }\r
+ }\r
+ },\r
+ 0,\r
+ {\r
+ FvbProtocolGetAttributes,\r
+ FvbProtocolSetAttributes,\r
+ FvbProtocolGetPhysicalAddress,\r
+ FvbProtocolGetBlockSize,\r
+ FvbProtocolRead,\r
+ FvbProtocolWrite,\r
+ FvbProtocolEraseBlocks,\r
+ NULL\r
+ },\r
+ {\r
+ FvbExtendProtocolEraseCustomBlockRange\r
+ }\r
+};\r
+\r
+\r
+\r
+VOID\r
+EFIAPI\r
+FvbVirtualddressChangeEvent (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Fixup internal data so that EFI and SAL can be call in virtual mode.\r
+ Call the passed in Child Notify event and convert the mFvbModuleGlobal\r
+ date items to there virtual address.\r
+\r
+ mFvbModuleGlobal->FvInstance[FVB_PHYSICAL] - Physical copy of instance data\r
+ mFvbModuleGlobal->FvInstance[FVB_VIRTUAL] - Virtual pointer to common \r
+ instance data.\r
+\r
+Arguments:\r
+\r
+ (Standard EFI notify event - EFI_EVENT_NOTIFY)\r
+\r
+Returns: \r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ EFI_FW_VOL_INSTANCE *FwhInstance;\r
+ UINTN Index;\r
+\r
+ EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal->FvInstance[FVB_VIRTUAL]);\r
+\r
+ //\r
+ // Convert the base address of all the instances\r
+ //\r
+ Index = 0;\r
+ FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];\r
+ while (Index < mFvbModuleGlobal->NumFv) {\r
+ EfiConvertPointer (0x0, (VOID **) &FwhInstance->FvBase[FVB_VIRTUAL]);\r
+ FwhInstance = (EFI_FW_VOL_INSTANCE *)\r
+ (\r
+ (UINTN) ((UINT8 *) FwhInstance) + FwhInstance->VolumeHeader.HeaderLength +\r
+ (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))\r
+ );\r
+ Index++;\r
+ }\r
+\r
+ EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal->FvbScratchSpace[FVB_VIRTUAL]);\r
+ EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal);\r
+}\r
+\r
+EFI_STATUS\r
+GetFvbInstance (\r
+ IN UINTN Instance,\r
+ IN ESAL_FWB_GLOBAL *Global,\r
+ OUT EFI_FW_VOL_INSTANCE **FwhInstance,\r
+ IN BOOLEAN Virtual\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Retrieves the physical address of a memory mapped FV\r
+\r
+Arguments:\r
+ Instance - The FV instance whose base address is going to be\r
+ returned\r
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all\r
+ instance data\r
+ FwhInstance - The EFI_FW_VOL_INSTANCE fimrware instance structure\r
+ Virtual - Whether CPU is in virtual or physical mode\r
+\r
+Returns: \r
+ EFI_SUCCESS - Successfully returns\r
+ EFI_INVALID_PARAMETER - Instance not found\r
+\r
+--*/\r
+{\r
+ EFI_FW_VOL_INSTANCE *FwhRecord;\r
+\r
+ if (Instance >= Global->NumFv) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ //\r
+ // Find the right instance of the FVB private data\r
+ //\r
+ FwhRecord = Global->FvInstance[Virtual];\r
+ while (Instance > 0) {\r
+ FwhRecord = (EFI_FW_VOL_INSTANCE *)\r
+ (\r
+ (UINTN) ((UINT8 *) FwhRecord) + FwhRecord->VolumeHeader.HeaderLength +\r
+ (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))\r
+ );\r
+ Instance--;\r
+ }\r
+\r
+ *FwhInstance = FwhRecord;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+FvbGetPhysicalAddress (\r
+ IN UINTN Instance,\r
+ OUT EFI_PHYSICAL_ADDRESS *Address,\r
+ IN ESAL_FWB_GLOBAL *Global,\r
+ IN BOOLEAN Virtual\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Retrieves the physical address of a memory mapped FV\r
+\r
+Arguments:\r
+ Instance - The FV instance whose base address is going to be\r
+ returned\r
+ Address - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS \r
+ that on successful return, contains the base address\r
+ of the firmware volume. \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 - Successfully returns\r
+ EFI_INVALID_PARAMETER - Instance not found\r
+\r
+--*/\r
+{\r
+ EFI_FW_VOL_INSTANCE *FwhInstance;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Find the right instance of the FVB private data\r
+ //\r
+ Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);\r
+ ASSERT_EFI_ERROR (Status);\r
+ *Address = FwhInstance->FvBase[Virtual];\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+FvbGetVolumeAttributes (\r
+ IN UINTN Instance,\r
+ OUT EFI_FVB_ATTRIBUTES *Attributes,\r
+ IN ESAL_FWB_GLOBAL *Global,\r
+ IN BOOLEAN Virtual\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Retrieves attributes, insures positive polarity of attribute bits, returns\r
+ resulting attributes in output parameter\r
+\r
+Arguments:\r
+ Instance - The FV instance whose attributes is going to be \r
+ returned\r
+ Attributes - Output buffer which contains attributes\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 - Successfully returns\r
+ EFI_INVALID_PARAMETER - Instance not found\r
+\r
+--*/\r
+{\r
+ EFI_FW_VOL_INSTANCE *FwhInstance;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Find the right instance of the FVB private data\r
+ //\r
+ Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);\r
+ ASSERT_EFI_ERROR (Status);\r
+ *Attributes = FwhInstance->VolumeHeader.Attributes;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+FvbGetLbaAddress (\r
+ IN UINTN Instance,\r
+ IN EFI_LBA Lba,\r
+ OUT UINTN *LbaAddress,\r
+ OUT UINTN *LbaLength,\r
+ OUT UINTN *NumOfBlocks,\r
+ IN ESAL_FWB_GLOBAL *Global,\r
+ IN BOOLEAN Virtual\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Retrieves the starting address of an LBA in an FV\r
+\r
+Arguments:\r
+ Instance - The FV instance which the Lba belongs to\r
+ Lba - The logical block address\r
+ LbaAddress - On output, contains the physical starting address \r
+ of the Lba\r
+ LbaLength - On output, contains the length of the block\r
+ NumOfBlocks - A pointer to a caller allocated UINTN in which the\r
+ number of consecutive blocks starting with Lba is\r
+ returned. All blocks in this range have a size of\r
+ BlockSize\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 - Successfully returns\r
+ EFI_INVALID_PARAMETER - Instance not found\r
+\r
+--*/\r
+{\r
+ UINT32 NumBlocks;\r
+ UINT32 BlockLength;\r
+ UINTN Offset;\r
+ EFI_LBA StartLba;\r
+ EFI_LBA NextLba;\r
+ EFI_FW_VOL_INSTANCE *FwhInstance;\r
+ EFI_FV_BLOCK_MAP_ENTRY *BlockMap;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Find the right instance of the FVB private data\r
+ //\r
+ Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ StartLba = 0;\r
+ Offset = 0;\r
+ BlockMap = &(FwhInstance->VolumeHeader.FvBlockMap[0]);\r
+\r
+ //\r
+ // Parse the blockmap of the FV to find which map entry the Lba belongs to\r
+ //\r
+ while (TRUE) {\r
+ NumBlocks = BlockMap->NumBlocks;\r
+ BlockLength = BlockMap->BlockLength;\r
+\r
+ if (NumBlocks == 0 || BlockLength == 0) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ NextLba = StartLba + NumBlocks;\r
+\r
+ //\r
+ // The map entry found\r
+ //\r
+ if (Lba >= StartLba && Lba < NextLba) {\r
+ Offset = Offset + (UINTN) MultU64x32 ((Lba - StartLba), BlockLength);\r
+ if (LbaAddress != NULL) {\r
+ *LbaAddress = FwhInstance->FvBase[Virtual] + Offset;\r
+ }\r
+\r
+ if (LbaLength != NULL) {\r
+ *LbaLength = BlockLength;\r
+ }\r
+\r
+ if (NumOfBlocks != NULL) {\r
+ *NumOfBlocks = (UINTN) (NextLba - Lba);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ StartLba = NextLba;\r
+ Offset = Offset + NumBlocks * BlockLength;\r
+ BlockMap++;\r
+ }\r
+}\r
+\r
+EFI_STATUS\r
+FvbReadBlock (\r
+ IN UINTN Instance,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN BlockOffset,\r
+ IN OUT UINTN *NumBytes,\r
+ IN UINT8 *Buffer,\r
+ IN ESAL_FWB_GLOBAL *Global,\r
+ IN BOOLEAN Virtual\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Reads specified number of bytes into a buffer from the specified block\r
+\r
+Arguments:\r
+ Instance - The FV instance to be read from\r
+ Lba - The logical block address to be read from\r
+ BlockOffset - Offset into the block at which to begin reading\r
+ NumBytes - Pointer that on input contains the total size of\r
+ the buffer. On output, it contains the total number\r
+ of bytes read\r
+ Buffer - Pointer to a caller allocated buffer that will be\r
+ used to hold the data read\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 read successfully and \r
+ contents are in Buffer\r
+ EFI_BAD_BUFFER_SIZE - Read attempted across a LBA boundary. On output,\r
+ NumBytes contains the total number of bytes returned\r
+ in Buffer\r
+ EFI_ACCESS_DENIED - The firmware volume is in the ReadDisabled state\r
+ EFI_DEVICE_ERROR - The block device is not functioning correctly and \r
+ could not be read\r
+ EFI_INVALID_PARAMETER - Instance not found, or NumBytes, Buffer are NULL\r
+\r
+--*/\r
+{\r
+ EFI_FVB_ATTRIBUTES Attributes;\r
+ UINTN LbaAddress;\r
+ UINTN LbaLength;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Check for invalid conditions\r
+ //\r
+ if ((NumBytes == NULL) || (Buffer == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (*NumBytes == 0) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL, Global, Virtual);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Check if the FV is read enabled\r
+ //\r
+ FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);\r
+\r
+ if ((Attributes & EFI_FVB_READ_STATUS) == 0) {\r
+ return EFI_ACCESS_DENIED;\r
+ }\r
+ //\r
+ // Perform boundary checks and adjust NumBytes\r
+ //\r
+ if (BlockOffset > LbaLength) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (LbaLength < (*NumBytes + BlockOffset)) {\r
+ *NumBytes = (UINT32) (LbaLength - BlockOffset);\r
+ Status = EFI_BAD_BUFFER_SIZE;\r
+ }\r
+\r
+ CopyMem (Buffer, (UINT8 *) (LbaAddress + BlockOffset), (UINTN) (*NumBytes));\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+FvbWriteBlock (\r
+ IN UINTN Instance,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN BlockOffset,\r
+ IN OUT UINTN *NumBytes,\r
+ IN UINT8 *Buffer,\r
+ IN ESAL_FWB_GLOBAL *Global,\r
+ IN BOOLEAN Virtual\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Writes specified number of bytes from the input buffer to the block\r
+\r
+Arguments:\r
+ Instance - The FV instance to be written to\r
+ Lba - The starting logical block index to write to\r
+ BlockOffset - Offset into the block at which to begin writing\r
+ NumBytes - Pointer that on input contains the total size of\r
+ the buffer. On output, it contains the total number\r
+ of bytes actually written\r
+ Buffer - Pointer to a caller allocated buffer that contains\r
+ the source for the write\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 written successfully\r
+ EFI_BAD_BUFFER_SIZE - Write attempted across a LBA boundary. On output,\r
+ NumBytes contains the total number of bytes\r
+ actually written\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\r
+ EFI_INVALID_PARAMETER - Instance not found, or NumBytes, Buffer are NULL\r
+\r
+--*/\r
+{\r
+ EFI_FVB_ATTRIBUTES Attributes;\r
+ UINTN LbaAddress;\r
+ UINTN LbaLength;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Check for invalid conditions\r
+ //\r
+ if ((NumBytes == NULL) || (Buffer == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (*NumBytes == 0) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL, Global, Virtual);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Check if the FV is write enabled\r
+ //\r
+ FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);\r
+\r
+ if ((Attributes & EFI_FVB_WRITE_STATUS) == 0) {\r
+ return EFI_ACCESS_DENIED;\r
+ }\r
+ //\r
+ // Perform boundary checks and adjust NumBytes\r
+ //\r
+ if (BlockOffset > LbaLength) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (LbaLength < (*NumBytes + BlockOffset)) {\r
+ *NumBytes = (UINT32) (LbaLength - BlockOffset);\r
+ Status = EFI_BAD_BUFFER_SIZE;\r
+ }\r
+ //\r
+ // Write data\r
+ //\r
+ CopyMem ((UINT8 *) (LbaAddress + BlockOffset), Buffer, (UINTN) (*NumBytes));\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+FvbEraseBlock (\r
+ IN UINTN Instance,\r
+ IN EFI_LBA Lba,\r
+ IN ESAL_FWB_GLOBAL *Global,\r
+ IN BOOLEAN Virtual\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Erases and initializes a firmware volume block\r
+\r
+Arguments:\r
+ Instance - The FV instance to be erased\r
+ Lba - The logical block index to be erased\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 erase request was successfully completed\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
+\r
+ EFI_FVB_ATTRIBUTES Attributes;\r
+ UINTN LbaAddress;\r
+ UINTN LbaLength;\r
+ EFI_STATUS Status;\r
+ UINT8 Data;\r
+\r
+ //\r
+ // Check if the FV is write enabled\r
+ //\r
+ FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);\r
+\r
+ if ((Attributes & EFI_FVB_WRITE_STATUS) == 0) {\r
+ return EFI_ACCESS_DENIED;\r
+ }\r
+ //\r
+ // Get the starting address of the block for erase.\r
+ //\r
+ Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL, Global, Virtual);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if ((Attributes & EFI_FVB_ERASE_POLARITY) != 0) {\r
+ Data = 0xFF;\r
+ } else {\r
+ Data = 0x0;\r
+ }\r
+\r
+ SetMem ((UINT8 *) LbaAddress, LbaLength, Data);\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
+\r
+ //\r
+ // First LBA\r
+ //\r
+ FvbGetLbaAddress (Instance, StartLba, NULL, &LbaSize, NULL, Global, Virtual);\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
+ FvbWriteBlock (Instance, StartLba, 0, &ScratchLbaSizeData, Global->FvbScratchSpace[Virtual], Global, Virtual);\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
+ FvbGetLbaAddress (Instance, LastLba, NULL, &LbaSize, NULL, Global, Virtual);\r
+ FvbReadBlock (Instance, LastLba, 0, &LbaSize, Global->FvbScratchSpace[Virtual], Global, Virtual);\r
+ FvbEraseBlock (Instance, LastLba, Global, Virtual);\r
+ }\r
+\r
+ ScratchLbaSizeData = LbaSize - (OffsetStartLba + 1);\r
+\r
+ return FvbWriteBlock (\r
+ Instance,\r
+ LastLba,\r
+ (OffsetLastLba + 1),\r
+ &ScratchLbaSizeData,\r
+ Global->FvbScratchSpace[Virtual],\r
+ Global,\r
+ Virtual\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+FvbSetVolumeAttributes (\r
+ IN UINTN Instance,\r
+ IN OUT EFI_FVB_ATTRIBUTES *Attributes,\r
+ IN ESAL_FWB_GLOBAL *Global,\r
+ IN BOOLEAN Virtual\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Modifies the current settings of the firmware volume according to the \r
+ input parameter, and returns the new setting of the volume\r
+\r
+Arguments:\r
+ Instance - The FV instance whose attributes is going to be \r
+ modified\r
+ Attributes - On input, it is a pointer to EFI_FVB_ATTRIBUTES \r
+ containing the desired firmware volume settings.\r
+ On successful return, it contains the new settings\r
+ of the firmware volume\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 - Successfully returns\r
+ EFI_ACCESS_DENIED - The volume setting is locked and cannot be modified\r
+ EFI_INVALID_PARAMETER - Instance not found, or The attributes requested are\r
+ in conflict with the capabilities as declared in the\r
+ firmware volume header\r
+\r
+--*/\r
+{\r
+ EFI_FW_VOL_INSTANCE *FwhInstance;\r
+ EFI_FVB_ATTRIBUTES OldAttributes;\r
+ EFI_FVB_ATTRIBUTES *AttribPtr;\r
+ UINT32 Capabilities;\r
+ UINT32 OldStatus;\r
+ UINT32 NewStatus;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Find the right instance of the FVB private data\r
+ //\r
+ Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ AttribPtr = (EFI_FVB_ATTRIBUTES *) &(FwhInstance->VolumeHeader.Attributes);\r
+ OldAttributes = *AttribPtr;\r
+ Capabilities = OldAttributes & EFI_FVB_CAPABILITIES;\r
+ OldStatus = OldAttributes & EFI_FVB_STATUS;\r
+ NewStatus = *Attributes & EFI_FVB_STATUS;\r
+\r
+ //\r
+ // If firmware volume is locked, no status bit can be updated\r
+ //\r
+ if (OldAttributes & EFI_FVB_LOCK_STATUS) {\r
+ if (OldStatus ^ NewStatus) {\r
+ return EFI_ACCESS_DENIED;\r
+ }\r
+ }\r
+ //\r
+ // Test read disable\r
+ //\r
+ if ((Capabilities & EFI_FVB_READ_DISABLED_CAP) == 0) {\r
+ if ((NewStatus & EFI_FVB_READ_STATUS) == 0) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ }\r
+ //\r
+ // Test read enable\r
+ //\r
+ if ((Capabilities & EFI_FVB_READ_ENABLED_CAP) == 0) {\r
+ if (NewStatus & EFI_FVB_READ_STATUS) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ }\r
+ //\r
+ // Test write disable\r
+ //\r
+ if ((Capabilities & EFI_FVB_WRITE_DISABLED_CAP) == 0) {\r
+ if ((NewStatus & EFI_FVB_WRITE_STATUS) == 0) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ }\r
+ //\r
+ // Test write enable\r
+ //\r
+ if ((Capabilities & EFI_FVB_WRITE_ENABLED_CAP) == 0) {\r
+ if (NewStatus & EFI_FVB_WRITE_STATUS) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ }\r
+ //\r
+ // Test lock\r
+ //\r
+ if ((Capabilities & EFI_FVB_LOCK_CAP) == 0) {\r
+ if (NewStatus & EFI_FVB_LOCK_STATUS) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ }\r
+\r
+ *AttribPtr = (*AttribPtr) & (0xFFFFFFFF & (~EFI_FVB_STATUS));\r
+ *AttribPtr = (*AttribPtr) | NewStatus;\r
+ *Attributes = *AttribPtr;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+//\r
+// FVB protocol APIs\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+FvbProtocolGetPhysicalAddress (\r
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ OUT EFI_PHYSICAL_ADDRESS *Address\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Retrieves the physical address of the device.\r
+\r
+Arguments:\r
+\r
+ This - Calling context\r
+ Address - Output buffer containing the address.\r
+\r
+Returns:\r
+\r
+Returns: \r
+ EFI_SUCCESS - Successfully returns\r
+\r
+--*/\r
+{\r
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
+\r
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
+\r
+ return FvbGetPhysicalAddress (FvbDevice->Instance, Address, mFvbModuleGlobal, EfiGoneVirtual ());\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FvbProtocolGetBlockSize (\r
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ IN EFI_LBA Lba,\r
+ OUT UINTN *BlockSize,\r
+ OUT UINTN *NumOfBlocks\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Retrieve the size of a logical block\r
+\r
+Arguments:\r
+ This - Calling context\r
+ Lba - Indicates which block to return the size for.\r
+ BlockSize - A pointer to a caller allocated UINTN in which\r
+ the size of the block is returned\r
+ NumOfBlocks - a pointer to a caller allocated UINTN in which the\r
+ number of consecutive blocks starting with Lba is\r
+ returned. All blocks in this range have a size of\r
+ BlockSize\r
+\r
+Returns: \r
+ EFI_SUCCESS - The firmware volume was read successfully and \r
+ contents are in Buffer\r
+\r
+--*/\r
+{\r
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
+\r
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
+\r
+ return FvbGetLbaAddress (\r
+ FvbDevice->Instance,\r
+ Lba,\r
+ NULL,\r
+ BlockSize,\r
+ NumOfBlocks,\r
+ mFvbModuleGlobal,\r
+ EfiGoneVirtual ()\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FvbProtocolGetAttributes (\r
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ OUT EFI_FVB_ATTRIBUTES *Attributes\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Retrieves Volume attributes. No polarity translations are done.\r
+\r
+Arguments:\r
+ This - Calling context\r
+ Attributes - output buffer which contains attributes\r
+\r
+Returns: \r
+ EFI_SUCCESS - Successfully returns\r
+\r
+--*/\r
+{\r
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
+\r
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
+\r
+ return FvbGetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ());\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FvbProtocolSetAttributes (\r
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ IN OUT EFI_FVB_ATTRIBUTES *Attributes\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Sets Volume attributes. No polarity translations are done.\r
+\r
+Arguments:\r
+ This - Calling context\r
+ Attributes - output buffer which contains attributes\r
+\r
+Returns: \r
+ EFI_SUCCESS - Successfully returns\r
+\r
+--*/\r
+{\r
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
+\r
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
+\r
+ return FvbSetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ());\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FvbProtocolEraseBlocks (\r
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ ... \r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ The EraseBlock() function erases one or more blocks as denoted by the \r
+ variable argument list. The entire parameter list of blocks must be verified\r
+ prior to erasing any blocks. If a block is requested that does not exist \r
+ within the associated firmware volume (it has a larger index than the last \r
+ block of the firmware volume), the EraseBlock() function must return\r
+ EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.\r
+\r
+Arguments:\r
+ This - Calling context\r
+ ... - Starting LBA followed by Number of Lba to erase. \r
+ a -1 to terminate the list.\r
+\r
+Returns: \r
+ EFI_SUCCESS - The erase request was successfully completed\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
+ EFI_FW_VOL_INSTANCE *FwhInstance;\r
+ UINTN NumOfBlocks;\r
+ VA_LIST args;\r
+ EFI_LBA StartingLba;\r
+ UINTN NumOfLba;\r
+ EFI_STATUS Status;\r
+\r
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
+\r
+ Status = GetFvbInstance (FvbDevice->Instance, mFvbModuleGlobal, &FwhInstance, EfiGoneVirtual ());\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ NumOfBlocks = FwhInstance->NumOfBlocks;\r
+\r
+ VA_START (args, This);\r
+\r
+ do {\r
+ StartingLba = VA_ARG (args, EFI_LBA);\r
+ if (StartingLba == EFI_LBA_LIST_TERMINATOR) {\r
+ break;\r
+ }\r
+\r
+ NumOfLba = VA_ARG (args, UINT32);\r
+\r
+ //\r
+ // Check input parameters\r
+ //\r
+ if (NumOfLba == 0) {\r
+ VA_END (args);\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if ((StartingLba + NumOfLba) > NumOfBlocks) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ } while (1);\r
+\r
+ VA_END (args);\r
+\r
+ VA_START (args, This);\r
+ do {\r
+ StartingLba = VA_ARG (args, EFI_LBA);\r
+ if (StartingLba == EFI_LBA_LIST_TERMINATOR) {\r
+ break;\r
+ }\r
+\r
+ NumOfLba = VA_ARG (args, UINT32);\r
+\r
+ while (NumOfLba > 0) {\r
+ Status = FvbEraseBlock (FvbDevice->Instance, StartingLba, mFvbModuleGlobal, EfiGoneVirtual ());\r
+ if (EFI_ERROR (Status)) {\r
+ VA_END (args);\r
+ return Status;\r
+ }\r
+\r
+ StartingLba++;\r
+ NumOfLba--;\r
+ }\r
+\r
+ } while (1);\r
+\r
+ VA_END (args);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FvbProtocolWrite (\r
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN Offset,\r
+ IN OUT UINTN *NumBytes,\r
+ IN UINT8 *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Writes data beginning at Lba:Offset from FV. The write terminates either\r
+ when *NumBytes of data have been written, or when a block boundary is\r
+ reached. *NumBytes is updated to reflect the actual number of bytes\r
+ written. The write opertion does not include erase. This routine will\r
+ attempt to write only the specified bytes. If the writes do not stick,\r
+ it will return an error.\r
+\r
+Arguments:\r
+ This - Calling context\r
+ Lba - Block in which to begin write\r
+ Offset - Offset in the block at which to begin write\r
+ NumBytes - On input, indicates the requested write size. On\r
+ output, indicates the actual number of bytes written\r
+ Buffer - Buffer containing source data for the write.\r
+\r
+Returns: \r
+ EFI_SUCCESS - The firmware volume was written successfully\r
+ EFI_BAD_BUFFER_SIZE - Write attempted across a LBA boundary. On output,\r
+ NumBytes contains the total number of bytes\r
+ actually written\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\r
+ EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL\r
+\r
+--*/\r
+{\r
+\r
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
+\r
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
+\r
+ return FvbWriteBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer, mFvbModuleGlobal, EfiGoneVirtual ());\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FvbProtocolRead (\r
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN Offset,\r
+ IN OUT UINTN *NumBytes,\r
+ IN UINT8 *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Reads data beginning at Lba:Offset from FV. The Read terminates either\r
+ when *NumBytes of data have been read, or when a block boundary is\r
+ reached. *NumBytes is updated to reflect the actual number of bytes\r
+ written. The write opertion does not include erase. This routine will\r
+ attempt to write only the specified bytes. If the writes do not stick,\r
+ it will return an error.\r
+\r
+Arguments:\r
+ This - Calling context\r
+ Lba - Block in which to begin Read\r
+ Offset - Offset in the block at which to begin Read\r
+ NumBytes - On input, indicates the requested write size. On\r
+ output, indicates the actual number of bytes Read\r
+ Buffer - Buffer containing source data for the Read.\r
+\r
+Returns: \r
+ EFI_SUCCESS - The firmware volume was read successfully and \r
+ contents are in Buffer\r
+ EFI_BAD_BUFFER_SIZE - Read attempted across a LBA boundary. On output,\r
+ NumBytes contains the total number of bytes returned\r
+ in Buffer\r
+ EFI_ACCESS_DENIED - The firmware volume is in the ReadDisabled state\r
+ EFI_DEVICE_ERROR - The block device is not functioning correctly and \r
+ could not be read\r
+ EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL\r
+\r
+--*/\r
+{\r
+\r
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
+\r
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);\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
+Routine Description:\r
+ Check the integrity of firmware volume header\r
+\r
+Arguments:\r
+ FwVolHeader - A pointer to a firmware volume header\r
+\r
+Returns: \r
+ EFI_SUCCESS - The firmware volume is consistent\r
+ EFI_NOT_FOUND - The firmware volume has corrupted. So it is not an FV\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
+ // HeaderLength cannot be an odd number\r
+ //\r
+ if ((FwVolHeader->Revision != EFI_FVH_REVISION) ||\r
+ (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||\r
+ (FwVolHeader->FvLength == ((UINTN) -1)) ||\r
+ ((FwVolHeader->HeaderLength & 0x01) != 0)\r
+ ) {\r
+ return EFI_NOT_FOUND;\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 = *Ptr++;\r
+ HeaderLength--;\r
+ }\r
+\r
+ if (Checksum != 0) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FvbInitialize (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ This function does common initialization for FVB services\r
+\r
+Arguments:\r
+\r
+Returns:\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_FW_VOL_INSTANCE *FwhInstance;\r
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
+ EFI_DXE_SERVICES *DxeServices;\r
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;\r
+ UINT32 BufferSize;\r
+ EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry;\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
+ // Get the DXE services table\r
+ //\r
+ DxeServices = gDS;\r
+\r
+ //\r
+ // Allocate runtime services data for global variable, which contains\r
+ // the private data of all firmware volume block instances\r
+ //\r
+ Status = gBS->AllocatePool (\r
+ EfiRuntimeServicesData,\r
+ sizeof (ESAL_FWB_GLOBAL),\r
+ &mFvbModuleGlobal\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Calculate the total size for all firmware volume block instances\r
+ //\r
+ BufferSize = 0;\r
+\r
+ FvHob.Raw = GetHobList ();\r
+ while ((FvHob.Raw = GetNextHob (EFI_HOB_TYPE_FV, FvHob.Raw)) != NULL) {\r
+ BaseAddress = FvHob.FirmwareVolume->BaseAddress;\r
+ Length = FvHob.FirmwareVolume->Length;\r
+ //\r
+ // Check if it is a "real" flash\r
+ //\r
+ Status = DxeServices->GetMemorySpaceDescriptor (\r
+ BaseAddress,\r
+ &Descriptor\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+\r
+ if (Descriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) {\r
+ FvHob.Raw = GET_NEXT_HOB (FvHob);\r
+ continue;\r
+ }\r
+\r
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress;\r
+ Status = ValidateFvHeader (FwVolHeader);\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Get FvbInfo\r
+ //\r
+ Status = GetFvbInfo (Length, &FwVolHeader);\r
+ if (EFI_ERROR (Status)) {\r
+ FvHob.Raw = GET_NEXT_HOB (FvHob);\r
+ continue;\r
+ }\r
+ }\r
+\r
+ BufferSize += (sizeof (EFI_FW_VOL_INSTANCE) + FwVolHeader->HeaderLength - sizeof (EFI_FIRMWARE_VOLUME_HEADER));\r
+ FvHob.Raw = GET_NEXT_HOB (FvHob);\r
+ }\r
+\r
+ //\r
+ // Only need to allocate once. There is only one copy of physical memory for\r
+ // the private data of each FV instance. But in virtual mode or in physical\r
+ // mode, the address of the the physical memory may be different.\r
+ //\r
+ Status = gBS->AllocatePool (\r
+ EfiRuntimeServicesData,\r
+ BufferSize,\r
+ &mFvbModuleGlobal->FvInstance[FVB_PHYSICAL]\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Make a virtual copy of the FvInstance pointer.\r
+ //\r
+ FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];\r
+ mFvbModuleGlobal->FvInstance[FVB_VIRTUAL] = FwhInstance;\r
+\r
+ mFvbModuleGlobal->NumFv = 0;\r
+ MaxLbaSize = 0;\r
+\r
+ FvHob.Raw = GetHobList ();\r
+ while (NULL != (FvHob.Raw = GetNextHob (EFI_HOB_TYPE_FV, FvHob.Raw))) {\r
+ BaseAddress = FvHob.FirmwareVolume->BaseAddress;\r
+ Length = FvHob.FirmwareVolume->Length;\r
+ //\r
+ // Check if it is a "real" flash\r
+ //\r
+ Status = DxeServices->GetMemorySpaceDescriptor (\r
+ BaseAddress,\r
+ &Descriptor\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+\r
+ if (Descriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) {\r
+ FvHob.Raw = GET_NEXT_HOB (FvHob);\r
+ continue;\r
+ }\r
+\r
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress;\r
+ Status = ValidateFvHeader (FwVolHeader);\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Get FvbInfo to provide in FwhInstance.\r
+ //\r
+ Status = GetFvbInfo (Length, &FwVolHeader);\r
+ if (EFI_ERROR (Status)) {\r
+ FvHob.Raw = GET_NEXT_HOB (FvHob);\r
+ continue;\r
+ }\r
+ //\r
+ // Write healthy FV header back.\r
+ //\r
+ CopyMem (\r
+ (VOID *) (UINTN) BaseAddress,\r
+ (VOID *) FwVolHeader,\r
+ FwVolHeader->HeaderLength\r
+ );\r
+ }\r
+\r
+ FwhInstance->FvBase[FVB_PHYSICAL] = (UINTN) BaseAddress;\r
+ FwhInstance->FvBase[FVB_VIRTUAL] = (UINTN) BaseAddress;\r
+\r
+ CopyMem ((UINTN *) &(FwhInstance->VolumeHeader), (UINTN *) FwVolHeader, FwVolHeader->HeaderLength);\r
+ FwVolHeader = &(FwhInstance->VolumeHeader);\r
+ EfiInitializeLock (&(FwhInstance->FvbDevLock), EFI_TPL_HIGH_LEVEL);\r
+\r
+ NumOfBlocks = 0;\r
+\r
+ for (PtrBlockMapEntry = FwVolHeader->FvBlockMap; 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
+ //\r
+ if (MaxLbaSize < PtrBlockMapEntry->BlockLength) {\r
+ MaxLbaSize = PtrBlockMapEntry->BlockLength;\r
+ }\r
+\r
+ NumOfBlocks = NumOfBlocks + PtrBlockMapEntry->NumBlocks;\r
+ }\r
+ //\r
+ // The total number of blocks in the FV.\r
+ //\r
+ FwhInstance->NumOfBlocks = NumOfBlocks;\r
+\r
+ //\r
+ // Add a FVB Protocol Instance\r
+ //\r
+ Status = gBS->AllocatePool (\r
+ EfiRuntimeServicesData,\r
+ sizeof (EFI_FW_VOL_BLOCK_DEVICE),\r
+ &FvbDevice\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ CopyMem (FvbDevice, &mFvbDeviceTemplate, sizeof (EFI_FW_VOL_BLOCK_DEVICE));\r
+\r
+ FvbDevice->Instance = mFvbModuleGlobal->NumFv;\r
+ mFvbModuleGlobal->NumFv++;\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
+ //\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
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // LocateDevicePath fails so install a new interface and device path\r
+ //\r
+ FwbHandle = NULL;\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &FwbHandle,\r
+ &gEfiFirmwareVolumeBlockProtocolGuid,\r
+ &FvbDevice->FwVolBlockInstance,\r
+ &gEfiDevicePathProtocolGuid,\r
+ &FvbDevice->DevicePath,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ } else if (EfiIsDevicePathEnd (TempFwbDevicePath)) {\r
+ //\r
+ // Device allready exists, so reinstall the FVB protocol\r
+ //\r
+ Status = gBS->HandleProtocol (\r
+ FwbHandle,\r
+ &gEfiFirmwareVolumeBlockProtocolGuid,\r
+ &OldFwbInterface\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ Status = gBS->ReinstallProtocolInterface (\r
+ FwbHandle,\r
+ &gEfiFirmwareVolumeBlockProtocolGuid,\r
+ OldFwbInterface,\r
+ &FvbDevice->FwVolBlockInstance\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ } else {\r
+ //\r
+ // There was a FVB protocol on an End Device Path node\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
+ (UINTN) ((UINT8 *) FwhInstance) + FwVolHeader->HeaderLength +\r
+ (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))\r
+ );\r
+\r
+ FvHob.Raw = GET_NEXT_HOB (FvHob);\r
+ }\r
+\r
+ //\r
+ // Allocate for scratch space, an intermediate buffer for FVB extention\r
+ //\r
+ Status = gBS->AllocatePool (\r
+ EfiRuntimeServicesData,\r
+ MaxLbaSize,\r
+ &mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL]\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ mFvbModuleGlobal->FvbScratchSpace[FVB_VIRTUAL] = mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL];\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. 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
+Module Name:\r
+\r
+ FvbInfo.c\r
+\r
+Abstract:\r
+\r
+ Defines data structure that is the volume header found.These data is intent\r
+ to decouple FVB driver with FV header.\r
+\r
+--*/\r
+\r
+#include "FlashLayout.h"\r
+\r
+#define FIRMWARE_BLOCK_SIZE 0x10000\r
+\r
+typedef struct {\r
+ UINT64 FvLength;\r
+ EFI_FIRMWARE_VOLUME_HEADER FvbInfo;\r
+ //\r
+ // EFI_FV_BLOCK_MAP_ENTRY ExtraBlockMap[n];//n=0\r
+ //\r
+ EFI_FV_BLOCK_MAP_ENTRY End[1];\r
+} EFI_FVB_MEDIA_INFO;\r
+\r
+#define FVB_MEDIA_BLOCK_SIZE FIRMWARE_BLOCK_SIZE\r
+#define RECOVERY_BOIS_BLOCK_NUM FIRMWARE_BLOCK_NUMBER\r
+#define SYSTEM_NV_BLOCK_NUM 2\r
+\r
+EFI_FVB_MEDIA_INFO mPlatformFvbMediaInfo[] = {\r
+ //\r
+ // Recovery BOIS FVB\r
+ //\r
+ {\r
+ EFI_WINNT_FIRMWARE_LENGTH,\r
+ {\r
+ {\r
+ 0,\r
+ }, // ZeroVector[16]\r
+ EFI_FIRMWARE_FILE_SYSTEM_GUID,\r
+ FVB_MEDIA_BLOCK_SIZE * RECOVERY_BOIS_BLOCK_NUM,\r
+ EFI_FVH_SIGNATURE,\r
+ EFI_FVB_READ_ENABLED_CAP |\r
+ EFI_FVB_READ_STATUS |\r
+ EFI_FVB_WRITE_ENABLED_CAP |\r
+ EFI_FVB_WRITE_STATUS |\r
+ EFI_FVB_ERASE_POLARITY,\r
+ sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),\r
+ 0, // CheckSum\r
+ {\r
+ 0,\r
+ }, // Reserved[3]\r
+ 1, // Revision\r
+ {\r
+ RECOVERY_BOIS_BLOCK_NUM,\r
+ FVB_MEDIA_BLOCK_SIZE,\r
+ }\r
+ },\r
+ {\r
+ 0,\r
+ 0\r
+ }\r
+ },\r
+ //\r
+ // Systen NvStorage FVB\r
+ //\r
+ {\r
+ EFI_WINNT_RUNTIME_UPDATABLE_LENGTH + EFI_WINNT_FTW_SPARE_BLOCK_LENGTH,\r
+ {\r
+ {\r
+ 0,\r
+ }, // ZeroVector[16]\r
+ EFI_SYSTEM_NV_DATA_HOB_GUID,\r
+ FVB_MEDIA_BLOCK_SIZE * SYSTEM_NV_BLOCK_NUM,\r
+ EFI_FVH_SIGNATURE,\r
+ EFI_FVB_READ_ENABLED_CAP |\r
+ EFI_FVB_READ_STATUS |\r
+ EFI_FVB_WRITE_ENABLED_CAP |\r
+ EFI_FVB_WRITE_STATUS |\r
+ EFI_FVB_ERASE_POLARITY,\r
+ sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),\r
+ 0, // CheckSum\r
+ {\r
+ 0,\r
+ }, // Reserved[3]\r
+ 1, // Revision\r
+ {\r
+ SYSTEM_NV_BLOCK_NUM,\r
+ FVB_MEDIA_BLOCK_SIZE,\r
+ }\r
+ },\r
+ {\r
+ 0,\r
+ 0\r
+ }\r
+ }\r
+};\r
+\r
+EFI_STATUS\r
+GetFvbInfo (\r
+ IN UINT64 FvLength,\r
+ OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo\r
+ )\r
+{\r
+ UINTN Index;\r
+\r
+ for (Index = 0; Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB_MEDIA_INFO); Index += 1) {\r
+ if (mPlatformFvbMediaInfo[Index].FvLength == FvLength) {\r
+ *FvbInfo = &mPlatformFvbMediaInfo[Index].FvbInfo;\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. 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
+Module Name:\r
+\r
+ FwBlockService.h\r
+ \r
+Abstract:\r
+\r
+ Firmware volume block driver for Intel Firmware Hub (FWH) device\r
+\r
+--*/\r
+\r
+#ifndef _FW_BLOCK_SERVICE_H\r
+#define _FW_BLOCK_SERVICE_H\r
+\r
+//\r
+// BugBug: Add documentation here for data structure!!!!\r
+//\r
+#define FVB_PHYSICAL 0\r
+#define FVB_VIRTUAL 1\r
+\r
+typedef struct {\r
+ EFI_LOCK FvbDevLock;\r
+ UINTN FvBase[2];\r
+ UINTN NumOfBlocks;\r
+ EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;\r
+} EFI_FW_VOL_INSTANCE;\r
+\r
+typedef struct {\r
+ UINT32 NumFv;\r
+ EFI_FW_VOL_INSTANCE *FvInstance[2];\r
+ UINT8 *FvbScratchSpace[2];\r
+} ESAL_FWB_GLOBAL;\r
+\r
+//\r
+// Fvb Protocol instance data\r
+//\r
+#define FVB_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE)\r
+#define FVB_EXTEND_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, FvbExtension, FVB_DEVICE_SIGNATURE)\r
+#define FVB_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('F', 'V', 'B', 'N')\r
+\r
+typedef struct {\r
+ MEMMAP_DEVICE_PATH MemMapDevPath;\r
+ EFI_DEVICE_PATH_PROTOCOL EndDevPath;\r
+} FV_DEVICE_PATH;\r
+\r
+typedef struct {\r
+ UINTN Signature;\r
+ FV_DEVICE_PATH DevicePath;\r
+ UINTN Instance;\r
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FwVolBlockInstance;\r
+ EFI_FVB_EXTENSION_PROTOCOL FvbExtension;\r
+} EFI_FW_VOL_BLOCK_DEVICE;\r
+\r
+EFI_STATUS\r
+GetFvbInfo (\r
+ IN UINT64 FvLength,\r
+ OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo\r
+ )\r
+;\r
+\r
+EFI_STATUS\r
+FvbReadBlock (\r
+ IN UINTN Instance,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN BlockOffset,\r
+ IN OUT UINTN *NumBytes,\r
+ IN UINT8 *Buffer,\r
+ IN ESAL_FWB_GLOBAL *Global,\r
+ IN BOOLEAN Virtual\r
+ )\r
+;\r
+\r
+EFI_STATUS\r
+FvbWriteBlock (\r
+ IN UINTN Instance,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN BlockOffset,\r
+ IN OUT UINTN *NumBytes,\r
+ IN UINT8 *Buffer,\r
+ IN ESAL_FWB_GLOBAL *Global,\r
+ IN BOOLEAN Virtual\r
+ )\r
+;\r
+\r
+EFI_STATUS\r
+FvbEraseBlock (\r
+ IN UINTN Instance,\r
+ IN EFI_LBA Lba,\r
+ IN ESAL_FWB_GLOBAL *Global,\r
+ IN BOOLEAN Virtual\r
+ )\r
+;\r
+\r
+EFI_STATUS\r
+FvbSetVolumeAttributes (\r
+ IN UINTN Instance,\r
+ IN OUT EFI_FVB_ATTRIBUTES *Attributes,\r
+ IN ESAL_FWB_GLOBAL *Global,\r
+ IN BOOLEAN Virtual\r
+ )\r
+;\r
+\r
+EFI_STATUS\r
+FvbGetVolumeAttributes (\r
+ IN UINTN Instance,\r
+ OUT EFI_FVB_ATTRIBUTES *Attributes,\r
+ IN ESAL_FWB_GLOBAL *Global,\r
+ IN BOOLEAN Virtual\r
+ )\r
+;\r
+\r
+EFI_STATUS\r
+FvbGetPhysicalAddress (\r
+ IN UINTN Instance,\r
+ OUT EFI_PHYSICAL_ADDRESS *Address,\r
+ IN ESAL_FWB_GLOBAL *Global,\r
+ IN BOOLEAN Virtual\r
+ )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FvbInitialize (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+;\r
+\r
+\r
+VOID\r
+EFIAPI\r
+FvbClassAddressChangeEvent (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+;\r
+\r
+EFI_STATUS\r
+FvbGetLbaAddress (\r
+ IN UINTN Instance,\r
+ IN EFI_LBA Lba,\r
+ OUT UINTN *LbaAddress,\r
+ OUT UINTN *LbaLength,\r
+ OUT UINTN *NumOfBlocks,\r
+ IN ESAL_FWB_GLOBAL *Global,\r
+ IN BOOLEAN Virtual\r
+ )\r
+;\r
+\r
+//\r
+// Protocol APIs\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+FvbProtocolGetAttributes (\r
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ OUT EFI_FVB_ATTRIBUTES *Attributes\r
+ )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FvbProtocolSetAttributes (\r
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ IN OUT EFI_FVB_ATTRIBUTES *Attributes\r
+ )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FvbProtocolGetPhysicalAddress (\r
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ OUT EFI_PHYSICAL_ADDRESS *Address\r
+ )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FvbProtocolGetBlockSize (\r
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ IN EFI_LBA Lba,\r
+ OUT UINTN *BlockSize,\r
+ OUT UINTN *NumOfBlocks\r
+ )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FvbProtocolRead (\r
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN Offset,\r
+ IN OUT UINTN *NumBytes,\r
+ IN UINT8 *Buffer\r
+ )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FvbProtocolWrite (\r
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN Offset,\r
+ IN OUT UINTN *NumBytes,\r
+ IN UINT8 *Buffer\r
+ )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FvbProtocolEraseBlocks (\r
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
+ ...\r
+ )\r
+;\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
+#endif\r
-<?xml version="1.0" encoding="UTF-8"?>\r
+<?xml version="1.0" encoding="UTF-8"?>\r
<!--Copyright (c) 2006, Intel Corporation\r
All rights reserved. This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
</LibraryClassDefinitions>\r
<SourceFiles>\r
<Filename>Nt32Fwh.dxs</Filename>\r
- <Filename SupArchList="IA32">nt32\FWBlockService.c</Filename>\r
- <Filename SupArchList="IA32">nt32\FwBlockService.h</Filename>\r
- <Filename SupArchList="IA32">nt32\FvbInfo.c</Filename>\r
- <Filename ToolCode="DUMMY">Common\FWBlockService.c</Filename>\r
- <Filename ToolCode="DUMMY">Common\FwBlockService.h</Filename>\r
- <Filename ToolCode="DUMMY">Common\ia32\Ia32Fwh.c</Filename>\r
+ <Filename SupArchList="IA32">FWBlockService.c</Filename>\r
+ <Filename SupArchList="IA32">FwBlockService.h</Filename>\r
+ <Filename SupArchList="IA32">FvbInfo.c</Filename>\r
</SourceFiles>\r
<PackageDependencies>\r
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
<Protocol Usage="SOMETIMES_PRODUCED">\r
<ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>\r
</Protocol>\r
- <Protocol Usage="SOMETIMES_PRODUCED">\r
+ <Protocol Usage="ALWAYS_PRODUCED">\r
<ProtocolCName>gEfiFirmwareVolumeBlockProtocolGuid</ProtocolCName>\r
</Protocol>\r
<Protocol Usage="ALWAYS_PRODUCED">\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. 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
-Module Name:\r
-\r
- FWBlockService.c\r
- \r
-Abstract:\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include "FWBlockService.h"\r
-\r
-ESAL_FWB_GLOBAL *mFvbModuleGlobal;\r
-\r
-EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate = {\r
- FVB_DEVICE_SIGNATURE,\r
- {\r
- {\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
- },\r
- {\r
- END_DEVICE_PATH_TYPE,\r
- END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
- {\r
- sizeof (EFI_DEVICE_PATH_PROTOCOL),\r
- 0\r
- }\r
- }\r
- },\r
- 0,\r
- {\r
- FvbProtocolGetAttributes,\r
- FvbProtocolSetAttributes,\r
- FvbProtocolGetPhysicalAddress,\r
- FvbProtocolGetBlockSize,\r
- FvbProtocolRead,\r
- FvbProtocolWrite,\r
- FvbProtocolEraseBlocks,\r
- NULL\r
- },\r
- {\r
- FvbExtendProtocolEraseCustomBlockRange\r
- }\r
-};\r
-\r
-\r
-\r
-VOID\r
-EFIAPI\r
-FvbVirtualddressChangeEvent (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Fixup internal data so that EFI and SAL can be call in virtual mode.\r
- Call the passed in Child Notify event and convert the mFvbModuleGlobal\r
- date items to there virtual address.\r
-\r
- mFvbModuleGlobal->FvInstance[FVB_PHYSICAL] - Physical copy of instance data\r
- mFvbModuleGlobal->FvInstance[FVB_VIRTUAL] - Virtual pointer to common \r
- instance data.\r
-\r
-Arguments:\r
-\r
- (Standard EFI notify event - EFI_EVENT_NOTIFY)\r
-\r
-Returns: \r
-\r
- None\r
-\r
---*/\r
-{\r
- EFI_FW_VOL_INSTANCE *FwhInstance;\r
- UINTN Index;\r
-\r
- EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal->FvInstance[FVB_VIRTUAL]);\r
-\r
- //\r
- // Convert the base address of all the instances\r
- //\r
- Index = 0;\r
- FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];\r
- while (Index < mFvbModuleGlobal->NumFv) {\r
- EfiConvertPointer (0x0, (VOID **) &FwhInstance->FvBase[FVB_VIRTUAL]);\r
- FwhInstance = (EFI_FW_VOL_INSTANCE *)\r
- (\r
- (UINTN) ((UINT8 *) FwhInstance) + FwhInstance->VolumeHeader.HeaderLength +\r
- (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))\r
- );\r
- Index++;\r
- }\r
-\r
- EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal->FvbScratchSpace[FVB_VIRTUAL]);\r
- EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal);\r
-}\r
-\r
-EFI_STATUS\r
-GetFvbInstance (\r
- IN UINTN Instance,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- OUT EFI_FW_VOL_INSTANCE **FwhInstance,\r
- IN BOOLEAN Virtual\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Retrieves the physical address of a memory mapped FV\r
-\r
-Arguments:\r
- Instance - The FV instance whose base address is going to be\r
- returned\r
- Global - Pointer to ESAL_FWB_GLOBAL that contains all\r
- instance data\r
- FwhInstance - The EFI_FW_VOL_INSTANCE fimrware instance structure\r
- Virtual - Whether CPU is in virtual or physical mode\r
-\r
-Returns: \r
- EFI_SUCCESS - Successfully returns\r
- EFI_INVALID_PARAMETER - Instance not found\r
-\r
---*/\r
-{\r
- EFI_FW_VOL_INSTANCE *FwhRecord;\r
-\r
- if (Instance >= Global->NumFv) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Find the right instance of the FVB private data\r
- //\r
- FwhRecord = Global->FvInstance[Virtual];\r
- while (Instance > 0) {\r
- FwhRecord = (EFI_FW_VOL_INSTANCE *)\r
- (\r
- (UINTN) ((UINT8 *) FwhRecord) + FwhRecord->VolumeHeader.HeaderLength +\r
- (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))\r
- );\r
- Instance--;\r
- }\r
-\r
- *FwhInstance = FwhRecord;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-FvbGetPhysicalAddress (\r
- IN UINTN Instance,\r
- OUT EFI_PHYSICAL_ADDRESS *Address,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Retrieves the physical address of a memory mapped FV\r
-\r
-Arguments:\r
- Instance - The FV instance whose base address is going to be\r
- returned\r
- Address - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS \r
- that on successful return, contains the base address\r
- of the firmware volume. \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 - Successfully returns\r
- EFI_INVALID_PARAMETER - Instance not found\r
-\r
---*/\r
-{\r
- EFI_FW_VOL_INSTANCE *FwhInstance;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Find the right instance of the FVB private data\r
- //\r
- Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);\r
- ASSERT_EFI_ERROR (Status);\r
- *Address = FwhInstance->FvBase[Virtual];\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-FvbGetVolumeAttributes (\r
- IN UINTN Instance,\r
- OUT EFI_FVB_ATTRIBUTES *Attributes,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Retrieves attributes, insures positive polarity of attribute bits, returns\r
- resulting attributes in output parameter\r
-\r
-Arguments:\r
- Instance - The FV instance whose attributes is going to be \r
- returned\r
- Attributes - Output buffer which contains attributes\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 - Successfully returns\r
- EFI_INVALID_PARAMETER - Instance not found\r
-\r
---*/\r
-{\r
- EFI_FW_VOL_INSTANCE *FwhInstance;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Find the right instance of the FVB private data\r
- //\r
- Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);\r
- ASSERT_EFI_ERROR (Status);\r
- *Attributes = FwhInstance->VolumeHeader.Attributes;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-FvbGetLbaAddress (\r
- IN UINTN Instance,\r
- IN EFI_LBA Lba,\r
- OUT UINTN *LbaAddress,\r
- OUT UINTN *LbaLength,\r
- OUT UINTN *NumOfBlocks,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Retrieves the starting address of an LBA in an FV\r
-\r
-Arguments:\r
- Instance - The FV instance which the Lba belongs to\r
- Lba - The logical block address\r
- LbaAddress - On output, contains the physical starting address \r
- of the Lba\r
- LbaLength - On output, contains the length of the block\r
- NumOfBlocks - A pointer to a caller allocated UINTN in which the\r
- number of consecutive blocks starting with Lba is\r
- returned. All blocks in this range have a size of\r
- BlockSize\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 - Successfully returns\r
- EFI_INVALID_PARAMETER - Instance not found\r
-\r
---*/\r
-{\r
- UINT32 NumBlocks;\r
- UINT32 BlockLength;\r
- UINTN Offset;\r
- EFI_LBA StartLba;\r
- EFI_LBA NextLba;\r
- EFI_FW_VOL_INSTANCE *FwhInstance;\r
- EFI_FV_BLOCK_MAP_ENTRY *BlockMap;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Find the right instance of the FVB private data\r
- //\r
- Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- StartLba = 0;\r
- Offset = 0;\r
- BlockMap = &(FwhInstance->VolumeHeader.FvBlockMap[0]);\r
-\r
- //\r
- // Parse the blockmap of the FV to find which map entry the Lba belongs to\r
- //\r
- while (TRUE) {\r
- NumBlocks = BlockMap->NumBlocks;\r
- BlockLength = BlockMap->BlockLength;\r
-\r
- if (NumBlocks == 0 || BlockLength == 0) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- NextLba = StartLba + NumBlocks;\r
-\r
- //\r
- // The map entry found\r
- //\r
- if (Lba >= StartLba && Lba < NextLba) {\r
- Offset = Offset + (UINTN) MultU64x32 ((Lba - StartLba), BlockLength);\r
- if (LbaAddress != NULL) {\r
- *LbaAddress = FwhInstance->FvBase[Virtual] + Offset;\r
- }\r
-\r
- if (LbaLength != NULL) {\r
- *LbaLength = BlockLength;\r
- }\r
-\r
- if (NumOfBlocks != NULL) {\r
- *NumOfBlocks = (UINTN) (NextLba - Lba);\r
- }\r
-\r
- return EFI_SUCCESS;\r
- }\r
-\r
- StartLba = NextLba;\r
- Offset = Offset + NumBlocks * BlockLength;\r
- BlockMap++;\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-FvbReadBlock (\r
- IN UINTN Instance,\r
- IN EFI_LBA Lba,\r
- IN UINTN BlockOffset,\r
- IN OUT UINTN *NumBytes,\r
- IN UINT8 *Buffer,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Reads specified number of bytes into a buffer from the specified block\r
-\r
-Arguments:\r
- Instance - The FV instance to be read from\r
- Lba - The logical block address to be read from\r
- BlockOffset - Offset into the block at which to begin reading\r
- NumBytes - Pointer that on input contains the total size of\r
- the buffer. On output, it contains the total number\r
- of bytes read\r
- Buffer - Pointer to a caller allocated buffer that will be\r
- used to hold the data read\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 read successfully and \r
- contents are in Buffer\r
- EFI_BAD_BUFFER_SIZE - Read attempted across a LBA boundary. On output,\r
- NumBytes contains the total number of bytes returned\r
- in Buffer\r
- EFI_ACCESS_DENIED - The firmware volume is in the ReadDisabled state\r
- EFI_DEVICE_ERROR - The block device is not functioning correctly and \r
- could not be read\r
- EFI_INVALID_PARAMETER - Instance not found, or NumBytes, Buffer are NULL\r
-\r
---*/\r
-{\r
- EFI_FVB_ATTRIBUTES Attributes;\r
- UINTN LbaAddress;\r
- UINTN LbaLength;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Check for invalid conditions\r
- //\r
- if ((NumBytes == NULL) || (Buffer == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (*NumBytes == 0) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL, Global, Virtual);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Check if the FV is read enabled\r
- //\r
- FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);\r
-\r
- if ((Attributes & EFI_FVB_READ_STATUS) == 0) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- //\r
- // Perform boundary checks and adjust NumBytes\r
- //\r
- if (BlockOffset > LbaLength) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (LbaLength < (*NumBytes + BlockOffset)) {\r
- *NumBytes = (UINT32) (LbaLength - BlockOffset);\r
- Status = EFI_BAD_BUFFER_SIZE;\r
- }\r
-\r
- CopyMem (Buffer, (UINT8 *) (LbaAddress + BlockOffset), (UINTN) (*NumBytes));\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-FvbWriteBlock (\r
- IN UINTN Instance,\r
- IN EFI_LBA Lba,\r
- IN UINTN BlockOffset,\r
- IN OUT UINTN *NumBytes,\r
- IN UINT8 *Buffer,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Writes specified number of bytes from the input buffer to the block\r
-\r
-Arguments:\r
- Instance - The FV instance to be written to\r
- Lba - The starting logical block index to write to\r
- BlockOffset - Offset into the block at which to begin writing\r
- NumBytes - Pointer that on input contains the total size of\r
- the buffer. On output, it contains the total number\r
- of bytes actually written\r
- Buffer - Pointer to a caller allocated buffer that contains\r
- the source for the write\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 written successfully\r
- EFI_BAD_BUFFER_SIZE - Write attempted across a LBA boundary. On output,\r
- NumBytes contains the total number of bytes\r
- actually written\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\r
- EFI_INVALID_PARAMETER - Instance not found, or NumBytes, Buffer are NULL\r
-\r
---*/\r
-{\r
- EFI_FVB_ATTRIBUTES Attributes;\r
- UINTN LbaAddress;\r
- UINTN LbaLength;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Check for invalid conditions\r
- //\r
- if ((NumBytes == NULL) || (Buffer == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (*NumBytes == 0) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL, Global, Virtual);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Check if the FV is write enabled\r
- //\r
- FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);\r
-\r
- if ((Attributes & EFI_FVB_WRITE_STATUS) == 0) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- //\r
- // Perform boundary checks and adjust NumBytes\r
- //\r
- if (BlockOffset > LbaLength) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (LbaLength < (*NumBytes + BlockOffset)) {\r
- *NumBytes = (UINT32) (LbaLength - BlockOffset);\r
- Status = EFI_BAD_BUFFER_SIZE;\r
- }\r
- //\r
- // Write data\r
- //\r
- CopyMem ((UINT8 *) (LbaAddress + BlockOffset), Buffer, (UINTN) (*NumBytes));\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-FvbEraseBlock (\r
- IN UINTN Instance,\r
- IN EFI_LBA Lba,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Erases and initializes a firmware volume block\r
-\r
-Arguments:\r
- Instance - The FV instance to be erased\r
- Lba - The logical block index to be erased\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 erase request was successfully completed\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
-\r
- EFI_FVB_ATTRIBUTES Attributes;\r
- UINTN LbaAddress;\r
- UINTN LbaLength;\r
- EFI_STATUS Status;\r
- UINT8 Data;\r
-\r
- //\r
- // Check if the FV is write enabled\r
- //\r
- FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);\r
-\r
- if ((Attributes & EFI_FVB_WRITE_STATUS) == 0) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- //\r
- // Get the starting address of the block for erase.\r
- //\r
- Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL, Global, Virtual);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if ((Attributes & EFI_FVB_ERASE_POLARITY) != 0) {\r
- Data = 0xFF;\r
- } else {\r
- Data = 0x0;\r
- }\r
-\r
- SetMem ((UINT8 *) LbaAddress, LbaLength, Data);\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
-\r
- //\r
- // First LBA\r
- //\r
- FvbGetLbaAddress (Instance, StartLba, NULL, &LbaSize, NULL, Global, Virtual);\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
- FvbWriteBlock (Instance, StartLba, 0, &ScratchLbaSizeData, Global->FvbScratchSpace[Virtual], Global, Virtual);\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
- FvbGetLbaAddress (Instance, LastLba, NULL, &LbaSize, NULL, Global, Virtual);\r
- FvbReadBlock (Instance, LastLba, 0, &LbaSize, Global->FvbScratchSpace[Virtual], Global, Virtual);\r
- FvbEraseBlock (Instance, LastLba, Global, Virtual);\r
- }\r
-\r
- ScratchLbaSizeData = LbaSize - (OffsetStartLba + 1);\r
-\r
- return FvbWriteBlock (\r
- Instance,\r
- LastLba,\r
- (OffsetLastLba + 1),\r
- &ScratchLbaSizeData,\r
- Global->FvbScratchSpace[Virtual],\r
- Global,\r
- Virtual\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-FvbSetVolumeAttributes (\r
- IN UINTN Instance,\r
- IN OUT EFI_FVB_ATTRIBUTES *Attributes,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Modifies the current settings of the firmware volume according to the \r
- input parameter, and returns the new setting of the volume\r
-\r
-Arguments:\r
- Instance - The FV instance whose attributes is going to be \r
- modified\r
- Attributes - On input, it is a pointer to EFI_FVB_ATTRIBUTES \r
- containing the desired firmware volume settings.\r
- On successful return, it contains the new settings\r
- of the firmware volume\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 - Successfully returns\r
- EFI_ACCESS_DENIED - The volume setting is locked and cannot be modified\r
- EFI_INVALID_PARAMETER - Instance not found, or The attributes requested are\r
- in conflict with the capabilities as declared in the\r
- firmware volume header\r
-\r
---*/\r
-{\r
- EFI_FW_VOL_INSTANCE *FwhInstance;\r
- EFI_FVB_ATTRIBUTES OldAttributes;\r
- EFI_FVB_ATTRIBUTES *AttribPtr;\r
- UINT32 Capabilities;\r
- UINT32 OldStatus;\r
- UINT32 NewStatus;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Find the right instance of the FVB private data\r
- //\r
- Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- AttribPtr = (EFI_FVB_ATTRIBUTES *) &(FwhInstance->VolumeHeader.Attributes);\r
- OldAttributes = *AttribPtr;\r
- Capabilities = OldAttributes & EFI_FVB_CAPABILITIES;\r
- OldStatus = OldAttributes & EFI_FVB_STATUS;\r
- NewStatus = *Attributes & EFI_FVB_STATUS;\r
-\r
- //\r
- // If firmware volume is locked, no status bit can be updated\r
- //\r
- if (OldAttributes & EFI_FVB_LOCK_STATUS) {\r
- if (OldStatus ^ NewStatus) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- }\r
- //\r
- // Test read disable\r
- //\r
- if ((Capabilities & EFI_FVB_READ_DISABLED_CAP) == 0) {\r
- if ((NewStatus & EFI_FVB_READ_STATUS) == 0) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
- //\r
- // Test read enable\r
- //\r
- if ((Capabilities & EFI_FVB_READ_ENABLED_CAP) == 0) {\r
- if (NewStatus & EFI_FVB_READ_STATUS) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
- //\r
- // Test write disable\r
- //\r
- if ((Capabilities & EFI_FVB_WRITE_DISABLED_CAP) == 0) {\r
- if ((NewStatus & EFI_FVB_WRITE_STATUS) == 0) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
- //\r
- // Test write enable\r
- //\r
- if ((Capabilities & EFI_FVB_WRITE_ENABLED_CAP) == 0) {\r
- if (NewStatus & EFI_FVB_WRITE_STATUS) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
- //\r
- // Test lock\r
- //\r
- if ((Capabilities & EFI_FVB_LOCK_CAP) == 0) {\r
- if (NewStatus & EFI_FVB_LOCK_STATUS) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
-\r
- *AttribPtr = (*AttribPtr) & (0xFFFFFFFF & (~EFI_FVB_STATUS));\r
- *AttribPtr = (*AttribPtr) | NewStatus;\r
- *Attributes = *AttribPtr;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-//\r
-// FVB protocol APIs\r
-//\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolGetPhysicalAddress (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- OUT EFI_PHYSICAL_ADDRESS *Address\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Retrieves the physical address of the device.\r
-\r
-Arguments:\r
-\r
- This - Calling context\r
- Address - Output buffer containing the address.\r
-\r
-Returns:\r
-\r
-Returns: \r
- EFI_SUCCESS - Successfully returns\r
-\r
---*/\r
-{\r
- EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
-\r
- FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
-\r
- return FvbGetPhysicalAddress (FvbDevice->Instance, Address, mFvbModuleGlobal, EfiGoneVirtual ());\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolGetBlockSize (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- IN EFI_LBA Lba,\r
- OUT UINTN *BlockSize,\r
- OUT UINTN *NumOfBlocks\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Retrieve the size of a logical block\r
-\r
-Arguments:\r
- This - Calling context\r
- Lba - Indicates which block to return the size for.\r
- BlockSize - A pointer to a caller allocated UINTN in which\r
- the size of the block is returned\r
- NumOfBlocks - a pointer to a caller allocated UINTN in which the\r
- number of consecutive blocks starting with Lba is\r
- returned. All blocks in this range have a size of\r
- BlockSize\r
-\r
-Returns: \r
- EFI_SUCCESS - The firmware volume was read successfully and \r
- contents are in Buffer\r
-\r
---*/\r
-{\r
- EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
-\r
- FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
-\r
- return FvbGetLbaAddress (\r
- FvbDevice->Instance,\r
- Lba,\r
- NULL,\r
- BlockSize,\r
- NumOfBlocks,\r
- mFvbModuleGlobal,\r
- EfiGoneVirtual ()\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolGetAttributes (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- OUT EFI_FVB_ATTRIBUTES *Attributes\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Retrieves Volume attributes. No polarity translations are done.\r
-\r
-Arguments:\r
- This - Calling context\r
- Attributes - output buffer which contains attributes\r
-\r
-Returns: \r
- EFI_SUCCESS - Successfully returns\r
-\r
---*/\r
-{\r
- EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
-\r
- FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
-\r
- return FvbGetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ());\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolSetAttributes (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- IN OUT EFI_FVB_ATTRIBUTES *Attributes\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Sets Volume attributes. No polarity translations are done.\r
-\r
-Arguments:\r
- This - Calling context\r
- Attributes - output buffer which contains attributes\r
-\r
-Returns: \r
- EFI_SUCCESS - Successfully returns\r
-\r
---*/\r
-{\r
- EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
-\r
- FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
-\r
- return FvbSetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ());\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolEraseBlocks (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- ... \r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- The EraseBlock() function erases one or more blocks as denoted by the \r
- variable argument list. The entire parameter list of blocks must be verified\r
- prior to erasing any blocks. If a block is requested that does not exist \r
- within the associated firmware volume (it has a larger index than the last \r
- block of the firmware volume), the EraseBlock() function must return\r
- EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.\r
-\r
-Arguments:\r
- This - Calling context\r
- ... - Starting LBA followed by Number of Lba to erase. \r
- a -1 to terminate the list.\r
-\r
-Returns: \r
- EFI_SUCCESS - The erase request was successfully completed\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
- EFI_FW_VOL_INSTANCE *FwhInstance;\r
- UINTN NumOfBlocks;\r
- VA_LIST args;\r
- EFI_LBA StartingLba;\r
- UINTN NumOfLba;\r
- EFI_STATUS Status;\r
-\r
- FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
-\r
- Status = GetFvbInstance (FvbDevice->Instance, mFvbModuleGlobal, &FwhInstance, EfiGoneVirtual ());\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- NumOfBlocks = FwhInstance->NumOfBlocks;\r
-\r
- VA_START (args, This);\r
-\r
- do {\r
- StartingLba = VA_ARG (args, EFI_LBA);\r
- if (StartingLba == EFI_LBA_LIST_TERMINATOR) {\r
- break;\r
- }\r
-\r
- NumOfLba = VA_ARG (args, UINT32);\r
-\r
- //\r
- // Check input parameters\r
- //\r
- if (NumOfLba == 0) {\r
- VA_END (args);\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if ((StartingLba + NumOfLba) > NumOfBlocks) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- } while (1);\r
-\r
- VA_END (args);\r
-\r
- VA_START (args, This);\r
- do {\r
- StartingLba = VA_ARG (args, EFI_LBA);\r
- if (StartingLba == EFI_LBA_LIST_TERMINATOR) {\r
- break;\r
- }\r
-\r
- NumOfLba = VA_ARG (args, UINT32);\r
-\r
- while (NumOfLba > 0) {\r
- Status = FvbEraseBlock (FvbDevice->Instance, StartingLba, mFvbModuleGlobal, EfiGoneVirtual ());\r
- if (EFI_ERROR (Status)) {\r
- VA_END (args);\r
- return Status;\r
- }\r
-\r
- StartingLba++;\r
- NumOfLba--;\r
- }\r
-\r
- } while (1);\r
-\r
- VA_END (args);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolWrite (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- IN EFI_LBA Lba,\r
- IN UINTN Offset,\r
- IN OUT UINTN *NumBytes,\r
- IN UINT8 *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Writes data beginning at Lba:Offset from FV. The write terminates either\r
- when *NumBytes of data have been written, or when a block boundary is\r
- reached. *NumBytes is updated to reflect the actual number of bytes\r
- written. The write opertion does not include erase. This routine will\r
- attempt to write only the specified bytes. If the writes do not stick,\r
- it will return an error.\r
-\r
-Arguments:\r
- This - Calling context\r
- Lba - Block in which to begin write\r
- Offset - Offset in the block at which to begin write\r
- NumBytes - On input, indicates the requested write size. On\r
- output, indicates the actual number of bytes written\r
- Buffer - Buffer containing source data for the write.\r
-\r
-Returns: \r
- EFI_SUCCESS - The firmware volume was written successfully\r
- EFI_BAD_BUFFER_SIZE - Write attempted across a LBA boundary. On output,\r
- NumBytes contains the total number of bytes\r
- actually written\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\r
- EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL\r
-\r
---*/\r
-{\r
-\r
- EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
-\r
- FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
-\r
- return FvbWriteBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer, mFvbModuleGlobal, EfiGoneVirtual ());\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolRead (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- IN EFI_LBA Lba,\r
- IN UINTN Offset,\r
- IN OUT UINTN *NumBytes,\r
- IN UINT8 *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Reads data beginning at Lba:Offset from FV. The Read terminates either\r
- when *NumBytes of data have been read, or when a block boundary is\r
- reached. *NumBytes is updated to reflect the actual number of bytes\r
- written. The write opertion does not include erase. This routine will\r
- attempt to write only the specified bytes. If the writes do not stick,\r
- it will return an error.\r
-\r
-Arguments:\r
- This - Calling context\r
- Lba - Block in which to begin Read\r
- Offset - Offset in the block at which to begin Read\r
- NumBytes - On input, indicates the requested write size. On\r
- output, indicates the actual number of bytes Read\r
- Buffer - Buffer containing source data for the Read.\r
-\r
-Returns: \r
- EFI_SUCCESS - The firmware volume was read successfully and \r
- contents are in Buffer\r
- EFI_BAD_BUFFER_SIZE - Read attempted across a LBA boundary. On output,\r
- NumBytes contains the total number of bytes returned\r
- in Buffer\r
- EFI_ACCESS_DENIED - The firmware volume is in the ReadDisabled state\r
- EFI_DEVICE_ERROR - The block device is not functioning correctly and \r
- could not be read\r
- EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL\r
-\r
---*/\r
-{\r
-\r
- EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
-\r
- FvbDevice = FVB_DEVICE_FROM_THIS (This);\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
-Routine Description:\r
- Check the integrity of firmware volume header\r
-\r
-Arguments:\r
- FwVolHeader - A pointer to a firmware volume header\r
-\r
-Returns: \r
- EFI_SUCCESS - The firmware volume is consistent\r
- EFI_NOT_FOUND - The firmware volume has corrupted. So it is not an FV\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
- // HeaderLength cannot be an odd number\r
- //\r
- if ((FwVolHeader->Revision != EFI_FVH_REVISION) ||\r
- (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||\r
- (FwVolHeader->FvLength == ((UINTN) -1)) ||\r
- ((FwVolHeader->HeaderLength & 0x01) != 0)\r
- ) {\r
- return EFI_NOT_FOUND;\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 = *Ptr++;\r
- HeaderLength--;\r
- }\r
-\r
- if (Checksum != 0) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbInitialize (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- This function does common initialization for FVB services\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_FW_VOL_INSTANCE *FwhInstance;\r
- EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
- EFI_DXE_SERVICES *DxeServices;\r
- EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;\r
- UINT32 BufferSize;\r
- EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry;\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
- // Get the DXE services table\r
- //\r
- DxeServices = gDS;\r
-\r
- //\r
- // Allocate runtime services data for global variable, which contains\r
- // the private data of all firmware volume block instances\r
- //\r
- Status = gBS->AllocatePool (\r
- EfiRuntimeServicesData,\r
- sizeof (ESAL_FWB_GLOBAL),\r
- &mFvbModuleGlobal\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Calculate the total size for all firmware volume block instances\r
- //\r
- BufferSize = 0;\r
-\r
- FvHob.Raw = GetHobList ();\r
- while ((FvHob.Raw = GetNextHob (EFI_HOB_TYPE_FV, FvHob.Raw)) != NULL) {\r
- BaseAddress = FvHob.FirmwareVolume->BaseAddress;\r
- Length = FvHob.FirmwareVolume->Length;\r
- //\r
- // Check if it is a "real" flash\r
- //\r
- Status = DxeServices->GetMemorySpaceDescriptor (\r
- BaseAddress,\r
- &Descriptor\r
- );\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
-\r
- if (Descriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) {\r
- FvHob.Raw = GET_NEXT_HOB (FvHob);\r
- continue;\r
- }\r
-\r
- FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress;\r
- Status = ValidateFvHeader (FwVolHeader);\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Get FvbInfo\r
- //\r
- Status = GetFvbInfo (Length, &FwVolHeader);\r
- if (EFI_ERROR (Status)) {\r
- FvHob.Raw = GET_NEXT_HOB (FvHob);\r
- continue;\r
- }\r
- }\r
-\r
- BufferSize += (sizeof (EFI_FW_VOL_INSTANCE) + FwVolHeader->HeaderLength - sizeof (EFI_FIRMWARE_VOLUME_HEADER));\r
- FvHob.Raw = GET_NEXT_HOB (FvHob);\r
- }\r
-\r
- //\r
- // Only need to allocate once. There is only one copy of physical memory for\r
- // the private data of each FV instance. But in virtual mode or in physical\r
- // mode, the address of the the physical memory may be different.\r
- //\r
- Status = gBS->AllocatePool (\r
- EfiRuntimeServicesData,\r
- BufferSize,\r
- &mFvbModuleGlobal->FvInstance[FVB_PHYSICAL]\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Make a virtual copy of the FvInstance pointer.\r
- //\r
- FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];\r
- mFvbModuleGlobal->FvInstance[FVB_VIRTUAL] = FwhInstance;\r
-\r
- mFvbModuleGlobal->NumFv = 0;\r
- MaxLbaSize = 0;\r
-\r
- FvHob.Raw = GetHobList ();\r
- while (NULL != (FvHob.Raw = GetNextHob (EFI_HOB_TYPE_FV, FvHob.Raw))) {\r
- BaseAddress = FvHob.FirmwareVolume->BaseAddress;\r
- Length = FvHob.FirmwareVolume->Length;\r
- //\r
- // Check if it is a "real" flash\r
- //\r
- Status = DxeServices->GetMemorySpaceDescriptor (\r
- BaseAddress,\r
- &Descriptor\r
- );\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
-\r
- if (Descriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) {\r
- FvHob.Raw = GET_NEXT_HOB (FvHob);\r
- continue;\r
- }\r
-\r
- FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress;\r
- Status = ValidateFvHeader (FwVolHeader);\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Get FvbInfo to provide in FwhInstance.\r
- //\r
- Status = GetFvbInfo (Length, &FwVolHeader);\r
- if (EFI_ERROR (Status)) {\r
- FvHob.Raw = GET_NEXT_HOB (FvHob);\r
- continue;\r
- }\r
- //\r
- // Write healthy FV header back.\r
- //\r
- CopyMem (\r
- (VOID *) (UINTN) BaseAddress,\r
- (VOID *) FwVolHeader,\r
- FwVolHeader->HeaderLength\r
- );\r
- }\r
-\r
- FwhInstance->FvBase[FVB_PHYSICAL] = (UINTN) BaseAddress;\r
- FwhInstance->FvBase[FVB_VIRTUAL] = (UINTN) BaseAddress;\r
-\r
- CopyMem ((UINTN *) &(FwhInstance->VolumeHeader), (UINTN *) FwVolHeader, FwVolHeader->HeaderLength);\r
- FwVolHeader = &(FwhInstance->VolumeHeader);\r
- EfiInitializeLock (&(FwhInstance->FvbDevLock), EFI_TPL_HIGH_LEVEL);\r
-\r
- NumOfBlocks = 0;\r
-\r
- for (PtrBlockMapEntry = FwVolHeader->FvBlockMap; 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
- //\r
- if (MaxLbaSize < PtrBlockMapEntry->BlockLength) {\r
- MaxLbaSize = PtrBlockMapEntry->BlockLength;\r
- }\r
-\r
- NumOfBlocks = NumOfBlocks + PtrBlockMapEntry->NumBlocks;\r
- }\r
- //\r
- // The total number of blocks in the FV.\r
- //\r
- FwhInstance->NumOfBlocks = NumOfBlocks;\r
-\r
- //\r
- // Add a FVB Protocol Instance\r
- //\r
- Status = gBS->AllocatePool (\r
- EfiRuntimeServicesData,\r
- sizeof (EFI_FW_VOL_BLOCK_DEVICE),\r
- &FvbDevice\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- CopyMem (FvbDevice, &mFvbDeviceTemplate, sizeof (EFI_FW_VOL_BLOCK_DEVICE));\r
-\r
- FvbDevice->Instance = mFvbModuleGlobal->NumFv;\r
- mFvbModuleGlobal->NumFv++;\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
- //\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
- if (EFI_ERROR (Status)) {\r
- //\r
- // LocateDevicePath fails so install a new interface and device path\r
- //\r
- FwbHandle = NULL;\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &FwbHandle,\r
- &gEfiFirmwareVolumeBlockProtocolGuid,\r
- &FvbDevice->FwVolBlockInstance,\r
- &gEfiDevicePathProtocolGuid,\r
- &FvbDevice->DevicePath,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- } else if (EfiIsDevicePathEnd (TempFwbDevicePath)) {\r
- //\r
- // Device allready exists, so reinstall the FVB protocol\r
- //\r
- Status = gBS->HandleProtocol (\r
- FwbHandle,\r
- &gEfiFirmwareVolumeBlockProtocolGuid,\r
- &OldFwbInterface\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Status = gBS->ReinstallProtocolInterface (\r
- FwbHandle,\r
- &gEfiFirmwareVolumeBlockProtocolGuid,\r
- OldFwbInterface,\r
- &FvbDevice->FwVolBlockInstance\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- } else {\r
- //\r
- // There was a FVB protocol on an End Device Path node\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
- (UINTN) ((UINT8 *) FwhInstance) + FwVolHeader->HeaderLength +\r
- (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))\r
- );\r
-\r
- FvHob.Raw = GET_NEXT_HOB (FvHob);\r
- }\r
-\r
- //\r
- // Allocate for scratch space, an intermediate buffer for FVB extention\r
- //\r
- Status = gBS->AllocatePool (\r
- EfiRuntimeServicesData,\r
- MaxLbaSize,\r
- &mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL]\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- mFvbModuleGlobal->FvbScratchSpace[FVB_VIRTUAL] = mFvbModuleGlobal->FvbScratchSpace[FVB_PHYSICAL];\r
-\r
- return EFI_SUCCESS;\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. 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
-Module Name:\r
-\r
- FvbInfo.c\r
-\r
-Abstract:\r
-\r
- Defines data structure that is the volume header found.These data is intent\r
- to decouple FVB driver with FV header.\r
-\r
---*/\r
-\r
-#include "FlashLayout.h"\r
-\r
-#define FIRMWARE_BLOCK_SIZE 0x10000\r
-\r
-typedef struct {\r
- UINT64 FvLength;\r
- EFI_FIRMWARE_VOLUME_HEADER FvbInfo;\r
- //\r
- // EFI_FV_BLOCK_MAP_ENTRY ExtraBlockMap[n];//n=0\r
- //\r
- EFI_FV_BLOCK_MAP_ENTRY End[1];\r
-} EFI_FVB_MEDIA_INFO;\r
-\r
-#define FVB_MEDIA_BLOCK_SIZE FIRMWARE_BLOCK_SIZE\r
-#define RECOVERY_BOIS_BLOCK_NUM FIRMWARE_BLOCK_NUMBER\r
-#define SYSTEM_NV_BLOCK_NUM 2\r
-\r
-EFI_FVB_MEDIA_INFO mPlatformFvbMediaInfo[] = {\r
- //\r
- // Recovery BOIS FVB\r
- //\r
- {\r
- EFI_WINNT_FIRMWARE_LENGTH,\r
- {\r
- {\r
- 0,\r
- }, // ZeroVector[16]\r
- EFI_FIRMWARE_FILE_SYSTEM_GUID,\r
- FVB_MEDIA_BLOCK_SIZE * RECOVERY_BOIS_BLOCK_NUM,\r
- EFI_FVH_SIGNATURE,\r
- EFI_FVB_READ_ENABLED_CAP |\r
- EFI_FVB_READ_STATUS |\r
- EFI_FVB_WRITE_ENABLED_CAP |\r
- EFI_FVB_WRITE_STATUS |\r
- EFI_FVB_ERASE_POLARITY,\r
- sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),\r
- 0, // CheckSum\r
- {\r
- 0,\r
- }, // Reserved[3]\r
- 1, // Revision\r
- {\r
- RECOVERY_BOIS_BLOCK_NUM,\r
- FVB_MEDIA_BLOCK_SIZE,\r
- }\r
- },\r
- {\r
- 0,\r
- 0\r
- }\r
- },\r
- //\r
- // Systen NvStorage FVB\r
- //\r
- {\r
- EFI_WINNT_RUNTIME_UPDATABLE_LENGTH + EFI_WINNT_FTW_SPARE_BLOCK_LENGTH,\r
- {\r
- {\r
- 0,\r
- }, // ZeroVector[16]\r
- EFI_SYSTEM_NV_DATA_HOB_GUID,\r
- FVB_MEDIA_BLOCK_SIZE * SYSTEM_NV_BLOCK_NUM,\r
- EFI_FVH_SIGNATURE,\r
- EFI_FVB_READ_ENABLED_CAP |\r
- EFI_FVB_READ_STATUS |\r
- EFI_FVB_WRITE_ENABLED_CAP |\r
- EFI_FVB_WRITE_STATUS |\r
- EFI_FVB_ERASE_POLARITY,\r
- sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),\r
- 0, // CheckSum\r
- {\r
- 0,\r
- }, // Reserved[3]\r
- 1, // Revision\r
- {\r
- SYSTEM_NV_BLOCK_NUM,\r
- FVB_MEDIA_BLOCK_SIZE,\r
- }\r
- },\r
- {\r
- 0,\r
- 0\r
- }\r
- }\r
-};\r
-\r
-EFI_STATUS\r
-GetFvbInfo (\r
- IN UINT64 FvLength,\r
- OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo\r
- )\r
-{\r
- UINTN Index;\r
-\r
- for (Index = 0; Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB_MEDIA_INFO); Index += 1) {\r
- if (mPlatformFvbMediaInfo[Index].FvLength == FvLength) {\r
- *FvbInfo = &mPlatformFvbMediaInfo[Index].FvbInfo;\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. 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
-Module Name:\r
-\r
- FwBlockService.h\r
- \r
-Abstract:\r
-\r
- Firmware volume block driver for Intel Firmware Hub (FWH) device\r
-\r
---*/\r
-\r
-#ifndef _FW_BLOCK_SERVICE_H\r
-#define _FW_BLOCK_SERVICE_H\r
-\r
-//\r
-// BugBug: Add documentation here for data structure!!!!\r
-//\r
-#define FVB_PHYSICAL 0\r
-#define FVB_VIRTUAL 1\r
-\r
-typedef struct {\r
- EFI_LOCK FvbDevLock;\r
- UINTN FvBase[2];\r
- UINTN NumOfBlocks;\r
- EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;\r
-} EFI_FW_VOL_INSTANCE;\r
-\r
-typedef struct {\r
- UINT32 NumFv;\r
- EFI_FW_VOL_INSTANCE *FvInstance[2];\r
- UINT8 *FvbScratchSpace[2];\r
-} ESAL_FWB_GLOBAL;\r
-\r
-//\r
-// Fvb Protocol instance data\r
-//\r
-#define FVB_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE)\r
-#define FVB_EXTEND_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, FvbExtension, FVB_DEVICE_SIGNATURE)\r
-#define FVB_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('F', 'V', 'B', 'N')\r
-\r
-typedef struct {\r
- MEMMAP_DEVICE_PATH MemMapDevPath;\r
- EFI_DEVICE_PATH_PROTOCOL EndDevPath;\r
-} FV_DEVICE_PATH;\r
-\r
-typedef struct {\r
- UINTN Signature;\r
- FV_DEVICE_PATH DevicePath;\r
- UINTN Instance;\r
- EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FwVolBlockInstance;\r
- EFI_FVB_EXTENSION_PROTOCOL FvbExtension;\r
-} EFI_FW_VOL_BLOCK_DEVICE;\r
-\r
-EFI_STATUS\r
-GetFvbInfo (\r
- IN UINT64 FvLength,\r
- OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-FvbReadBlock (\r
- IN UINTN Instance,\r
- IN EFI_LBA Lba,\r
- IN UINTN BlockOffset,\r
- IN OUT UINTN *NumBytes,\r
- IN UINT8 *Buffer,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-FvbWriteBlock (\r
- IN UINTN Instance,\r
- IN EFI_LBA Lba,\r
- IN UINTN BlockOffset,\r
- IN OUT UINTN *NumBytes,\r
- IN UINT8 *Buffer,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-FvbEraseBlock (\r
- IN UINTN Instance,\r
- IN EFI_LBA Lba,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-FvbSetVolumeAttributes (\r
- IN UINTN Instance,\r
- IN OUT EFI_FVB_ATTRIBUTES *Attributes,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-FvbGetVolumeAttributes (\r
- IN UINTN Instance,\r
- OUT EFI_FVB_ATTRIBUTES *Attributes,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-FvbGetPhysicalAddress (\r
- IN UINTN Instance,\r
- OUT EFI_PHYSICAL_ADDRESS *Address,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbInitialize (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-;\r
-\r
-\r
-VOID\r
-EFIAPI\r
-FvbClassAddressChangeEvent (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-FvbGetLbaAddress (\r
- IN UINTN Instance,\r
- IN EFI_LBA Lba,\r
- OUT UINTN *LbaAddress,\r
- OUT UINTN *LbaLength,\r
- OUT UINTN *NumOfBlocks,\r
- IN ESAL_FWB_GLOBAL *Global,\r
- IN BOOLEAN Virtual\r
- )\r
-;\r
-\r
-//\r
-// Protocol APIs\r
-//\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolGetAttributes (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- OUT EFI_FVB_ATTRIBUTES *Attributes\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolSetAttributes (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- IN OUT EFI_FVB_ATTRIBUTES *Attributes\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolGetPhysicalAddress (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- OUT EFI_PHYSICAL_ADDRESS *Address\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolGetBlockSize (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- IN EFI_LBA Lba,\r
- OUT UINTN *BlockSize,\r
- OUT UINTN *NumOfBlocks\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolRead (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- IN EFI_LBA Lba,\r
- IN UINTN Offset,\r
- IN OUT UINTN *NumBytes,\r
- IN UINT8 *Buffer\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolWrite (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- IN EFI_LBA Lba,\r
- IN UINTN Offset,\r
- IN OUT UINTN *NumBytes,\r
- IN UINT8 *Buffer\r
- )\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-FvbProtocolEraseBlocks (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,\r
- ...\r
- )\r
-;\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
-#endif\r