13cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** @file 23cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Firmware Volume Block Driver for Lakeport Platform. 33cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 43cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Firmware volume block driver for FWH or SPI device. 53cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei It depends on which Flash Device Library to be linked with this driver. 63cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 73cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiCopyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR> 83cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 93cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei This program and the accompanying materials are licensed and made available under 113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei the terms and conditions of the BSD License that accompanies this distribution. 133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei The full text of the license may be found at 153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei http://opensource.org/licenses/bsd-license.php. 173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include "FvbService.h" 303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei// 323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei// Global variable for this FVB driver which contains 333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei// the private data of all firmware volume block instances. 343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei// 353cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFWB_GLOBAL mFvbModuleGlobal; 363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei// 383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei// This platform driver knows there are 3 FVs on 393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei// FD, which are FvRecovery, FvMain and FvNvStorage. 403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei// 413cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiUINT32 mPlatformFvBaseAddress[] = { 423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FixedPcdGet32(PcdFlashNvStorageVariableBase), 433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei}; 443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 453cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate = { 463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei HARDWARE_DEVICE_PATH, 493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei HW_MEMMAP_DP, 503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (UINT8)(sizeof (MEMMAP_DEVICE_PATH)), 523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8) 533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei }, 553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EfiMemoryMappedIO, 563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (EFI_PHYSICAL_ADDRESS) 0, 573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (EFI_PHYSICAL_ADDRESS) 0, 583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei }, 593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei END_DEVICE_PATH_TYPE, 613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei END_ENTIRE_DEVICE_PATH_SUBTYPE, 623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei END_DEVICE_PATH_LENGTH, 643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 0 653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei}; 683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 693cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate = { 703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MEDIA_DEVICE_PATH, 733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MEDIA_PIWG_FW_VOL_DP, 743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)), 763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8) 773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei }, 793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 0 } 803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei }, 813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei END_DEVICE_PATH_TYPE, 833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei END_ENTIRE_DEVICE_PATH_SUBTYPE, 843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei END_DEVICE_PATH_LENGTH, 863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 0 873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei}; 903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei// 923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei// Template structure used when installing FVB protocol. 933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei// 943cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate = { 953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FVB_DEVICE_SIGNATURE, 963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NULL, 973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 0, // Instance 983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbProtocolGetAttributes, 1003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbProtocolSetAttributes, 1013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbProtocolGetPhysicalAddress, 1023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbProtocolGetBlockSize, 1033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbProtocolRead, 1043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbProtocolWrite, 1053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbProtocolEraseBlocks, 1063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NULL 1073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } // FwVolBlockInstance 1083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei}; 1093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 1123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Get the pointer to EFI_FW_VOL_INSTANCE from the buffer pointed 1133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei by mFvbModuleGlobal.FvInstance based on a index. 1143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Each EFI_FW_VOL_INSTANCE is with variable length as 1153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei we have a block map at the end of the EFI_FIRMWARE_VOLUME_HEADER. 1163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Instance The index of the EFI_FW_VOL_INSTANCE. 1183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @return A pointer to EFI_FW_VOL_INSTANCE. 1203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 1223cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_FW_VOL_INSTANCE * 1233cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiGetFvbInstance ( 1243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINTN Instance 1253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 1263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 1273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FW_VOL_INSTANCE *FwhRecord; 1283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ( Instance >= mFvbModuleGlobal.NumFv ) { 1303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); 1313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return NULL; 1323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Find the right instance of the FVB private data. 1363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FwhRecord = mFvbModuleGlobal.FvInstance; 1383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei while ( Instance > 0 ) { 1393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FwhRecord = (EFI_FW_VOL_INSTANCE *) ((UINTN)((UINT8 *)FwhRecord) + 1403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FwhRecord->VolumeHeader.HeaderLength + 1413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))); 1423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Instance --; 1433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return FwhRecord; 1463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 1483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 1513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Get the EFI_FVB_ATTRIBUTES_2 of a FV. 1523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] The index of the EFI_FW_VOL_INSTANCE. 1543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @return EFI_FVB_ATTRIBUTES_2 of the FV identified by Instance. 1563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 1583cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiSTATIC 1593cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_FVB_ATTRIBUTES_2 1603cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbGetVolumeAttributes ( 1613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINTN Instance 1623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 1633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 1643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FW_VOL_INSTANCE * FwInstance = NULL; 1653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FwInstance = GetFvbInstance(Instance); 1663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ASSERT_EFI_ERROR (FwInstance != NULL); 1673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ( FwInstance != NULL ) { 1693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return FwInstance->VolumeHeader.Attributes; 1703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } else { 1713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return 0; 1723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 1743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 1773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Retrieves the starting address of an LBA in an FV. It also 1783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return a few other attribut of the FV. 1793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Instance The index of the EFI_FW_VOL_INSTANCE. 1813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Lba The logical block address. 1823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[out] LbaAddress On output, contains the physical starting address 1833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei of the Lba. 1843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[out] LbaLength On output, contains the length of the block. 1853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[out] NumOfBlocks A pointer to a caller allocated UINTN in which the 1863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei number of consecutive blocks starting with Lba is 1873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei returned. All blocks in this range have a size of 1883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BlockSize. 1893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS Successfully returns. 1913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_INVALID_PARAMETER Instance not found. 1923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 1943cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiSTATIC 1953cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 1963cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbGetLbaAddress ( 1973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINTN Instance, 1983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_LBA Lba, 1993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei OUT UINTN *LbaAddress, 2003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei OUT UINTN *LbaLength, 2013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei OUT UINTN *NumOfBlocks 2023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 2033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 2043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINT32 NumBlocks = 0; 2053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINT32 BlockLength = 0; 2063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN Offset; 2073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_LBA StartLba; 2083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_LBA NextLba; 2093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FW_VOL_INSTANCE *FwhInstance; 2103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FV_BLOCK_MAP_ENTRY *BlockMap = NULL; 2113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Find the right instance of the FVB private data. 2143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FwhInstance = GetFvbInstance (Instance); 2163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei StartLba = 0; 2183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Offset = 0; 2193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BlockMap = &(FwhInstance->VolumeHeader.BlockMap[0]); 2203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ASSERT_EFI_ERROR (BlockMap != NULL); 2213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Parse the blockmap of the FV to find which map entry the Lba belongs to. 2243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei while (TRUE) { 2263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ( BlockMap != NULL) { 2273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NumBlocks = BlockMap->NumBlocks; 2283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BlockLength = BlockMap->Length; 2293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 2303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ( NumBlocks == 0 || BlockLength == 0) { 2323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_INVALID_PARAMETER; 2333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 2343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NextLba = StartLba + NumBlocks; 2363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // The map entry found. 2393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (Lba >= StartLba && Lba < NextLba) { 2413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Offset = Offset + (UINTN)MultU64x32((Lba - StartLba), BlockLength); 2423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ( LbaAddress && FwhInstance ) { 2433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *LbaAddress = FwhInstance->FvBase + Offset; 2443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 2453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (LbaLength ) { 2473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *LbaLength = BlockLength; 2483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 2493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (NumOfBlocks ) { 2513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *NumOfBlocks = (UINTN)(NextLba - Lba); 2523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 2533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_SUCCESS; 2543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 2553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei StartLba = NextLba; 2573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Offset = Offset + NumBlocks * BlockLength; 2583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BlockMap++; 2593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 2603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 2613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 2643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Reads specified number of bytes into a buffer from the specified block. 2653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Instance The FV instance to be read from. 2673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Lba The logical block address to be read from. 2683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] BlockOffset Offset into the block at which to begin reading. 2693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] NumBytes Pointer that on input contains the total size of 2703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei the buffer. On output, it contains the total number 2713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei of bytes read. 2723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Buffer Pointer to a caller allocated buffer that will be 2733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei used to hold the data read. 2743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS The firmware volume was read successfully and 2773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei contents are in Buffer. 2783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_BAD_BUFFER_SIZE Read attempted across a LBA boundary. On output, 2793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NumBytes contains the total number of bytes returned 2803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei in Buffer. 2813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state. 2823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_DEVICE_ERROR The block device is not functioning correctly and 2833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei could not be read. 2843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_INVALID_PARAMETER Instance not found, or NumBytes, Buffer are NULL. 2853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 2873cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiSTATIC 2883cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 2893cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbReadBlock ( 2903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINTN Instance, 2913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_LBA Lba, 2923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINTN BlockOffset, 2933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN OUT UINTN *NumBytes, 2943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINT8 *Buffer 2953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 2963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 2973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB_ATTRIBUTES_2 Attributes; 2983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN LbaAddress; 2993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN LbaLength; 3003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 3013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ( (NumBytes == NULL) || (Buffer == NULL)) { 3033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return (EFI_INVALID_PARAMETER); 3043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 3053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (*NumBytes == 0) { 3063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return (EFI_INVALID_PARAMETER); 3073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 3083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL); 3103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (EFI_ERROR(Status)) { 3113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 3123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 3133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Attributes = FvbGetVolumeAttributes (Instance); 3153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ( (Attributes & EFI_FVB2_READ_STATUS) == 0) { 3173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return (EFI_ACCESS_DENIED); 3183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 3193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (BlockOffset > LbaLength) { 3213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return (EFI_INVALID_PARAMETER); 3223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 3233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (LbaLength < ( *NumBytes + BlockOffset ) ) { 3253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *NumBytes = (UINT32) (LbaLength - BlockOffset); 3263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = EFI_BAD_BUFFER_SIZE; 3273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 3283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei LibFvbFlashDeviceRead (LbaAddress + BlockOffset, NumBytes, Buffer); 3303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 3323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 3333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 3363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Writes specified number of bytes from the input buffer to the block. 3373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Instance The FV instance to be written to. 3393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Lba The starting logical block index to write to. 3403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] BlockOffset Offset into the block at which to begin writing. 3413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] NumBytes Pointer that on input contains the total size of 3423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei the buffer. On output, it contains the total number 3433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei of bytes actually written. 3443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Buffer Pointer to a caller allocated buffer that contains 3453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei the source for the write. 3463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS The firmware volume was written successfully. 3473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_BAD_BUFFER_SIZE Write attempted across a LBA boundary. On output, 3483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NumBytes contains the total number of bytes 3493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei actually writte. 3503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. 3513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_DEVICE_ERROR The block device is not functioning correctly and 3523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei could not be written. 3533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_INVALID_PARAMETER Instance not found, or NumBytes, Buffer are NULL. 3543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 3563cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 3573cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbWriteBlock ( 3583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINTN Instance, 3593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_LBA Lba, 3603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINTN BlockOffset, 3613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN OUT UINTN *NumBytes, 3623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINT8 *Buffer 3633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 3643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 3653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB_ATTRIBUTES_2 Attributes; 3663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN LbaAddress; 3673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN LbaLength; 3683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FW_VOL_INSTANCE *FwhInstance; 3693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 3703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status1; 3713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FwhInstance = GetFvbInstance (Instance); 3733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ( (NumBytes == NULL) || (Buffer == NULL)) { 3753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return (EFI_INVALID_PARAMETER); 3763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 3773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (*NumBytes == 0) { 3783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return (EFI_INVALID_PARAMETER); 3793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 3803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL); 3823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (EFI_ERROR(Status)) { 3833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 3843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 3853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 3873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Check if the FV is write enabled. 3883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 3893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Attributes = FvbGetVolumeAttributes (Instance); 3903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ( (Attributes & EFI_FVB2_WRITE_STATUS) == 0) { 3913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return (EFI_ACCESS_DENIED); 3923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 3933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 3953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Perform boundary checks and adjust NumBytes. 3963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 3973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (BlockOffset > LbaLength) { 3983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return (EFI_INVALID_PARAMETER); 3993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 4003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ( LbaLength < ( *NumBytes + BlockOffset ) ) { 4023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei DEBUG ((EFI_D_ERROR, 4033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei "FvWriteBlock: Reducing Numbytes from 0x%x to 0x%x\n", 4043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *NumBytes, 4053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (UINT32)(LbaLength-BlockOffset)) 4063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 4073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *NumBytes = (UINT32) (LbaLength - BlockOffset); 4083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = EFI_BAD_BUFFER_SIZE; 4093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 4103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei LibFvbFlashDeviceBlockLock (LbaAddress, LbaLength, FALSE); 4123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status1 = LibFvbFlashDeviceWrite (LbaAddress + BlockOffset, NumBytes, Buffer); 4143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei LibFvbFlashDeviceBlockLock (LbaAddress, LbaLength, TRUE); 4163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei WriteBackInvalidateDataCacheRange ((VOID *) (LbaAddress + BlockOffset), *NumBytes); 4173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ( EFI_ERROR (Status1) ) { 4193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status1; 4203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 4213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 4233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 4243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 4273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Erases and initializes a firmware volume block. 4283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Instance The FV instance to be erased. 4303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Lba The logical block index to be erased. 4313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS The erase request was successfully completed. 4333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. 4343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_DEVICE_ERROR The block device is not functioning correctly and 4353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei could not be written. Firmware device may have been 4363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei partially erased. 4373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_INVALID_PARAMETER Instance not found. 4383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 4403cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 4413cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbEraseBlock ( 4423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINTN Instance, 4433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_LBA Lba 4443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 4453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 4463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB_ATTRIBUTES_2 Attributes; 4473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN LbaAddress; 4483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FW_VOL_INSTANCE *FwhInstance; 4493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN LbaLength; 4503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 4513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 4533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Find the right instance of the FVB private data. 4543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 4553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FwhInstance = GetFvbInstance (Instance); 4563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 4583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Check if the FV is write enabled. 4593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 4603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Attributes = FvbGetVolumeAttributes (Instance); 4613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if( (Attributes & EFI_FVB2_WRITE_STATUS) == 0) { 4633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return (EFI_ACCESS_DENIED); 4643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 4653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 4673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Get the starting address of the block for erase. 4683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 4693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL); 4703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (EFI_ERROR(Status)) { 4713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 4723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 4733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei LibFvbFlashDeviceBlockLock (LbaAddress, LbaLength, FALSE); 4753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = LibFvbFlashDeviceBlockErase (LbaAddress, LbaLength); 4773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei LibFvbFlashDeviceBlockLock (LbaAddress, LbaLength, TRUE); 4793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei WriteBackInvalidateDataCacheRange ((VOID *) LbaAddress, LbaLength); 4813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 4833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 4843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 4873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Modifies the current settings of the firmware volume according to the 4883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei input parameter, and returns the new setting of the volume. 4893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Instance The FV instance whose attributes is going to be 4913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei modified. 4923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Attributes On input, it is a pointer to EFI_FVB_ATTRIBUTES_2 4933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei containing the desired firmware volume settings. 4943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei On successful return, it contains the new settings 4953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei of the firmware volume. 4963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS Successfully returns. 4983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_ACCESS_DENIED The volume setting is locked and cannot be modified. 4993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_INVALID_PARAMETER Instance not found, or The attributes requested are 5003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei in conflict with the capabilities as declared in the 5013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei firmware volume header. 5023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 5043cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiSTATIC 5053cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 5063cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbSetVolumeAttributes ( 5073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINTN Instance, 5083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes 5093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 5103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 5113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FW_VOL_INSTANCE *FwhInstance = NULL; 5123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB_ATTRIBUTES_2 OldAttributes = 0; 5133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB_ATTRIBUTES_2 *AttribPtr = NULL; 5143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB_ATTRIBUTES_2 UnchangedAttributes; 5153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINT32 Capabilities; 5163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINT32 OldStatus, NewStatus; 5173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Find the right instance of the FVB private data. 5203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FwhInstance = GetFvbInstance (Instance); 5223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei AttribPtr = (EFI_FVB_ATTRIBUTES_2 *) & (FwhInstance->VolumeHeader.Attributes); 5243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ASSERT_EFI_ERROR (AttribPtr != NULL); 5253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ( AttribPtr != NULL) { 5273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei OldAttributes = *AttribPtr; 5283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 5293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Capabilities = OldAttributes & EFI_FVB2_CAPABILITIES; 5313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei OldStatus = OldAttributes & EFI_FVB2_STATUS; 5323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NewStatus = *Attributes & EFI_FVB2_STATUS; 5333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UnchangedAttributes = EFI_FVB2_READ_DISABLED_CAP | \ 5353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB2_READ_ENABLED_CAP | \ 5363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB2_WRITE_DISABLED_CAP | \ 5373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB2_WRITE_ENABLED_CAP | \ 5383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB2_LOCK_CAP | \ 5393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB2_STICKY_WRITE | \ 5403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB2_MEMORY_MAPPED | \ 5413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB2_ERASE_POLARITY | \ 5423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB2_READ_LOCK_CAP | \ 5433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB2_WRITE_LOCK_CAP | \ 5443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB2_ALIGNMENT; 5453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Some attributes of FV is read only can *not* be set. 5483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ((OldAttributes & UnchangedAttributes) ^ (*Attributes & UnchangedAttributes)) { 5503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_INVALID_PARAMETER; 5513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 5523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // If firmware volume is locked, no status bit can be updated. 5553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ( OldAttributes & EFI_FVB2_LOCK_STATUS ) { 5573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ( OldStatus ^ NewStatus ) { 5583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_ACCESS_DENIED; 5593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 5603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 5613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Test read disable. 5643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ((Capabilities & EFI_FVB2_READ_DISABLED_CAP) == 0) { 5663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ((NewStatus & EFI_FVB2_READ_STATUS) == 0) { 5673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_INVALID_PARAMETER; 5683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 5693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 5703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Test read enable. 5733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ((Capabilities & EFI_FVB2_READ_ENABLED_CAP) == 0) { 5753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (NewStatus & EFI_FVB2_READ_STATUS) { 5763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_INVALID_PARAMETER; 5773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 5783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 5793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Test write disable. 5823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ((Capabilities & EFI_FVB2_WRITE_DISABLED_CAP) == 0) { 5843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ((NewStatus & EFI_FVB2_WRITE_STATUS) == 0) { 5853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_INVALID_PARAMETER; 5863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 5873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 5883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Test write enable. 5913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ((Capabilities & EFI_FVB2_WRITE_ENABLED_CAP) == 0) { 5933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (NewStatus & EFI_FVB2_WRITE_STATUS) { 5943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_INVALID_PARAMETER; 5953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 5963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 5973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Test lock. 6003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 6013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ((Capabilities & EFI_FVB2_LOCK_CAP) == 0) { 6023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (NewStatus & EFI_FVB2_LOCK_STATUS) { 6033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_INVALID_PARAMETER; 6043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 6053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 6063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *AttribPtr = (*AttribPtr) & (0xFFFFFFFF & (~EFI_FVB2_STATUS)); 6083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *AttribPtr = (*AttribPtr) | NewStatus; 6093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *Attributes = *AttribPtr; 6103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_SUCCESS; 6123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 6133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei// 6153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei// FVB protocol APIs. 6163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei// 6173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 6183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Retrieves the physical address of the device. 6193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] This A pointer to EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL. 6213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[out] Address Output buffer containing the address. 6223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei retval EFI_SUCCESS The function always return successfully. 6243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 6263cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 6273cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 6283cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbProtocolGetPhysicalAddress ( 6293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, 6303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei OUT EFI_PHYSICAL_ADDRESS *Address 6313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 6323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 6333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; 6343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FW_VOL_INSTANCE *FvInstance; 6353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbDevice = FVB_DEVICE_FROM_THIS (This); 6373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvInstance = GetFvbInstance(FvbDevice->Instance); 6383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (FvInstance != NULL) { 6403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *Address = FvInstance->FvBase; 6413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 6423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_SUCCESS; 6443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 6453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 6483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Retrieve the size of a logical block. 6493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] This Calling context. 6513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Lba Indicates which block to return the size for. 6523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[out] BlockSize A pointer to a caller allocated UINTN in which 6533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei the size of the block is returned. 6543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[out] NumOfBlocks A pointer to a caller allocated UINTN in which the 6553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei number of consecutive blocks starting with Lba is 6563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei returned. All blocks in this range have a size of 6573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BlockSize. 6583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS The function always return successfully. 6603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 6623cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 6633cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 6643cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbProtocolGetBlockSize ( 6653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, 6663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_LBA Lba, 6673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei OUT UINTN *BlockSize, 6683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei OUT UINTN *NumOfBlocks 6693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 6703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 6713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; 6723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei DEBUG((EFI_D_INFO, 6743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei "FvbProtocolGetBlockSize: Lba: 0x%lx BlockSize: 0x%x NumOfBlocks: 0x%x\n", 6753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Lba, 6763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BlockSize, 6773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NumOfBlocks) 6783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 6793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbDevice = FVB_DEVICE_FROM_THIS (This); 6813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return FvbGetLbaAddress ( 6833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbDevice->Instance, 6843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Lba, 6853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NULL, 6863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BlockSize, 6873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NumOfBlocks 6883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 6893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 6903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 6933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Retrieves Volume attributes. No polarity translations are done. 6943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] This Calling context. 6963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[out] Attributes Output buffer which contains attributes. 6973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS The function always return successfully. 6993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 7013cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 7023cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 7033cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbProtocolGetAttributes ( 7043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, 7053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei OUT EFI_FVB_ATTRIBUTES_2 *Attributes 7063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 7073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 7083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; 7093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbDevice = FVB_DEVICE_FROM_THIS (This); 7113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *Attributes = FvbGetVolumeAttributes (FvbDevice->Instance); 7133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei DEBUG ((EFI_D_INFO, 7153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei "FvbProtocolGetAttributes: This: 0x%x Attributes: 0x%x\n", 7163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei This, 7173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *Attributes) 7183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 7193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_SUCCESS; 7213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 7223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 7253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Sets Volume attributes. No polarity translations are done. 7263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] This Calling context. 7283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[out] Attributes Output buffer which contains attributes. 7293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS The function always return successfully. 7313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 7333cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 7343cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 7353cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbProtocolSetAttributes ( 7363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, 7373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes 7383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 7393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 7403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 7413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; 7423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei DEBUG((EFI_D_INFO, 7443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei "FvbProtocolSetAttributes: Before SET - This: 0x%x Attributes: 0x%x\n", 7453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei This, 7463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *Attributes) 7473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 7483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbDevice = FVB_DEVICE_FROM_THIS (This); 7503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = FvbSetVolumeAttributes (FvbDevice->Instance, Attributes); 7523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei DEBUG((EFI_D_INFO, 7543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei "FvbProtocolSetAttributes: After SET - This: 0x%x Attributes: 0x%x\n", 7553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei This, 7563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *Attributes) 7573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 7583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 7603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 7613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 7643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei The EraseBlock() function erases one or more blocks as denoted by the 7653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei variable argument list. The entire parameter list of blocks must be verified 7663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei prior to erasing any blocks. If a block is requested that does not exist 7673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei within the associated firmware volume (it has a larger index than the last 7683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei block of the firmware volume), the EraseBlock() function must return 7693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_INVALID_PARAMETER without modifying the contents of the firmware volume. 7703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] This Calling context. 7723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] ... Starting LBA followed by Number of Lba to erase. 7733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei a -1 to terminate the list. 7743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS The erase request was successfully completed. 7763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. 7773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_DEVICE_ERROR The block device is not functioning correctly and 7783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei could not be written. Firmware device may have been 7793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei partially erased. 7803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 7823cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 7833cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 7843cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbProtocolEraseBlocks ( 7853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, 7863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ... 7873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 7883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 7893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; 7903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FW_VOL_INSTANCE *FwhInstance; 7913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN NumOfBlocks = 0; 7923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VA_LIST args; 7933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_LBA StartingLba; 7943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN NumOfLba; 7953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 7963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei DEBUG((EFI_D_INFO, "FvbProtocolEraseBlocks: \n")); 7983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbDevice = FVB_DEVICE_FROM_THIS (This); 7993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FwhInstance = GetFvbInstance (FvbDevice->Instance); 8013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (FwhInstance != NULL) { 8033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NumOfBlocks = FwhInstance->NumOfBlocks; 8043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 8053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VA_START (args, This); 8073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei do { 8093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei StartingLba = VA_ARG (args, EFI_LBA); 8103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ( StartingLba == EFI_LBA_LIST_TERMINATOR ) { 8113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei break; 8123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 8133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NumOfLba = VA_ARG (args, UINT32); 8153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 8173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Check input parameters. 8183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 8193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (NumOfLba == 0) { 8203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VA_END (args); 8213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_INVALID_PARAMETER; 8223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 8233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ( ( StartingLba + NumOfLba ) > NumOfBlocks ) { 8253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_INVALID_PARAMETER; 8263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 8273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } while ( 1 ); 8283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VA_END (args); 8303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VA_START (args, This); 8323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei do { 8333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei StartingLba = VA_ARG (args, EFI_LBA); 8343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (StartingLba == EFI_LBA_LIST_TERMINATOR) { 8353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei break; 8363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 8373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NumOfLba = VA_ARG (args, UINT32); 8393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei while ( NumOfLba > 0 ) { 8413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = FvbEraseBlock (FvbDevice->Instance, StartingLba); 8423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ( EFI_ERROR(Status)) { 8433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VA_END (args); 8443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 8453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 8463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei StartingLba ++; 8473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NumOfLba --; 8483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 8493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } while ( 1 ); 8513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VA_END (args); 8533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_SUCCESS; 8553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 8563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 8593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Writes data beginning at Lba:Offset from FV. The write terminates either 8603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei when *NumBytes of data have been written, or when a block boundary is 8613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei reached. *NumBytes is updated to reflect the actual number of bytes 8623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei written. The write opertion does not include erase. This routine will 8633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei attempt to write only the specified bytes. If the writes do not stick, 8643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei it will return an error. 8653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] This Calling context. 8673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Lba Block in which to begin write. 8683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Offset Offset in the block at which to begin write. 8693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in,out] NumBytes On input, indicates the requested write size. On 8703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei output, indicates the actual number of bytes written 8713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Buffer Buffer containing source data for the write. 8723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS The firmware volume was written successfully. 8743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_BAD_BUFFER_SIZE Write attempted across a LBA boundary. On output, 8753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NumBytes contains the total number of bytes 8763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei actually written. 8773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. 8783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_DEVICE_ERROR The block device is not functioning correctly and 8793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei could not be written. 8803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL. 8813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 8833cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 8843cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 8853cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbProtocolWrite ( 8863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, 8873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_LBA Lba, 8883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINTN Offset, 8893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN OUT UINTN *NumBytes, 8903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINT8 *Buffer 8913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 8923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 8933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; 8953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbDevice = FVB_DEVICE_FROM_THIS (This); 8973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei DEBUG((EFI_D_INFO, 8993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei "FvbProtocolWrite: Lba: 0x%lx Offset: 0x%x NumBytes: 0x%x, Buffer: 0x%x\n", 9003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Lba, 9013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Offset, 9023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *NumBytes, 9033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Buffer) 9043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 9053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return FvbWriteBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer); 9073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 9083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 9113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Reads data beginning at Lba:Offset from FV. The Read terminates either 9123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei when *NumBytes of data have been read, or when a block boundary is 9133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei reached. *NumBytes is updated to reflect the actual number of bytes 9143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei written. The write opertion does not include erase. This routine will 9153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei attempt to write only the specified bytes. If the writes do not stick, 9163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei it will return an error. 9173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] This Calling context. 9193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Lba Block in which to begin write. 9203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Offset Offset in the block at which to begin write 9213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in,out] NumBytes On input, indicates the requested write size. On 9223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei output, indicates the actual number of bytes written. 9233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Buffer Buffer containing source data for the write. 9243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9263cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiReturns: 9273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS The firmware volume was read successfully and 9283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei contents are in Buffer. 9293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_BAD_BUFFER_SIZE Read attempted across a LBA boundary. On output, 9303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NumBytes contains the total number of bytes returned 9313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei in Buffer. 9323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state 9333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_DEVICE_ERROR The block device is not functioning correctly and 9343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei could not be read. 9353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL. 9363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 9383cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 9393cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 9403cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbProtocolRead ( 9413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, 9423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_LBA Lba, 9433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINTN Offset, 9443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN OUT UINTN *NumBytes, 9453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei OUT UINT8 *Buffer 9463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 9473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 9483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; 9503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 9513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbDevice = FVB_DEVICE_FROM_THIS (This); 9533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = FvbReadBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer); 9543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei DEBUG((EFI_D_INFO, 9553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei "FvbProtocolRead: Lba: 0x%lx Offset: 0x%x NumBytes: 0x%x, Buffer: 0x%x\n", 9563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Lba, 9573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Offset, 9583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *NumBytes, 9593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Buffer) 9603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 9613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 9633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 9643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 9673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Check the integrity of firmware volume header. 9683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] FwVolHeader A pointer to a firmware volume header. 9703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval TRUE The firmware volume is consistent. 9723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval FALSE The firmware volume has corrupted. 9733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 9753cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiBOOLEAN 9763cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiIsFvHeaderValid ( 9773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_PHYSICAL_ADDRESS FvBase, 9783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN CONST EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader 9793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 9803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 9813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (FvBase == PcdGet32(PcdFlashNvStorageVariableBase)) { 9823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (CompareMem (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid, sizeof(EFI_GUID)) != 0 ) { 9833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return FALSE; 9843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 9853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } else { 9863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (CompareMem (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem2Guid, sizeof(EFI_GUID)) != 0 ) { 9873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return FALSE; 9883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 9893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 9903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ( (FwVolHeader->Revision != EFI_FVH_REVISION) || 9913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (FwVolHeader->Signature != EFI_FVH_SIGNATURE) || 9923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (FwVolHeader->FvLength == ((UINTN) -1)) || 9933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ((FwVolHeader->HeaderLength & 0x01 ) !=0) ) { 9943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return FALSE; 9953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 9963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (CalculateCheckSum16 ((UINT16 *) FwVolHeader, FwVolHeader->HeaderLength) != 0) { 9983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return FALSE; 9993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 10003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 10013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return TRUE; 10023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 10033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 10043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 10053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 10063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei The function does the necessary initialization work for 10073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Firmware Volume Block Driver. 10083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 10093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS This funtion always return EFI_SUCCESS. 10103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei It will ASSERT on errors. 10113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 10123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 10133cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 10143cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbInitialize ( 10153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VOID 10163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 10173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 10183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FW_VOL_INSTANCE *FwhInstance; 10193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; 10203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FIRMWARE_VOLUME_HEADER *FvHeader; 10213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry; 10223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_PHYSICAL_ADDRESS BaseAddress; 10233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 10243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN BufferSize; 10253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN TmpHeaderLength; 10263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN Idx; 10273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINT32 MaxLbaSize; 10283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BOOLEAN FvHeaderValid; 10293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 10303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 10313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Calculate the total size for all firmware volume block instances. 10323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 10333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BufferSize = 0; 10343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei for (Idx = 0; Idx < 1; Idx++) { 10353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) mPlatformFvBaseAddress[Idx]; 10363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BufferSize += (FvHeader->HeaderLength + 10373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei sizeof (EFI_FW_VOL_INSTANCE) - 10383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei sizeof (EFI_FIRMWARE_VOLUME_HEADER) 10393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 10403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 10413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 10423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei mFvbModuleGlobal.FvInstance = (EFI_FW_VOL_INSTANCE *) AllocateRuntimeZeroPool (BufferSize); 10433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ASSERT (NULL != mFvbModuleGlobal.FvInstance); 10443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 10453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 10463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MaxLbaSize = 0; 10473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FwhInstance = mFvbModuleGlobal.FvInstance; 10483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei mFvbModuleGlobal.NumFv = 0; 10493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 10503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei for (Idx = 0; Idx < 1; Idx++) { 10513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BaseAddress = mPlatformFvBaseAddress[Idx]; 10523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress; 10533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 10543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (!IsFvHeaderValid (BaseAddress, FwVolHeader)) { 10553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvHeaderValid = FALSE; 10563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 10573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // If not valid, get FvbInfo from the information carried in 10583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // FVB driver. 10593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 10603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei DEBUG ((EFI_D_ERROR, "Fvb: FV header @ 0x%lx invalid\n", BaseAddress)); 10613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = GetFvbInfo (BaseAddress, &FwVolHeader); 10623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ASSERT_EFI_ERROR(Status); 10633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 10643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Write back a healthy FV header. 10653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 10663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei DEBUG ((EFI_D_ERROR, "FwBlockService.c: Writing back healthy FV header\n")); 10673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei LibFvbFlashDeviceBlockLock ((UINTN)BaseAddress, FwVolHeader->BlockMap->Length, FALSE); 10683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 10693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = LibFvbFlashDeviceBlockErase ((UINTN)BaseAddress, FwVolHeader->BlockMap->Length); 10703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 10713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei TmpHeaderLength = (UINTN) FwVolHeader->HeaderLength; 10723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = LibFvbFlashDeviceWrite ( 10733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (UINTN)BaseAddress, 10743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &TmpHeaderLength, 10753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (UINT8 *) FwVolHeader 10763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 10773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 10783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei LibFvbFlashDeviceBlockLock ((UINTN)BaseAddress, FwVolHeader->BlockMap->Length, TRUE); 10793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 10803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei WriteBackInvalidateDataCacheRange ( 10813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (VOID *) (UINTN) BaseAddress, 10823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FwVolHeader->BlockMap->Length 10833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 10843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 10853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 10863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 10873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei CopyMem (&(FwhInstance->VolumeHeader), FwVolHeader, FwVolHeader->HeaderLength); 10883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 10893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FwVolHeader = &(FwhInstance->VolumeHeader); 10903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FwhInstance->FvBase = (UINTN)BaseAddress; 10913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 10923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 10933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Process the block map for each FV. 10943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 10953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FwhInstance->NumOfBlocks = 0; 10963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei for (PtrBlockMapEntry = FwVolHeader->BlockMap; PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) { 10973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 10983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Get the maximum size of a block. 10993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 11003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (MaxLbaSize < PtrBlockMapEntry->Length) { 11013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MaxLbaSize = PtrBlockMapEntry->Length; 11023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 11033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FwhInstance->NumOfBlocks += PtrBlockMapEntry->NumBlocks; 11043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 11053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 11063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 11073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Add a FVB Protocol Instance. 11083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 11093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei mFvbModuleGlobal.NumFv++; 11103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei InstallFvbProtocol (FwhInstance, mFvbModuleGlobal.NumFv - 1); 11113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 11123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 11133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Move on to the next FwhInstance. 11143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1115 FwhInstance = (EFI_FW_VOL_INSTANCE *) ((UINTN)((UINT8 *)FwhInstance) + 1116 FwVolHeader->HeaderLength + 1117 (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))); 1118 1119 } 1120 1121 return EFI_SUCCESS; 1122} 1123 1124