| /**@file | |
| Firmware Volume Block Protocol Runtime Interface Abstraction | |
| And FVB Extension protocol Runtime Interface Abstraction | |
| mFvbEntry is an array of Handle Fvb pairs. The Fvb Lib Instance matches the | |
| index in the mFvbEntry array. This should be the same sequence as the FVB's | |
| were described in the HOB. We have to remember the handle so we can tell if | |
| the protocol has been reinstalled and it needs updating. | |
| Copyright (c) 2006 - 2008, Intel Corporation | |
| All rights reserved. This program and the accompanying materials | |
| are licensed and made available under the terms and conditions of the BSD License | |
| which accompanies this distribution. The full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| **/ | |
| #include "Fvb.h" | |
| // | |
| // Event for Set Virtual Map Changed Event | |
| // | |
| EFI_EVENT mSetVirtualMapChangedEvent = NULL; | |
| // | |
| // Lib will ASSERT if more FVB devices than this are added to the system. | |
| // | |
| FVB_ENTRY *mFvbEntry = NULL; | |
| EFI_EVENT mFvbRegistration = NULL; | |
| UINTN mFvbCount = 0; | |
| /** | |
| Check whether an address is runtime memory or not. | |
| @param Address The Address being checked. | |
| @retval TRUE The address is runtime memory. | |
| @retval FALSE The address is not runtime memory. | |
| **/ | |
| BOOLEAN | |
| IsRuntimeMemory ( | |
| IN VOID *Address | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| UINT8 TmpMemoryMap[1]; | |
| UINTN MapKey; | |
| UINTN DescriptorSize; | |
| UINT32 DescriptorVersion; | |
| UINTN MemoryMapSize; | |
| EFI_MEMORY_DESCRIPTOR *MemoryMap; | |
| EFI_MEMORY_DESCRIPTOR *MemoryMapPtr; | |
| BOOLEAN IsRuntime; | |
| UINTN Index; | |
| IsRuntime = FALSE; | |
| // | |
| // Get System MemoryMapSize | |
| // | |
| MemoryMapSize = 1; | |
| Status = gBS->GetMemoryMap ( | |
| &MemoryMapSize, | |
| (EFI_MEMORY_DESCRIPTOR *)TmpMemoryMap, | |
| &MapKey, | |
| &DescriptorSize, | |
| &DescriptorVersion | |
| ); | |
| ASSERT (Status == EFI_BUFFER_TOO_SMALL); | |
| // | |
| // Enlarge space here, because we will allocate pool now. | |
| // | |
| MemoryMapSize += EFI_PAGE_SIZE; | |
| MemoryMap = AllocatePool (MemoryMapSize); | |
| ASSERT (MemoryMap != NULL); | |
| // | |
| // Get System MemoryMap | |
| // | |
| Status = gBS->GetMemoryMap ( | |
| &MemoryMapSize, | |
| MemoryMap, | |
| &MapKey, | |
| &DescriptorSize, | |
| &DescriptorVersion | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| MemoryMapPtr = MemoryMap; | |
| // | |
| // Search the request Address | |
| // | |
| for (Index = 0; Index < (MemoryMapSize / DescriptorSize); Index++) { | |
| if (((EFI_PHYSICAL_ADDRESS)(UINTN)Address >= MemoryMap->PhysicalStart) && | |
| ((EFI_PHYSICAL_ADDRESS)(UINTN)Address < MemoryMap->PhysicalStart | |
| + LShiftU64 (MemoryMap->NumberOfPages, EFI_PAGE_SHIFT))) { | |
| // | |
| // Found it | |
| // | |
| if ((MemoryMap->Attribute & EFI_MEMORY_RUNTIME) != 0) { | |
| IsRuntime = TRUE; | |
| } | |
| break; | |
| } | |
| // | |
| // Get next item | |
| // | |
| MemoryMap = (EFI_MEMORY_DESCRIPTOR *)((UINTN) MemoryMap + DescriptorSize); | |
| } | |
| // | |
| // Done | |
| // | |
| FreePool (MemoryMapPtr); | |
| return IsRuntime; | |
| } | |
| /** | |
| Update mFvbEntry. Add new entry, or update existing entry if Fvb protocol is | |
| reinstalled. | |
| @param Event The Event that is being processed | |
| @param Context Event Context | |
| **/ | |
| VOID | |
| EFIAPI | |
| FvbNotificationEvent ( | |
| IN EFI_EVENT Event, | |
| IN VOID *Context | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| UINTN BufferSize; | |
| EFI_HANDLE Handle; | |
| UINTN Index; | |
| UINTN UpdateIndex; | |
| while (TRUE) { | |
| BufferSize = sizeof (Handle); | |
| Status = gBS->LocateHandle ( | |
| ByRegisterNotify, | |
| &gEfiFirmwareVolumeBlockProtocolGuid, | |
| mFvbRegistration, | |
| &BufferSize, | |
| &Handle | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| // | |
| // Exit Path of While Loop.... | |
| // | |
| break; | |
| } | |
| UpdateIndex = MAX_FVB_COUNT; | |
| for (Index = 0; Index < mFvbCount; Index++) { | |
| if (mFvbEntry[Index].Handle == Handle) { | |
| // | |
| // If the handle is already in the table just update the protocol | |
| // | |
| UpdateIndex = Index; | |
| break; | |
| } | |
| } | |
| if (UpdateIndex == MAX_FVB_COUNT) { | |
| // | |
| // Use the next free slot for a new entry | |
| // | |
| UpdateIndex = mFvbCount++; | |
| // | |
| // Check the UpdateIndex whether exceed the maximum value. | |
| // | |
| ASSERT (UpdateIndex < MAX_FVB_COUNT); | |
| mFvbEntry[UpdateIndex].Handle = Handle; | |
| } | |
| // | |
| // The array does not have enough entries | |
| // | |
| ASSERT (UpdateIndex < MAX_FVB_COUNT); | |
| // | |
| // Get the interface pointer and if it's ours, skip it | |
| // | |
| Status = gBS->HandleProtocol ( | |
| Handle, | |
| &gEfiFirmwareVolumeBlockProtocolGuid, | |
| (VOID **) &mFvbEntry[UpdateIndex].Fvb | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| Status = gBS->HandleProtocol ( | |
| Handle, | |
| &gEfiFvbExtensionProtocolGuid, | |
| (VOID **) &mFvbEntry[UpdateIndex].FvbExtension | |
| ); | |
| if (Status != EFI_SUCCESS) { | |
| mFvbEntry[UpdateIndex].FvbExtension = NULL; | |
| } | |
| // | |
| // Check the FVB can be accessed in RUNTIME, The FVBs in FVB handle list come from two ways: | |
| // 1) Dxe Core. (FVB information is transferred from FV HOB). 2) FVB driver. The FVB produced | |
| // Dxe core is used to discovery DXE driver and dispatch. These FVBs can only be accessed in | |
| // boot time. FVB driver will discovery all FV in FLASH and these FVBs can be accessed in | |
| // runtime. The FVB itself produced by FVB driver is allocated in runtime memory. So we can | |
| // determine the what FVB can be accessed in RUNTIME by judging whether FVB itself is allocated | |
| // in RUNTIME memory. | |
| // | |
| mFvbEntry[UpdateIndex].IsRuntimeAccess = IsRuntimeMemory (mFvbEntry[UpdateIndex].Fvb); | |
| } | |
| } | |
| /** | |
| Convert all pointers in mFvbEntry after ExitBootServices. | |
| @param Event The Event that is being processed | |
| @param Context Event Context | |
| **/ | |
| VOID | |
| EFIAPI | |
| FvbVirtualAddressChangeNotifyEvent ( | |
| IN EFI_EVENT Event, | |
| IN VOID *Context | |
| ) | |
| { | |
| UINTN Index; | |
| if (mFvbEntry != NULL) { | |
| for (Index = 0; Index < MAX_FVB_COUNT; Index++) { | |
| if (!mFvbEntry[Index].IsRuntimeAccess) { | |
| continue; | |
| } | |
| if (mFvbEntry[Index].Fvb != NULL) { | |
| EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetBlockSize); | |
| EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetPhysicalAddress); | |
| EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetAttributes); | |
| EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->SetAttributes); | |
| EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->Read); | |
| EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->Write); | |
| EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->EraseBlocks); | |
| EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb); | |
| } | |
| if (mFvbEntry[Index].FvbExtension != NULL) { | |
| EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].FvbExtension->EraseFvbCustomBlock); | |
| EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].FvbExtension); | |
| } | |
| } | |
| EfiConvertPointer (0x0, (VOID **) &mFvbEntry); | |
| } | |
| } | |
| /** | |
| Library constructor function entry. | |
| @param ImageHandle The handle of image who call this library. | |
| @param SystemTable The point of System Table. | |
| @retval EFI_SUCESS Success construct this library. | |
| @retval Others Fail to construct this library. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| FvbLibInitialize ( | |
| IN EFI_HANDLE ImageHandle, | |
| IN EFI_SYSTEM_TABLE *SystemTable | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| mFvbEntry = AllocateRuntimeZeroPool (sizeof (FVB_ENTRY) * MAX_FVB_COUNT); | |
| ASSERT (mFvbEntry != NULL); | |
| // | |
| // Register FvbNotificationEvent () notify function. | |
| // | |
| EfiCreateProtocolNotifyEvent ( | |
| &gEfiFirmwareVolumeBlockProtocolGuid, | |
| TPL_CALLBACK, | |
| FvbNotificationEvent, | |
| NULL, | |
| &mFvbRegistration | |
| ); | |
| // | |
| // Register SetVirtualAddressMap () notify function | |
| // | |
| Status = gBS->CreateEvent ( | |
| EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, | |
| TPL_NOTIFY, | |
| FvbVirtualAddressChangeNotifyEvent, | |
| NULL, | |
| &mSetVirtualMapChangedEvent | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| return Status; | |
| } | |
| // | |
| // ============================================================================= | |
| // The following functions wrap Fvb protocol in the Runtime Lib functions. | |
| // The Instance translates into Fvb instance. The Fvb order defined by HOBs and | |
| // thus the sequence of FVB protocol addition define Instance. | |
| // | |
| /** | |
| Reads specified number of bytes into a buffer from the specified block. | |
| The EfiFvbReadBlock() function reads the requested number of bytes from | |
| the requested block in the specified firmware volume and stores them in | |
| the provided buffer. Implementations should be mindful that the firmware | |
| volume might be in the ReadDisabled state. If it is in this state, the | |
| EfiFvbReadBlock() function must return the status code EFI_ACCESS_DENIED | |
| without modifying the contents of the buffer. | |
| The EfiFvbReadBlock() function must also prevent spanning block boundaries. | |
| If a read is requested that would span a block boundary, the read must read | |
| up to the boundary but not beyond. The output parameter NumBytes must be | |
| set to correctly indicate the number of bytes actually read. | |
| The caller must be aware that a read may be partially completed. | |
| If NumBytes is NULL, then ASSERT(). | |
| If Buffer is NULL, then ASSERT(). | |
| @param[in] Instance The FV instance to be read from. | |
| @param[in] Lba The logical block address to be read from | |
| @param[in] Offset The offset relative to the block, at which to begin reading. | |
| @param[in, out] NumBytes Pointer to a UINTN. On input, *NumBytes contains the total | |
| size of the buffer. On output, it contains the actual number | |
| of bytes read. | |
| @param[out] Buffer Pointer to a caller allocated buffer that will be | |
| used to hold the data read. | |
| @retval EFI_SUCCESS The firmware volume was read successfully and contents are in Buffer. | |
| @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA boundary. On output, NumBytes contains | |
| the total number of bytes returned in Buffer. | |
| @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state. | |
| @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be read. | |
| @retval EFI_INVALID_PARAMETER Invalid parameter, Instance is larger than the max FVB number. Lba index | |
| is larger than the last block of the firmware volume. Offset is larger | |
| than the block size. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| EfiFvbReadBlock ( | |
| IN UINTN Instance, | |
| IN EFI_LBA Lba, | |
| IN UINTN Offset, | |
| IN OUT UINTN *NumBytes, | |
| OUT UINT8 *Buffer | |
| ) | |
| { | |
| ASSERT (NumBytes != NULL); | |
| ASSERT (Buffer != NULL); | |
| if (Instance >= mFvbCount) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| return mFvbEntry[Instance].Fvb->Read (mFvbEntry[Instance].Fvb, Lba, Offset, NumBytes, Buffer); | |
| } | |
| /** | |
| Writes specified number of bytes from the input buffer to the block | |
| The EfiFvbWriteBlock() function writes the specified number of bytes | |
| from the provided buffer to the specified block and offset in the | |
| requested firmware volume. | |
| If the firmware volume is sticky write, the caller must ensure that | |
| all the bits of the specified range to write are in the EFI_FVB_ERASE_POLARITY | |
| state before calling the EfiFvbWriteBlock() function, or else the | |
| result will be unpredictable. This unpredictability arises because, | |
| for a sticky-write firmware volume, a write may negate a bit in the | |
| EFI_FVB_ERASE_POLARITY state but it cannot flip it back again. In | |
| general, before calling the EfiFvbWriteBlock() function, the caller | |
| should call the EfiFvbEraseBlock() function first to erase the specified | |
| block to write. A block erase cycle will transition bits from the | |
| (NOT)EFI_FVB_ERASE_POLARITY state back to the EFI_FVB_ERASE_POLARITY state. | |
| Implementations should be mindful that the firmware volume might be | |
| in the WriteDisabled state. If it is in this state, the EfiFvbWriteBlock() | |
| function must return the status code EFI_ACCESS_DENIED without modifying | |
| the contents of the firmware volume. | |
| The EfiFvbWriteBlock() function must also prevent spanning block boundaries. | |
| If a write is requested that spans a block boundary, the write must store | |
| up to the boundary but not beyond. The output parameter NumBytes must be | |
| set to correctly indicate the number of bytes actually written. The caller | |
| must be aware that a write may be partially completed. | |
| All writes, partial or otherwise, must be fully flushed to the hardware | |
| before the EfiFvbWriteBlock() function returns. | |
| If NumBytes is NULL, then ASSERT(). | |
| @param Instance The FV instance to be written to. | |
| @param Lba The starting logical block index to write. | |
| @param Offset The offset relative to the block to write. | |
| @param NumBytes Pointer to a UINTN. On input, *NumBytes contains | |
| the total size of the buffer. On output, it contains | |
| the actual number of bytes written. | |
| @param Buffer Pointer to a caller allocated buffer that contains | |
| the source for the write | |
| @retval EFI_SUCCESS The firmware volume was written successfully. | |
| @retval EFI_BAD_BUFFER_SIZE The write was attempted across an LBA boundary. | |
| On output, NumBytes contains the total number of bytes actually written. | |
| @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. | |
| @retval EFI_DEVICE_ERROR The block device is malfunctioning and could not be written. | |
| @retval EFI_INVALID_PARAMETER Invalid parameter, Instance is larger than the max FVB number. | |
| Lba index is larger than the last block of the firmware volume. | |
| Offset is larger than the block size. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| EfiFvbWriteBlock ( | |
| IN UINTN Instance, | |
| IN EFI_LBA Lba, | |
| IN UINTN Offset, | |
| IN OUT UINTN *NumBytes, | |
| IN UINT8 *Buffer | |
| ) | |
| { | |
| ASSERT (NumBytes != NULL); | |
| if (Instance >= mFvbCount) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| return mFvbEntry[Instance].Fvb->Write (mFvbEntry[Instance].Fvb, Lba, Offset, NumBytes, Buffer); | |
| } | |
| /** | |
| Erases and initializes a firmware volume block. | |
| The EfiFvbEraseBlock() function erases one block specified by Lba. | |
| Implementations should be mindful that the firmware volume might | |
| be in the WriteDisabled state. If it is in this state, the EfiFvbEraseBlock() | |
| function must return the status code EFI_ACCESS_DENIED without | |
| modifying the contents of the firmware volume. If Instance is | |
| larger than the max FVB number, or Lba index is larger than the | |
| last block of the firmware volume, this function return the status | |
| code EFI_INVALID_PARAMETER. | |
| All calls to EfiFvbEraseBlock() must be fully flushed to the | |
| hardware before this function returns. | |
| @param[in] Instance The FV instance to be erased. | |
| @param[in] Lba The logical block index to be erased from. | |
| @retval EFI_SUCCESS The erase request was successfully completed. | |
| @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. | |
| @retval EFI_DEVICE_ERROR The block device is not functioning correctly and | |
| could not be written. The firmware device may | |
| have been partially erased. | |
| @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max | |
| FVB number. Lba index is larger than the last block | |
| of the firmware volume. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| EfiFvbEraseBlock ( | |
| IN UINTN Instance, | |
| IN EFI_LBA Lba | |
| ) | |
| { | |
| if (Instance >= mFvbCount) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| return mFvbEntry[Instance].Fvb->EraseBlocks (mFvbEntry[Instance].Fvb, Lba, 1, EFI_LBA_LIST_TERMINATOR); | |
| } | |
| /** | |
| Retrieves the attributes and current settings of the specified block, | |
| returns resulting attributes in output parameter. | |
| The EfiFvbGetAttributes() function retrieves the attributes and current | |
| settings of the block specified by Instance. If Instance is larger than | |
| the max FVB number, this function returns the status code EFI_INVALID_PARAMETER. | |
| If Attributes is NULL, then ASSERT(). | |
| @param[in] Instance The FV instance to be operated. | |
| @param[out] Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the | |
| attributes and current settings are returned. | |
| @retval EFI_EFI_SUCCESS The firmware volume attributes were returned. | |
| @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max FVB number. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| EfiFvbGetVolumeAttributes ( | |
| IN UINTN Instance, | |
| OUT EFI_FVB_ATTRIBUTES_2 *Attributes | |
| ) | |
| { | |
| ASSERT (Attributes != NULL); | |
| if (Instance >= mFvbCount) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| return mFvbEntry[Instance].Fvb->GetAttributes (mFvbEntry[Instance].Fvb, Attributes); | |
| } | |
| /** | |
| Modify the attributes and current settings of the specified block | |
| according to the input parameter. | |
| The EfiFvbSetAttributes() function sets configurable firmware volume | |
| attributes and returns the new settings of the firmware volume specified | |
| by Instance. If Instance is larger than the max FVB number, this function | |
| returns the status code EFI_INVALID_PARAMETER. | |
| If Attributes is NULL, then ASSERT(). | |
| @param[in] Instance The FV instance to be operated. | |
| @param[in, out]Attributes On input, Attributes is a pointer to EFI_FVB_ATTRIBUTES_2 | |
| that contains the desired firmware volume settings. | |
| On successful return, it contains the new settings of the firmware volume. | |
| @retval EFI_EFI_SUCCESS The firmware volume attributes were modified successfully. | |
| @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max FVB number. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| EfiFvbSetVolumeAttributes ( | |
| IN UINTN Instance, | |
| IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes | |
| ) | |
| { | |
| ASSERT (Attributes != NULL); | |
| if (Instance >= mFvbCount) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| return mFvbEntry[Instance].Fvb->SetAttributes (mFvbEntry[Instance].Fvb, Attributes); | |
| } | |
| /** | |
| Retrieves the physical address of the specified memory mapped FV. | |
| Retrieve the base address of a memory-mapped firmware volume specified by Instance. | |
| If Instance is larger than the max FVB number, this function returns the status | |
| code EFI_INVALID_PARAMETER. | |
| If BaseAddress is NULL, then ASSERT(). | |
| @param[in] Instance The FV instance to be operated. | |
| @param[out] BaseAddress Pointer to a caller allocated EFI_PHYSICAL_ADDRESS | |
| that on successful return, contains the base address | |
| of the firmware volume. | |
| @retval EFI_EFI_SUCCESS The firmware volume base address is returned. | |
| @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max FVB number. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| EfiFvbGetPhysicalAddress ( | |
| IN UINTN Instance, | |
| OUT EFI_PHYSICAL_ADDRESS *BaseAddress | |
| ) | |
| { | |
| ASSERT (BaseAddress != NULL); | |
| if (Instance >= mFvbCount) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| return mFvbEntry[Instance].Fvb->GetPhysicalAddress (mFvbEntry[Instance].Fvb, BaseAddress); | |
| } | |
| /** | |
| Retrieve the block size of the specified fv. | |
| The EfiFvbGetBlockSize() function retrieves the size of the requested block. | |
| It also returns the number of additional blocks with the identical size. | |
| If Instance is larger than the max FVB number, or Lba index is larger than | |
| the last block of the firmware volume, this function return the status code | |
| EFI_INVALID_PARAMETER. | |
| If BlockSize is NULL, then ASSERT(). | |
| If NumOfBlocks is NULL, then ASSERT(). | |
| @param[in] Instance The FV instance to be operated. | |
| @param[in] Lba Indicates which block to return the size for. | |
| @param[out] BlockSize Pointer to a caller-allocated UINTN in which the | |
| size of the block is returned. | |
| @param[out] NumOfBlocks Pointer to a caller-allocated UINTN in which the | |
| number of consecutive blocks, starting with Lba, | |
| is returned. All blocks in this range have a size of BlockSize. | |
| @retval EFI_EFI_SUCCESS The firmware volume base address is returned. | |
| @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max FVB number. | |
| Lba index is larger than the last block of the firmware volume. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| EfiFvbGetBlockSize ( | |
| IN UINTN Instance, | |
| IN EFI_LBA Lba, | |
| OUT UINTN *BlockSize, | |
| OUT UINTN *NumOfBlocks | |
| ) | |
| { | |
| ASSERT (BlockSize != NULL); | |
| ASSERT (NumOfBlocks != NULL); | |
| if (Instance >= mFvbCount) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| return mFvbEntry[Instance].Fvb->GetBlockSize (mFvbEntry[Instance].Fvb, Lba, BlockSize, NumOfBlocks); | |
| } | |
| /** | |
| Erases and initializes a specified range of a firmware volume. | |
| The EfiFvbEraseCustomBlockRange() function erases the specified range in the firmware | |
| volume index by Instance. If Instance is larger than the max FVB number, StartLba or | |
| LastLba index is larger than the last block of the firmware volume, StartLba > LastLba | |
| or StartLba equal to LastLba but OffsetStartLba > OffsetLastLba, this function return | |
| the status code EFI_INVALID_PARAMETER. | |
| @param[in] Instance The FV instance to be operated. | |
| @param[in] StartLba The starting logical block index to be erased. | |
| @param[in] OffsetStartLba Offset into the starting block at which to | |
| begin erasing. | |
| @param[in] LastLba The last logical block index to be erased. | |
| @param[in] OffsetLastLba Offset into the last block at which to end erasing. | |
| @retval EFI_EFI_SUCCESS Successfully erase custom block range | |
| @retval EFI_INVALID_PARAMETER Invalid parameter. Instance is larger than the max FVB number. | |
| @retval EFI_UNSUPPORTED Firmware volume block device has no this capability. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| EfiFvbEraseCustomBlockRange ( | |
| IN UINTN Instance, | |
| IN EFI_LBA StartLba, | |
| IN UINTN OffsetStartLba, | |
| IN EFI_LBA LastLba, | |
| IN UINTN OffsetLastLba | |
| ) | |
| { | |
| if (Instance >= mFvbCount) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| if (!(mFvbEntry[Instance].FvbExtension)) { | |
| return EFI_UNSUPPORTED; | |
| } | |
| if (!(mFvbEntry[Instance].FvbExtension->EraseFvbCustomBlock)) { | |
| return EFI_UNSUPPORTED; | |
| } | |
| return mFvbEntry[Instance].FvbExtension->EraseFvbCustomBlock ( | |
| mFvbEntry[Instance].FvbExtension, | |
| StartLba, | |
| OffsetStartLba, | |
| LastLba, | |
| OffsetLastLba | |
| ); | |
| } |