hc
2024-03-25 edb30157bad0c0001c32b854271ace01d3b9a16a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
/** @file
  MemHost.h
 
  @copyright
  Copyright 2006 - 2021 Intel Corporation. <BR>
 
  SPDX-License-Identifier: BSD-2-Clause-Patent
**/
 
#ifndef _memhost_h
#define _memhost_h
 
#include <Ppi/MemoryPolicyPpi.h>
#include "DataTypes.h"
#include "PlatformHost.h"
#include "MemRegs.h"
#include "MemDefaults.h"
#include "NGNDimmPlatformCfgData.h"
#include "MrcCommonTypes.h"
#include "MemHostChipCommon.h"
#include <MemCommon.h>
#include <PiPei.h>
#include <Memory/Ddr4SpdRegisters.h>
 
#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;              ///<Memory controller number
  UINT8                             numDimmSlots;      ///<Number of DIMM slots per channel
  UINT32                            memSize;           ///<Memory size for this channel (64MB granularity)
  UINT32                            ddr4RemSize;       ///<Remaining DDR4 Memory size for this channel
  UINT32                            volSize;           ///<Volatile size of the NVM dimms in this channel
  UINT32                            NonVolSize;        ///<Non Volatile size of the NVM dimms in this channel
  UINT32                            volRemSize;        ///<Remaining Volatile size of the NVM dimms in this channel
  UINT32                            perSize;           ///<Pmem size of the NVM dimms in this channel
  UINT32                            perRemSize;        ///<Remaining Pmem size of the NVM dimms in this channel
  UINT32                            WbCachePerSize;    ///<Persistent WB cache (AD-WB) size of the NVM dimms in this channel
  UINT32                            WbCachePerRemSize; ///<Remaining Persistent WB cache (AD-WB) size of the NVM dimms in this channel
  UINT32                            ctrlSize;          ///<Ctrl region size of the NVM dimms in this channel
  UINT32                            ctrlRemSize;       ///<Remaining Ctrl region size of the NVM dimms in this channel
  UINT32                            NVmemSize;         ///< NVDIMM channel memory size
  UINT32                            NVmemRemSize;
  UINT32                            remSize;           ///< Size not yet mapped in units of 64 MB
  UINT32                            DdrCacheSize;      ///< Size of DDR memory reserved for 2LM cache (64MB granularity)
  DIMM_DEVICE_INFO_STRUCT           dimmList[MAX_DIMM];
  HOST_DDRT_DIMM_DEVICE_INFO_STRUCT DdrtDimmList[MAX_DDRT_DIMM_PER_CH];
  UINT8                             CsrUnlock;              ///< Whether FMC CSRs are unlocked (accessible/writable)
  UINT16                            FisVersion[MAX_DIMM];   ///< Firmwre Interface Specification version
} DDR_CHANNEL_STRUCT; //struct ddrChannel
 
typedef union {
  struct {
    UINT8 TrainingPatternMode : 3; // Bits[2:0] - Training Pattern Mode
    UINT8 QcaUcaTrainingDone : 1; // Bits[3] - QCA training or UDIMM CA training are done or not
    UINT8 BitIndex : 2; // Bits[5:4] - Used to indicate which bit to test.
    UINT8 CoarseRdDqDqsTrainingDone : 1; // Bits[6] - Coarse Read Dq/Dqs training are done or not
    UINT8 Reserved : 1; // Bits[7] - Reserved for future use.
  } Bits;
  UINT8 Data;
} TRAINING_STATUS_STRUCT;
 
#define MAX_FAIL_RANGE 128
 
