/** @file
  Instance of SMM IO check library.

  SMM IO check library library implementation. This library consumes GCD to collect all valid
  IO space defined by a platform.
  A platform may have its own SmmIoLib instance to exclude more IO space.

  Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/


#include <PiSmm.h>

#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/SmmServicesTableLib.h>
#include <Library/HobLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Protocol/SmmReadyToLock.h>
#include <Protocol/SmmEndOfDxe.h>

EFI_GCD_MEMORY_SPACE_DESCRIPTOR   *mSmmIoLibGcdMemSpace       = NULL;
UINTN                             mSmmIoLibGcdMemNumberOfDesc = 0;

EFI_PHYSICAL_ADDRESS  mSmmIoLibInternalMaximumSupportMemAddress = 0;

VOID                  *mSmmIoLibRegistrationEndOfDxe;
VOID                  *mSmmIoLibRegistrationReadyToLock;

BOOLEAN               mSmmIoLibReadyToLock = FALSE;

/**
  Calculate and save the maximum support address.

**/
VOID
SmmIoLibInternalCalculateMaximumSupportAddress (
  VOID
  )
{
  VOID         *Hob;
  UINT32       RegEax;
  UINT8        MemPhysicalAddressBits;

  //
  // Get physical address bits supported.
  //
  Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
  if (Hob != NULL) {
    MemPhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;
  } else {
    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
    if (RegEax >= 0x80000008) {
      AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
      MemPhysicalAddressBits = (UINT8) RegEax;
    } else {
      MemPhysicalAddressBits = 36;
    }
  }
  //
  // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.
  //
  ASSERT (MemPhysicalAddressBits <= 52);
  if (MemPhysicalAddressBits > 48) {
    MemPhysicalAddressBits = 48;
  }

  //
  // Save the maximum support address in one global variable
  //
  mSmmIoLibInternalMaximumSupportMemAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)(LShiftU64 (1, MemPhysicalAddressBits) - 1);
  DEBUG ((DEBUG_INFO, "mSmmIoLibInternalMaximumSupportMemAddress = 0x%lx\n", mSmmIoLibInternalMaximumSupportMemAddress));
}

/**
  This function check if the MMIO resource is valid per processor architecture and
  valid per platform design.

  @param BaseAddress  The MMIO start address to be checked.
  @param Length       The MMIO length to be checked.
  @param Owner        A GUID representing the owner of the resource.
                      This GUID may be used by producer to correlate the device ownership of the resource.
                      NULL means no specific owner.

  @retval TRUE  This MMIO resource is valid per processor architecture and valid per platform design.
  @retval FALSE This MMIO resource is not valid per processor architecture or valid per platform design.
**/
BOOLEAN
EFIAPI
SmmIsMmioValid (
  IN EFI_PHYSICAL_ADDRESS  BaseAddress,
  IN UINT64                Length,
  IN EFI_GUID              *Owner  OPTIONAL
  )
{
  UINTN                           Index;
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Desc;
  BOOLEAN                         InValidRegion;

  //
  // Check override.
  // NOTE: (B:0->L:4G) is invalid for IA32, but (B:1->L:4G-1)/(B:4G-1->L:1) is valid.
  //
  if ((Length > mSmmIoLibInternalMaximumSupportMemAddress) ||
      (BaseAddress > mSmmIoLibInternalMaximumSupportMemAddress) ||
      ((Length != 0) && (BaseAddress > (mSmmIoLibInternalMaximumSupportMemAddress - (Length - 1)))) ) {
    //
    // Overflow happen
    //
    DEBUG ((
      DEBUG_ERROR,
      "SmmIsMmioValid: Overflow: BaseAddress (0x%lx) - Length (0x%lx), MaximumSupportMemAddress (0x%lx)\n",
      BaseAddress,
      Length,
      mSmmIoLibInternalMaximumSupportMemAddress
      ));
    return FALSE;
  }

  //
  // Check override for valid MMIO region
  //
  if (mSmmIoLibReadyToLock) {
    InValidRegion = FALSE;
    for (Index = 0; Index < mSmmIoLibGcdMemNumberOfDesc; Index ++) {
      Desc = &mSmmIoLibGcdMemSpace[Index];
      if ((Desc->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) &&
          (BaseAddress >= Desc->BaseAddress) &&
          ((BaseAddress + Length) <= (Desc->BaseAddress + Desc->Length))) {
        InValidRegion = TRUE;
      }
    }

    if (!InValidRegion) {
      DEBUG ((
        DEBUG_ERROR,
        "SmmIsMmioValid: Not in valid MMIO region: BaseAddress (0x%lx) - Length (0x%lx)\n",
        BaseAddress,
        Length
        ));
      return FALSE;
    }
  }
  return TRUE;
}

