/* $NoKeywords:$ */
/**
 * @file
 *
 * mmMemRestore.c
 *
 * Main Memory Feature implementation file for Node Interleaving
 *
 * @xrefitem bom "File Content Label" "Release Content"
 * @e project: AGESA
 * @e sub-project: (Mem/Main)
 * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 17:16:51 +0800 (Wed, 22 Dec 2010) $
 *
 **/
/*****************************************************************************
*
* Copyright (c) 2011, Advanced Micro Devices, Inc.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Advanced Micro Devices, Inc. nor the names of 
 *       its contributors may be used to endorse or promote products derived 
 *       from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ***************************************************************************
*
*/

/*
 *----------------------------------------------------------------------------
 *                                MODULES USED
 *
 *----------------------------------------------------------------------------
 */

#include "AGESA.h"
#include "amdlib.h"
#include "OptionMemory.h"
#include "mm.h"
#include "mn.h"
#include "Ids.h"
#include "S3.h"
#include "mfs3.h"
#include "heapManager.h"
#include "Filecode.h"
CODE_GROUP (G1_PEICC)
RDATA_GROUP (G1_PEICC)

#define FILECODE PROC_MEM_MAIN_MMMEMRESTORE_FILECODE

#define ST_PRE_ESR  0
#define ST_POST_ESR 1
#define ST_DONE     2

/*----------------------------------------------------------------------------
 *                        PROTOTYPES OF LOCAL FUNCTIONS
 *
 *----------------------------------------------------------------------------
 */
BOOLEAN
STATIC
MemMRestoreDqsTimings (
  IN       VOID                *Storage,
  IN       MEM_MAIN_DATA_BLOCK *MemMainPtr
  );

BOOLEAN
STATIC
MemMSetCSRNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       PCI_SPECIAL_CASE *SpecialCases,
  IN       PCI_ADDR PciAddr,
  IN       UINT32 Value
  );

VOID
STATIC
MemMCreateS3NbBlock (
  IN OUT   MEM_MAIN_DATA_BLOCK *MemMainPtr,
     OUT   S3_MEM_NB_BLOCK **S3NBPtr
  );
/*-----------------------------------------------------------------------------
*                                EXPORTED FUNCTIONS
*
*-----------------------------------------------------------------------------
*/
VOID
MemMContextSave (
  IN OUT   MEM_MAIN_DATA_BLOCK *MemMainPtr
  );

BOOLEAN
MemMContextRestore (
  IN OUT   MEM_MAIN_DATA_BLOCK *MemMainPtr
  );

extern MEM_NB_SUPPORT memNBInstalled[];

/* -----------------------------------------------------------------------------*/
/**
 *
 *  Check and save memory context if possible.
 *
 *     @param[in,out]   *MemMainPtr   - Pointer to the MEM_MAIN_DATA_BLOCK
 *
 */
