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
++;
105 // Check the UpdateIndex whether exceed the maximum value.
107 ASSERT (UpdateIndex
< MAX_FVB_COUNT
);
108 mFvbEntry
[UpdateIndex
].Handle
= Handle
;
111 // The array does not have enough entries
113 ASSERT (UpdateIndex
< MAX_FVB_COUNT
);
116 // Get the interface pointer and if it's ours, skip it
118 Status
= gBS
->HandleProtocol (Handle
, &gEfiFirmwareVolumeBlockProtocolGuid
, (VOID
**) &mFvbEntry
[UpdateIndex
].Fvb
);
119 ASSERT_EFI_ERROR (Status
);
121 Status
= gBS
->HandleProtocol (Handle
, &gEfiFvbExtensionProtocolGuid
, (VOID
**) &mFvbEntry
[UpdateIndex
].FvbExtension
);
122 if (Status
!= EFI_SUCCESS
) {
123 mFvbEntry
[UpdateIndex
].FvbExtension
= NULL
;
130 FvbVirtualAddressChangeNotifyEvent (
138 Convert all pointers in mFvbEntry after ExitBootServices.
142 Event - The Event that is being processed
144 Context - Event Context
153 if (mFvbEntry
!= NULL
) {
154 for (Index
= 0; Index
< MAX_FVB_COUNT
; Index
++) {
155 if (NULL
!= mFvbEntry
[Index
].Fvb
) {
156 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->GetBlockSize
);
157 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->GetPhysicalAddress
);
158 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->GetVolumeAttributes
);
159 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->SetVolumeAttributes
);
160 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->Read
);
161 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->Write
);
162 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->EraseBlocks
);
163 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
);
166 if (NULL
!= mFvbEntry
[Index
].FvbExtension
) {
167 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].FvbExtension
->EraseFvbCustomBlock
);
168 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].FvbExtension
);
172 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
);
179 IN EFI_HANDLE ImageHandle
,
180 IN EFI_SYSTEM_TABLE
*SystemTable
185 Initialize globals and register Fvb Protocol notification function.
198 Status
= gBS
->AllocatePool (
199 EfiRuntimeServicesData
,
200 (UINTN
) sizeof (FVB_ENTRY
) * MAX_FVB_COUNT
,
204 if (EFI_ERROR (Status
)) {
208 ZeroMem (mFvbEntry
, sizeof (FVB_ENTRY
) * MAX_FVB_COUNT
);
210 EfiCreateProtocolNotifyEvent (
211 &gEfiFirmwareVolumeBlockProtocolGuid
,
213 FvbNotificationEvent
,
219 // Register SetVirtualAddressMap () notify function
221 // Status = gBS->CreateEvent (
222 // EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
224 // EfiRuntimeLibFvbVirtualNotifyEvent,
226 // &mEfiFvbVirtualNotifyEvent
228 // ASSERT_EFI_ERROR (Status);
232 // Register SetVirtualAddressMap () notify function
235 ASSERT_EFI_ERROR (Status
);
237 mEfiFvbInitialized
= TRUE
;
242 // The following functions wrap Fvb protocol in the Runtime Lib functions.
243 // The Instance translates into Fvb instance. The Fvb order defined by HOBs and
244 // thus the sequence of FVB protocol addition define Instance.
246 // EfiFvbInitialize () must be called before any of the following functions
255 IN OUT UINTN
*NumBytes
,
261 Reads specified number of bytes into a buffer from the specified block
264 Instance - The FV instance to be read from
265 Lba - The logical block address to be read from
266 Offset - Offset into the block at which to begin reading
267 NumBytes - Pointer that on input contains the total size of
268 the buffer. On output, it contains the total number
270 Buffer - Pointer to a caller allocated buffer that will be
271 used to hold the data read
277 EFI_INVALID_PARAMETER - invalid parameter
281 if (Instance
>= mFvbCount
) {
282 return EFI_INVALID_PARAMETER
;
285 return mFvbEntry
[Instance
].Fvb
->Read (mFvbEntry
[Instance
].Fvb
, Lba
, Offset
, NumBytes
, Buffer
);
293 IN OUT UINTN
*NumBytes
,
299 Writes specified number of bytes from the input buffer to the block
302 Instance - The FV instance to be written to
303 Lba - The starting logical block index to write to
304 Offset - Offset into the block at which to begin writing
305 NumBytes - Pointer that on input contains the total size of
306 the buffer. On output, it contains the total number
307 of bytes actually written
308 Buffer - Pointer to a caller allocated buffer that contains
309 the source for the write
315 EFI_INVALID_PARAMETER - invalid parameter
319 if (Instance
>= mFvbCount
) {
320 return EFI_INVALID_PARAMETER
;
323 return mFvbEntry
[Instance
].Fvb
->Write (mFvbEntry
[Instance
].Fvb
, Lba
, Offset
, NumBytes
, Buffer
);
334 Erases and initializes a firmware volume block
337 Instance - The FV instance to be erased
338 Lba - The logical block index to be erased
344 EFI_INVALID_PARAMETER - invalid parameter
348 if (Instance
>= mFvbCount
) {
349 return EFI_INVALID_PARAMETER
;
352 return mFvbEntry
[Instance
].Fvb
->EraseBlocks (mFvbEntry
[Instance
].Fvb
, Lba
, -1);
356 EfiFvbGetVolumeAttributes (
358 OUT EFI_FVB_ATTRIBUTES
*Attributes
363 Retrieves attributes, insures positive polarity of attribute bits, returns
364 resulting attributes in output parameter
367 Instance - The FV instance whose attributes is going to be
369 Attributes - Output buffer which contains attributes
374 EFI_INVALID_PARAMETER - invalid parameter
378 if (Instance
>= mFvbCount
) {
379 return EFI_INVALID_PARAMETER
;
382 return mFvbEntry
[Instance
].Fvb
->GetVolumeAttributes (mFvbEntry
[Instance
].Fvb
, Attributes
);
386 EfiFvbSetVolumeAttributes (
388 IN EFI_FVB_ATTRIBUTES Attributes
393 Modifies the current settings of the firmware volume according to the
394 input parameter, and returns the new setting of the volume
397 Instance - The FV instance whose attributes is going to be
399 Attributes - On input, it is a pointer to EFI_FVB_ATTRIBUTES
400 containing the desired firmware volume settings.
401 On successful return, it contains the new settings
402 of the firmware volume
407 EFI_INVALID_PARAMETER - invalid parameter
411 if (Instance
>= mFvbCount
) {
412 return EFI_INVALID_PARAMETER
;
415 return mFvbEntry
[Instance
].Fvb
->SetVolumeAttributes (mFvbEntry
[Instance
].Fvb
, &Attributes
);
419 EfiFvbGetPhysicalAddress (
421 OUT EFI_PHYSICAL_ADDRESS
*BaseAddress
426 Retrieves the physical address of a memory mapped FV
429 Instance - The FV instance whose base address is going to be
431 BaseAddress - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS
432 that on successful return, contains the base address
433 of the firmware volume.
439 EFI_INVALID_PARAMETER - invalid parameter
443 if (Instance
>= mFvbCount
) {
444 return EFI_INVALID_PARAMETER
;
447 return mFvbEntry
[Instance
].Fvb
->GetPhysicalAddress (mFvbEntry
[Instance
].Fvb
, BaseAddress
);
454 OUT UINTN
*BlockSize
,
455 OUT UINTN
*NumOfBlocks
460 Retrieve the size of a logical block
463 Instance - The FV instance whose block size is going to be
465 Lba - Indicates which block to return the size for.
466 BlockSize - A pointer to a caller allocated UINTN in which
467 the size of the block is returned
468 NumOfBlocks - a pointer to a caller allocated UINTN in which the
469 number of consecutive blocks starting with Lba is
470 returned. All blocks in this range have a size of
474 EFI_SUCCESS - The firmware volume was read successfully and
475 contents are in Buffer
477 EFI_INVALID_PARAMETER - invalid parameter
481 if (Instance
>= mFvbCount
) {
482 return EFI_INVALID_PARAMETER
;
485 return mFvbEntry
[Instance
].Fvb
->GetBlockSize (mFvbEntry
[Instance
].Fvb
, Lba
, BlockSize
, NumOfBlocks
);
489 EfiFvbEraseCustomBlockRange (
492 IN UINTN OffsetStartLba
,
494 IN UINTN OffsetLastLba
499 Erases and initializes a specified range of a firmware volume
502 Instance - The FV instance to be erased
503 StartLba - The starting logical block index to be erased
504 OffsetStartLba - Offset into the starting block at which to
506 LastLba - The last logical block index to be erased
507 OffsetLastLba - Offset into the last block at which to end erasing
513 EFI_INVALID_PARAMETER - invalid parameter
515 EFI_UNSUPPORTED - not support
519 if (Instance
>= mFvbCount
) {
520 return EFI_INVALID_PARAMETER
;
523 if (!(mFvbEntry
[Instance
].FvbExtension
)) {
524 return EFI_UNSUPPORTED
;
527 if (!(mFvbEntry
[Instance
].FvbExtension
->EraseFvbCustomBlock
)) {
528 return EFI_UNSUPPORTED
;
531 return mFvbEntry
[Instance
].FvbExtension
->EraseFvbCustomBlock (
532 mFvbEntry
[Instance
].FvbExtension
,