/** @file

  Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Uefi.h>
#include <Library/BaseLib.h>
#include <Library/CacheLib.h>
#include <Library/CacheAsRamLib.h>
#include "CacheLibInternal.h"

/**
  Search the memory cache type for specific memory from MTRR.

  @param[in]  MemoryAddress         the address of target memory
  @param[in]  MemoryLength          the length of target memory
  @param[in]  ValidMtrrAddressMask  the MTRR address mask
  @param[out] UsedMsrNum            the used MSR number
  @param[out] UsedMemoryCacheType   the cache type for the target memory

  @retval EFI_SUCCESS    The memory is found in MTRR and cache type is returned
  @retval EFI_NOT_FOUND  The memory is not found in MTRR

**/
EFI_STATUS
SearchForExactMtrr (
  IN  EFI_PHYSICAL_ADDRESS      MemoryAddress,
  IN  UINT64                    MemoryLength,
  IN  UINT64                    ValidMtrrAddressMask,
  OUT UINT32                    *UsedMsrNum,
  OUT EFI_MEMORY_CACHE_TYPE     *MemoryCacheType
  );

/**
  Check if CacheType match current default setting.

  @param[in] MemoryCacheType  input cache type to be checked.

  @retval TRUE MemoryCacheType is default MTRR setting.
  @retval FALSE MemoryCacheType is NOT default MTRR setting.
**/
BOOLEAN
IsDefaultType (
  IN  EFI_MEMORY_CACHE_TYPE     MemoryCacheType
  );

/**
  Return MTRR alignment requirement for base address and size.

  @param[in]  BaseAddress     Base address.
  @param[in]  Size            Size.

  @retval Zero      Aligned.
  @retval Non-Zero  Not aligned.

**/
UINT32
CheckMtrrAlignment (
  IN  UINT64                    BaseAddress,
  IN  UINT64                    Size
  );

typedef struct {
  UINT32    Msr;
  UINT32    BaseAddress;
  UINT32    Length;
} EFI_FIXED_MTRR;

EFI_FIXED_MTRR mFixedMtrrTable[] = {
  { EFI_MSR_IA32_MTRR_FIX64K_00000, 0,       0x10000},
  { EFI_MSR_IA32_MTRR_FIX16K_80000, 0x80000, 0x4000},
  { EFI_MSR_IA32_MTRR_FIX16K_A0000, 0xA0000, 0x4000},
  { EFI_MSR_IA32_MTRR_FIX4K_C0000,  0xC0000, 0x1000},
  { EFI_MSR_IA32_MTRR_FIX4K_C8000,  0xC8000, 0x1000},
  { EFI_MSR_IA32_MTRR_FIX4K_D0000,  0xD0000, 0x1000},
  { EFI_MSR_IA32_MTRR_FIX4K_D8000,  0xD8000, 0x1000},
  { EFI_MSR_IA32_MTRR_FIX4K_E0000,  0xE0000, 0x1000},
  { EFI_MSR_IA32_MTRR_FIX4K_E8000,  0xE8000, 0x1000},
  { EFI_MSR_IA32_MTRR_FIX4K_F0000,  0xF0000, 0x1000},
  { EFI_MSR_IA32_MTRR_FIX4K_F8000,  0xF8000, 0x1000}
};

/**
  Given the input, check if the number of MTRR is lesser.
  if positive or subtractive.

  @param[in]  Input   Length of Memory to program MTRR.

  @retval  Zero      do positive.
  @retval  Non-Zero  do subtractive.

**/
INT8
CheckDirection (
  IN  UINT64                    Input
  )
{
  return 0;
}

/**
  Disable cache and its mtrr.

  @param[out]  OldMtrr To return the Old MTRR value

**/
VOID
EfiDisableCacheMtrr (
  OUT UINT64                   *OldMtrr
  )
{
  UINT64  TempQword;

  //
  // Disable Cache MTRR
  //
  *OldMtrr = AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE);
  TempQword = (*OldMtrr) & ~B_EFI_MSR_GLOBAL_MTRR_ENABLE & ~B_EFI_MSR_FIXED_MTRR_ENABLE;
  AsmWriteMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, TempQword);
  AsmDisableCache ();
}

