/* $NoKeywords:$ */
/**
 * @file
 *
 * mnfeat.c
 *
 * Common Northbridge features
 *
 * @xrefitem bom "File Content Label" "Release Content"
 * @e project: AGESA
 * @e sub-project: (Mem/NB)
 * @e \$Revision: 38442 $ @e \$Date: 2010-09-24 06:39:57 +0800 (Fri, 24 Sep 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 "AdvancedApi.h"
#include "amdlib.h"
#include "Ids.h"
#include "OptionMemory.h"
#include "mm.h"
#include "mn.h"
#include "mu.h"
#include "PlatformMemoryConfiguration.h"
#include "merrhdl.h"
#include "Filecode.h"
CODE_GROUP (G1_PEICC)
RDATA_GROUP (G1_PEICC)

#define FILECODE PROC_MEM_NB_MNFEAT_FILECODE
/*----------------------------------------------------------------------------
 *                          DEFINITIONS AND MACROS
 *
 *----------------------------------------------------------------------------
 */
#define MAX_CL_CONT_READ  32
#define MAX_CL_CONT_WRITE 32

/*----------------------------------------------------------------------------
 *                           TYPEDEFS AND STRUCTURES
 *
 *----------------------------------------------------------------------------
 */

/*----------------------------------------------------------------------------
 *                        PROTOTYPES OF LOCAL FUNCTIONS
 *
 *----------------------------------------------------------------------------
 */

VOID
MemNInitCPGNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  );

VOID
MemNInitDqsTrainRcvrEnHwNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  );

VOID
MemNDisableDqsTrainRcvrEnHwNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  );

VOID
STATIC
MemNContWritePatternNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT32 Address,
  IN       UINT8 Pattern[],
  IN       UINT16 ClCount
  );

VOID
STATIC
MemNContReadPatternNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 Buffer[],
  IN       UINT32 Address,
  IN       UINT16 ClCount
  );

VOID
STATIC
MemNGenHwRcvEnReadsNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT32 Address
  );

UINT16
STATIC
MemNCompareTestPatternClientNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 Buffer[],
  IN       UINT8 Pattern[],
  IN       UINT16 ByteCount
  );

UINT16
STATIC
MemNInsDlyCompareTestPatternClientNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 Buffer[],
  IN       UINT8 Pattern[],
  IN       UINT16 ByteCount
  );

VOID
STATIC
MemNContWritePatternClientNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT32 Address,
  IN       UINT8 Pattern[],
  IN       UINT16 ClCount
  );

VOID
STATIC
MemNContReadPatternClientNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 Buffer[],
  IN       UINT32 Address,
  IN       UINT16 ClCount
  );

VOID
STATIC
MemNGenHwRcvEnReadsClientNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT32 Address
  );

BOOLEAN
STATIC
MemNBeforeMemClrClientNb (
  IN OUT   MEM_NB_BLOCK  *NBPtr,
  IN       VOID *UnUsed
  );

VOID
STATIC
MemNGenHwRcvEnReadsUnb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT32 Address
  );

VOID
STATIC
MemNRrwActivateCmd (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 ChipSelect,
  IN       UINT8 Bank,
  IN       UINT32 RowAddress
  );

VOID
STATIC
MemNRrwPrechargeCmd (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 ChipSelect,
  IN       UINT8 Bank
  );

VOID
STATIC
MemNContReadPatternUnb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 Buffer[],
  IN       UINT32 Address,
  IN       UINT16 ClCount
  );

VOID
STATIC
MemNContWritePatternUnb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT32 Address,
  IN       UINT8 Pattern[],
  IN       UINT16 ClCount
  );

VOID
MemNInitCPGClientNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  );

VOID
MemNInitCPGUnb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  );

/*----------------------------------------------------------------------------
 *                            EXPORTED FUNCTIONS
 *
 *----------------------------------------------------------------------------
 */

/* -----------------------------------------------------------------------------*/
/**
 *
 *      This function assigns read/write function pointers to CPG read/write modules.
 *
 *     @param[in,out] NBPtr  - Pointer to the MEM_NB_BLOCK
 *
 */
VOID
MemNInitCPGNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  NBPtr->WritePattern = MemNContWritePatternNb;
  NBPtr->ReadPattern = MemNContReadPatternNb;
  NBPtr->GenHwRcvEnReads = MemNGenHwRcvEnReadsNb;
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *   This function initializes member functions of HW Rx En Training.
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */

VOID
MemNInitDqsTrainRcvrEnHwNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  NBPtr->MemNPrepareRcvrEnDlySeed = MemNPrepareRcvrEnDlySeedNb;
}
/* -----------------------------------------------------------------------------*/
/**
 *
 *   This function disables member functions of Hw Rx En Training.
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */

VOID
MemNDisableDqsTrainRcvrEnHwNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  NBPtr->MemNPrepareRcvrEnDlySeed = (VOID (*) (MEM_NB_BLOCK *)) memDefRet;
}

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

/* -----------------------------------------------------------------------------*/
/**
 *
 *      This function writes 9 or 18 cache lines continuously using GH CPG engine
 *
 *     @param[in,out] NBPtr  - Pointer to the MEM_NB_BLOCK
 *     @param[in]     Pattern - Array of bytes that will be written to DRAM
 *     @param[in]     Address - System Address [47:16]
 *     @param[in] ClCount - Number of cache lines
 *
 */
