AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / Recovery / Mem / NB / DA / mrnda.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * mrnda.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 "mrnda.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_DA_MRNDA_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 MemRecNInitNBRegTableDA (
98   IN OUT   TSEFO *NBRegTable
99   );
100
101 UINT32
102 STATIC
103 MemRecNCmnGetSetFieldDA (
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 MemRecNcmnGetSetTrainDlyDA (
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 MemRecNIsIdSupportedDA (
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 RecModeDefRegArrayDA[] = {
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 MemRecConstructNBBlockDA (
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 (!MemRecNIsIdSupportedDA (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_DA * (
182                                           sizeof (DCT_STRUCT) + (
183                                             MAX_CHANNELS_PER_DCT_DA * (
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_DA;
198   MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr;
199   AllocHeapParams.BufferPtr += MAX_DCTS_PER_NODE_DA * sizeof (DCT_STRUCT);
200   for (Dct = 0; Dct < MAX_DCTS_PER_NODE_DA; Dct++) {
201     MCTPtr->DctData[Dct].Dct = Dct;
202     MCTPtr->DctData[Dct].ChannelCount = MAX_CHANNELS_PER_DCT_DA;
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_DA * sizeof (CH_DEF_STRUCT);
206     for (Channel = 0; Channel < MAX_CHANNELS_PER_DCT_DA; 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   MemRecNInitNBRegTableDA (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 = RecModeDefRegArrayDA;
241
242   NBPtr->SwitchNodeRec = (VOID (*) (MEM_NB_BLOCK *, UINT8)) MemRecDefRet;
243   NBPtr->SwitchDCT = MemRecNSwitchDctDA;
244   NBPtr->SwitchChannel = MemRecNSwitchChannelDA;
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 = MemRecNCmnGetSetFieldDA;
256   NBPtr->MemRecNcmnGetSetTrainDlyNb = MemRecNcmnGetSetTrainDlyDA;
257   NBPtr->MemRecNSwitchDctNb = MemRecNSwitchDctDA;
258   NBPtr->TrainingFlow = MemNRecTrainingFlowNb;
259   NBPtr->MemRecNInitializeMctNb = MemRecNInitializeMctDA;
260   NBPtr->MemRecNFinalizeMctNb = MemRecNFinalizeMctDA;
261   NBPtr->IsSupported[DramModeBeforeDimmPres] = TRUE;
262   NBPtr->IsSupported[CheckClearOnDimmMirror] = TRUE;
263   MemRecNSwitchDctDA (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 MemRecNSwitchDctDA (
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   MemRecNSwitchChannelDA (NBPtr, NBPtr->Channel);
291 }
292 /* -----------------------------------------------------------------------------*/
293 /**
294  *
295  *   This function sets the current channel to work on.
296  *   Should be called before accessing a certain channel
297  *   All data structures will be updated to point to the current channel
298  *
299  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
300  *     @param[in]   Channel - ID of the target channel
301  *
302  */
303
304 VOID
305 MemRecNSwitchChannelDA (
306   IN OUT   MEM_NB_BLOCK *NBPtr,
307   IN       UINT8 Channel
308   )
309 {
310   NBPtr->Channel = Channel & 1;
311   NBPtr->ChannelPtr = &(NBPtr->DCTPtr->ChData[NBPtr->Channel]);
312 }
313 /*----------------------------------------------------------------------------
314  *                              LOCAL FUNCTIONS
315  *
316  *----------------------------------------------------------------------------
317  */
318
319 /* -----------------------------------------------------------------------------*/
320 /**
321  *
322  *   This function gets or set DQS timing during training.
323  *
324  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
325  *     @param[in]   TrnDly - type of delay to be set
326  *     @param[in]   DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed
327  *                  (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding
328  *     @param[in]   Field - Value to be programmed
329  *     @param[in]   IsSet - Indicates if the function will set or get
330  *
331  *     @return      value read, if the function is used as a "get"
332  */
333
334 UINT32
335 STATIC
336 MemRecNcmnGetSetTrainDlyDA (
337   IN OUT   MEM_NB_BLOCK *NBPtr,
338   IN       UINT8 IsSet,
339   IN       TRN_DLY_TYPE TrnDly,
340   IN       DRBN DrbnVar,
341   IN       UINT16 Field
342   )
343 {
344   UINT16 Index;
345   UINT16 Offset;
346   UINT32 Value;
347   UINT32 Address;
348   UINT8 Dimm;
349   UINT8 Byte;
350
351   Dimm = DRBN_DIMM (DrbnVar);
352   Byte = DRBN_BYTE (DrbnVar);
353
354   ASSERT (Dimm < 4);
355   ASSERT (Byte <= 8);
356
357   switch (TrnDly) {
358   case AccessRcvEnDly:
359     Index = 0x10;
360     break;
361   case AccessWrDqsDly:
362     Index = 0x30;
363     break;
364   case AccessWrDatDly:
365     Index = 0x01;
366     break;
367   case AccessRdDqsDly:
368     Index = 0x05;
369     break;
370   case AccessPhRecDly:
371     Index = 0x50;
372     break;
373   default:
374     Index = 0;
375     IDS_ERROR_TRAP;
376   }
377
378   switch (TrnDly) {
379   case AccessRcvEnDly:
380   case AccessWrDqsDly:
381     Index += (Dimm * 3);
382     if (Byte & 0x04) {
383       // if byte 4,5,6,7
384       Index += 0x10;
385     }
386     if (Byte & 0x02) {
387       // if byte 2,3,6,7
388       Index++;
389     }
390     Offset = 16 * (Byte % 2);
391     break;
392
393   case AccessRdDqsDly:
394     Field &= ~ 0x0001;
395   case AccessWrDatDly:
396     Index += (Dimm * 0x100);
397     // break is not being used here because AccessRdDqsDly and AccessWrDatDly also need
398     // to run AccessPhRecDly sequence.
399   case AccessPhRecDly:
400     Index += (Byte / 4);
401     Offset = 8 * (Byte % 4);
402     break;
403   default:
404     Offset = 0;
405     IDS_ERROR_TRAP;
406   }
407
408   Address = Index;
409   MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
410   while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
411   Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
412
413   if (IsSet) {
414     if (TrnDly == AccessPhRecDly) {
415       Value = NBPtr->DctCachePtr->PhRecReg[Index & 0x03];
416     }
417
418     Value = ((UINT32)Field << Offset) | (Value & (~((UINT32)0xFF << Offset)));
419     MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value);
420     Address |= DCT_ACCESS_WRITE;
421     MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
422     while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
423
424     if (TrnDly == AccessPhRecDly) {
425       NBPtr->DctCachePtr->PhRecReg[Index & 0x03] = Value;
426     }
427   } else {
428     Value = (Value >> Offset) & 0xFF;
429   }
430
431   return Value;
432 }
433
434 /* -----------------------------------------------------------------------------*/
435 /**
436  *
437  *   This function gets or sets a value to a bit field in a PCI register.
438  *
439  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
440  *     @param[in]   IsSet - Indicates if the function will set or get
441  *     @param[in]   FieldName - Name of field to be set
442  *     @param[in]   Field - Value to be programmed
443  *
444  *     @return      value read, if the function is used as a "get"
445  */
446
447 UINT32
448 STATIC
449 MemRecNCmnGetSetFieldDA (
450   IN OUT   MEM_NB_BLOCK *NBPtr,
451   IN       UINT8 IsSet,
452   IN       BIT_FIELD_NAME FieldName,
453   IN       UINT32 Field
454   )
455 {
456   SBDFO Address;
457   PCI_ADDR PciAddr;
458   UINT8 Type;
459   UINT32 Value;
460   UINT32 Highbit;
461   UINT32 Lowbit;
462   UINT32 Mask;
463
464   Value = 0;
465   if (FieldName < BFEndOfList) {
466     Address = NBPtr->NBRegTable[FieldName];
467     if (Address) {
468       Lowbit = TSEFO_END (Address);
469       Highbit = TSEFO_START (Address);
470       Type = TSEFO_TYPE (Address);
471
472       // If Fn2 and DCT1 selected, set Address to be 1xx
473       if (((Address & 0xF000) == 0x2000) && NBPtr->Dct) {
474         Address |= 0x0100;
475       }
476       if ((Address >> 29) == ((DCT_PHY_ACCESS << 1) | 1)) {
477         // Special DCT Phy access
478         Address &= 0x0FFFFFFF;
479         Lowbit = 0;
480         Highbit = 16;
481       } else {
482         // Normal DCT Phy access
483         Address = TSEFO_OFFSET (Address);
484       }
485
486
487       if (Type == NB_ACCESS) {
488         Address |= (((UINT32) (24 + 0)) << 15);
489         PciAddr.AddressValue = Address;
490         LibAmdPciRead (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader);
491       } else if (Type == DCT_PHY_ACCESS) {
492         MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
493         while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
494
495         Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
496       } else {
497         IDS_ERROR_TRAP;
498       }
499
500       if (IsSet) {
501         // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
502         if ((Highbit - Lowbit) != 31) {
503           Mask = (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
504         } else {
505           Mask = (UINT32)0xFFFFFFFF;
506         }
507         Value &= ~(Mask << Lowbit);
508         Value |= (Field & Mask) << Lowbit;
509
510         if (Type == NB_ACCESS) {
511           PciAddr.AddressValue = Address;
512           LibAmdPciWrite (AccessWidth32, PciAddr , &Value, &NBPtr->MemPtr->StdHeader);
513         } else if (Type == DCT_PHY_ACCESS) {
514           MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value);
515           Address |= DCT_ACCESS_WRITE;
516
517           MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
518           while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
519         } else {
520           IDS_ERROR_TRAP;
521         }
522       } else {
523         Value = Value >> Lowbit;  // Shift
524         // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
525         if ((Highbit - Lowbit) != 31) {
526           Value &= (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
527         }
528       }
529     }
530   } else {
531     IDS_ERROR_TRAP;   // Invalid bit field index
532   }
533   return Value;
534 }
535
536
537 /* -----------------------------------------------------------------------------*/
538 /**
539  *
540  *   This function initializes bit field translation table
541  *
542  *     @param[in,out]   *NBRegTable   - Pointer to the NB Table *
543  */
544
545 VOID
546 STATIC
547 MemRecNInitNBRegTableDA (
548   IN OUT   TSEFO *NBRegTable
549   )
550 {
551   UINT16 i;
552   for (i = 0; i <= BFEndOfList; i++) {
553     NBRegTable[i] = 0;
554   }
555
556   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x00), 31,  0, BFDevVendorIDReg);
557   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x60),  2,  0, BFNodeID);
558
559   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x40), 31, 0, BFDramBaseReg0);
560   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x44), 31, 0, BFDramLimitReg0);
561
562   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x40), 31,  0, BFCSBaseAddr0Reg);
563   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x44), 31,  0, BFCSBaseAddr1Reg);
564   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x48), 31,  0, BFCSBaseAddr2Reg);
565   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x4C), 31,  0, BFCSBaseAddr3Reg);
566   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x50), 31,  0, BFCSBaseAddr4Reg);
567   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x54), 31,  0, BFCSBaseAddr5Reg);
568   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x58), 31,  0, BFCSBaseAddr6Reg);
569   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x5C), 31,  0, BFCSBaseAddr7Reg);
570
571   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x60), 31,  0, BFCSMask0Reg);
572   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x64), 31,  0, BFCSMask1Reg);
573   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x68), 31,  0, BFCSMask2Reg);
574   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x6C), 31,  0, BFCSMask3Reg);
575
576   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31,  0, BFDramControlReg);
577   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31,  0, BFDramInitRegReg);
578   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x80), 31,  0, BFDramBankAddrReg);
579   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 31,  0, BFDramMRSReg);
580   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84),  9,  7, BFDramTerm);
581   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 11, 10, BFDramTermDyn);
582   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x88), 31,  0, BFDramTimingLoReg);
583   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 31,  0, BFDramTimingHiReg);
584   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 31,  0, BFDramConfigLoReg);
585   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 31,  0, BFDramConfigHiReg);
586   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31,  0, BFDctAddlOffsetReg);
587   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x9C), 31,  0, BFDctAddlDataReg);
588   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 31, BFDctAccessDone);
589
590   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0xD4),  4,  0, BFNbFid);
591
592   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 18, 18, BFDqsRcvEnTrain);
593   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 22, BFMaxLatency);
594
595   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 15,  0, BFMrsAddress);
596   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 18, 16, BFMrsBank);
597   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 22, 20, BFMrsChipSel);
598   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 26, 26, BFSendMrsCmd);
599   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 27, 27, BFDeassertMemRstX);
600   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 28, 28, BFAssertCke);
601   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 29, 29, BFSendZQCmd);
602   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 30, 30, BFSendCtrlWord);
603   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 31, BFEnDramInit);
604
605   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C),  7,  7, BFLevel);
606   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 12, 12, BFMrsQoff);
607
608   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 18, 18, BFDisAutoRefresh);
609
610   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90),  0,  0, BFInitDram);
611   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 16, 16, BFUnBuffDimm);
612
613   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94),  8,  8, BFDdr3Mode);
614   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94),  9,  9, BFLegacyBiosMode);
615   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 11, 10, BFZqcsInterval);
616   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 14, 14, BFDisDramInterface);
617
618   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8),  6,  6, BFOdtSwizzle);
619   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 15, 8, BFCtrlWordCS);
620
621   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110),  8, 8, BFDramEnabled);
622   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 31, 0, BFDctSelBaseAddrReg);
623   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x114), 31, 0, BFDctSelBaseOffsetReg);
624
625   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C),  6,  2, BFMctWrLimit);
626   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 12, 12, BFPrefCpuDis);
627   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 13, 13, BFPrefIoDis);
628   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 29, 29, BFFlushWrOnStpGnt);
629
630   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 31,  0, BFODCControl);
631   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x04, 31,  0, BFAddrTmgControl);
632
633   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08,  0,  0, BFWrtLvTrEn);
634   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08,  1,  1, BFWrtLvTrMode);
635   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08,  5,  4, BFTrDimmSel);
636   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 11,  8, BFWrLvOdt);
637   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 12, 12, BFWrLvOdtEn);
638   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 30, 30, BFDisAutoComp);
639
640 }
641
642 /*-----------------------------------------------------------------------------*/
643 /**
644  *     MemRecNIsIdSupportedDA
645  *      This function matches the CPU_LOGICAL_ID with certain criteria to
646  *      determine if it is supported by this NBBlock.
647  *
648  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
649  *     @param[in]       *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID
650  *
651  */
652 BOOLEAN
653 STATIC
654 MemRecNIsIdSupportedDA (
655   IN OUT   MEM_NB_BLOCK *NBPtr,
656   IN       CPU_LOGICAL_ID *LogicalIdPtr
657   )
658 {
659
660   if ((LogicalIdPtr->Revision & (AMD_F10_BL_ALL | AMD_F10_DA_ALL)) != 0) {
661     return TRUE;
662   } else {
663     return FALSE;
664   }
665 }