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