VOID
STATIC
MemNContWritePatternNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT32 Address,
  IN       UINT8 Pattern[],
  IN       UINT16 ClCount
  )
{
  UINT16 ClDiff;
  if (ClCount > MAX_CL_CONT_WRITE) {
    ClDiff = ClCount - MAX_CL_CONT_WRITE;
    ClCount = MAX_CL_CONT_WRITE;
  } else {
    ClDiff = 0;
  }

  // Set F2x11C[MctWrLimit] to desired number of cachelines in the burst.
  MemNSetBitFieldNb (NBPtr, BFMctWrLimit, MAX_CL_CONT_WRITE - ClCount);

  // Issue the stream of writes. When F2x11C[MctWrLimit] is reached (or when F2x11C[FlushWr] is set
  // again), all the writes are written to DRAM.
  Address = MemUSetUpperFSbase (Address, NBPtr->MemPtr);
  MemUWriteCachelines (Address, Pattern, ClCount);

  // Flush out prior writes by setting F2x11C[FlushWr].
  MemNSetBitFieldNb (NBPtr, BFFlushWr, 1);
  // Wait for F2x11C[FlushWr] to clear, indicating prior writes have been flushed.
  while (MemNGetBitFieldNb (NBPtr, BFFlushWr) != 0) {}

  // Set F2x11C[MctWrLimit] to 1Fh to disable write bursting.
  MemNSetBitFieldNb (NBPtr, BFMctWrLimit, 0x1F);

  if (ClDiff > 0) {
    MemNContWritePatternNb (NBPtr, Address + (MAX_CL_CONT_WRITE * 64), Pattern + (MAX_CL_CONT_WRITE * 64), ClDiff);
  }
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *      This function reads 9 or 18 cache lines continuously using GH CPG engine
 *
 *     @param[in,out] NBPtr  - Pointer to the MEM_NB_BLOCK
 *     @param[in,out] Buffer - Array of bytes to be filled with data read from DRAM
 *     @param[in]     Address - System Address [47:16]
 *     @param[in] ClCount - Number of cache lines
 *
 */

VOID
STATIC
MemNContReadPatternNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 Buffer[],
  IN       UINT32 Address,
  IN       UINT16 ClCount
  )
{
  BOOLEAN DisAutoRefresh;
  UINT16 ClDiff;
  if (ClCount > MAX_CL_CONT_READ) {
    ClDiff = ClCount - MAX_CL_CONT_READ;
    ClCount = MAX_CL_CONT_READ;
  } else {
    ClDiff = 0;
  }

  Address = MemUSetUpperFSbase (Address, NBPtr->MemPtr);

  // 1. BIOS ensures that the only accesses outstanding to the MCT are training reads.
  // 2. If F2x[1, 0]90[BurstLength32]=1, then BIOS ensures that the DCTs and DRAMs are configured for 64
  // byte bursts (8-beat burst length). This requires that BIOS issue MRS commands to the devices
  // to change to an 8-beat burst length and then to restore the desired burst length after training
  // is complete.

  if (MemNGetBitFieldNb (NBPtr, BFDisAutoRefresh) == 0) {
    DisAutoRefresh = FALSE;
    // 3. BIOS programs F2x[1, 0]90[ForceAutoPchg] = 0 and F2x[1, 0]8C[DisAutoRefresh] = 1.
    // 4. If necessary, BIOS programs F2x[1, 0]78[EarlyArbEn] = 1 at this time. See register description.
    MemNSetBitFieldNb (NBPtr, BFDisAutoRefresh, 1);
    // MemNSetBitFieldNb (NBPtr, BFForceAutoPchg, 0);  // ForceAutoPchg is 0 by default.
    MemNSetBitFieldNb (NBPtr, BFZqcsInterval, 0);
  } else {
    DisAutoRefresh = TRUE;
  }

  MemNSetBitFieldNb (NBPtr, BFPrefCpuDis, 0);

  // 5. BIOS sets F2x11C[MctPrefReqLimit] to the number of training reads (Ntrain) it wishes to generate in the
  // training sequence.
  MemNSetBitFieldNb (NBPtr, BFMctPrefReqLimit, ClCount - 1);

  // 6. BIOS sets F2x11C[PrefDramTrainMode] bit.
  // 7. The act of setting F2x11C[PrefDramTrainMode] causes the MCT to flush out the prefetch stride predictor
  // table (removing any existing prefetch stride patterns).
  MemNSetBitFieldNb (NBPtr, BFPrefDramTrainMode, 1);

  // 8. BIOS issues an SFENCE (or other serializing instruction) to ensure that the prior write completes.
  // 9. For revision C and earlier processors, BIOS generates two training reads. For revision D processors BIOS
  // generates three training reads. Three are required to detect the stride with DCQ buddy enabled. These must
  // be to consecutive cache lines (i.e. 64 bytes apart) and must not cross a naturally aligned 4 Kbyte boundary.
  // 10. These reads set up a stride pattern which is detected by the prefetcher. The prefetcher then continues to
  // issue prefetches until F2x11C[MctPrefReqLimit] is reached, at which point the MCT clears
  // F2x11C[PrefDramTrainMode].
  MemUDummyCLRead (Address);
  MemUDummyCLRead (Address + 0x40);
  if (NBPtr->IsSupported[CheckDummyCLRead]) {
    MemUDummyCLRead (Address + 0x80);
  }
  // 11. BIOS issues the remaining (Ntrain - 2 for revisions C and earlier or Ntrain - 3 for revision D) reads after
  // checking that F2x11C[PrefDramTrainMode] is cleared. These reads must be to consecutive cache lines
  // (i.e., 64 bytes apart) and must not cross a naturally aligned 4KB boundary. These reads hit the prefetches
  // and read the data from the prefetch buffer.
  while (MemNGetBitFieldNb (NBPtr, BFPrefDramTrainMode) != 0) {}
  MemUReadCachelines (Buffer, Address, ClCount);

  // 14. BIOS restores the target values for F2x[1, 0]90[ForceAutoPchg], F2x[1, 0]8C[DisAutoRefresh] and
  // F2x[1, 0]90[BurstLength32].
  if (!DisAutoRefresh) {
    MemNSetBitFieldNb (NBPtr, BFDisAutoRefresh, 0);
    MemNSetBitFieldNb (NBPtr, BFZqcsInterval, 2);
  }

  if (ClDiff > 0) {
    MemNContReadPatternNb (NBPtr, Buffer + (MAX_CL_CONT_READ * 64), Address + (MAX_CL_CONT_READ * 64), ClDiff);
  }
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *      This function generates a continuous burst of reads during HW RcvEn training.
 *
 *     @param[in,out] NBPtr  - Pointer to the MEM_NB_BLOCK
 *     @param[in]     Address - System Address [47:16]
 *
 */
VOID
STATIC
MemNGenHwRcvEnReadsNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT32 Address
  )
{
  UINT8  TempBuffer[12 * 64];
  UINT8  BurstCount;

  for (BurstCount = 0; BurstCount < 10; BurstCount++) {
    NBPtr->ReadPattern (NBPtr, TempBuffer, Address, 12);
    NBPtr->FlushPattern (NBPtr, Address, 12);
  }
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *      This function writes cache lines continuously using TCB CPG engine
 *
 *     @param[in,out] NBPtr  - Pointer to the MEM_NB_BLOCK
 *     @param[in]     Pattern - Array of bytes that will be written to DRAM
 *     @param[in]     Address - System Address [47:16]
 *     @param[in] ClCount - Number of cache lines
 *
 */
VOID
STATIC
MemNContWritePatternClientNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT32 Address,
  IN       UINT8 Pattern[],
  IN       UINT16 ClCount
  )
{
  UINT32 PatternHash;
  UINT32 *DwordPtr;
  UINT16 i;
  UINT16 j;
  UINT16 Multiplier;

  Multiplier = 1;

  // 1. Program D18F2x1C0[WrDramTrainMode]=1.
  MemNSetBitFieldNb (NBPtr, BFWrDramTrainMode, 1);

  PatternHash = ClCount << 24;
  for (i = 0; i < 3; i ++) {
    PatternHash |= (Pattern[i * ClCount * 24 + 9] << (8 * i));
  }
  if (NBPtr->CPGInit != PatternHash) {

    if (ClCount == 3) {
      // Double pattern length for MaxRdLat training
      Multiplier = 2;
    }

    // If write training buffer has not been initialized, initialize it
    // 2. Program D18F2x1C0[TrainLength] to the appropriate number of cache lines.
    MemNSetBitFieldNb (NBPtr, BFTrainLength, ClCount * Multiplier);

    // 3. Program D18F2x1D0[WrTrainBufAddr]=000h.
    MemNSetBitFieldNb (NBPtr, BFWrTrainBufAddr, 0);

    // 4. Successively write each dword of the training pattern to D18F2x1D4.
    DwordPtr = (UINT32 *) Pattern;
    for (j = 0; j < Multiplier; j++) {
      for (i = 0; i < (ClCount * 16); i++) {
        MemNSetBitFieldNb (NBPtr, BFWrTrainBufDat, DwordPtr[i]);
      }
    }

    NBPtr->CPGInit = PatternHash;
  }

  // 5. Program D18F2x1D0[WrTrainBufAddr]=000h
  MemNSetBitFieldNb (NBPtr, BFWrTrainBufAddr, 0);

  // 6. Program the DRAM training address
  MemNSetBitFieldNb (NBPtr, BFWrTrainAdrPtrLo, Address << (16 - 6));
  MemNSetBitFieldNb (NBPtr, BFWrTrainAdrPtrHi, (Address >> (38 - 16)) & 3);

  // 7. Program D18F2x1C0[WrTrainGo]=1.
  MemNSetBitFieldNb (NBPtr, BFWrTrainGo, 1);

  // 8. Wait for D18F2x1C0[WrTrainGo]=0.
  while (MemNGetBitFieldNb (NBPtr, BFWrTrainGo) != 0) {}

  // 9. Program D18F2x1C0[WrDramTrainMode]=0.
  MemNSetBitFieldNb (NBPtr, BFWrDramTrainMode, 0);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *      This function reads cache lines continuously using TCB CPG engine
 *
 *     @param[in,out] NBPtr  - Pointer to the MEM_NB_BLOCK
 *     @param[in,out] Buffer - Array of bytes to be filled with data read from DRAM
 *     @param[in]     Address - System Address [47:16]
 *     @param[in] ClCount - Number of cache lines
 *
 */

VOID
STATIC
MemNContReadPatternClientNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 Buffer[],
  IN       UINT32 Address,
  IN       UINT16 ClCount
  )
{
  UINT16 Multiplier;

  Multiplier = 1;
  if (ClCount == 3) {
    // Double pattern length for MaxRdLat training
    Multiplier = 2;
  }

  // 1. Program D18F2x1C0[RdDramTrainMode]=1.
  MemNSetBitFieldNb (NBPtr, BFRdDramTrainMode, 1);

  // 2. Program D18F2x1C0[TrainLength] to the appropriate number of cache lines.
  MemNSetBitFieldNb (NBPtr, BFTrainLength, ClCount * Multiplier);

  // 3. Program the DRAM training address as follows:
  MemNSetBitFieldNb (NBPtr, BFWrTrainAdrPtrLo, Address << (16 - 6));
  MemNSetBitFieldNb (NBPtr, BFWrTrainAdrPtrHi, (Address >> (38 - 16)) & 3);

  // 4. Program D18F2x1D0[WrTrainBufAddr]=000h
  MemNSetBitFieldNb (NBPtr, BFWrTrainBufAddr, 0);

  // 5. Program D18F2x1C0[RdTrainGo]=1.
  MemNSetBitFieldNb (NBPtr, BFRdTrainGo, 1);

  // 6. Wait for D18F2x1C0[RdTrainGo]=0.
  while (MemNGetBitFieldNb (NBPtr, BFRdTrainGo) != 0) {}

  // 7. Read D18F2x1E8[TrainCmpSts] and D18F2x1E8[TrainCmpSts2].
  // This step will be accomplished in Compare routine.

  // 8. Program D18F2x1C0[RdDramTrainMode]=0.
  MemNSetBitFieldNb (NBPtr, BFRdDramTrainMode, 0);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *      This function generates a continuous burst of reads during HW RcvEn training.
 *
 *     @param[in,out] NBPtr  - Pointer to the MEM_NB_BLOCK
 *     @param[in]     Address - System Address [47:16]
 *
 */
VOID
STATIC
MemNGenHwRcvEnReadsClientNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT32 Address
  )
{
  UINT8  TempBuffer[64];
  UINT8  Count;

  for (Count = 0; Count < 3; Count++) {
    NBPtr->ReadPattern (NBPtr, TempBuffer, Address, 64);
  }
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *      This function assigns read/write function pointers to CPG read/write modules.
 *
 *     @param[in,out] NBPtr  - Pointer to the MEM_NB_BLOCK
 *
 */
VOID
MemNInitCPGClientNb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  NBPtr->WritePattern = MemNContWritePatternClientNb;
  NBPtr->ReadPattern = MemNContReadPatternClientNb;
  NBPtr->GenHwRcvEnReads = MemNGenHwRcvEnReadsClientNb;
  NBPtr->FlushPattern = (VOID (*) (MEM_NB_BLOCK *, UINT32, UINT16)) memDefRet;
  NBPtr->CompareTestPattern = MemNCompareTestPatternClientNb;
  NBPtr->InsDlyCompareTestPattern = MemNInsDlyCompareTestPatternClientNb;
  NBPtr->FamilySpecificHook[BeforeMemClr] = MemNBeforeMemClrClientNb;
  NBPtr->CPGInit = 0;
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *       This function compares test pattern with data in buffer and
 *       return a pass/fail bitmap for 8 bytelanes (upper 8 bits are reserved)
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *     @param[in]       Buffer[]  -  Buffer data from DRAM (Measured data from DRAM) to compare
 *     @param[in]       Pattern[]  - Pattern (Expected data in ROM/CACHE) to compare against
 *     @param[in]       ByteCount - Byte count
 *
 *     @return  PASS - Bitmap of results of comparison
 */

UINT16
STATIC
MemNCompareTestPatternClientNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 Buffer[],
  IN       UINT8 Pattern[],
  IN       UINT16 ByteCount
  )
{
  return ~((UINT16) MemNGetBitFieldNb (NBPtr, BFTrainCmpSts));
}

