3 Firmware Volume Block Protocol Runtime Interface Abstraction
4 And FVB Extension protocol Runtime Interface Abstraction
6 mFvbEntry is an array of Handle Fvb pairs. The Fvb Lib Instance matches the
7 index in the mFvbEntry array. This should be the same sequence as the FVB's
8 were described in the HOB. We have to remember the handle so we can tell if
9 the protocol has been reinstalled and it needs updateing.
11 If you are using any of these lib functions.you must first call FvbInitialize ().
13 Copyright (c) 2006 - 2008, Intel Corporation
14 All rights reserved. This program and the accompanying materials
15 are licensed and made available under the terms and conditions of the BSD License
16 which accompanies this distribution. The full text of the license may be found at
17 http://opensource.org/licenses/bsd-license.php
19 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
20 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
28 // Event for Set Virtual Map Changed Event
30 STATIC EFI_EVENT mSetVirtualMapChangedEvent
= NULL
;
33 // Lib will ASSERT if more FVB devices than this are added to the system.
35 STATIC FVB_ENTRY
*mFvbEntry
;
36 STATIC EFI_EVENT mFvbRegistration
;
37 STATIC UINTN mFvbCount
;
40 Check whether an address is runtime memory or not.
42 @param Address The Address being checked.
44 @retval TRUE The address is runtime memory.
45 @retval FALSE The address is not runtime memory.
53 UINT8 TmpMemoryMap
[1];
56 UINT32 DescriptorVersion
;
58 EFI_MEMORY_DESCRIPTOR
*MemoryMap
;
59 EFI_MEMORY_DESCRIPTOR
*MemoryMapPtr
;
66 // Get System MemoryMapSize
69 Status
= gBS
->GetMemoryMap (
71 (EFI_MEMORY_DESCRIPTOR
*)TmpMemoryMap
,
76 ASSERT (Status
== EFI_BUFFER_TOO_SMALL
);
78 // Enlarge space here, because we will allocate pool now.
80 MemoryMapSize
+= EFI_PAGE_SIZE
;
81 Status
= gBS
->AllocatePool (
86 ASSERT_EFI_ERROR (Status
);
89 // Get System MemoryMap
91 Status
= gBS
->GetMemoryMap (
98 ASSERT_EFI_ERROR (Status
);
100 MemoryMapPtr
= MemoryMap
;
102 // Search the request Address
104 for (Index
= 0; Index
< (MemoryMapSize
/ DescriptorSize
); Index
++) {
105 if (((EFI_PHYSICAL_ADDRESS
)(UINTN
)Address
>= MemoryMap
->PhysicalStart
) &&
106 ((EFI_PHYSICAL_ADDRESS
)(UINTN
)Address
< MemoryMap
->PhysicalStart
107 + LShiftU64 (MemoryMap
->NumberOfPages
, EFI_PAGE_SHIFT
))) {
111 if (MemoryMap
->Attribute
& EFI_MEMORY_RUNTIME
) {
119 MemoryMap
= (EFI_MEMORY_DESCRIPTOR
*)((UINTN
)MemoryMap
+ DescriptorSize
);
125 gBS
->FreePool (MemoryMapPtr
);
131 Update mFvbEntry. Add new entry, or update existing entry if Fvb protocol is
134 @param Event The Event that is being processed
135 @param Context Event Context
141 FvbNotificationEvent (
153 BufferSize
= sizeof (Handle
);
154 Status
= gBS
->LocateHandle (
156 &gEfiFirmwareVolumeBlockProtocolGuid
,
161 if (EFI_ERROR (Status
)) {
163 // Exit Path of While Loop....
168 UpdateIndex
= MAX_FVB_COUNT
;
169 for (Index
= 0; Index
< mFvbCount
; Index
++) {
170 if (mFvbEntry
[Index
].Handle
== Handle
) {
172 // If the handle is already in the table just update the protocol
179 if (UpdateIndex
== MAX_FVB_COUNT
) {
181 // Use the next free slot for a new entry
183 UpdateIndex
= mFvbCount
++;
185 // Check the UpdateIndex whether exceed the maximum value.
187 ASSERT (UpdateIndex
< MAX_FVB_COUNT
);
188 mFvbEntry
[UpdateIndex
].Handle
= Handle
;
191 // The array does not have enough entries
193 ASSERT (UpdateIndex
< MAX_FVB_COUNT
);
196 // Get the interface pointer and if it's ours, skip it
198 Status
= gBS
->HandleProtocol (
200 &gEfiFirmwareVolumeBlockProtocolGuid
,
201 (VOID
**) &mFvbEntry
[UpdateIndex
].Fvb
203 ASSERT_EFI_ERROR (Status
);
205 Status
= gBS
->HandleProtocol (
207 &gEfiFvbExtensionProtocolGuid
,
208 (VOID
**) &mFvbEntry
[UpdateIndex
].FvbExtension
210 if (Status
!= EFI_SUCCESS
) {
211 mFvbEntry
[UpdateIndex
].FvbExtension
= NULL
;
215 // Check the FVB can be accessed in RUNTIME, The FVBs in FVB handle list comes
217 // 1) Dxe Core. (FVB information is transferred from FV HOB).
219 // The FVB produced Dxe core is used for discoverying DXE driver and dispatch. These
220 // FVBs can only be accessed in boot time.
221 // FVB driver will discovery all FV in FLASH and these FVBs can be accessed in runtime.
222 // The FVB itself produced by FVB driver is allocated in runtime memory. So we can
223 // determine the what FVB can be accessed in RUNTIME by judging whether FVB itself is allocated
224 // in RUNTIME memory.
226 mFvbEntry
[UpdateIndex
].IsRuntimeAccess
= IsRuntimeMemory (mFvbEntry
[UpdateIndex
].Fvb
);
231 Convert all pointers in mFvbEntry after ExitBootServices.
233 @param Event The Event that is being processed
234 @param Context Event Context
239 FvbVirtualAddressChangeNotifyEvent (
245 if (mFvbEntry
!= NULL
) {
246 for (Index
= 0; Index
< MAX_FVB_COUNT
; Index
++) {
247 if (!mFvbEntry
[Index
].IsRuntimeAccess
) {
251 if (NULL
!= mFvbEntry
[Index
].Fvb
) {
252 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->GetBlockSize
);
253 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->GetPhysicalAddress
);
254 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->GetAttributes
);
255 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->SetAttributes
);
256 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->Read
);
257 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->Write
);
258 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
->EraseBlocks
);
259 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].Fvb
);
262 if (NULL
!= mFvbEntry
[Index
].FvbExtension
) {
263 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].FvbExtension
->EraseFvbCustomBlock
);
264 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
[Index
].FvbExtension
);
268 EfiConvertPointer (0x0, (VOID
**) &mFvbEntry
);
273 Library constructor function entry.
275 @param ImageHandle The handle of image who call this libary.
276 @param SystemTable The point of System Table.
278 @retval EFI_SUCESS Sucess construct this library.
279 @retval Others Fail to contruct this libary.
284 IN EFI_HANDLE ImageHandle
,
285 IN EFI_SYSTEM_TABLE
*SystemTable
291 Status
= gBS
->AllocatePool (
292 EfiRuntimeServicesData
,
293 (UINTN
) sizeof (FVB_ENTRY
) * MAX_FVB_COUNT
,
297 if (EFI_ERROR (Status
)) {
301 ZeroMem (mFvbEntry
, sizeof (FVB_ENTRY
) * MAX_FVB_COUNT
);
303 EfiCreateProtocolNotifyEvent (
304 &gEfiFirmwareVolumeBlockProtocolGuid
,
306 FvbNotificationEvent
,
312 // Register SetVirtualAddressMap () notify function
314 Status
= gBS
->CreateEvent (
315 EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
,
317 FvbVirtualAddressChangeNotifyEvent
,
319 &mSetVirtualMapChangedEvent
321 ASSERT_EFI_ERROR (Status
);
327 // =============================================================================
328 // The following functions wrap Fvb protocol in the Runtime Lib functions.
329 // The Instance translates into Fvb instance. The Fvb order defined by HOBs and
330 // thus the sequence of FVB protocol addition define Instance.
332 // EfiFvbInitialize () must be called before any of the following functions
334 // =============================================================================
338 Reads specified number of bytes into a buffer from the specified block
340 @param Instance The FV instance to be read from.
341 @param Lba The logical block address to be read from
342 @param Offset Offset into the block at which to begin reading
343 @param NumBytes Pointer that on input contains the total size of
344 the buffer. On output, it contains the total number
346 @param Buffer Pointer to a caller allocated buffer that will be
347 used to hold the data read
349 @retval EFI_INVALID_PARAMETER Invalid parameter
350 @retval EFI_SUCESS Sucess to Read block
351 @retval Others Fail to read block
358 IN OUT UINTN
*NumBytes
,
362 ASSERT (NumBytes
!= NULL
);
363 ASSERT (Buffer
!= NULL
);
365 if (Instance
>= mFvbCount
) {
366 return EFI_INVALID_PARAMETER
;
369 if (EfiAtRuntime() && !mFvbEntry
[Instance
].IsRuntimeAccess
) {
370 return EFI_INVALID_PARAMETER
;
373 return mFvbEntry
[Instance
].Fvb
->Read (mFvbEntry
[Instance
].Fvb
, Lba
, Offset
, NumBytes
, Buffer
);
377 Writes specified number of bytes from the input buffer to the block
379 @param Instance The FV instance to be written to
380 @param Lba The starting logical block index to write to
381 @param Offset Offset into the block at which to begin writing
382 @param NumBytes Pointer that on input contains the total size of
383 the buffer. On output, it contains the total number
384 of bytes actually written
385 @param Buffer Pointer to a caller allocated buffer that contains
386 the source for the write
388 @retval EFI_INVALID_PARAMETER Invalid parameter
389 @retval EFI_SUCESS Sucess to write block
390 @retval Others Fail to write block
397 IN OUT UINTN
*NumBytes
,
401 ASSERT (NumBytes
!= NULL
);
403 if (Instance
>= mFvbCount
) {
404 return EFI_INVALID_PARAMETER
;
407 if (EfiAtRuntime() && !mFvbEntry
[Instance
].IsRuntimeAccess
) {
408 return EFI_INVALID_PARAMETER
;
411 return mFvbEntry
[Instance
].Fvb
->Write (mFvbEntry
[Instance
].Fvb
, Lba
, Offset
, NumBytes
, Buffer
);
415 Erases and initializes a firmware volume block
417 @param Instance The FV instance to be erased
418 @param Lba The logical block index to be erased
420 @retval EFI_INVALID_PARAMETER Invalid parameter
421 @retval EFI_SUCESS Sucess to erase block
422 @retval Others Fail to erase block
430 if (Instance
>= mFvbCount
) {
431 return EFI_INVALID_PARAMETER
;
434 if (EfiAtRuntime() && !mFvbEntry
[Instance
].IsRuntimeAccess
) {
435 return EFI_INVALID_PARAMETER
;
438 return mFvbEntry
[Instance
].Fvb
->EraseBlocks (mFvbEntry
[Instance
].Fvb
, Lba
, 1, EFI_LBA_LIST_TERMINATOR
);
442 Retrieves attributes, insures positive polarity of attribute bits, returns
443 resulting attributes in output parameter
445 @param Instance The FV instance whose attributes is going to be returned
446 @param Attributes Output buffer which contains attributes
448 @retval EFI_INVALID_PARAMETER Invalid parameter
449 @retval EFI_SUCESS Sucess to get Fv attribute
450 @retval Others Fail to get Fv attribute
453 EfiFvbGetVolumeAttributes (
455 OUT EFI_FVB_ATTRIBUTES
*Attributes
458 ASSERT (Attributes
!= NULL
);
460 if (Instance
>= mFvbCount
) {
461 return EFI_INVALID_PARAMETER
;
464 if (EfiAtRuntime() && !mFvbEntry
[Instance
].IsRuntimeAccess
) {
465 return EFI_INVALID_PARAMETER
;
468 return mFvbEntry
[Instance
].Fvb
->GetAttributes (mFvbEntry
[Instance
].Fvb
, Attributes
);
472 Modifies the current settings of the firmware volume according to the
473 input parameter, and returns the new setting of the volume
475 @param Instance The FV instance whose attributes is going to be
477 @param Attributes On input, it is a pointer to EFI_FVB_ATTRIBUTES
478 containing the desired firmware volume settings.
479 On successful return, it contains the new settings
480 of the firmware volume
482 @retval EFI_INVALID_PARAMETER Invalid parameter
483 @retval EFI_SUCESS Sucess to set Fv attribute
484 @retval Others Fail to set Fv attribute
487 EfiFvbSetVolumeAttributes (
489 IN OUT EFI_FVB_ATTRIBUTES
*Attributes
492 ASSERT (Attributes
!= NULL
);
494 if (Instance
>= mFvbCount
) {
495 return EFI_INVALID_PARAMETER
;
498 if (EfiAtRuntime() && !mFvbEntry
[Instance
].IsRuntimeAccess
) {
499 return EFI_INVALID_PARAMETER
;
502 return mFvbEntry
[Instance
].Fvb
->SetAttributes (mFvbEntry
[Instance
].Fvb
, Attributes
);
506 Retrieves the physical address of a memory mapped FV
508 @param Instance The FV instance whose base address is going to be
510 @param BaseAddress Pointer to a caller allocated EFI_PHYSICAL_ADDRESS
511 that on successful return, contains the base address
512 of the firmware volume.
514 @retval EFI_INVALID_PARAMETER Invalid parameter
515 @retval EFI_SUCESS Sucess to get physical address
516 @retval Others Fail to get physical address
519 EfiFvbGetPhysicalAddress (
521 OUT EFI_PHYSICAL_ADDRESS
*BaseAddress
524 ASSERT (BaseAddress
!= NULL
);
526 if (Instance
>= mFvbCount
) {
527 return EFI_INVALID_PARAMETER
;
530 if (EfiAtRuntime() && !mFvbEntry
[Instance
].IsRuntimeAccess
) {
531 return EFI_INVALID_PARAMETER
;
534 return mFvbEntry
[Instance
].Fvb
->GetPhysicalAddress (mFvbEntry
[Instance
].Fvb
, BaseAddress
);
538 Retrieve the size of a logical block
540 @param Instance The FV instance whose block size is going to be
542 @param Lba Indicates which block to return the size for.
543 @param BlockSize A pointer to a caller allocated UINTN in which
544 the size of the block is returned
545 @param 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
550 @retval EFI_INVALID_PARAMETER Invalid parameter
551 @retval EFI_SUCESS Sucess to get block size
552 @retval Others Fail to get block size
558 OUT UINTN
*BlockSize
,
559 OUT UINTN
*NumOfBlocks
562 ASSERT (BlockSize
!= NULL
);
563 ASSERT (NumOfBlocks
!= NULL
);
565 if (Instance
>= mFvbCount
) {
566 return EFI_INVALID_PARAMETER
;
569 if (EfiAtRuntime() && !mFvbEntry
[Instance
].IsRuntimeAccess
) {
570 return EFI_INVALID_PARAMETER
;
573 return mFvbEntry
[Instance
].Fvb
->GetBlockSize (mFvbEntry
[Instance
].Fvb
, Lba
, BlockSize
, NumOfBlocks
);
577 Erases and initializes a specified range of a firmware volume
579 @param Instance The FV instance to be erased
580 @param StartLba The starting logical block index to be erased
581 @param OffsetStartLba Offset into the starting block at which to
583 @param LastLba The last logical block index to be erased
584 @param OffsetLastLba Offset into the last block at which to end erasing
586 @retval EFI_INVALID_PARAMETER Invalid parameter
587 @retval EFI_SUCESS Sucess to erase custom block range
588 @retval Others Fail to erase custom block range
591 EfiFvbEraseCustomBlockRange (
594 IN UINTN OffsetStartLba
,
596 IN UINTN OffsetLastLba
599 if (Instance
>= mFvbCount
) {
600 return EFI_INVALID_PARAMETER
;
603 if (EfiAtRuntime() && !mFvbEntry
[Instance
].IsRuntimeAccess
) {
604 return EFI_INVALID_PARAMETER
;
607 if (!(mFvbEntry
[Instance
].FvbExtension
)) {
608 return EFI_UNSUPPORTED
;
611 if (!(mFvbEntry
[Instance
].FvbExtension
->EraseFvbCustomBlock
)) {
612 return EFI_UNSUPPORTED
;
615 return mFvbEntry
[Instance
].FvbExtension
->EraseFvbCustomBlock (
616 mFvbEntry
[Instance
].FvbExtension
,