/** @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>

  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 <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;

//
// 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;

  DEBUG ((EFI_D_VERBOSE, "%a: Request=\"%s\"\n", __FUNCTION__, Request));

  Status = PlatformConfigToFormState (&MainFormState);
  if (EFI_ERROR (Status)) {
    *Progress = Request;
    return Status;
  }

  //
  // Answer the textual request keying off the binary form state.
  //
  Status = gHiiConfigRouting->BlockToConfig (gHiiConfigRouting, Request,
                                (VOID *) &MainFormState, sizeof MainFormState,
                                Results, Progress);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "%a: BlockToConfig(): %r, Progress=\"%s\"\n",
      __FUNCTION__, Status, (Status == EFI_DEVICE_ERROR) ? NULL : *Progress));
  } else {
    DEBUG ((EFI_D_VERBOSE, "%a: Results=\"%s\"\n", __FUNCTION__, *Results));
  }
  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 ((EFI_D_VERBOSE, "%a: Configuration=\"%s\"\n", __FUNCTION__,
    Configuration));

  //
  // 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 ((EFI_D_ERROR, "%a: ConfigToBlock(): %r, Progress=\"%s\"\n",
      __FUNCTION__, 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 ((EFI_D_VERBOSE, "%a: Action=0x%Lx QuestionId=%d Type=%d\n",
    __FUNCTION__, (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) ? EFI_D_VERBOSE : EFI_D_ERROR,
      "%a: failed to load platform config: %r\n", __FUNCTION__, 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);
  }

  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;
  }

  //
  // 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;
}
