/** @file
 Emu Bus driver

Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2011, Apple Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent


**/

#include "EmuBusDriverDxe.h"



//
// DriverBinding protocol global
//
EFI_DRIVER_BINDING_PROTOCOL           gEmuBusDriverBinding = {
  EmuBusDriverBindingSupported,
  EmuBusDriverBindingStart,
  EmuBusDriverBindingStop,
  0xa,
  NULL,
  NULL
};



EFI_STATUS
EFIAPI
EmuBusDriverBindingSupported (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;
  EMU_THUNK_PROTOCOL        *EmuThunk;

  //
  // Check the contents of the first Device Path Node of RemainingDevicePath to make sure
  // it is a legal Device Path Node for this bus driver's children.
  //
  if (RemainingDevicePath != NULL) {
    //
    // Check if RemainingDevicePath is the End of Device Path Node,
    // if yes, go on checking other conditions
    //
    if (!IsDevicePathEnd (RemainingDevicePath)) {
      //
      // If RemainingDevicePath isn't the End of Device Path Node,
      // check its validation
      //
      if (RemainingDevicePath->Type != HARDWARE_DEVICE_PATH ||
          RemainingDevicePath->SubType != HW_VENDOR_DP ||
          DevicePathNodeLength(RemainingDevicePath) != sizeof(EMU_VENDOR_DEVICE_PATH_NODE)) {
        return EFI_UNSUPPORTED;
      }
    }
  }

  //
  // Open the IO Abstraction(s) needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEmuThunkProtocolGuid,
                  (VOID **)&EmuThunk   ,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (Status == EFI_ALREADY_STARTED) {
    return EFI_SUCCESS;
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Close the I/O Abstraction(s) used to perform the supported test
  //
  gBS->CloseProtocol (
        ControllerHandle,
        &gEmuThunkProtocolGuid,
        This->DriverBindingHandle,
        ControllerHandle
        );

  //
  // Open the EFI Device Path protocol needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&ParentDevicePath,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (Status == EFI_ALREADY_STARTED) {
    return EFI_SUCCESS;
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }


  //
  // Close protocol, don't use device path protocol in the Support() function
  //
  gBS->CloseProtocol (
        ControllerHandle,
        &gEfiDevicePathProtocolGuid,
        This->DriverBindingHandle,
        ControllerHandle
        );

  return Status;
}


