/** @file
  This driver effectuates OVMF's platform configuration settings and exposes
  them via HII.

  Copyright (C) 2014, Red Hat, Inc.
  Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/HiiLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiHiiServicesLib.h>
#include <Protocol/DevicePath.h>
#include <Protocol/GraphicsOutput.h>
#include <Protocol/HiiConfigAccess.h>
#include <Guid/MdeModuleHii.h>
#include <Guid/OvmfPlatformConfig.h>

#include "Platform.h"
#include "PlatformConfig.h"

//
// The HiiAddPackages() library function requires that any controller (or
// image) handle, to be associated with the HII packages under installation, be
// "decorated" with a device path. The tradition seems to be a vendor device
// path.
//
// We'd like to associate our HII packages with the driver's image handle. The
// first idea is to use the driver image's device path. Unfortunately, loaded
// images only come with an EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL (not the
// usual EFI_DEVICE_PATH_PROTOCOL), ie. a different GUID. In addition, even the
// EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL interface may be NULL, if the image
// has been loaded from an "unnamed" memory source buffer.
//
// Hence let's just stick with the tradition -- use a dedicated vendor device
// path, with the driver's FILE_GUID.
//
#pragma pack(1)
typedef struct {
  VENDOR_DEVICE_PATH          VendorDevicePath;
  EFI_DEVICE_PATH_PROTOCOL    End;
} PKG_DEVICE_PATH;
#pragma pack()

STATIC PKG_DEVICE_PATH  mPkgDevicePath = {
  {
    {
      HARDWARE_DEVICE_PATH,
      HW_VENDOR_DP,
      {
        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
        (UINT8)(sizeof (VENDOR_DEVICE_PATH) >> 8)
      }
    },
    EFI_CALLER_ID_GUID
  },
  {
    END_DEVICE_PATH_TYPE,
    END_ENTIRE_DEVICE_PATH_SUBTYPE,
    {
      (UINT8)(END_DEVICE_PATH_LENGTH),
      (UINT8)(END_DEVICE_PATH_LENGTH >> 8)
    }
  }
};

//
// The configuration interface between the HII engine (form display etc) and
// this driver.
//
STATIC EFI_HII_CONFIG_ACCESS_PROTOCOL  mConfigAccess;

//
// The handle representing our list of packages after installation.
//
STATIC EFI_HII_HANDLE  mInstalledPackages;

//
// The arrays below constitute our HII package list. They are auto-generated by
// the VFR compiler and linked into the driver image during the build.
//
// - The strings package receives its C identifier from the driver's BASE_NAME,
//   plus "Strings".
//
// - The forms package receives its C identifier from the VFR file's basename,
//   plus "Bin".
//
//
extern UINT8  PlatformDxeStrings[];
extern UINT8  PlatformFormsBin[];

//
// We want to be notified about GOP installations until we find one GOP
// interface that lets us populate the form.
//
STATIC EFI_EVENT  mGopEvent;

//
// The registration record underneath this pointer allows us to iterate through
// the GOP instances one by one.
//
STATIC VOID  *mGopTracker;

//
// The driver image handle, used to obtain the device path for <ConfigHdr>.
//
STATIC EFI_HANDLE  mImageHandle;

//
// Cache the resolutions we get from the GOP.
//
typedef struct {
  UINT32    X;
  UINT32    Y;
} GOP_MODE;

STATIC UINTN     mNumGopModes;
STATIC GOP_MODE  *mGopModes;

/**
  Load the persistent platform configuration and translate it to binary form
  state.

  If the platform configuration is missing, then the function fills in a
  default state.

  @param[out] MainFormState  Binary form/widget state after translation.

  @retval EFI_SUCCESS  Form/widget state ready.
  @return              Error codes from underlying functions.
**/
STATIC
EFI_STATUS
EFIAPI
PlatformConfigToFormState (
  OUT MAIN_FORM_STATE  *MainFormState
  )
{
  EFI_STATUS       Status;
  PLATFORM_CONFIG  PlatformConfig;
  UINT64           OptionalElements;
  UINTN            ModeNumber;

  ZeroMem (MainFormState, sizeof *MainFormState);

  Status = PlatformConfigLoad (&PlatformConfig, &OptionalElements);
  switch (Status) {
    case EFI_SUCCESS:
      if (OptionalElements & PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION) {
        //
        // Format the preferred resolution as text.
        //
        UnicodeSPrintAsciiFormat (
          (CHAR16 *)MainFormState->CurrentPreferredResolution,
          sizeof MainFormState->CurrentPreferredResolution,
          "%Ldx%Ld",
          (INT64)PlatformConfig.HorizontalResolution,
          (INT64)PlatformConfig.VerticalResolution
          );

        //
        // Try to locate it in the drop-down list too. This may not succeed, but
        // that's fine.
        //
        for (ModeNumber = 0; ModeNumber < mNumGopModes; ++ModeNumber) {
          if ((mGopModes[ModeNumber].X == PlatformConfig.HorizontalResolution) &&
              (mGopModes[ModeNumber].Y == PlatformConfig.VerticalResolution))
          {
            MainFormState->NextPreferredResolution = (UINT32)ModeNumber;
            break;
          }
        }

        break;
      }

    //
    // fall through otherwise
    //

    case EFI_NOT_FOUND:
      UnicodeSPrintAsciiFormat (
        (CHAR16 *)MainFormState->CurrentPreferredResolution,
        sizeof MainFormState->CurrentPreferredResolution,
        "Unset"
        );
      break;

    default:
      return Status;
  }

  return EFI_SUCCESS;
}

