13cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** @file 23cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 33cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Implement the Firmware Volume Block (FVB) services based on SMM FVB 43cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei module and install FVB protocol. 53cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 63cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiCopyright (c) 2010 - 2014, Intel Corporation. All rights reserved. <BR> 73cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 83cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 93cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei This program and the accompanying materials are licensed and made available under 103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei the terms and conditions of the BSD License that accompanies this distribution. 123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei The full text of the license may be found at 143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei http://opensource.org/licenses/bsd-license.php. 163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include "FvbSmmDxe.h" 293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 303cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_HANDLE mHandle = NULL; 313cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication = NULL; 323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei// 343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei// Template structure used when installing FVB protocol. 353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei// 363cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_FVB_DEVICE mFvbDeviceTemplate = { 373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FVB_DEVICE_SIGNATURE, 383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NULL, 393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbGetAttributes, 413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbSetAttributes, 423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbGetPhysicalAddress, 433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbGetBlockSize, 443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbRead, 453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbWrite, 463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbEraseBlocks, 473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NULL 483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei }, 493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NULL 503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei}; 513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 523cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate = { 533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei HARDWARE_DEVICE_PATH, 563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei HW_MEMMAP_DP, 573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (UINT8)(sizeof (MEMMAP_DEVICE_PATH)), 593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8) 603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei }, 623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EfiMemoryMappedIO, 633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (EFI_PHYSICAL_ADDRESS) 0, 643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (EFI_PHYSICAL_ADDRESS) 0, 653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei }, 663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei END_DEVICE_PATH_TYPE, 683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei END_ENTIRE_DEVICE_PATH_SUBTYPE, 693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei END_DEVICE_PATH_LENGTH, 713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 0 723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei}; 753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 763cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate = { 773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MEDIA_DEVICE_PATH, 803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MEDIA_PIWG_FW_VOL_DP, 813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)), 833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8) 843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei }, 863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 0 } 873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei }, 883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei END_DEVICE_PATH_TYPE, 903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei END_ENTIRE_DEVICE_PATH_SUBTYPE, 913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei { 923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei END_DEVICE_PATH_LENGTH, 933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 0 943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei}; 973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Initialize the communicate buffer using DataSize and Function. 1003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei The communicate size is: SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + 1023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei DataSize. 1033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[out] CommunicateBuffer The communicate buffer. Caller should free it after use. 1053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[out] DataPtr Points to the data in the communicate buffer. Caller should not free it. 1063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] DataSize The payload size. 1073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Function The function number used to initialize the communicate header. 1083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_INVALID_PARAMETER The data size is too big. 1103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS Find the specified variable. 1113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 1133cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 1143cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiInitCommunicateBuffer ( 1153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei OUT VOID **CommunicateBuffer, 1163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei OUT VOID **DataPtr, 1173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINTN DataSize, 1183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINTN Function 1193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 1203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 1213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; 1223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SMM_FVB_COMMUNICATE_FUNCTION_HEADER *SmmFvbFunctionHeader; 1233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // The whole buffer size: SMM_COMMUNICATE_HEADER_SIZE + SMM_FVB_COMMUNICATE_HEADER_SIZE + DataSize. 1263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmCommunicateHeader = AllocatePool (DataSize + SMM_COMMUNICATE_HEADER_SIZE + SMM_FVB_COMMUNICATE_HEADER_SIZE); 1283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ASSERT (SmmCommunicateHeader != NULL); 1293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Prepare data buffer. 1323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gEfiSmmFirmwareVolumeBlockProtocolGuid); 1343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmCommunicateHeader->MessageLength = DataSize + SMM_FVB_COMMUNICATE_HEADER_SIZE; 1353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbFunctionHeader = (SMM_FVB_COMMUNICATE_FUNCTION_HEADER *) SmmCommunicateHeader->Data; 1373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbFunctionHeader->Function = Function; 1383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *CommunicateBuffer = SmmCommunicateHeader; 1403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *DataPtr = SmmFvbFunctionHeader->Data; 1413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_SUCCESS; 1433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 1443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 1473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Send the data in communicate buffer to SMM. 1483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[out] SmmCommunicateHeader The communicate buffer. 1503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] DataSize The payload size. 1513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 1533cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 1543cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiSendCommunicateBuffer ( 1553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader, 1563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINTN DataSize 1573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 1583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 1593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 1603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN CommSize; 1613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SMM_FVB_COMMUNICATE_FUNCTION_HEADER *SmmFvbFunctionHeader; 1623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei CommSize = DataSize + SMM_COMMUNICATE_HEADER_SIZE + SMM_FVB_COMMUNICATE_HEADER_SIZE; 1643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = mSmmCommunication->Communicate ( 1653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei mSmmCommunication, 1663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmCommunicateHeader, 1673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &CommSize 1683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 1693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ASSERT_EFI_ERROR (Status); 1703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbFunctionHeader = (SMM_FVB_COMMUNICATE_FUNCTION_HEADER *) SmmCommunicateHeader->Data; 1723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return SmmFvbFunctionHeader->ReturnStatus; 1733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 1743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 1763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei This function retrieves the attributes and current settings of the block. 1773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. 1793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[out] Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the attributes 1813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei and current settings are returned. Type EFI_FVB_ATTRIBUTES_2 1823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei is defined in EFI_FIRMWARE_VOLUME_HEADER. 1833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS The firmware volume attributes were returned. 1853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_INVALID_PARAMETER Attributes is NULL. 1863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 1873cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 1883cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 1893cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbGetAttributes ( 1903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, 1913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei OUT EFI_FVB_ATTRIBUTES_2 *Attributes 1923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 1933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 1943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 1953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN PayloadSize; 1963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; 1973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SMM_FVB_ATTRIBUTES_HEADER *SmmFvbAttributesHeader; 1983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; 1993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB_DEVICE *FvbDevice; 2003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (Attributes == NULL) { 2023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_INVALID_PARAMETER; 2033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 2043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbDevice = FVB_DEVICE_FROM_THIS (This); 2063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvb = FvbDevice->SmmFvbInstance; 2073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Initialize the communicate buffer. 2103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei PayloadSize = sizeof (SMM_FVB_ATTRIBUTES_HEADER); 2123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = InitCommunicateBuffer ( 2133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (VOID **)&SmmCommunicateHeader, 2143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (VOID **)&SmmFvbAttributesHeader, 2153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei PayloadSize, 2163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FUNCTION_GET_ATTRIBUTES 2173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 2183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (EFI_ERROR (Status)) { 2193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 2203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 2213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbAttributesHeader->SmmFvb = SmmFvb; 2233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbAttributesHeader->Attributes = 0; 2243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Send data to SMM. 2273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); 2293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Get data from SMM. 2323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *Attributes = SmmFvbAttributesHeader->Attributes; 2343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FreePool (SmmCommunicateHeader); 2353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 2373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 2383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 2413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Sets Volume attributes. No polarity translations are done. 2423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] This Calling context. 2443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[out] Attributes Output buffer which contains attributes. 2453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS Set the Attributes successfully. 2473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_INVALID_PARAMETER Attributes is NULL. 2483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 2503cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 2513cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 2523cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbSetAttributes ( 2533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, 2543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes 2553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 2563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 2573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 2583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN PayloadSize; 2593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; 2603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SMM_FVB_ATTRIBUTES_HEADER *SmmFvbAttributesHeader; 2613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; 2623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB_DEVICE *FvbDevice; 2633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (Attributes == NULL) { 2653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_INVALID_PARAMETER; 2663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 2673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbDevice = FVB_DEVICE_FROM_THIS (This); 2693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvb = FvbDevice->SmmFvbInstance; 2703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Initialize the communicate buffer. 2733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei PayloadSize = sizeof (SMM_FVB_ATTRIBUTES_HEADER); 2753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = InitCommunicateBuffer ( 2763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (VOID **)&SmmCommunicateHeader, 2773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (VOID **)&SmmFvbAttributesHeader, 2783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei PayloadSize, 2793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FUNCTION_SET_ATTRIBUTES 2803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 2813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (EFI_ERROR (Status)) { 2823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 2833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 2843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbAttributesHeader->SmmFvb = SmmFvb; 2863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbAttributesHeader->Attributes = *Attributes; 2873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Send data to SMM. 2903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); 2923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Get data from SMM. 2953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 2963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *Attributes = SmmFvbAttributesHeader->Attributes; 2973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FreePool (SmmCommunicateHeader); 2983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 2993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 3003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 3013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 3043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Retrieves the physical address of the FVB instance. 3053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] SmmFvb A pointer to EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL. 3073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[out] Address Output buffer containing the address. 3083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS Get the address successfully. 3103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval Others Failed to get address. 3113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 3133cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 3143cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiGetPhysicalAddress ( 3153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb, 3163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei OUT EFI_PHYSICAL_ADDRESS *Address 3173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 3183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 3193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 3203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN PayloadSize; 3213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; 3223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SMM_FVB_PHYSICAL_ADDRESS_HEADER *SmmFvbPhysicalAddressHeader; 3233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 3253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Initialize the communicate buffer. 3263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 3273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei PayloadSize = sizeof (SMM_FVB_PHYSICAL_ADDRESS_HEADER); 3283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = InitCommunicateBuffer ( 3293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (VOID **)&SmmCommunicateHeader, 3303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (VOID **)&SmmFvbPhysicalAddressHeader, 3313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei PayloadSize, 3323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FUNCTION_GET_PHYSICAL_ADDRESS 3333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 3343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (EFI_ERROR (Status)) { 3353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 3363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 3373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbPhysicalAddressHeader->SmmFvb = SmmFvb; 3393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbPhysicalAddressHeader->Address = 0; 3403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 3423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Send data to SMM. 3433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 3443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); 3453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 3473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Get data from SMM. 3483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 3493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *Address = SmmFvbPhysicalAddressHeader->Address; 3503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FreePool (SmmCommunicateHeader); 3513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 3533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 3543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 3573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Retrieves the physical address of the FVB instance. 3583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] This A pointer to EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL. 3603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[out] Address Output buffer containing the address. 3613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS Get the address successfully. 3633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval Others Failed to get the address. 3643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 3663cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 3673cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 3683cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbGetPhysicalAddress ( 3693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, 3703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei OUT EFI_PHYSICAL_ADDRESS *Address 3713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 3723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 3733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 3743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; 3753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB_DEVICE *FvbDevice; 3763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (Address == NULL) { 3783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_INVALID_PARAMETER; 3793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 3803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbDevice = FVB_DEVICE_FROM_THIS (This); 3823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvb = FvbDevice->SmmFvbInstance; 3833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = GetPhysicalAddress (SmmFvb, Address); 3853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 3873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 3883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 3913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Retrieve the size of a logical block. 3923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 3933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] This Calling context. 3943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Lba Indicates which block to return the size for. 3953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[out] BlockSize A pointer to a caller allocated UINTN in which 3963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei the size of the block is returned. 3973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[out] NumOfBlocks A pointer to a caller allocated UINTN in which the 3983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei number of consecutive blocks starting with Lba is 3993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei returned. All blocks in this range have a size of 4003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BlockSize. 4013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS Get BlockSize and NumOfBlocks successfully. 4033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_INVALID_PARAMETER BlockSize or NumOfBlocks are NULL. 4043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 4053cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 4063cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 4073cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbGetBlockSize ( 4083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, 4093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_LBA Lba, 4103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei OUT UINTN *BlockSize, 4113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei OUT UINTN *NumOfBlocks 4123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 4133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 4143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 4153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN PayloadSize; 4163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; 4173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SMM_FVB_BLOCK_SIZE_HEADER *SmmFvbBlockSizeHeader; 4183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; 4193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB_DEVICE *FvbDevice; 4203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ((BlockSize == NULL) || (NumOfBlocks == NULL)) { 4223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_INVALID_PARAMETER; 4233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 4243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbDevice = FVB_DEVICE_FROM_THIS (This); 4263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvb = FvbDevice->SmmFvbInstance; 4273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 4293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Initialize the communicate buffer. 4303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 4313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei PayloadSize = sizeof (SMM_FVB_BLOCK_SIZE_HEADER); 4323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = InitCommunicateBuffer ( 4333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (VOID **)&SmmCommunicateHeader, 4343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (VOID **)&SmmFvbBlockSizeHeader, 4353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei PayloadSize, 4363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FUNCTION_GET_BLOCK_SIZE 4373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 4383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (EFI_ERROR (Status)) { 4393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 4403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 4413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbBlockSizeHeader->SmmFvb = SmmFvb; 4433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbBlockSizeHeader->Lba = Lba; 4443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 4463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Send data to SMM. 4473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 4483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); 4493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 4513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Get data from SMM. 4523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 4533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *BlockSize = SmmFvbBlockSizeHeader->BlockSize; 4543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *NumOfBlocks = SmmFvbBlockSizeHeader->NumOfBlocks; 4553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FreePool (SmmCommunicateHeader); 4563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 4583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 4593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 4623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Reads data beginning at Lba:Offset from FV. The Read terminates either 4633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei when *NumBytes of data have been read, or when a block boundary is 4643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei reached. *NumBytes is updated to reflect the actual number of bytes 4653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei written. The write opertion does not include erase. This routine will 4663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei attempt to write only the specified bytes. If the writes do not stick, 4673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei it will return an error. 4683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] This Calling context 4703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Lba Block in which to begin write 4713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Offset Offset in the block at which to begin write 4723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in,out] NumBytes On input, indicates the requested write size. On 4733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei output, indicates the actual number of bytes written 4743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Buffer Buffer containing source data for the write. 4753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS The firmware volume was read successfully and 4773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei contents are in Buffer. 4783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_BAD_BUFFER_SIZE Read attempted across a LBA boundary. On output, 4793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NumBytes contains the total number of bytes returned 4803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei in Buffer. 4813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state 4823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_DEVICE_ERROR The block device is not functioning correctly and 4833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei could not be read. 4843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL. 4853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 4863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 4873cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 4883cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 4893cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbRead ( 4903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, 4913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_LBA Lba, 4923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINTN Offset, 4933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN OUT UINTN *NumBytes, 4943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei OUT UINT8 *Buffer 4953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 4963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 4973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 4983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN PayloadSize; 4993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; 5003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SMM_FVB_READ_WRITE_HEADER *SmmFvbReadWriteHeader; 5013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; 5023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB_DEVICE *FvbDevice; 5033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ((NumBytes == NULL) || (Buffer == NULL)) { 5053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_INVALID_PARAMETER; 5063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 5073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbDevice = FVB_DEVICE_FROM_THIS (This); 5093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvb = FvbDevice->SmmFvbInstance; 5103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Initialize the communicate buffer. 5133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei PayloadSize = sizeof (SMM_FVB_READ_WRITE_HEADER) + *NumBytes; 5153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = InitCommunicateBuffer ( 5163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (VOID **)&SmmCommunicateHeader, 5173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (VOID **)&SmmFvbReadWriteHeader, 5183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei PayloadSize, EFI_FUNCTION_READ 5193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 5203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (EFI_ERROR (Status)) { 5213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 5223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 5233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbReadWriteHeader->SmmFvb = SmmFvb; 5253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbReadWriteHeader->Lba = Lba; 5263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbReadWriteHeader->Offset = Offset; 5273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbReadWriteHeader->NumBytes = *NumBytes; 5283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Send data to SMM. 5313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); 5333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Get data from SMM. 5363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *NumBytes = SmmFvbReadWriteHeader->NumBytes; 5383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (!EFI_ERROR (Status)) { 5393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei CopyMem (Buffer, (UINT8 *)(SmmFvbReadWriteHeader + 1), *NumBytes); 5403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 5413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FreePool (SmmCommunicateHeader); 5423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 5443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 5453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 5483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Writes data beginning at Lba:Offset from FV. The write terminates either 5493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei when *NumBytes of data have been written, or when a block boundary is 5503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei reached. *NumBytes is updated to reflect the actual number of bytes 5513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei written. The write opertion does not include erase. This routine will 5523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei attempt to write only the specified bytes. If the writes do not stick, 5533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei it will return an error. 5543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] This Calling context. 5563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Lba Block in which to begin write. 5573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Offset Offset in the block at which to begin write. 5583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in,out] NumBytes On input, indicates the requested write size. On 5593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei output, indicates the actual number of bytes written. 5603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Buffer Buffer containing source data for the write. 5613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS The firmware volume was written successfully. 5633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_BAD_BUFFER_SIZE Write attempted across a LBA boundary. On output, 5643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NumBytes contains the total number of bytes 5653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei actually written. 5663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. 5673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_DEVICE_ERROR The block device is not functioning correctly and 5683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei could not be written. 5693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL. 5703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 5723cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 5733cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 5743cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbWrite ( 5753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, 5763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_LBA Lba, 5773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINTN Offset, 5783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN OUT UINTN *NumBytes, 5793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINT8 *Buffer 5803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 5813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 5823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 5833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN PayloadSize; 5843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; 5853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SMM_FVB_READ_WRITE_HEADER *SmmFvbReadWriteHeader; 5863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; 5873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB_DEVICE *FvbDevice; 5883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ((NumBytes == NULL) || (Buffer == NULL)) { 5903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_INVALID_PARAMETER; 5913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 5923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbDevice = FVB_DEVICE_FROM_THIS (This); 5943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvb = FvbDevice->SmmFvbInstance; 5953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 5963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Initialize the communicate buffer. 5983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 5993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei PayloadSize = sizeof (SMM_FVB_READ_WRITE_HEADER) + *NumBytes; 6003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = InitCommunicateBuffer ( 6013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (VOID **)&SmmCommunicateHeader, 6023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (VOID **)&SmmFvbReadWriteHeader, 6033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei PayloadSize, 6043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FUNCTION_WRITE 6053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 6063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (EFI_ERROR (Status)) { 6073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 6083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 6093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbReadWriteHeader->SmmFvb = SmmFvb; 6113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbReadWriteHeader->Lba = Lba; 6123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbReadWriteHeader->Offset = Offset; 6133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbReadWriteHeader->NumBytes = *NumBytes; 6143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei CopyMem ((UINT8 *)(SmmFvbReadWriteHeader + 1), Buffer, *NumBytes); 6153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 6173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Send data to SMM. 6183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 6193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); 6203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 6223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Get data from SMM. 6233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 6243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei *NumBytes = SmmFvbReadWriteHeader->NumBytes; 6253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FreePool (SmmCommunicateHeader); 6263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 6283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 6293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 6323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei The EraseBlock() function erases NumOfLba blocks started from StartingLba. 6333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] This Calling context. 6353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] StartingLba Starting LBA followed to erase. 6363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] NumOfLba Number of block to erase. 6373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS The erase request was successfully completed. 6393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. 6403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_DEVICE_ERROR The block device is not functioning correctly and 6413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei could not be written. Firmware device may have been 6423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei partially erased. 6433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 6453cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 6463cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEraseBlock ( 6473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, 6483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_LBA StartingLba, 6493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN UINTN NumOfLba 6503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 6513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 6523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 6533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN PayloadSize; 6543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader; 6553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SMM_FVB_BLOCKS_HEADER *SmmFvbBlocksHeader; 6563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; 6573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB_DEVICE *FvbDevice; 6583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbDevice = FVB_DEVICE_FROM_THIS (This); 6603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvb = FvbDevice->SmmFvbInstance; 6613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 6633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Initialize the communicate buffer. 6643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 6653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei PayloadSize = sizeof (SMM_FVB_BLOCKS_HEADER); 6663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = InitCommunicateBuffer ( 6673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (VOID **)&SmmCommunicateHeader, 6683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (VOID **)&SmmFvbBlocksHeader, 6693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei PayloadSize, 6703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FUNCTION_ERASE_BLOCKS 6713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 6723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (EFI_ERROR (Status)) { 6733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 6743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 6753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbBlocksHeader->SmmFvb = SmmFvb; 6773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbBlocksHeader->StartLba = StartingLba; 6783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvbBlocksHeader->NumOfLba = NumOfLba; 6793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 6813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Send data to SMM. 6823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 6833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize); 6843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 6863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Get data from SMM. 6873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 6883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FreePool (SmmCommunicateHeader); 6893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 6913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 6923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 6943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 6953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei The EraseBlocks() function erases one or more blocks as denoted by the 6963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei variable argument list. The entire parameter list of blocks must be verified 6973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei prior to erasing any blocks. If a block is requested that does not exist 6983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei within the associated firmware volume (it has a larger index than the last 6993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei block of the firmware volume), the EraseBlock() function must return 7003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_INVALID_PARAMETER without modifying the contents of the firmware volume. 7013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] This Calling context/ 7033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] ... Starting LBA followed by Number of Lba to erase. 7043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei a -1 to terminate the list. 7053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/ 7063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS The erase request was successfully completed 7073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state/ 7083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_DEVICE_ERROR The block device is not functioning correctly and 7093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei could not be written. Firmware device may have been 7103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei partially erased/ 7113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 7133cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 7143cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 7153cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbEraseBlocks ( 7163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, 7173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ... 7183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 7193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 7203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 7213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VA_LIST Marker; 7223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_LBA StartingLba; 7233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN NumOfLba; 7243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = EFI_SUCCESS; 7263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 7283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Check the parameter. 7293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 7303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VA_START (Marker, This); 7313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei do { 7323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei StartingLba = VA_ARG (Marker, EFI_LBA); 7333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (StartingLba == EFI_LBA_LIST_TERMINATOR ) { 7343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei break; 7353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 7363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NumOfLba = VA_ARG (Marker, UINT32); 7383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (NumOfLba == 0) { 7393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_INVALID_PARAMETER; 7403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 7413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } while ( 1 ); 7433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VA_END (Marker); 7443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 7463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Erase the blocks. 7473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 7483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VA_START (Marker, This); 7493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei do { 7503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei StartingLba = VA_ARG (Marker, EFI_LBA); 7513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (StartingLba == EFI_LBA_LIST_TERMINATOR ) { 7523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei break; 7533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 7543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NumOfLba = VA_ARG (Marker, UINT32); 7553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = EraseBlock (This, StartingLba, NumOfLba); 7563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (EFI_ERROR (Status)) { 7573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei break; 7583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 7593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } while ( 1 ); 7603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VA_END (Marker); 7613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return Status; 7633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 7643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 7673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Install the FVB protocol which based on SMM FVB protocol. 7683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] SmmFvb The SMM FVB protocol. 7703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 7723cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiVOID 7733cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiInstallFvb ( 7743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb 7753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 7763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 7773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 7783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_HANDLE FvbHandle; 7793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FVB_DEVICE *FvbDevice; 7803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FIRMWARE_VOLUME_HEADER *VolumeHeader; 7813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_PHYSICAL_ADDRESS Address; 7823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *OldFvbInterface; 7833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbDevice = AllocateRuntimeCopyPool (sizeof (EFI_FVB_DEVICE), &mFvbDeviceTemplate); 7853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ASSERT (FvbDevice != NULL); 7863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbDevice->SmmFvbInstance = SmmFvb; 7873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gBS->LocateProtocol ( 7893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &gEfiSmmCommunicationProtocolGuid, 7903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NULL, 7913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (VOID **) &mSmmCommunication 7923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 7933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ASSERT_EFI_ERROR (Status); 7943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = GetPhysicalAddress (SmmFvb, &Address); 7963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ASSERT_EFI_ERROR (Status); 7973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 7983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN)Address; 7993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 8013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Set up the devicepath. 8023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 8033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (VolumeHeader->ExtHeaderOffset == 0) { 8043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 8053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH. 8063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 8073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate); 8083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.StartingAddress = (UINTN)Address; 8093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.EndingAddress = (UINTN)Address + VolumeHeader->FvLength - 1; 8103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } else { 8113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate); 8123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei CopyGuid ( 8133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &((FV_PIWG_DEVICE_PATH *)FvbDevice->DevicePath)->FvDevPath.FvName, 8143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (GUID *)(UINTN)((UINTN)Address + VolumeHeader->ExtHeaderOffset) 8153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 8163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 8173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 8193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Find a handle with a matching device path that has supports FW Block protocol. 8203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 8213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gBS->LocateDevicePath ( 8223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &gEfiFirmwareVolumeBlockProtocolGuid, 8233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &FvbDevice->DevicePath, 8243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &FvbHandle 8253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 8263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (EFI_ERROR (Status) ) { 8273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 8283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // LocateDevicePath fails so install a new interface and device path. 8293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 8303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbHandle = NULL; 8313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gBS->InstallMultipleProtocolInterfaces ( 8323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &FvbHandle, 8333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &gEfiFirmwareVolumeBlockProtocolGuid, 8343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &FvbDevice->FvbInstance, 8353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &gEfiDevicePathProtocolGuid, 8363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbDevice->DevicePath, 8373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NULL 8383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 8393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ASSERT_EFI_ERROR (Status); 8403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } else if (IsDevicePathEnd (FvbDevice->DevicePath)) { 8413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 8423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Device allready exists, so reinstall the FVB protocol. 8433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 8443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gBS->HandleProtocol ( 8453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbHandle, 8463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &gEfiFirmwareVolumeBlockProtocolGuid, 8473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (VOID **) &OldFvbInterface 8483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 8493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ASSERT_EFI_ERROR (Status); 8503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gBS->ReinstallProtocolInterface ( 8523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FvbHandle, 8533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &gEfiFirmwareVolumeBlockProtocolGuid, 8543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei OldFvbInterface, 8553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &FvbDevice->FvbInstance 8563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 8573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ASSERT_EFI_ERROR (Status); 8583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } else { 8593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 8603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // There was a FVB protocol on an End Device Path node. 8613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 8623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ASSERT (FALSE); 8633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 8643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 8653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 8683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SMM Firmware Volume Block Protocol notification event handler. 8693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Discover NV Variable Store and install Variable Write Arch Protocol. 8713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Event Event whose notification function is being invoked. 8733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] Context Pointer to the notification function's context. 8743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 8753cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiVOID 8763cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 8773cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiSmmFvbReady ( 8783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_EVENT Event, 8793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN VOID *Context 8803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 8813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 8823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status; 8833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_HANDLE *HandleBuffer; 8843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN HandleCount; 8853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN Index; 8863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL *SmmFvb; 8873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 8883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 8893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Locate all handles of Smm Fvb protocol. 8903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 8913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gBS->LocateHandleBuffer ( 8923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ByProtocol, 8933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &gEfiSmmFirmwareVolumeBlockProtocolGuid, 8943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NULL, 8953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &HandleCount, 8963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &HandleBuffer 8973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 8983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (EFI_ERROR (Status)) { 8993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return ; 9003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 9013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 9033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Install FVB protocol. 9043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 9053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei for (Index = 0; Index < HandleCount; Index++) { 9063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SmmFvb = NULL; 9073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gBS->HandleProtocol ( 9083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei HandleBuffer[Index], 9093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &gEfiSmmFirmwareVolumeBlockProtocolGuid, 9103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (VOID **) &SmmFvb 9113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 9123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (EFI_ERROR (Status)) { 9133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei break; 9143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 9153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei InstallFvb (SmmFvb); 9173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 9183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei FreePool (HandleBuffer); 9203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 9213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 9243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei The driver entry point for Firmware Volume Block Driver. 9253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9263cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei The function does the necessary initialization work 9273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Firmware Volume Block Driver. 9283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] ImageHandle The firmware allocated handle for the UEFI image. 9303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @param[in] SystemTable A pointer to the EFI system table. 9313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei @retval EFI_SUCCESS This funtion always return EFI_SUCCESS. 9333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei It will ASSERT on errors. 9343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei**/ 9363cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 9373cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 9383cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiFvbSmmDxeInitialize ( 9393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_HANDLE ImageHandle, 9403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_SYSTEM_TABLE *SystemTable 9413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 9423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 9433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VOID *SmmFvbRegistration; 9443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 9453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 9463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Smm FVB driver is ready. 9473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 9483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EfiCreateProtocolNotifyEvent ( 9493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &gEfiSmmFirmwareVolumeBlockProtocolGuid, 950 TPL_CALLBACK, 951 SmmFvbReady, 952 NULL, 953 &SmmFvbRegistration 954 ); 955 956 return EFI_SUCCESS; 957} 958 959