/** @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;

//
// 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 ((DEBUG_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 ((DEBUG_ERROR, "%a: BlockToConfig(): %r, Progress=\"%s\"\n",
      __FUNCTION__, Status, (Status == EFI_DEVICE_ERROR) ? NULL : *Progress));
  } else {
    DEBUG ((DEBUG_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 ((DEBUG_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 ((DEBUG_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 ((DEBUG_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) ? DEBUG_VERBOSE : DEBUG_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;
}
