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 mFvbEntry
[UpdateIndex
].Handle
= Handle
;
109 // The array does not have enough entries
111 ASSERT (UpdateIndex
< MAX_FVB_COUNT
);
114 // Get the interface pointer and if it's ours, skip it
116 Status
= gBS
->HandleProtocol (Handle
, &gEfiFirmwareVolumeBlockProtocolGuid
, &mFvbEntry
[UpdateIndex
].Fvb
);
117 ASSERT_EFI_ERROR (Status
);
119 Status
= gBS
->HandleProtocol (Handle
, &gEfiFvbExtensionProtocolGuid
, &mFvbEntry
[UpdateIndex
].FvbExtension
);
120 if (Status
!= EFI_SUCCESS
) {
121 mFvbEntry
[UpdateIndex
].FvbExtension
= NULL
;
128 FvbVirtualAddressChangeNotifyEvent (
136 Convert all pointers in mFvbEntry after ExitBootServices.
140 Event - The Event that is being processed
142 Context - Event Context
151 if (mFvbEntry
!= NULL
) {
152 for (Index
= 0; Index
< MAX_FVB_COUNT
; Index
++) {
153 if (NULL
!= mFvbEntry
[Index
].Fvb
) {
154 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->GetBlockSize
);
155 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->GetPhysicalAddress
);
156 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->GetVolumeAttributes
);
157 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->SetVolumeAttributes
);
158 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->Read
);
159 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->Write
);
160 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->EraseBlocks
);
161 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
);
164 if (NULL
!= mFvbEntry
[Index
].FvbExtension
) {
165 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].FvbExtension
->EraseFvbCustomBlock
);
166 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].FvbExtension
);
170 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
);
177 IN EFI_HANDLE ImageHandle
,
178 IN EFI_SYSTEM_TABLE
*SystemTable
183 Initialize globals and register Fvb Protocol notification function.
196 Status
= gBS
->AllocatePool (
197 EfiRuntimeServicesData
,
198 (UINTN
) sizeof (FVB_ENTRY
) * MAX_FVB_COUNT
,
202 if (EFI_ERROR (Status
)) {
206 ZeroMem (mFvbEntry
, sizeof (FVB_ENTRY
) * MAX_FVB_COUNT
);
208 EfiCreateProtocolNotifyEvent (
209 &gEfiFirmwareVolumeBlockProtocolGuid
,
211 FvbNotificationEvent
,
217 // Register SetVirtualAddressMap () notify function
219 // Status = gBS->CreateEvent (
220 // EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
222 // EfiRuntimeLibFvbVirtualNotifyEvent,
224 // &mEfiFvbVirtualNotifyEvent
226 // ASSERT_EFI_ERROR (Status);
230 // Register SetVirtualAddressMap () notify function
233 ASSERT_EFI_ERROR (Status
);
235 mEfiFvbInitialized
= TRUE
;
240 // The following functions wrap Fvb protocol in the Runtime Lib functions.
241 // The Instance translates into Fvb instance. The Fvb order defined by HOBs and
242 // thus the sequence of FVB protocol addition define Instance.
244 // EfiFvbInitialize () must be called before any of the following functions
253 IN OUT UINTN
*NumBytes
,
259 Reads specified number of bytes into a buffer from the specified block
262 Instance - The FV instance to be read from
263 Lba - The logical block address to be read from
264 Offset - Offset into the block at which to begin reading
265 NumBytes - Pointer that on input contains the total size of
266 the buffer. On output, it contains the total number
268 Buffer - Pointer to a caller allocated buffer that will be
269 used to hold the data read
275 EFI_INVALID_PARAMETER - invalid parameter
279 if (Instance
>= mFvbCount
) {
280 return EFI_INVALID_PARAMETER
;
283 return mFvbEntry
[Instance
].Fvb
->Read (mFvbEntry
[Instance
].Fvb
, Lba
, Offset
, NumBytes
, Buffer
);
291 IN OUT UINTN
*NumBytes
,
297 Writes specified number of bytes from the input buffer to the block
300 Instance - The FV instance to be written to
301 Lba - The starting logical block index to write to
302 Offset - Offset into the block at which to begin writing
303 NumBytes - Pointer that on input contains the total size of
304 the buffer. On output, it contains the total number
305 of bytes actually written
306 Buffer - Pointer to a caller allocated buffer that contains
307 the source for the write
313 EFI_INVALID_PARAMETER - invalid parameter
317 if (Instance
>= mFvbCount
) {
318 return EFI_INVALID_PARAMETER
;
321 return mFvbEntry
[Instance
].Fvb
->Write (mFvbEntry
[Instance
].Fvb
, Lba
, Offset
, NumBytes
, Buffer
);
332 Erases and initializes a firmware volume block
335 Instance - The FV instance to be erased
336 Lba - The logical block index to be erased
342 EFI_INVALID_PARAMETER - invalid parameter
346 if (Instance
>= mFvbCount
) {
347 return EFI_INVALID_PARAMETER
;
350 return mFvbEntry
[Instance
].Fvb
->EraseBlocks (mFvbEntry
[Instance
].Fvb
, Lba
, -1);
354 EfiFvbGetVolumeAttributes (
356 OUT EFI_FVB_ATTRIBUTES
*Attributes
361 Retrieves attributes, insures positive polarity of attribute bits, returns
362 resulting attributes in output parameter
365 Instance - The FV instance whose attributes is going to be
367 Attributes - Output buffer which contains attributes
372 EFI_INVALID_PARAMETER - invalid parameter
376 if (Instance
>= mFvbCount
) {
377 return EFI_INVALID_PARAMETER
;
380 return mFvbEntry
[Instance
].Fvb
->GetVolumeAttributes (mFvbEntry
[Instance
].Fvb
, Attributes
);
384 EfiFvbSetVolumeAttributes (
386 IN EFI_FVB_ATTRIBUTES Attributes
391 Modifies the current settings of the firmware volume according to the
392 input parameter, and returns the new setting of the volume
395 Instance - The FV instance whose attributes is going to be
397 Attributes - On input, it is a pointer to EFI_FVB_ATTRIBUTES
398 containing the desired firmware volume settings.
399 On successful return, it contains the new settings
400 of the firmware volume
405 EFI_INVALID_PARAMETER - invalid parameter
409 if (Instance
>= mFvbCount
) {
410 return EFI_INVALID_PARAMETER
;
413 return mFvbEntry
[Instance
].Fvb
->SetVolumeAttributes (mFvbEntry
[Instance
].Fvb
, &Attributes
);
417 EfiFvbGetPhysicalAddress (
419 OUT EFI_PHYSICAL_ADDRESS
*BaseAddress
424 Retrieves the physical address of a memory mapped FV
427 Instance - The FV instance whose base address is going to be
429 BaseAddress - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS
430 that on successful return, contains the base address
431 of the firmware volume.
437 EFI_INVALID_PARAMETER - invalid parameter
441 if (Instance
>= mFvbCount
) {
442 return EFI_INVALID_PARAMETER
;
445 return mFvbEntry
[Instance
].Fvb
->GetPhysicalAddress (mFvbEntry
[Instance
].Fvb
, BaseAddress
);
452 OUT UINTN
*BlockSize
,
453 OUT UINTN
*NumOfBlocks
458 Retrieve the size of a logical block
461 Instance - The FV instance whose block size is going to be
463 Lba - Indicates which block to return the size for.
464 BlockSize - A pointer to a caller allocated UINTN in which
465 the size of the block is returned
466 NumOfBlocks - a pointer to a caller allocated UINTN in which the
467 number of consecutive blocks starting with Lba is
468 returned. All blocks in this range have a size of
472 EFI_SUCCESS - The firmware volume was read successfully and
473 contents are in Buffer
475 EFI_INVALID_PARAMETER - invalid parameter
479 if (Instance
>= mFvbCount
) {
480 return EFI_INVALID_PARAMETER
;
483 return mFvbEntry
[Instance
].Fvb
->GetBlockSize (mFvbEntry
[Instance
].Fvb
, Lba
, BlockSize
, NumOfBlocks
);
487 EfiFvbEraseCustomBlockRange (
490 IN UINTN OffsetStartLba
,
492 IN UINTN OffsetLastLba
497 Erases and initializes a specified range of a firmware volume
500 Instance - The FV instance to be erased
501 StartLba - The starting logical block index to be erased
502 OffsetStartLba - Offset into the starting block at which to
504 LastLba - The last logical block index to be erased
505 OffsetLastLba - Offset into the last block at which to end erasing
511 EFI_INVALID_PARAMETER - invalid parameter
513 EFI_UNSUPPORTED - not support
517 if (Instance
>= mFvbCount
) {
518 return EFI_INVALID_PARAMETER
;
521 if (!(mFvbEntry
[Instance
].FvbExtension
)) {
522 return EFI_UNSUPPORTED
;
525 if (!(mFvbEntry
[Instance
].FvbExtension
->EraseFvbCustomBlock
)) {
526 return EFI_UNSUPPORTED
;
529 return mFvbEntry
[Instance
].FvbExtension
->EraseFvbCustomBlock (
530 mFvbEntry
[Instance
].FvbExtension
,