/** @file

  Copyright (c) 2004  - 2016, 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 that 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.    
                                                                                   

Module Name:


  MemoryPeim.c

Abstract:

  Tiano PEIM to provide the platform support functionality.
  This file implements the Platform Memory Range PPI

--*/

#include "PlatformEarlyInit.h"

//
// Need min. of 48MB PEI phase
//
#define  PEI_MIN_MEMORY_SIZE               (6 * 0x800000)
#define  PEI_RECOVERY_MIN_MEMORY_SIZE      (6 * 0x800000)

//
// This is the memory needed for PEI to start up DXE.
//
// Over-estimating this size will lead to higher fragmentation
// of main memory.  Under-estimation of this will cause catastrophic
// failure of PEI to load DXE.  Generally, the failure may only be
// realized during capsule updates.
//
#define PRERESERVED_PEI_MEMORY ( \
  EFI_SIZE_TO_PAGES (3 * 0x800000)   /* PEI Core memory based stack          */ \
  )

EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
  { EfiACPIReclaimMemory,       0x40  },    // 0x40 pages = 256k for ASL
  { EfiACPIMemoryNVS,           0x100 },    // 0x100 pages = 1 MB for S3, SMM, HII, etc
  { EfiReservedMemoryType,      0x600 },    // 48k for BIOS Reserved
  { EfiMemoryMappedIO,          0     },
  { EfiMemoryMappedIOPortSpace, 0     },
  { EfiPalCode,                 0     },
  { EfiRuntimeServicesCode,     0x200 },
  { EfiRuntimeServicesData,     0x100 },
  { EfiLoaderCode,              0x100 },
  { EfiLoaderData,              0x100 },
  { EfiBootServicesCode,        0x800 },
  { EfiBootServicesData,        0x2500},
  { EfiConventionalMemory,      0     },
  { EfiUnusableMemory,          0     },
  { EfiMaxMemoryType,           0     }
};

STATIC
EFI_STATUS
GetMemorySize (
  IN  CONST EFI_PEI_SERVICES    **PeiServices,
  OUT UINT64              *LowMemoryLength,
  OUT UINT64              *HighMemoryLength
  );


/**
  Initializes the valid address mask for MTRRs.

  This function initializes the valid bits mask and valid address mask for MTRRs.

**/
UINT64
InitializeAddressMtrrMask (
  VOID
  )
{
  UINT32                    RegEax;
  UINT8                     PhysicalAddressBits; 
  UINT64                    ValidMtrrBitsMask;

  AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);

  if (RegEax >= 0x80000008) {
    AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);

    PhysicalAddressBits = (UINT8) RegEax;
  } else {
    PhysicalAddressBits = 36;
  }

  ValidMtrrBitsMask    = LShiftU64 (1, PhysicalAddressBits) - 1;
  return (ValidMtrrBitsMask & 0xfffffffffffff000ULL);
}