/**
  Recover cache MTRR.

  @param[in] EnableMtrr Whether to enable the MTRR
  @param[in] OldMtrr    The saved old MTRR value to restore when not to enable the MTRR

**/
VOID
EfiRecoverCacheMtrr (
  IN BOOLEAN                  EnableMtrr,
  IN UINT64                   OldMtrr
  )
{
  UINT64  TempQword;

  //
  // Enable Cache MTRR
  //
  if (EnableMtrr) {
    TempQword = AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE);
    TempQword |= (UINT64)(B_EFI_MSR_GLOBAL_MTRR_ENABLE | B_EFI_MSR_FIXED_MTRR_ENABLE);
  } else {
    TempQword = OldMtrr;
  }

  AsmWriteMsr64 (EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, TempQword);

  AsmEnableCache ();
}

/**
  Programming MTRR according to Memory address, length, and type.

  @param[in] MtrrNumber           the variable MTRR index number
  @param[in] MemoryAddress        the address of target memory
  @param[in] MemoryLength         the length of target memory
  @param[in] MemoryCacheType      the cache type of target memory
  @param[in] ValidMtrrAddressMask the MTRR address mask

**/
VOID
EfiProgramMtrr (
  IN  UINTN                     MtrrNumber,
  IN  EFI_PHYSICAL_ADDRESS      MemoryAddress,
  IN  UINT64                    MemoryLength,
  IN  EFI_MEMORY_CACHE_TYPE     MemoryCacheType,
  IN  UINT64                    ValidMtrrAddressMask
  )
{
  UINT64                        TempQword;
  UINT64                        OldMtrr;

  if (MemoryLength == 0) {
    return;
  }

  EfiDisableCacheMtrr (&OldMtrr);

  //
  // MTRR Physical Base
  //
  TempQword = (MemoryAddress & ValidMtrrAddressMask) | MemoryCacheType;
  AsmWriteMsr64 (MtrrNumber, TempQword);

  //
  // MTRR Physical Mask
  //
  TempQword = ~(MemoryLength - 1);
  AsmWriteMsr64 (MtrrNumber + 1, (TempQword & ValidMtrrAddressMask) | B_EFI_MSR_CACHE_MTRR_VALID);

  EfiRecoverCacheMtrr (TRUE, OldMtrr);
}

/**
  Calculate the maximum value which is a power of 2, but less the MemoryLength.

  @param[in]  MemoryAddress       Memory address.
  @param[in]  MemoryLength        The number to pass in.

  @return The maximum value which is align to power of 2 and less the MemoryLength

**/
UINT64
Power2MaxMemory (
  IN UINT64                 MemoryAddress,
  IN UINT64                 MemoryLength
  )
{
  UINT64                    Result;

  if (MemoryLength == 0) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Compute initial power of 2 size to return
  //
  Result = GetPowerOfTwo64(MemoryLength);

  //
  // Special case base of 0 as all ranges are valid
  //
  if (MemoryAddress == 0) {
    return Result;
  }

  //
  // Loop till a value that can be mapped to this base address is found
  //
  while (CheckMtrrAlignment (MemoryAddress, Result) != 0) {
    //
    // Need to try the next smaller power of 2
    //
    Result = RShiftU64 (Result, 1);
  }

  return Result;
}

/**
  Return MTRR alignment requirement for base address and size.

  @param[in]  BaseAddress     Base address.
  @param[in]  Size            Size.

  @retval Zero      Aligned.
  @retval Non-Zero  Not aligned.

**/
UINT32
CheckMtrrAlignment (
  IN  UINT64    BaseAddress,
  IN  UINT64    Size
  )
{
  UINT32      ShiftedBase;
  UINT32      ShiftedSize;

  //
  // Shift base and size right 12 bits to allow for larger memory sizes.  The
  // MTRRs do not use the first 12 bits so this is safe for now.  Only supports
  // up to 52 bits of physical address space.
  //
  ShiftedBase = (UINT32) RShiftU64 (BaseAddress, 12);
  ShiftedSize = (UINT32) RShiftU64 (Size, 12);

  //
  // Return the results to the caller of the MOD
  //
  return ShiftedBase % ShiftedSize;
}

