REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the MdeModulePkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
		
			
				
	
	
		
			441 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			441 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @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 ();
 | |
|   }
 | |
| }
 |