/**
  This function is called by the HII machinery when it fetches the form state.

  See the precise documentation in the UEFI spec.

  @param[in]  This      The Config Access Protocol instance.

  @param[in]  Request   A <ConfigRequest> format UCS-2 string describing the
                        query.

  @param[out] Progress  A pointer into Request on output, identifying the query
                        element where processing failed.

  @param[out] Results   A <MultiConfigAltResp> format UCS-2 string that has
                        all values filled in for the names in the Request
                        string.

  @retval EFI_SUCCESS  Extraction of form state in <MultiConfigAltResp>
                       encoding successful.
  @return              Status codes from underlying functions.

**/
STATIC
EFI_STATUS
EFIAPI
ExtractConfig (
  IN CONST  EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN CONST  EFI_STRING                      Request,
  OUT       EFI_STRING                      *Progress,
  OUT       EFI_STRING                      *Results
  )
{
  MAIN_FORM_STATE  MainFormState;
  EFI_STATUS       Status;
  EFI_STRING       ConfigRequestHdr;
  EFI_STRING       ConfigRequest;
  UINTN            Size;
  BOOLEAN          AllocatedRequest;

  DEBUG ((DEBUG_VERBOSE, "%a: Request=\"%s\"\n", __func__, Request));

  if ((Progress == NULL) || (Results == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  ConfigRequestHdr = NULL;
  ConfigRequest    = NULL;
  Size             = 0;
  AllocatedRequest = FALSE;

  //
  // Check if <ConfigHdr> matches the GUID and name
  //
  *Progress = Request;
  if ((Request != NULL) &&
      !HiiIsConfigHdrMatch (
         Request,
         &gOvmfPlatformConfigGuid,
         mHiiFormName
         )
      )
  {
    return EFI_NOT_FOUND;
  }

  Status = PlatformConfigToFormState (&MainFormState);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
    //
    // Request has no <RequestElement>, so construct full request string.
    // Allocate and fill a buffer large enough to hold <ConfigHdr>
    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a
    // null terminator.
    //
    ConfigRequestHdr = HiiConstructConfigHdr (
                         &gOvmfPlatformConfigGuid,
                         mHiiFormName,
                         mImageHandle
                         );
    if (ConfigRequestHdr == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Size             = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
    ConfigRequest    = AllocateZeroPool (Size);
    AllocatedRequest = TRUE;
    if (ConfigRequest == NULL) {
      FreePool (ConfigRequestHdr);
      return EFI_OUT_OF_RESOURCES;
    }

    UnicodeSPrint (
      ConfigRequest,
      Size,
      L"%s&OFFSET=0&WIDTH=%016LX",
      ConfigRequestHdr,
      sizeof MainFormState
      );
    FreePool (ConfigRequestHdr);
  } else {
    ConfigRequest = Request;
  }

  //
  // Answer the textual request keying off the binary form state.
  //
  Status = gHiiConfigRouting->BlockToConfig (
                                gHiiConfigRouting,
                                ConfigRequest,
                                (VOID *)&MainFormState,
                                sizeof MainFormState,
                                Results,
                                Progress
                                );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: BlockToConfig(): %r, Progress=\"%s\"\n",
      __func__,
      Status,
      (Status == EFI_DEVICE_ERROR) ? NULL : *Progress
      ));
  } else {
    DEBUG ((DEBUG_VERBOSE, "%a: Results=\"%s\"\n", __func__, *Results));
  }

  //
  // If we used a newly allocated ConfigRequest, update Progress to point to
  // original Request instead of ConfigRequest.
  //
  if (Request == NULL) {
    *Progress = NULL;
  } else if (StrStr (Request, L"OFFSET") == NULL) {
    if (EFI_ERROR (Status)) {
      //
      // Since we constructed ConfigRequest, failure can only occur if there
      // is not enough memory. In this case, we point Progress to the first
      // character of Request.
      //
      *Progress = Request;
    } else {
      //
      // In case of success, we point Progress to the null terminator of
      // Request.
      //
      *Progress = Request + StrLen (Request);
    }
  }

  if (AllocatedRequest) {
    FreePool (ConfigRequest);
  }

  return Status;
}

