1*f439973dSWarner Losh /** @file 2*f439973dSWarner Losh This file provides control over block-oriented firmware devices. 3*f439973dSWarner Losh 4*f439973dSWarner Losh Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> 5*f439973dSWarner Losh SPDX-License-Identifier: BSD-2-Clause-Patent 6*f439973dSWarner Losh 7*f439973dSWarner Losh @par Revision Reference: PI 8*f439973dSWarner Losh Version 1.0 and 1.2. 9*f439973dSWarner Losh 10*f439973dSWarner Losh **/ 11*f439973dSWarner Losh 12*f439973dSWarner Losh #ifndef __FIRMWARE_VOLUME_BLOCK_H__ 13*f439973dSWarner Losh #define __FIRMWARE_VOLUME_BLOCK_H__ 14*f439973dSWarner Losh 15*f439973dSWarner Losh // 16*f439973dSWarner Losh // EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL is defined in PI 1.0 spec and its GUID value 17*f439973dSWarner Losh // is later updated to be the same as that of EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL 18*f439973dSWarner Losh // defined in PI 1.2 spec. 19*f439973dSWarner Losh // 20*f439973dSWarner Losh #define EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID \ 21*f439973dSWarner Losh { 0x8f644fa9, 0xe850, 0x4db1, {0x9c, 0xe2, 0xb, 0x44, 0x69, 0x8e, 0x8d, 0xa4 } } 22*f439973dSWarner Losh 23*f439973dSWarner Losh #define EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL_GUID \ 24*f439973dSWarner Losh { 0x8f644fa9, 0xe850, 0x4db1, {0x9c, 0xe2, 0xb, 0x44, 0x69, 0x8e, 0x8d, 0xa4 } } 25*f439973dSWarner Losh 26*f439973dSWarner Losh typedef struct _EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL; 27*f439973dSWarner Losh 28*f439973dSWarner Losh typedef EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL; 29*f439973dSWarner Losh 30*f439973dSWarner Losh /** 31*f439973dSWarner Losh The GetAttributes() function retrieves the attributes and 32*f439973dSWarner Losh current settings of the block. 33*f439973dSWarner Losh 34*f439973dSWarner Losh @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. 35*f439973dSWarner Losh 36*f439973dSWarner Losh @param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the 37*f439973dSWarner Losh attributes and current settings are 38*f439973dSWarner Losh returned. Type EFI_FVB_ATTRIBUTES_2 is defined 39*f439973dSWarner Losh in EFI_FIRMWARE_VOLUME_HEADER. 40*f439973dSWarner Losh 41*f439973dSWarner Losh @retval EFI_SUCCESS The firmware volume attributes were 42*f439973dSWarner Losh returned. 43*f439973dSWarner Losh 44*f439973dSWarner Losh **/ 45*f439973dSWarner Losh typedef 46*f439973dSWarner Losh EFI_STATUS 47*f439973dSWarner Losh (EFIAPI *EFI_FVB_GET_ATTRIBUTES)( 48*f439973dSWarner Losh IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, 49*f439973dSWarner Losh OUT EFI_FVB_ATTRIBUTES_2 *Attributes 50*f439973dSWarner Losh ); 51*f439973dSWarner Losh 52*f439973dSWarner Losh /** 53*f439973dSWarner Losh The SetAttributes() function sets configurable firmware volume 54*f439973dSWarner Losh attributes and returns the new settings of the firmware volume. 55*f439973dSWarner Losh 56*f439973dSWarner Losh @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. 57*f439973dSWarner Losh 58*f439973dSWarner Losh @param Attributes On input, Attributes is a pointer to 59*f439973dSWarner Losh EFI_FVB_ATTRIBUTES_2 that contains the 60*f439973dSWarner Losh desired firmware volume settings. On 61*f439973dSWarner Losh successful return, it contains the new 62*f439973dSWarner Losh settings of the firmware volume. Type 63*f439973dSWarner Losh EFI_FVB_ATTRIBUTES_2 is defined in 64*f439973dSWarner Losh EFI_FIRMWARE_VOLUME_HEADER. 65*f439973dSWarner Losh 66*f439973dSWarner Losh @retval EFI_SUCCESS The firmware volume attributes were returned. 67*f439973dSWarner Losh 68*f439973dSWarner Losh @retval EFI_INVALID_PARAMETER The attributes requested are in 69*f439973dSWarner Losh conflict with the capabilities 70*f439973dSWarner Losh as declared in the firmware 71*f439973dSWarner Losh volume header. 72*f439973dSWarner Losh 73*f439973dSWarner Losh **/ 74*f439973dSWarner Losh typedef 75*f439973dSWarner Losh EFI_STATUS 76*f439973dSWarner Losh (EFIAPI *EFI_FVB_SET_ATTRIBUTES)( 77*f439973dSWarner Losh IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, 78*f439973dSWarner Losh IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes 79*f439973dSWarner Losh ); 80*f439973dSWarner Losh 81*f439973dSWarner Losh /** 82*f439973dSWarner Losh The GetPhysicalAddress() function retrieves the base address of 83*f439973dSWarner Losh a memory-mapped firmware volume. This function should be called 84*f439973dSWarner Losh only for memory-mapped firmware volumes. 85*f439973dSWarner Losh 86*f439973dSWarner Losh @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. 87*f439973dSWarner Losh 88*f439973dSWarner Losh @param Address Pointer to a caller-allocated 89*f439973dSWarner Losh EFI_PHYSICAL_ADDRESS that, on successful 90*f439973dSWarner Losh return from GetPhysicalAddress(), contains the 91*f439973dSWarner Losh base address of the firmware volume. 92*f439973dSWarner Losh 93*f439973dSWarner Losh @retval EFI_SUCCESS The firmware volume base address was returned. 94*f439973dSWarner Losh 95*f439973dSWarner Losh @retval EFI_UNSUPPORTED The firmware volume is not memory mapped. 96*f439973dSWarner Losh 97*f439973dSWarner Losh **/ 98*f439973dSWarner Losh typedef 99*f439973dSWarner Losh EFI_STATUS 100*f439973dSWarner Losh (EFIAPI *EFI_FVB_GET_PHYSICAL_ADDRESS)( 101*f439973dSWarner Losh IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, 102*f439973dSWarner Losh OUT EFI_PHYSICAL_ADDRESS *Address 103*f439973dSWarner Losh ); 104*f439973dSWarner Losh 105*f439973dSWarner Losh /** 106*f439973dSWarner Losh The GetBlockSize() function retrieves the size of the requested 107*f439973dSWarner Losh block. It also returns the number of additional blocks with 108*f439973dSWarner Losh the identical size. The GetBlockSize() function is used to 109*f439973dSWarner Losh retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER). 110*f439973dSWarner Losh 111*f439973dSWarner Losh 112*f439973dSWarner Losh @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. 113*f439973dSWarner Losh 114*f439973dSWarner Losh @param Lba Indicates the block for which to return the size. 115*f439973dSWarner Losh 116*f439973dSWarner Losh @param BlockSize Pointer to a caller-allocated UINTN in which 117*f439973dSWarner Losh the size of the block is returned. 118*f439973dSWarner Losh 119*f439973dSWarner Losh @param NumberOfBlocks Pointer to a caller-allocated UINTN in 120*f439973dSWarner Losh which the number of consecutive blocks, 121*f439973dSWarner Losh starting with Lba, is returned. All 122*f439973dSWarner Losh blocks in this range have a size of 123*f439973dSWarner Losh BlockSize. 124*f439973dSWarner Losh 125*f439973dSWarner Losh 126*f439973dSWarner Losh @retval EFI_SUCCESS The firmware volume base address was returned. 127*f439973dSWarner Losh 128*f439973dSWarner Losh @retval EFI_INVALID_PARAMETER The requested LBA is out of range. 129*f439973dSWarner Losh 130*f439973dSWarner Losh **/ 131*f439973dSWarner Losh typedef 132*f439973dSWarner Losh EFI_STATUS 133*f439973dSWarner Losh (EFIAPI *EFI_FVB_GET_BLOCK_SIZE)( 134*f439973dSWarner Losh IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, 135*f439973dSWarner Losh IN EFI_LBA Lba, 136*f439973dSWarner Losh OUT UINTN *BlockSize, 137*f439973dSWarner Losh OUT UINTN *NumberOfBlocks 138*f439973dSWarner Losh ); 139*f439973dSWarner Losh 140*f439973dSWarner Losh /** 141*f439973dSWarner Losh Reads the specified number of bytes into a buffer from the specified block. 142*f439973dSWarner Losh 143*f439973dSWarner Losh The Read() function reads the requested number of bytes from the 144*f439973dSWarner Losh requested block and stores them in the provided buffer. 145*f439973dSWarner Losh Implementations should be mindful that the firmware volume 146*f439973dSWarner Losh might be in the ReadDisabled state. If it is in this state, 147*f439973dSWarner Losh the Read() function must return the status code 148*f439973dSWarner Losh EFI_ACCESS_DENIED without modifying the contents of the 149*f439973dSWarner Losh buffer. The Read() function must also prevent spanning block 150*f439973dSWarner Losh boundaries. If a read is requested that would span a block 151*f439973dSWarner Losh boundary, the read must read up to the boundary but not 152*f439973dSWarner Losh beyond. The output parameter NumBytes must be set to correctly 153*f439973dSWarner Losh indicate the number of bytes actually read. The caller must be 154*f439973dSWarner Losh aware that a read may be partially completed. 155*f439973dSWarner Losh 156*f439973dSWarner Losh @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. 157*f439973dSWarner Losh 158*f439973dSWarner Losh @param Lba The starting logical block index 159*f439973dSWarner Losh from which to read. 160*f439973dSWarner Losh 161*f439973dSWarner Losh @param Offset Offset into the block at which to begin reading. 162*f439973dSWarner Losh 163*f439973dSWarner Losh @param NumBytes Pointer to a UINTN. At entry, *NumBytes 164*f439973dSWarner Losh contains the total size of the buffer. At 165*f439973dSWarner Losh exit, *NumBytes contains the total number of 166*f439973dSWarner Losh bytes read. 167*f439973dSWarner Losh 168*f439973dSWarner Losh @param Buffer Pointer to a caller-allocated buffer that will 169*f439973dSWarner Losh be used to hold the data that is read. 170*f439973dSWarner Losh 171*f439973dSWarner Losh @retval EFI_SUCCESS The firmware volume was read successfully, 172*f439973dSWarner Losh and contents are in Buffer. 173*f439973dSWarner Losh 174*f439973dSWarner Losh @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA 175*f439973dSWarner Losh boundary. On output, NumBytes 176*f439973dSWarner Losh contains the total number of bytes 177*f439973dSWarner Losh returned in Buffer. 178*f439973dSWarner Losh 179*f439973dSWarner Losh @retval EFI_ACCESS_DENIED The firmware volume is in the 180*f439973dSWarner Losh ReadDisabled state. 181*f439973dSWarner Losh 182*f439973dSWarner Losh @retval EFI_DEVICE_ERROR The block device is not 183*f439973dSWarner Losh functioning correctly and could 184*f439973dSWarner Losh not be read. 185*f439973dSWarner Losh 186*f439973dSWarner Losh **/ 187*f439973dSWarner Losh typedef 188*f439973dSWarner Losh EFI_STATUS 189*f439973dSWarner Losh (EFIAPI *EFI_FVB_READ)( 190*f439973dSWarner Losh IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, 191*f439973dSWarner Losh IN EFI_LBA Lba, 192*f439973dSWarner Losh IN UINTN Offset, 193*f439973dSWarner Losh IN OUT UINTN *NumBytes, 194*f439973dSWarner Losh IN OUT UINT8 *Buffer 195*f439973dSWarner Losh ); 196*f439973dSWarner Losh 197*f439973dSWarner Losh /** 198*f439973dSWarner Losh Writes the specified number of bytes from the input buffer to the block. 199*f439973dSWarner Losh 200*f439973dSWarner Losh The Write() function writes the specified number of bytes from 201*f439973dSWarner Losh the provided buffer to the specified block and offset. If the 202*f439973dSWarner Losh firmware volume is sticky write, the caller must ensure that 203*f439973dSWarner Losh all the bits of the specified range to write are in the 204*f439973dSWarner Losh EFI_FVB_ERASE_POLARITY state before calling the Write() 205*f439973dSWarner Losh function, or else the result will be unpredictable. This 206*f439973dSWarner Losh unpredictability arises because, for a sticky-write firmware 207*f439973dSWarner Losh volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY 208*f439973dSWarner Losh state but cannot flip it back again. Before calling the 209*f439973dSWarner Losh Write() function, it is recommended for the caller to first call 210*f439973dSWarner Losh the EraseBlocks() function to erase the specified block to 211*f439973dSWarner Losh write. A block erase cycle will transition bits from the 212*f439973dSWarner Losh (NOT)EFI_FVB_ERASE_POLARITY state back to the 213*f439973dSWarner Losh EFI_FVB_ERASE_POLARITY state. Implementations should be 214*f439973dSWarner Losh mindful that the firmware volume might be in the WriteDisabled 215*f439973dSWarner Losh state. If it is in this state, the Write() function must 216*f439973dSWarner Losh return the status code EFI_ACCESS_DENIED without modifying the 217*f439973dSWarner Losh contents of the firmware volume. The Write() function must 218*f439973dSWarner Losh also prevent spanning block boundaries. If a write is 219*f439973dSWarner Losh requested that spans a block boundary, the write must store up 220*f439973dSWarner Losh to the boundary but not beyond. The output parameter NumBytes 221*f439973dSWarner Losh must be set to correctly indicate the number of bytes actually 222*f439973dSWarner Losh written. The caller must be aware that a write may be 223*f439973dSWarner Losh partially completed. All writes, partial or otherwise, must be 224*f439973dSWarner Losh fully flushed to the hardware before the Write() service 225*f439973dSWarner Losh returns. 226*f439973dSWarner Losh 227*f439973dSWarner Losh @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. 228*f439973dSWarner Losh 229*f439973dSWarner Losh @param Lba The starting logical block index to write to. 230*f439973dSWarner Losh 231*f439973dSWarner Losh @param Offset Offset into the block at which to begin writing. 232*f439973dSWarner Losh 233*f439973dSWarner Losh @param NumBytes The pointer to a UINTN. At entry, *NumBytes 234*f439973dSWarner Losh contains the total size of the buffer. At 235*f439973dSWarner Losh exit, *NumBytes contains the total number of 236*f439973dSWarner Losh bytes actually written. 237*f439973dSWarner Losh 238*f439973dSWarner Losh @param Buffer The pointer to a caller-allocated buffer that 239*f439973dSWarner Losh contains the source for the write. 240*f439973dSWarner Losh 241*f439973dSWarner Losh @retval EFI_SUCCESS The firmware volume was written successfully. 242*f439973dSWarner Losh 243*f439973dSWarner Losh @retval EFI_BAD_BUFFER_SIZE The write was attempted across an 244*f439973dSWarner Losh LBA boundary. On output, NumBytes 245*f439973dSWarner Losh contains the total number of bytes 246*f439973dSWarner Losh actually written. 247*f439973dSWarner Losh 248*f439973dSWarner Losh @retval EFI_ACCESS_DENIED The firmware volume is in the 249*f439973dSWarner Losh WriteDisabled state. 250*f439973dSWarner Losh 251*f439973dSWarner Losh @retval EFI_DEVICE_ERROR The block device is malfunctioning 252*f439973dSWarner Losh and could not be written. 253*f439973dSWarner Losh 254*f439973dSWarner Losh 255*f439973dSWarner Losh **/ 256*f439973dSWarner Losh typedef 257*f439973dSWarner Losh EFI_STATUS 258*f439973dSWarner Losh (EFIAPI *EFI_FVB_WRITE)( 259*f439973dSWarner Losh IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, 260*f439973dSWarner Losh IN EFI_LBA Lba, 261*f439973dSWarner Losh IN UINTN Offset, 262*f439973dSWarner Losh IN OUT UINTN *NumBytes, 263*f439973dSWarner Losh IN UINT8 *Buffer 264*f439973dSWarner Losh ); 265*f439973dSWarner Losh 266*f439973dSWarner Losh /// 267*f439973dSWarner Losh /// EFI_LBA_LIST_TERMINATOR 268*f439973dSWarner Losh /// 269*f439973dSWarner Losh #define EFI_LBA_LIST_TERMINATOR 0xFFFFFFFFFFFFFFFFULL 270*f439973dSWarner Losh 271*f439973dSWarner Losh /** 272*f439973dSWarner Losh Erases and initializes a firmware volume block. 273*f439973dSWarner Losh 274*f439973dSWarner Losh The EraseBlocks() function erases one or more blocks as denoted 275*f439973dSWarner Losh by the variable argument list. The entire parameter list of 276*f439973dSWarner Losh blocks must be verified before erasing any blocks. If a block is 277*f439973dSWarner Losh requested that does not exist within the associated firmware 278*f439973dSWarner Losh volume (it has a larger index than the last block of the 279*f439973dSWarner Losh firmware volume), the EraseBlocks() function must return the 280*f439973dSWarner Losh status code EFI_INVALID_PARAMETER without modifying the contents 281*f439973dSWarner Losh of the firmware volume. Implementations should be mindful that 282*f439973dSWarner Losh the firmware volume might be in the WriteDisabled state. If it 283*f439973dSWarner Losh is in this state, the EraseBlocks() function must return the 284*f439973dSWarner Losh status code EFI_ACCESS_DENIED without modifying the contents of 285*f439973dSWarner Losh the firmware volume. All calls to EraseBlocks() must be fully 286*f439973dSWarner Losh flushed to the hardware before the EraseBlocks() service 287*f439973dSWarner Losh returns. 288*f439973dSWarner Losh 289*f439973dSWarner Losh @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL 290*f439973dSWarner Losh instance. 291*f439973dSWarner Losh 292*f439973dSWarner Losh @param ... The variable argument list is a list of tuples. 293*f439973dSWarner Losh Each tuple describes a range of LBAs to erase 294*f439973dSWarner Losh and consists of the following: 295*f439973dSWarner Losh - An EFI_LBA that indicates the starting LBA 296*f439973dSWarner Losh - A UINTN that indicates the number of blocks to 297*f439973dSWarner Losh erase. 298*f439973dSWarner Losh 299*f439973dSWarner Losh The list is terminated with an 300*f439973dSWarner Losh EFI_LBA_LIST_TERMINATOR. For example, the 301*f439973dSWarner Losh following indicates that two ranges of blocks 302*f439973dSWarner Losh (5-7 and 10-11) are to be erased: EraseBlocks 303*f439973dSWarner Losh (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR); 304*f439973dSWarner Losh 305*f439973dSWarner Losh @retval EFI_SUCCESS The erase request successfully 306*f439973dSWarner Losh completed. 307*f439973dSWarner Losh 308*f439973dSWarner Losh @retval EFI_ACCESS_DENIED The firmware volume is in the 309*f439973dSWarner Losh WriteDisabled state. 310*f439973dSWarner Losh @retval EFI_DEVICE_ERROR The block device is not functioning 311*f439973dSWarner Losh correctly and could not be written. 312*f439973dSWarner Losh The firmware device may have been 313*f439973dSWarner Losh partially erased. 314*f439973dSWarner Losh @retval EFI_INVALID_PARAMETER One or more of the LBAs listed 315*f439973dSWarner Losh in the variable argument list do 316*f439973dSWarner Losh not exist in the firmware volume. 317*f439973dSWarner Losh 318*f439973dSWarner Losh **/ 319*f439973dSWarner Losh typedef 320*f439973dSWarner Losh EFI_STATUS 321*f439973dSWarner Losh (EFIAPI *EFI_FVB_ERASE_BLOCKS)( 322*f439973dSWarner Losh IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, 323*f439973dSWarner Losh ... 324*f439973dSWarner Losh ); 325*f439973dSWarner Losh 326*f439973dSWarner Losh /// 327*f439973dSWarner Losh /// The Firmware Volume Block Protocol is the low-level interface 328*f439973dSWarner Losh /// to a firmware volume. File-level access to a firmware volume 329*f439973dSWarner Losh /// should not be done using the Firmware Volume Block Protocol. 330*f439973dSWarner Losh /// Normal access to a firmware volume must use the Firmware 331*f439973dSWarner Losh /// Volume Protocol. Typically, only the file system driver that 332*f439973dSWarner Losh /// produces the Firmware Volume Protocol will bind to the 333*f439973dSWarner Losh /// Firmware Volume Block Protocol. 334*f439973dSWarner Losh /// 335*f439973dSWarner Losh struct _EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL { 336*f439973dSWarner Losh EFI_FVB_GET_ATTRIBUTES GetAttributes; 337*f439973dSWarner Losh EFI_FVB_SET_ATTRIBUTES SetAttributes; 338*f439973dSWarner Losh EFI_FVB_GET_PHYSICAL_ADDRESS GetPhysicalAddress; 339*f439973dSWarner Losh EFI_FVB_GET_BLOCK_SIZE GetBlockSize; 340*f439973dSWarner Losh EFI_FVB_READ Read; 341*f439973dSWarner Losh EFI_FVB_WRITE Write; 342*f439973dSWarner Losh EFI_FVB_ERASE_BLOCKS EraseBlocks; 343*f439973dSWarner Losh /// 344*f439973dSWarner Losh /// The handle of the parent firmware volume. 345*f439973dSWarner Losh /// 346*f439973dSWarner Losh EFI_HANDLE ParentHandle; 347*f439973dSWarner Losh }; 348*f439973dSWarner Losh 349*f439973dSWarner Losh extern EFI_GUID gEfiFirmwareVolumeBlockProtocolGuid; 350*f439973dSWarner Losh extern EFI_GUID gEfiFirmwareVolumeBlock2ProtocolGuid; 351*f439973dSWarner Losh 352*f439973dSWarner Losh #endif 353