typedef union {
  struct {
    UINT32 row : 18;        // This field is used for < > 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; ///<to prevent looping inside RMT
  UINT8                   earlyCmdClkExecuted;
  UINT8                   checkMappedOutRanks;
#ifdef DEBUG_CODE_BLOCK
  UINT8                   earlyCtlClkSerialDebugFlag;
#endif // DEBUG_CODE_BLOCK
  UINT32                  memSize;          ///< Total physical memory size
  UINT32                  NVmemSize;          ///< Total physical memory size
  UINT32                  TotalInterleavedMemSize;      ///< DDR4 memory size for this socket (64MB granularity)
  UINT32                  TotalInterleavedNVMemSize; /// < Actual NVMEM interleaved.
  UINT32                  QCLKPeriod;       ///< QCLK Period in pico seconds
  UINT32                  lowMemBase;       ///< Mem base in 64MB units for below 4GB mem.
  UINT32                  lowMemSize;       ///< Mem size in 64MB units for below 4GB mem.
  UINT32                  highMemBase;      ///< Mem base in 64MB units for above 4GB mem.
  UINT32                  highMemSize;      ///< Mem size in 64MB units for above 4GB mem.
  UINT32                  initialLFSRSeed;
  UINT32                  piSettingStopFlag[MAX_CH];
  UINT8                   pxcEnabled;
  struct Socket           socket[MAX_SOCKET];                        ///< Per socket structure
  struct TrainingVariable TrainingVar;       ///< Local variable for DDR training
  UINT32                  NumValidPprEntries;
  PPR_ADDR_MRC_SETUP      pprAddrSetup[MAX_PPR_ADDR_ENTRIES_SPPR];
  UINT8                   pprStatus[MAX_PPR_ADDR_ENTRIES_SPPR];
  UINT8                   softPprDone[MAX_SOCKET];
  ///
  /// Flag to skip RowTestPPR execution, so it wont return false error
  ///
  BOOLEAN                 SkipPprRowTest[MAX_SOCKET];
  //
  // Avanced Memtest Failure Range tracking
  //
  UINT8                   FailRangeInitDone[MAX_SOCKET];
  ROW_FAIL_RANGE          FailRange[MAX_CH][MAX_FAIL_RANGE];
  UINT32                  FailMax[MAX_CH];  // This is initialized to 0 prior to any memtest, indicating no failures
  INT32                   FailIndex[MAX_CH];
  UINT8                   RetryState;
  ROW_FAIL_RANGE          LastFail[MAX_CH];
  UINT8                   PprResourceAvailable[MAX_CH][MAX_DIMM * MAX_RANK_DIMM_3DS * MAX_SUBRANK_3DS][MAX_STROBE];  // Max logical ranks = 16 (2DPC, 3DS 2R-4H), each BG is bit-mapped into UINT8
  UINT64_STRUCT           AdvMemtestErrInjMask;
  UINT8                   InjectErrorMATS[MAX_CH];
  UINT8                   AmtErrInjDone;
  BOOLEAN                 IsDdrMemInitDone;    ///< Flag indicates if DDR memory init is done.
 
#ifdef LRDIMM_SUPPORT
  struct TrainingResults  lrTrainRes[MAX_CH][MAX_STROBE];
  struct lrMrecTrainingResults lrMrecTrainRes[MAX_CH][MAX_STROBE];
  struct TrainingResults  lrMrdTrainRes[MAX_CH][MAX_STROBE];
  struct TrainingResults  lrDwlTrainRes[MAX_CH][MAX_STROBE];
  struct lrMrecTrainingResults lrCwlTrainRes[MAX_CH][MAX_STROBE];
  struct TrainingResults  lrMwdTrainRes[MAX_CH][MAX_STROBE];
  UINT8                   InPbaWaMode;
  UINT8                   InOvrRttPrkMode;
#endif // LRDIMM_SUPPORT
 
  UINT8                   maxSubRank;
  UINT8                   currentSubRank;
  struct TrainingResults  trainRes[MAX_CH][MAX_STROBE];
  BOOLEAN                 PerformanceTrackerInitialized;
  UINT8                   firstPass;
  UINT8                   previousBootError;
  UINT8                   xoverModeVar;     ///< xover mode (1 = xover2:2, 0 = native 1:1)
  UINT32                  Reserved6;
  UINT8                   Reserved7[RESERVED_2];
  EFI_GUID                Reserved8[RESERVED_2];
  UINT8                   Reserved9;
 
  SPD_SOURCE              SpdSource;        ///< Determines SPD data source
  UINT8                   SmbMode[MAX_SOCKET][MAX_SMB_INSTANCE]; ///< Stores type of smbus mode: 0 - I2C mode, 1 - I3C mode
  UINT8                   rankInter;        ///< 1, 2, 4, or 8 way interleave
  UINT8                   RasStatePrevBoot;
  UINT32                  mccpubusno;
  UINT32                  rtDefaultValue;
  UINT8                   channelEn;
  UINT8                   runningRmt;   ///< Flag to check that the RankMarginTool is currently being running
  UINT32                  lastCheckpoint[MAX_SOCKET];
  UINT8                   notRunningFromCT; ///< PostPackageRepairMain called from the CallTable (CT)
  UINT32                  chBitMask;
  UINT8                   FmcMaxCached;     ///< Record how many FMC register been cached
  UINT32                  FmcCachedReads;   ///< Record the amount of total FMC cache read times
  MEM_CHIP_POLICY         memChipPolicy;
  BOOLEAN                 secondPass[MAX_CH][MAX_STROBE];
  UINT8                   volMemMode;       ///< 0: 1LM  1:2LM 2:Undefined
  UINT8                   CacheMemType;     ///< 0: DDR$DDRT  Only valid if volMemMode is 2LM
 
  UINT8                   PmemCaching;        // caching contorl for AppDirect
  UINT8                   EadrSupport;        // eADR support
  UINT8                   EadrCacheFlushMode;
 
  UINT8                   imcInter;           // Number of ways to interleave imc (1 or 2)
  UINT32                  mmiohBase;          // MMIOH base in 64MB granularity
  UINT8                   read2tckCL[MAX_CH];     // increases to CL or CWL based on TCLK preamble
  UINT8                   write2tckCWL[MAX_CH];
  UINT8                   memInterleaveGran1LM;
  struct Reserved168      Reserved168;
  UINT32                  optionsNgn;
  UINT8                   setSecureEraseAllDIMMs;
  UINT8                   setSecureEraseSktCh[MAX_SOCKET][MAX_CH];
  UINT8                   SetSecureEraseSktChHob[MAX_SOCKET][MAX_CH];
  BOOLEAN                 AdrStateForPmemModule[MAX_SOCKET][MAX_CH];   // ADR state for Intel PMEM Modules
  UINT8                   AppDirectMemoryHole;
  UINT8                   LsxImplementation;
  UINT32                  NvdimmSmbusMaxAccessTime;
  UINT32                  NvdimmSmbusReleaseDelay;
  MEMORY_MAP_BLOCK_DECODER_DATA BlockDecoderData;   // Block decoder data for memory map
  UINT8                   ExtendedType17;
 
  BOOLEAN                 DdrtReadPendingQueueTimedOut[MAX_SOCKET][MAX_CH];  ///< Each element represents whether a given channel has had a DDRT Read Pending Queue (RPQ) timeout
  BOOLEAN                 DdrtReadPendingQueueCreditLimitSet[MAX_SOCKET][MAX_CH];  ///< Each element represents whether a given channel has the DDRT Read Pending (RPQ) credit limit enabled
  BOOLEAN                 DdrtSkipRpqDrainInCpgcPolling[MAX_SOCKET];  ///< Indicates whether to drain the DDRT RPQ when polling for CPGC done
  BOOLEAN                 WrLvlDeNormalizeStatus[MAX_SOCKET][MAX_CH][MAX_DIMM];
  BOOLEAN                 EkvPresent;   ///< Set if EKV controller on system
  BOOLEAN                 BwvPresent;   ///< Set if BWV controller on system
  BOOLEAN                 FastWarmBootDowngraded; ///On slow boot when FWR is downgrated to SWR NVDIMMS need to do a catastrophic save to prevent data loss
  BOOLEAN                 DcpmmWaitMediaReady; ///< Set on Slow Warm boots to indicate that BIOS needs to poll for Media Ready on DCPMM DIMMs after CKE is asserted
  BOOLEAN                 WarmBootRequested; ///< Set on Warm boots when is not possible to detect warm boot it via subBootMode (when BIOS internally promoted warm reset to cold reset/fast cold reset)
  CMI_CREDIT_CONFIG_DEFAULT   CmiCreditConfigDefault;
  UINT16                  BiosFisRevision;
  UINT16                  MaxAveragePowerLimit;  ///< Max Power limit in mW used for averaged power ( Valid range ends at 15000mW)
  UINT16                  MinAveragePowerLimit;  ///< Min Power limit in mW used for averaged power ( Valid range starts from 10000mW)
  UINT16                  CurrAveragePowerLimit; ///< Current Power limit in mW used for average power
  UINT16                  MaxMbbPowerLimit;    ///< Max MBB power limit ( Valid range ends at 18000mW).
  UINT16                  MinMbbPowerLimit;    ///< Min MBB power limit ( Valid range starts from 15000mW).
  UINT16                  CurrMbbPowerLimit; ///< Current Power limit in mW used for MBB power
  UINT32                  MaxMbbAveragePowerTimeConstant;  ///< Max MBB Average Power Time Constant
  UINT32                  MinMbbAveragePowerTimeConstant;  ///< Min MBB Average Power Time Constant
  UINT32                  CurrMbbAveragePowerTimeConstant; ///< Current MBB Average POwer Time Constant
  BOOLEAN                 RmtMinimumMarginCheckEnable;
} MEM_VAR_STRUCT;  // struct memVar
 
#pragma pack(pop)
 
#endif // _memhost_h