VOID
MemMContextSave (
  IN OUT   MEM_MAIN_DATA_BLOCK *MemMainPtr
  )
{
  UINT8 Node;
  UINT8 i;
  MEM_PARAMETER_STRUCT *RefPtr;
  LOCATE_HEAP_PTR LocHeap;
  ALLOCATE_HEAP_PARAMS AllocHeapParams;
  DEVICE_BLOCK_HEADER *DeviceList;
  AMD_CONFIG_PARAMS *StdHeader;
  UINT32 BufferSize;
  VOID *BufferOffset;
  MEM_NB_BLOCK  *NBArray;
  S3_MEM_NB_BLOCK *S3NBPtr;
  DESCRIPTOR_GROUP DeviceDescript[MAX_NODES_SUPPORTED];

  NBArray = MemMainPtr->NBPtr;
  RefPtr = NBArray[BSP_DIE].RefPtr;

  if (RefPtr->SaveMemContextCtl) {
    RefPtr->MemContext.NvStorage = NULL;
    RefPtr->MemContext.NvStorageSize = 0;

    // Make sure DQS training has occurred before saving memory context
    if (!RefPtr->MemRestoreCtl) {
      StdHeader = &MemMainPtr->MemPtr->StdHeader;

      MemMCreateS3NbBlock (MemMainPtr, &S3NBPtr);
      if (S3NBPtr != NULL) {
        // Get the mask bit and the register list for node that presents
        BufferSize = 0;
        for (Node = 0; Node < MemMainPtr->DieCount; Node ++) {
          S3NBPtr->MemS3GetConPCIMask (&NBArray[Node], (VOID *)&DeviceDescript[Node]);
          S3NBPtr->MemS3GetConMSRMask (&NBArray[Node], (VOID *)&DeviceDescript[Node]);
          BufferSize += S3NBPtr->MemS3GetRegLstPtr (&NBArray[Node], (VOID *)&DeviceDescript[Node]);
        }

        // Base on the size of the device list, apply for a buffer for it.
        AllocHeapParams.RequestedBufferSize = (UINT32) (BufferSize + sizeof (DEVICE_BLOCK_HEADER));
        AllocHeapParams.BufferHandle = AMD_MEM_S3_DATA_HANDLE;
        AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
        if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) == AGESA_SUCCESS) {
          DeviceList = (DEVICE_BLOCK_HEADER *) AllocHeapParams.BufferPtr;
          DeviceList->RelativeOrMaskOffset = (UINT16) AllocHeapParams.RequestedBufferSize;

          // Copy device list on the stack to the heap.
          BufferOffset = sizeof (DEVICE_BLOCK_HEADER) + AllocHeapParams.BufferPtr;
          for (Node = 0; Node < MemMainPtr->DieCount; Node ++) {
            for (i = PRESELFREF; i <= POSTSELFREF; i ++) {
              // Copy PCI device descriptor to the heap if it exists.
              if (DeviceDescript[Node].PCIDevice[i].RegisterListID != 0xFFFFFFFF) {
                LibAmdMemCopy ((VOID *) BufferOffset, &(DeviceDescript[Node].PCIDevice[i]), sizeof (PCI_DEVICE_DESCRIPTOR), StdHeader);
                DeviceList->NumDevices ++;
                BufferOffset += sizeof (PCI_DEVICE_DESCRIPTOR);
              }
              // Copy conditional PCI device descriptor to the heap if it exists.
              if (DeviceDescript[Node].CPCIDevice[i].RegisterListID != 0xFFFFFFFF) {
                LibAmdMemCopy ((VOID *) BufferOffset, &(DeviceDescript[Node].CPCIDevice[i]), sizeof (CONDITIONAL_PCI_DEVICE_DESCRIPTOR), StdHeader);
                DeviceList->NumDevices ++;
                BufferOffset += sizeof (CONDITIONAL_PCI_DEVICE_DESCRIPTOR);
              }
              // Copy MSR device descriptor to the heap if it exists.
              if (DeviceDescript[Node].MSRDevice[i].RegisterListID != 0xFFFFFFFF) {
                LibAmdMemCopy ((VOID *) BufferOffset, &(DeviceDescript[Node].MSRDevice[i]), sizeof (MSR_DEVICE_DESCRIPTOR), StdHeader);
                DeviceList->NumDevices ++;
                BufferOffset += sizeof (MSR_DEVICE_DESCRIPTOR);
              }
              // Copy conditional MSR device descriptor to the heap if it exists.
              if (DeviceDescript[Node].CMSRDevice[i].RegisterListID != 0xFFFFFFFF) {
                LibAmdMemCopy ((VOID *) BufferOffset, &(DeviceDescript[Node].PCIDevice[i]), sizeof (CONDITIONAL_MSR_DEVICE_DESCRIPTOR), StdHeader);
                DeviceList->NumDevices ++;
                BufferOffset += sizeof (CONDITIONAL_MSR_DEVICE_DESCRIPTOR);
              }
            }
          }

          // Determine size needed
          BufferSize = GetWorstCaseContextSize (DeviceList, INIT_RESUME, StdHeader);
          AllocHeapParams.RequestedBufferSize = BufferSize;
          AllocHeapParams.BufferHandle = AMD_S3_SAVE_HANDLE;
          AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
          if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) == AGESA_SUCCESS) {
            // Save memory context
            SaveDeviceListContext (DeviceList, AllocHeapParams.BufferPtr, INIT_RESUME, &BufferSize, StdHeader);
            RefPtr->MemContext.NvStorageSize = BufferSize;
          }

          HeapDeallocateBuffer (AMD_MEM_S3_DATA_HANDLE, StdHeader);
        }
      }
      HeapDeallocateBuffer (AMD_MEM_S3_NB_HANDLE, StdHeader);

      // Locate MemContext since it might have been shifted after deallocating
      LocHeap.BufferHandle = AMD_S3_SAVE_HANDLE;
      if (HeapLocateBuffer (&LocHeap, StdHeader) == AGESA_SUCCESS) {
        RefPtr->MemContext.NvStorage = LocHeap.BufferPtr;
      }
    }
  }

  for (Node = 0; Node < MemMainPtr->DieCount; Node++) {
    NBArray[Node].FamilySpecificHook[AfterSaveRestore] (&NBArray[Node], &NBArray[Node]);
  }
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *  Check and restore memory context if possible.
 *
 *     @param[in,out]   *MemMainPtr   - Pointer to the MEM_MAIN_DATA_BLOCK
 *
 *     @return          TRUE -  DQS timing restore succeeds.
 *     @return          FALSE - DQS timing restore fails.
 */
