/** @file

  Implement the Driver Binding Protocol and the Component Name 2 Protocol for
  the Virtio GPU hybrid driver.

  Copyright (C) 2016, Red Hat, Inc.

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Protocol/ComponentName2.h>
#include <Protocol/DevicePath.h>
#include <Protocol/DriverBinding.h>
#include <Protocol/PciIo.h>

#include "VirtioGpu.h"

//
// The device path node that describes the Video Output Device Attributes for
// the single head (UEFI child handle) that we support.
//
// The ACPI_DISPLAY_ADR() macro corresponds to Table B-2, section "B.4.2 _DOD"
// in the ACPI 3.0b spec, or more recently, to Table B-379, section "B.3.2
// _DOD" in the ACPI 6.0 spec.
//
STATIC CONST ACPI_ADR_DEVICE_PATH mAcpiAdr = {
  {                                         // Header
    ACPI_DEVICE_PATH,                       //   Type
    ACPI_ADR_DP,                            //   SubType
    { sizeof mAcpiAdr, 0 },                 //   Length
  },
  ACPI_DISPLAY_ADR (                        // ADR
    1,                                      //   DeviceIdScheme: use the ACPI
                                            //     bit-field definitions
    0,                                      //   HeadId
    0,                                      //   NonVgaOutput
    1,                                      //   BiosCanDetect
    0,                                      //   VendorInfo
    ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, //   Type
    0,                                      //   Port
    0                                       //   Index
    )
};

//
// Component Name 2 Protocol implementation.
//
STATIC CONST EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {
  { "en", L"Virtio GPU Driver" },
  { NULL, NULL                 }
};

STATIC
EFI_STATUS
EFIAPI
VirtioGpuGetDriverName (
  IN  EFI_COMPONENT_NAME2_PROTOCOL *This,
  IN  CHAR8                        *Language,
  OUT CHAR16                       **DriverName
  )
{
  return LookupUnicodeString2 (Language, This->SupportedLanguages,
           mDriverNameTable, DriverName, FALSE /* Iso639Language */);
}

