X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=EdkModulePkg%2FLibrary%2FEdkFvbServiceLib%2FIa32%2FFvb.c;h=c94c8242ac1419bb8666ce582c7888eecf76dd1d;hp=04693eb6322b184c3d448c2ee2275cd89144be6c;hb=fce67685cc278da736f10e7721fddc91cbdac471;hpb=95ed6470d1e3acdb355316138935e43052f72274 diff --git a/EdkModulePkg/Library/EdkFvbServiceLib/Ia32/Fvb.c b/EdkModulePkg/Library/EdkFvbServiceLib/Ia32/Fvb.c index 04693eb632..c94c8242ac 100644 --- a/EdkModulePkg/Library/EdkFvbServiceLib/Ia32/Fvb.c +++ b/EdkModulePkg/Library/EdkFvbServiceLib/Ia32/Fvb.c @@ -1,19 +1,4 @@ -/*++ - -Copyright (c) 2006, 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. - -Module Name: - - Fvb.c - -Abstract: +/**@file Firmware Volume Block Protocol Runtime Abstraction @@ -23,11 +8,17 @@ Abstract: the protocol has been reinstalled and it needs updateing. If you are using any of these lib functions.you must first call FvbInitialize (). + +Copyright (c) 2006, 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. -Key: - FVB - Firmware Volume Block - ---*/ +**/ #include "Fvb.h" @@ -39,6 +30,105 @@ STATIC EFI_EVENT mFvbRegistration; STATIC BOOLEAN mEfiFvbInitialized = FALSE; STATIC UINTN mFvbCount; +/** + 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; + Status = gBS->AllocatePool ( + EfiBootServicesData, + MemoryMapSize, + (VOID**)&MemoryMap + ); + ASSERT_EFI_ERROR (Status); + + // + // 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) { + IsRuntime = TRUE; + } + break; + } + // + // Get next item + // + MemoryMap = (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemoryMap + DescriptorSize); + } + + // + // Done + // + gBS->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 + +**/ STATIC VOID EFIAPI @@ -46,22 +136,6 @@ FvbNotificationEvent ( IN EFI_EVENT Event, IN VOID *Context ) -/*++ - -Routine Description: - Update mFvbEntry. Add new entry, or update existing entry if Fvb protocol is - reinstalled. - -Arguments: - - Event - The Event that is being processed - - Context - Event Context - -Returns: - None - ---*/ { EFI_STATUS Status; UINTN BufferSize; @@ -115,43 +189,59 @@ Returns: // // Get the interface pointer and if it's ours, skip it // - Status = gBS->HandleProtocol (Handle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **) &mFvbEntry[UpdateIndex].Fvb); + Status = gBS->HandleProtocol ( + Handle, + &gEfiFirmwareVolumeBlockProtocolGuid, + (VOID **) &mFvbEntry[UpdateIndex].Fvb + ); ASSERT_EFI_ERROR (Status); - Status = gBS->HandleProtocol (Handle, &gEfiFvbExtensionProtocolGuid, (VOID **) &mFvbEntry[UpdateIndex].FvbExtension); + 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 comes + // from two way: + // 1) Dxe Core. (FVB information is transferred from FV HOB). + // 2) FVB driver. + // The FVB produced Dxe core is used for discoverying 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 ) -/*++ - -Routine Description: - - Convert all pointers in mFvbEntry after ExitBootServices. - -Arguments: - - Event - The Event that is being processed - - Context - Event Context - -Returns: - - None - ---*/ { UINTN Index; if (mFvbEntry != NULL) { for (Index = 0; Index < MAX_FVB_COUNT; Index++) { + if (!mFvbEntry[Index].IsRuntimeAccess) { + continue; + } + if (NULL != mFvbEntry[Index].Fvb) { EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetBlockSize); EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetPhysicalAddress); @@ -173,24 +263,21 @@ Returns: } } +/** + Library constructor function entry. + + @param ImageHandle The handle of image who call this libary. + @param SystemTable The point of System Table. + + @retval EFI_SUCESS Sucess construct this library. + @retval Others Fail to contruct this libary. +**/ EFI_STATUS EFIAPI FvbLibInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) -/*++ - -Routine Description: - Initialize globals and register Fvb Protocol notification function. - -Arguments: - None - -Returns: - EFI_SUCCESS - ---*/ { UINTN Status; mFvbCount = 0; @@ -238,15 +325,34 @@ Returns: return EFI_SUCCESS; } -// + +// +// ============================================================================= // 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. // // EfiFvbInitialize () must be called before any of the following functions // must be called. -// +// ============================================================================= +// +/** + Reads specified number of bytes into a buffer from the specified block + + @param Instance The FV instance to be read from. + @param Lba The logical block address to be read from + @param Offset Offset into the block at which to begin reading + @param NumBytes Pointer that on input contains the total size of + the buffer. On output, it contains the total number + of bytes read + @param Buffer Pointer to a caller allocated buffer that will be + used to hold the data read + + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_SUCESS Sucess to Read block + @retval Others Fail to read block +**/ EFI_STATUS EfiFvbReadBlock ( IN UINTN Instance, @@ -255,36 +361,34 @@ EfiFvbReadBlock ( IN OUT UINTN *NumBytes, IN UINT8 *Buffer ) -/*++ - -Routine Description: - Reads specified number of bytes into a buffer from the specified block - -Arguments: - Instance - The FV instance to be read from - Lba - The logical block address to be read from - Offset - Offset into the block at which to begin reading - NumBytes - Pointer that on input contains the total size of - the buffer. On output, it contains the total number - of bytes read - Buffer - Pointer to a caller allocated buffer that will be - used to hold the data read - -Returns: - - Status code - - EFI_INVALID_PARAMETER - invalid parameter - ---*/ { 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 + + @param Instance The FV instance to be written to + @param Lba The starting logical block index to write to + @param Offset Offset into the block at which to begin writing + @param NumBytes Pointer that on input contains the total size of + the buffer. On output, it contains the total number + of bytes actually written + @param Buffer Pointer to a caller allocated buffer that contains + the source for the write + + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_SUCESS Sucess to write block + @retval Others Fail to write block +**/ EFI_STATUS EfiFvbWriteBlock ( IN UINTN Instance, @@ -293,160 +397,152 @@ EfiFvbWriteBlock ( IN OUT UINTN *NumBytes, IN UINT8 *Buffer ) -/*++ - -Routine Description: - Writes specified number of bytes from the input buffer to the block - -Arguments: - Instance - The FV instance to be written to - Lba - The starting logical block index to write to - Offset - Offset into the block at which to begin writing - NumBytes - Pointer that on input contains the total size of - the buffer. On output, it contains the total number - of bytes actually written - Buffer - Pointer to a caller allocated buffer that contains - the source for the write - -Returns: - - Status code - - EFI_INVALID_PARAMETER - invalid parameter - ---*/ { 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 + + @param Instance The FV instance to be erased + @param Lba The logical block index to be erased + + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_SUCESS Sucess to erase block + @retval Others Fail to erase block +**/ EFI_STATUS EfiFvbEraseBlock ( IN UINTN Instance, IN EFI_LBA Lba ) -/*++ - -Routine Description: - Erases and initializes a firmware volume block - -Arguments: - Instance - The FV instance to be erased - Lba - The logical block index to be erased - -Returns: - - Status code - - EFI_INVALID_PARAMETER - invalid parameter - ---*/ { 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); } +/** + Retrieves attributes, insures positive polarity of attribute bits, returns + resulting attributes in output parameter + + @param Instance The FV instance whose attributes is going to be returned + @param Attributes Output buffer which contains attributes + + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_SUCESS Sucess to get Fv attribute + @retval Others Fail to get Fv attribute +**/ EFI_STATUS EfiFvbGetVolumeAttributes ( IN UINTN Instance, OUT EFI_FVB_ATTRIBUTES *Attributes ) -/*++ - -Routine Description: - Retrieves attributes, insures positive polarity of attribute bits, returns - resulting attributes in output parameter - -Arguments: - Instance - The FV instance whose attributes is going to be - returned - Attributes - Output buffer which contains attributes - -Returns: - Status code - - EFI_INVALID_PARAMETER - invalid parameter - ---*/ { if (Instance >= mFvbCount) { return EFI_INVALID_PARAMETER; } + if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) { + return EFI_INVALID_PARAMETER; + } + return mFvbEntry[Instance].Fvb->GetVolumeAttributes (mFvbEntry[Instance].Fvb, Attributes); } -EFI_STATUS -EfiFvbSetVolumeAttributes ( - IN UINTN Instance, - IN EFI_FVB_ATTRIBUTES Attributes - ) -/*++ +/** + Modifies the current settings of the firmware volume according to the + input parameter, and returns the new setting of the volume -Routine Description: - Modifies the current settings of the firmware volume according to the - input parameter, and returns the new setting of the volume - -Arguments: - Instance - The FV instance whose attributes is going to be + @param Instance The FV instance whose attributes is going to be modified - Attributes - On input, it is a pointer to EFI_FVB_ATTRIBUTES + @param Attributes On input, it is a pointer to EFI_FVB_ATTRIBUTES containing the desired firmware volume settings. On successful return, it contains the new settings of the firmware volume - -Returns: - Status code - - EFI_INVALID_PARAMETER - invalid parameter - ---*/ + + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_SUCESS Sucess to set Fv attribute + @retval Others Fail to set Fv attribute +**/ +EFI_STATUS +EfiFvbSetVolumeAttributes ( + IN UINTN Instance, + IN EFI_FVB_ATTRIBUTES Attributes + ) { if (Instance >= mFvbCount) { return EFI_INVALID_PARAMETER; } + if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) { + return EFI_INVALID_PARAMETER; + } + return mFvbEntry[Instance].Fvb->SetVolumeAttributes (mFvbEntry[Instance].Fvb, &Attributes); } +/** + Retrieves the physical address of a memory mapped FV + + @param Instance The FV instance whose base address is going to be + returned + @param BaseAddress Pointer to a caller allocated EFI_PHYSICAL_ADDRESS + that on successful return, contains the base address + of the firmware volume. + + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_SUCESS Sucess to get physical address + @retval Others Fail to get physical address +**/ EFI_STATUS EfiFvbGetPhysicalAddress ( IN UINTN Instance, OUT EFI_PHYSICAL_ADDRESS *BaseAddress ) -/*++ - -Routine Description: - Retrieves the physical address of a memory mapped FV - -Arguments: - Instance - The FV instance whose base address is going to be - returned - BaseAddress - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS - that on successful return, contains the base address - of the firmware volume. - -Returns: - - Status code - - EFI_INVALID_PARAMETER - invalid parameter - ---*/ { 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 size of a logical block + + @param Instance The FV instance whose block size is going to be + returned + @param Lba Indicates which block to return the size for. + @param BlockSize A pointer to a caller allocated UINTN in which + the size of the block is returned + @param NumOfBlocks a 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_INVALID_PARAMETER Invalid parameter + @retval EFI_SUCESS Sucess to get block size + @retval Others Fail to get block size +**/ EFI_STATUS EfiFvbGetBlockSize ( IN UINTN Instance, @@ -454,37 +550,32 @@ EfiFvbGetBlockSize ( OUT UINTN *BlockSize, OUT UINTN *NumOfBlocks ) -/*++ - -Routine Description: - Retrieve the size of a logical block - -Arguments: - Instance - The FV instance whose block size is going to be - returned - Lba - Indicates which block to return the size for. - BlockSize - A pointer to a caller allocated UINTN in which - the size of the block is returned - NumOfBlocks - a 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 - -Returns: - EFI_SUCCESS - The firmware volume was read successfully and - contents are in Buffer - - EFI_INVALID_PARAMETER - invalid parameter - ---*/ { 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 + + @param Instance The FV instance to be erased + @param StartLba The starting logical block index to be erased + @param OffsetStartLba Offset into the starting block at which to + begin erasing + @param LastLba The last logical block index to be erased + @param OffsetLastLba Offset into the last block at which to end erasing + + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_SUCESS Sucess to erase custom block range + @retval Others Fail to erase custom block range +**/ EFI_STATUS EfiFvbEraseCustomBlockRange ( IN UINTN Instance, @@ -493,33 +584,15 @@ EfiFvbEraseCustomBlockRange ( IN EFI_LBA LastLba, IN UINTN OffsetLastLba ) -/*++ - -Routine Description: - Erases and initializes a specified range of a firmware volume - -Arguments: - Instance - The FV instance to be erased - StartLba - The starting logical block index to be erased - OffsetStartLba - Offset into the starting block at which to - begin erasing - LastLba - The last logical block index to be erased - OffsetLastLba - Offset into the last block at which to end erasing - -Returns: - - Status code - - EFI_INVALID_PARAMETER - invalid parameter - - EFI_UNSUPPORTED - not support - ---*/ { if (Instance >= mFvbCount) { return EFI_INVALID_PARAMETER; } + if (EfiAtRuntime() && !mFvbEntry[Instance].IsRuntimeAccess) { + return EFI_INVALID_PARAMETER; + } + if (!(mFvbEntry[Instance].FvbExtension)) { return EFI_UNSUPPORTED; }