BOOLEAN
MemMContextRestore (
  IN OUT   MEM_MAIN_DATA_BLOCK *MemMainPtr
  )
{
  UINT8 Node;
  MEM_NB_BLOCK  *NBArray;
  MEM_PARAMETER_STRUCT *RefPtr;
  S3_MEM_NB_BLOCK *S3NBPtr;

  NBArray = MemMainPtr->NBPtr;
  RefPtr = NBArray[BSP_DIE].RefPtr;

  IDS_HDT_CONSOLE (MEM_STATUS, "\nStart Mem Restore\n");
  if (RefPtr->MemRestoreCtl) {
    if (RefPtr->MemContext.NvStorage != NULL) {
      MemMCreateS3NbBlock (MemMainPtr, &S3NBPtr);
      if (S3NBPtr != NULL) {
        // Check DIMM config and restore DQS timings if possible
        if (!MemMRestoreDqsTimings (RefPtr->MemContext.NvStorage, MemMainPtr)) {
          RefPtr->MemRestoreCtl = FALSE;
        }
      } else {
        RefPtr->MemRestoreCtl = FALSE;
      }
      HeapDeallocateBuffer (AMD_MEM_S3_NB_HANDLE, &(MemMainPtr->MemPtr->StdHeader));
    } else {
      RefPtr->MemRestoreCtl = FALSE;
    }
  }

  for (Node = 0; Node < MemMainPtr->DieCount; Node++) {
    NBArray[Node].FamilySpecificHook[AfterSaveRestore] (&NBArray[Node], &NBArray[Node]);
  }
  IDS_HDT_CONSOLE (MEM_FLOW, RefPtr->MemRestoreCtl ? "Mem Restore Succeeds!\n" : "Mem Restore Fails!\n");
  return RefPtr->MemRestoreCtl;
}

/*----------------------------------------------------------------------------
 *                              LOCAL FUNCTIONS
 *
 *----------------------------------------------------------------------------
 */

/*---------------------------------------------------------------------------------------*/
/**
 * Restores all devices that contains DQS timings
 *
 *     @param[in]     Storage        Beginning of the device list.
 *     @param[in,out]   MemMainPtr   - Pointer to the MEM_MAIN_DATA_BLOCK
 *
 *     @return          TRUE -  No fatal error occurs.
 *     @return          FALSE - Fatal error occurs.
 *
 */
