3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Firmware Volume Block Protocol Runtime Abstraction
20 mFvbEntry is an array of Handle Fvb pairs. The Fvb Lib Instance matches the
21 index in the mFvbEntry array. This should be the same sequence as the FVB's
22 were described in the HOB. We have to remember the handle so we can tell if
23 the protocol has been reinstalled and it needs updateing.
25 If you are using any of these lib functions.you must first call FvbInitialize ().
28 FVB - Firmware Volume Block
35 // Lib will ASSERT if more FVB devices than this are added to the system.
37 STATIC FVB_ENTRY
*mFvbEntry
;
38 // STATIC EFI_EVENT mFvbVirtualNotifyEvent;
39 STATIC EFI_EVENT mFvbRegistration
;
40 // STATIC EFI_EVENT mEfiFvbVirtualNotifyEvent;
41 STATIC BOOLEAN mEfiFvbInitialized
= FALSE
;
42 STATIC UINTN mFvbCount
;
47 FvbNotificationEvent (
54 Update mFvbEntry. Add new entry, or update existing entry if Fvb protocol is
59 Event - The Event that is being processed
61 Context - Event Context
75 BufferSize
= sizeof (Handle
);
76 Status
= gBS
->LocateHandle (
78 &gEfiFirmwareVolumeBlockProtocolGuid
,
83 if (EFI_ERROR (Status
)) {
85 // Exit Path of While Loop....
90 UpdateIndex
= MAX_FVB_COUNT
;
91 for (Index
= 0; Index
< mFvbCount
; Index
++) {
92 if (mFvbEntry
[Index
].Handle
== Handle
) {
94 // If the handle is already in the table just update the protocol
101 if (UpdateIndex
== MAX_FVB_COUNT
) {
103 // Use the next free slot for a new entry
105 UpdateIndex
= mFvbCount
++;
106 ASSERT (UpdateIndex
< MAX_FVB_COUNT
);
107 mFvbEntry
[UpdateIndex
].Handle
= Handle
;
110 // The array does not have enough entries
112 ASSERT (UpdateIndex
< MAX_FVB_COUNT
);
115 // Get the interface pointer and if it's ours, skip it
117 Status
= gBS
->HandleProtocol (Handle
, &gEfiFirmwareVolumeBlockProtocolGuid
, (VOID
**)&mFvbEntry
[UpdateIndex
].Fvb
);
118 ASSERT_EFI_ERROR (Status
);
120 Status
= gBS
->HandleProtocol (Handle
, &gEfiFvbExtensionProtocolGuid
, (VOID
**)&mFvbEntry
[UpdateIndex
].FvbExtension
);
121 if (Status
!= EFI_SUCCESS
) {
122 mFvbEntry
[UpdateIndex
].FvbExtension
= NULL
;
129 FvbVirtualAddressChangeNotifyEvent (
137 Convert all pointers in mFvbEntry after ExitBootServices.
141 Event - The Event that is being processed
143 Context - Event Context
152 if (mFvbEntry
!= NULL
) {
153 for (Index
= 0; Index
< MAX_FVB_COUNT
; Index
++) {
154 if (NULL
!= mFvbEntry
[Index
].Fvb
) {
155 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->GetBlockSize
);
156 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->GetPhysicalAddress
);
157 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->GetVolumeAttributes
);
158 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->SetVolumeAttributes
);
159 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->Read
);
160 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->Write
);
161 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->EraseBlocks
);
162 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
);
165 if (NULL
!= mFvbEntry
[Index
].FvbExtension
) {
166 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].FvbExtension
->EraseFvbCustomBlock
);
167 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].FvbExtension
);
171 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
);
178 IN EFI_HANDLE ImageHandle
,
179 IN EFI_SYSTEM_TABLE
*SystemTable
184 Initialize globals and register Fvb Protocol notification function.
197 Status
= gBS
->AllocatePool (
198 EfiRuntimeServicesData
,
199 (UINTN
) sizeof (FVB_ENTRY
) * MAX_FVB_COUNT
,
203 if (EFI_ERROR (Status
)) {
207 ZeroMem (mFvbEntry
, sizeof (FVB_ENTRY
) * MAX_FVB_COUNT
);
209 EfiCreateProtocolNotifyEvent (
210 &gEfiFirmwareVolumeBlockProtocolGuid
,
212 FvbNotificationEvent
,
218 // Register SetVirtualAddressMap () notify function
220 // Status = gBS->CreateEvent (
221 // EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
223 // EfiRuntimeLibFvbVirtualNotifyEvent,
225 // &mEfiFvbVirtualNotifyEvent
227 // ASSERT_EFI_ERROR (Status);
231 // Register SetVirtualAddressMap () notify function
234 ASSERT_EFI_ERROR (Status
);
236 mEfiFvbInitialized
= TRUE
;
241 // The following functions wrap Fvb protocol in the Runtime Lib functions.
242 // The Instance translates into Fvb instance. The Fvb order defined by HOBs and
243 // thus the sequence of FVB protocol addition define Instance.
245 // EfiFvbInitialize () must be called before any of the following functions
254 IN OUT UINTN
*NumBytes
,
260 Reads specified number of bytes into a buffer from the specified block
263 Instance - The FV instance to be read from
264 Lba - The logical block address to be read from
265 Offset - Offset into the block at which to begin reading
266 NumBytes - Pointer that on input contains the total size of
267 the buffer. On output, it contains the total number
269 Buffer - Pointer to a caller allocated buffer that will be
270 used to hold the data read
276 EFI_INVALID_PARAMETER - invalid parameter
280 if (Instance
>= mFvbCount
) {
281 return EFI_INVALID_PARAMETER
;
284 return mFvbEntry
[Instance
].Fvb
->Read (mFvbEntry
[Instance
].Fvb
, Lba
, Offset
, NumBytes
, Buffer
);
292 IN OUT UINTN
*NumBytes
,
298 Writes specified number of bytes from the input buffer to the block
301 Instance - The FV instance to be written to
302 Lba - The starting logical block index to write to
303 Offset - Offset into the block at which to begin writing
304 NumBytes - Pointer that on input contains the total size of
305 the buffer. On output, it contains the total number
306 of bytes actually written
307 Buffer - Pointer to a caller allocated buffer that contains
308 the source for the write
314 EFI_INVALID_PARAMETER - invalid parameter
318 if (Instance
>= mFvbCount
) {
319 return EFI_INVALID_PARAMETER
;
322 return mFvbEntry
[Instance
].Fvb
->Write (mFvbEntry
[Instance
].Fvb
, Lba
, Offset
, NumBytes
, Buffer
);
333 Erases and initializes a firmware volume block
336 Instance - The FV instance to be erased
337 Lba - The logical block index to be erased
343 EFI_INVALID_PARAMETER - invalid parameter
347 if (Instance
>= mFvbCount
) {
348 return EFI_INVALID_PARAMETER
;
351 return mFvbEntry
[Instance
].Fvb
->EraseBlocks (mFvbEntry
[Instance
].Fvb
, Lba
, -1);
355 EfiFvbGetVolumeAttributes (
357 OUT EFI_FVB_ATTRIBUTES
*Attributes
362 Retrieves attributes, insures positive polarity of attribute bits, returns
363 resulting attributes in output parameter
366 Instance - The FV instance whose attributes is going to be
368 Attributes - Output buffer which contains attributes
373 EFI_INVALID_PARAMETER - invalid parameter
377 if (Instance
>= mFvbCount
) {
378 return EFI_INVALID_PARAMETER
;
381 return mFvbEntry
[Instance
].Fvb
->GetVolumeAttributes (mFvbEntry
[Instance
].Fvb
, Attributes
);
385 EfiFvbSetVolumeAttributes (
387 IN EFI_FVB_ATTRIBUTES Attributes
392 Modifies the current settings of the firmware volume according to the
393 input parameter, and returns the new setting of the volume
396 Instance - The FV instance whose attributes is going to be
398 Attributes - On input, it is a pointer to EFI_FVB_ATTRIBUTES
399 containing the desired firmware volume settings.
400 On successful return, it contains the new settings
401 of the firmware volume
406 EFI_INVALID_PARAMETER - invalid parameter
410 if (Instance
>= mFvbCount
) {
411 return EFI_INVALID_PARAMETER
;
414 return mFvbEntry
[Instance
].Fvb
->SetVolumeAttributes (mFvbEntry
[Instance
].Fvb
, &Attributes
);
418 EfiFvbGetPhysicalAddress (
420 OUT EFI_PHYSICAL_ADDRESS
*BaseAddress
425 Retrieves the physical address of a memory mapped FV
428 Instance - The FV instance whose base address is going to be
430 BaseAddress - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS
431 that on successful return, contains the base address
432 of the firmware volume.
438 EFI_INVALID_PARAMETER - invalid parameter
442 if (Instance
>= mFvbCount
) {
443 return EFI_INVALID_PARAMETER
;
446 return mFvbEntry
[Instance
].Fvb
->GetPhysicalAddress (mFvbEntry
[Instance
].Fvb
, BaseAddress
);
453 OUT UINTN
*BlockSize
,
454 OUT UINTN
*NumOfBlocks
459 Retrieve the size of a logical block
462 Instance - The FV instance whose block size is going to be
464 Lba - Indicates which block to return the size for.
465 BlockSize - A pointer to a caller allocated UINTN in which
466 the size of the block is returned
467 NumOfBlocks - a pointer to a caller allocated UINTN in which the
468 number of consecutive blocks starting with Lba is
469 returned. All blocks in this range have a size of
473 EFI_SUCCESS - The firmware volume was read successfully and
474 contents are in Buffer
476 EFI_INVALID_PARAMETER - invalid parameter
480 if (Instance
>= mFvbCount
) {
481 return EFI_INVALID_PARAMETER
;
484 return mFvbEntry
[Instance
].Fvb
->GetBlockSize (mFvbEntry
[Instance
].Fvb
, Lba
, BlockSize
, NumOfBlocks
);
488 EfiFvbEraseCustomBlockRange (
491 IN UINTN OffsetStartLba
,
493 IN UINTN OffsetLastLba
498 Erases and initializes a specified range of a firmware volume
501 Instance - The FV instance to be erased
502 StartLba - The starting logical block index to be erased
503 OffsetStartLba - Offset into the starting block at which to
505 LastLba - The last logical block index to be erased
506 OffsetLastLba - Offset into the last block at which to end erasing
512 EFI_INVALID_PARAMETER - invalid parameter
514 EFI_UNSUPPORTED - not support
518 if (Instance
>= mFvbCount
) {
519 return EFI_INVALID_PARAMETER
;
522 if (!(mFvbEntry
[Instance
].FvbExtension
)) {
523 return EFI_UNSUPPORTED
;
526 if (!(mFvbEntry
[Instance
].FvbExtension
->EraseFvbCustomBlock
)) {
527 return EFI_UNSUPPORTED
;
530 return mFvbEntry
[Instance
].FvbExtension
->EraseFvbCustomBlock (
531 mFvbEntry
[Instance
].FvbExtension
,