STATIC
EFI_STATUS
EFIAPI
VirtioGpuGetControllerName (
  IN  EFI_COMPONENT_NAME2_PROTOCOL *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  EFI_HANDLE                   ChildHandle       OPTIONAL,
  IN  CHAR8                        *Language,
  OUT CHAR16                       **ControllerName
  )
{
  EFI_STATUS Status;
  VGPU_DEV   *VgpuDev;

  //
  // Look up the VGPU_DEV "protocol interface" on ControllerHandle.
  //
  Status = gBS->OpenProtocol (ControllerHandle, &gEfiCallerIdGuid,
                  (VOID **)&VgpuDev, gImageHandle, ControllerHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Sanity check: if we found gEfiCallerIdGuid on ControllerHandle, then we
  // keep its Virtio Device Protocol interface open BY_DRIVER.
  //
  ASSERT_EFI_ERROR (EfiTestManagedDevice (ControllerHandle, gImageHandle,
                      &gVirtioDeviceProtocolGuid));

  if (ChildHandle == NULL) {
    //
    // The caller is querying the name of the VGPU_DEV controller.
    //
    return LookupUnicodeString2 (Language, This->SupportedLanguages,
             VgpuDev->BusName, ControllerName, FALSE /* Iso639Language */);
  }

  //
  // Otherwise, the caller is looking for the name of the GOP child controller.
  // Check if it is asking about the GOP child controller that we manage. (The
  // condition below covers the case when we haven't produced the GOP child
  // controller yet, or we've destroyed it since.)
  //
  if (VgpuDev->Child == NULL || ChildHandle != VgpuDev->Child->GopHandle) {
    return EFI_UNSUPPORTED;
  }
  //
  // Sanity check: our GOP child controller keeps the VGPU_DEV controller's
  // Virtio Device Protocol interface open BY_CHILD_CONTROLLER.
  //
  ASSERT_EFI_ERROR (EfiTestChildHandle (ControllerHandle, ChildHandle,
                      &gVirtioDeviceProtocolGuid));

  return LookupUnicodeString2 (Language, This->SupportedLanguages,
           VgpuDev->Child->GopName, ControllerName,
           FALSE /* Iso639Language */);
}

STATIC CONST EFI_COMPONENT_NAME2_PROTOCOL mComponentName2 = {
  VirtioGpuGetDriverName,
  VirtioGpuGetControllerName,
  "en"                       // SupportedLanguages (RFC 4646)
};

//
// Helper functions for the Driver Binding Protocol Implementation.
//
/**
  Format the VGPU_DEV controller name, to be looked up and returned by
  VirtioGpuGetControllerName().

  @param[in] ControllerHandle  The handle that identifies the VGPU_DEV
                               controller.

  @param[in] AgentHandle       The handle of the agent that will attempt to
                               temporarily open the PciIo protocol. This is the
                               DriverBindingHandle member of the
                               EFI_DRIVER_BINDING_PROTOCOL whose Start()
                               function is calling this function.

  @param[in] DevicePath        The device path that is installed on
                               ControllerHandle.

  @param[out] ControllerName   A dynamically allocated unicode string that
                               unconditionally says "Virtio GPU Device", with a
                               PCI Segment:Bus:Device.Function location
                               optionally appended. The latter part is only
                               produced if DevicePath contains at least one
                               PciIo node; in that case, the most specific such
                               node is used for retrieving the location info.
                               The caller is responsible for freeing
                               ControllerName after use.

  @retval EFI_SUCCESS           ControllerName has been formatted.

  @retval EFI_OUT_OF_RESOURCES  Failed to allocate memory for ControllerName.
**/
STATIC
EFI_STATUS
FormatVgpuDevName (
  IN  EFI_HANDLE               ControllerHandle,
  IN  EFI_HANDLE               AgentHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL *DevicePath,
  OUT CHAR16                   **ControllerName
  )
{
  EFI_HANDLE          PciIoHandle;
  EFI_PCI_IO_PROTOCOL *PciIo;
  UINTN               Segment, Bus, Device, Function;
  STATIC CONST CHAR16 ControllerNameStem[] = L"Virtio GPU Device";
  UINTN               ControllerNameSize;

  if (EFI_ERROR (gBS->LocateDevicePath (&gEfiPciIoProtocolGuid, &DevicePath,
                        &PciIoHandle)) ||
      EFI_ERROR (gBS->OpenProtocol (PciIoHandle, &gEfiPciIoProtocolGuid,
                        (VOID **)&PciIo, AgentHandle, ControllerHandle,
                        EFI_OPEN_PROTOCOL_GET_PROTOCOL)) ||
      EFI_ERROR (PciIo->GetLocation (PciIo, &Segment, &Bus, &Device,
                          &Function))) {
    //
    // Failed to retrieve location info, return verbatim copy of static string.
    //
    *ControllerName = AllocateCopyPool (sizeof ControllerNameStem,
                        ControllerNameStem);
    return (*ControllerName == NULL) ? EFI_OUT_OF_RESOURCES : EFI_SUCCESS;
  }
  //
  // Location info available, format ControllerName dynamically.
  //
  ControllerNameSize = sizeof ControllerNameStem + // includes L'\0'
                       sizeof (CHAR16) * (1 + 4 +  // Segment
                                          1 + 2 +  // Bus
                                          1 + 2 +  // Device
                                          1 + 1    // Function
                                          );
  *ControllerName = AllocatePool (ControllerNameSize);
  if (*ControllerName == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  UnicodeSPrintAsciiFormat (*ControllerName, ControllerNameSize,
    "%s %04x:%02x:%02x.%x", ControllerNameStem, (UINT32)Segment, (UINT32)Bus,
    (UINT32)Device, (UINT32)Function);
  return EFI_SUCCESS;
}

/**
  Dynamically allocate and initialize the VGPU_GOP child object within an
  otherwise configured parent VGPU_DEV object.

  This function adds a BY_CHILD_CONTROLLER reference to ParentBusController's
  VIRTIO_DEVICE_PROTOCOL interface.

  @param[in,out] ParentBus        The pre-initialized VGPU_DEV object that the
                                  newly created VGPU_GOP object will be the
                                  child of.

  @param[in] ParentDevicePath     The device path protocol instance that is
                                  installed on ParentBusController.

  @param[in] ParentBusController  The UEFI controller handle on which the
                                  ParentBus VGPU_DEV object and the
                                  ParentDevicePath device path protocol are
                                  installed.

  @param[in] DriverBindingHandle  The DriverBindingHandle member of
                                  EFI_DRIVER_BINDING_PROTOCOL whose Start()
                                  function is calling this function. It is
                                  passed as AgentHandle to gBS->OpenProtocol()
                                  when creating the BY_CHILD_CONTROLLER
                                  reference.

  @retval EFI_SUCCESS           ParentBus->Child has been created and
                                populated, and ParentBus->Child->GopHandle now
                                references ParentBusController->VirtIo
                                BY_CHILD_CONTROLLER.

  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.

  @return                       Error codes from underlying functions.
**/
STATIC
EFI_STATUS
InitVgpuGop (
  IN OUT VGPU_DEV                 *ParentBus,
  IN     EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
  IN     EFI_HANDLE               ParentBusController,
  IN     EFI_HANDLE               DriverBindingHandle
  )
{
  VGPU_GOP            *VgpuGop;
  EFI_STATUS          Status;
  CHAR16              *ParentBusName;
  STATIC CONST CHAR16 NameSuffix[] = L" Head #0";
  UINTN               NameSize;
  CHAR16              *Name;
  EFI_TPL             OldTpl;
  VOID                *ParentVirtIo;

  VgpuGop = AllocateZeroPool (sizeof *VgpuGop);
  if (VgpuGop == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  VgpuGop->Signature = VGPU_GOP_SIG;
  VgpuGop->ParentBus = ParentBus;

  //
  // Format a human-readable controller name for VGPU_GOP, and stash it for
  // VirtioGpuGetControllerName() to look up. We simply append NameSuffix to
  // ParentBus->BusName.
  //
  Status = LookupUnicodeString2 ("en", mComponentName2.SupportedLanguages,
             ParentBus->BusName, &ParentBusName, FALSE /* Iso639Language */);
  ASSERT_EFI_ERROR (Status);
  NameSize = StrSize (ParentBusName) - sizeof (CHAR16) + sizeof NameSuffix;
  Name = AllocatePool (NameSize);
  if (Name == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto FreeVgpuGop;
  }
  UnicodeSPrintAsciiFormat (Name, NameSize, "%s%s", ParentBusName, NameSuffix);
  Status = AddUnicodeString2 ("en", mComponentName2.SupportedLanguages,
             &VgpuGop->GopName, Name, FALSE /* Iso639Language */);
  FreePool (Name);
  if (EFI_ERROR (Status)) {
    goto FreeVgpuGop;
  }

  //
  // Create the child device path.
  //
  VgpuGop->GopDevicePath = AppendDevicePathNode (ParentDevicePath,
                             &mAcpiAdr.Header);
  if (VgpuGop->GopDevicePath == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto FreeVgpuGopName;
  }

  //
  // Mask protocol notify callbacks until we're done.
  //
  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  //
  // Create the child handle with the child device path.
  //
  Status = gBS->InstallProtocolInterface (&VgpuGop->GopHandle,
                  &gEfiDevicePathProtocolGuid, EFI_NATIVE_INTERFACE,
                  VgpuGop->GopDevicePath);
  if (EFI_ERROR (Status)) {
    goto FreeDevicePath;
  }

  //
  // The child handle must present a reference to the parent handle's Virtio
  // Device Protocol interface.
  //
  Status = gBS->OpenProtocol (ParentBusController, &gVirtioDeviceProtocolGuid,
                  &ParentVirtIo, DriverBindingHandle, VgpuGop->GopHandle,
                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER);
  if (EFI_ERROR (Status)) {
    goto UninstallDevicePath;
  }
  ASSERT (ParentVirtIo == ParentBus->VirtIo);

  //
  // Initialize our Graphics Output Protocol.
  //
  // Fill in the function members of VgpuGop->Gop from the template, then set
  // up the rest of the GOP infrastructure by calling SetMode() right now.
  //
  CopyMem (&VgpuGop->Gop, &mGopTemplate, sizeof mGopTemplate);
  Status = VgpuGop->Gop.SetMode (&VgpuGop->Gop, 0);
  if (EFI_ERROR (Status)) {
    goto CloseVirtIoByChild;
  }

  //
  // Install the Graphics Output Protocol on the child handle.
  //
  Status = gBS->InstallProtocolInterface (&VgpuGop->GopHandle,
                  &gEfiGraphicsOutputProtocolGuid, EFI_NATIVE_INTERFACE,
                  &VgpuGop->Gop);
  if (EFI_ERROR (Status)) {
    goto UninitGop;
  }

  //
  // We're done.
  //
  gBS->RestoreTPL (OldTpl);
  ParentBus->Child = VgpuGop;
  return EFI_SUCCESS;

UninitGop:
  ReleaseGopResources (VgpuGop, TRUE /* DisableHead */);

CloseVirtIoByChild:
  gBS->CloseProtocol (ParentBusController, &gVirtioDeviceProtocolGuid,
    DriverBindingHandle, VgpuGop->GopHandle);

UninstallDevicePath:
  gBS->UninstallProtocolInterface (VgpuGop->GopHandle,
         &gEfiDevicePathProtocolGuid, VgpuGop->GopDevicePath);

FreeDevicePath:
  gBS->RestoreTPL (OldTpl);
  FreePool (VgpuGop->GopDevicePath);

FreeVgpuGopName:
  FreeUnicodeStringTable (VgpuGop->GopName);

FreeVgpuGop:
  FreePool (VgpuGop);

  return Status;
}

/**
  Tear down and release the VGPU_GOP child object within the VGPU_DEV parent
  object.

  This function removes the BY_CHILD_CONTROLLER reference from
  ParentBusController's VIRTIO_DEVICE_PROTOCOL interface.

  @param[in,out] ParentBus        The VGPU_DEV object that the VGPU_GOP child
                                  object will be removed from.

  @param[in] ParentBusController  The UEFI controller handle on which the
                                  ParentBus VGPU_DEV object is installed.

  @param[in] DriverBindingHandle  The DriverBindingHandle member of
                                  EFI_DRIVER_BINDING_PROTOCOL whose Stop()
                                  function is calling this function. It is
                                  passed as AgentHandle to gBS->CloseProtocol()
                                  when removing the BY_CHILD_CONTROLLER
                                  reference.
**/
STATIC
VOID
UninitVgpuGop (
  IN OUT VGPU_DEV   *ParentBus,
  IN     EFI_HANDLE ParentBusController,
  IN     EFI_HANDLE DriverBindingHandle
  )
{
  VGPU_GOP   *VgpuGop;
  EFI_STATUS Status;

  VgpuGop = ParentBus->Child;
  Status = gBS->UninstallProtocolInterface (VgpuGop->GopHandle,
                  &gEfiGraphicsOutputProtocolGuid, &VgpuGop->Gop);
  ASSERT_EFI_ERROR (Status);

  //
  // Uninitialize VgpuGop->Gop.
  //
  ReleaseGopResources (VgpuGop, TRUE /* DisableHead */);

  Status = gBS->CloseProtocol (ParentBusController, &gVirtioDeviceProtocolGuid,
                  DriverBindingHandle, VgpuGop->GopHandle);
  ASSERT_EFI_ERROR (Status);

  Status = gBS->UninstallProtocolInterface (VgpuGop->GopHandle,
                  &gEfiDevicePathProtocolGuid, VgpuGop->GopDevicePath);
  ASSERT_EFI_ERROR (Status);

  FreePool (VgpuGop->GopDevicePath);
  FreeUnicodeStringTable (VgpuGop->GopName);
  FreePool (VgpuGop);

  ParentBus->Child = NULL;
}

//
// Driver Binding Protocol Implementation.
//
STATIC
EFI_STATUS
EFIAPI
VirtioGpuDriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL *This,
  IN EFI_HANDLE                  ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath OPTIONAL
  )
{
  EFI_STATUS             Status;
  VIRTIO_DEVICE_PROTOCOL *VirtIo;

  //
  // - If RemainingDevicePath is NULL: the caller is interested in creating all
  //   child handles.
  // - If RemainingDevicePath points to an end node: the caller is not
  //   interested in creating any child handle.
  // - Otherwise, the caller would like to create the one child handle
  //   specified in RemainingDevicePath. In this case we have to see if the
  //   requested device path is supportable.
  //
  if (RemainingDevicePath != NULL &&
      !IsDevicePathEnd (RemainingDevicePath) &&
      (DevicePathNodeLength (RemainingDevicePath) != sizeof mAcpiAdr ||
       CompareMem (RemainingDevicePath, &mAcpiAdr, sizeof mAcpiAdr) != 0)) {
    return EFI_UNSUPPORTED;
  }

  //
  // Open the Virtio Device Protocol interface on the controller, BY_DRIVER.
  //
  Status = gBS->OpenProtocol (ControllerHandle, &gVirtioDeviceProtocolGuid,
                  (VOID **)&VirtIo, This->DriverBindingHandle,
                  ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
  if (EFI_ERROR (Status)) {
    //
    // If this fails, then by default we cannot support ControllerHandle. There
    // is one exception: we've already bound the device, have not produced any
    // GOP child controller, and now the caller wants us to produce the child
    // controller (either specifically or as part of "all children"). That's
    // allowed.
    //
    if (Status == EFI_ALREADY_STARTED) {
      EFI_STATUS Status2;
      VGPU_DEV   *VgpuDev;

      Status2 = gBS->OpenProtocol (ControllerHandle, &gEfiCallerIdGuid,
                       (VOID **)&VgpuDev, This->DriverBindingHandle,
                       ControllerHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
      ASSERT_EFI_ERROR (Status2);

      if (VgpuDev->Child == NULL &&
          (RemainingDevicePath == NULL ||
           !IsDevicePathEnd (RemainingDevicePath))) {
        Status = EFI_SUCCESS;
      }
    }

    return Status;
  }

  //
  // First BY_DRIVER open; check the VirtIo revision and subsystem.
  //
  if (VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0) ||
      VirtIo->SubSystemDeviceId != VIRTIO_SUBSYSTEM_GPU_DEVICE) {
    Status = EFI_UNSUPPORTED;
    goto CloseVirtIo;
  }

  //
  // We'll need the device path of the VirtIo device both for formatting
  // VGPU_DEV.BusName and for populating VGPU_GOP.GopDevicePath.
  //
  Status = gBS->OpenProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid,
                  NULL, This->DriverBindingHandle, ControllerHandle,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL);

CloseVirtIo:
  gBS->CloseProtocol (ControllerHandle, &gVirtioDeviceProtocolGuid,
    This->DriverBindingHandle, ControllerHandle);

  return Status;
}

STATIC
EFI_STATUS
EFIAPI
VirtioGpuDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL *This,
  IN EFI_HANDLE                  ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath OPTIONAL
  )
{
  EFI_STATUS               Status;
  VIRTIO_DEVICE_PROTOCOL   *VirtIo;
  BOOLEAN                  VirtIoBoundJustNow;
  VGPU_DEV                 *VgpuDev;
  EFI_DEVICE_PATH_PROTOCOL *DevicePath;

  //
  // Open the Virtio Device Protocol.
  //
  // The result of this operation, combined with the checks in
  // VirtioGpuDriverBindingSupported(), uniquely tells us whether we are
  // binding the VirtIo controller on this call (with or without creating child
  // controllers), or else we're *only* creating child controllers.
  //
  Status = gBS->OpenProtocol (ControllerHandle, &gVirtioDeviceProtocolGuid,
                  (VOID **)&VirtIo, This->DriverBindingHandle,
                  ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
  if (EFI_ERROR (Status)) {
    //
    // The assertions below are based on the success of
    // VirtioGpuDriverBindingSupported(): we bound ControllerHandle earlier,
    // without producing child handles, and now we're producing the GOP child
    // handle only.
    //
    ASSERT (Status == EFI_ALREADY_STARTED);

    Status = gBS->OpenProtocol (ControllerHandle, &gEfiCallerIdGuid,
                    (VOID **)&VgpuDev, This->DriverBindingHandle,
                    ControllerHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
    ASSERT_EFI_ERROR (Status);

    ASSERT (VgpuDev->Child == NULL);
    ASSERT (
      RemainingDevicePath == NULL || !IsDevicePathEnd (RemainingDevicePath));

    VirtIoBoundJustNow = FALSE;
  } else {
    VirtIoBoundJustNow = TRUE;

    //
    // Allocate the private structure.
    //
    VgpuDev = AllocateZeroPool (sizeof *VgpuDev);
    if (VgpuDev == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto CloseVirtIo;
    }
    VgpuDev->VirtIo = VirtIo;
  }

  //
  // Grab the VirtIo controller's device path. This is necessary regardless of
  // VirtIoBoundJustNow.
  //
  Status = gBS->OpenProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid,
                  (VOID **)&DevicePath, This->DriverBindingHandle,
                  ControllerHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
  if (EFI_ERROR (Status)) {
    goto FreeVgpuDev;
  }

  //
  // Create VGPU_DEV if we've bound the VirtIo controller right now (that is,
  // if we aren't *only* creating child handles).
  //
  if (VirtIoBoundJustNow) {
    CHAR16 *VgpuDevName;

    //
    // Format a human-readable controller name for VGPU_DEV, and stash it for
    // VirtioGpuGetControllerName() to look up.
    //
    Status = FormatVgpuDevName (ControllerHandle, This->DriverBindingHandle,
               DevicePath, &VgpuDevName);
    if (EFI_ERROR (Status)) {
      goto FreeVgpuDev;
    }
    Status = AddUnicodeString2 ("en", mComponentName2.SupportedLanguages,
               &VgpuDev->BusName, VgpuDevName, FALSE /* Iso639Language */);
    FreePool (VgpuDevName);
    if (EFI_ERROR (Status)) {
      goto FreeVgpuDev;
    }

    Status = VirtioGpuInit (VgpuDev);
    if (EFI_ERROR (Status)) {
      goto FreeVgpuDevBusName;
    }

    Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK,
                    VirtioGpuExitBoot, VgpuDev /* NotifyContext */,
                    &VgpuDev->ExitBoot);
    if (EFI_ERROR (Status)) {
      goto UninitGpu;
    }

    //
    // Install the VGPU_DEV "protocol interface" on ControllerHandle.
    //
    Status = gBS->InstallProtocolInterface (&ControllerHandle,
                    &gEfiCallerIdGuid, EFI_NATIVE_INTERFACE, VgpuDev);
    if (EFI_ERROR (Status)) {
      goto CloseExitBoot;
    }

    if (RemainingDevicePath != NULL && IsDevicePathEnd (RemainingDevicePath)) {
      //
      // No child handle should be produced; we're done.
      //
      DEBUG ((DEBUG_INFO, "%a: bound VirtIo=%p without producing GOP\n",
        __FUNCTION__, (VOID *)VgpuDev->VirtIo));
      return EFI_SUCCESS;
    }
  }

  //
  // Below we'll produce our single child handle: the caller requested it
  // either specifically, or as part of all child handles.
  //
  ASSERT (VgpuDev->Child == NULL);
  ASSERT (
    RemainingDevicePath == NULL || !IsDevicePathEnd (RemainingDevicePath));

  Status = InitVgpuGop (VgpuDev, DevicePath, ControllerHandle,
             This->DriverBindingHandle);
  if (EFI_ERROR (Status)) {
    goto UninstallVgpuDev;
  }

  //
  // We're done.
  //
  DEBUG ((DEBUG_INFO, "%a: produced GOP %a VirtIo=%p\n", __FUNCTION__,
    VirtIoBoundJustNow ? "while binding" : "for pre-bound",
    (VOID *)VgpuDev->VirtIo));
  return EFI_SUCCESS;

UninstallVgpuDev:
  if (VirtIoBoundJustNow) {
    gBS->UninstallProtocolInterface (ControllerHandle, &gEfiCallerIdGuid,
           VgpuDev);
  }

CloseExitBoot:
  if (VirtIoBoundJustNow) {
    gBS->CloseEvent (VgpuDev->ExitBoot);
  }

UninitGpu:
  if (VirtIoBoundJustNow) {
    VirtioGpuUninit (VgpuDev);
  }

FreeVgpuDevBusName:
  if (VirtIoBoundJustNow) {
    FreeUnicodeStringTable (VgpuDev->BusName);
  }

FreeVgpuDev:
  if (VirtIoBoundJustNow) {
    FreePool (VgpuDev);
  }

CloseVirtIo:
  if (VirtIoBoundJustNow) {
    gBS->CloseProtocol (ControllerHandle, &gVirtioDeviceProtocolGuid,
      This->DriverBindingHandle, ControllerHandle);
  }

  return Status;
}

STATIC
EFI_STATUS
EFIAPI
VirtioGpuDriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL *This,
  IN  EFI_HANDLE                  ControllerHandle,
  IN  UINTN                       NumberOfChildren,
  IN  EFI_HANDLE                  *ChildHandleBuffer OPTIONAL
  )
{
  EFI_STATUS Status;
  VGPU_DEV   *VgpuDev;

  //
  // Look up the VGPU_DEV "protocol interface" on ControllerHandle.
  //
  Status = gBS->OpenProtocol (ControllerHandle, &gEfiCallerIdGuid,
                  (VOID **)&VgpuDev, This->DriverBindingHandle,
                  ControllerHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Sanity check: if we found gEfiCallerIdGuid on ControllerHandle, then we
  // keep its Virtio Device Protocol interface open BY_DRIVER.
  //
  ASSERT_EFI_ERROR (EfiTestManagedDevice (ControllerHandle,
                      This->DriverBindingHandle, &gVirtioDeviceProtocolGuid));

  switch (NumberOfChildren) {
  case 0:
    //
    // The caller wants us to unbind the VirtIo controller.
    //
    if (VgpuDev->Child != NULL) {
      //
      // We still have the GOP child.
      //
      Status = EFI_DEVICE_ERROR;
      break;
    }

    DEBUG ((DEBUG_INFO, "%a: unbinding GOP-less VirtIo=%p\n", __FUNCTION__,
      (VOID *)VgpuDev->VirtIo));

    Status = gBS->UninstallProtocolInterface (ControllerHandle,
                    &gEfiCallerIdGuid, VgpuDev);
    ASSERT_EFI_ERROR (Status);

    Status = gBS->CloseEvent (VgpuDev->ExitBoot);
    ASSERT_EFI_ERROR (Status);

    VirtioGpuUninit (VgpuDev);
    FreeUnicodeStringTable (VgpuDev->BusName);
    FreePool (VgpuDev);

    Status = gBS->CloseProtocol (ControllerHandle, &gVirtioDeviceProtocolGuid,
                    This->DriverBindingHandle, ControllerHandle);
    ASSERT_EFI_ERROR (Status);
    break;

  case 1:
    //
    // The caller wants us to destroy our child GOP controller.
    //
    if (VgpuDev->Child == NULL ||
        ChildHandleBuffer[0] != VgpuDev->Child->GopHandle) {
      //
      // We have no child controller at the moment, or it differs from the one
      // the caller wants us to destroy. I.e., we don't own the child
      // controller passed in.
      //
      Status = EFI_DEVICE_ERROR;
      break;
    }
    //
    // Sanity check: our GOP child controller keeps the VGPU_DEV controller's
    // Virtio Device Protocol interface open BY_CHILD_CONTROLLER.
    //
    ASSERT_EFI_ERROR (EfiTestChildHandle (ControllerHandle,
                        VgpuDev->Child->GopHandle,
                        &gVirtioDeviceProtocolGuid));

    DEBUG ((DEBUG_INFO, "%a: destroying GOP under VirtIo=%p\n", __FUNCTION__,
      (VOID *)VgpuDev->VirtIo));
    UninitVgpuGop (VgpuDev, ControllerHandle, This->DriverBindingHandle);
    break;

  default:
    //
    // Impossible, we never produced more than one child.
    //
    Status = EFI_DEVICE_ERROR;
    break;
  }
  return Status;
}

STATIC EFI_DRIVER_BINDING_PROTOCOL mDriverBinding = {
  VirtioGpuDriverBindingSupported,
  VirtioGpuDriverBindingStart,
  VirtioGpuDriverBindingStop,
  0x10,                            // Version
  NULL,                            // ImageHandle, overwritten in entry point
  NULL                             // DriverBindingHandle, ditto
};

//
// Entry point of the driver.
//
EFI_STATUS
EFIAPI
VirtioGpuEntryPoint (
  IN EFI_HANDLE       ImageHandle,
  IN EFI_SYSTEM_TABLE *SystemTable
  )
{
  return EfiLibInstallDriverBindingComponentName2 (ImageHandle, SystemTable,
           &mDriverBinding, ImageHandle, NULL /* ComponentName */,
           &mComponentName2);
}
