summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromFv.c
diff options
context:
space:
mode:
Diffstat (limited to 'MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromFv.c')
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromFv.c880
1 files changed, 440 insertions, 440 deletions
diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromFv.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromFv.c
index 562f5a02f6..5c6cc54916 100644
--- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromFv.c
+++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromFv.c
@@ -1,440 +1,440 @@
-/** @file
- Var Check Hii generation from FV.
-
-Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "VarCheckHiiGen.h"
-
-// {d0bc7cb4-6a47-495f-aa11-710746da06a2}
-#define EFI_VFR_ATTRACT_GUID \
-{ 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } }
-
-EFI_GUID gVfrArrayAttractGuid = EFI_VFR_ATTRACT_GUID;
-
-#define ALL_FF_GUID \
-{ 0xFFFFFFFF, 0xFFFF, 0xFFFF, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } }
-
-EFI_GUID mAllFfGuid = ALL_FF_GUID;
-
-#define VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE SIGNATURE_32 ('V', 'D', 'R', 'I')
-
-typedef struct {
- UINTN Signature;
- LIST_ENTRY Link;
- EFI_GUID *DriverGuid;
-} VAR_CHECK_VFR_DRIVER_INFO;
-
-LIST_ENTRY mVfrDriverList = INITIALIZE_LIST_HEAD_VARIABLE (mVfrDriverList);
-
-#define VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK(a) CR (a, VAR_CHECK_VFR_DRIVER_INFO, Link, VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE)
-
-#define MAX_MATCH_GUID_NUM 100
-
-/**
- Get the address by Guid.
-
- Parse the FFS and find the GUID address.
- There may be multiple Guids matching the searched Guid.
-
- @param Ffs Pointer to the FFS.
- @param Guid Guid to find.
- @param Length The length of FFS.
- @param Offset Pointer to pointer to the offset.
- @param NumOfMatchingGuid The number of matching Guid.
-
- @retval EFI_SUCCESS One or multiple Guids matching the searched Guid.
- @retval EFI_NOT_FOUND No Guid matching the searched Guid.
-
-**/
-EFI_STATUS
-GetAddressByGuid (
- IN VOID *Ffs,
- IN EFI_GUID *Guid,
- IN UINTN Length,
- OUT UINTN **Offset,
- OUT UINT8 *NumOfMatchingGuid
- )
-{
- UINTN LoopControl;
- BOOLEAN Found;
-
- if ((Ffs == NULL) || (Guid == NULL) || (Length == 0)) {
- return EFI_NOT_FOUND;
- }
-
- if (NumOfMatchingGuid != NULL) {
- *NumOfMatchingGuid = 0;
- }
-
- Found = FALSE;
- for (LoopControl = 0; LoopControl < Length; LoopControl++) {
- if (CompareGuid (Guid, (EFI_GUID *)((UINT8 *)Ffs + LoopControl))) {
- Found = TRUE;
- //
- // If NumOfMatchGuid or Offset are NULL, means user only want
- // to check whether current FFS includes this Guid or not.
- //
- if ((NumOfMatchingGuid != NULL) && (Offset != NULL)) {
- if (*NumOfMatchingGuid == 0) {
- *Offset = InternalVarCheckAllocateZeroPool (sizeof (UINTN) * MAX_MATCH_GUID_NUM);
- ASSERT (*Offset != NULL);
- }
-
- *(*Offset + *NumOfMatchingGuid) = LoopControl + sizeof (EFI_GUID);
- (*NumOfMatchingGuid)++;
- } else {
- break;
- }
- }
- }
-
- return (Found ? EFI_SUCCESS : EFI_NOT_FOUND);
-}
-
-/**
- Search the VfrBin Base address.
-
- According to the known GUID gVfrArrayAttractGuid to get the base address from FFS.
-
- @param Ffs Pointer to the FFS.
- @param EfiAddr Pointer to the EFI in FFS
- @param Length The length of FFS.
- @param Offset Pointer to pointer to the Addr (Offset).
- @param NumOfMatchingOffset The number of Addr (Offset).
-
- @retval EFI_SUCCESS Get the address successfully.
- @retval EFI_NOT_FOUND No VfrBin found.
-
-**/
-EFI_STATUS
-SearchVfrBinInFfs (
- IN VOID *Ffs,
- IN VOID *EfiAddr,
- IN UINTN Length,
- OUT UINTN **Offset,
- OUT UINT8 *NumOfMatchingOffset
- )
-{
- UINTN Index;
- EFI_STATUS Status;
- UINTN VirOffValue;
-
- if ((Ffs == NULL) || (Offset == NULL)) {
- return EFI_NOT_FOUND;
- }
-
- Status = GetAddressByGuid (
- Ffs,
- &gVfrArrayAttractGuid,
- Length,
- Offset,
- NumOfMatchingOffset
- );
- if (Status != EFI_SUCCESS) {
- return Status;
- }
-
- for (Index = 0; Index < *NumOfMatchingOffset; Index++) {
- //
- // Got the virOffset after the GUID
- //
- VirOffValue = *(UINTN *)((UINTN)Ffs + *(*Offset + Index));
- //
- // Transfer the offset to the VA address. One modules may own multiple VfrBin address.
- //
- *(*Offset + Index) = (UINTN)EfiAddr + VirOffValue;
- }
-
- return Status;
-}
-
-/**
- Parse FFS.
-
- @param[in] Fv2 Pointer to Fv2 protocol.
- @param[in] DriverGuid Pointer to driver GUID.
-
- @return Found the driver in the FV or not.
-
-**/
-BOOLEAN
-ParseFfs (
- IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv2,
- IN EFI_GUID *DriverGuid
- )
-{
- EFI_STATUS Status;
- EFI_FV_FILETYPE FoundType;
- EFI_FV_FILE_ATTRIBUTES FileAttributes;
- UINT32 AuthenticationStatus;
- UINTN Size;
- VOID *Buffer;
- UINTN SectionSize;
- VOID *SectionBuffer;
- UINTN VfrBinIndex;
- UINT8 NumberofMatchingVfrBin;
- UINTN *VfrBinBaseAddress;
-
- Status = Fv2->ReadFile (
- Fv2,
- DriverGuid,
- NULL,
- &Size,
- &FoundType,
- &FileAttributes,
- &AuthenticationStatus
- );
- if (EFI_ERROR (Status)) {
- return FALSE;
- }
-
- Buffer = NULL;
- Status = Fv2->ReadSection (
- Fv2,
- DriverGuid,
- EFI_SECTION_RAW,
- 0, // Instance
- &Buffer,
- &Size,
- &AuthenticationStatus
- );
- if (!EFI_ERROR (Status)) {
- Status = SearchVfrBinInFfs (Buffer, 0, Size, &VfrBinBaseAddress, &NumberofMatchingVfrBin);
- if (!EFI_ERROR (Status)) {
- SectionBuffer = NULL;
- Status = Fv2->ReadSection (
- Fv2,
- DriverGuid,
- EFI_SECTION_PE32,
- 0, // Instance
- &SectionBuffer,
- &SectionSize,
- &AuthenticationStatus
- );
- if (!EFI_ERROR (Status)) {
- DEBUG ((DEBUG_INFO, "FfsNameGuid - %g\n", DriverGuid));
- DEBUG ((DEBUG_INFO, "NumberofMatchingVfrBin - 0x%02x\n", NumberofMatchingVfrBin));
-
- for (VfrBinIndex = 0; VfrBinIndex < NumberofMatchingVfrBin; VfrBinIndex++) {
- #ifdef DUMP_HII_DATA
- DEBUG_CODE (
- DumpHiiPackage ((UINT8 *)(UINTN)SectionBuffer + VfrBinBaseAddress[VfrBinIndex] + sizeof (UINT32));
- );
- #endif
- VarCheckParseHiiPackage ((UINT8 *)(UINTN)SectionBuffer + VfrBinBaseAddress[VfrBinIndex] + sizeof (UINT32), TRUE);
- }
-
- FreePool (SectionBuffer);
- }
-
- InternalVarCheckFreePool (VfrBinBaseAddress);
- }
-
- FreePool (Buffer);
- }
-
- return TRUE;
-}
-
-/**
- Parse FVs.
-
- @param[in] ScanAll Scan all modules in all FVs or not.
-
-**/
-VOID
-ParseFv (
- IN BOOLEAN ScanAll
- )
-{
- EFI_STATUS Status;
- EFI_HANDLE *HandleBuffer;
- UINTN HandleCount;
- UINTN Index;
- EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv2;
- VOID *Key;
- EFI_FV_FILETYPE FileType;
- EFI_GUID NameGuid;
- EFI_FV_FILE_ATTRIBUTES FileAttributes;
- UINTN Size;
- UINTN FfsIndex;
- VAR_CHECK_VFR_DRIVER_INFO *VfrDriverInfo;
- LIST_ENTRY *VfrDriverLink;
-
- HandleBuffer = NULL;
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiFirmwareVolume2ProtocolGuid,
- NULL,
- &HandleCount,
- &HandleBuffer
- );
- if (EFI_ERROR (Status)) {
- return;
- }
-
- //
- // Search all FVs
- //
- for (Index = 0; Index < HandleCount; Index++) {
- DEBUG ((DEBUG_INFO, "FvIndex - %x\n", Index));
- Status = gBS->HandleProtocol (
- HandleBuffer[Index],
- &gEfiFirmwareVolume2ProtocolGuid,
- (VOID **)&Fv2
- );
- ASSERT_EFI_ERROR (Status);
-
- DEBUG_CODE_BEGIN ();
- EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *Fvb2;
- EFI_PHYSICAL_ADDRESS FvAddress;
- UINT64 FvSize;
-
- Status = gBS->HandleProtocol (
- HandleBuffer[Index],
- &gEfiFirmwareVolumeBlock2ProtocolGuid,
- (VOID **)&Fvb2
- );
- ASSERT_EFI_ERROR (Status);
- Status = Fvb2->GetPhysicalAddress (Fvb2, &FvAddress);
- if (!EFI_ERROR (Status)) {
- DEBUG ((DEBUG_INFO, "FvAddress - 0x%08x\n", FvAddress));
- FvSize = ((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvAddress)->FvLength;
- DEBUG ((DEBUG_INFO, "FvSize - 0x%08x\n", FvSize));
- }
-
- DEBUG_CODE_END ();
-
- if (ScanAll) {
- //
- // Need to parse all modules in all FVs.
- //
- Key = InternalVarCheckAllocateZeroPool (Fv2->KeySize);
- ASSERT (Key != NULL);
-
- for (FfsIndex = 0; ; FfsIndex++) {
- FileType = EFI_FV_FILETYPE_ALL;
- Status = Fv2->GetNextFile (
- Fv2,
- Key,
- &FileType,
- &NameGuid,
- &FileAttributes,
- &Size
- );
- if (EFI_ERROR (Status)) {
- break;
- }
-
- ParseFfs (Fv2, &NameGuid);
- }
-
- InternalVarCheckFreePool (Key);
- } else {
- //
- // Only parse drivers in the VFR drivers list.
- //
- VfrDriverLink = mVfrDriverList.ForwardLink;
- while (VfrDriverLink != &mVfrDriverList) {
- VfrDriverInfo = VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK (VfrDriverLink);
- VfrDriverLink = VfrDriverLink->ForwardLink;
- if (ParseFfs (Fv2, VfrDriverInfo->DriverGuid)) {
- //
- // Found the driver in the FV.
- //
- RemoveEntryList (&VfrDriverInfo->Link);
- InternalVarCheckFreePool (VfrDriverInfo);
- }
- }
- }
- }
-
- FreePool (HandleBuffer);
-}
-
-/**
- Create Vfr Driver List.
-
- @param[in] DriverGuidArray Driver Guid Array
-
-**/
-VOID
-CreateVfrDriverList (
- IN EFI_GUID *DriverGuidArray
- )
-{
- UINTN Index;
- VAR_CHECK_VFR_DRIVER_INFO *VfrDriverInfo;
-
- for (Index = 0; !IsZeroGuid (&DriverGuidArray[Index]); Index++) {
- DEBUG ((DEBUG_INFO, "CreateVfrDriverList: %g\n", &DriverGuidArray[Index]));
- VfrDriverInfo = InternalVarCheckAllocateZeroPool (sizeof (*VfrDriverInfo));
- ASSERT (VfrDriverInfo != NULL);
- VfrDriverInfo->Signature = VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE;
- VfrDriverInfo->DriverGuid = &DriverGuidArray[Index];
- InsertTailList (&mVfrDriverList, &VfrDriverInfo->Link);
- }
-}
-
-/**
- Destroy Vfr Driver List.
-
-**/
-VOID
-DestroyVfrDriverList (
- VOID
- )
-{
- VAR_CHECK_VFR_DRIVER_INFO *VfrDriverInfo;
- LIST_ENTRY *VfrDriverLink;
-
- while (mVfrDriverList.ForwardLink != &mVfrDriverList) {
- VfrDriverLink = mVfrDriverList.ForwardLink;
- VfrDriverInfo = VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK (VfrDriverLink);
- RemoveEntryList (&VfrDriverInfo->Link);
- InternalVarCheckFreePool (VfrDriverInfo);
- }
-}
-
-/**
- Generate from FV.
-
-**/
-VOID
-VarCheckHiiGenFromFv (
- VOID
- )
-{
- EFI_GUID *DriverGuidArray;
- BOOLEAN ScanAll;
-
- DEBUG ((DEBUG_INFO, "VarCheckHiiGenDxeFromFv\n"));
-
- //
- // Get vfr driver guid array from PCD.
- //
- DriverGuidArray = (EFI_GUID *)PcdGetPtr (PcdVarCheckVfrDriverGuidArray);
-
- if (IsZeroGuid (&DriverGuidArray[0])) {
- //
- // No VFR driver will be parsed from FVs.
- //
- return;
- }
-
- if (CompareGuid (&DriverGuidArray[0], &mAllFfGuid)) {
- ScanAll = TRUE;
- } else {
- ScanAll = FALSE;
- CreateVfrDriverList (DriverGuidArray);
- }
-
- ParseFv (ScanAll);
-
- if (!ScanAll) {
- DestroyVfrDriverList ();
- }
-}
+/** @file
+ Var Check Hii generation from FV.
+
+Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "VarCheckHiiGen.h"
+
+// {d0bc7cb4-6a47-495f-aa11-710746da06a2}
+#define EFI_VFR_ATTRACT_GUID \
+{ 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } }
+
+EFI_GUID gVfrArrayAttractGuid = EFI_VFR_ATTRACT_GUID;
+
+#define ALL_FF_GUID \
+{ 0xFFFFFFFF, 0xFFFF, 0xFFFF, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } }
+
+EFI_GUID mAllFfGuid = ALL_FF_GUID;
+
+#define VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE SIGNATURE_32 ('V', 'D', 'R', 'I')
+
+typedef struct {
+ UINTN Signature;
+ LIST_ENTRY Link;
+ EFI_GUID *DriverGuid;
+} VAR_CHECK_VFR_DRIVER_INFO;
+
+LIST_ENTRY mVfrDriverList = INITIALIZE_LIST_HEAD_VARIABLE (mVfrDriverList);
+
+#define VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK(a) CR (a, VAR_CHECK_VFR_DRIVER_INFO, Link, VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE)
+
+#define MAX_MATCH_GUID_NUM 100
+
+/**
+ Get the address by Guid.
+
+ Parse the FFS and find the GUID address.
+ There may be multiple Guids matching the searched Guid.
+
+ @param Ffs Pointer to the FFS.
+ @param Guid Guid to find.
+ @param Length The length of FFS.
+ @param Offset Pointer to pointer to the offset.
+ @param NumOfMatchingGuid The number of matching Guid.
+
+ @retval EFI_SUCCESS One or multiple Guids matching the searched Guid.
+ @retval EFI_NOT_FOUND No Guid matching the searched Guid.
+
+**/
+EFI_STATUS
+GetAddressByGuid (
+ IN VOID *Ffs,
+ IN EFI_GUID *Guid,
+ IN UINTN Length,
+ OUT UINTN **Offset,
+ OUT UINT8 *NumOfMatchingGuid
+ )
+{
+ UINTN LoopControl;
+ BOOLEAN Found;
+
+ if ((Ffs == NULL) || (Guid == NULL) || (Length == 0)) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (NumOfMatchingGuid != NULL) {
+ *NumOfMatchingGuid = 0;
+ }
+
+ Found = FALSE;
+ for (LoopControl = 0; LoopControl < Length; LoopControl++) {
+ if (CompareGuid (Guid, (EFI_GUID *)((UINT8 *)Ffs + LoopControl))) {
+ Found = TRUE;
+ //
+ // If NumOfMatchGuid or Offset are NULL, means user only want
+ // to check whether current FFS includes this Guid or not.
+ //
+ if ((NumOfMatchingGuid != NULL) && (Offset != NULL)) {
+ if (*NumOfMatchingGuid == 0) {
+ *Offset = InternalVarCheckAllocateZeroPool (sizeof (UINTN) * MAX_MATCH_GUID_NUM);
+ ASSERT (*Offset != NULL);
+ }
+
+ *(*Offset + *NumOfMatchingGuid) = LoopControl + sizeof (EFI_GUID);
+ (*NumOfMatchingGuid)++;
+ } else {
+ break;
+ }
+ }
+ }
+
+ return (Found ? EFI_SUCCESS : EFI_NOT_FOUND);
+}
+
+/**
+ Search the VfrBin Base address.
+
+ According to the known GUID gVfrArrayAttractGuid to get the base address from FFS.
+
+ @param Ffs Pointer to the FFS.
+ @param EfiAddr Pointer to the EFI in FFS
+ @param Length The length of FFS.
+ @param Offset Pointer to pointer to the Addr (Offset).
+ @param NumOfMatchingOffset The number of Addr (Offset).
+
+ @retval EFI_SUCCESS Get the address successfully.
+ @retval EFI_NOT_FOUND No VfrBin found.
+
+**/
+EFI_STATUS
+SearchVfrBinInFfs (
+ IN VOID *Ffs,
+ IN VOID *EfiAddr,
+ IN UINTN Length,
+ OUT UINTN **Offset,
+ OUT UINT8 *NumOfMatchingOffset
+ )
+{
+ UINTN Index;
+ EFI_STATUS Status;
+ UINTN VirOffValue;
+
+ if ((Ffs == NULL) || (Offset == NULL)) {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = GetAddressByGuid (
+ Ffs,
+ &gVfrArrayAttractGuid,
+ Length,
+ Offset,
+ NumOfMatchingOffset
+ );
+ if (Status != EFI_SUCCESS) {
+ return Status;
+ }
+
+ for (Index = 0; Index < *NumOfMatchingOffset; Index++) {
+ //
+ // Got the virOffset after the GUID
+ //
+ VirOffValue = *(UINTN *)((UINTN)Ffs + *(*Offset + Index));
+ //
+ // Transfer the offset to the VA address. One modules may own multiple VfrBin address.
+ //
+ *(*Offset + Index) = (UINTN)EfiAddr + VirOffValue;
+ }
+
+ return Status;
+}
+
+/**
+ Parse FFS.
+
+ @param[in] Fv2 Pointer to Fv2 protocol.
+ @param[in] DriverGuid Pointer to driver GUID.
+
+ @return Found the driver in the FV or not.
+
+**/
+BOOLEAN
+ParseFfs (
+ IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv2,
+ IN EFI_GUID *DriverGuid
+ )
+{
+ EFI_STATUS Status;
+ EFI_FV_FILETYPE FoundType;
+ EFI_FV_FILE_ATTRIBUTES FileAttributes;
+ UINT32 AuthenticationStatus;
+ UINTN Size;
+ VOID *Buffer;
+ UINTN SectionSize;
+ VOID *SectionBuffer;
+ UINTN VfrBinIndex;
+ UINT8 NumberofMatchingVfrBin;
+ UINTN *VfrBinBaseAddress;
+
+ Status = Fv2->ReadFile (
+ Fv2,
+ DriverGuid,
+ NULL,
+ &Size,
+ &FoundType,
+ &FileAttributes,
+ &AuthenticationStatus
+ );
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ Buffer = NULL;
+ Status = Fv2->ReadSection (
+ Fv2,
+ DriverGuid,
+ EFI_SECTION_RAW,
+ 0, // Instance
+ &Buffer,
+ &Size,
+ &AuthenticationStatus
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = SearchVfrBinInFfs (Buffer, 0, Size, &VfrBinBaseAddress, &NumberofMatchingVfrBin);
+ if (!EFI_ERROR (Status)) {
+ SectionBuffer = NULL;
+ Status = Fv2->ReadSection (
+ Fv2,
+ DriverGuid,
+ EFI_SECTION_PE32,
+ 0, // Instance
+ &SectionBuffer,
+ &SectionSize,
+ &AuthenticationStatus
+ );
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "FfsNameGuid - %g\n", DriverGuid));
+ DEBUG ((DEBUG_INFO, "NumberofMatchingVfrBin - 0x%02x\n", NumberofMatchingVfrBin));
+
+ for (VfrBinIndex = 0; VfrBinIndex < NumberofMatchingVfrBin; VfrBinIndex++) {
+ #ifdef DUMP_HII_DATA
+ DEBUG_CODE (
+ DumpHiiPackage ((UINT8 *)(UINTN)SectionBuffer + VfrBinBaseAddress[VfrBinIndex] + sizeof (UINT32));
+ );
+ #endif
+ VarCheckParseHiiPackage ((UINT8 *)(UINTN)SectionBuffer + VfrBinBaseAddress[VfrBinIndex] + sizeof (UINT32), TRUE);
+ }
+
+ FreePool (SectionBuffer);
+ }
+
+ InternalVarCheckFreePool (VfrBinBaseAddress);
+ }
+
+ FreePool (Buffer);
+ }
+
+ return TRUE;
+}
+
+/**
+ Parse FVs.
+
+ @param[in] ScanAll Scan all modules in all FVs or not.
+
+**/
+VOID
+ParseFv (
+ IN BOOLEAN ScanAll
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount;
+ UINTN Index;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv2;
+ VOID *Key;
+ EFI_FV_FILETYPE FileType;
+ EFI_GUID NameGuid;
+ EFI_FV_FILE_ATTRIBUTES FileAttributes;
+ UINTN Size;
+ UINTN FfsIndex;
+ VAR_CHECK_VFR_DRIVER_INFO *VfrDriverInfo;
+ LIST_ENTRY *VfrDriverLink;
+
+ HandleBuffer = NULL;
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ //
+ // Search all FVs
+ //
+ for (Index = 0; Index < HandleCount; Index++) {
+ DEBUG ((DEBUG_INFO, "FvIndex - %x\n", Index));
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID **)&Fv2
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG_CODE_BEGIN ();
+ EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *Fvb2;
+ EFI_PHYSICAL_ADDRESS FvAddress;
+ UINT64 FvSize;
+
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiFirmwareVolumeBlock2ProtocolGuid,
+ (VOID **)&Fvb2
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = Fvb2->GetPhysicalAddress (Fvb2, &FvAddress);
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "FvAddress - 0x%08x\n", FvAddress));
+ FvSize = ((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvAddress)->FvLength;
+ DEBUG ((DEBUG_INFO, "FvSize - 0x%08x\n", FvSize));
+ }
+
+ DEBUG_CODE_END ();
+
+ if (ScanAll) {
+ //
+ // Need to parse all modules in all FVs.
+ //
+ Key = InternalVarCheckAllocateZeroPool (Fv2->KeySize);
+ ASSERT (Key != NULL);
+
+ for (FfsIndex = 0; ; FfsIndex++) {
+ FileType = EFI_FV_FILETYPE_ALL;
+ Status = Fv2->GetNextFile (
+ Fv2,
+ Key,
+ &FileType,
+ &NameGuid,
+ &FileAttributes,
+ &Size
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ ParseFfs (Fv2, &NameGuid);
+ }
+
+ InternalVarCheckFreePool (Key);
+ } else {
+ //
+ // Only parse drivers in the VFR drivers list.
+ //
+ VfrDriverLink = mVfrDriverList.ForwardLink;
+ while (VfrDriverLink != &mVfrDriverList) {
+ VfrDriverInfo = VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK (VfrDriverLink);
+ VfrDriverLink = VfrDriverLink->ForwardLink;
+ if (ParseFfs (Fv2, VfrDriverInfo->DriverGuid)) {
+ //
+ // Found the driver in the FV.
+ //
+ RemoveEntryList (&VfrDriverInfo->Link);
+ InternalVarCheckFreePool (VfrDriverInfo);
+ }
+ }
+ }
+ }
+
+ FreePool (HandleBuffer);
+}
+
+/**
+ Create Vfr Driver List.
+
+ @param[in] DriverGuidArray Driver Guid Array
+
+**/
+VOID
+CreateVfrDriverList (
+ IN EFI_GUID *DriverGuidArray
+ )
+{
+ UINTN Index;
+ VAR_CHECK_VFR_DRIVER_INFO *VfrDriverInfo;
+
+ for (Index = 0; !IsZeroGuid (&DriverGuidArray[Index]); Index++) {
+ DEBUG ((DEBUG_INFO, "CreateVfrDriverList: %g\n", &DriverGuidArray[Index]));
+ VfrDriverInfo = InternalVarCheckAllocateZeroPool (sizeof (*VfrDriverInfo));
+ ASSERT (VfrDriverInfo != NULL);
+ VfrDriverInfo->Signature = VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE;
+ VfrDriverInfo->DriverGuid = &DriverGuidArray[Index];
+ InsertTailList (&mVfrDriverList, &VfrDriverInfo->Link);
+ }
+}
+
+/**
+ Destroy Vfr Driver List.
+
+**/
+VOID
+DestroyVfrDriverList (
+ VOID
+ )
+{
+ VAR_CHECK_VFR_DRIVER_INFO *VfrDriverInfo;
+ LIST_ENTRY *VfrDriverLink;
+
+ while (mVfrDriverList.ForwardLink != &mVfrDriverList) {
+ VfrDriverLink = mVfrDriverList.ForwardLink;
+ VfrDriverInfo = VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK (VfrDriverLink);
+ RemoveEntryList (&VfrDriverInfo->Link);
+ InternalVarCheckFreePool (VfrDriverInfo);
+ }
+}
+
+/**
+ Generate from FV.
+
+**/
+VOID
+VarCheckHiiGenFromFv (
+ VOID
+ )
+{
+ EFI_GUID *DriverGuidArray;
+ BOOLEAN ScanAll;
+
+ DEBUG ((DEBUG_INFO, "VarCheckHiiGenDxeFromFv\n"));
+
+ //
+ // Get vfr driver guid array from PCD.
+ //
+ DriverGuidArray = (EFI_GUID *)PcdGetPtr (PcdVarCheckVfrDriverGuidArray);
+
+ if (IsZeroGuid (&DriverGuidArray[0])) {
+ //
+ // No VFR driver will be parsed from FVs.
+ //
+ return;
+ }
+
+ if (CompareGuid (&DriverGuidArray[0], &mAllFfGuid)) {
+ ScanAll = TRUE;
+ } else {
+ ScanAll = FALSE;
+ CreateVfrDriverList (DriverGuidArray);
+ }
+
+ ParseFv (ScanAll);
+
+ if (!ScanAll) {
+ DestroyVfrDriverList ();
+ }
+}