/** @file

  Generic non-coherent implementation of DmaLib.h

  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
  Copyright (c) 2015 - 2017, Linaro, Ltd. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <PiDxe.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/DmaLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/IoLib.h>
#include <Library/BaseMemoryLib.h>

#include <Protocol/Cpu.h>

typedef struct {
  EFI_PHYSICAL_ADDRESS    HostAddress;
  VOID                    *BufferAddress;
  UINTN                   NumberOfBytes;
  DMA_MAP_OPERATION       Operation;
  BOOLEAN                 DoubleBuffer;
} MAP_INFO_INSTANCE;

typedef struct {
  LIST_ENTRY    Link;
  VOID          *HostAddress;
  UINTN         NumPages;
  UINT64        Attributes;
} UNCACHED_ALLOCATION;

STATIC EFI_CPU_ARCH_PROTOCOL  *mCpu;
STATIC LIST_ENTRY             UncachedAllocationList;

STATIC PHYSICAL_ADDRESS  mDmaHostAddressLimit;

STATIC
PHYSICAL_ADDRESS
HostToDeviceAddress (
  IN  VOID  *Address
  )
{
  return (PHYSICAL_ADDRESS)(UINTN)Address + PcdGet64 (PcdDmaDeviceOffset);
}

/**
  Allocates one or more 4KB pages of a certain memory type at a specified
  alignment.

  Allocates the number of 4KB pages specified by Pages of a certain memory type
  with an alignment specified by Alignment. The allocated buffer is returned.
  If Pages is 0, then NULL is returned. If there is not enough memory at the
  specified alignment remaining to satisfy the request, then NULL is returned.
  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
  If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().

  @param  MemoryType            The type of memory to allocate.
  @param  Pages                 The number of 4 KB pages to allocate.
  @param  Alignment             The requested alignment of the allocation.
                                Must be a power of two.
                                If Alignment is zero, then byte alignment is
                                used.

  @return A pointer to the allocated buffer or NULL if allocation fails.

**/
STATIC
VOID *
InternalAllocateAlignedPages (
  IN EFI_MEMORY_TYPE  MemoryType,
  IN UINTN            Pages,
  IN UINTN            Alignment
  )
{
  EFI_STATUS            Status;
  EFI_PHYSICAL_ADDRESS  Memory;
  UINTN                 AlignedMemory;
  UINTN                 AlignmentMask;
  UINTN                 UnalignedPages;
  UINTN                 RealPages;

  //
  // Alignment must be a power of two or zero.
  //
  ASSERT ((Alignment & (Alignment - 1)) == 0);

  if (Pages == 0) {
    return NULL;
  }

  if (Alignment > EFI_PAGE_SIZE) {
    //
    // Calculate the total number of pages since alignment is larger than page
    // size.
    //
    AlignmentMask = Alignment - 1;
    RealPages     = Pages + EFI_SIZE_TO_PAGES (Alignment);
    //
    // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not
    // overflow.
    //
    ASSERT (RealPages > Pages);

    Memory = mDmaHostAddressLimit;
    Status = gBS->AllocatePages (
                    AllocateMaxAddress,
                    MemoryType,
                    RealPages,
                    &Memory
                    );
    if (EFI_ERROR (Status)) {
      return NULL;
    }

    AlignedMemory  = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask;
    UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory);
    if (UnalignedPages > 0) {
      //
      // Free first unaligned page(s).
      //
      Status = gBS->FreePages (Memory, UnalignedPages);
      ASSERT_EFI_ERROR (Status);
    }

    Memory         = AlignedMemory + EFI_PAGES_TO_SIZE (Pages);
    UnalignedPages = RealPages - Pages - UnalignedPages;
    if (UnalignedPages > 0) {
      //
      // Free last unaligned page(s).
      //
      Status = gBS->FreePages (Memory, UnalignedPages);
      ASSERT_EFI_ERROR (Status);
    }
  } else {
    //
    // Do not over-allocate pages in this case.
    //
    Memory = mDmaHostAddressLimit;
    Status = gBS->AllocatePages (
                    AllocateMaxAddress,
                    MemoryType,
                    Pages,
                    &Memory
                    );
    if (EFI_ERROR (Status)) {
      return NULL;
    }

    AlignedMemory = (UINTN)Memory;
  }

  return (VOID *)AlignedMemory;
}