/*-----------------------------------------------------------------------------*/
/**
 *
 *       This function compares test pattern with data in buffer and
 *       return a pass/fail bitmap for 8 bytelanes (upper 8 bits are reserved)
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *     @param[in]       Buffer[]  -  Buffer data from DRAM (Measured data from DRAM) to compare
 *     @param[in]       Pattern[]  - Pattern (Expected data in ROM/CACHE) to compare against
 *     @param[in]       ByteCount - Byte count
 *
 *     @retval  Bitmap of results of comparison
 */
UINT16
STATIC
MemNInsDlyCompareTestPatternClientNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 Buffer[],
  IN       UINT8 Pattern[],
  IN       UINT16 ByteCount
  )
{
  return ~((UINT16) MemNGetBitFieldNb (NBPtr, BFTrainCmpSts2));
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *      This function calculates RcvEn seed value for each rank
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 */
VOID
MemNPrepareRcvrEnDlySeedNb (
  IN OUT   MEM_NB_BLOCK  *NBPtr
  )
{
  MEM_TECH_BLOCK *TechPtr;
  CH_DEF_STRUCT *ChannelPtr;
  DIE_STRUCT *MCTPtr;
  UINT16 SeedTotal;
  UINT16 SeedFine;
  UINT16 SeedGross;
  UINT16 SeedPreGross;
  UINT16 SeedTotalPreScaling;
  UINT8  ByteLane;
  UINT16 Speed;
  UINT16 PlatEst;
  UINT8 ChipSel;
  UINT8 Pass;
  UINT16 *PlatEstSeed;
  UINT16 SeedValue[9];
  UINT16 SeedTtl[9];
  UINT16 SeedPre[9];

  TechPtr = NBPtr->TechPtr;
  MCTPtr = NBPtr->MCTPtr;
  ChannelPtr = TechPtr->NBPtr->ChannelPtr;
  Speed = NBPtr->DCTPtr->Timings.Speed;
  SeedTotalPreScaling = 0;
  ChipSel = TechPtr->ChipSel;
  Pass = TechPtr->Pass;

  for (ByteLane = 0; ByteLane < (MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) {
    TechPtr->Bytelane = ByteLane;
    if (Pass == 1) {
      // Get platform override seed
      PlatEstSeed = (UINT16 *) FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_RXEN_SEED, MCTPtr->SocketId, ChannelPtr->ChannelID);
      // For Pass1, BIOS starts with the delay value obtained from the first pass of write
      // levelization training that was done in DDR3 Training and add a delay value of 3Bh.
      PlatEst = 0x3B;
      NBPtr->FamilySpecificHook[OverrideRcvEnSeed] (NBPtr, &PlatEst);
      PlatEst = ((PlatEstSeed != NULL) ? PlatEstSeed[ByteLane] : PlatEst);
      SeedTotal = ChannelPtr->WrDqsDlys[(ChipSel >> 1) * TechPtr->DlyTableWidth () + ByteLane] + PlatEst;
      SeedValue[ByteLane] = PlatEst;
    } else {
      // For Pass2
      // SeedTotalPreScaling = (the total delay values in D18F2x[1,0]9C_x0000_00[24:10] from pass 1 of
      //  DQS receiver enable training) - 20h. Subtract 1UI to get back to preamble left edge.
      if ((ChipSel & 1) == 0) {
        // Save Seed for odd CS SeedTotalPreScaling RxEn Value
        TechPtr->PrevPassRcvEnDly[ByteLane] = ChannelPtr->RcvEnDlys[(ChipSel >> 1) * TechPtr->DlyTableWidth () + ByteLane];
      }
      SeedTotalPreScaling = TechPtr->PrevPassRcvEnDly[ByteLane] - 0x20;
      // SeedTotal = SeedTotalPreScaling*target frequency/lowest supported frequency.
      SeedTotal = (UINT16) (((UINT32) SeedTotalPreScaling * Speed) / TechPtr->PrevSpeed);
      NBPtr->FamilySpecificHook[OverrideRcvEnSeedPassN] (NBPtr, &SeedTotal);
    }
    SeedTtl[ByteLane] = SeedTotal;

    // SeedGross = SeedTotal DIV 32.
    SeedGross = SeedTotal >> 5;
    // SeedFine = SeedTotal MOD 32.
    SeedFine = SeedTotal & 0x1F;
    // Next, determine the gross component of SeedTotal. SeedGrossPass1=SeedTotal DIV 32.
    // Then, determine the fine delay component of SeedTotal. SeedFinePass1=SeedTotal MOD 32.
    // Use SeedGrossPass1 to determine SeedPreGrossPass1:

    if ((SeedGross & 0x1) != 0) {
      //if SeedGross is odd
      SeedPreGross = 1;
    } else {
      //if SeedGross is even
      SeedPreGross = 2;
    }
    // (SeedGross - SeedPreGross)
    TechPtr->DiffSeedGrossSeedPreGross[ByteLane] = (SeedGross - SeedPreGross) << 5;

    //BIOS programs registers F2x[1, 0]9C_x[51:50] and F2x[1, 0]9C_x52 with SeedPreGrossPass1
    //and SeedFinePass1 from the preceding steps.

    NBPtr->SetTrainDly (NBPtr, AccessPhRecDly, DIMM_BYTE_ACCESS (ChipSel >> 1, ByteLane), (SeedPreGross << 5) | SeedFine);
    SeedPre[ByteLane] = (SeedPreGross << 5) | SeedFine;

    // 202688: Program seed value to RcvEnDly also.
    NBPtr->SetTrainDly (NBPtr, AccessRcvEnDly, DIMM_BYTE_ACCESS (ChipSel >> 1, ByteLane), SeedGross << 5);
  }

  IDS_HDT_CONSOLE_DEBUG_CODE (
    if (Pass == 1) {
      IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tSeedValue: ");
      for (ByteLane = 0; ByteLane < (MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) {
        IDS_HDT_CONSOLE (MEM_FLOW, "%03x ", SeedValue[ByteLane]);
      }
      IDS_HDT_CONSOLE (MEM_FLOW, "\n");
    }
    IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tSeedTotal: ");
    for (ByteLane = 0; ByteLane < (MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) {
      IDS_HDT_CONSOLE (MEM_FLOW, "%03x ", SeedTtl[ByteLane]);
    }
    IDS_HDT_CONSOLE (MEM_FLOW, "\n\t\t\t  SeedPRE: ");
    for (ByteLane = 0; ByteLane < (MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) {
      IDS_HDT_CONSOLE (MEM_FLOW, "%03x ", SeedPre[ByteLane]);
    }
    IDS_HDT_CONSOLE (MEM_FLOW, "\n");
  );
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *  Waits specified number of MEMCLKs
 *      @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *      @param[in] MemClkCount - Number of MEMCLKs
 *
 * ----------------------------------------------------------------------------
 */
VOID
MemNWaitXMemClksNb (
  IN OUT   MEM_NB_BLOCK  *NBPtr,
  IN       UINT32 MemClkCount
  )
{
  MemUWait10ns ((MemClkCount * 100 + NBPtr->DCTPtr->Timings.Speed - 1) / NBPtr->DCTPtr->Timings.Speed, NBPtr->MemPtr);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *  Issues dummy TCB write read to zero out CL that is used for MemClr
 *      @param[in,out] *NBPtr  - Pointer to the MEM_NB_BLOCK
 *      @param[in,out] *UnUsed - unused
 *
 * ----------------------------------------------------------------------------
 */
BOOLEAN
STATIC
MemNBeforeMemClrClientNb (
  IN OUT   MEM_NB_BLOCK  *NBPtr,
  IN       VOID *UnUsed
  )
{
  UINT8 Pattern[64];
  UINT8 i;

  for (i = 0; i < 64; i++) {
    Pattern[i] = 0;
  }

  MemNContWritePatternClientNb (NBPtr, 0x20, Pattern, 1);
  MemNContReadPatternClientNb (NBPtr, Pattern, 0x20, 1);
  return TRUE;
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *   This function uses the PRBS generator in the DCT to send a DDR Activate command
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *     @param[in]        ChipSelect - Chip select 0-7
 *     @param[in]        Bank - Bank Address 0-7
 *     @param[in]        RowAddress - Row Address [17:0]
 *
 */

VOID
STATIC
MemNRrwActivateCmd (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 ChipSelect,
  IN       UINT8 Bank,
  IN       UINT32 RowAddress
  )
{
  // Set Chip select
  MemNSetBitFieldNb (NBPtr, BFCmdChipSelect, (1 << ChipSelect));
  // Set Bank Address
  MemNSetBitFieldNb (NBPtr, BFCmdBank, Bank);
  // Set Row Address
  MemNSetBitFieldNb (NBPtr, BFCmdAddress, RowAddress);
  // Send the command
  MemNSetBitFieldNb (NBPtr, BFSendActCmd, 1);
  // Wait for command complete
  MemNPollBitFieldNb (NBPtr, BFSendActCmd, 0, PCI_ACCESS_TIMEOUT, FALSE);
  // Wait 75 MEMCLKs
  NBPtr->WaitXMemClks (NBPtr, 75);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *   This function uses the PRBS generator in the DCT to send a DDR Precharge
 *     or Precharge All command
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *     @param[in]        ChipSelect - Chip select 0-7
 *     @param[in]        Bank - Bank Address 0-7, PRECHARGE_ALL_BANKS = Precharge All
 *
 *
 */

VOID
STATIC
MemNRrwPrechargeCmd (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 ChipSelect,
  IN       UINT8 Bank
  )
{
  // Wait 25 MEMCLKs
  NBPtr->WaitXMemClks (NBPtr, 25);
  // Set Chip select
  NBPtr->SetBitField (NBPtr, BFCmdChipSelect, (1 << ChipSelect));
  if (Bank == PRECHARGE_ALL_BANKS) {
    // Set Row Address, bit 10
    NBPtr->SetBitField (NBPtr, BFCmdAddress,  NBPtr->GetBitField (NBPtr, BFCmdAddress) | (1 << 10) );
  } else {
    // Clear Row Address, bit 10
    NBPtr->SetBitField (NBPtr, BFCmdAddress,  NBPtr->GetBitField (NBPtr, BFCmdAddress) & (~(1 << 10)) );
    // Set Bank Address
    NBPtr->SetBitField (NBPtr, BFCmdBank, Bank);
  }
  // Send the command
  NBPtr->SetBitField (NBPtr, BFSendPchgCmd, 1);
  // Wait for command complete
  NBPtr->PollBitField (NBPtr, BFSendPchgCmd, 0, PCI_ACCESS_TIMEOUT, FALSE);
  // Wait 25 MEMCLKs
  NBPtr->WaitXMemClks (NBPtr, 25);
}
/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *      This function generates a continuous burst of reads for HW RcvEn
 *        training using the Unified Northbridge Reliable Read/Write Engine.
 *
 *     @param[in,out] NBPtr   - Pointer to the MEM_NB_BLOCK
 *     @param[in]     Address - Unused by this function
 *
 */
VOID
STATIC
MemNGenHwRcvEnReadsUnb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT32 Address
  )
{
  VOID  *DummyPtr;
  DummyPtr = NULL;
  //
  // Issue Stream of Reads from the Target Rank
  //
  NBPtr->ReadPattern (NBPtr, DummyPtr, 0, NBPtr->TechPtr->PatternLength);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *     This function generates a continuous stream of reads from DRAM using the
 *       Unified Northbridge Reliable Read/Write Engine.
 *
 *     @param[in,out] NBPtr   - Pointer to the MEM_NB_BLOCK
 *     @param[in,out] Buffer  - Unused by this function
 *     @param[in]     Address - Unused by this function
 *     @param[in]     ClCount - Number of cache lines to read
 *
 *     Assumptions:
 *
 *
 *
 */

VOID
STATIC
MemNContReadPatternUnb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 Buffer[],
  IN       UINT32 Address,
  IN       UINT16 ClCount
  )
{
  MEM_TECH_BLOCK *TechPtr;
  RRW_SETTINGS *Rrw;
  UINT8 CmdTgt;
  UINT8 ChipSel;

  TechPtr = NBPtr->TechPtr;
  Rrw = &NBPtr->RrwSettings;

  ChipSel = TechPtr->ChipSel;
  CmdTgt = Rrw->CmdTgt;
  //
  // Wait for RRW Engine to be ready and turn it on
  //
  NBPtr->PollBitField (NBPtr, BFCmdSendInProg, 0, PCI_ACCESS_TIMEOUT, FALSE);
  NBPtr->SetBitField (NBPtr, BFCmdTestEnable, 1);
  //
  // Depending upon the Cmd Target, send Row Activate and set Chipselect
  //   for the Row or Rows that will be used
  //
  MemNRrwActivateCmd (NBPtr, ChipSel, Rrw->TgtBankAddressA, Rrw->TgtRowAddressA);
  NBPtr->SetBitField (NBPtr, BFTgtChipSelectA, ChipSel);
  if (CmdTgt == CMD_TGT_AB) {
    MemNRrwActivateCmd (NBPtr, ChipSel, Rrw->TgtBankAddressB, Rrw->TgtRowAddressB);
    NBPtr->SetBitField (NBPtr, BFTgtChipSelectB, ChipSel);
  }
  // Set Comparison Masks
  NBPtr->SetBitField (NBPtr, BFDramDqMaskLow, Rrw->CompareMaskLow);
  NBPtr->SetBitField (NBPtr, BFDramDqMaskHigh, Rrw->CompareMaskHigh);
  //
  // If All Dimms are ECC Capable Test ECC. Otherwise, mask it off
  //
  NBPtr->SetBitField (NBPtr, BFDramEccMask, (NBPtr->MCTPtr->Status[SbEccDimms] == TRUE) ? Rrw->CompareMaskEcc : 0xFF);
  //
  // Program the PRBS Seed
  //
  NBPtr->SetBitField (NBPtr, BFDataPrbsSeed, Rrw->DataPrbsSeed);
  //
  // Set the Command Count
  //
  NBPtr->SetBitField (NBPtr, BFCmdCount, ClCount);
  //
  // Program the Bubble Count and CmdStreamLen
  //
  NBPtr->SetBitField (NBPtr, BFBubbleCnt, 0);
  NBPtr->SetBitField (NBPtr, BFBubbleCnt2, 0);
  NBPtr->SetBitField (NBPtr, BFCmdStreamLen, 1);
  //
  // Program the Starting Address
  //
  NBPtr->SetBitField (NBPtr, BFTgtBankA, Rrw->TgtBankAddressA);
  NBPtr->SetBitField (NBPtr, BFTgtAddressA, Rrw->TgtColAddressA);
  if (CmdTgt == CMD_TGT_AB) {
    NBPtr->SetBitField (NBPtr, BFTgtBankB, Rrw->TgtBankAddressB);
    NBPtr->SetBitField (NBPtr, BFTgtAddressB, Rrw->TgtColAddressB);
  }
  //
  // Reset All Errors and Disable StopOnErr
  //
  NBPtr->SetBitField (NBPtr, BFResetAllErr, 1);
  NBPtr->SetBitField (NBPtr, BFStopOnErr, 0);
  //
  // Program the CmdTarget
  //
  NBPtr->SetBitField (NBPtr, BFCmdTgt, CmdTgt);
  //
  // Set CmdType to read
  //
  NBPtr->SetBitField (NBPtr, BFCmdType, CMD_TYPE_READ);
  //
  // Start the Commands
  //
  NBPtr->SetBitField (NBPtr, BFSendCmd, 1);
  //
  // Commands have started, wait for the reads to complete then clear the command
  //
  NBPtr->PollBitField (NBPtr, BFTestStatus, 1, PCI_ACCESS_TIMEOUT, FALSE);
  NBPtr->PollBitField (NBPtr, BFCmdSendInProg, 0, PCI_ACCESS_TIMEOUT, FALSE);
  NBPtr->SetBitField (NBPtr, BFSendCmd, 0);
  //
  // Send the Precharge All Command
  //
  MemNRrwPrechargeCmd (NBPtr, ChipSel, PRECHARGE_ALL_BANKS);
  //
  // Turn Off the RRW Engine
  //
  NBPtr->SetBitField (NBPtr, BFCmdTestEnable, 0);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *     This function generates a continuous stream of writes to DRAM using the
 *       Unified Northbridge Reliable Read/Write Engine.
 *
 *     @param[in,out] NBPtr   - Pointer to the MEM_NB_BLOCK
 *     @param[in,out] Address - Unused by this function
 *     @param[in]     Pattern - Unused by this function
 *     @param[in]     ClCount - Number of cache lines to write
 *
 */

VOID
STATIC
MemNContWritePatternUnb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT32 Address,
  IN       UINT8 Pattern[],
  IN       UINT16 ClCount
  )
{
  MEM_TECH_BLOCK *TechPtr;
  RRW_SETTINGS *Rrw;
  UINT8 CmdTgt;
  UINT8 ChipSel;

  TechPtr = NBPtr->TechPtr;
  Rrw = &NBPtr->RrwSettings;

  ChipSel = TechPtr->ChipSel;
  CmdTgt = Rrw->CmdTgt;
  //
  // Wait for RRW Engine to be ready and turn it on
  //
  NBPtr->PollBitField (NBPtr, BFCmdSendInProg, 0, PCI_ACCESS_TIMEOUT, FALSE);
  NBPtr->SetBitField (NBPtr, BFCmdTestEnable, 1);

  //
  // Depending upon the Cmd Target, send Row Activate and set Chipselect
  //   for the Row or Rows that will be used
  //
  MemNRrwActivateCmd (NBPtr, ChipSel, Rrw->TgtBankAddressA, Rrw->TgtRowAddressA);
  NBPtr->SetBitField (NBPtr, BFTgtChipSelectA, ChipSel);
  if (CmdTgt == CMD_TGT_AB) {
    MemNRrwActivateCmd (NBPtr, ChipSel, Rrw->TgtBankAddressB, Rrw->TgtRowAddressB);
    NBPtr->SetBitField (NBPtr, BFTgtChipSelectB, ChipSel);
  }
  //
  // Program the PRBS Seed
  //
  NBPtr->SetBitField (NBPtr, BFDataPrbsSeed, Rrw->DataPrbsSeed);
  //
  // Set the Command Count
  //
  NBPtr->SetBitField (NBPtr, BFCmdCount, ClCount);
  //
  // Program the Bubble Count and CmdStreamLen
  //
  NBPtr->SetBitField (NBPtr, BFBubbleCnt, 0);
  NBPtr->SetBitField (NBPtr, BFBubbleCnt2, 0);
  NBPtr->SetBitField (NBPtr, BFCmdStreamLen, 1);
  //
  // Program the Starting Address
  //
  NBPtr->SetBitField (NBPtr, BFTgtBankA, Rrw->TgtBankAddressA);
  NBPtr->SetBitField (NBPtr, BFTgtAddressA, Rrw->TgtColAddressA);
  if (CmdTgt == CMD_TGT_AB) {
    NBPtr->SetBitField (NBPtr, BFTgtBankB, Rrw->TgtBankAddressB);
    NBPtr->SetBitField (NBPtr, BFTgtAddressB, Rrw->TgtColAddressB);
  }
  //
  // Program the CmdTarget
  //
  NBPtr->SetBitField (NBPtr, BFCmdTgt, CmdTgt);
  //
  // Set CmdType to read
  //
  NBPtr->SetBitField (NBPtr, BFCmdType, CMD_TYPE_WRITE);
  //
  // Start the Commands
  //
  NBPtr->SetBitField (NBPtr, BFSendCmd, 1);
  //
  // Commands have started, wait for the writes to complete then clear the command
  //
  NBPtr->PollBitField (NBPtr, BFTestStatus, 1, PCI_ACCESS_TIMEOUT, FALSE);
  NBPtr->PollBitField (NBPtr, BFCmdSendInProg, 0, PCI_ACCESS_TIMEOUT, FALSE);
  NBPtr->SetBitField (NBPtr, BFSendCmd, 0);
  //
  // Send the Precharge All Command
  //
  MemNRrwPrechargeCmd (NBPtr, ChipSel, PRECHARGE_ALL_BANKS);
  //
  // Turn Off the RRW Engine
  //
  NBPtr->SetBitField (NBPtr, BFCmdTestEnable, 0);
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *       This function checks the Error status bits for comparison results
 *
 *     @param[in,out]   *NBPtr    - Pointer to the MEM_NB_BLOCK
 *     @param[in]       Buffer[]  -  Not used in this implementation
 *     @param[in]       Pattern[] - Not used in this implementation
 *     @param[in]       ByteCount - Not used in this implementation
 *
 *     @return  PASS - Bitmap of results of comparison
 */

UINT16
STATIC
MemNCompareTestPatternUnb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 Buffer[],
  IN       UINT8 Pattern[],
  IN       UINT16 ByteCount
  )
{


  UINT16 i;
  UINT16 Pass;
  UINT8 ChipSel;
  UINT8 ColumnCount;
  UINT8* FailingBitMaskPtr;
  UINT8 FailingBitMask[9];
  UINT32 NibbleErrSts;

  ChipSel = NBPtr->TechPtr->ChipSel;
  ColumnCount = NBPtr->ChannelPtr->ColumnCount;
  // Calculate Failing Bitmask pointer
  FailingBitMaskPtr = &(NBPtr->ChannelPtr->FailingBitMask[(ColumnCount * NBPtr->TechPtr->ChipSel)]);

  //
  // Get Failing bit data
  //
  *((UINT32*)FailingBitMask) = NBPtr->GetBitField (NBPtr, BFDQErrLow);
  *((UINT32*)&FailingBitMask[4]) = NBPtr->GetBitField (NBPtr, BFDQErrHigh);
  FailingBitMask[8] = (UINT8)NBPtr->GetBitField (NBPtr, BFEccErr);

  Pass = 0x0000;
  //
  // Get Comparison Results - Convert Nibble Masks to Byte Masks
  //
  NibbleErrSts = NBPtr->GetBitField (NBPtr, BFNibbleErrSts);

  for (i = 0; i < ColumnCount ; i++) {
    Pass |= ((NibbleErrSts & 0x03) > 0 ) ? (1 << i) : 0;
    NibbleErrSts >>= 2;
    FailingBitMaskPtr[i] = FailingBitMask[i];
  }
  Pass = ~Pass;
  return Pass;
}

/*-----------------------------------------------------------------------------*/
/**
 *
 *       This function checks the Error status bits for offset comparison results
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *     @param[in]       Buffer[]  -  Buffer data from DRAM (Measured data from DRAM) to compare
 *     @param[in]       Pattern[]  - Pattern (Expected data in ROM/CACHE) to compare against
 *     @param[in]       ByteCount - Byte count
 *
 *     @retval  Bitmap of results of comparison
 */
UINT16
STATIC
MemNInsDlyCompareTestPatternUnb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       UINT8 Buffer[],
  IN       UINT8 Pattern[],
  IN       UINT16 ByteCount
  )
{
  UINT16 i;
  UINT16 Pass;
  UINT8 ColumnCount;
  UINT32 NibbleErr180Sts;

  ColumnCount = NBPtr->ChannelPtr->ColumnCount;
  Pass = 0x0000;
  //
  // Get Comparison Results - Convert Nibble Masks to Byte Masks
  //
  NibbleErr180Sts = NBPtr->GetBitField (NBPtr, BFNibbleErr180Sts);

  for (i = 0; i < ColumnCount ; i++) {
    Pass |= ((NibbleErr180Sts & 0x03) > 0 ) ? (1 << i) : 0;
    NibbleErr180Sts >>= 2;
  }
  Pass = ~Pass;

  return Pass;
}

/* -----------------------------------------------------------------------------*/
/**
 *
 *      This function assigns read/write function pointers to CPG read/write modules.
 *
 *     @param[in,out] NBPtr  - Pointer to the MEM_NB_BLOCK
 *
 */
VOID
MemNInitCPGUnb (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  NBPtr->WritePattern = MemNContWritePatternUnb;
  NBPtr->ReadPattern = MemNContReadPatternUnb;
  NBPtr->GenHwRcvEnReads = MemNGenHwRcvEnReadsUnb;
  NBPtr->FlushPattern = (VOID (*) (MEM_NB_BLOCK *, UINT32, UINT16)) memDefRet;
  NBPtr->TrainingPatternInit = (AGESA_STATUS (*) (MEM_NB_BLOCK *)) memDefRetSuccess;
  NBPtr->TrainingPatternFinalize = (AGESA_STATUS (*) (MEM_NB_BLOCK *)) memDefRetSuccess;
  NBPtr->CompareTestPattern = MemNCompareTestPatternUnb;
  NBPtr->InsDlyCompareTestPattern = MemNInsDlyCompareTestPatternUnb;
  NBPtr->FamilySpecificHook[SetupHwTrainingEngine] = MemNSetupHwTrainingEngineUnb;
  NBPtr->CPGInit = 0;
}

