/** @file
  Debug Port Library implementation based on usb3 debug port.

  Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Base.h>
#include <PiDxe.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/HobLib.h>
#include <Protocol/PciIo.h>
#include <Protocol/IoMmu.h>
#include <Protocol/DxeSmmReadyToLock.h>
#include "DebugCommunicationLibUsb3Internal.h"

GUID  gUsb3DbgGuid =  USB3_DBG_GUID;

USB3_DEBUG_PORT_HANDLE  mUsb3Instance         = { USB3DBG_UNINITIALIZED };
EFI_PHYSICAL_ADDRESS    mUsb3InstanceAddr     = 0;
EFI_PHYSICAL_ADDRESS    *mUsb3InstanceAddrPtr = NULL;
EFI_PCI_IO_PROTOCOL     *mUsb3PciIo           = NULL;

/**
  Creates a named event that can be signaled.

  This function creates an event using NotifyTpl, NotifyFunction.
  If Name is NULL, then ASSERT().
  If NotifyTpl is not a legal TPL value, then ASSERT().
  If NotifyFunction is NULL, then ASSERT().

  @param  Name                  Supplies the GUID name of the event.
  @param  NotifyTpl             Supplies the task priority level of the event notifications.
  @param  NotifyFunction        Supplies the function to notify when the event is signaled.
  @param  Event                 A pointer to the event created.

  @retval EFI_SUCCESS           A named event was created.
  @retval EFI_OUT_OF_RESOURCES  There are not enough resource to create the named event.

**/
EFI_STATUS
EFIAPI
Usb3NamedEventListen (
  IN CONST EFI_GUID    *Name,
  IN EFI_TPL           NotifyTpl,
  IN EFI_EVENT_NOTIFY  NotifyFunction,
  IN EFI_EVENT         *Event
  )
{
  EFI_STATUS  Status;
  VOID        *RegistrationLocal;

  ASSERT (Name != NULL);
  ASSERT (NotifyFunction != NULL);
  ASSERT (NotifyTpl <= TPL_HIGH_LEVEL);

  //
  // Create event
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  NotifyTpl,
                  NotifyFunction,
                  NULL,
                  Event
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Register for an installation of protocol interface
  //
  Status = gBS->RegisterProtocolNotify (
                  (EFI_GUID *)Name,
                  *Event,
                  &RegistrationLocal
                  );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/**
  USB3 map one DMA buffer.

  @param PciIo          Pointer to PciIo for USB3 debug port.
  @param Address        DMA buffer address to be mapped.
  @param NumberOfBytes  Number of bytes to be mapped.

**/
VOID
Usb3MapOneDmaBuffer (
  IN EFI_PCI_IO_PROTOCOL   *PciIo,
  IN EFI_PHYSICAL_ADDRESS  Address,
  IN UINTN                 NumberOfBytes
  )
{
  EFI_STATUS            Status;
  VOID                  *HostAddress;
  EFI_PHYSICAL_ADDRESS  DeviceAddress;
  VOID                  *Mapping;

  HostAddress = (VOID *)(UINTN)Address;
  Status      = PciIo->Map (
                         PciIo,
                         EfiPciIoOperationBusMasterCommonBuffer,
                         HostAddress,
                         &NumberOfBytes,
                         &DeviceAddress,
                         &Mapping
                         );
  ASSERT_EFI_ERROR (Status);
  ASSERT (DeviceAddress == ((EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress));
}

/**
  USB3 map DMA buffers.

  @param Instance       Pointer to USB3 debug port instance.
  @param PciIo          Pointer to PciIo for USB3 debug port.

**/
VOID
Usb3MapDmaBuffers (
  IN USB3_DEBUG_PORT_HANDLE  *Instance,
  IN EFI_PCI_IO_PROTOCOL     *PciIo
  )
{
  Usb3MapOneDmaBuffer (
    PciIo,
    Instance->UrbIn.Data,
    XHCI_DEBUG_DEVICE_MAX_PACKET_SIZE * 2 + USB3_DEBUG_PORT_WRITE_MAX_PACKET_SIZE
    );

  Usb3MapOneDmaBuffer (
    PciIo,
    Instance->TransferRingIn.RingSeg0,
    sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER
    );

  Usb3MapOneDmaBuffer (
    PciIo,
    Instance->TransferRingOut.RingSeg0,
    sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER
    );

  Usb3MapOneDmaBuffer (
    PciIo,
    Instance->EventRing.EventRingSeg0,
    sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER
    );

  Usb3MapOneDmaBuffer (
    PciIo,
    Instance->EventRing.ERSTBase,
    sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER
    );

  Usb3MapOneDmaBuffer (
    PciIo,
    Instance->DebugCapabilityContext,
    sizeof (XHC_DC_CONTEXT)
    );

  Usb3MapOneDmaBuffer (
    PciIo,
    ((XHC_DC_CONTEXT *)(UINTN)Instance->DebugCapabilityContext)->DbcInfoContext.String0DescAddress,
    STRING0_DESC_LEN + MANU_DESC_LEN + PRODUCT_DESC_LEN + SERIAL_DESC_LEN
    );
}

/**
  Invoke a notification event

  @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.

**/
VOID
EFIAPI
Usb3DxeSmmReadyToLockNotify (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  USB3_DEBUG_PORT_HANDLE  *Instance;

  DEBUG ((DEBUG_INFO, "%a()\n", __func__));

  Instance = GetUsb3DebugPortInstance ();
  ASSERT (Instance != NULL);

  Instance->InNotify = TRUE;

  //
  // For the case that the USB3 debug port instance and DMA buffers are
  // from PEI HOB with IOMMU enabled.
  // Reinitialize USB3 debug port with granted DXE DMA buffer accessible
  // by SMM environment.
  //
  InitializeUsbDebugHardware (Instance);

  //
  // Wait some time for host to be ready after re-initialization.
  //
  MicroSecondDelay (1000000);

  Instance->InNotify = FALSE;
  gBS->CloseEvent (Event);
}

/**
  USB3 get IOMMU protocol.

  @return Pointer to IOMMU protocol.

**/
EDKII_IOMMU_PROTOCOL *
Usb3GetIoMmu (
  VOID
  )
{
  EFI_STATUS            Status;
  EDKII_IOMMU_PROTOCOL  *IoMmu;

  IoMmu  = NULL;
  Status = gBS->LocateProtocol (
                  &gEdkiiIoMmuProtocolGuid,
                  NULL,
                  (VOID **)&IoMmu
                  );
  if (!EFI_ERROR (Status) && (IoMmu != NULL)) {
    return IoMmu;
  }

  return NULL;
}

/**
  Invoke a notification event

  @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.

**/
VOID
EFIAPI
Usb3PciIoNotify (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
  EFI_STATUS              Status;
  UINTN                   PciIoHandleCount;
  EFI_HANDLE              *PciIoHandleBuffer;
  UINTN                   Index;
  EFI_PCI_IO_PROTOCOL     *PciIo;
  UINTN                   PciSegment;
  UINTN                   PciBusNumber;
  UINTN                   PciDeviceNumber;
  UINTN                   PciFunctionNumber;
  UINT32                  PciAddress;
  USB3_DEBUG_PORT_HANDLE  *Instance;
  EFI_EVENT               SmmReadyToLockEvent;

  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiPciIoProtocolGuid,
                  NULL,
                  &PciIoHandleCount,
                  &PciIoHandleBuffer
                  );
  if (!EFI_ERROR (Status) &&
      (PciIoHandleBuffer != NULL) &&
      (PciIoHandleCount != 0))
  {
    for (Index = 0; Index < PciIoHandleCount; Index++) {
      Status = gBS->HandleProtocol (
                      PciIoHandleBuffer[Index],
                      &gEfiPciIoProtocolGuid,
                      (VOID **)&PciIo
                      );
      ASSERT_EFI_ERROR (Status);
      Status = PciIo->GetLocation (PciIo, &PciSegment, &PciBusNumber, &PciDeviceNumber, &PciFunctionNumber);
      ASSERT_EFI_ERROR (Status);
      PciAddress = (UINT32)((PciBusNumber << 20) | (PciDeviceNumber << 15) | (PciFunctionNumber << 12));
      if (PciAddress == PcdGet32 (PcdUsbXhciPciAddress)) {
        //
        // Found the PciIo for USB3 debug port.
        //
        DEBUG ((DEBUG_INFO, "%a()\n", __func__));
        if (Usb3GetIoMmu () != NULL) {
          Instance = GetUsb3DebugPortInstance ();
          ASSERT (Instance != NULL);
          if (Instance->Ready) {
            Instance->InNotify = TRUE;
            Usb3MapDmaBuffers (Instance, PciIo);
            Instance->InNotify = FALSE;

            if (Instance->FromHob) {
              mUsb3PciIo = PciIo;
              Usb3NamedEventListen (
                &gEfiDxeSmmReadyToLockProtocolGuid,
                TPL_NOTIFY,
                Usb3DxeSmmReadyToLockNotify,
                &SmmReadyToLockEvent
                );
            }
          }
        }

        gBS->CloseEvent (Event);
        break;
      }
    }

    gBS->FreePool (PciIoHandleBuffer);
  }
}

/**
  Return USB3 debug instance address pointer.

**/
EFI_PHYSICAL_ADDRESS *
GetUsb3DebugPortInstanceAddrPtr (
  VOID
  )
{
  if (mUsb3InstanceAddrPtr == NULL) {
    //
    // Use the local variables temporarily.
    //
    mUsb3InstanceAddr    = (EFI_PHYSICAL_ADDRESS)(UINTN)&mUsb3Instance;
    mUsb3InstanceAddrPtr = &mUsb3InstanceAddr;
  }

  return mUsb3InstanceAddrPtr;
}

/**
  Allocates pages that are suitable for an OperationBusMasterCommonBuffer or
  OperationBusMasterCommonBuffer64 mapping.

  @param PciIo                  Pointer to PciIo for USB3 debug port.
  @param Pages                  The number of pages to allocate.
  @param Address                A pointer to store the base system memory address of the
                                allocated range.

  @retval EFI_SUCCESS           The requested memory pages were allocated.
  @retval EFI_UNSUPPORTED       Attributes is unsupported. The only legal attribute bits are
                                MEMORY_WRITE_COMBINE and MEMORY_CACHED.
  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
  @retval EFI_OUT_OF_RESOURCES  The memory pages could not be allocated.

**/
EFI_STATUS
Usb3AllocateDmaBuffer (
  IN EFI_PCI_IO_PROTOCOL  *PciIo,
  IN UINTN                Pages,
  OUT VOID                **Address
  )
{
  EFI_STATUS  Status;

  *Address = NULL;
  Status   = PciIo->AllocateBuffer (
                      PciIo,
                      AllocateAnyPages,
                      EfiRuntimeServicesData,
                      Pages,
                      Address,
                      0
                      );
  if (!EFI_ERROR (Status)) {
    Usb3MapOneDmaBuffer (
      PciIo,
      (EFI_PHYSICAL_ADDRESS)(UINTN)*Address,
      EFI_PAGES_TO_SIZE (Pages)
      );
  }

  return Status;
}

/**
  Allocate aligned memory for XHC's usage.

  @param  BufferSize      The size, in bytes, of the Buffer.

  @return A pointer to the allocated buffer or NULL if allocation fails.

**/
VOID *
AllocateAlignBuffer (
  IN UINTN  BufferSize
  )
{
  EFI_PHYSICAL_ADDRESS  TmpAddr;
  EFI_STATUS            Status;
  VOID                  *Buf;

  Buf = NULL;

  if (gBS != NULL) {
    if (mUsb3PciIo != NULL) {
      Usb3AllocateDmaBuffer (
        mUsb3PciIo,
        EFI_SIZE_TO_PAGES (BufferSize),
        &Buf
        );
    } else {
      TmpAddr = 0xFFFFFFFF;
      Status  = gBS->AllocatePages (
                       AllocateMaxAddress,
                       EfiACPIMemoryNVS,
                       EFI_SIZE_TO_PAGES (BufferSize),
                       &TmpAddr
                       );
      if (!EFI_ERROR (Status)) {
        Buf = (VOID *)(UINTN)TmpAddr;
      }
    }
  }

  return Buf;
}

/**
  The constructor function initialize USB3 debug port.

  @param  ImageHandle   The firmware allocated handle for the EFI image.
  @param  SystemTable   A pointer to the EFI System Table.

  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

**/
EFI_STATUS
EFIAPI
DebugCommunicationUsb3DxeConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_PHYSICAL_ADDRESS    *AddrPtr;
  USB3_DEBUG_PORT_HANDLE  *Instance;
  EFI_PHYSICAL_ADDRESS    Address;
  EFI_STATUS              Status;
  EFI_EVENT               Event;

  Status = EfiGetSystemConfigurationTable (&gUsb3DbgGuid, (VOID **)&AddrPtr);
  if (EFI_ERROR (Status) || (AddrPtr == NULL)) {
    //
    // Instead of using local variables, install system configuration table for
    // the local instance and the buffer to save instance address pointer.
    //
    Address = SIZE_4GB;
    Status  = gBS->AllocatePages (
                     AllocateMaxAddress,
                     EfiACPIMemoryNVS,
                     EFI_SIZE_TO_PAGES (sizeof (EFI_PHYSICAL_ADDRESS) + sizeof (USB3_DEBUG_PORT_HANDLE)),
                     &Address
                     );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    AddrPtr = (EFI_PHYSICAL_ADDRESS *)(UINTN)Address;
    ZeroMem (AddrPtr, sizeof (EFI_PHYSICAL_ADDRESS) + sizeof (USB3_DEBUG_PORT_HANDLE));
    Instance = (USB3_DEBUG_PORT_HANDLE *)(AddrPtr + 1);
    CopyMem (Instance, &mUsb3Instance, sizeof (USB3_DEBUG_PORT_HANDLE));
    *AddrPtr = (EFI_PHYSICAL_ADDRESS)(UINTN)Instance;

    Status = gBS->InstallConfigurationTable (&gUsb3DbgGuid, AddrPtr);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  if (mUsb3InstanceAddrPtr != NULL) {
    *AddrPtr = *mUsb3InstanceAddrPtr;
  }

  mUsb3InstanceAddrPtr = AddrPtr;

  Instance = GetUsb3DebugPortInstance ();
  ASSERT (Instance != NULL);

  if (Instance->PciIoEvent == 0) {
    Status = Usb3NamedEventListen (
               &gEfiPciIoProtocolGuid,
               TPL_NOTIFY,
               Usb3PciIoNotify,
               &Event
               );
    if (!EFI_ERROR (Status)) {
      Instance->PciIoEvent = (EFI_PHYSICAL_ADDRESS)(UINTN)Event;
    }
  }

  return EFI_SUCCESS;
}

/**
  The destructor function.

  @param  ImageHandle   The firmware allocated handle for the EFI image.
  @param  SystemTable   A pointer to the EFI System Table.

  @retval EFI_SUCCESS   The destructor always returns EFI_SUCCESS.

**/
EFI_STATUS
EFIAPI
DebugCommunicationUsb3DxeDestructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  USB3_DEBUG_PORT_HANDLE  *Instance;

  Instance = GetUsb3DebugPortInstance ();
  ASSERT (Instance != NULL);

  if (Instance->PciIoEvent != 0) {
    //
    // Close the event created.
    //
    gBS->CloseEvent ((EFI_EVENT)(UINTN)Instance->PciIoEvent);
    Instance->PciIoEvent = 0;
  }

  return EFI_SUCCESS;
}