/**
  Provides the DMA controller-specific addresses needed to access system memory.

  Operation is relative to the DMA bus master.

  @param  Operation             Indicates if the bus master is going to read or
                                write to system memory.
  @param  HostAddress           The system memory address to map to the DMA
                                controller.
  @param  NumberOfBytes         On input the number of bytes to map. On output
                                the number of bytes that were mapped.
  @param  DeviceAddress         The resulting map address for the bus master
                                controller to use to access the host's
                                HostAddress.
  @param  Mapping               A resulting value to pass to Unmap().

  @retval EFI_SUCCESS           The range was mapped for the returned
                                NumberOfBytes.
  @retval EFI_UNSUPPORTED       The HostAddress cannot be mapped as a common
                                buffer.
  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack
                                of resources.
  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested
                                address.

**/
EFI_STATUS
EFIAPI
DmaMap (
  IN     DMA_MAP_OPERATION  Operation,
  IN     VOID               *HostAddress,
  IN OUT UINTN              *NumberOfBytes,
  OUT    PHYSICAL_ADDRESS   *DeviceAddress,
  OUT    VOID               **Mapping
  )
{
  EFI_STATUS                       Status;
  MAP_INFO_INSTANCE                *Map;
  VOID                             *Buffer;
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  GcdDescriptor;
  UINTN                            AllocSize;

  if ((HostAddress == NULL) ||
      (NumberOfBytes == NULL) ||
      (DeviceAddress == NULL) ||
      (Mapping == NULL))
  {
    return EFI_INVALID_PARAMETER;
  }

  if (Operation >= MapOperationMaximum) {
    return EFI_INVALID_PARAMETER;
  }

  *DeviceAddress = HostToDeviceAddress (HostAddress);

  // Remember range so we can flush on the other side
  Map = AllocatePool (sizeof (MAP_INFO_INSTANCE));
  if (Map == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (((UINTN)HostAddress + *NumberOfBytes) > mDmaHostAddressLimit) {
    if (Operation == MapOperationBusMasterCommonBuffer) {
      goto CommonBufferError;
    }

    AllocSize          = ALIGN_VALUE (*NumberOfBytes, mCpu->DmaBufferAlignment);
    Map->BufferAddress = InternalAllocateAlignedPages (
                           EfiBootServicesData,
                           EFI_SIZE_TO_PAGES (AllocSize),
                           mCpu->DmaBufferAlignment
                           );
    if (Map->BufferAddress == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto FreeMapInfo;
    }

    if (Operation == MapOperationBusMasterRead) {
      CopyMem (Map->BufferAddress, (VOID *)(UINTN)HostAddress, *NumberOfBytes);
    }

    mCpu->FlushDataCache (
            mCpu,
            (UINTN)Map->BufferAddress,
            AllocSize,
            EfiCpuFlushTypeWriteBack
            );

    *DeviceAddress = HostToDeviceAddress (Map->BufferAddress);
  } else if ((Operation != MapOperationBusMasterRead) &&
             ((((UINTN)HostAddress & (mCpu->DmaBufferAlignment - 1)) != 0) ||
              ((*NumberOfBytes & (mCpu->DmaBufferAlignment - 1)) != 0)))
  {
    // Get the cacheability of the region
    Status = gDS->GetMemorySpaceDescriptor ((UINTN)HostAddress, &GcdDescriptor);
    if (EFI_ERROR (Status)) {
      goto FreeMapInfo;
    }

    // If the mapped buffer is not an uncached buffer
    if ((GcdDescriptor.Attributes & (EFI_MEMORY_WB | EFI_MEMORY_WT)) != 0) {
      //
      // Operations of type MapOperationBusMasterCommonBuffer are only allowed
      // on uncached buffers.
      //
      if (Operation == MapOperationBusMasterCommonBuffer) {
        goto CommonBufferError;
      }

      //
      // If the buffer does not fill entire cache lines we must double buffer
      // into a suitably aligned allocation that allows us to invalidate the
      // cache without running the risk of corrupting adjacent unrelated data.
      // Note that pool allocations are guaranteed to be 8 byte aligned, so
      // we only have to add (alignment - 8) worth of padding.
      //
      Map->DoubleBuffer = TRUE;
      AllocSize         = ALIGN_VALUE (*NumberOfBytes, mCpu->DmaBufferAlignment) +
                          (mCpu->DmaBufferAlignment - 8);
      Map->BufferAddress = AllocatePool (AllocSize);
      if (Map->BufferAddress == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto FreeMapInfo;
      }

      Buffer         = ALIGN_POINTER (Map->BufferAddress, mCpu->DmaBufferAlignment);
      *DeviceAddress = HostToDeviceAddress (Buffer);

      //
      // Get rid of any dirty cachelines covering the double buffer. This
      // prevents them from being written back unexpectedly, potentially
      // overwriting the data we receive from the device.
      //
      mCpu->FlushDataCache (
              mCpu,
              (UINTN)Buffer,
              *NumberOfBytes,
              EfiCpuFlushTypeWriteBack
              );
    } else {
      Map->DoubleBuffer = FALSE;
    }
  } else {
    Map->DoubleBuffer = FALSE;

    DEBUG_CODE_BEGIN ();

    //
    // The operation type check above only executes if the buffer happens to be
    // misaligned with respect to CWG, but even if it is aligned, we should not
    // allow arbitrary buffers to be used for creating consistent mappings.
    // So duplicate the check here when running in DEBUG mode, just to assert
    // that we are not trying to create a consistent mapping for cached memory.
    //
    Status = gDS->GetMemorySpaceDescriptor ((UINTN)HostAddress, &GcdDescriptor);
    ASSERT_EFI_ERROR (Status);

    ASSERT (
      Operation != MapOperationBusMasterCommonBuffer ||
      (GcdDescriptor.Attributes & (EFI_MEMORY_WB | EFI_MEMORY_WT)) == 0
      );

    DEBUG_CODE_END ();

    // Flush the Data Cache (should not have any effect if the memory region is
    // uncached)
    mCpu->FlushDataCache (
            mCpu,
            (UINTN)HostAddress,
            *NumberOfBytes,
            EfiCpuFlushTypeWriteBackInvalidate
            );
  }

  Map->HostAddress   = (UINTN)HostAddress;
  Map->NumberOfBytes = *NumberOfBytes;
  Map->Operation     = Operation;

  *Mapping = Map;

  return EFI_SUCCESS;

CommonBufferError:
  DEBUG ((
    DEBUG_ERROR,
    "%a: Operation type 'MapOperationBusMasterCommonBuffer' is only "
    "supported\non memory regions that were allocated using "
    "DmaAllocateBuffer ()\n",
    __FUNCTION__
    ));
  Status = EFI_UNSUPPORTED;
FreeMapInfo:
  FreePool (Map);

  return Status;
}

/**
  Completes the DmaMapBusMasterRead(), DmaMapBusMasterWrite(), or
  DmaMapBusMasterCommonBuffer() operation and releases any corresponding
  resources.

  @param  Mapping               The mapping value returned from DmaMap*().

  @retval EFI_SUCCESS           The range was unmapped.
  @retval EFI_DEVICE_ERROR      The data was not committed to the target system
                                memory.
  @retval EFI_INVALID_PARAMETER An inconsistency was detected between the
                                mapping type and the DoubleBuffer field

**/
EFI_STATUS
EFIAPI
DmaUnmap (
  IN  VOID  *Mapping
  )
{
  MAP_INFO_INSTANCE  *Map;
  EFI_STATUS         Status;
  VOID               *Buffer;
  UINTN              AllocSize;

  if (Mapping == NULL) {
    ASSERT (FALSE);
    return EFI_INVALID_PARAMETER;
  }

  Map = (MAP_INFO_INSTANCE *)Mapping;

  Status = EFI_SUCCESS;
  if (((UINTN)Map->HostAddress + Map->NumberOfBytes) > mDmaHostAddressLimit) {
    AllocSize = ALIGN_VALUE (Map->NumberOfBytes, mCpu->DmaBufferAlignment);
    if (Map->Operation == MapOperationBusMasterWrite) {
      mCpu->FlushDataCache (
              mCpu,
              (UINTN)Map->BufferAddress,
              AllocSize,
              EfiCpuFlushTypeInvalidate
              );
      CopyMem (
        (VOID *)(UINTN)Map->HostAddress,
        Map->BufferAddress,
        Map->NumberOfBytes
        );
    }

    FreePages (Map->BufferAddress, EFI_SIZE_TO_PAGES (AllocSize));
  } else if (Map->DoubleBuffer) {
    ASSERT (Map->Operation == MapOperationBusMasterWrite);

    if (Map->Operation != MapOperationBusMasterWrite) {
      Status = EFI_INVALID_PARAMETER;
    } else {
      Buffer = ALIGN_POINTER (Map->BufferAddress, mCpu->DmaBufferAlignment);

      mCpu->FlushDataCache (
              mCpu,
              (UINTN)Buffer,
              Map->NumberOfBytes,
              EfiCpuFlushTypeInvalidate
              );

      CopyMem ((VOID *)(UINTN)Map->HostAddress, Buffer, Map->NumberOfBytes);

      FreePool (Map->BufferAddress);
    }
  } else {
    if (Map->Operation == MapOperationBusMasterWrite) {
      //
      // Make sure we read buffer from uncached memory and not the cache
      //
      mCpu->FlushDataCache (
              mCpu,
              Map->HostAddress,
              Map->NumberOfBytes,
              EfiCpuFlushTypeInvalidate
              );
    }
  }

  FreePool (Map);

  return Status;
}

/**
  Allocates pages that are suitable for an DmaMap() of type
  MapOperationBusMasterCommonBuffer mapping.

  @param  MemoryType            The type of memory to allocate,
                                EfiBootServicesData or EfiRuntimeServicesData.
  @param  Pages                 The number of pages to allocate.
  @param  HostAddress           A pointer to store the base system memory
                                address of the allocated range.

  @retval EFI_SUCCESS           The requested memory pages were allocated.
  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
  @retval EFI_OUT_OF_RESOURCES  The memory pages could not be allocated.

**/
EFI_STATUS
EFIAPI
DmaAllocateBuffer (
  IN  EFI_MEMORY_TYPE  MemoryType,
  IN  UINTN            Pages,
  OUT VOID             **HostAddress
  )
{
  return DmaAllocateAlignedBuffer (MemoryType, Pages, 0, HostAddress);
}

/**
  Allocates pages that are suitable for an DmaMap() of type
  MapOperationBusMasterCommonBuffer mapping, at the requested alignment.

  @param  MemoryType            The type of memory to allocate,
                                EfiBootServicesData or EfiRuntimeServicesData.
  @param  Pages                 The number of pages to allocate.
  @param  Alignment             Alignment in bytes of the base of the returned
                                buffer (must be a power of 2)
  @param  HostAddress           A pointer to store the base system memory
                                address of the allocated range.

  @retval EFI_SUCCESS           The requested memory pages were allocated.
  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
  @retval EFI_OUT_OF_RESOURCES  The memory pages could not be allocated.

**/
EFI_STATUS
EFIAPI
DmaAllocateAlignedBuffer (
  IN  EFI_MEMORY_TYPE  MemoryType,
  IN  UINTN            Pages,
  IN  UINTN            Alignment,
  OUT VOID             **HostAddress
  )
{
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  GcdDescriptor;
  VOID                             *Allocation;
  UINT64                           MemType;
  UNCACHED_ALLOCATION              *Alloc;
  EFI_STATUS                       Status;

  if (Alignment == 0) {
    Alignment = EFI_PAGE_SIZE;
  }

  if ((HostAddress == NULL) ||
      ((Alignment & (Alignment - 1)) != 0))
  {
    return EFI_INVALID_PARAMETER;
  }

  if ((MemoryType == EfiBootServicesData) ||
      (MemoryType == EfiRuntimeServicesData))
  {
    Allocation = InternalAllocateAlignedPages (MemoryType, Pages, Alignment);
  } else {
    return EFI_INVALID_PARAMETER;
  }

  if (Allocation == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  // Get the cacheability of the region
  Status = gDS->GetMemorySpaceDescriptor ((UINTN)Allocation, &GcdDescriptor);
  if (EFI_ERROR (Status)) {
    goto FreeBuffer;
  }

  // Choose a suitable uncached memory type that is supported by the region
  if (GcdDescriptor.Capabilities & EFI_MEMORY_WC) {
    MemType = EFI_MEMORY_WC;
  } else if (GcdDescriptor.Capabilities & EFI_MEMORY_UC) {
    MemType = EFI_MEMORY_UC;
  } else {
    Status = EFI_UNSUPPORTED;
    goto FreeBuffer;
  }

  Alloc = AllocatePool (sizeof *Alloc);
  if (Alloc == NULL) {
    goto FreeBuffer;
  }

  Alloc->HostAddress = Allocation;
  Alloc->NumPages    = Pages;
  Alloc->Attributes  = GcdDescriptor.Attributes;

  InsertHeadList (&UncachedAllocationList, &Alloc->Link);

  // Remap the region with the new attributes
  Status = gDS->SetMemorySpaceAttributes (
                  (PHYSICAL_ADDRESS)(UINTN)Allocation,
                  EFI_PAGES_TO_SIZE (Pages),
                  MemType
                  );
  if (EFI_ERROR (Status)) {
    goto FreeAlloc;
  }

  Status = mCpu->FlushDataCache (
                   mCpu,
                   (PHYSICAL_ADDRESS)(UINTN)Allocation,
                   EFI_PAGES_TO_SIZE (Pages),
                   EfiCpuFlushTypeInvalidate
                   );
  if (EFI_ERROR (Status)) {
    goto FreeAlloc;
  }

  *HostAddress = Allocation;

  return EFI_SUCCESS;

FreeAlloc:
  RemoveEntryList (&Alloc->Link);
  FreePool (Alloc);

FreeBuffer:
  FreePages (Allocation, Pages);
  return Status;
}

/**
  Frees memory that was allocated with DmaAllocateBuffer().

  @param  Pages                 The number of pages to free.
  @param  HostAddress           The base system memory address of the allocated
                                range.

  @retval EFI_SUCCESS           The requested memory pages were freed.
  @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and
                                Pages was not allocated with
                                DmaAllocateBuffer().

**/
EFI_STATUS
EFIAPI
DmaFreeBuffer (
  IN  UINTN  Pages,
  IN  VOID   *HostAddress
  )
{
  LIST_ENTRY           *Link;
  UNCACHED_ALLOCATION  *Alloc;
  BOOLEAN              Found;
  EFI_STATUS           Status;

  if (HostAddress == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  for (Link = GetFirstNode (&UncachedAllocationList), Found = FALSE;
       !IsNull (&UncachedAllocationList, Link);
       Link = GetNextNode (&UncachedAllocationList, Link))
  {
    Alloc = BASE_CR (Link, UNCACHED_ALLOCATION, Link);
    if ((Alloc->HostAddress == HostAddress) && (Alloc->NumPages == Pages)) {
      Found = TRUE;
      break;
    }
  }

  if (!Found) {
    ASSERT (FALSE);
    return EFI_INVALID_PARAMETER;
  }

  RemoveEntryList (&Alloc->Link);

  Status = gDS->SetMemorySpaceAttributes (
                  (PHYSICAL_ADDRESS)(UINTN)HostAddress,
                  EFI_PAGES_TO_SIZE (Pages),
                  Alloc->Attributes
                  );
  if (EFI_ERROR (Status)) {
    goto FreeAlloc;
  }

  //
  // If we fail to restore the original attributes, it is better to leak the
  // memory than to return it to the heap
  //
  FreePages (HostAddress, Pages);

FreeAlloc:
  FreePool (Alloc);
  return Status;
}

EFI_STATUS
EFIAPI
NonCoherentDmaLibConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  InitializeListHead (&UncachedAllocationList);

  //
  // Ensure that the combination of DMA addressing offset and limit produces
  // a sane value.
  //
  ASSERT (PcdGet64 (PcdDmaDeviceLimit) > PcdGet64 (PcdDmaDeviceOffset));

  mDmaHostAddressLimit = PcdGet64 (PcdDmaDeviceLimit) -
                         PcdGet64 (PcdDmaDeviceOffset);

  // Get the Cpu protocol for later use
  return gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&mCpu);
}