/**
  Programs fixed MTRRs registers.

  @param[in]  MemoryCacheType  The memory type to set.
  @param[in]  Base             The base address of memory range.
  @param[in]  Length           The length of memory range.

  @retval RETURN_SUCCESS      The cache type was updated successfully
  @retval RETURN_UNSUPPORTED  The requested range or cache type was invalid
                              for the fixed MTRRs.

**/
EFI_STATUS
ProgramFixedMtrr (
  IN  EFI_MEMORY_CACHE_TYPE     MemoryCacheType,
  IN  UINT64                    *Base,
  IN  UINT64                    *Len
  )
{
  UINT32                      MsrNum;
  UINT32                      ByteShift;
  UINT64                      TempQword;
  UINT64                      OrMask;
  UINT64                      ClearMask;

  TempQword = 0;
  OrMask =  0;
  ClearMask = 0;

  for (MsrNum = 0; MsrNum < V_EFI_FIXED_MTRR_NUMBER; MsrNum++) {
    if ((*Base >= mFixedMtrrTable[MsrNum].BaseAddress) &&
        (*Base < (mFixedMtrrTable[MsrNum].BaseAddress + 8 * mFixedMtrrTable[MsrNum].Length))) {
      break;
    }
  }
  if (MsrNum == V_EFI_FIXED_MTRR_NUMBER ) {
    return EFI_DEVICE_ERROR;
  }
  //
  // We found the fixed MTRR to be programmed
  //
  for (ByteShift=0; ByteShift < 8; ByteShift++) {
    if ( *Base == (mFixedMtrrTable[MsrNum].BaseAddress + ByteShift * mFixedMtrrTable[MsrNum].Length)) {
      break;
    }
  }
  if (ByteShift == 8 ) {
    return EFI_DEVICE_ERROR;
  }
  for (; ((ByteShift<8) && (*Len >= mFixedMtrrTable[MsrNum].Length));ByteShift++) {
    OrMask |= LShiftU64((UINT64) MemoryCacheType, (UINT32) (ByteShift* 8));
    ClearMask |= LShiftU64((UINT64) 0xFF, (UINT32) (ByteShift * 8));
    *Len -= mFixedMtrrTable[MsrNum].Length;
    *Base += mFixedMtrrTable[MsrNum].Length;
  }
  TempQword = (AsmReadMsr64 (mFixedMtrrTable[MsrNum].Msr) & (~ClearMask)) | OrMask;
  AsmWriteMsr64 (mFixedMtrrTable[MsrNum].Msr, TempQword);

  return EFI_SUCCESS;
}

/**
  Check if there is a valid variable MTRR that overlaps the given range.

  @param[in]  Start  Base Address of the range to check.
  @param[in]  End    End address of the range to check.

  @retval TRUE   Mtrr overlap.
  @retval FALSE  Mtrr not overlap.
**/
BOOLEAN
CheckMtrrOverlap (
  IN  EFI_PHYSICAL_ADDRESS      Start,
  IN  EFI_PHYSICAL_ADDRESS      End
  )
{
  return FALSE;
}

