text: /** @file
    This file initialises and Installs GopPolicy Protocol.
  
  
    Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
    SPDX-License-Identifier: BSD-2-Clause-Patent
  **/
  
  #include "GopPolicyInitDxe.h"
  #include <Protocol/GopPolicy.h>
  
  GLOBAL_REMOVE_IF_UNREFERENCED GOP_POLICY_PROTOCOL        mGOPPolicy;
  GLOBAL_REMOVE_IF_UNREFERENCED UINT32                     mVbtSize = 0;
  GLOBAL_REMOVE_IF_UNREFERENCED EFI_PHYSICAL_ADDRESS       mVbtAddress = 0;
  
  //
  // Function implementations
  //
  
  /**
  
    @param[out] CurrentLidStatus
  
    @retval     EFI_SUCCESS
    @retval     EFI_UNSUPPORTED
  **/
  
  EFI_STATUS
  EFIAPI
  GetPlatformLidStatus (
    OUT LID_STATUS *CurrentLidStatus
    )
  {
    return EFI_UNSUPPORTED;
  }
  
  /**
  
    @param[out] CurrentDockStatus
  
    @retval     EFI_SUCCESS
    @retval     EFI_UNSUPPORTED
  **/
  EFI_STATUS
  EFIAPI
  GetPlatformDockStatus (
    OUT DOCK_STATUS  CurrentDockStatus
    )
  {
      return EFI_UNSUPPORTED;
  }
  
  
  /**
  
    @param[out] VbtAddress
    @param[out] VbtSize
  
    @retval     EFI_SUCCESS
    @retval     EFI_NOT_FOUND
  **/
  EFI_STATUS
  EFIAPI
  GetVbtData (
    OUT EFI_PHYSICAL_ADDRESS *VbtAddress,
    OUT UINT32               *VbtSize
    )
  {
    EFI_STATUS                    Status;
    UINTN                         FvProtocolCount;
    EFI_HANDLE                    *FvHandles;
    EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
    UINTN                         Index;
    UINT32                        AuthenticationStatus;
    UINT8                         *Buffer;
    UINTN                         VbtBufferSize;
  
    Status = EFI_NOT_FOUND;
    if ( mVbtAddress == 0) {
      Fv           = NULL;
      Buffer       = 0;
      FvHandles    = NULL;
      Status = gBS->LocateHandleBuffer (
                      ByProtocol,
                      &gEfiFirmwareVolume2ProtocolGuid,
                      NULL,
                      &FvProtocolCount,
                      &FvHandles
                      );
      if (!EFI_ERROR (Status)) {
        for (Index = 0; Index < FvProtocolCount; Index++) {
          Status = gBS->HandleProtocol (
                          FvHandles[Index],
                          &gEfiFirmwareVolume2ProtocolGuid,
                          (VOID **) &Fv
                          );
          VbtBufferSize = 0;
          Status = Fv->ReadSection (
                         Fv,
                         PcdGetPtr(PcdIntelGraphicsVbtFileGuid),
                         EFI_SECTION_RAW,
                         0,
                         (VOID **) &Buffer,
                         &VbtBufferSize,
                         &AuthenticationStatus
                         );
          if (!EFI_ERROR (Status)) {
            *VbtAddress = (EFI_PHYSICAL_ADDRESS)Buffer;
            *VbtSize = (UINT32)VbtBufferSize;
            mVbtAddress = *VbtAddress;
            mVbtSize = *VbtSize;
            Status = EFI_SUCCESS;
            break;
          }
        }
      } else {
        Status = EFI_NOT_FOUND;
      }
  
      if (FvHandles != NULL) {
        FreePool (FvHandles);
        FvHandles = NULL;
      }
    } else {
      *VbtAddress = mVbtAddress;
      *VbtSize = mVbtSize;
      Status = EFI_SUCCESS;
    }
  
    return Status;
  }
  
  /**
  Initialize GOP DXE Policy
  
  @param[in] ImageHandle          Image handle of this driver.
  
  @retval EFI_SUCCESS             Initialization complete.
  @retval EFI_UNSUPPORTED         The chipset is unsupported by this driver.
  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver.
  @retval EFI_DEVICE_ERROR        Device error, driver exits abnormally.
  **/
  
  EFI_STATUS
  EFIAPI
  GopPolicyInitDxe (
    IN EFI_HANDLE       ImageHandle
    )
  {
    EFI_STATUS  Status;
  
    //
    // Initialize the EFI Driver Library
    //
    SetMem (&mGOPPolicy, sizeof (GOP_POLICY_PROTOCOL), 0);
  
    mGOPPolicy.Revision                = GOP_POLICY_PROTOCOL_REVISION_03;
    mGOPPolicy.GetPlatformLidStatus    = GetPlatformLidStatus;
    mGOPPolicy.GetVbtData              = GetVbtData;
    mGOPPolicy.GetPlatformDockStatus   = GetPlatformDockStatus;
  
    //
    // Install protocol to allow access to this Policy.
    //
    Status = gBS->InstallMultipleProtocolInterfaces (
                    &ImageHandle,
                    &gGopPolicyProtocolGuid,
                    &mGOPPolicy,
                    NULL
                    );
  
    return Status;
  }
  
  