3 Firmware File System driver that produce full Firmware Volume2 protocol.
4 Layers on top of Firmware Block protocol to produce a file abstraction
7 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
9 This program and the accompanying materials
10 are licensed and made available under the terms and conditions
11 of the BSD License which accompanies this distribution. The
12 full text of the license may be found at
13 http://opensource.org/licenses/bsd-license.php
15 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
16 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 #include "FwVolDriver.h"
22 #define KEYSIZE sizeof (UINTN)
25 Given the supplied FW_VOL_BLOCK_PROTOCOL, allocate a buffer for output and
26 copy the real length volume header into it.
28 @param Fvb The FW_VOL_BLOCK_PROTOCOL instance from which to
29 read the volume header
30 @param FwVolHeader Pointer to pointer to allocated buffer in which
31 the volume header is returned.
33 @retval EFI_OUT_OF_RESOURCES No enough buffer could be allocated.
34 @retval EFI_SUCCESS Successfully read volume header to the allocated
36 @retval EFI_ACCESS_DENIED Read status of FV is not enabled.
37 @retval EFI_INVALID_PARAMETER The FV Header signature is not as expected or
38 the file system could not be understood.
42 IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*Fvb
,
43 OUT EFI_FIRMWARE_VOLUME_HEADER
**FwVolHeader
47 EFI_FIRMWARE_VOLUME_HEADER TempFvh
;
48 EFI_FVB_ATTRIBUTES_2 FvbAttributes
;
50 EFI_PHYSICAL_ADDRESS BaseAddress
;
53 // Determine the real length of FV header
55 Status
= Fvb
->GetAttributes (
59 if (EFI_ERROR (Status
)) {
63 if ((FvbAttributes
& EFI_FVB2_READ_STATUS
) == 0) {
64 return EFI_ACCESS_DENIED
;
68 // Just avoid compiling warning
71 FvhLength
= sizeof (EFI_FIRMWARE_VOLUME_HEADER
);
74 // memory-mapped FV and non memory-mapped has different ways to read
76 if ((FvbAttributes
& EFI_FVB2_MEMORY_MAPPED
) != 0) {
77 Status
= Fvb
->GetPhysicalAddress (
81 if (EFI_ERROR (Status
)) {
84 CopyMem (&TempFvh
, (VOID
*) (UINTN
) BaseAddress
, FvhLength
);
96 // Validate FV Header signature, if not as expected, continue.
98 if (TempFvh
.Signature
!= EFI_FVH_SIGNATURE
) {
99 return EFI_INVALID_PARAMETER
;
103 // Check to see that the file system is indeed formatted in a way we can
106 if ((!CompareGuid (&TempFvh
.FileSystemGuid
, &gEfiFirmwareFileSystem2Guid
)) &&
107 (!CompareGuid (&TempFvh
.FileSystemGuid
, &gEfiFirmwareFileSystem3Guid
))) {
108 return EFI_INVALID_PARAMETER
;
111 *FwVolHeader
= AllocatePool (TempFvh
.HeaderLength
);
112 if (*FwVolHeader
== NULL
) {
113 return EFI_OUT_OF_RESOURCES
;
116 // Read the whole header
118 if ((FvbAttributes
& EFI_FVB2_MEMORY_MAPPED
) != 0) {
119 CopyMem (*FwVolHeader
, (VOID
*) (UINTN
) BaseAddress
, TempFvh
.HeaderLength
);
122 // Assumed the first block is bigger than the length of Fv headder
124 FvhLength
= TempFvh
.HeaderLength
;
130 (UINT8
*) *FwVolHeader
133 // Check whether Read successes.
135 if (EFI_ERROR (Status
)) {
136 FreePool (*FwVolHeader
);
146 Free FvDevice resource when error happens.
148 @param FvDevice Pointer to the FvDevice to be freed.
151 FreeFvDeviceResource (
152 IN FV_DEVICE
*FvDevice
156 FREE_SPACE_ENTRY
*FreeSpaceEntry
;
157 FFS_FILE_LIST_ENTRY
*FfsFileEntry
;
158 LIST_ENTRY
*NextEntry
;
163 LbaEntry
= (LBA_ENTRY
*) FvDevice
->LbaHeader
.ForwardLink
;
164 while (&LbaEntry
->Link
!= &FvDevice
->LbaHeader
) {
165 NextEntry
= (&LbaEntry
->Link
)->ForwardLink
;
167 LbaEntry
= (LBA_ENTRY
*) NextEntry
;
170 // Free File List Entry
172 FfsFileEntry
= (FFS_FILE_LIST_ENTRY
*) FvDevice
->FfsFileListHeader
.ForwardLink
;
173 while (&FfsFileEntry
->Link
!= &FvDevice
->FfsFileListHeader
) {
174 NextEntry
= (&FfsFileEntry
->Link
)->ForwardLink
;
175 FreePool (FfsFileEntry
);
176 FfsFileEntry
= (FFS_FILE_LIST_ENTRY
*) NextEntry
;
181 FreeSpaceEntry
= (FREE_SPACE_ENTRY
*) FvDevice
->FreeSpaceHeader
.ForwardLink
;
182 while (&FreeSpaceEntry
->Link
!= &FvDevice
->FreeSpaceHeader
) {
183 NextEntry
= (&FreeSpaceEntry
->Link
)->ForwardLink
;
184 FreePool (FreeSpaceEntry
);
185 FreeSpaceEntry
= (FREE_SPACE_ENTRY
*) NextEntry
;
190 FreePool ((UINT8
*) (UINTN
) FvDevice
->CachedFv
);
197 Firmware volume inherits authentication status from the FV image file and section(in another firmware volume)
198 where it came from or propagated from PEI-phase.
200 @param FvDevice A pointer to the FvDevice.
204 FwVolInheritAuthenticationStatus (
205 IN FV_DEVICE
*FvDevice
209 EFI_FIRMWARE_VOLUME_HEADER
*CachedFvHeader
;
210 EFI_FIRMWARE_VOLUME_EXT_HEADER
*CachedFvExtHeader
;
211 EFI_FIRMWARE_VOLUME2_PROTOCOL
*ParentFvProtocol
;
213 EFI_GUID FileNameGuid
;
214 EFI_FV_FILETYPE FileType
;
215 EFI_FV_FILE_ATTRIBUTES FileAttributes
;
217 EFI_SECTION_TYPE SectionType
;
218 UINT32 AuthenticationStatus
;
219 EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
;
220 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FvExtHeader
;
222 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*Fvb
;
223 EFI_FVB_ATTRIBUTES_2 FvbAttributes
;
224 EFI_PHYSICAL_ADDRESS BaseAddress
;
225 EFI_PEI_HOB_POINTERS Fv3Hob
;
227 if (FvDevice
->Fv
.ParentHandle
!= NULL
) {
228 CachedFvHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) (UINTN
) FvDevice
->CachedFv
;
231 // By Parent Handle, find out the FV image file and section(in another firmware volume) where the firmware volume came from
233 Status
= gBS
->HandleProtocol (FvDevice
->Fv
.ParentHandle
, &gEfiFirmwareVolume2ProtocolGuid
, (VOID
**) &ParentFvProtocol
);
234 if (!EFI_ERROR (Status
) && (ParentFvProtocol
!= NULL
)) {
237 FileType
= EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
;
238 Status
= ParentFvProtocol
->GetNextFile (
246 if (EFI_ERROR (Status
)) {
250 SectionType
= EFI_SECTION_FIRMWARE_VOLUME_IMAGE
;
253 Status
= ParentFvProtocol
->ReadSection (
260 &AuthenticationStatus
262 if (!EFI_ERROR (Status
)) {
263 if ((FvHeader
->FvLength
== CachedFvHeader
->FvLength
) &&
264 (FvHeader
->ExtHeaderOffset
== CachedFvHeader
->ExtHeaderOffset
)) {
265 if (FvHeader
->ExtHeaderOffset
!= 0) {
267 // Both FVs contain extension header, then compare their FV Name GUID
269 FvExtHeader
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*) ((UINTN
) FvHeader
+ FvHeader
->ExtHeaderOffset
);
270 CachedFvExtHeader
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*) ((UINTN
) CachedFvHeader
+ CachedFvHeader
->ExtHeaderOffset
);
271 if (CompareGuid (&FvExtHeader
->FvName
, &CachedFvExtHeader
->FvName
)) {
273 // Found the FV image section where the firmware volume came from,
274 // and then inherit authentication status from it.
276 FvDevice
->AuthenticationStatus
= AuthenticationStatus
;
277 FreePool ((VOID
*) FvHeader
);
282 // Both FVs don't contain extension header, then compare their whole FV Image.
284 if (CompareMem ((VOID
*) FvHeader
, (VOID
*) CachedFvHeader
, (UINTN
) FvHeader
->FvLength
) == 0) {
286 // Found the FV image section where the firmware volume came from
287 // and then inherit authentication status from it.
289 FvDevice
->AuthenticationStatus
= AuthenticationStatus
;
290 FreePool ((VOID
*) FvHeader
);
295 FreePool ((VOID
*) FvHeader
);
302 Status
= Fvb
->GetAttributes (Fvb
, &FvbAttributes
);
303 if (EFI_ERROR (Status
)) {
307 if ((FvbAttributes
& EFI_FVB2_MEMORY_MAPPED
) != 0) {
309 // Get volume base address
311 Status
= Fvb
->GetPhysicalAddress (Fvb
, &BaseAddress
);
312 if (EFI_ERROR (Status
)) {
317 // Get the authentication status propagated from PEI-phase to DXE.
319 Fv3Hob
.Raw
= GetHobList ();
320 while ((Fv3Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_FV3
, Fv3Hob
.Raw
)) != NULL
) {
321 if (Fv3Hob
.FirmwareVolume3
->BaseAddress
== BaseAddress
) {
322 FvDevice
->AuthenticationStatus
= Fv3Hob
.FirmwareVolume3
->AuthenticationStatus
;
325 Fv3Hob
.Raw
= GET_NEXT_HOB (Fv3Hob
);
332 Check if an FV is consistent and allocate cache for it.
334 @param FvDevice A pointer to the FvDevice to be checked.
336 @retval EFI_OUT_OF_RESOURCES No enough buffer could be allocated.
337 @retval EFI_VOLUME_CORRUPTED File system is corrupted.
338 @retval EFI_SUCCESS FV is consistent and cache is allocated.
343 IN FV_DEVICE
*FvDevice
347 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*Fvb
;
348 EFI_FVB_ATTRIBUTES_2 FvbAttributes
;
349 EFI_FV_BLOCK_MAP_ENTRY
*BlockMap
;
350 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
351 EFI_FIRMWARE_VOLUME_EXT_HEADER
*FwVolExtHeader
;
354 FREE_SPACE_ENTRY
*FreeSpaceEntry
;
355 FFS_FILE_LIST_ENTRY
*FfsFileEntry
;
364 EFI_FFS_FILE_STATE FileState
;
367 EFI_PHYSICAL_ADDRESS BaseAddress
;
371 Status
= Fvb
->GetAttributes (Fvb
, &FvbAttributes
);
372 if (EFI_ERROR (Status
)) {
376 InitializeListHead (&FvDevice
->LbaHeader
);
377 InitializeListHead (&FvDevice
->FreeSpaceHeader
);
378 InitializeListHead (&FvDevice
->FfsFileListHeader
);
381 Status
= GetFwVolHeader (Fvb
, &FwVolHeader
);
382 if (EFI_ERROR (Status
)) {
385 ASSERT (FwVolHeader
!= NULL
);
387 FvDevice
->IsFfs3Fv
= CompareGuid (&FwVolHeader
->FileSystemGuid
, &gEfiFirmwareFileSystem3Guid
);
390 // Double Check firmware volume header here
392 if (!VerifyFvHeaderChecksum (FwVolHeader
)) {
393 FreePool (FwVolHeader
);
394 return EFI_VOLUME_CORRUPTED
;
397 BlockMap
= FwVolHeader
->BlockMap
;
400 // FwVolHeader->FvLength is the whole FV length including FV header
402 FwCache
= AllocateZeroPool ((UINTN
) FwVolHeader
->FvLength
);
403 if (FwCache
== NULL
) {
404 FreePool (FwVolHeader
);
405 return EFI_OUT_OF_RESOURCES
;
408 FvDevice
->CachedFv
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) FwCache
;
417 if ((FvbAttributes
& EFI_FVB2_MEMORY_MAPPED
) != 0) {
419 // Get volume base address
421 Status
= Fvb
->GetPhysicalAddress (Fvb
, &BaseAddress
);
422 if (EFI_ERROR (Status
)) {
423 FreePool (FwVolHeader
);
427 Ptr
= (UINT8
*) ((UINTN
) BaseAddress
);
429 DEBUG((EFI_D_INFO
, "Fv Base Address is 0x%LX\n", BaseAddress
));
432 // Copy whole FV into the memory
434 while ((BlockMap
->NumBlocks
!= 0) || (BlockMap
->Length
!= 0)) {
436 for (Index
= 0; Index
< BlockMap
->NumBlocks
; Index
++) {
437 LbaEntry
= AllocatePool (sizeof (LBA_ENTRY
));
438 if (LbaEntry
== NULL
) {
439 FreePool (FwVolHeader
);
440 FreeFvDeviceResource (FvDevice
);
441 return EFI_OUT_OF_RESOURCES
;
444 LbaEntry
->LbaIndex
= LbaIndex
;
445 LbaEntry
->StartingAddress
= LbaStart
;
446 LbaEntry
->BlockLength
= BlockMap
->Length
;
449 // Copy each LBA into memory
451 if ((FvbAttributes
& EFI_FVB2_MEMORY_MAPPED
) != 0) {
453 CopyMem (LbaStart
, Ptr
, BlockMap
->Length
);
454 Ptr
+= BlockMap
->Length
;
458 Size
= BlockMap
->Length
;
467 // Not check EFI_BAD_BUFFER_SIZE, for Size = BlockMap->Length
469 if (EFI_ERROR (Status
)) {
470 FreePool (FwVolHeader
);
471 FreeFvDeviceResource (FvDevice
);
478 LbaStart
+= BlockMap
->Length
;
480 InsertTailList (&FvDevice
->LbaHeader
, &LbaEntry
->Link
);
486 FvDevice
->FwVolHeader
= (EFI_FIRMWARE_VOLUME_HEADER
*) FwCache
;
489 // it is not used any more, so free FwVolHeader
491 FreePool (FwVolHeader
);
494 // Scan to check the free space & File list
496 if ((FvbAttributes
& EFI_FVB2_ERASE_POLARITY
) != 0) {
502 FvDevice
->ErasePolarity
= ErasePolarity
;
505 // go through the whole FV cache, check the consistence of the FV
507 if (FvDevice
->FwVolHeader
->ExtHeaderOffset
!= 0) {
509 // Searching for files starts on an 8 byte aligned boundary after the end of the Extended Header if it exists.
511 FwVolExtHeader
= (EFI_FIRMWARE_VOLUME_EXT_HEADER
*) (UINTN
) (FvDevice
->CachedFv
+ FvDevice
->FwVolHeader
->ExtHeaderOffset
);
512 Ptr
= (UINT8
*) FwVolExtHeader
+ FwVolExtHeader
->ExtHeaderSize
;
514 Ptr
= (UINT8
*) (UINTN
) (FvDevice
->CachedFv
+ FvDevice
->FwVolHeader
->HeaderLength
);
516 Ptr
= (UINT8
*) ALIGN_POINTER (Ptr
, 8);
517 TopFvAddress
= (UINT8
*) (UINTN
) (FvDevice
->CachedFv
+ FvDevice
->FwVolHeader
->FvLength
);
520 // Build FFS list & Free Space List here
522 while (Ptr
< TopFvAddress
) {
523 TestLength
= TopFvAddress
- Ptr
;
525 if (TestLength
> sizeof (EFI_FFS_FILE_HEADER
)) {
526 TestLength
= sizeof (EFI_FFS_FILE_HEADER
);
529 if (IsBufferErased (ErasePolarity
, Ptr
, TestLength
)) {
531 // We found free space
537 TestLength
= TopFvAddress
- Ptr
;
539 if (TestLength
> sizeof (EFI_FFS_FILE_HEADER
)) {
540 TestLength
= sizeof (EFI_FFS_FILE_HEADER
);
543 if (!IsBufferErased (ErasePolarity
, Ptr
, TestLength
)) {
547 FreeSize
+= TestLength
;
549 } while (Ptr
< TopFvAddress
);
551 FreeSpaceEntry
= AllocateZeroPool (sizeof (FREE_SPACE_ENTRY
));
552 if (FreeSpaceEntry
== NULL
) {
553 FreeFvDeviceResource (FvDevice
);
554 return EFI_OUT_OF_RESOURCES
;
557 // Create a Free space entry
559 FreeSpaceEntry
->StartingAddress
= FreeStart
;
560 FreeSpaceEntry
->Length
= FreeSize
;
561 InsertTailList (&FvDevice
->FreeSpaceHeader
, &FreeSpaceEntry
->Link
);
565 // double check boundary
567 if (TestLength
< sizeof (EFI_FFS_FILE_HEADER
)) {
571 if (!IsValidFFSHeader (
572 FvDevice
->ErasePolarity
,
573 (EFI_FFS_FILE_HEADER
*) Ptr
575 FileState
= GetFileState (
576 FvDevice
->ErasePolarity
,
577 (EFI_FFS_FILE_HEADER
*) Ptr
579 if ((FileState
== EFI_FILE_HEADER_INVALID
) || (FileState
== EFI_FILE_HEADER_CONSTRUCTION
)) {
580 if (IS_FFS_FILE2 (Ptr
)) {
581 if (!FvDevice
->IsFfs3Fv
) {
582 DEBUG ((EFI_D_ERROR
, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &((EFI_FFS_FILE_HEADER
*) Ptr
)->Name
));
584 Ptr
= Ptr
+ sizeof (EFI_FFS_FILE_HEADER2
);
586 Ptr
= Ptr
+ sizeof (EFI_FFS_FILE_HEADER
);
593 // File system is corrputed, return
595 FreeFvDeviceResource (FvDevice
);
596 return EFI_VOLUME_CORRUPTED
;
600 if (IS_FFS_FILE2 (Ptr
)) {
601 ASSERT (FFS_FILE2_SIZE (Ptr
) > 0x00FFFFFF);
602 if (!FvDevice
->IsFfs3Fv
) {
603 DEBUG ((EFI_D_ERROR
, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &((EFI_FFS_FILE_HEADER
*) Ptr
)->Name
));
604 Ptr
= Ptr
+ FFS_FILE2_SIZE (Ptr
);
606 // Adjust Ptr to the next 8-byte aligned boundary.
608 while (((UINTN
) Ptr
& 0x07) != 0) {
615 if (IsValidFFSFile (FvDevice
, (EFI_FFS_FILE_HEADER
*) Ptr
)) {
616 FileState
= GetFileState (
617 FvDevice
->ErasePolarity
,
618 (EFI_FFS_FILE_HEADER
*) Ptr
622 // check for non-deleted file
624 if (FileState
!= EFI_FILE_DELETED
) {
626 // Create a FFS list entry for each non-deleted file
628 FfsFileEntry
= AllocateZeroPool (sizeof (FFS_FILE_LIST_ENTRY
));
629 if (FfsFileEntry
== NULL
) {
630 FreeFvDeviceResource (FvDevice
);
631 return EFI_OUT_OF_RESOURCES
;
634 FfsFileEntry
->FfsHeader
= Ptr
;
635 InsertTailList (&FvDevice
->FfsFileListHeader
, &FfsFileEntry
->Link
);
638 if (IS_FFS_FILE2 (Ptr
)) {
639 Ptr
= Ptr
+ FFS_FILE2_SIZE (Ptr
);
641 Ptr
= Ptr
+ FFS_FILE_SIZE (Ptr
);
645 // Adjust Ptr to the next 8-byte aligned boundary.
647 while (((UINTN
) Ptr
& 0x07) != 0) {
652 // File system is corrupted, return
654 FreeFvDeviceResource (FvDevice
);
655 return EFI_VOLUME_CORRUPTED
;
659 FvDevice
->CurrentFfsFile
= NULL
;
665 Entry point function does install/reinstall FV2 protocol with full functionality.
667 @param ImageHandle A handle for the image that is initializing this driver
668 @param SystemTable A pointer to the EFI system table
670 @retval EFI_SUCCESS At least one Fv protocol install/reinstall successfully.
671 @retval EFI_NOT_FOUND No FV protocol install/reinstall successfully.
676 IN EFI_HANDLE ImageHandle
,
677 IN EFI_SYSTEM_TABLE
*SystemTable
681 EFI_HANDLE
*HandleBuffer
;
684 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*Fvb
;
685 EFI_FIRMWARE_VOLUME2_PROTOCOL
*Fv
;
687 EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
;
691 DEBUG ((EFI_D_INFO
, "=========FwVol writable driver installed\n"));
694 // Locate all handles of Fvb protocol
696 Status
= gBS
->LocateHandleBuffer (
698 &gEfiFirmwareVolumeBlockProtocolGuid
,
703 if (EFI_ERROR (Status
)) {
704 return EFI_NOT_FOUND
;
707 for (Index
= 0; Index
< HandleCount
; Index
+= 1) {
708 Status
= gBS
->HandleProtocol (
710 &gEfiFirmwareVolumeBlockProtocolGuid
,
713 if (EFI_ERROR (Status
)) {
718 Status
= GetFwVolHeader (Fvb
, &FwVolHeader
);
719 if (EFI_ERROR (Status
)) {
722 ASSERT (FwVolHeader
!= NULL
);
723 FreePool (FwVolHeader
);
727 // Check if there is an FV protocol already installed in that handle
729 Status
= gBS
->HandleProtocol (
731 &gEfiFirmwareVolume2ProtocolGuid
,
734 if (!EFI_ERROR (Status
)) {
738 // FwVol protocol on the handle so create a new one
740 FvDevice
= AllocateZeroPool (sizeof (FV_DEVICE
));
741 if (FvDevice
== NULL
) {
745 FvDevice
->Signature
= FV_DEVICE_SIGNATURE
;
749 // Firmware Volume Protocol interface
751 FvDevice
->Fv
.GetVolumeAttributes
= FvGetVolumeAttributes
;
752 FvDevice
->Fv
.SetVolumeAttributes
= FvSetVolumeAttributes
;
753 FvDevice
->Fv
.ReadFile
= FvReadFile
;
754 FvDevice
->Fv
.ReadSection
= FvReadFileSection
;
755 FvDevice
->Fv
.WriteFile
= FvWriteFile
;
756 FvDevice
->Fv
.GetNextFile
= FvGetNextFile
;
757 FvDevice
->Fv
.KeySize
= KEYSIZE
;
758 FvDevice
->Fv
.GetInfo
= FvGetVolumeInfo
;
759 FvDevice
->Fv
.SetInfo
= FvSetVolumeInfo
;
760 FvDevice
->Fv
.ParentHandle
= Fvb
->ParentHandle
;
762 Status
= FvCheck (FvDevice
);
763 if (EFI_ERROR (Status
)) {
765 // The file system is not consistence
771 FwVolInheritAuthenticationStatus (FvDevice
);
775 // Reinstall an New FV protocol
777 // FvDevice = FV_DEVICE_FROM_THIS (Fv);
778 // FvDevice->Fvb = Fvb;
779 // FreeFvDeviceResource (FvDevice);
781 Status
= gBS
->ReinstallProtocolInterface (
783 &gEfiFirmwareVolume2ProtocolGuid
,
787 if (!EFI_ERROR (Status
)) {
793 DEBUG ((EFI_D_INFO
, "Reinstall FV protocol as writable - %r\n", Status
));
794 ASSERT_EFI_ERROR (Status
);
797 // Install an New FV protocol
799 Status
= gBS
->InstallProtocolInterface (
801 &gEfiFirmwareVolume2ProtocolGuid
,
802 EFI_NATIVE_INTERFACE
,
805 if (!EFI_ERROR (Status
)) {
811 DEBUG ((EFI_D_INFO
, "Install FV protocol as writable - %r\n", Status
));
812 ASSERT_EFI_ERROR (Status
);
818 // As long as one Fv protocol install/reinstall successfully,
819 // success should return to ensure this image will be not unloaded.
820 // Otherwise, new Fv protocols are corrupted by other loaded driver.
827 // No FV protocol install/reinstall successfully.
828 // EFI_NOT_FOUND should return to ensure this image will be unloaded.
830 return EFI_NOT_FOUND
;