3 Copyright (c) 2005 - 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
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
, &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
, &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
);
316 gBS
->CloseEvent (mFvbEvent
);
318 gEfiFvbInitialized
= FALSE
;
324 // The following functions wrap Fvb protocol in the Runtime Lib functions.
325 // The Instance translates into Fvb instance. The Fvb order defined by HOBs and
326 // thus the sequence of FVB protocol addition define Instance.
328 // EfiFvbInitialize () must be called before any of the following functions
337 IN OUT UINTN
*NumBytes
,
343 Reads specified number of bytes into a buffer from the specified block
346 Instance - The FV instance to be read from
347 Lba - The logical block address to be read from
348 Offset - Offset into the block at which to begin reading
349 NumBytes - Pointer that on input contains the total size of
350 the buffer. On output, it contains the total number
352 Buffer - Pointer to a caller allocated buffer that will be
353 used to hold the data read
359 EFI_INVALID_PARAMETER - invalid parameter
363 if (Instance
>= mFvbCount
) {
364 return EFI_INVALID_PARAMETER
;
367 return mFvbEntry
[Instance
].Fvb
->Read (mFvbEntry
[Instance
].Fvb
, Lba
, Offset
, NumBytes
, Buffer
);
375 IN OUT UINTN
*NumBytes
,
381 Writes specified number of bytes from the input buffer to the block
384 Instance - The FV instance to be written to
385 Lba - The starting logical block index to write to
386 Offset - Offset into the block at which to begin writing
387 NumBytes - Pointer that on input contains the total size of
388 the buffer. On output, it contains the total number
389 of bytes actually written
390 Buffer - Pointer to a caller allocated buffer that contains
391 the source for the write
397 EFI_INVALID_PARAMETER - invalid parameter
401 if (Instance
>= mFvbCount
) {
402 return EFI_INVALID_PARAMETER
;
405 return mFvbEntry
[Instance
].Fvb
->Write (mFvbEntry
[Instance
].Fvb
, Lba
, Offset
, NumBytes
, Buffer
);
416 Erases and initializes a firmware volume block
419 Instance - The FV instance to be erased
420 Lba - The logical block index to be erased
426 EFI_INVALID_PARAMETER - invalid parameter
430 if (Instance
>= mFvbCount
) {
431 return EFI_INVALID_PARAMETER
;
434 return mFvbEntry
[Instance
].Fvb
->EraseBlocks (mFvbEntry
[Instance
].Fvb
, Lba
, -1);
438 EfiFvbGetVolumeAttributes (
440 OUT EFI_FVB_ATTRIBUTES
*Attributes
445 Retrieves attributes, insures positive polarity of attribute bits, returns
446 resulting attributes in output parameter
449 Instance - The FV instance whose attributes is going to be
451 Attributes - Output buffer which contains attributes
456 EFI_INVALID_PARAMETER - invalid parameter
460 if (Instance
>= mFvbCount
) {
461 return EFI_INVALID_PARAMETER
;
464 return mFvbEntry
[Instance
].Fvb
->GetVolumeAttributes (mFvbEntry
[Instance
].Fvb
, Attributes
);
468 EfiFvbSetVolumeAttributes (
470 IN EFI_FVB_ATTRIBUTES Attributes
475 Modifies the current settings of the firmware volume according to the
476 input parameter, and returns the new setting of the volume
479 Instance - The FV instance whose attributes is going to be
481 Attributes - On input, it is a pointer to EFI_FVB_ATTRIBUTES
482 containing the desired firmware volume settings.
483 On successful return, it contains the new settings
484 of the firmware volume
489 EFI_INVALID_PARAMETER - invalid parameter
493 if (Instance
>= mFvbCount
) {
494 return EFI_INVALID_PARAMETER
;
497 return mFvbEntry
[Instance
].Fvb
->SetVolumeAttributes (mFvbEntry
[Instance
].Fvb
, &Attributes
);
501 EfiFvbGetPhysicalAddress (
503 OUT EFI_PHYSICAL_ADDRESS
*BaseAddress
508 Retrieves the physical address of a memory mapped FV
511 Instance - The FV instance whose base address is going to be
513 BaseAddress - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS
514 that on successful return, contains the base address
515 of the firmware volume.
521 EFI_INVALID_PARAMETER - invalid parameter
525 if (Instance
>= mFvbCount
) {
526 return EFI_INVALID_PARAMETER
;
529 return mFvbEntry
[Instance
].Fvb
->GetPhysicalAddress (mFvbEntry
[Instance
].Fvb
, BaseAddress
);
536 OUT UINTN
*BlockSize
,
537 OUT UINTN
*NumOfBlocks
542 Retrieve the size of a logical block
545 Instance - The FV instance whose block size is going to be
547 Lba - Indicates which block to return the size for.
548 BlockSize - A pointer to a caller allocated UINTN in which
549 the size of the block is returned
550 NumOfBlocks - a pointer to a caller allocated UINTN in which the
551 number of consecutive blocks starting with Lba is
552 returned. All blocks in this range have a size of
556 EFI_SUCCESS - The firmware volume was read successfully and
557 contents are in Buffer
559 EFI_INVALID_PARAMETER - invalid parameter
563 if (Instance
>= mFvbCount
) {
564 return EFI_INVALID_PARAMETER
;
567 return mFvbEntry
[Instance
].Fvb
->GetBlockSize (mFvbEntry
[Instance
].Fvb
, Lba
, BlockSize
, NumOfBlocks
);
571 EfiFvbEraseCustomBlockRange (
574 IN UINTN OffsetStartLba
,
576 IN UINTN OffsetLastLba
581 Erases and initializes a specified range of a firmware volume
584 Instance - The FV instance to be erased
585 StartLba - The starting logical block index to be erased
586 OffsetStartLba - Offset into the starting block at which to
588 LastLba - The last logical block index to be erased
589 OffsetLastLba - Offset into the last block at which to end erasing
595 EFI_INVALID_PARAMETER - invalid parameter
597 EFI_UNSUPPORTED - not support
601 if (Instance
>= mFvbCount
) {
602 return EFI_INVALID_PARAMETER
;
605 if (!(mFvbEntry
[Instance
].FvbExtension
)) {
606 return EFI_UNSUPPORTED
;
609 if (!(mFvbEntry
[Instance
].FvbExtension
->EraseFvbCustomBlock
)) {
610 return EFI_UNSUPPORTED
;
613 return mFvbEntry
[Instance
].FvbExtension
->EraseFvbCustomBlock (
614 mFvbEntry
[Instance
].FvbExtension
,