/** @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", __FUNCTION__));

  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", __FUNCTION__));
        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;
}