EFI_STATUS
EFIAPI
SetPeiCacheMode (
  IN  CONST EFI_PEI_SERVICES    **PeiServices
  )
{
  EFI_STATUS              Status;
  PEI_CACHE_PPI           *CachePpi;

  EFI_BOOT_MODE           BootMode;
  UINT64                  MemoryLength;
  UINT64                  MemOverflow;
  UINT64                  MemoryLengthUc;
  UINT64                  MaxMemoryLength;
  UINT64                  LowMemoryLength;
  UINT64                  HighMemoryLength;
  UINT8                   Index;
  MTRR_SETTINGS           MtrrSetting;
  UINT64                  ValidMtrrAddressMask;

  //
  // Load Cache PPI
  //
  Status = (**PeiServices).LocatePpi (
             PeiServices,
             &gPeiCachePpiGuid,    // GUID
             0,                    // Instance
             NULL,                 // EFI_PEI_PPI_DESCRIPTOR
             (void **)&CachePpi             // PPI
             );
  if (!EFI_ERROR(Status)) {
    //
    // Clear the CAR Settings (Default Cache Type => UC)
    //
    DEBUG ((EFI_D_INFO, "Reset cache attribute and disable CAR. \n"));
    CachePpi->ResetCache(
                (EFI_PEI_SERVICES**)PeiServices,
                CachePpi
                );
 }


  //
  // Variable initialization
  //
  LowMemoryLength = 0;
  HighMemoryLength = 0;
  MemoryLengthUc = 0;

  Status = (*PeiServices)->GetBootMode (
                             PeiServices,
                             &BootMode
                             );

  ValidMtrrAddressMask = InitializeAddressMtrrMask ();

  //
  // Determine memory usage
  //
  GetMemorySize (
    PeiServices,
    &LowMemoryLength,
    &HighMemoryLength
    );

  LowMemoryLength  = (EFI_PHYSICAL_ADDRESS)MmPci32( 0, 0, 2, 0, 0x70);
  LowMemoryLength   &=  0xFFF00000ULL;

  MaxMemoryLength = LowMemoryLength;

  //
  // Round up to nearest 256MB with high memory and 64MB w/o high memory
  //
  if (HighMemoryLength != 0 ) {
    MemOverflow = (LowMemoryLength & 0x0fffffff);
    if (MemOverflow != 0) {
      MaxMemoryLength = LowMemoryLength + (0x10000000 - MemOverflow);
    }
  } else {
    MemOverflow = (LowMemoryLength & 0x03ffffff);
    if (MemOverflow != 0) {
      MaxMemoryLength = LowMemoryLength + (0x4000000 - MemOverflow);
    }
  }

  ZeroMem (&MtrrSetting, sizeof(MTRR_SETTINGS));
  for (Index = 0; Index < 2; Index++) {
    MtrrSetting.Fixed.Mtrr[Index]=0x0606060606060606;
   }
  for (Index = 2; Index < 11; Index++) {
    MtrrSetting.Fixed.Mtrr[Index]=0x0505050505050505;
   }

  //
  // Cache the flash area to improve the boot performance in PEI phase
  //
  Index = 0;
  ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[0].Base)->Uint64 = FixedPcdGet32 (PcdFlashAreaBaseAddress);
  ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[0].Base)->Bits.Type = CacheWriteProtected;
  ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[0].Mask)->Uint64 = (~((UINT64)(FixedPcdGet32 (PcdFlashAreaSize) - 1))) & ValidMtrrAddressMask;
  ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[0].Mask)->Bits.V = 1;

  Index ++;

  MemOverflow =0;
  while (MaxMemoryLength > MemOverflow){
    MemoryLength = MaxMemoryLength - MemOverflow;
    MemoryLength = GetPowerOfTwo64 (MemoryLength);

    ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Base)->Uint64 = MemOverflow & ValidMtrrAddressMask;
    ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Base)->Bits.Type = CacheWriteBack;
    ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Mask)->Uint64 = (~(MemoryLength - 1)) & ValidMtrrAddressMask;
    ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Mask)->Bits.V = 1;

    MemOverflow += MemoryLength;
    Index++;
  }

  MemoryLength = LowMemoryLength;

  while (MaxMemoryLength != MemoryLength) {
    MemoryLengthUc = GetPowerOfTwo64 (MaxMemoryLength - MemoryLength);

    ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Base)->Uint64 = (MaxMemoryLength - MemoryLengthUc) & ValidMtrrAddressMask;
    ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Base)->Bits.Type = CacheUncacheable;
    ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Mask)->Uint64 = (~(MemoryLengthUc   - 1)) & ValidMtrrAddressMask;
    ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Mask)->Bits.V = 1;

    MaxMemoryLength -= MemoryLengthUc;
    Index++;
  }

  MemOverflow =0x100000000;
  while (HighMemoryLength > 0) {

    MemoryLength = HighMemoryLength;
    MemoryLength = GetPowerOfTwo64 (MemoryLength);
    if (MemoryLength > MemOverflow){
      MemoryLength = MemOverflow;
    }

    ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Base)->Uint64 = MemOverflow & ValidMtrrAddressMask;
    ((MSR_IA32_MTRR_PHYSBASE_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Base)->Bits.Type = CacheWriteBack;
    ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Mask)->Uint64 = (~(MemoryLength - 1)) & ValidMtrrAddressMask;
    ((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &MtrrSetting.Variables.Mtrr[Index].Mask)->Bits.V = 1;

    MemOverflow += MemoryLength;
    HighMemoryLength -= MemoryLength;
    Index++;
  }


  for (Index = 0; Index < MTRR_NUMBER_OF_VARIABLE_MTRR; Index++) {
    if (MtrrSetting.Variables.Mtrr[Index].Base == 0){
      break;
    }
    DEBUG ((EFI_D_INFO, "Base=%lx, Mask=%lx\n",MtrrSetting.Variables.Mtrr[Index].Base ,MtrrSetting.Variables.Mtrr[Index].Mask));
  }

  //
  // set FE/E bits for IA32_MTRR_DEF_TYPE
  //
  MtrrSetting.MtrrDefType |=  3 <<10;

  MtrrSetAllMtrrs(&MtrrSetting);
  //
  // Dump MTRR Setting
  //
  MtrrDebugPrintAllMtrrs ();

  return EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
