/** @file
MemHost.h
@copyright
Copyright 2006 - 2021 Intel Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef _memhost_h
#define _memhost_h
#include
#include "DataTypes.h"
#include "PlatformHost.h"
#include "MemRegs.h"
#include "MemDefaults.h"
#include "NGNDimmPlatformCfgData.h"
#include "MrcCommonTypes.h"
#include "MemHostChipCommon.h"
#include
#include
#include
#define RESERVED_2 2
typedef struct TrainingStepDoneStruct {
UINT8 DramRxEq : 1;
UINT8 HostFlyBy : 1;
UINT8 TxVref : 1;
UINT8 DqSwzDone : 1;
UINT8 Reserved : 4;
} TRAINING_STEP_DONE_STRUCT;
#define CADB_MUX_MAX 4
#define MAX_BITS_IN_BYTE 8 // BITS per byte
#define MAX_BITS_IN_DWORD 32 // BITS per dword
#define BITS_PER_NIBBLE 4
#define MAX_NIBBLES_PER_BYTE 2
#define INDEX_NIBBLE0 0
#define INDEX_NIBBLE1 1
//
// DDR4 DB has 4 DFE coeff taps
//
#define DB_DFE_TAP 4
#pragma pack(push, 1)
///
/// Rand per channel information
//
typedef struct RankCh {
UINT8 dimm; ///< DIMM this rank belongs to
UINT8 rank; ///< Rank on the DIMM (0-3)
UINT8 Roundtrip;
UINT8 IOLatency;
} CHANNEL_RANKS;
typedef enum {
INVALID_BUS,
SMBUS,
EMRS,
CPGC,
SAD,
} BUS_TYPE;
//
// -----------------------------------------------------------------------------
///
/// Common DRAM timings
///
struct comTime {
UINT8 nCL;
UINT8 nWR;
UINT8 nRCD;
UINT8 nAL;
UINT8 nRP;
UINT8 nRC;
UINT8 nWTR;
UINT8 nWTR_L;
UINT8 nRAS;
UINT8 nRTP;
UINT8 nFAW;
UINT8 nRRD;
UINT8 nRRD_L;
UINT8 nWL;
UINT16 nRFC;
UINT32 tCL;
UINT16 tRCD;
UINT16 tRP;
UINT16 tRC;
UINT16 tRFC;
UINT16 tRRD;
UINT16 tRRD_L;
UINT16 tRAS;
UINT16 tCCD;
UINT16 tCCD_WR;
UINT16 tCCD_L;
UINT16 tCCD_WR_L;
UINT64 casSup;
UINT8 casSupRange;
}; //struct comTime
//
// Only applicable for x16 devices where 2 strobes are within a single DRAM device
//
typedef struct _X16_MAPPING {
UINT8 PairLogical[MAX_STROBE/2]; ///< Identifies logical strobe within the same DRAM device
BOOLEAN IsLow[MAX_STROBE/2]; ///< TRUE: represents the current logical strobe is connected to DQSL
///< FALSE: represents the current logical strobe is connected to DQSU
} X16_MAPPING;
//
// Packed bit field structure for storing MR1 RX EQ bits
//
typedef struct {
UINT32 Strobe0 : 3; //bits 0...2
UINT32 Strobe1 : 3; //bits 3...5
UINT32 Strobe2 : 3; //bits 6...8
UINT32 Strobe3 : 3; //bits 9...11
UINT32 Strobe4 : 3; //bits 12..14
UINT32 Strobe5 : 3; //bits 15..17
UINT32 Strobe6 : 3; //bits 18..20
UINT32 Strobe7 : 3; //bits 21..23
UINT32 Strobe8 : 3; //bits 24..26
UINT32 Rsvd : 5; //bits 27..31
} Mr1RxEqStruct;
//
// NVRAM structures for S3 state
//
///
/// DIMM rank info
/// List indexed by rank number
///
typedef struct ddrRank {
UINT8 enabled; ///< 0 = disabled, 1 = enabled
UINT8 rankIndex;
UINT8 phyRank; ///< Physical Rank #(3:0)
UINT8 logicalRank; ///< Logical Rank number (0 - 7)
UINT8 ckIndex; ///< Index to the clock for this rank
UINT8 ctlIndex; ///< Index to the control group for this rank
UINT8 CKEIndex;
UINT8 ODTIndex;
UINT8 CSIndex;
UINT8 devTagInfo;
UINT16 RttWr;
UINT16 RttPrk;
UINT16 RttNom;
UINT16 rankSize; ///< Units of 64 MB
UINT16 remSize; ///< Units of 64 MB
UINT16 NVrankSize; ///< Units of 64 MB
UINT8 cmdLeft;
UINT8 cmdRight;
UINT8 cmdLow;
UINT8 cmdHigh;
UINT8 rxDQLeftSt;
UINT8 rxDQRightSt;
UINT8 txDQLeftSt;
UINT8 txDQRightSt;
UINT16 OutDrvImpCtrl;
UINT8 DqSwzDdr5[SUB_CH][20];
UINT8 faultyParts[MAX_STROBE];
#ifdef LRDIMM_SUPPORT
UINT8 lrbufRxVref[MAX_STROBE]; ///< Actual value of backside RxVref
UINT8 lrBuf_FxBC4x5x[MAX_STROBE];
UINT8 lrBuf_FxBC8x9x[MAX_STROBE];
#endif
UINT8 lrBuf_FxBC2x3x[MAX_STROBE];
UINT8 lrBuf_FxBCAxBx[MAX_STROBE];
UINT8 lrBuf_FxBCCxEx[MAX_STROBE/2];
UINT8 lrBuf_FxBCDxFx[MAX_STROBE/2];
UINT32 lrbufTxVref[MAX_STROBE]; ///< Actual value of backside TxVref
//
// MR1 per strobe Rx Eq value structure with 9 elements per structure
// therefore you need MAX_STROBE/9 structures to store all elements
//
Mr1RxEqStruct Mr1RxEqSettings[MAX_STROBE/9];
} DDR_RANK_STRUCT; //struct ddrRank
typedef enum {
DIMM_RANK_MAP_OUT_UNKNOWN = 0,
DIMM_RANK_MAP_OUT_MEM_DECODE,
DIMM_RANK_MAP_OUT_POP_POR_VIOLATION,
DIMM_RANK_MAP_OUT_RANK_DISABLED,
DIMM_RANK_MAP_OUT_ADVMEMTEST_FAILURE,
DIMM_RANK_MAP_OUT_MAX
} DIMM_RANK_MAP_OUT_REASON;
///
/// DIMM information stored in NVRAM
//
typedef struct dimmNvram {
UINT8 dimmPresent; ///< 1 = DIMM present in this slot
UINT8 mailboxReady;
UINT16 lrbufswizzle;
INT32 minTCK; ///< minimum tCK for this DIMM (SPD_MIN_TCK)
UINT8 ftbTCK; ///< fine offset for tCK
UINT32 tCL;
UINT16 tRCD;
UINT16 tRP;
UINT8 ftbTRP; ///< DDR4 fine offset for tRP
UINT8 ftbTRCD; ///< DDR4 fine offset for tRCD
UINT8 ftbTAA; ///< DDR4 fine offset for tAA
UINT8 mapOut[MAX_RANK_DIMM]; ///< 1 = User requested rank made non-Present
UINT8 numRanks; ///< Number of logical ranks on this DIMM
UINT8 numDramRanks; ///< Number of physical DRAM ranks on this DIMM
UINT8 techIndex; ///< Index into DIMM technology table
UINT8 aepTechIndex; ///< Index into NVM DIMM technology table
UINT8 fmcType; ///< Far Memory Controller Type
UINT8 fmcRev; ///< Far Memory Controller Rev Type
SPD_AEP_MOD_REVISION_STRUCT FmcModRev; ///< Far Memory Controller Module Rev and Type
UINT8 NvmStepping; ///< NVM Device Stepping
UINT8 NvmDevDensity; ///< NVM DEV DENSITY
UINT8 NvmDevType; ///< NVM DEV TYPE
UINT8 SPDRawCard; ///< Raw Card Number
UINT8 DimmRevType; ///< RCD Revision
UINT8 SPDOtherOptFeatures;///< SDRAM Other Optional features
UINT8 SPDAddrMapp; ///< Address Mapping from Edge connector to DRAM
UINT8 SPDRegRev; ///< Register Revision
UINT8 SPDODCtl; ///< Register Output Drive Strength for Control
UINT8 SPDODCk; ///< Register Output Drive Strength for Clock
#ifdef LRDIMM_SUPPORT
UINT16 SPDLrbufVen; ///< LRDIMM Data Buffer Vendor ID
UINT8 SPDLrbufDramVrefdqR0; ///< DRAM VrefDQ for Package Rank 0
UINT8 SPDLrbufDramVrefdqR1; ///< DRAM VrefDQ for Package Rank 1
UINT8 SPDLrbufDramVrefdqR2; ///< DRAM VrefDQ for Package Rank 2
UINT8 SPDLrbufDramVrefdqR3; ///< DRAM VrefDQ for Package Rank 3
UINT8 SPDLrbufDbVrefdq; ///< LR Data Buffer VrefDQ for DRAM Interface
UINT8 SPDLrbufDbDsRttLe1866; ///< LR Data Buffer MDQ Drive Strength and RTT for data rate <= 1866
UINT8 SPDLrbufDbDsRttGt1866Le2400; ///< LR Data Buffer MDQ Drive Strength and RTT for data rate > 1866 and <= 2400
UINT8 SPDLrbufDbDsRttGt2400Le3200; ///< LR Data Buffer MDQ Drive Strength and RTT for data rate > 2400 and <= 3200
UINT8 SPDLrbufDramDs; ///< LR Buffer DRAM Drive Strength (for data rates <1866, 1866 < data rate < 2400, and 2400 < data rate < 3200)
UINT8 SPDLrbufDramOdtWrNomLe1866; ///< LR Buffer DRAM ODT (RTT_WR and RTT_NOM) for data rate <= 1866
UINT8 SPDLrbufDramOdtWrNomGt1866Le2400; ///< LR Buffer DRAM ODT (RTT_WR and RTT_NOM) for data rate > 1866 and <= 2400
UINT8 SPDLrbufDramOdtWrNomGt2400Le3200; ///< LR Buffer DRAM ODT (RTT_WR and RTT_NOM) for data rate > 2400 and <= 3200
UINT8 SPDLrbufDramOdtParkLe1866; ///< LR Buffer DRAM ODT (RTT_WR and RTT_NOM) for data rate <= 1866
UINT8 SPDLrbufDramOdtParkGt1866Le2400; ///< LR Buffer DRAM ODT (RTT_WR and RTT_NOM) for data rate > 1866 and <= 2400
UINT8 SPDLrbufDramOdtParkGt2400Le3200; ///< LR Buffer DRAM ODT (RTT_WR and RTT_NOM) for data rate > 2400 and <= 3200
UINT8 rcLrFunc;
UINT8 lrBuf_BC00;
UINT8 lrBuf_BC01;
UINT8 lrBuf_BC02;
UINT8 lrBuf_BC03;
UINT8 lrBuf_BC04;
UINT8 lrBuf_BC05;
UINT8 lrBuf_BC1x;
UINT8 LrBuf_DFECoef[MAX_BITS_IN_BYTE][DB_DFE_TAP][MAX_STROBE/2]; // JEDEC F3BCCx-Fx coeffcient. 8 DQ x 4 taps x 9 DB
UINT8 Dfe_F2BCEX; // JEDEC DB02DFE DQ selection and global enable
#endif // LRDIMM_SUPPORT
UINT8 XMPOrg; ///< XMP organization and configuration
UINT8 XMPRev;
UINT32 XMPChecksum;
UINT8 x4Present; ///< Set if this is a x4 rank
UINT8 keyByte;
UINT8 keyByte2; ///< Logical module type (for MRC compat)
UINT8 DcpmmPresent; ///< Is an NVM DIMM present?
BOOLEAN NvmDimmDisable; ///< 1 = NVMDimm present but got disabled in this slot
UINT8 actKeyByte2; ///< Actual module type reported by SPD
UINT8 SPDModuleOrg; ///< Logical number of DRAM ranks and device width
UINT8 actSPDModuleOrg; ///< Actual number of DRAM ranks and device width
UINT8 dramIOWidth; ///< The encoded value of DRAM IO width
UINT8 dramIOWidthSecondary; ///< The encoded value of IO width for secondary SDRAM
BOOLEAN rankMix; ///< Used to indicate if the target DIMM is asymmetric
UINT8 SPDDeviceType; ///< Primary SDRAM Device Type
UINT8 SPDSecondaryDeviceType; ///< Secondary SDRAM Device Type
UINT8 numBankAddressBits; ///< Number of bank address bits per bank group
UINT8 numBankAddressBitsSecondary; ///< Number of bank address bits per bank group of Secondary SDRAM
UINT8 numBankGroupBits; ///< Number of bank group bits
UINT8 numBankGroupBitsSecondary; ///< Number of bank group bits of Secondary SDRAM
UINT8 sdramCapacity; ///< Encoded SDRAM capacity based on DDR4 format
UINT8 sdramCapacitySecondary; ///< Encoded SDRAM capacity based on DDR4 format for Secondary SDRAM
UINT8 numRowBits; ///< Number of row address bits
UINT8 numRowBitsSecondary; ///< Number of row address bits of Secondary SDRAM
UINT8 numColBits; ///< Number of column address bits
UINT8 numColBitsSecondary; ///< Number of column address bits of Secondary SDRAM
UINT8 dieCount; ///< Number of SDRAM dies per package for symmetric DIMMs or Primary SDRAM dies per package for asymmetric DIMMs
UINT8 dieCountSecondary; ///< Number of Secondary DRAM dies per package for asymmetric DIMMs
UINT8 cidBitMap; ///< SubRanks per chip select per dimm of DDR4 3DS and non3ds_lrdimm
UINT8 lrRankMult; ///< Rank multiplication factor
UINT8 SPDMemBusWidth; ///< Width of the Primary bus and extension
UINT8 dimmTs; ///< Module Thermal Sensor
UINT8 dimmAttrib; ///< Module attributes
UINT8 mtbDiv; ///< medium time base divisor (SPD_MTB_DIV)
UINT8 SPDftb; ///< fine time base (SPD_FTB)
UINT32 dimmMemTech; ///< Used to program DIMMMTR
UINT16 SPDRegVen; ///< Register Vendor ID
UINT16 SPDMMfgId; ///< Module Mfg Id from SPD
UINT8 SPDMMfLoc; ///< Module Mfg Location from SPD
UINT16 SPDModDate; ///< Module Manufacturing Date
UINT16 SPDDramMfgId; ///< DRAM Mfg Id
UINT8 SPDDramRev; ///< DRAM Rev Id
UINT8 SPDModSN[SPD_MODULE_SERIAL]; ///< Module Serial Number
UINT8 SPDModPartDDR4[SPD_MODULE_PART_DDR4]; ///< Module Part Number DDR4
UINT8 SPDOptionalFeature; ///< DDR4 optional feature
UINT8 AitDramPoll;
BOOLEAN NvDimmNPresent; ///< JEDEC NVDIMM-N Type Memory Present
UINT16 NvDimmStatus;
// Bit Description
// 0 NVDIMM controller failure
// 1 NVDIMM restore failed
// 2 NVDIMM restore retry
// 3 NVDIMM backup failed
// 4 NVDIMM erase failed
// 5 NVDIMM erase retry
// 6 NVDIMM arm failed
// 7 No backup energy source detected
// 8 Backup energy source charge failed
// 9 NVDIMM uncorrectable memory error
// 10 NVDIMM correctable memory memory error threshold
// 11-15 Reserved
UINT8 lrbufRid; ///< LR Buffer Revision ID (from buffer not SPD)
UINT8 lrbufGen; ///< LR Buffer Gen
UINT8 SPDIntelSN[5]; ///< Intel DIMM serial number
struct ddrRank rankList[MAX_RANK_DIMM];
UINT8 SPDmtb; ///< DDR4 medium time base (SPD_TB_DDR4)
UINT8 SPDSpecRev; ///< Revision of the SPD spec for this data
UINT8 SpdModuleType; ///< SPD Byte 2 (0x002): Key Byte / Host Bus Command Protocol Type
UINT8 rcCache[16]; /// DDR4 RCD cache
UINT8 rcxCache[16];
UINT8 lrDimmPresent;
UINT8 rcClk;
UINT8 rcCmd;
UINT8 rcCtl;
UINT16 rcVref;
INT16 QxCAClkOffset; ///< RCD QxCA Training Offset
UINT8 dqSwz[36];
UINT16 rawCap; ///< Raw Capacity
UINT16 VendorID; ///< Vendor ID for NVMDIMM Mgmt driver thru Nfit
UINT16 DeviceID; ///< Device ID for NVMDIMM Mgmt driver thru Nfit
UINT16 RevisionID;
UINT16 SubsystemVendorID;
UINT16 SubsystemDeviceID;
UINT16 SubsystemRevisionID;
UINT8 DimmGnt2Erid; ///< DIMM-side Grant-to-ERID (produced by SPD and consumed by FMC; distinct from MC-programmed value)
X16_MAPPING LogicalX16Mapping;
UINT8 manufacturer[NGN_MAX_MANUFACTURER_STRLEN]; /* Manufacturer */
UINT8 serialNumber[NGN_MAX_SERIALNUMBER_STRLEN]; /* Serial Number */
UINT8 PartNumber[NGN_MAX_PARTNUMBER_STRLEN]; /* Part Number */
UINT16 volCap; /* Volatile Capacity (2LM region) */
UINT16 nonVolCap; /* NonVolatile Capacity (PMEM/PMEM$ region + Blk region) */
UINT16 perCap; /* Persistent Capcity (PMEM/PMEM$). This size is not obtained from FNV. This is derived data. */
UINT16 WbCachePerCap; /* Persistent WB cache Capcity (AD-WB) This size is not obtained from FNV. This is derived data. */
UINT32 volRegionDPA; /* DPA start address of 2LM Region */
UINT32 perRegionDPA; /* DPA start address of PMEM Region */
struct firmwareRev firmwareRevision; /* Firmware Revision */
UINT8 dimmSku; /* Dimm SKU info Bit0:MemorymodeEnabled 1: StoragemodeEnabled 2:AppDirectmodeEnabled 3:DieSparingCapable 4:SoftProgrammableSKU 5:MemorymodeEncryptionEnabled 6:AppDirectmodeEncryptionEnabled 7:StoragemodeEncrytionEnabled */
UINT16 InterfaceFormatCode;
UINT16 VendorIDIdentifyDIMM;
UINT16 DeviceIDIdentifyDIMM;
UINT32 DdrtDimmBasicTiming;
UINT8 Uniqueid[NGN_MAX_UID_STRLEN]; /* Unique ID */
DIMM_RANK_MAP_OUT_REASON MapOutReason[MAX_RANK_DIMM];
UINT8 VlpRdimmPresent;
RDIMM_RDIMM_THERMAL_HEAT_SPREADER_SOLUTION_STRUCT SpdThermalHeatSpreaderSolution; ///< Byte 132 (0x084) (Registered): RDIMM Thermal Heat Spreader Solution
UINT8 pad[1]; ///< padding added to eliminate: MemChipDdrio.c(5567): warning C4366: The result of the unary '&' operator may be unaligned. ie: &((*ChannelNvList)[Channel].ddrCRClkControls)
} DIMM_NVRAM_STRUCT; //struct dimmNvram
#define MAX_CMD_CSR 16
#define MAX_SIDE 2
///
/// Channel information stored in NVRAM
///
typedef struct channelNvram {
UINT8 enabled; ///< 0 = channel disabled, 1 = channel enabled
UINT8 mb3trainingfailure;
UINT8 features; ///< Bit mask of features to enable or disable
UINT8 maxDimm; ///< Number of DIMM
UINT8 numRanks; ///< Number of ranks on this channel
UINT8 numQuadRanks; ///< Number of QR DIMMs on this channel
UINT8 timingMode; ///< Command timing mode(1N, 2N, or 3N) for normal operation
UINT8 trainTimingMode; ///< Command timing mode(1N, 2N, or 3N) for training
UINT8 ckeMask; ///< CKE signals to assert during IOSAV mode
UINT8 chFailed; ///< ddr4 memory in this channel had failed (MFO)
UINT8 ngnChFailed; ///< NGN memory in this channel had failed (MFO)
struct comTime common; ///< Common timings for this channel
struct dimmNvram dimmList[MAX_DIMM];
struct RankCh rankPerCh[MAX_RANK_CH];
UINT32 dimmVrefControlFnv1;
UINT32 dimmVrefControlFnv1Sa; // SA fub
UINT32 ddrCrCmdPiCodingFnv;
UINT32 ddrCrCmdPiCodingFnv2;
UINT8 encodedCSMode;
UINT8 cidBitMap;
UINT8 txVrefSafe[MAX_RANK_CH];
UINT8 dimmRevType;
UINT8 lrDimmPresent;
#ifdef LRDIMM_SUPPORT
UINT8 chOneRankTimingModeEnable;
#endif
UINT8 lrRankMultEnabled;
UINT8 v110NotSupported;
UINT8 v120NotSupported;
UINT32 rankErrCountStatus;
UINT32 rankErrCountInfo[(MAX_RANK_CH * SUB_CH)/2];
UINT32 rankErrThresholdInfo[(MAX_RANK_CH * SUB_CH)/2];
UINT8 ddrtEnabled;
UINT32 SmiSpareCtlMcMainExt;
UINT8 spareInUse;
UINT8 spareDimm[MAX_RANK_CH/2];
UINT8 spareRank[MAX_RANK_CH/2];
UINT16 spareRankSize[MAX_RANK_CH/2];
UINT8 spareLogicalRank[MAX_SPARE_RANK];
UINT8 sparePhysicalRank[MAX_SPARE_RANK];
UINT32 ioLatency1;
UINT32 tcrwp; ///< TCRWP_MCDDC_CTL_STRUCT
UINT32 tcothp; ///< TCOTHP_MCDDC_CTL_STRUCT
UINT32 tcothp2;
UINT32 TCMr0Shadow;
UINT32 TCMr2Shadow;
UINT32 TCMr4Shadow;
UINT32 TCMr5Shadow;
INT16 normalizationFactor;
UINT8 FmcWrCreditLimit;
UINT8 FmcRdCreditLimit;
UINT8 twoXRefreshSetPerCh; /* Saves the refreshRate value for each channel */
UINT8 tCCDAdder;
BUS_TYPE fnvAccessMode;
UINT32 ddrtDimm0BasicTiming;
UINT32 ddrtDimm1BasicTiming;
UINT32 cadbMuxPattern[CADB_MUX_MAX];
UINT8 EccModeMcMain[(MAX_RANK_CH * SUB_CH)];
UINT32 Plus1Failover[(MAX_RANK_CH * SUB_CH)];
UINT32 LinkRetryErrLimits;
UINT32 LinkLinkFail;
UINT32 mtCas2CasDr; /* CNX Change */
UINT32 mtCas2CasDd; /* CNX Change */
UINT32 mtCas2CasSr; /* CNX Change */
UINT32 mtCas2CasSg; /* CNX Change */
UINT32 mtCas2CasDs; /* CNX Change */
UINT32 tCke; /* CNX Change */
UINT32 MemoryTimingsAdj;
UINT8 T_rrdr_org; ///< Nvram Variable to store original tRRDR turnaround timing parameter
UINT8 T_rrdd_org; ///< Nvram Variable to store original tRRDD turnaround timing parameter
UINT8 T_rrdr; ///< Nvram Variable to store current tRRDR turnaround timing parameter
UINT8 T_rrdd; ///< Nvram Variable to store current tRRDD turnaround timing parameter
#ifndef DDRIO_DATA_1S
UINT32 dataControl0;
UINT32 dataControl1[MAX_STROBE]; ///< need to save for each strobe
UINT32 dataControl2[MAX_STROBE];
UINT32 dataControl4[MAX_STROBE];
UINT32 dataControl3[MAX_STROBE];
UINT32 dataOffsetComp[MAX_STROBE];
UINT8 DrvStaticLegCfg[MAX_STROBE];
UINT8 OdtSegmentEnable[MAX_STROBE];
UINT8 DataSegmentEnable[MAX_STROBE];
UINT8 RcompCode[MAX_STROBE];
UINT32 LegacyRxDfeTxEcho[MAX_STROBE]; //Used to store Legacy RxDfe or TxEcho register values
UINT32 ddrCRClkControls;
UINT32 DdrCrCmdNControls;
UINT32 DdrCrCmdSControls;
UINT32 DdrCrCkeControls;
UINT32 DdrCrCtlControls;
UINT32 clkCsr;
INT16 TxDqsDelay[MAX_RANK_CH][MAX_STROBE];
UINT32 txGroup0[MAX_RANK_CH][MAX_STROBE];
UINT32 txGroup1[MAX_RANK_CH][MAX_STROBE];
UINT32 TxEqCoefTap2[MAX_RANK_CH][MAX_STROBE];
UINT16 XtalkDeltaN0[MAX_RANK_CH][MAX_STROBE];
UINT16 XtalkDeltaN1[MAX_RANK_CH][MAX_STROBE];
UINT32 txTco[MAX_RANK_CH][MAX_STROBE];
UINT32 rxGroup0[MAX_RANK_CH][MAX_STROBE];
UINT32 rxGroup1[MAX_RANK_CH][MAX_STROBE];
UINT32 RxDfeCoeff[MAX_STROBE];
UINT32 RxDfeControl[MAX_STROBE];
UINT32 rxOffset[MAX_RANK_CH][MAX_STROBE];
UINT32 rxVrefCtrl[MAX_STROBE];
UINT8 txVrefCache[MAX_RANK_CH][MAX_STROBE]; ///< Cached value of txVref (this might not be the programmed value)
UINT8 txVref[MAX_RANK_CH][MAX_STROBE]; ///< Actual current value of txVref
UINT32 ddrCRCmdTrainingCmdN;
UINT32 ddrCRCmdTrainingCmdS;
UINT32 ddrCRCtlTraining;
UINT32 ddrCRCkeTraining;
UINT32 ddrCRClkTraining;
UINT32 ddrCRClkRanksUsed;
UINT32 dataOffsetTrain[MAX_STROBE];
UINT32 DataTrainFeedbackMultiCast;
UINT32 ddrCRCmdControls3CmdN;
UINT32 ddrCRCmdControls3CmdS;
UINT32 ddrCRCmdControls3Ctl;
UINT32 ddrCRCmdControls3Cke;
UINT32 cmdCsr[MAX_CMD_CSR];
UINT32 rxGroup1n[MAX_RANK_CH][MAX_STROBE]; /* CNX Change */
UINT32 rxGroup1p[MAX_RANK_CH][MAX_STROBE]; /* CNX Change */
UINT32 DdrCrintfDataTiming0;
UINT32 TxDqBitClockDelta[MAX_RANK_CH][MAX_STROBE]; ///< Each unit represent 64 ticks
///< [7:0] -> UIs for Bit 0
///< [15:8] -> UIs for Bit 1
///< [23:16] -> UIs for Bit 2
///< [31:24] -> UIs for Bit 3
UINT32 EnableRidUnderfillOrg; ///< Nvram Variable to store original EnableRidUnderfill RDB entry
UINT32 EnableRidVc2Org; ///< Nvram Variable to store original EnableRidVc2 RDB entry
UINT32 EnableRidVc3Org; ///< Nvram Variable to store original EnableRidVC3 RDB entry
#endif // !DDRIO_DATA_1S
} CHANNEL_NVRAM_STRUCT, *PCHANNEL_NVRAM_STRUCT;
///
/// IMC information stored in NVRAM
///
typedef struct imcNvram {
UINT8 enabled; ///< 0 = imc disabled, 1 = imc enabled
UINT32 scrubMask; ///< Scrub mask
UINT32 scrubMask2; ///< Scrub mask2
UINT8 EmcaLtCtlMcMainExt;
UINT32 ExRasConfigHaCfg;
UINT32 SmiSpareCtlMcMainExt;
UINT8 AppDirectHoleSize;
UINT8 imcNodeId; /* System wide socket id for imc */
BOOLEAN LaneReversalEn;
#ifndef DDRIO_DATA_1S
UINT32 ddrCRCompCtl0;
UINT32 ddrCRCompCtl3; // This is need for silicon workaround 'S1409370801'
UINT32 dimmVrefControl1;
#endif // !DDRIO_DATA_1S
} IMC_NVRAM_STRUCT; //struct imcNvram
///
/// Socket information stored in NVRAM
///
struct socketNvram {
UINT8 enabled;
INT32 minTCK; ///< minimum tCK for this DIMM
UINT8 ddrFreq; ///< DDR Frequency of this socket
UINT16 ddrFreqMHz; ///< DDR Frequency of this socket in MHz
UINT16 QCLKps; ///< Qclk period in pS
UINT8 cmdClkTrainingDone;
UINT8 ddrVoltage; ///< Voltage of this socket
UINT8 lrDimmPresent;
UINT8 DcpmmPresent;
BOOLEAN x16DimmPresent;
UINT8 maxDimmPop; ///< Maximum number of DIMM populated on a channel for a socket
UINT8 wa; ///< Bit field for workarounds
UINT8 ddr4SpdPageEn;
struct channelNvram channelList[MAX_CH];
struct imcNvram imc[MAX_IMC];
UINT64_STRUCT procPpin; ///< Processor PPIN number
UINT32 smiCtrlUboxMisc;
UINT8 refreshRate;
INT8 normalizationFactorEn;
UINT16 WdbCacheValidPerChannel; ///< Channel bitmask indicating whether the WDB cache is valid
TRAINING_STEP_DONE_STRUCT TrainingStepDone; ///< Indicators of whether a given training step is done
UINT8 ddrtFreq;
UINT8 cmdVrefTrainingDone;
UINT8 mcpPresent;
UINT32 FaultyPartsFlag[MAX_CH]; ///< Store faulty strobe info in a channel to NVRAM
UINT32 CsrWriteLatency[MAX_CH]; ///< CSR Write Latency from Core-Ubox-iMC[ch] roundtrip
UINT32 CsrReadLatency[MAX_CH]; ///< CSR Read Latency from Core-Ubox-iMC[ch] roundtrip
}; //struct socketNvram
typedef struct socketNvram SOCKET_NVRAM;
typedef struct memNvram {
UINT8 DataGood; ///< Set to one if valid data is present in this structure
UINT8 RASmode; ///< RAS mode (lockstep, mirror, sparing)
UINT16 RASmodeEx; ///< Extended RAS mode (patrol scrub)
UINT8 ratioIndex; ///< Index into the DDR3 ratio table
UINT8 eccEn; ///< Set if ECC will be enabled
UINT8 dimmTypePresent; ///< Type of DIMMs populated (RDIMM,UDIMM,SODIMM)
UINT8 DcpmmPresent; ///< Is an DCPMM present in the system?
UINT16 dramType; ///< DDR3 or DDR4 (from keybyte in SPD)
UINT32 scrambleSeed; ///< Data scrambling seed
UINT32 socketBitMap; ///< CPU present mask
UINT8 ExtendedADDDCEn;
struct memSetup savedSetupData;
struct socketNvram socket[MAX_SOCKET];
UINT8 XMPProfilesSup;
UINT8 XMPProfilesRevision;
struct memTiming profileMemTime[2];
UINT16 Crc16;
BOOLEAN FmcCacheDone; ///< Variable to indicate FMC Register caching is finished
UINT8 threeDsModeDisabled; ///< Variable to track if 3DS mode is enabled/disabled for CPGC
UINT8 volMemMode;
UINT8 CacheMemType; ///< Only valid if volMemMode is 2LM
#ifdef DDRIO_DATA_1S
UINT8 DdrioNvdata[DDRIO_DATA_1S * MAX_SOCKET];
#endif // DDRIO_DATA_1S
#ifdef DRAM_DATA_1S
UINT8 DramNvdata[DRAM_DATA_1S * MAX_SOCKET];
#endif // DRAM_DATA_1S
#ifdef RCD_DATA_1S
UINT8 RcdNvdata[RCD_DATA_1S * MAX_SOCKET];
#endif // RCD_DATA_1S
#ifdef LRDIMM_DB_DATA_1S
UINT8 DbNvdata[LRDIMM_DB_DATA_1S * MAX_SOCKET];
#endif // LRDIMM_DB_DATA_1S
} MEM_NVRAM_STRUCT;
//
// Max number for FMC cache register and structure
//
#define MAX_FMC_CACHE 2
struct FmcCacheSt {
UINT8 Status; // Cache status
UINT32 Reg; // Register
UINT32 Data; // Data
}; // struct FmcCacheSt
///
/// Rank info
///
struct rankDevice {
UINT16 MR0; ///< MR0 value for this rank
UINT16 MR1; ///< MR1 value for this rank
UINT16 MR2; ///< MR2 value for this rank
UINT16 MR3; ///< MR3 value for this rank
UINT16 MR4; ///< MR4 value for this rank
UINT16 MR5; ///< MR5 value for this rank
UINT16 MR6[MAX_STROBE]; ///< MR6 value for this rank/dram
#ifdef LRDIMM_SUPPORT
UINT8 CurrentLrdimmTrainingMode;
UINT8 CurrentDramMode;
UINT16 CurrentMpr0Pattern;
UINT8 lrbufRxVrefCache[MAX_STROBE];
UINT8 cachedLrBuf_FxBC2x3x[MAX_STROBE];
UINT8 cachedLrBuf_FxBC4x5x[MAX_STROBE];
UINT8 cachedLrBuf_FxBC8x9x[MAX_STROBE];
UINT8 cachedLrBuf_FxBCAxBx[MAX_STROBE];
UINT8 cachedLrBuf_FxBCCxEx[MAX_STROBE/2];
UINT8 cachedLrBuf_FxBCDxFx[MAX_STROBE/2];
#endif
UINT32 lrbufTxVrefCache[MAX_STROBE];
}; //struct rankDevice
///
/// DIMM info
/// List ordered by proximity to Host (far to near)
///
typedef struct dimmDevice {
INT32 minTCK; ///< minimum tCK for this DIMM (SPD_MIN_TCK)
#ifdef DEBUG_CODE_BLOCK
UINT32 tCL;
UINT16 tRCD;
UINT16 tRP;
#endif // DEBUG_CODE_BLOCK
UINT16 NVmemSize;
UINT16 memSize; ///< Memory size for this DIMM (64MB granularity)
UINT16 UnmappedMemSize;
struct rankDevice rankStruct[MAX_RANK_DIMM];
struct FmcCacheSt FmcCache[MAX_FMC_CACHE]; ///< FMC cache info/status
UINT8 SPDPartitionRatio[MAX_SOCKET * MAX_IMC]; ///< NVM DIMM partitionRatios
UINT8 CachedLrBuf_DFECoef[MAX_BITS_IN_BYTE][DB_DFE_TAP][MAX_STROBE/2]; // JEDEC F3BCCx-Fx coeffcient. 8 DQ x 4 taps x 9 DB
BOOLEAN FmcWdbFlushFailed; /// < 0 = WDB flush failed on previous boot, 1 = WDB flush completed w/o errors on previous boot
BOOLEAN EadrFlushFailed; /// < 0 = Extended ADR flush failed on previous boot, 1 = Extended ADR flush completed w/o errors on previous boot
} DIMM_DEVICE_INFO_STRUCT; //struct dimmDevice
///
/// DDRT DIMM info
///
typedef struct {
UINT16 NgnLogSeqNum[NGN_LOG_TYPE_NUM][NGN_LOG_LEVEL_NUM];
UINT16 NgnMaxLogEntries[NGN_LOG_TYPE_NUM][NGN_LOG_LEVEL_NUM];
UINT8 NvdimmLinkFailOnPrevBoot : 1, /* Link failure was detected in this boot */
NvdimmMediaErrLogged : 1, /* Media error log was detected in this boot */
NvdimmTempErrLogged : 1, /* Fatal temperature error log was detected in this boot */
NvdimmUnmapped : 1, /* NVDIMM is not to be mapped per memory population POR enforcement or SKU Limit violation. */
NvdimmUnmappedReason : 1, /* Reason of NVDIMM is not to be mapped 0 - population POR enforcement, 1 - SKU Limit Violation */
NvdimmRemapped : 1, /* NVDIMM is not to be unmapped per memory population POR enforcement. */
NvdimmAdModeNotEnabled : 1, /* Indicates whether DIMM SKU reports AD mode enabled or not */
Reserved : 1;
UINT64_STRUCT NgnBsr; /* NGN NVDIMM Boot Status Register */
} HOST_DDRT_DIMM_DEVICE_INFO_STRUCT;
typedef struct {
UINT8 WdbLine[MRC_WDB_LINE_SIZE];
} TWdbLine;
///
/// TT channel info
///
typedef struct ddrChannel {
UINT8 mcId; /// comparisons; more significant bits are used for match comparison only
UINT32 bankPair : 4;
UINT32 logicalSubRank : 3;
UINT32 logicalRank : 3;
UINT32 upperBgMask : 2; // bit-0 = 1 means failure with upper BG bit = 0; bit-1 = 1 means failure with upper BG = 1
UINT32 rfu: 1;
UINT32 valid : 1;
} Bits;
UINT32 Data;
} ROW_ADDR;
typedef struct {
ROW_ADDR addr;
UINT32 size;
UINT32 mask[3];
} ROW_FAIL_RANGE;
///
/// socket info
///
typedef struct Socket {
UINT8 SocketDieCount; ///< Number of cpu dies present in the socket
UINT32 NumMemSs;
MRC_MSM MemSsList[MAX_MEM_SS];
BOOLEAN ImcPresent[MAX_IMC]; ///< on multi-die, some iMCs might not exist
UINT8 imcEnabled[MAX_IMC];
UINT8 fatalError;
UINT8 majorCode;
UINT8 minorCode;
UINT8 maxRankDimm; ///< Maximum number or ranks supported per DIMM
UINT32 memSize; ///< DDR4 memory size for this socket (64MB granularity)
TRAINING_STATUS_STRUCT TrainingStatus;
struct ddrChannel channelList[MAX_CH];
UINT8 socketSubBootMode;
UINT8 hostRefreshStatus;
UINT8 firstJEDECDone; ///< Flag to indicate the first JEDEC Init has executed
UINT64_STRUCT procPpin;
UINT8 cadbMRSMode; ///< Mode of operation (LOAD / EXECUTE / NORMAL)
UINT8 cadbMRSIndex[MAX_CH];
UINT32 NVmemSize; ///< Memory size for this node
UINT32 TotalInterleavedMemSize; ///< DDR4 memory size for this socket (64MB granularity)
UINT32 TotalInterleavedNVMemSize;///< Actual NVMEM interleaved.
UINT32 volSize; ///< Volatile size of the NVM dimms for this socket (64MB granularity)
UINT32 perSize; ///< Persistent size of the NVM dimms for this socket (64MB granularity)
UINT32 WbCachePerSize; ///< Persistent WB cache (AD-WB) size of the NVM dimms for this socket (64MB granularity)
BOOLEAN TurnaroundInitDone; ///< Turnaround Initialization Done
MRC_TT CurrentTestType; ///< Training step currently being executed by this socket
SOCKET_CHIP ///< Chip hook to enable Socket fields
} SOCKET_INFO_STRUCT; // struct Socket
///
/// Sub-boot state internal to MRC (8-15 are definable). The 2 main boot types and paths through KTI RC/MRC - NormalBoot and S3Resume.
/// Within NormalBoot and S3Resume, the sub-boot type can be cold, warm, fast warm, fast cold, and ADR resume. These are populated
/// at the beginning of MRC so they are not applicable for KTI RC.
///
typedef enum SubBootMode
{
ColdBoot = 8, // Normal path through MRC with full mem detection, init, training, etc.
WarmBoot = 9, // Warm boot path through MRC. Some functionality can be skipped for speed.
WarmBootFast = 10, // Fast warm boot path uses the NVRAM structure to skip as much MRC
// code as possible to try to get through MRC fast. Should be as close
// as possible to the S3 flow.
ColdBootFast = 11, // Fast cold boot path uses the NVRAM structure to skip as much MRC
// code as possible on a cold boot.
AdrResume = 12, // ADR flow can skip most of MRC (i.e. take the S3 path) for DIMMs that
// are in self-refresh. But the DIMMs that are not in self-refresh
// must go through more of MRC.
NvDimmResume = 13 // NvDimm flow is similar to Adr Batterybackup, but the DIMMs need
// Rx & Mx registers initialized.
} SUB_BOOT_MODE;
///
/// define the Training_Result_UP/DOWN CRs struct.
///
struct TrainingResults {
UINT32 results[4];
};
#ifdef LRDIMM_SUPPORT
struct lrMrecTrainingResults {
UINT8 results;
};
#endif // LRDIMM_SUPPORT
#define MEM_CHIP_POLICY_DEF(x) Host->var.mem.memChipPolicy.x
#define MEM_CHIP_POLICY_VALUE(Host, x) Host->var.mem.memChipPolicy.x
typedef struct {
UINT8 maxVrefSettings; // MAX_VREF_SETTINGS
UINT8 earlyVrefStepSize; // EARLY_VREF_STEP_SIZE
INT16 ctlPiGrp; // CTL_PI_GRP
UINT8 minIoLatency; // MIN_IO_LATENCY
UINT16 cas2DrvenMaxGap; // CAS2DRVEN_MAXGAP
UINT8 mrcRoundTripIoComp; // MRC_ROUND_TRIP_IO_COMPENSATION;
UINT8 mrcRoundTripIoCompStart; // MRC_ROUND_TRIP_IO_COMP_START;
UINT8 mrcRoundTripMax; // MRC_ROUND_TRIP_MAX_VALUE;
UINT32 SrPbspCheckinCsr; // SR_PBSP_CHECKIN_CSR (BIOSNONSTICKYSCRATCHPAD2_UBOX_MISC_REG) // UBOX scratchpad CSR02
UINT32 SrBiosSerialDebugCsr; // SR_BIOS_SERIAL_DEBUG_CSR(BIOSSCRATCHPAD6_UBOX_MISC_REG) // UBOX scratchpad CSR6
UINT32 SrPostCodeCsr; // SR_POST_CODE_CSR (BIOSNONSTICKYSCRATCHPAD7_UBOX_MISC_REG) // UBOX scratchpad CSR7
UINT32 SrErrorCodeCsr; // SR_ERROR_CODE_CSR (BIOSNONSTICKYSCRATCHPAD8_UBOX_MISC_REG) // UBOX scratchpad CSR8
UINT32 SrMemoryDataStorageDispatchPipeCsr; // #define SR_MEMORY_DATA_STORAGE_DISPATCH_PIPE_CSR (BIOSNONSTICKYSCRATCHPAD13_UBOX_MISC_REG) // UBOX scratchpad CSR13
UINT32 SrMemoryDataStorageCommandPipeCsr; // #define SR_MEMORY_DATA_STORAGE_COMMAND_PIPE_CSR (BIOSNONSTICKYSCRATCHPAD14_UBOX_MISC_REG) // UBOX scratchpad CSR14
UINT32 SrMemoryDataStorageDataPipeCsr; // #define SR_MEMORY_DATA_STORAGE_DATA_PIPE_CSR (BIOSNONSTICKYSCRATCHPAD15_UBOX_MISC_REG) // UBOX scratchpad CSR15
UINT32 SrBdatStructPtrCsr; // SR_BDAT_STRUCT_PTR_CSR
UINT32 BiosStickyScratchPad0; // BIOSSCRATCHPAD0_UBOX_MISC_REG
UINT8 PerBitMarginDefault; // PER_BIT_MARGIN_DEFAULT
UINT8 RxOdtDefault; // RX_ODT_DEFAULT
UINT8 CmdTxEqDefault; // CMD_TX_EQ_DEFAULT
UINT8 RxDfeDefault; // RX_DFE_DEFAULT
UINT8 TxRiseFallSlewRateDefault; // TX_RF_SLEW_RATE_DEFAULT
UINT8 RmtColdFastBootDefault; // RMT_COLD_FAST_BOOT_DEFAULT
UINT8 RxVrefTrainingMode; // RX_VREF_TRAINING_MODE
UINT8 TxVrefTrainingMode; // TX_VREF_TRAINING_MODE
UINT16 MaxPhaseInReadAdjustmentDq; // MAX_PHASE_IN_READ_ADJUSTMENT_DQ
} MEM_CHIP_POLICY;
struct DimmDeviceTraining {
UINT8 oneRankTimingModeLrbuf_FxBC2x3x[MAX_STROBE];
UINT8 oneRankTimingModeLrbuf_FxBC4x5x[MAX_STROBE];
UINT8 oneRankTimingModeLrbuf_FxBC8x9x[MAX_STROBE];
UINT8 oneRankTimingModeLrbuf_FxBCAxBx[MAX_STROBE];
UINT8 oneRankTimingModeLrbuf_FxBCCxEx[MAX_STROBE/2];
UINT8 oneRankTimingModeLrbuf_FxBCDxFx[MAX_STROBE/2];
UINT8 originalRank0Lrbuf_FxBC2x3x[MAX_RANK_DIMM][MAX_STROBE];
UINT8 originalRank0Lrbuf_FxBC4x5x[MAX_RANK_DIMM][MAX_STROBE];
UINT8 originalRank0Lrbuf_FxBC8x9x[MAX_RANK_DIMM][MAX_STROBE];
UINT8 originalRank0Lrbuf_FxBCAxBx[MAX_RANK_DIMM][MAX_STROBE];
UINT8 originalRank0Lrbuf_FxBCCxEx[MAX_RANK_DIMM][MAX_STROBE/2];
UINT8 originalRank0Lrbuf_FxBCDxFx[MAX_RANK_DIMM][MAX_STROBE/2];
}; //struct DimmDeviceTraining
/// TT channel info
///
struct DdrChannelTraining {
TWdbLine WdbLines[MRC_WDB_LINES];
struct DimmDeviceTraining dimmList[MAX_DIMM];
}; //struct DdrChannelTraining
struct TrainingVariable {
UINT8 rdVrefLo;
UINT8 rdVrefHi;
UINT8 wrVrefLo;
UINT8 wrVrefHi;
UINT8 cmdVrefLo;
UINT8 cmdVrefHi;
UINT8 DQPat; ///< Global Variables storing the current DQPat REUT Test
UINT8 DQPatLC; ///< Global Variables storing the current DQPat Loopcount
BOOLEAN EnDumRd; ///< Enable/Disable Logic Analizer
INT16 TxDqLeft[MAX_CH][MAX_RANK_CH][MAX_STROBE];
INT16 TxDqRight[MAX_CH][MAX_RANK_CH][MAX_STROBE];
INT16 TxVrefLow[MAX_CH][MAX_RANK_CH][MAX_STROBE];
INT16 TxVrefHigh[MAX_CH][MAX_RANK_CH][MAX_STROBE];
INT16 RxDqsLeft[MAX_CH][MAX_RANK_CH][MAX_STROBE];
INT16 RxDqsRight[MAX_CH][MAX_RANK_CH][MAX_STROBE];
INT16 RxVrefLow[MAX_CH][MAX_RANK_CH][MAX_STROBE];
INT16 RxVrefHigh[MAX_CH][MAX_RANK_CH][MAX_STROBE];
struct DdrChannelTraining channelList[MAX_CH];
}; //struct TrainingVariable
///
/// Indicates how SPD data should be retrieved:
/// SpdSmbus Data should be retrieved via SMBUS
/// SpdInternal Data should be retrieved via internal SPD array
/// SpdInternalTrace Data should be retrieved via internal SPD array, but the SMBUS transactions should still be
/// carried out to generate register traces for debugging
///
typedef enum {
SpdSmbus,
SpdInternal,
SpdInternalTrace,
SpdMax
} SPD_SOURCE;
//
// CMI Read and Write credit configuration register defaults
//
typedef struct {
UINT32 CmiRdCreditConfigN0;
UINT32 CmiRdCreditConfigN1;
UINT32 CmiWrCreditConfigN0;
UINT32 CmiWrCreditConfigN1;
BOOLEAN Valid; /// Set to TRUE when structure is updated
} CMI_CREDIT_CONFIG_DEFAULT;
///
/// TT Host info
///
typedef struct memVar {
UINT8 currentSocket; ///< Current socket being initialized
UINT8 PostCodeMinor;
SUB_BOOT_MODE subBootMode; ///< WarmBoot, WarmBootFast, etc.
UINT8 wipeMemory; ///< Write 0 to all memory to clean secrets
UINT8 skipMemoryInit; ///< Skip memory init based on certain conditions.
UINT8 ddrFreqLimit; ///< Set to limit frequency by the user
UINT8 chInter; ///< Number of ways to interleave channels (1,2,3, or 4)
UINT8 callingTrngOffstCfgOnce; ///