/** @file Header file for FvbServicesRuntimeDxe driver. ;****************************************************************************** ;* Copyright (c) 2012 - 2020, Insyde Software Corp. All Rights Reserved. ;* ;* You may not reproduce, distribute, publish, display, perform, modify, adapt, ;* transmit, broadcast, present, recite, release, license or otherwise exploit ;* any part of this publication in any form, by any means, without the prior ;* written permission of Insyde Software Corporation. ;* ;****************************************************************************** */ #ifndef _FVB_SERVICES_RUNTIME_DXE_H_ #define _FVB_SERVICES_RUNTIME_DXE_H_ #include // // The protocols, PPI and GUID defintions for this module // #include #include #include #include #include #include #include #include // // The Library classes this module consumes // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define SMM_FD_FUNCTIONS_PROTOCOL_GUID \ { \ 0xdb122ac0, 0x19e2, 0x497e, { 0x9f, 0xdf, 0xee, 0x80, 0xe, 0xcb, 0xc5, 0x7f } \ } // // BugBug: Add documentation here for data structure!!!! // #define FVB_PHYSICAL 0 #define FVB_VIRTUAL 1 typedef struct { UINTN FvBase[2]; UINTN NumOfBlocks; EFI_FIRMWARE_VOLUME_HEADER VolumeHeader; } EFI_FW_VOL_INSTANCE; typedef struct { UINT32 NumFv; EFI_FW_VOL_INSTANCE *FvInstance[2]; UINT8 *FvbScratchSpace[2]; } ESAL_FWB_GLOBAL; // // Fvb Protocol instance data // #define FVB_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE) #define FVB_EXTEND_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, FvbExtension, FVB_DEVICE_SIGNATURE) #define FVB_DEVICE_SIGNATURE SIGNATURE_32 ('F', 'V', 'B', 'N') /// /// Size of SMM communicate header, without including the payload. /// #define SMM_COMMUNICATE_HEADER_SIZE (OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)) typedef struct { MEDIA_FW_VOL_DEVICE_PATH FvDevPath; EFI_DEVICE_PATH_PROTOCOL EndDevPath; } FV_PIWG_DEVICE_PATH; typedef struct { MEMMAP_DEVICE_PATH MemMapDevPath; EFI_DEVICE_PATH_PROTOCOL EndDevPath; } FV_MEMMAP_DEVICE_PATH; typedef struct { UINTN Signature; EFI_DEVICE_PATH_PROTOCOL *DevicePath; UINTN Instance; EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FwVolBlockInstance; } EFI_FW_VOL_BLOCK_DEVICE; typedef struct { EFI_PHYSICAL_ADDRESS BaseAddress; EFI_FIRMWARE_VOLUME_HEADER FvbInfo; // // EFI_FV_BLOCK_MAP_ENTRY ExtraBlockMap[n];//n=0 // EFI_FV_BLOCK_MAP_ENTRY End[1]; } EFI_FVB_MEDIA_INFO; // // Accessing FVB relative definitions // #define SMM_FVB_ACCESS_SIGNATURE SIGNATURE_32 ('S', 'M', 'F', 'A') typedef enum { PfatReadFvb, PfatWriteFvb, PfatEraseFvb, } SMM_FVB_ACCESS_TYPE; typedef EFI_STATUS (EFIAPI *SMI_SUB_FUNCTION) ( VOID ); typedef struct { SMM_FVB_ACCESS_TYPE FunNum; SMI_SUB_FUNCTION SmiSubFunction; } SMI_SUB_FUNCTION_MAP; // // Status : Output status after function execution. // Singature : Signature for SMM_FVB_BUFFER, the signature must be SMM_FIRMWARE_VOLUME_SIGNATURE // AccessType : Access type for this execution. the value should be PfatReadFvb, PfatWriteFvb, or PfatEraseFvb. // AccessAddress : The address which want to access in FV. // DataSize : Data size by byte for access. // DataBuffer : Data buffer for access. this buffer must append at the end of SMM_FVB_BUFFER. // typedef struct { EFI_STATUS Status; UINT32 Signature; UINTN AccessAddress; SMM_FVB_ACCESS_TYPE AccessType; UINTN DataSize; // //UINT8 *DataBuffer; // } SMM_FVB_BUFFER; typedef EFI_STATUS (EFIAPI *SMM_FLASH_READ)( IN UINT8 *Dest, IN UINT8 *Src, IN UINTN Count ); typedef EFI_STATUS (EFIAPI *SMM_FLASH_WRITE)( IN UINT8 *Dest, IN UINT8 *Src, IN UINTN *NumBytes, IN UINTN LbaWriteAddress ); typedef EFI_STATUS (EFIAPI *SMM_FLASH_ERASE)( IN UINTN LbaWriteAddress, IN UINTN EraseSize ); typedef struct _SMM_FD_FUNCTIONS { SMM_FLASH_READ SmmFlashRead; SMM_FLASH_WRITE SmmFlashWrite; SMM_FLASH_ERASE SmmFlashErase; } SMM_FD_FUNCTIONS; /** Calculate correct checksum for all of backup firmware volume headers and put the checksum result to all of backup firmware volume headers. **/ VOID RecalculateFvHeaderChecksum ( VOID ); /** Get backup firmware volume header contents according to physical base address. @param[in] BaseAddress Firmware volume start address. @param[out] FvbInfo Double pointer to output firmware volume header. @retval EFI_SUCCESS Get firmware volume contents successful. @retval EFI_NOT_FOUND Cannot find corresponding firmware volume header. **/ EFI_STATUS GetFvbInfo ( IN UINT64 FvLength, OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo ); // // Protocol APIs // /** Retrieves Volume attributes. No polarity translations are done. @param[in] This Calling context. @param[out] Attributes Output buffer which contains attributes @retval EFI_SUCCESS Successfully returns. **/ EFI_STATUS EFIAPI FvbProtocolGetAttributes ( IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, OUT EFI_FVB_ATTRIBUTES_2 *Attributes ); /** Sets Volume attributes. No polarity translations are done. @param [in] This Calling context. @param [in,out] Attributes Output buffer which contains attributes. @retval EFI_SUCCESS Successfully returns. **/ EFI_STATUS EFIAPI FvbProtocolSetAttributes ( IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes ); /** Retrieves the physical address of the device. @param [in] This Calling context. @param [out] Address Output buffer containing the address. @retval EFI_SUCCESS Successfully returns. **/ EFI_STATUS EFIAPI FvbProtocolGetPhysicalAddress ( IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, OUT EFI_PHYSICAL_ADDRESS *Address ); /** Retrieve the size of a logical block. @param [in] This Calling context. @param [in] Lba Indicates which block to return the size for. @param [out] BlockSize A pointer to a caller allocated UINTN in which the size of the block is returned. @param [out] NumOfBlocks a pointer to a caller allocated UINTN in which the number of consecutive blocks starting with Lba is returned. All blocks in this range have a size of BlockSize. @retval EFI_SUCCESS The firmware volume was read successfully and contents are in Buffer. **/ EFI_STATUS EFIAPI FvbProtocolGetBlockSize ( IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, IN CONST EFI_LBA Lba, OUT UINTN *BlockSize, OUT UINTN *NumOfBlocks ); /** Reads data beginning at Lba:Offset from FV. The Read terminates either when *NumBytes of data have been read, or when a block boundary is reached. *NumBytes is updated to reflect the actual number of bytes written. The write opertion does not include erase. This routine will attempt to write only the specified bytes. If the writes do not stick, it will return an error. @param[in] This Calling context. @param[in] Lba Block in which to begin Read. @param[in] Offset Offset in the block at which to begin Read. @param[in, out] NumBytes On input, indicates the requested write size. On output, indicates the actual number of bytes Read. @param[in] Buffer Buffer containing source data for the Read. @retval EFI_SUCCESS The firmware volume was read successfully and contents are in Buffer. @retval EFI_BAD_BUFFER_SIZE Read attempted across a LBA boundary. On output, NumBytes contains the total number of bytes returned in Buffer. @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state. @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be read. @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL. **/ EFI_STATUS EFIAPI FvbProtocolRead ( IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, IN CONST EFI_LBA Lba, IN CONST UINTN Offset, IN OUT UINTN *NumBytes, IN UINT8 *Buffer ); /** Writes data beginning at Lba:Offset from FV. The write terminates either when *NumBytes of data have been written, or when a block boundary is reached. *NumBytes is updated to reflect the actual number of bytes written. The write opertion does not include erase. This routine will attempt to write only the specified bytes. If the writes do not stick, it will return an error. @param[in] This Calling context. @param[in] Lba Block in which to begin write. @param[in] Offset Offset in the block at which to begin write. @param[in, out] NumBytes On input, indicates the requested write size. On output, indicates the actual number of bytes written. @param[in] Buffer Buffer containing source data for the write. @retval EFI_SUCCESS The firmware volume was written successfully. @retval EFI_BAD_BUFFER_SIZE Write attempted across a LBA boundary. On output, NumBytes contains the total number of bytes actually written. @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be written. @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL. **/ EFI_STATUS EFIAPI FvbProtocolWrite ( IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, IN EFI_LBA Lba, IN UINTN Offset, IN OUT UINTN *NumBytes, IN UINT8 *Buffer ); /** The EraseBlock() function erases one or more blocks as denoted by the variable argument list. The entire parameter list of blocks must be verified prior to erasing any blocks. If a block is requested that does not exist within the associated firmware volume (it has a larger index than the last block of the firmware volume), the EraseBlock() function must return EFI_INVALID_PARAMETER without modifying the contents of the firmware volume. @retval EFI_SUCCESS The erase request was successfully completed @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be written. Firmware device may have been partially erased. **/ EFI_STATUS EFIAPI FvbProtocolEraseBlocks ( IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, ... ); /** Communication service SMI Handler entry. This SMI handler provides services for the firmware volume access through SMI. @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). @param[in] RegisterContext Points to an optional handler context which was specified when the handler was registered. @param[in, out] CommBuffer A pointer to a collection of data in memory that will be conveyed from a non-SMM environment into an SMM environment. @param[in, out] CommBufferSize The size of the CommBuffer. @retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers should still be called. @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should still be called. @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still be called. @retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced. **/ EFI_STATUS EFIAPI SmmFvbAccessHandler ( IN EFI_HANDLE DispatchHandle, IN CONST VOID *RegisterContext, IN OUT VOID *CommBuffer, IN OUT UINTN *CommBufferSize ); extern ESAL_FWB_GLOBAL *mFvbModuleGlobal; extern EFI_SMM_SYSTEM_TABLE2 *mSmst; extern BOOLEAN mFvbAccessThroughSmi; extern SMM_FVB_BUFFER *mSmmCommunicationBuffer; extern SMM_FVB_BUFFER *mSmmPhyCommunicationBuffer; extern UINTN mSmmCommunicationBufferSize; extern EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication; extern EFI_GUID mSmmFdFunctionsProtocolGuid; extern EFI_GUID gFvbAccessThroughSmiGuid; #endif