SetDxeCacheMode (
  IN  CONST EFI_PEI_SERVICES    **PeiServices
  )
{
  //
  // This is not needed for now.
  //
  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
GetMemorySize (
  IN  CONST EFI_PEI_SERVICES    **PeiServices,
  OUT UINT64              *LowMemoryLength,
  OUT UINT64              *HighMemoryLength
  )
{
  EFI_STATUS              Status;
  EFI_PEI_HOB_POINTERS    Hob;

  *HighMemoryLength = 0;
  *LowMemoryLength = 0x100000;

  //
  // Get the HOB list for processing
  //
  Status = (*PeiServices)->GetHobList (PeiServices, (void **)&Hob.Raw);
  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  // Collect memory ranges
  //
  while (!END_OF_HOB_LIST (Hob)) {
    if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
      if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
        //
        // Need memory above 1MB to be collected here
        //
        if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000 &&
            Hob.ResourceDescriptor->PhysicalStart < (EFI_PHYSICAL_ADDRESS) 0x100000000) {
          *LowMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
        } else if (Hob.ResourceDescriptor->PhysicalStart >= (EFI_PHYSICAL_ADDRESS) 0x100000000) {
          *HighMemoryLength += (UINT64) (Hob.ResourceDescriptor->ResourceLength);
        }
      }
    }
    Hob.Raw = GET_NEXT_HOB (Hob);
  }

  return EFI_SUCCESS;
}


/**
  Publish Memory Type Information.

  @param  NULL

  @retval EFI_SUCCESS    Success.
  @retval Others         Errors have occurred.
**/

EFI_STATUS
EFIAPI
PublishMemoryTypeInfo (
  void
  )
{
  EFI_STATUS                      Status;
  EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;
  UINTN                           DataSize;
  EFI_MEMORY_TYPE_INFORMATION     MemoryData[EfiMaxMemoryType + 1];

  Status = PeiServicesLocatePpi (
             &gEfiPeiReadOnlyVariable2PpiGuid,
             0,
             NULL,
            (void **)&Variable
             );
  if (EFI_ERROR(Status)) {
    DEBUG((EFI_D_ERROR, "WARNING: Locating Pei variable failed 0x%x \n", Status));
    DEBUG((EFI_D_ERROR, "Build Hob from default\n"));
    //
    // Build the default GUID'd HOB for DXE
    //
    BuildGuidDataHob (
      &gEfiMemoryTypeInformationGuid,
      mDefaultMemoryTypeInformation,
      sizeof (mDefaultMemoryTypeInformation)
      );

    return Status;
  }


  DataSize = sizeof (MemoryData);

  //
  // This variable is saved in BDS stage. Now read it back
  //
  Status = Variable->GetVariable (
                       Variable,
                       EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
                       &gEfiMemoryTypeInformationGuid,
                       NULL,
                       &DataSize,
                       &MemoryData
                       );
  if (EFI_ERROR (Status)) {
  	//
    //build default
    //
    DEBUG((EFI_D_ERROR, "Build Hob from default\n"));
    BuildGuidDataHob (
      &gEfiMemoryTypeInformationGuid,
      mDefaultMemoryTypeInformation,
      sizeof (mDefaultMemoryTypeInformation)
      );

  } else {
  	//
    // Build the GUID'd HOB for DXE from variable
    //
    DEBUG((EFI_D_ERROR, "Build Hob from variable \n"));
    BuildGuidDataHob (
      &gEfiMemoryTypeInformationGuid,
      MemoryData,
      DataSize
      );
  }

  return Status;
}