/**
  Given the memory range and cache type, programs the MTRRs.

  @param[in] MemoryAddress           Base Address of Memory to program MTRR.
  @param[in] MemoryLength            Length of Memory to program MTRR.
  @param[in] MemoryCacheType         Cache Type.

  @retval EFI_SUCCESS            Mtrr are set successfully.
  @retval EFI_LOAD_ERROR         No empty MTRRs to use.
  @retval EFI_INVALID_PARAMETER  The input parameter is not valid.
  @retval others                 An error occurs when setting MTTR.

**/
EFI_STATUS
EFIAPI
SetCacheAttributes (
  IN  EFI_PHYSICAL_ADDRESS      MemoryAddress,
  IN  UINT64                    MemoryLength,
  IN  EFI_MEMORY_CACHE_TYPE     MemoryCacheType
  )
{
  EFI_STATUS            Status;
  UINT32                MsrNum, MsrNumEnd;
  UINT64                TempQword;
  UINT32                LastVariableMtrrForBios;
  UINT64                OldMtrr;
  UINT32                UsedMsrNum;
  EFI_MEMORY_CACHE_TYPE UsedMemoryCacheType;
  UINT64                ValidMtrrAddressMask;
  UINT32                Cpuid_RegEax;

  AsmCpuid (CPUID_EXTENDED_FUNCTION, &Cpuid_RegEax, NULL, NULL, NULL);
  if (Cpuid_RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) {
    AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &Cpuid_RegEax, NULL, NULL, NULL);
    ValidMtrrAddressMask = (LShiftU64((UINT64) 1, (Cpuid_RegEax & 0xFF)) - 1) & (~(UINT64)0x0FFF);
  } else {
    ValidMtrrAddressMask = (LShiftU64((UINT64) 1, 36) - 1) & (~(UINT64)0x0FFF);
  }

  //
  // Check for invalid parameter
  //
  if ((MemoryAddress & ~ValidMtrrAddressMask) != 0 || (MemoryLength & ~ValidMtrrAddressMask) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  if (MemoryLength == 0) {
    return EFI_INVALID_PARAMETER;
  }

  switch (MemoryCacheType) {
    case EFI_CACHE_UNCACHEABLE:
    case EFI_CACHE_WRITECOMBINING:
    case EFI_CACHE_WRITETHROUGH:
    case EFI_CACHE_WRITEPROTECTED:
    case EFI_CACHE_WRITEBACK:
      break;

    default:
      return EFI_INVALID_PARAMETER;
  }

  //
  // Check if Fixed MTRR
  //
  if ((MemoryAddress + MemoryLength) <= (1 << 20)) {
    Status = EFI_SUCCESS;
    EfiDisableCacheMtrr (&OldMtrr);
    while ((MemoryLength > 0) && (Status == EFI_SUCCESS)) {
      Status = ProgramFixedMtrr (MemoryCacheType, &MemoryAddress, &MemoryLength);
    }
    EfiRecoverCacheMtrr (TRUE, OldMtrr);
    return Status;
  }

  //
  // Search if the range attribute has been set before
  //
  Status = SearchForExactMtrr(
                              MemoryAddress,
                              MemoryLength,
                              ValidMtrrAddressMask,
                              &UsedMsrNum,
                              &UsedMemoryCacheType
                              );

  if (!EFI_ERROR(Status)) {
    //
    // Compare if it has the same type as current setting
    //
    if (UsedMemoryCacheType == MemoryCacheType) {
      return EFI_SUCCESS;
    } else {
      //
      // Different type
      //

      //
      // Check if the set type is the same as Default Type
      //
      if (IsDefaultType(MemoryCacheType)) {
        //
        // Clear the MTRR
        //
        AsmWriteMsr64(UsedMsrNum, 0);
        AsmWriteMsr64(UsedMsrNum + 1, 0);

        return EFI_SUCCESS;
      } else {
        //
        // Modify the MTRR type
        //
        EfiProgramMtrr(UsedMsrNum,
                       MemoryAddress,
                       MemoryLength,
                       MemoryCacheType,
                       ValidMtrrAddressMask
                       );
        return EFI_SUCCESS;
      }
    }
  }

#if 0
  //
  // @bug - Need to create memory map so that when checking for overlap we
  //        can determine if an overlap exists based on all caching requests.
  //
  // Don't waste a variable MTRR if the caching attrib is same as default in MTRR_DEF_TYPE
  //
  if (MemoryCacheType == (AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE) & B_EFI_MSR_CACHE_MEMORY_TYPE))  {
    if (!CheckMtrrOverlap (MemoryAddress, MemoryAddress+MemoryLength-1)) {
      return EFI_SUCCESS;
    }
  }
#endif

  //
  // Find first unused MTRR
  //
  MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT));
  for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum +=2) {
    if ((AsmReadMsr64(MsrNum+1) & B_EFI_MSR_CACHE_MTRR_VALID) == 0 ) {
      break;
    }
  }

  //
  // Reserve 1 MTRR pair for OS.
  //
  LastVariableMtrrForBios = MsrNumEnd - 1 - (EFI_CACHE_NUM_VAR_MTRR_PAIRS_FOR_OS * 2);
  if (MsrNum > LastVariableMtrrForBios) {
    return EFI_LOAD_ERROR;
  }

  //
  // Special case for 1 MB base address
  //
  if (MemoryAddress == BASE_1MB) {
    MemoryAddress = 0;
  }

  //
  // Program MTRRs
  //
  TempQword = MemoryLength;

  if (TempQword == Power2MaxMemory(MemoryAddress, TempQword)) {
    EfiProgramMtrr(MsrNum,
                   MemoryAddress,
                   MemoryLength,
                   MemoryCacheType,
                   ValidMtrrAddressMask
                   );

  } else {
    //
    // Fill in MTRRs with values.  Direction can not be checked for this method
    // as we are using WB as the default cache type and only setting areas to UC.
    //
    do {
      //
      // Do boundary check so we don't go past last MTRR register
      // for BIOS use.  Leave one MTRR pair for OS use.
      //
      if (MsrNum > LastVariableMtrrForBios) {
        return EFI_LOAD_ERROR;
      }

      //
      // Set next power of 2 region
      //
      MemoryLength = Power2MaxMemory(MemoryAddress, TempQword);
      EfiProgramMtrr(MsrNum,
                     MemoryAddress,
                     MemoryLength,
                     MemoryCacheType,
                     ValidMtrrAddressMask
                     );
      MemoryAddress += MemoryLength;
      TempQword -= MemoryLength;
      MsrNum += 2;
    } while (TempQword != 0);
  }

  return EFI_SUCCESS;
}

