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 mFvbRegistration
;
39 STATIC BOOLEAN mEfiFvbInitialized
= FALSE
;
40 STATIC UINTN mFvbCount
;
45 FvbNotificationEvent (
52 Update mFvbEntry. Add new entry, or update existing entry if Fvb protocol is
57 Event - The Event that is being processed
59 Context - Event Context
73 BufferSize
= sizeof (Handle
);
74 Status
= gBS
->LocateHandle (
76 &gEfiFirmwareVolumeBlockProtocolGuid
,
81 if (EFI_ERROR (Status
)) {
83 // Exit Path of While Loop....
88 UpdateIndex
= MAX_FVB_COUNT
;
89 for (Index
= 0; Index
< mFvbCount
; Index
++) {
90 if (mFvbEntry
[Index
].Handle
== Handle
) {
92 // If the handle is already in the table just update the protocol
99 if (UpdateIndex
== MAX_FVB_COUNT
) {
101 // Use the next free slot for a new entry
103 UpdateIndex
= mFvbCount
++;;
104 mFvbEntry
[UpdateIndex
].Handle
= Handle
;
107 // The array does not have enough entries
109 ASSERT (UpdateIndex
< MAX_FVB_COUNT
);
112 // Get the interface pointer and if it's ours, skip it
114 Status
= gBS
->HandleProtocol (Handle
, &gEfiFirmwareVolumeBlockProtocolGuid
, (VOID
**) &mFvbEntry
[UpdateIndex
].Fvb
);
115 ASSERT_EFI_ERROR (Status
);
117 Status
= gBS
->HandleProtocol (Handle
, &gEfiFvbExtensionProtocolGuid
, (VOID
**) &mFvbEntry
[UpdateIndex
].FvbExtension
);
118 if (Status
!= EFI_SUCCESS
) {
119 mFvbEntry
[UpdateIndex
].FvbExtension
= NULL
;
126 FvbVirtualAddressChangeNotifyEvent (
134 Convert all pointers in mFvbEntry after ExitBootServices.
138 Event - The Event that is being processed
140 Context - Event Context
149 if (mFvbEntry
!= NULL
) {
150 for (Index
= 0; Index
< MAX_FVB_COUNT
; Index
++) {
151 if (NULL
!= mFvbEntry
[Index
].Fvb
) {
152 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->GetBlockSize
);
153 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->GetPhysicalAddress
);
154 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->GetVolumeAttributes
);
155 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->SetVolumeAttributes
);
156 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->Read
);
157 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->Write
);
158 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->EraseBlocks
);
159 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
);
162 if (NULL
!= mFvbEntry
[Index
].FvbExtension
) {
163 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].FvbExtension
->EraseFvbCustomBlock
);
164 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].FvbExtension
);
168 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
);
175 IN EFI_HANDLE ImageHandle
,
176 IN EFI_SYSTEM_TABLE
*SystemTable
181 Initialize globals and register Fvb Protocol notification function.
194 Status
= gBS
->AllocatePool (
195 EfiRuntimeServicesData
,
196 (UINTN
) sizeof (FVB_ENTRY
) * MAX_FVB_COUNT
,
200 if (EFI_ERROR (Status
)) {
204 ZeroMem (mFvbEntry
, sizeof (FVB_ENTRY
) * MAX_FVB_COUNT
);
206 EfiCreateProtocolNotifyEvent (
207 &gEfiFirmwareVolumeBlockProtocolGuid
,
209 FvbNotificationEvent
,
215 // Register SetVirtualAddressMap () notify function
217 // Status = gBS->CreateEvent (
218 // EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
220 // EfiRuntimeLibFvbVirtualNotifyEvent,
222 // &mEfiFvbVirtualNotifyEvent
224 // ASSERT_EFI_ERROR (Status);
228 // Register SetVirtualAddressMap () notify function
231 ASSERT_EFI_ERROR (Status
);
233 mEfiFvbInitialized
= TRUE
;
238 // The following functions wrap Fvb protocol in the Runtime Lib functions.
239 // The Instance translates into Fvb instance. The Fvb order defined by HOBs and
240 // thus the sequence of FVB protocol addition define Instance.
242 // EfiFvbInitialize () must be called before any of the following functions
251 IN OUT UINTN
*NumBytes
,
257 Reads specified number of bytes into a buffer from the specified block
260 Instance - The FV instance to be read from
261 Lba - The logical block address to be read from
262 Offset - Offset into the block at which to begin reading
263 NumBytes - Pointer that on input contains the total size of
264 the buffer. On output, it contains the total number
266 Buffer - Pointer to a caller allocated buffer that will be
267 used to hold the data read
273 EFI_INVALID_PARAMETER - invalid parameter
277 if (Instance
>= mFvbCount
) {
278 return EFI_INVALID_PARAMETER
;
281 return mFvbEntry
[Instance
].Fvb
->Read (mFvbEntry
[Instance
].Fvb
, Lba
, Offset
, NumBytes
, Buffer
);
289 IN OUT UINTN
*NumBytes
,
295 Writes specified number of bytes from the input buffer to the block
298 Instance - The FV instance to be written to
299 Lba - The starting logical block index to write to
300 Offset - Offset into the block at which to begin writing
301 NumBytes - Pointer that on input contains the total size of
302 the buffer. On output, it contains the total number
303 of bytes actually written
304 Buffer - Pointer to a caller allocated buffer that contains
305 the source for the write
311 EFI_INVALID_PARAMETER - invalid parameter
315 if (Instance
>= mFvbCount
) {
316 return EFI_INVALID_PARAMETER
;
319 return mFvbEntry
[Instance
].Fvb
->Write (mFvbEntry
[Instance
].Fvb
, Lba
, Offset
, NumBytes
, Buffer
);
330 Erases and initializes a firmware volume block
333 Instance - The FV instance to be erased
334 Lba - The logical block index to be erased
340 EFI_INVALID_PARAMETER - invalid parameter
344 if (Instance
>= mFvbCount
) {
345 return EFI_INVALID_PARAMETER
;
348 return mFvbEntry
[Instance
].Fvb
->EraseBlocks (mFvbEntry
[Instance
].Fvb
, Lba
, -1);
352 EfiFvbGetVolumeAttributes (
354 OUT EFI_FVB_ATTRIBUTES
*Attributes
359 Retrieves attributes, insures positive polarity of attribute bits, returns
360 resulting attributes in output parameter
363 Instance - The FV instance whose attributes is going to be
365 Attributes - Output buffer which contains attributes
370 EFI_INVALID_PARAMETER - invalid parameter
374 if (Instance
>= mFvbCount
) {
375 return EFI_INVALID_PARAMETER
;
378 return mFvbEntry
[Instance
].Fvb
->GetVolumeAttributes (mFvbEntry
[Instance
].Fvb
, Attributes
);
382 EfiFvbSetVolumeAttributes (
384 IN EFI_FVB_ATTRIBUTES Attributes
389 Modifies the current settings of the firmware volume according to the
390 input parameter, and returns the new setting of the volume
393 Instance - The FV instance whose attributes is going to be
395 Attributes - On input, it is a pointer to EFI_FVB_ATTRIBUTES
396 containing the desired firmware volume settings.
397 On successful return, it contains the new settings
398 of the firmware volume
403 EFI_INVALID_PARAMETER - invalid parameter
407 if (Instance
>= mFvbCount
) {
408 return EFI_INVALID_PARAMETER
;
411 return mFvbEntry
[Instance
].Fvb
->SetVolumeAttributes (mFvbEntry
[Instance
].Fvb
, &Attributes
);
415 EfiFvbGetPhysicalAddress (
417 OUT EFI_PHYSICAL_ADDRESS
*BaseAddress
422 Retrieves the physical address of a memory mapped FV
425 Instance - The FV instance whose base address is going to be
427 BaseAddress - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS
428 that on successful return, contains the base address
429 of the firmware volume.
435 EFI_INVALID_PARAMETER - invalid parameter
439 if (Instance
>= mFvbCount
) {
440 return EFI_INVALID_PARAMETER
;
443 return mFvbEntry
[Instance
].Fvb
->GetPhysicalAddress (mFvbEntry
[Instance
].Fvb
, BaseAddress
);
450 OUT UINTN
*BlockSize
,
451 OUT UINTN
*NumOfBlocks
456 Retrieve the size of a logical block
459 Instance - The FV instance whose block size is going to be
461 Lba - Indicates which block to return the size for.
462 BlockSize - A pointer to a caller allocated UINTN in which
463 the size of the block is returned
464 NumOfBlocks - a pointer to a caller allocated UINTN in which the
465 number of consecutive blocks starting with Lba is
466 returned. All blocks in this range have a size of
470 EFI_SUCCESS - The firmware volume was read successfully and
471 contents are in Buffer
473 EFI_INVALID_PARAMETER - invalid parameter
477 if (Instance
>= mFvbCount
) {
478 return EFI_INVALID_PARAMETER
;
481 return mFvbEntry
[Instance
].Fvb
->GetBlockSize (mFvbEntry
[Instance
].Fvb
, Lba
, BlockSize
, NumOfBlocks
);
485 EfiFvbEraseCustomBlockRange (
488 IN UINTN OffsetStartLba
,
490 IN UINTN OffsetLastLba
495 Erases and initializes a specified range of a firmware volume
498 Instance - The FV instance to be erased
499 StartLba - The starting logical block index to be erased
500 OffsetStartLba - Offset into the starting block at which to
502 LastLba - The last logical block index to be erased
503 OffsetLastLba - Offset into the last block at which to end erasing
509 EFI_INVALID_PARAMETER - invalid parameter
511 EFI_UNSUPPORTED - not support
515 if (Instance
>= mFvbCount
) {
516 return EFI_INVALID_PARAMETER
;
519 if (!(mFvbEntry
[Instance
].FvbExtension
)) {
520 return EFI_UNSUPPORTED
;
523 if (!(mFvbEntry
[Instance
].FvbExtension
->EraseFvbCustomBlock
)) {
524 return EFI_UNSUPPORTED
;
527 return mFvbEntry
[Instance
].FvbExtension
->EraseFvbCustomBlock (
528 mFvbEntry
[Instance
].FvbExtension
,