/**
  Interpret the binary form state and save it as persistent platform
  configuration.

  @param[in] MainFormState  Binary form/widget state to verify and save.

  @retval EFI_SUCCESS  Platform configuration saved.
  @return              Error codes from underlying functions.
**/
STATIC
EFI_STATUS
EFIAPI
FormStateToPlatformConfig (
  IN CONST MAIN_FORM_STATE  *MainFormState
  )
{
  EFI_STATUS       Status;
  PLATFORM_CONFIG  PlatformConfig;
  CONST GOP_MODE   *GopMode;

  //
  // There's nothing to do with the textual CurrentPreferredResolution field.
  // We verify and translate the selection in the drop-down list.
  //
  if (MainFormState->NextPreferredResolution >= mNumGopModes) {
    return EFI_INVALID_PARAMETER;
  }

  GopMode = mGopModes + MainFormState->NextPreferredResolution;

  ZeroMem (&PlatformConfig, sizeof PlatformConfig);
  PlatformConfig.HorizontalResolution = GopMode->X;
  PlatformConfig.VerticalResolution   = GopMode->Y;

  Status = PlatformConfigSave (&PlatformConfig);
  return Status;
}

/**
  This function is called by the HII machinery when it wants the driver to
  interpret and persist the form state.

  See the precise documentation in the UEFI spec.

  @param[in]  This           The Config Access Protocol instance.

  @param[in]  Configuration  A <ConfigResp> format UCS-2 string describing the
                             form state.

  @param[out] Progress       A pointer into Configuration on output,
                             identifying the element where processing failed.

  @retval EFI_SUCCESS  Configuration verified, state permanent.

  @return              Status codes from underlying functions.
**/
STATIC
EFI_STATUS
EFIAPI
RouteConfig (
  IN CONST  EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN CONST  EFI_STRING                      Configuration,
  OUT       EFI_STRING                      *Progress
  )
{
  MAIN_FORM_STATE  MainFormState;
  UINTN            BlockSize;
  EFI_STATUS       Status;

  DEBUG ((
    DEBUG_VERBOSE,
    "%a: Configuration=\"%s\"\n",
    __func__,
    Configuration
    ));

  if ((Progress == NULL) || (Configuration == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check if <ConfigHdr> matches the GUID and name
  //
  *Progress = Configuration;
  if ((Configuration != NULL) &&
      !HiiIsConfigHdrMatch (
         Configuration,
         &gOvmfPlatformConfigGuid,
         mHiiFormName
         )
      )
  {
    return EFI_NOT_FOUND;
  }

  //
  // the "read" step in RMW
  //
  Status = PlatformConfigToFormState (&MainFormState);
  if (EFI_ERROR (Status)) {
    *Progress = Configuration;
    return Status;
  }

  //
  // the "modify" step in RMW
  //
  // (Update the binary form state. This update may be partial, which is why in
  // general we must pre-load the form state from the platform config.)
  //
  BlockSize = sizeof MainFormState;
  Status    = gHiiConfigRouting->ConfigToBlock (
                                   gHiiConfigRouting,
                                   Configuration,
                                   (VOID *)&MainFormState,
                                   &BlockSize,
                                   Progress
                                   );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: ConfigToBlock(): %r, Progress=\"%s\"\n",
      __func__,
      Status,
      (Status == EFI_BUFFER_TOO_SMALL) ? NULL : *Progress
      ));
    return Status;
  }

  //
  // the "write" step in RMW
  //
  Status = FormStateToPlatformConfig (&MainFormState);
  if (EFI_ERROR (Status)) {
    *Progress = Configuration;
  }

  return Status;
}