BOOLEAN
STATIC
MemMRestoreDqsTimings (
  IN       VOID                *Storage,
  IN       MEM_MAIN_DATA_BLOCK *MemMainPtr
  )
{
  AMD_CONFIG_PARAMS *StdHeader;
  UINT8 *OrMask;
  DEVICE_DESCRIPTORS Device;
  INT16 i;
  INT16 j;
  DEVICE_BLOCK_HEADER *DeviceList;
  PCI_REGISTER_BLOCK_HEADER *Reg;
  CPCI_REGISTER_BLOCK_HEADER *CReg;
  MSR_REGISTER_BLOCK_HEADER *MsrReg;
  CMSR_REGISTER_BLOCK_HEADER *CMsrReg;
  PCI_ADDR PciAddress;
  MEM_NB_BLOCK  *NBArray;
  UINT8 State;
  UINT8 Node;
  UINT8 Dct;
  UINT8 MaxNode;

  NBArray = MemMainPtr->NBPtr;
  StdHeader = &(MemMainPtr->MemPtr->StdHeader);
  DeviceList = (DEVICE_BLOCK_HEADER *) Storage;
  Device.CommonDeviceHeader = (DEVICE_DESCRIPTOR *) &DeviceList[1];
  OrMask = (UINT8 *) DeviceList + DeviceList->RelativeOrMaskOffset;

  if (DeviceList->NumDevices == 0) {
    return FALSE;
  }

  MaxNode = 0;
  State = ST_PRE_ESR;
  for (i = 0; State != ST_DONE; i++) {
    if (((State == ST_PRE_ESR) && (Device.CommonDeviceHeader->Type == DEV_TYPE_PCI_PRE_ESR)) ||
        ((State == ST_POST_ESR) && (Device.CommonDeviceHeader->Type == DEV_TYPE_PCI))) {
      MemFS3GetPciDeviceRegisterList (Device.PciDevice, &Reg, StdHeader);
      Node = Device.PciDevice->Node;
      IDS_HDT_CONSOLE (MEM_STATUS, "Node %d\n", Node);
      PciAddress = NBArray[Node].PciAddr;
      for (j = 0; j < Reg->NumRegisters; j++) {
        PciAddress.Address.Function = Reg->RegisterList[j].Function;
        PciAddress.Address.Register = Reg->RegisterList[j].Offset;
        PciAddress.Address.Segment = (Reg->RegisterList[j].Type.SpecialCaseFlag != 0) ?
                                     0xF - Reg->RegisterList[j].Type.SpecialCaseIndex : 0;
        if (!MemMSetCSRNb (&NBArray[Node], Reg->SpecialCases, PciAddress, *((UINT32 *) OrMask) & Reg->RegisterList[j].AndMask)) {
          return FALSE;   // Restore fails
        }
        OrMask += (Reg->RegisterList[j].Type.RegisterSize == 0) ? 4 : Reg->RegisterList[j].Type.RegisterSize;
      }

      if (MaxNode < Node) {
        MaxNode = Node;
      }

    } else if (((State == ST_PRE_ESR) && (Device.CommonDeviceHeader->Type == DEV_TYPE_CPCI_PRE_ESR)) ||
               ((State == ST_POST_ESR) && (Device.CommonDeviceHeader->Type == DEV_TYPE_CPCI))) {
      MemFS3GetCPciDeviceRegisterList (Device.CPciDevice, &CReg, StdHeader);
      Node = Device.CPciDevice->Node;
      IDS_HDT_CONSOLE (MEM_STATUS, "Node %d\n", Node);
      PciAddress = NBArray[Node].PciAddr;
      for (j = 0; j < CReg->NumRegisters; j++) {
        if (((Device.CPciDevice->Mask1 & CReg->RegisterList[j].Mask1) != 0) &&
            ((Device.CPciDevice->Mask2 & CReg->RegisterList[j].Mask2) != 0)) {
          PciAddress.Address.Function = CReg->RegisterList[j].Function;
          PciAddress.Address.Register = CReg->RegisterList[j].Offset;
          PciAddress.Address.Segment = (CReg->RegisterList[j].Type.SpecialCaseFlag != 0) ?
                                       0xF - CReg->RegisterList[j].Type.SpecialCaseIndex : 0;
          if (!MemMSetCSRNb (&NBArray[Node], CReg->SpecialCases, PciAddress, *((UINT32 *) OrMask) & CReg->RegisterList[j].AndMask)) {
            return FALSE;   // Restore fails
          }
          OrMask += (CReg->RegisterList[j].Type.RegisterSize == 0) ? 4 : CReg->RegisterList[j].Type.RegisterSize;
        }
      }
    } else if (((State == ST_PRE_ESR) && (Device.CommonDeviceHeader->Type == DEV_TYPE_MSR_PRE_ESR)) ||
               ((State == ST_POST_ESR) && (Device.CommonDeviceHeader->Type == DEV_TYPE_MSR))) {
      MemFS3GetMsrDeviceRegisterList (Device.MsrDevice, &MsrReg, StdHeader);
      for (j = 0; j < MsrReg->NumRegisters; j++) {
        OrMask += 8;
      }
    } else if (((State == ST_PRE_ESR) && (Device.CommonDeviceHeader->Type == DEV_TYPE_CMSR_PRE_ESR)) ||
               ((State == ST_POST_ESR) && (Device.CommonDeviceHeader->Type == DEV_TYPE_CMSR))) {
      MemFS3GetCMsrDeviceRegisterList (Device.CMsrDevice, &CMsrReg, StdHeader);
      for (j = 0; j < CMsrReg->NumRegisters; j++) {
        if (((Device.CMsrDevice->Mask1 & CMsrReg->RegisterList[j].Mask1) != 0) &&
            ((Device.CMsrDevice->Mask2 & CMsrReg->RegisterList[j].Mask2) != 0)) {
          OrMask += 8;
        }
      }
    }

    switch (Device.CommonDeviceHeader->Type) {
    case DEV_TYPE_PCI_PRE_ESR:
      // Fall through to advance the pointer after restoring context
    case DEV_TYPE_PCI:
      Device.PciDevice++;
      break;
    case DEV_TYPE_CPCI_PRE_ESR:
      // Fall through to advance the pointer after restoring context
    case DEV_TYPE_CPCI:
      Device.CPciDevice++;
      break;
    case DEV_TYPE_MSR_PRE_ESR:
      // Fall through to advance the pointer after restoring context
    case DEV_TYPE_MSR:
      Device.MsrDevice++;
      break;
    case DEV_TYPE_CMSR_PRE_ESR:
      // Fall through to advance the pointer after restoring context
    case DEV_TYPE_CMSR:
      Device.CMsrDevice++;
      break;
    default:
      ASSERT (FALSE);
      break;
    }

    if (i == (DeviceList->NumDevices - 1)) {
      // Go to next state
      State++;
      i = -1;
      Device.CommonDeviceHeader = (DEVICE_DESCRIPTOR *) &DeviceList[1];

      // Check to see if processor or DIMM population has changed
      if ((MaxNode + 1) != MemMainPtr->DieCount) {
        IDS_HDT_CONSOLE (MEM_FLOW, "\tSTOP: Population changed\n");
        return FALSE;
      }

      // Perform MemClk frequency change
      for (Node = 0; Node < MemMainPtr->DieCount; Node ++) {
        if (NBArray[Node].MCTPtr->NodeMemSize != 0) {
          NBArray[Node].BeforeDqsTraining (&NBArray[Node]);
          if (NBArray[Node].DCTPtr->Timings.Speed < NBArray[Node].DCTPtr->Timings.TargetSpeed) {
            for (Dct = 0; Dct < NBArray[Node].DctCount; Dct++) {
              NBArray[Node].SwitchDCT (&NBArray[Node], Dct);
              NBArray[Node].DCTPtr->Timings.Speed = NBArray[Node].DCTPtr->Timings.TargetSpeed;
            }
            IDS_OPTION_HOOK (IDS_BEFORE_MEM_FREQ_CHG, &NBArray[Node], &(MemMainPtr->MemPtr->StdHeader));
            NBArray[Node].ChangeFrequency (&NBArray[Node]);
          }
        }
      }
    }
  }

  return TRUE;
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *   This function filters out other settings and only restores DQS timings.
 *
 *     @param[in,out]   NBPtr   - Pointer to the MEM_NB_BLOCK
 *     @param[in]   SpecialCases - Pointer to special cases array handlers
 *     @param[in]   PciAddr - address of the CSR register in PCI_ADDR format.
 *     @param[in]   Value - Value to be programmed
 *
 *     @return          TRUE -  No fatal error occurs.
 *     @return          FALSE - Fatal error occurs.
 *
 */

BOOLEAN
STATIC
MemMSetCSRNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       PCI_SPECIAL_CASE *SpecialCases,
  IN       PCI_ADDR PciAddr,
  IN       UINT32 Value
  )
{
  UINT32 Offset;
  UINT8  Dct;
  UINT32 Temp;
  BOOLEAN RetVal;
  UINT32 BOffset;

  RetVal = TRUE;
  if (PciAddr.Address.Segment != 0) {
    if (PciAddr.Address.Segment == 0xF) {
      PciAddr.Address.Segment = 0;
      Dct = (UINT8) ((PciAddr.Address.Register >> 10) & 1);
      Offset = PciAddr.Address.Register & 0x3FF;
      BOffset = PciAddr.Address.Register & 0xFF;
      if ((PciAddr.Address.Register & 0x800) == 0) {
        if (((BOffset >= 1) && (BOffset <= 3)) ||
            ((BOffset >= 5) && (BOffset <= 7)) ||
            ((Offset >= 0x10) && (Offset <= 0x2B)) ||
            ((Offset >= 0x30) && (Offset <= 0x4A))) {
          IDS_HDT_CONSOLE (MEM_FLOW, "\t\tF2_%d9C_%03x = %08x\n", Dct, Offset, Value);
          //MemNS3SetCSR
          SpecialCases[0].Restore (AccessS3SaveWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader);
        }
      }
    }
  } else {
    Dct = (UINT8) ((PciAddr.Address.Register >> 8) & 1);
    Offset = PciAddr.Address.Register & 0xFF;

    if (PciAddr.Address.Function == 2) {
      if ((Offset >= 0x40) && (Offset < 0x60) && ((Value & 4) != 0)) {
        // If TestFail bit is set, set CsTestFail
        NBPtr->SwitchDCT (NBPtr, Dct);
        NBPtr->DCTPtr->Timings.CsTrainFail |= (UINT16)1 << ((Offset - 0x40) >> 2);
        IDS_HDT_CONSOLE (MEM_FLOW, "\tBad CS:%d\n", ((Offset - 0x40) >> 2));
      } else if (Offset == 0x80) {
        LibAmdPciRead (AccessWidth32, PciAddr, &Temp, &NBPtr->MemPtr->StdHeader);
        if (Temp != Value) {
          IDS_HDT_CONSOLE (MEM_FLOW, "\tSTOP: DIMM config changed\n");
          RetVal = FALSE;
        }
      } else if (Offset == 0x90) {
        LibAmdPciRead (AccessWidth32, PciAddr, &Temp, &NBPtr->MemPtr->StdHeader);
        if ((Temp & 0x0001F000) != (Value & 0x0001F000)) {
          IDS_HDT_CONSOLE (MEM_FLOW, "\tSTOP: DIMM config changed\n");
          RetVal = FALSE;
        }
      } else if (Offset == 0x94) {
        LibAmdPciRead (AccessWidth32, PciAddr, &Temp, &NBPtr->MemPtr->StdHeader);
        if ((Temp & 0x00061000) != (Value & 0x00061000)) {
          IDS_HDT_CONSOLE (MEM_FLOW, "\tSTOP: DIMM config changed\n");
          RetVal = FALSE;
        }
        if (((Value & 0x4000) == 0) && (NBPtr->GetMemClkFreqId (NBPtr, NBPtr->DCTPtr->Timings.TargetSpeed) != ((Value & 7) + 1))) {
          IDS_HDT_CONSOLE (MEM_FLOW, "\tSTOP: MemClk has changed\n");
          RetVal = FALSE;
        }
        // Restore ZqcsInterval
        Temp &= 0xFFFFF3FF;
        Temp |= (Value & 0x00000C00);
        LibAmdPciWrite (AccessWidth32, PciAddr, &Temp, &NBPtr->MemPtr->StdHeader);
      } else if (Offset == 0x78) {
        // Program MaxRdLat
        LibAmdPciRead (AccessWidth32, PciAddr, &Temp, &NBPtr->MemPtr->StdHeader);
        Temp &= 0x0009BF0F;
        Temp |= (Value & 0xFFC00000);
        LibAmdPciWrite (AccessWidth32, PciAddr, &Temp, &NBPtr->MemPtr->StdHeader);
      } else if (PciAddr.Address.Register == 0x110) {
        if ((NBPtr->MCTPtr->NodeMemSize != 0) && (Value == 0x00000100)) {
          IDS_HDT_CONSOLE (MEM_FLOW, "\tSTOP: DIMM config changed\n");
          RetVal = FALSE;
        }
      }
    }
  }

  if (RetVal == FALSE) {
    NBPtr->SwitchDCT (NBPtr, 0);
    NBPtr->DCTPtr->Timings.CsTrainFail = 0;
    NBPtr->SwitchDCT (NBPtr, 1);
    NBPtr->DCTPtr->Timings.CsTrainFail = 0;
  }

  return RetVal;
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *  Create S3 NB Block.
 *
 *     @param[in,out]   MemMainPtr   - Pointer to the MEM_MAIN_DATA_BLOCK
 *     @param[out]      S3NBPtr   - Pointer to the S3 NB Block pointer
 *
 */
VOID
STATIC
MemMCreateS3NbBlock (
  IN OUT   MEM_MAIN_DATA_BLOCK *MemMainPtr,
     OUT   S3_MEM_NB_BLOCK **S3NBPtr
  )
{
  UINT8 Node;
  UINT8 i;
  MEM_NB_BLOCK  *NBArray;
  MEM_NB_BLOCK  *DummyNBs;
  ALLOCATE_HEAP_PARAMS AllocHeapParams;

  NBArray = MemMainPtr->NBPtr;

  *S3NBPtr = NULL;

  // Allocate heap for S3 NB Blocks
  AllocHeapParams.RequestedBufferSize = (MemMainPtr->DieCount * (sizeof (S3_MEM_NB_BLOCK) + sizeof (MEM_NB_BLOCK)));
  AllocHeapParams.BufferHandle = AMD_MEM_S3_NB_HANDLE;
  AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
  if (HeapAllocateBuffer (&AllocHeapParams, &(MemMainPtr->MemPtr->StdHeader)) == AGESA_SUCCESS) {
    *S3NBPtr = (S3_MEM_NB_BLOCK *) AllocHeapParams.BufferPtr;
    DummyNBs = (MEM_NB_BLOCK *) (AllocHeapParams.BufferPtr + MemMainPtr->DieCount * sizeof (S3_MEM_NB_BLOCK));

    // Initialize S3 NB Blocks
    for (Node = 0; Node < MemMainPtr->DieCount; Node ++) {
      (*S3NBPtr)[Node].NBPtr = &DummyNBs[Node];

      for (i = 0; memNBInstalled[i].MemS3ResumeConstructNBBlock != 0; i++) {
        if (memNBInstalled[i].MemS3ResumeConstructNBBlock (&(*S3NBPtr)[Node], NBArray[BSP_DIE].MemPtr, Node)) {
          break;
        }
      };
      if (memNBInstalled[i].MemS3ResumeConstructNBBlock == 0) {
        *S3NBPtr = NULL;
        break;
      }
    }
  }
}