/** @file
  Var Check Hii generation from FV.

Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#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 (
      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));
      }
    );

    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 ();
  }
}