EFI_STATUS
EFIAPI
EmuBusDriverBindingStart (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                      Status;
  EFI_STATUS                      InstallStatus;
  EMU_THUNK_PROTOCOL              *EmuThunk;
  EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;
  EMU_IO_DEVICE                   *EmuDevice;
  EMU_BUS_DEVICE                  *EmuBusDevice;
  EMU_IO_THUNK_PROTOCOL           *EmuIoThunk;
  UINT16                          ComponentName[512];
  EMU_VENDOR_DEVICE_PATH_NODE     *Node;
  BOOLEAN                         CreateDevice;

  InstallStatus = EFI_UNSUPPORTED;
  Status = EFI_UNSUPPORTED;

  //
  // Grab the protocols we need
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&ParentDevicePath,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
    return Status;
  }

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEmuThunkProtocolGuid,
                  (VOID **)&EmuThunk,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
    return Status;
  }

  if (Status != EFI_ALREADY_STARTED) {
    EmuBusDevice = AllocatePool (sizeof (EMU_BUS_DEVICE));
    if (EmuBusDevice == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    EmuBusDevice->Signature           = EMU_BUS_DEVICE_SIGNATURE;
    EmuBusDevice->ControllerNameTable = NULL;

    AddUnicodeString2 (
      "eng",
      gEmuBusDriverComponentName.SupportedLanguages,
      &EmuBusDevice->ControllerNameTable,
      L"Emulator Bus Controller",
      TRUE
      );
    AddUnicodeString2 (
      "en",
      gEmuBusDriverComponentName2.SupportedLanguages,
      &EmuBusDevice->ControllerNameTable,
      L"Emulator Bus Controller",
      FALSE
      );


    Status = gBS->InstallMultipleProtocolInterfaces (
                    &ControllerHandle,
                    &gEfiCallerIdGuid, EmuBusDevice,
                    NULL
                    );
    if (EFI_ERROR (Status)) {
      FreeUnicodeStringTable (EmuBusDevice->ControllerNameTable);
      gBS->FreePool (EmuBusDevice);
      return Status;
    }
  }


  for (Status = EFI_SUCCESS, EmuIoThunk = NULL; !EFI_ERROR (Status); ) {
    Status = EmuThunk->GetNextProtocol (TRUE, &EmuIoThunk);
    if (EFI_ERROR (Status)) {
      break;
    }

    CreateDevice = TRUE;
    if (RemainingDevicePath != NULL) {
      CreateDevice  = FALSE;
      //
      // Check if RemainingDevicePath is the End of Device Path Node,
      // if yes, don't create any child device
      //
      if (!IsDevicePathEnd (RemainingDevicePath)) {
        //
        // If RemainingDevicePath isn't the End of Device Path Node,
        // check its validation
        //
        Node          = (EMU_VENDOR_DEVICE_PATH_NODE *) RemainingDevicePath;
        if (Node->VendorDevicePath.Header.Type == HARDWARE_DEVICE_PATH &&
            Node->VendorDevicePath.Header.SubType == HW_VENDOR_DP &&
            DevicePathNodeLength (&Node->VendorDevicePath.Header) == sizeof (EMU_VENDOR_DEVICE_PATH_NODE)
            ) {
          if (CompareGuid (&Node->VendorDevicePath.Guid, EmuIoThunk->Protocol) && Node->Instance == EmuIoThunk->Instance) {
            CreateDevice = TRUE;
          }
        }
      }
    }

    if (CreateDevice) {
      //
      // Allocate instance structure, and fill in parent information.
      //
      EmuDevice = AllocatePool (sizeof (EMU_IO_DEVICE));
      if (EmuDevice == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      EmuDevice->Handle             = NULL;
      EmuDevice->ControllerHandle   = ControllerHandle;
      EmuDevice->ParentDevicePath   = ParentDevicePath;
      CopyMem (&EmuDevice->EmuIoThunk, EmuIoThunk, sizeof (EMU_IO_THUNK_PROTOCOL));

      EmuDevice->ControllerNameTable = NULL;

      StrnCpyS (
        ComponentName,
        sizeof (ComponentName) / sizeof (CHAR16),
        EmuIoThunk->ConfigString,
        sizeof (ComponentName) / sizeof (CHAR16)
        );

      EmuDevice->DevicePath = EmuBusCreateDevicePath (
                                  ParentDevicePath,
                                  EmuIoThunk->Protocol,
                                  EmuIoThunk->Instance
                                  );
      if (EmuDevice->DevicePath == NULL) {
        gBS->FreePool (EmuDevice);
        return EFI_OUT_OF_RESOURCES;
      }

      AddUnicodeString (
        "eng",
        gEmuBusDriverComponentName.SupportedLanguages,
        &EmuDevice->ControllerNameTable,
        ComponentName
        );

      EmuDevice->Signature = EMU_IO_DEVICE_SIGNATURE;

      InstallStatus = gBS->InstallMultipleProtocolInterfaces (
                            &EmuDevice->Handle,
                            &gEfiDevicePathProtocolGuid,  EmuDevice->DevicePath,
                            &gEmuIoThunkProtocolGuid,     &EmuDevice->EmuIoThunk,
                            NULL
                            );
      if (EFI_ERROR (InstallStatus)) {
        FreeUnicodeStringTable (EmuDevice->ControllerNameTable);
        gBS->FreePool (EmuDevice);
      } else {
        //
        // Open For Child Device
        //
        Status = gBS->OpenProtocol (
                        ControllerHandle,
                        &gEmuThunkProtocolGuid,
                        (VOID **)&EmuThunk   ,
                        This->DriverBindingHandle,
                        EmuDevice->Handle,
                        EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                        );
        if (!EFI_ERROR (Status)) {
          InstallStatus = EFI_SUCCESS;
        }
      }
    }
  }

  return InstallStatus;
}


EFI_STATUS
EFIAPI
EmuBusDriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  UINTN                        NumberOfChildren,
  IN  EFI_HANDLE                   *ChildHandleBuffer
  )
{
  EFI_STATUS                Status;
  UINTN                     Index;
  BOOLEAN                   AllChildrenStopped;
  EMU_IO_THUNK_PROTOCOL     *EmuIoThunk;
  EMU_BUS_DEVICE            *EmuBusDevice;
  EMU_IO_DEVICE             *EmuDevice;
  EMU_THUNK_PROTOCOL        *EmuThunk;

  //
  // Complete all outstanding transactions to Controller.
  // Don't allow any new transaction to Controller to be started.
  //

  if (NumberOfChildren == 0) {
    //
    // Close the bus driver
    //
    Status = gBS->OpenProtocol (
                    ControllerHandle,
                    &gEfiCallerIdGuid,
                    (VOID **)&EmuBusDevice,
                    This->DriverBindingHandle,
                    ControllerHandle,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    gBS->UninstallMultipleProtocolInterfaces (
          ControllerHandle,
          &gEfiCallerIdGuid,  EmuBusDevice,
          NULL
          );

    FreeUnicodeStringTable (EmuBusDevice->ControllerNameTable);

    gBS->FreePool (EmuBusDevice);

    gBS->CloseProtocol (
          ControllerHandle,
          &gEmuThunkProtocolGuid,
          This->DriverBindingHandle,
          ControllerHandle
          );

    gBS->CloseProtocol (
          ControllerHandle,
          &gEfiDevicePathProtocolGuid,
          This->DriverBindingHandle,
          ControllerHandle
          );
    return EFI_SUCCESS;
  }

  AllChildrenStopped = TRUE;

  for (Index = 0; Index < NumberOfChildren; Index++) {

    Status = gBS->OpenProtocol (
                    ChildHandleBuffer[Index],
                    &gEmuIoThunkProtocolGuid,
                    (VOID **)&EmuIoThunk,
                    This->DriverBindingHandle,
                    ControllerHandle,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (!EFI_ERROR (Status)) {
      EmuDevice = EMU_IO_DEVICE_FROM_THIS (EmuIoThunk);

      Status = gBS->CloseProtocol (
                      ControllerHandle,
                      &gEmuThunkProtocolGuid,
                      This->DriverBindingHandle,
                      EmuDevice->Handle
                      );

      Status = gBS->UninstallMultipleProtocolInterfaces (
                      EmuDevice->Handle,
                      &gEfiDevicePathProtocolGuid,  EmuDevice->DevicePath,
                      &gEmuIoThunkProtocolGuid,     &EmuDevice->EmuIoThunk,
                      NULL
                      );

      if (EFI_ERROR (Status)) {
        gBS->OpenProtocol (
              ControllerHandle,
              &gEmuThunkProtocolGuid,
              (VOID **) &EmuThunk   ,
              This->DriverBindingHandle,
              EmuDevice->Handle,
              EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
              );
      } else {
        //
        // Close the child handle
        //
        FreeUnicodeStringTable (EmuDevice->ControllerNameTable);
        FreePool (EmuDevice);
      }
    }

    if (EFI_ERROR (Status)) {
      AllChildrenStopped = FALSE;
    }
  }

  if (!AllChildrenStopped) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}


/*++

Routine Description:
  Create a device path node using Guid and InstanceNumber and append it to
  the passed in RootDevicePath

Arguments:
  RootDevicePath - Root of the device path to return.

  Guid           - GUID to use in vendor device path node.

  InstanceNumber - Instance number to use in the vendor device path. This
                    argument is needed to make sure each device path is unique.

Returns:

  EFI_DEVICE_PATH_PROTOCOL

**/
EFI_DEVICE_PATH_PROTOCOL *
EmuBusCreateDevicePath (
  IN  EFI_DEVICE_PATH_PROTOCOL  *RootDevicePath,
  IN  EFI_GUID                  *Guid,
  IN  UINT16                    InstanceNumber
  )
{
  EMU_VENDOR_DEVICE_PATH_NODE  DevicePath;

  DevicePath.VendorDevicePath.Header.Type     = HARDWARE_DEVICE_PATH;
  DevicePath.VendorDevicePath.Header.SubType  = HW_VENDOR_DP;
  SetDevicePathNodeLength (&DevicePath.VendorDevicePath.Header, sizeof (EMU_VENDOR_DEVICE_PATH_NODE));

  //
  // The GUID defines the Class
  //
  CopyMem (&DevicePath.VendorDevicePath.Guid, Guid, sizeof (EFI_GUID));

  //
  // Add an instance number so we can make sure there are no Device Path
  // duplication.
  //
  DevicePath.Instance = InstanceNumber;

  return AppendDevicePathNode (
          RootDevicePath,
          (EFI_DEVICE_PATH_PROTOCOL *) &DevicePath
          );
}



/**
  The user Entry Point for module EmuBusDriver. The user code starts with this function.

  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
  @param[in] SystemTable    A pointer to the EFI System Table.

  @retval EFI_SUCCESS       The entry point is executed successfully.
  @retval other             Some error occurs when executing this entry point.

**/
EFI_STATUS
EFIAPI
InitializeEmuBusDriver (
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
{
  EFI_STATUS              Status;

  Status = EfiLibInstallAllDriverProtocols (
             ImageHandle,
             SystemTable,
             &gEmuBusDriverBinding,
             ImageHandle,
             &gEmuBusDriverComponentName,
             NULL,
             NULL
             );
  ASSERT_EFI_ERROR (Status);


  return Status;
}