STATIC
EFI_STATUS
EFIAPI
Callback (
  IN     CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN     EFI_BROWSER_ACTION                    Action,
  IN     EFI_QUESTION_ID                       QuestionId,
  IN     UINT8                                 Type,
  IN OUT EFI_IFR_TYPE_VALUE                    *Value,
  OUT    EFI_BROWSER_ACTION_REQUEST            *ActionRequest
  )
{
  DEBUG ((
    DEBUG_VERBOSE,
    "%a: Action=0x%Lx QuestionId=%d Type=%d\n",
    __func__,
    (UINT64)Action,
    QuestionId,
    Type
    ));

  if (Action != EFI_BROWSER_ACTION_CHANGED) {
    return EFI_UNSUPPORTED;
  }

  switch (QuestionId) {
    case QUESTION_SAVE_EXIT:
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
      break;

    case QUESTION_DISCARD_EXIT:
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
      break;

    default:
      break;
  }

  return EFI_SUCCESS;
}

/**
  Query and save all resolutions supported by the GOP.

  @param[in]  Gop          The Graphics Output Protocol instance to query.

  @param[out] NumGopModes  The number of modes supported by the GOP. On output,
                           this parameter will be positive.

  @param[out] GopModes     On output, a dynamically allocated array containing
                           the resolutions returned by the GOP. The caller is
                           responsible for freeing the array after use.

  @retval EFI_UNSUPPORTED       No modes found.
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate GopModes.
  @return                       Error codes from Gop->QueryMode().

**/
STATIC
EFI_STATUS
EFIAPI
QueryGopModes (
  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL  *Gop,
  OUT UINTN                         *NumGopModes,
  OUT GOP_MODE                      **GopModes
  )
{
  EFI_STATUS  Status;
  UINT32      ModeNumber;

  if (Gop->Mode->MaxMode == 0) {
    return EFI_UNSUPPORTED;
  }

  *NumGopModes = Gop->Mode->MaxMode;

  *GopModes = AllocatePool (Gop->Mode->MaxMode * sizeof **GopModes);
  if (*GopModes == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  for (ModeNumber = 0; ModeNumber < Gop->Mode->MaxMode; ++ModeNumber) {
    EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info;
    UINTN                                 SizeOfInfo;

    Status = Gop->QueryMode (Gop, ModeNumber, &SizeOfInfo, &Info);
    if (EFI_ERROR (Status)) {
      goto FreeGopModes;
    }

    (*GopModes)[ModeNumber].X = Info->HorizontalResolution;
    (*GopModes)[ModeNumber].Y = Info->VerticalResolution;
    FreePool (Info);
  }

  return EFI_SUCCESS;

FreeGopModes:
  FreePool (*GopModes);

  return Status;
}

/**
  Create a set of "one-of-many" (ie. "drop down list") option IFR opcodes,
  based on available GOP resolutions, to be placed under a "one-of-many" (ie.
  "drop down list") opcode.

  @param[in]  PackageList   The package list with the formset and form for
                            which the drop down options are produced. Option
                            names are added as new strings to PackageList.

  @param[out] OpCodeBuffer  On output, a dynamically allocated opcode buffer
                            with drop down list options corresponding to GOP
                            resolutions. The caller is responsible for freeing
                            OpCodeBuffer with HiiFreeOpCodeHandle() after use.

  @param[in]  NumGopModes   Number of entries in GopModes.

  @param[in]  GopModes      Array of resolutions retrieved from the GOP.

  @retval EFI_SUCESS  Opcodes have been successfully produced.

  @return             Status codes from underlying functions. PackageList may
                      have been extended with new strings. OpCodeBuffer is
                      unchanged.
**/
STATIC
EFI_STATUS
EFIAPI
CreateResolutionOptions (
  IN  EFI_HII_HANDLE  PackageList,
  OUT VOID            **OpCodeBuffer,
  IN  UINTN           NumGopModes,
  IN  GOP_MODE        *GopModes
  )
{
  EFI_STATUS  Status;
  VOID        *OutputBuffer;
  UINTN       ModeNumber;

  OutputBuffer = HiiAllocateOpCodeHandle ();
  if (OutputBuffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  for (ModeNumber = 0; ModeNumber < NumGopModes; ++ModeNumber) {
    CHAR16         Desc[MAXSIZE_RES_CUR];
    EFI_STRING_ID  NewString;
    VOID           *OpCode;

    UnicodeSPrintAsciiFormat (
      Desc,
      sizeof Desc,
      "%Ldx%Ld",
      (INT64)GopModes[ModeNumber].X,
      (INT64)GopModes[ModeNumber].Y
      );
    NewString = HiiSetString (
                  PackageList,
                  0 /* new string */,
                  Desc,
                  NULL /* for all languages */
                  );
    if (NewString == 0) {
      Status = EFI_OUT_OF_RESOURCES;
      goto FreeOutputBuffer;
    }

    OpCode = HiiCreateOneOfOptionOpCode (
               OutputBuffer,
               NewString,
               0 /* Flags */,
               EFI_IFR_NUMERIC_SIZE_4,
               ModeNumber
               );
    if (OpCode == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto FreeOutputBuffer;
    }
  }

  *OpCodeBuffer = OutputBuffer;
  return EFI_SUCCESS;

FreeOutputBuffer:
  HiiFreeOpCodeHandle (OutputBuffer);

  return Status;
}

/**
  Populate the form identified by the (PackageList, FormSetGuid, FormId)
  triplet.

  The drop down list of video resolutions is generated from (NumGopModes,
  GopModes).

  @retval EFI_SUCESS  Form successfully updated.
  @return             Status codes from underlying functions.

**/
STATIC
EFI_STATUS
EFIAPI
PopulateForm (
  IN  EFI_HII_HANDLE  PackageList,
  IN  EFI_GUID        *FormSetGuid,
  IN  EFI_FORM_ID     FormId,
  IN  UINTN           NumGopModes,
  IN  GOP_MODE        *GopModes
  )
{
  EFI_STATUS          Status;
  VOID                *OpCodeBuffer;
  VOID                *OpCode;
  EFI_IFR_GUID_LABEL  *Anchor;
  VOID                *OpCodeBuffer2;

  OpCodeBuffer2 = NULL;

  //
  // 1. Allocate an empty opcode buffer.
  //
  OpCodeBuffer = HiiAllocateOpCodeHandle ();
  if (OpCodeBuffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // 2. Create a label opcode (which is a Tiano extension) inside the buffer.
  // The label's number must match the "anchor" label in the form.
  //
  OpCode = HiiCreateGuidOpCode (
             OpCodeBuffer,
             &gEfiIfrTianoGuid,
             NULL /* optional copy origin */,
             sizeof *Anchor
             );
  if (OpCode == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto FreeOpCodeBuffer;
  }

  Anchor               = OpCode;
  Anchor->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  Anchor->Number       = LABEL_RES_NEXT;

  //
  // 3. Create the opcodes inside the buffer that are to be inserted into the
  // form.
  //
  // 3.1. Get a list of resolutions.
  //
  Status = CreateResolutionOptions (
             PackageList,
             &OpCodeBuffer2,
             NumGopModes,
             GopModes
             );
  if (EFI_ERROR (Status)) {
    goto FreeOpCodeBuffer;
  }

  //
  // 3.2. Create a one-of-many question with the above options.
  //
  OpCode = HiiCreateOneOfOpCode (
             OpCodeBuffer,                        // create opcode inside this
                                                  //   opcode buffer,
             QUESTION_RES_NEXT,                   // ID of question,
             FORMSTATEID_MAIN_FORM,               // identifies form state
                                                  //   storage,
             (UINT16)OFFSET_OF (
                       MAIN_FORM_STATE,           // value of question stored
                       NextPreferredResolution
                       ),                         //   at this offset,
             STRING_TOKEN (STR_RES_NEXT),         // Prompt,
             STRING_TOKEN (STR_RES_NEXT_HELP),    // Help,
             0,                                   // QuestionFlags,
             EFI_IFR_NUMERIC_SIZE_4,              // see sizeof
                                                  //   NextPreferredResolution,
             OpCodeBuffer2,                       // buffer with possible
                                                  //   choices,
             NULL                                 // DEFAULT opcodes
             );
  if (OpCode == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto FreeOpCodeBuffer2;
  }

  //
  // 4. Update the form with the opcode buffer.
  //
  Status = HiiUpdateForm (
             PackageList,
             FormSetGuid,
             FormId,
             OpCodeBuffer, // buffer with head anchor, and new contents to be
                           // inserted at it
             NULL          // buffer with tail anchor, for deleting old
                           // contents up to it
             );

FreeOpCodeBuffer2:
  HiiFreeOpCodeHandle (OpCodeBuffer2);

FreeOpCodeBuffer:
  HiiFreeOpCodeHandle (OpCodeBuffer);

  return Status;
}

/**
  Load and execute the platform configuration.

  @retval EFI_SUCCESS            Configuration loaded and executed.
  @return                        Status codes from PlatformConfigLoad().
**/
STATIC
EFI_STATUS
EFIAPI
ExecutePlatformConfig (
  VOID
  )
{
  EFI_STATUS       Status;
  PLATFORM_CONFIG  PlatformConfig;
  UINT64           OptionalElements;
  RETURN_STATUS    PcdStatus;

  Status = PlatformConfigLoad (&PlatformConfig, &OptionalElements);
  if (EFI_ERROR (Status)) {
    DEBUG ((
      (Status == EFI_NOT_FOUND) ? DEBUG_VERBOSE : DEBUG_ERROR,
      "%a: failed to load platform config: %r\n",
      __func__,
      Status
      ));
    return Status;
  }

  if (OptionalElements & PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION) {
    //
    // Pass the preferred resolution to GraphicsConsoleDxe via dynamic PCDs.
    //
    PcdStatus = PcdSet32S (
                  PcdVideoHorizontalResolution,
                  PlatformConfig.HorizontalResolution
                  );
    ASSERT_RETURN_ERROR (PcdStatus);

    PcdStatus = PcdSet32S (
                  PcdVideoVerticalResolution,
                  PlatformConfig.VerticalResolution
                  );
    ASSERT_RETURN_ERROR (PcdStatus);

    PcdStatus = PcdSet8S (PcdVideoResolutionSource, 1);
    ASSERT_RETURN_ERROR (PcdStatus);
  }

  return EFI_SUCCESS;
}

/**
  Notification callback for GOP interface installation.

  @param[in] Event    Event whose notification function is being invoked.

  @param[in] Context  The pointer to the notification function's context, which
                      is implementation-dependent.
**/
STATIC
VOID
EFIAPI
GopInstalled (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  EFI_STATUS                    Status;
  EFI_GRAPHICS_OUTPUT_PROTOCOL  *Gop;

  ASSERT (Event == mGopEvent);

  //
  // Check further GOPs.
  //
  for ( ; ;) {
    mNumGopModes = 0;
    mGopModes    = NULL;

    Status = gBS->LocateProtocol (
                    &gEfiGraphicsOutputProtocolGuid,
                    mGopTracker,
                    (VOID **)&Gop
                    );
    if (EFI_ERROR (Status)) {
      return;
    }

    Status = QueryGopModes (Gop, &mNumGopModes, &mGopModes);
    if (EFI_ERROR (Status)) {
      continue;
    }

    Status = PopulateForm (
               mInstalledPackages,
               &gOvmfPlatformConfigGuid,
               FORMID_MAIN_FORM,
               mNumGopModes,
               mGopModes
               );
    if (EFI_ERROR (Status)) {
      FreePool (mGopModes);
      continue;
    }

    break;
  }

  //
  // Success -- so uninstall this callback. Closing the event removes all
  // pending notifications and all protocol registrations.
  //
  Status = gBS->CloseEvent (mGopEvent);
  ASSERT_EFI_ERROR (Status);
  mGopEvent   = NULL;
  mGopTracker = NULL;
}

/**
  Entry point for this driver.

  @param[in] ImageHandle  Image handle of this driver.
  @param[in] SystemTable  Pointer to SystemTable.

  @retval EFI_SUCESS            Driver has loaded successfully.
  @retval EFI_OUT_OF_RESOURCES  Failed to install HII packages.
  @return                       Error codes from lower level functions.

**/
EFI_STATUS
EFIAPI
PlatformInit (
  IN  EFI_HANDLE        ImageHandle,
  IN  EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  ExecutePlatformConfig ();

  mConfigAccess.ExtractConfig = &ExtractConfig;
  mConfigAccess.RouteConfig   = &RouteConfig;
  mConfigAccess.Callback      = &Callback;

  //
  // Declare ourselves suitable for HII communication.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &ImageHandle,
                  &gEfiDevicePathProtocolGuid,
                  &mPkgDevicePath,
                  &gEfiHiiConfigAccessProtocolGuid,
                  &mConfigAccess,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Save the driver image handle.
  //
  mImageHandle = ImageHandle;

  //
  // Publish the HII package list to HII Database.
  //
  mInstalledPackages = HiiAddPackages (
                         &gEfiCallerIdGuid,  // PackageListGuid
                         ImageHandle,        // associated DeviceHandle
                         PlatformDxeStrings, // 1st package
                         PlatformFormsBin,   // 2nd package
                         NULL                // terminator
                         );
  if (mInstalledPackages == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto UninstallProtocols;
  }

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  &GopInstalled,
                  NULL /* Context */,
                  &mGopEvent
                  );
  if (EFI_ERROR (Status)) {
    goto RemovePackages;
  }

  Status = gBS->RegisterProtocolNotify (
                  &gEfiGraphicsOutputProtocolGuid,
                  mGopEvent,
                  &mGopTracker
                  );
  if (EFI_ERROR (Status)) {
    goto CloseGopEvent;
  }

  //
  // Check already installed GOPs.
  //
  Status = gBS->SignalEvent (mGopEvent);
  ASSERT_EFI_ERROR (Status);

  return EFI_SUCCESS;

CloseGopEvent:
  gBS->CloseEvent (mGopEvent);

RemovePackages:
  HiiRemovePackages (mInstalledPackages);

UninstallProtocols:
  gBS->UninstallMultipleProtocolInterfaces (
         ImageHandle,
         &gEfiDevicePathProtocolGuid,
         &mPkgDevicePath,
         &gEfiHiiConfigAccessProtocolGuid,
         &mConfigAccess,
         NULL
         );
  return Status;
}

/**
  Unload the driver.

  @param[in]  ImageHandle  Handle that identifies the image to evict.

  @retval EFI_SUCCESS  The image has been unloaded.
**/
EFI_STATUS
EFIAPI
PlatformUnload (
  IN  EFI_HANDLE  ImageHandle
  )
{
  if (mGopEvent == NULL) {
    //
    // The GOP callback ran successfully and unregistered itself. Release the
    // resources allocated there.
    //
    ASSERT (mGopModes != NULL);
    FreePool (mGopModes);
  } else {
    //
    // Otherwise we need to unregister the callback.
    //
    ASSERT (mGopModes == NULL);
    gBS->CloseEvent (mGopEvent);
  }

  //
  // Release resources allocated by the entry point.
  //
  HiiRemovePackages (mInstalledPackages);
  gBS->UninstallMultipleProtocolInterfaces (
         ImageHandle,
         &gEfiDevicePathProtocolGuid,
         &mPkgDevicePath,
         &gEfiHiiConfigAccessProtocolGuid,
         &mConfigAccess,
         NULL
         );
  return EFI_SUCCESS;
}
