3 Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>
4 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
33 #include "EfiRuntimeLib.h"
34 #include EFI_PROTOCOL_DEFINITION (FirmwareVolumeBlock)
35 #include EFI_PROTOCOL_DEFINITION (FvbExtension)
38 // Lib will ASSERT if more FVB devices than this are added to the system.
41 VOID
*mFvbRegistration
;
42 VOID
*mFvbExtRegistration
;
43 //static EFI_EVENT mEfiFvbVirtualNotifyEvent;
44 BOOLEAN gEfiFvbInitialized
= FALSE
;
54 Check whether an address is runtime memory or not.
58 Address - The Address being checked.
61 TRUE - The address is runtime memory.
62 FALSE - The address is not runtime memory.
67 UINT8 TmpMemoryMap
[1];
70 UINT32 DescriptorVersion
;
72 EFI_MEMORY_DESCRIPTOR
*MemoryMap
;
73 EFI_MEMORY_DESCRIPTOR
*MemoryMapPtr
;
80 // Get System MemoryMapSize
83 Status
= gBS
->GetMemoryMap (
85 (EFI_MEMORY_DESCRIPTOR
*)TmpMemoryMap
,
90 ASSERT (Status
== EFI_BUFFER_TOO_SMALL
);
92 // Enlarge space here, because we will allocate pool now.
94 MemoryMapSize
+= EFI_PAGE_SIZE
;
95 Status
= gBS
->AllocatePool (
100 ASSERT_EFI_ERROR (Status
);
103 // Get System MemoryMap
105 Status
= gBS
->GetMemoryMap (
112 ASSERT_EFI_ERROR (Status
);
114 MemoryMapPtr
= MemoryMap
;
116 // Search the request Address
118 for (Index
= 0; Index
< (MemoryMapSize
/ DescriptorSize
); Index
++) {
119 if (((EFI_PHYSICAL_ADDRESS
)(UINTN
)Address
>= MemoryMap
->PhysicalStart
) &&
120 ((EFI_PHYSICAL_ADDRESS
)(UINTN
)Address
< MemoryMap
->PhysicalStart
121 + LShiftU64 (MemoryMap
->NumberOfPages
, EFI_PAGE_SHIFT
))) {
125 if (MemoryMap
->Attribute
& EFI_MEMORY_RUNTIME
) {
133 MemoryMap
= (EFI_MEMORY_DESCRIPTOR
*)((UINTN
)MemoryMap
+ DescriptorSize
);
139 gBS
->FreePool (MemoryMapPtr
);
146 FvbNotificationFunction (
153 Update mFvbEntry. Add new entry, or update existing entry if Fvb protocol is
158 Event - The Event that is being processed
160 Context - Event Context
172 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*Fvb
;
173 EFI_FVB_EXTENSION_PROTOCOL
*FvbExtension
;
176 BufferSize
= sizeof (Handle
);
177 Status
= gBS
->LocateHandle (
179 &gEfiFirmwareVolumeBlockProtocolGuid
,
184 if (EFI_ERROR (Status
)) {
186 // Exit Path of While Loop....
191 UpdateIndex
= MAX_FVB_COUNT
;
192 for (Index
= 0; Index
< mFvbCount
; Index
++) {
193 if (mFvbEntry
[Index
].Handle
== Handle
) {
195 // If the handle is already in the table just update the protocol
202 if (UpdateIndex
== MAX_FVB_COUNT
) {
204 // Use the next free slot for a new entry
206 UpdateIndex
= mFvbCount
;
209 // The array does not have enough entries
211 ASSERT (UpdateIndex
< MAX_FVB_COUNT
);
214 // Get the interface pointer and if it's ours, skip it.
215 // We check Runtime here, because it has no reason to register
216 // a boot time FVB protocol.
218 Status
= gBS
->HandleProtocol (Handle
, &gEfiFirmwareVolumeBlockProtocolGuid
, (VOID
**) &Fvb
);
219 ASSERT_EFI_ERROR (Status
);
220 if (IsMemoryRuntime (Fvb
)) {
222 // Increase mFvbCount if we need to add a new entry
224 if (UpdateIndex
== mFvbCount
) {
227 mFvbEntry
[UpdateIndex
].Handle
= Handle
;
228 mFvbEntry
[UpdateIndex
].Fvb
= Fvb
;
229 mFvbEntry
[UpdateIndex
].FvbExtension
= NULL
;
231 Status
= gBS
->HandleProtocol (Handle
, &gEfiFvbExtensionProtocolGuid
, (VOID
**) &FvbExtension
);
232 if ((Status
== EFI_SUCCESS
) && IsMemoryRuntime (FvbExtension
)) {
233 mFvbEntry
[UpdateIndex
].FvbExtension
= FvbExtension
;
246 Initialize globals and register Fvb Protocol notification function.
252 EFI_SUCCESS - Fvb is successfully initialized
253 others - Fail to initialize
260 Status
= gBS
->AllocatePool (
261 EfiRuntimeServicesData
,
262 (UINTN
) sizeof (FVB_ENTRY
) * MAX_FVB_COUNT
,
266 if (EFI_ERROR (Status
)) {
270 EfiZeroMem (mFvbEntry
, sizeof (FVB_ENTRY
) * MAX_FVB_COUNT
);
272 mFvbEvent
= RtEfiLibCreateProtocolNotifyEvent (
273 &gEfiFirmwareVolumeBlockProtocolGuid
,
275 FvbNotificationFunction
,
281 // Register SetVirtualAddressMap () notify function
283 // Status = gBS->CreateEvent (
284 // EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
286 // EfiRuntimeLibFvbVirtualNotifyEvent,
288 // &mEfiFvbVirtualNotifyEvent
290 // ASSERT_EFI_ERROR (Status);
292 gEfiFvbInitialized
= TRUE
;
304 Release resources allocated in EfiFvbInitialize.
314 gBS
->FreePool ((VOID
*) mFvbEntry
);
315 gBS
->CloseEvent (mFvbEvent
);
316 gEfiFvbInitialized
= FALSE
;
321 // The following functions wrap Fvb protocol in the Runtime Lib functions.
322 // The Instance translates into Fvb instance. The Fvb order defined by HOBs and
323 // thus the sequence of FVB protocol addition define Instance.
325 // EfiFvbInitialize () must be called before any of the following functions
334 IN OUT UINTN
*NumBytes
,
340 Reads specified number of bytes into a buffer from the specified block
343 Instance - The FV instance to be read from
344 Lba - The logical block address to be read from
345 Offset - Offset into the block at which to begin reading
346 NumBytes - Pointer that on input contains the total size of
347 the buffer. On output, it contains the total number
349 Buffer - Pointer to a caller allocated buffer that will be
350 used to hold the data read
356 EFI_INVALID_PARAMETER - invalid parameter
360 if (Instance
>= mFvbCount
) {
361 return EFI_INVALID_PARAMETER
;
364 return mFvbEntry
[Instance
].Fvb
->Read (mFvbEntry
[Instance
].Fvb
, Lba
, Offset
, NumBytes
, Buffer
);
372 IN OUT UINTN
*NumBytes
,
378 Writes specified number of bytes from the input buffer to the block
381 Instance - The FV instance to be written to
382 Lba - The starting logical block index to write to
383 Offset - Offset into the block at which to begin writing
384 NumBytes - Pointer that on input contains the total size of
385 the buffer. On output, it contains the total number
386 of bytes actually written
387 Buffer - Pointer to a caller allocated buffer that contains
388 the source for the write
394 EFI_INVALID_PARAMETER - invalid parameter
398 if (Instance
>= mFvbCount
) {
399 return EFI_INVALID_PARAMETER
;
402 return mFvbEntry
[Instance
].Fvb
->Write (mFvbEntry
[Instance
].Fvb
, Lba
, Offset
, NumBytes
, Buffer
);
413 Erases and initializes a firmware volume block
416 Instance - The FV instance to be erased
417 Lba - The logical block index to be erased
423 EFI_INVALID_PARAMETER - invalid parameter
427 if (Instance
>= mFvbCount
) {
428 return EFI_INVALID_PARAMETER
;
431 return mFvbEntry
[Instance
].Fvb
->EraseBlocks (mFvbEntry
[Instance
].Fvb
, Lba
, -1);
435 EfiFvbGetVolumeAttributes (
437 OUT EFI_FVB_ATTRIBUTES
*Attributes
442 Retrieves attributes, insures positive polarity of attribute bits, returns
443 resulting attributes in output parameter
446 Instance - The FV instance whose attributes is going to be
448 Attributes - Output buffer which contains attributes
453 EFI_INVALID_PARAMETER - invalid parameter
457 if (Instance
>= mFvbCount
) {
458 return EFI_INVALID_PARAMETER
;
461 return mFvbEntry
[Instance
].Fvb
->GetVolumeAttributes (mFvbEntry
[Instance
].Fvb
, Attributes
);
465 EfiFvbSetVolumeAttributes (
467 IN EFI_FVB_ATTRIBUTES Attributes
472 Modifies the current settings of the firmware volume according to the
476 Instance - The FV instance whose attributes is going to be
478 Attributes - It is a pointer to EFI_FVB_ATTRIBUTES
479 containing the desired firmware volume settings.
484 EFI_INVALID_PARAMETER - invalid parameter
488 if (Instance
>= mFvbCount
) {
489 return EFI_INVALID_PARAMETER
;
492 return mFvbEntry
[Instance
].Fvb
->SetVolumeAttributes (mFvbEntry
[Instance
].Fvb
, &Attributes
);
496 EfiFvbGetPhysicalAddress (
498 OUT EFI_PHYSICAL_ADDRESS
*BaseAddress
503 Retrieves the physical address of a memory mapped FV
506 Instance - The FV instance whose base address is going to be
508 BaseAddress - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS
509 that on successful return, contains the base address
510 of the firmware volume.
516 EFI_INVALID_PARAMETER - invalid parameter
520 if (Instance
>= mFvbCount
) {
521 return EFI_INVALID_PARAMETER
;
524 return mFvbEntry
[Instance
].Fvb
->GetPhysicalAddress (mFvbEntry
[Instance
].Fvb
, BaseAddress
);
531 OUT UINTN
*BlockSize
,
532 OUT UINTN
*NumOfBlocks
537 Retrieve the size of a logical block
540 Instance - The FV instance whose block size is going to be
542 Lba - Indicates which block to return the size for.
543 BlockSize - A pointer to a caller allocated UINTN in which
544 the size of the block is returned
545 NumOfBlocks - a pointer to a caller allocated UINTN in which the
546 number of consecutive blocks starting with Lba is
547 returned. All blocks in this range have a size of
551 EFI_SUCCESS - The firmware volume was read successfully and
552 contents are in Buffer
554 EFI_INVALID_PARAMETER - invalid parameter
558 if (Instance
>= mFvbCount
) {
559 return EFI_INVALID_PARAMETER
;
562 return mFvbEntry
[Instance
].Fvb
->GetBlockSize (mFvbEntry
[Instance
].Fvb
, Lba
, BlockSize
, NumOfBlocks
);
566 EfiFvbEraseCustomBlockRange (
569 IN UINTN OffsetStartLba
,
571 IN UINTN OffsetLastLba
576 Erases and initializes a specified range of a firmware volume
579 Instance - The FV instance to be erased
580 StartLba - The starting logical block index to be erased
581 OffsetStartLba - Offset into the starting block at which to
583 LastLba - The last logical block index to be erased
584 OffsetLastLba - Offset into the last block at which to end erasing
590 EFI_INVALID_PARAMETER - invalid parameter
592 EFI_UNSUPPORTED - not support
596 if (Instance
>= mFvbCount
) {
597 return EFI_INVALID_PARAMETER
;
600 if (!(mFvbEntry
[Instance
].FvbExtension
)) {
601 return EFI_UNSUPPORTED
;
604 if (!(mFvbEntry
[Instance
].FvbExtension
->EraseFvbCustomBlock
)) {
605 return EFI_UNSUPPORTED
;
608 return mFvbEntry
[Instance
].FvbExtension
->EraseFvbCustomBlock (
609 mFvbEntry
[Instance
].FvbExtension
,