/**
 Reset all the MTRRs to a known state.

  @retval  EFI_SUCCESS All MTRRs have been reset successfully.

**/
EFI_STATUS
EFIAPI
ResetCacheAttributes (
  VOID
  )
{
  UINT32                      MsrNum, MsrNumEnd;
  UINT16                      Index;
  UINT64                      OldMtrr;
  UINT64                      CacheType;
  BOOLEAN                     DisableCar;
  Index = 0;
  DisableCar = TRUE;

  //
  // Determine default cache type
  //
  CacheType = EFI_CACHE_UNCACHEABLE;

  //
  // Set default cache type
  //
  AsmWriteMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, CacheType);

  //
  // Disable CAR
  //
  DisableCacheAsRam (DisableCar);

  EfiDisableCacheMtrr (&OldMtrr);

  //
  // Reset Fixed MTRRs
  //
  for (Index = 0; Index < V_EFI_FIXED_MTRR_NUMBER; Index++) {
    AsmWriteMsr64 (mFixedMtrrTable[Index].Msr, 0);
  }

  //
  // Reset Variable MTRRs
  //
  MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT));
  for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum++) {
    AsmWriteMsr64 (MsrNum, 0);
  }

  //
  // Enable Fixed and Variable MTRRs
  //
  EfiRecoverCacheMtrr (TRUE, OldMtrr);

  return EFI_SUCCESS;
}

/**
  Search the memory cache type for specific memory from MTRR.

  @param[in]  MemoryAddress         the address of target memory
  @param[in]  MemoryLength          the length of target memory
  @param[in]  ValidMtrrAddressMask  the MTRR address mask
  @param[out] UsedMsrNum            the used MSR number
  @param[out] UsedMemoryCacheType   the cache type for the target memory

  @retval EFI_SUCCESS    The memory is found in MTRR and cache type is returned
  @retval EFI_NOT_FOUND  The memory is not found in MTRR

**/
EFI_STATUS
SearchForExactMtrr (
  IN  EFI_PHYSICAL_ADDRESS      MemoryAddress,
  IN  UINT64                    MemoryLength,
  IN  UINT64                    ValidMtrrAddressMask,
  OUT UINT32                    *UsedMsrNum,
  OUT EFI_MEMORY_CACHE_TYPE     *UsedMemoryCacheType
  )
{
  UINT32                      MsrNum, MsrNumEnd;
  UINT64                      TempQword;

  if (MemoryLength == 0) {
    return EFI_INVALID_PARAMETER;
  }

  MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT));
  for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum +=2) {
    TempQword = AsmReadMsr64(MsrNum+1);
    if ((TempQword & B_EFI_MSR_CACHE_MTRR_VALID) == 0) {
      continue;
    }

    if ((TempQword & ValidMtrrAddressMask) != ((~(MemoryLength - 1)) & ValidMtrrAddressMask)) {
      continue;
    }

    TempQword = AsmReadMsr64 (MsrNum);
    if ((TempQword & ValidMtrrAddressMask) != (MemoryAddress & ValidMtrrAddressMask)) {
      continue;
    }

    *UsedMemoryCacheType = (EFI_MEMORY_CACHE_TYPE)(TempQword & B_EFI_MSR_CACHE_MEMORY_TYPE);
    *UsedMsrNum = MsrNum;

    return EFI_SUCCESS;
  }

  return EFI_NOT_FOUND;
}

/**
  Check if CacheType match current default setting.

  @param[in] MemoryCacheType  input cache type to be checked.

  @retval TRUE MemoryCacheType is default MTRR setting.
  @retval TRUE MemoryCacheType is NOT default MTRR setting.
**/
BOOLEAN
IsDefaultType (
  IN  EFI_MEMORY_CACHE_TYPE     MemoryCacheType
  )
{
  if ((AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE) & B_EFI_MSR_CACHE_MEMORY_TYPE) != MemoryCacheType) {
    return FALSE;
  }

  return TRUE;
}

