/** @file

  Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#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      Alligned.
  @retval Non-Zero  Not alligned.

**/
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 inital 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      Alligned.
  @retval Non-Zero  Not alligned.

**/
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;
}

