AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / Recovery / Mem / NB / DR / mrndr.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * mrndr.c
6  *
7  * Common Northbridge  functions for Ridgeback Recovery
8  *
9  * @xrefitem bom "File Content Label" "Release Content"
10  * @e project: AGESA
11  * @e sub-project: (Proc/Recovery/Mem)
12  * @e \$Revision: 48317 $ @e \$Date: 2011-03-07 10:38:14 -0700 (Mon, 07 Mar 2011) $
13  *
14  **/
15 /*****************************************************************************
16 *
17 * Copyright (C) 2012 Advanced Micro Devices, Inc.
18 * All rights reserved.
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions are met:
22 *     * Redistributions of source code must retain the above copyright
23 *       notice, this list of conditions and the following disclaimer.
24 *     * Redistributions in binary form must reproduce the above copyright
25 *       notice, this list of conditions and the following disclaimer in the
26 *       documentation and/or other materials provided with the distribution.
27 *     * Neither the name of Advanced Micro Devices, Inc. nor the names of
28 *       its contributors may be used to endorse or promote products derived
29 *       from this software without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
32 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
35 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
38 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
40 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 *
42 * ***************************************************************************
43 *
44 */
45
46 /*
47  *----------------------------------------------------------------------------
48  *                                MODULES USED
49  *
50  *----------------------------------------------------------------------------
51  */
52
53
54
55 #include "AGESA.h"
56 #include "amdlib.h"
57 #include "Ids.h"
58 #include "cpuFamRegisters.h"
59 #include "cpuRegisters.h"
60 #include "cpuFamilyTranslation.h"
61 #include "mrport.h"
62 #include "mm.h"
63 #include "mn.h"
64 #include "mrndr.h"
65 #include "heapManager.h"
66 #include "AdvancedApi.h"
67 #include "Filecode.h"
68 CODE_GROUP (G2_PEI)
69 RDATA_GROUP (G2_PEI)
70
71 #define FILECODE PROC_RECOVERY_MEM_NB_DR_MRNDR_FILECODE
72 /*----------------------------------------------------------------------------
73  *                          DEFINITIONS AND MACROS
74  *
75  *----------------------------------------------------------------------------
76  */
77
78 #define SPLIT_CHANNEL   0x20000000
79 #define CHANNEL_SELECT  0x10000000
80 #define MAX_DELAYS    9   /* 8 data bytes + 1 ECC byte */
81 #define MAX_DIMMS     4   /* 4 DIMMs per channel */
82
83 /*----------------------------------------------------------------------------
84  *                           TYPEDEFS AND STRUCTURES
85  *
86  *----------------------------------------------------------------------------
87  */
88
89 /*----------------------------------------------------------------------------
90  *                        PROTOTYPES OF LOCAL FUNCTIONS
91  *
92  *----------------------------------------------------------------------------
93  */
94
95 VOID
96 STATIC
97 MemRecNInitNBRegTableDR (
98   IN OUT   TSEFO *NBRegTable
99   );
100
101 UINT32
102 STATIC
103 MemRecNCmnGetSetFieldDR (
104   IN OUT   MEM_NB_BLOCK *NBPtr,
105   IN       UINT8 IsSet,
106   IN       BIT_FIELD_NAME FieldName,
107   IN       UINT32 Field
108   );
109
110 UINT32
111 STATIC
112 MemRecNcmnGetSetTrainDlyDR (
113   IN OUT   MEM_NB_BLOCK *NBPtr,
114   IN       UINT8 IsSet,
115   IN       TRN_DLY_TYPE TrnDly,
116   IN       DRBN DrbnVar,
117   IN       UINT16 Field
118   );
119
120 BOOLEAN
121 STATIC
122 MemRecNIsIdSupportedDr (
123   IN OUT   MEM_NB_BLOCK *NBPtr,
124   IN       CPU_LOGICAL_ID *LogicalIdPtr
125   );
126
127 /*----------------------------------------------------------------------------
128  *                            EXPORTED FUNCTIONS
129  *
130  *----------------------------------------------------------------------------
131  */
132 STATIC CONST UINT32 RecModeDefRegArrayDR[] = {
133   BFDramControlReg,  0x320C2A06,
134   BFDramBankAddrReg, 0x00001111,
135   BFDramMRSReg,      0x000400A4,
136   BFDramTimingLoReg, 0x000A0092,
137   BFDramTimingHiReg, 0xB6D218FF,
138   BFDramConfigLoReg, 0x00000000,
139   BFDramConfigHiReg, 0x1F48010B,
140   NULL
141 };
142
143 /* -----------------------------------------------------------------------------*/
144 /**
145  *
146  *   This function initializes the northbridge block
147  *
148  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
149  *     @param[in,out]   *MemPtr  - Pointer to the MEM_DATA_STRUCT
150  *     @param[in]       NodeID   - Node ID for this NB block
151  *
152  *     @return          TRUE  - This node is a RB and this NB block has been initialized
153  *     @return          FALSE - This node is not a RB
154  */
155
156 BOOLEAN
157 MemRecConstructNBBlockDR (
158   IN OUT   MEM_NB_BLOCK *NBPtr,
159   IN OUT   MEM_DATA_STRUCT *MemPtr,
160   IN       UINT8 NodeID
161   )
162 {
163   UINT8 i;
164   UINT8 Dct;
165   UINT8 Channel;
166   DIE_STRUCT *MCTPtr;
167   ALLOCATE_HEAP_PARAMS AllocHeapParams;
168
169   //
170   // Determine if this is the expected NB Type
171   //
172   GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
173   if (!MemRecNIsIdSupportedDr (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) {
174     return FALSE;
175   }
176
177   //
178   // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs
179   //
180   MCTPtr = &MemPtr->DiesPerSystem[NodeID];
181   AllocHeapParams.RequestedBufferSize = MAX_DCTS_PER_NODE_DR * (
182                                           sizeof (DCT_STRUCT) + (
183                                             MAX_CHANNELS_PER_DCT_DR * (
184                                               sizeof (CH_DEF_STRUCT) + (
185                                                 MAX_DIMMS * MAX_DELAYS * NUMBER_OF_DELAY_TABLES
186                                               )
187                                             )
188                                           )
189                                         ) + (sizeof (TSEFO) * BFEndOfList);
190   AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0);
191   AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
192   if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) {
193     return FALSE;
194   }
195
196   MemPtr->DieCount = 1;
197   MCTPtr->DctCount = MAX_DCTS_PER_NODE_DR;
198   MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr;
199   AllocHeapParams.BufferPtr += MAX_DCTS_PER_NODE_DR * sizeof (DCT_STRUCT);
200   for (Dct = 0; Dct < MAX_DCTS_PER_NODE_DR; Dct++) {
201     MCTPtr->DctData[Dct].Dct = Dct;
202     MCTPtr->DctData[Dct].ChannelCount = MAX_CHANNELS_PER_DCT_DR;
203     MCTPtr->DctData[Dct].ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr;
204     MCTPtr->DctData[Dct].ChData[0].ChannelID = Dct;
205     AllocHeapParams.BufferPtr += MAX_CHANNELS_PER_DCT_DR * sizeof (CH_DEF_STRUCT);
206     for (Channel = 0; Channel < MAX_CHANNELS_PER_DCT_DR; Channel++) {
207       MCTPtr->DctData[Dct].ChData[Channel].RcvEnDlys = (UINT16 *) AllocHeapParams.BufferPtr;
208       AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS) * 2;
209       MCTPtr->DctData[Dct].ChData[Channel].WrDqsDlys = AllocHeapParams.BufferPtr;
210       MCTPtr->DctData[Dct].ChData[Channel].Dct = Dct;
211       AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS);
212     }
213   }
214
215   //
216   //  Initialize NB block's variables
217   //
218   NBPtr->NBRegTable = (TSEFO *) AllocHeapParams.BufferPtr;
219   NBPtr->MemPtr = MemPtr;
220   NBPtr->RefPtr = MemPtr->ParameterListPtr;
221   NBPtr->MCTPtr = MCTPtr;
222   NBPtr->SPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL];
223   NBPtr->AllNodeSPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL];
224
225   NBPtr->DctCachePtr = NBPtr->DctCache;
226
227   MemRecNInitNBRegTableDR (NBPtr->NBRegTable);
228   NBPtr->Dct = 0;
229   NBPtr->Channel = 0;
230   NBPtr->VarMtrrHiMsk = MemRecGetVarMtrrHiMsk (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
231
232   LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &NBPtr->MemPtr->StdHeader);
233   LibAmdMemFill (NBPtr->IsSupported, FALSE, sizeof (NBPtr->IsSupported), &NBPtr->MemPtr->StdHeader);
234   for (i = 0; i < NumberOfHooks; i++) {
235     NBPtr->FamilySpecificHook[i] = (BOOLEAN (*) (MEM_NB_BLOCK *, VOID *)) MemRecDefTrue;
236   }
237
238   NBPtr->InitRecovery = MemRecNMemInitNb;
239
240   NBPtr->RecModeDefRegArray = RecModeDefRegArrayDR;
241
242   NBPtr->SwitchNodeRec = (VOID (*) (MEM_NB_BLOCK *, UINT8)) MemRecDefRet;
243   NBPtr->SwitchDCT = MemRecNSwitchDctDR;
244   NBPtr->SwitchChannel = MemRecNSwitchChannelDR;
245   NBPtr->SetMaxLatency = MemRecNSetMaxLatencyNb;
246   NBPtr->GetSysAddrRec = MemRecNGetMCTSysAddrNb;
247   NBPtr->SendMrsCmd = MemRecNSendMrsCmdNb;
248   NBPtr->sendZQCmd = MemRecNSendZQCmdNb;
249   NBPtr->SetDramOdtRec = MemRecNSetDramOdtNb;
250
251   NBPtr->GetBitField = MemRecNGetBitFieldNb;
252   NBPtr->SetBitField = MemRecNSetBitFieldNb;
253   NBPtr->GetTrainDly = MemRecNGetTrainDlyNb;
254   NBPtr->SetTrainDly = MemRecNSetTrainDlyNb;
255   NBPtr->MemRecNCmnGetSetFieldNb = MemRecNCmnGetSetFieldDR;
256   NBPtr->MemRecNcmnGetSetTrainDlyNb = MemRecNcmnGetSetTrainDlyDR;
257   NBPtr->MemRecNSwitchDctNb = MemRecNSwitchDctDR;
258   NBPtr->TrainingFlow = MemNRecTrainingFlowNb;
259   NBPtr->MemRecNInitializeMctNb = MemRecNInitializeMctDR;
260   NBPtr->MemRecNFinalizeMctNb = MemRecNFinalizeMctDR;
261   NBPtr->IsSupported[DramModeBeforeDimmPres] = TRUE;
262   NBPtr->IsSupported[CheckClearOnDimmMirror] = TRUE;
263   MemRecNSwitchDctDR (NBPtr, 0);
264
265   return TRUE;
266 }
267
268 /* -----------------------------------------------------------------------------*/
269 /**
270  *
271  *   This function sets the current DCT to work on.
272  *   Should be called before accessing a certain DCT
273  *   All data structures will be updated to point to the current DCT
274  *
275  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
276  *     @param[in]   Dct - ID of the target DCT
277  *
278  */
279
280 VOID
281 MemRecNSwitchDctDR (
282   IN OUT   MEM_NB_BLOCK *NBPtr,
283   IN       UINT8 Dct
284   )
285 {
286   NBPtr->Dct = Dct & 1;
287   NBPtr->SPDPtr = &(NBPtr->AllNodeSPDPtr[Dct * MAX_DIMMS_PER_CHANNEL]);
288   NBPtr->DCTPtr = &(NBPtr->MCTPtr->DctData[NBPtr->Dct]);
289
290   MemRecNSwitchChannelDR (NBPtr, NBPtr->Channel);
291 }
292
293 /* -----------------------------------------------------------------------------*/
294 /**
295  *
296  *   This function sets the current channel to work on.
297  *   Should be called before accessing a certain channel
298  *   All data structures will be updated to point to the current channel
299  *
300  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
301  *     @param[in]   Channel - ID of the target channel
302  *
303  */
304
305 VOID
306 MemRecNSwitchChannelDR (
307   IN OUT   MEM_NB_BLOCK *NBPtr,
308   IN       UINT8 Channel
309   )
310 {
311   NBPtr->Channel = Channel & 1;
312   NBPtr->ChannelPtr = &(NBPtr->DCTPtr->ChData[NBPtr->Channel]);
313 }
314 /*----------------------------------------------------------------------------
315  *                              LOCAL FUNCTIONS
316  *
317  *----------------------------------------------------------------------------
318  */
319
320 /* -----------------------------------------------------------------------------*/
321 /**
322  *
323  *   This function gets or set DQS timing during training.
324  *
325  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
326  *     @param[in]   TrnDly - type of delay to be set
327  *     @param[in]   DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed
328  *                  (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding
329  *     @param[in]   Field - Value to be programmed
330  *     @param[in]   IsSet - Indicates if the function will set or get
331  *
332  *     @return      value read, if the function is used as a "get"
333  */
334
335 UINT32
336 STATIC
337 MemRecNcmnGetSetTrainDlyDR (
338   IN OUT   MEM_NB_BLOCK *NBPtr,
339   IN       UINT8 IsSet,
340   IN       TRN_DLY_TYPE TrnDly,
341   IN       DRBN DrbnVar,
342   IN       UINT16 Field
343   )
344 {
345   UINT16 Index;
346   UINT16 Offset;
347   UINT32 Value;
348   UINT32 Address;
349   UINT8 Dimm;
350   UINT8 Byte;
351
352   Dimm = DRBN_DIMM (DrbnVar);
353   Byte = DRBN_BYTE (DrbnVar);
354
355   ASSERT (Dimm < 4);
356   ASSERT (Byte <= 8);
357
358   switch (TrnDly) {
359   case AccessRcvEnDly:
360     Index = 0x10;
361     break;
362   case AccessWrDqsDly:
363     Index = 0x30;
364     break;
365   case AccessWrDatDly:
366     Index = 0x01;
367     break;
368   case AccessRdDqsDly:
369     Index = 0x05;
370     break;
371   case AccessPhRecDly:
372     Index = 0x50;
373     break;
374   default:
375     Index = 0;
376     IDS_ERROR_TRAP;
377   }
378
379   switch (TrnDly) {
380   case AccessRcvEnDly:
381   case AccessWrDqsDly:
382     Index += (Dimm * 3);
383     if (Byte & 0x04) {
384       // if byte 4,5,6,7
385       Index += 0x10;
386     }
387     if (Byte & 0x02) {
388       // if byte 2,3,6,7
389       Index++;
390     }
391     Offset = 16 * (Byte % 2);
392     break;
393
394   case AccessRdDqsDly:
395     Field &= ~ 0x0001;
396   case AccessWrDatDly:
397     Index += (Dimm * 0x100);
398     // break is not being used here because AccessRdDqsDly and AccessWrDatDly also need
399     // to run AccessPhRecDly sequence.
400   case AccessPhRecDly:
401     Index += (Byte / 4);
402     Offset = 8 * (Byte % 4);
403     break;
404   default:
405     Offset = 0;
406     IDS_ERROR_TRAP;
407   }
408
409   Address = Index;
410   MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
411   while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
412   Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
413
414   if (IsSet) {
415     if (TrnDly == AccessPhRecDly) {
416       Value = NBPtr->DctCachePtr->PhRecReg[Index & 0x03];
417     }
418
419     Value = ((UINT32)Field << Offset) | (Value & (~((UINT32)0xFF << Offset)));
420     MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value);
421     Address |= DCT_ACCESS_WRITE;
422     MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
423     while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
424
425     if (TrnDly == AccessPhRecDly) {
426       NBPtr->DctCachePtr->PhRecReg[Index & 0x03] = Value;
427     }
428   } else {
429     Value = (Value >> Offset) & 0xFF;
430   }
431
432   return Value;
433 }
434
435 /* -----------------------------------------------------------------------------*/
436 /**
437  *
438  *   This function gets or sets a value to a bit field in a PCI register.
439  *
440  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
441  *     @param[in]   IsSet - Indicates if the function will set or get
442  *     @param[in]   FieldName - Name of field to be set
443  *     @param[in]   Field - Value to be programmed
444  *
445  *     @return      value read, if the function is used as a "get"
446  */
447
448 UINT32
449 STATIC
450 MemRecNCmnGetSetFieldDR (
451   IN OUT   MEM_NB_BLOCK *NBPtr,
452   IN       UINT8 IsSet,
453   IN       BIT_FIELD_NAME FieldName,
454   IN       UINT32 Field
455   )
456 {
457   SBDFO Address;
458   PCI_ADDR PciAddr;
459   UINT8 Type;
460   UINT32 Value;
461   UINT32 Highbit;
462   UINT32 Lowbit;
463   UINT32 Mask;
464
465   Value = 0;
466   if (FieldName < BFEndOfList) {
467     Address = NBPtr->NBRegTable[FieldName];
468     if (Address) {
469       Lowbit = TSEFO_END (Address);
470       Highbit = TSEFO_START (Address);
471       Type = TSEFO_TYPE (Address);
472
473       // If Fn2 and DCT1 selected, set Address to be 1xx
474       if (((Address & 0xF000) == 0x2000) && NBPtr->Dct) {
475         Address |= 0x0100;
476       }
477       if ((Address >> 29) == ((DCT_PHY_ACCESS << 1) | 1)) {
478         // Special DCT Phy access
479         Address &= 0x0FFFFFFF;
480         Lowbit = 0;
481         Highbit = 16;
482       } else {
483         // Normal DCT Phy access
484         Address = TSEFO_OFFSET (Address);
485       }
486
487
488       if (Type == NB_ACCESS) {
489         Address |= (((UINT32) (24 + 0)) << 15);
490         PciAddr.AddressValue = Address;
491         LibAmdPciRead (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader);
492       } else if (Type == DCT_PHY_ACCESS) {
493         MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
494         while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
495
496         Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
497       } else {
498         IDS_ERROR_TRAP;
499       }
500
501       if (IsSet) {
502         // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
503         if ((Highbit - Lowbit) != 31) {
504           Mask = (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
505         } else {
506           Mask = (UINT32)0xFFFFFFFF;
507         }
508         Value &= ~(Mask << Lowbit);
509         Value |= (Field & Mask) << Lowbit;
510
511         if (Type == NB_ACCESS) {
512           PciAddr.AddressValue = Address;
513           LibAmdPciWrite (AccessWidth32, PciAddr , &Value, &NBPtr->MemPtr->StdHeader);
514         } else if (Type == DCT_PHY_ACCESS) {
515           MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value);
516           Address |= DCT_ACCESS_WRITE;
517
518           MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
519           while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
520         } else {
521           IDS_ERROR_TRAP;
522         }
523       } else {
524         Value = Value >> Lowbit;  // Shift
525         // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
526         if ((Highbit - Lowbit) != 31) {
527           Value &= (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
528         }
529       }
530     }
531   } else {
532     IDS_ERROR_TRAP;   // Invalid bit field index
533   }
534   return Value;
535 }
536
537
538 /* -----------------------------------------------------------------------------*/
539 /**
540  *
541  *   This function initializes bit field translation table
542  *
543  *     @param[in,out]   *NBRegTable   - Pointer to the NB Table *
544  */
545
546 VOID
547 STATIC
548 MemRecNInitNBRegTableDR (
549   IN OUT   TSEFO *NBRegTable
550   )
551 {
552   UINT16 i;
553   for (i = 0; i <= BFEndOfList; i++) {
554     NBRegTable[i] = 0;
555   }
556
557   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x00), 31,  0, BFDevVendorIDReg);
558   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x60),  2,  0, BFNodeID);
559
560   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x40), 31, 0, BFDramBaseReg0);
561   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x44), 31, 0, BFDramLimitReg0);
562
563   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x40), 31,  0, BFCSBaseAddr0Reg);
564   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x44), 31,  0, BFCSBaseAddr1Reg);
565   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x48), 31,  0, BFCSBaseAddr2Reg);
566   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x4C), 31,  0, BFCSBaseAddr3Reg);
567   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x50), 31,  0, BFCSBaseAddr4Reg);
568   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x54), 31,  0, BFCSBaseAddr5Reg);
569   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x58), 31,  0, BFCSBaseAddr6Reg);
570   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x5C), 31,  0, BFCSBaseAddr7Reg);
571
572   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x60), 31,  0, BFCSMask0Reg);
573   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x64), 31,  0, BFCSMask1Reg);
574   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x68), 31,  0, BFCSMask2Reg);
575   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x6C), 31,  0, BFCSMask3Reg);
576
577   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31,  0, BFDramControlReg);
578   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31,  0, BFDramInitRegReg);
579   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x80), 31,  0, BFDramBankAddrReg);
580   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 31,  0, BFDramMRSReg);
581   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84),  9,  7, BFDramTerm);
582   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 11, 10, BFDramTermDyn);
583   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x88), 31,  0, BFDramTimingLoReg);
584   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 31,  0, BFDramTimingHiReg);
585   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 31,  0, BFDramConfigLoReg);
586   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 31,  0, BFDramConfigHiReg);
587   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31,  0, BFDctAddlOffsetReg);
588   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x9C), 31,  0, BFDctAddlDataReg);
589   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 31, BFDctAccessDone);
590
591   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0xD4),  4,  0, BFNbFid);
592
593   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 18, 18, BFDqsRcvEnTrain);
594   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 22, BFMaxLatency);
595
596   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 15,  0, BFMrsAddress);
597   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 18, 16, BFMrsBank);
598   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 22, 20, BFMrsChipSel);
599   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 26, 26, BFSendMrsCmd);
600   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 27, 27, BFDeassertMemRstX);
601   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 28, 28, BFAssertCke);
602   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 29, 29, BFSendZQCmd);
603   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 30, 30, BFSendCtrlWord);
604   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 31, BFEnDramInit);
605
606   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C),  7,  7, BFLevel);
607   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 12, 12, BFMrsQoff);
608
609   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 18, 18, BFDisAutoRefresh);
610
611   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90),  0,  0, BFInitDram);
612   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 16, 16, BFUnBuffDimm);
613
614   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94),  8,  8, BFDdr3Mode);
615   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94),  9,  9, BFLegacyBiosMode);
616   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 11, 10, BFZqcsInterval);
617   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 14, 14, BFDisDramInterface);
618
619   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8),  5,  5, BFSubMemclkRegDly);
620   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8),  6,  6, BFOdtSwizzle);
621   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 15, 8, BFCtrlWordCS);
622
623   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110),  8, 8, BFDramEnabled);
624   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 31, 0, BFDctSelBaseAddrReg);
625   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x114), 31, 0, BFDctSelBaseOffsetReg);
626
627   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C),  6,  2, BFMctWrLimit);
628   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 12, 12, BFPrefCpuDis);
629   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 13, 13, BFPrefIoDis);
630   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 29, 29, BFFlushWrOnStpGnt);
631
632   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 31,  0, BFODCControl);
633   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x04, 31,  0, BFAddrTmgControl);
634
635   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08,  0,  0, BFWrtLvTrEn);
636   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08,  1,  1, BFWrtLvTrMode);
637   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08,  5,  4, BFTrDimmSel);
638   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 11,  8, BFWrLvOdt);
639   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 12, 12, BFWrLvOdtEn);
640   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 30, 30, BFDisAutoComp);
641
642 }
643
644 /*-----------------------------------------------------------------------------*/
645 /**
646  *     MemRecNIsIdSupportedDr
647  *      This function matches the CPU_LOGICAL_ID with certain criteria to
648  *      determine if it is supported by this NBBlock.
649  *
650  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
651  *     @param[in]       *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID
652  *
653  */
654 BOOLEAN
655 STATIC
656 MemRecNIsIdSupportedDr (
657   IN OUT   MEM_NB_BLOCK *NBPtr,
658   IN       CPU_LOGICAL_ID *LogicalIdPtr
659   )
660 {
661
662   if ((LogicalIdPtr->Revision & (AMD_F10_RB_ALL
663                                | AMD_F10_BL_ALL
664                                | AMD_F10_DA_ALL )) != 0) {
665     return TRUE;
666   } else {
667     return FALSE;
668   }
669 }