/**
  Merge continuous entries whose type is EfiGcdMemoryTypeMemoryMappedIo.

  @param[in, out]  GcdMemoryMap           A pointer to the buffer in which firmware places
                                          the current GCD memory map.
  @param[in, out]  NumberOfDescriptors    A pointer to the number of the
                                          GcdMemoryMap buffer. On input, this is the number of
                                          the current GCD memory map.  On output,
                                          it is the number of new GCD memory map after merge.
**/
STATIC
VOID
MergeGcdMmioEntry (
  IN OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *GcdMemoryMap,
  IN OUT UINTN                            *NumberOfDescriptors
  )
{
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR       *GcdMemoryMapEntry;
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR       *GcdMemoryMapEnd;
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR       *NewGcdMemoryMapEntry;
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR       *NextGcdMemoryMapEntry;

  GcdMemoryMapEntry = GcdMemoryMap;
  NewGcdMemoryMapEntry = GcdMemoryMap;
  GcdMemoryMapEnd = (EFI_GCD_MEMORY_SPACE_DESCRIPTOR *) ((UINT8 *) GcdMemoryMap + (*NumberOfDescriptors) * sizeof(EFI_GCD_MEMORY_SPACE_DESCRIPTOR));
  while ((UINTN)GcdMemoryMapEntry < (UINTN)GcdMemoryMapEnd) {
    CopyMem (NewGcdMemoryMapEntry, GcdMemoryMapEntry, sizeof(EFI_GCD_MEMORY_SPACE_DESCRIPTOR));
    NextGcdMemoryMapEntry = GcdMemoryMapEntry + 1;

    do {
      if (((UINTN)NextGcdMemoryMapEntry < (UINTN)GcdMemoryMapEnd) &&
          (GcdMemoryMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) && (NextGcdMemoryMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) &&
          ((GcdMemoryMapEntry->BaseAddress + GcdMemoryMapEntry->Length) == NextGcdMemoryMapEntry->BaseAddress)) {
        GcdMemoryMapEntry->Length += NextGcdMemoryMapEntry->Length;
        if (NewGcdMemoryMapEntry != GcdMemoryMapEntry) {
          NewGcdMemoryMapEntry->Length += NextGcdMemoryMapEntry->Length;
        }

        NextGcdMemoryMapEntry = NextGcdMemoryMapEntry + 1;
        continue;
      } else {
        GcdMemoryMapEntry = NextGcdMemoryMapEntry - 1;
        break;
      }
    } while (TRUE);

    GcdMemoryMapEntry = GcdMemoryMapEntry + 1;
    NewGcdMemoryMapEntry = NewGcdMemoryMapEntry + 1;
  }

  *NumberOfDescriptors = ((UINTN)NewGcdMemoryMapEntry - (UINTN)GcdMemoryMap) / sizeof(EFI_GCD_MEMORY_SPACE_DESCRIPTOR);

  return ;
}

/**
  Notification for SMM EndOfDxe protocol.

  @param[in] Protocol   Points to the protocol's unique identifier.
  @param[in] Interface  Points to the interface instance.
  @param[in] Handle     The handle on which the interface was installed.

  @retval EFI_SUCCESS           Notification runs successfully.
  @retval EFI_OUT_OF_RESOURCES  No enough resources to save GCD MMIO map.
**/
EFI_STATUS
EFIAPI
SmmIoLibInternalEndOfDxeNotify (
  IN CONST EFI_GUID  *Protocol,
  IN VOID            *Interface,
  IN EFI_HANDLE      Handle
  )
{
  UINTN                            NumberOfDescriptors;
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  *MemSpaceMap;
  EFI_STATUS                       Status;

  Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemSpaceMap);
  if (!EFI_ERROR (Status)) {

    MergeGcdMmioEntry (MemSpaceMap, &NumberOfDescriptors);

    mSmmIoLibGcdMemSpace = AllocateCopyPool (NumberOfDescriptors * sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR), MemSpaceMap);
    ASSERT (mSmmIoLibGcdMemSpace != NULL);
    if (mSmmIoLibGcdMemSpace == NULL) {
      gBS->FreePool (MemSpaceMap);
      return EFI_OUT_OF_RESOURCES;
    }

    mSmmIoLibGcdMemNumberOfDesc = NumberOfDescriptors;
    gBS->FreePool (MemSpaceMap);
  }

  return EFI_SUCCESS;
}

/**
  Notification for SMM ReadyToLock protocol.

  @param[in] Protocol   Points to the protocol's unique identifier.
  @param[in] Interface  Points to the interface instance.
  @param[in] Handle     The handle on which the interface was installed.

  @retval EFI_SUCCESS   Notification runs successfully.
**/
EFI_STATUS
EFIAPI
SmmIoLibInternalReadyToLockNotify (
  IN CONST EFI_GUID  *Protocol,
  IN VOID            *Interface,
  IN EFI_HANDLE      Handle
  )
{
  mSmmIoLibReadyToLock = TRUE;
  return EFI_SUCCESS;
}

/**
  The constructor function initializes the Smm IO library

  @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
SmmIoLibConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS                    Status;

  //
  // Calculate and save maximum support address
  //
  SmmIoLibInternalCalculateMaximumSupportAddress ();

  //
  // Register EndOfDxe to get GCD resource map
  //
  Status = gSmst->SmmRegisterProtocolNotify (&gEfiSmmEndOfDxeProtocolGuid, SmmIoLibInternalEndOfDxeNotify, &mSmmIoLibRegistrationEndOfDxe);
  ASSERT_EFI_ERROR (Status);

  //
  // Register ready to lock so that we can know when to check valid resource region
  //
  Status = gSmst->SmmRegisterProtocolNotify (&gEfiSmmReadyToLockProtocolGuid, SmmIoLibInternalReadyToLockNotify, &mSmmIoLibRegistrationReadyToLock);
  ASSERT_EFI_ERROR (Status);

  return EFI_SUCCESS;
}

/**
  The destructor function frees resource used in the Smm IO library

  @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 deconstructor always returns EFI_SUCCESS.
**/
EFI_STATUS
EFIAPI
SmmIoLibDestructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  gSmst->SmmRegisterProtocolNotify (&gEfiSmmEndOfDxeProtocolGuid, NULL, &mSmmIoLibRegistrationEndOfDxe);
  gSmst->SmmRegisterProtocolNotify (&gEfiSmmReadyToLockProtocolGuid, NULL, &mSmmIoLibRegistrationReadyToLock);
  return EFI_SUCCESS;
}
