AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / Recovery / Mem / NB / PH / mrnPh.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * mrnPh.c
6  *
7  * Common Northbridge  functions for Pharaoh 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 "mrnPh.h"
66 #include "heapManager.h"
67 #include "AdvancedApi.h"
68 #include "Filecode.h"
69 CODE_GROUP (G2_PEI)
70 RDATA_GROUP (G2_PEI)
71
72 #define FILECODE PROC_RECOVERY_MEM_NB_PH_MRNPH_FILECODE
73 /*----------------------------------------------------------------------------
74  *                          DEFINITIONS AND MACROS
75  *
76  *----------------------------------------------------------------------------
77  */
78
79 #define SPLIT_CHANNEL   0x20000000
80 #define CHANNEL_SELECT  0x10000000
81 #define MAX_DELAYS    9   /* 8 data bytes + 1 ECC byte */
82 #define MAX_DIMMS     4   /* 4 DIMMs per channel */
83
84 /*----------------------------------------------------------------------------
85  *                           TYPEDEFS AND STRUCTURES
86  *
87  *----------------------------------------------------------------------------
88  */
89
90 /*----------------------------------------------------------------------------
91  *                        PROTOTYPES OF LOCAL FUNCTIONS
92  *
93  *----------------------------------------------------------------------------
94  */
95
96 VOID
97 STATIC
98 MemRecNInitNBRegTablePh (
99   IN OUT   TSEFO *NBRegTable
100   );
101
102 UINT32
103 STATIC
104 MemRecNCmnGetSetFieldPh (
105   IN OUT   MEM_NB_BLOCK *NBPtr,
106   IN       UINT8 IsSet,
107   IN       BIT_FIELD_NAME FieldName,
108   IN       UINT32 Field
109   );
110
111 UINT32
112 STATIC
113 MemRecNcmnGetSetTrainDlyPh (
114   IN OUT   MEM_NB_BLOCK *NBPtr,
115   IN       UINT8 IsSet,
116   IN       TRN_DLY_TYPE TrnDly,
117   IN       DRBN DrbnVar,
118   IN       UINT16 Field
119   );
120
121 BOOLEAN
122 STATIC
123 MemRecNIsIdSupportedPh (
124   IN OUT   MEM_NB_BLOCK *NBPtr,
125   IN       CPU_LOGICAL_ID *LogicalIdPtr
126   );
127
128 /*----------------------------------------------------------------------------
129  *                            EXPORTED FUNCTIONS
130  *
131  *----------------------------------------------------------------------------
132  */
133 STATIC CONST UINT32 RecModeDefRegArrayPh[] = {
134   BFDramControlReg,  0x320C2A06,
135   BFDramBankAddrReg, 0x00001111,
136   BFDramMRSReg,      0x000400A4,
137   BFDramTimingLoReg, 0x000A0092,
138   BFDramTimingHiReg, 0xB6D218FF,
139   BFDramConfigLoReg, 0x00000000,
140   BFDramConfigHiReg, 0x1F48010B,
141   NULL
142 };
143
144 /* -----------------------------------------------------------------------------*/
145 /**
146  *
147  *   This function initializes the northbridge block
148  *
149  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
150  *     @param[in,out]   *MemPtr  - Pointer to the MEM_DATA_STRUCT
151  *     @param[in]       NodeID   - Node ID for this NB block
152  *
153  *     @return          TRUE  - This node is a RB and this NB block has been initialized
154  *     @return          FALSE - This node is not a RB
155  */
156
157 BOOLEAN
158 MemRecConstructNBBlockPh (
159   IN OUT   MEM_NB_BLOCK *NBPtr,
160   IN OUT   MEM_DATA_STRUCT *MemPtr,
161   IN       UINT8 NodeID
162   )
163 {
164   UINT8 i;
165   UINT8 Dct;
166   UINT8 Channel;
167   DIE_STRUCT *MCTPtr;
168   ALLOCATE_HEAP_PARAMS AllocHeapParams;
169
170   //
171   // Determine if this is the expected NB Type
172   //
173   GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
174   if (!MemRecNIsIdSupportedPh (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) {
175     return FALSE;
176   }
177
178   //
179   // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs
180   //
181   MCTPtr = &MemPtr->DiesPerSystem[NodeID];
182   AllocHeapParams.RequestedBufferSize = MAX_DCTS_PER_NODE_DA * (
183                                           sizeof (DCT_STRUCT) + (
184                                             MAX_CHANNELS_PER_DCT_DA * (
185                                               sizeof (CH_DEF_STRUCT) + (
186                                                 MAX_DIMMS * MAX_DELAYS * NUMBER_OF_DELAY_TABLES
187                                               )
188                                             )
189                                           )
190                                         ) + (sizeof (TSEFO) * BFEndOfList);
191   AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0);
192   AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
193   if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) {
194     return FALSE;
195   }
196
197   MemPtr->DieCount = 1;
198   MCTPtr->DctCount = MAX_DCTS_PER_NODE_DA;
199   MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr;
200   AllocHeapParams.BufferPtr += MAX_DCTS_PER_NODE_DA * sizeof (DCT_STRUCT);
201   for (Dct = 0; Dct < MAX_DCTS_PER_NODE_DA; Dct++) {
202     MCTPtr->DctData[Dct].Dct = Dct;
203     MCTPtr->DctData[Dct].ChannelCount = MAX_CHANNELS_PER_DCT_DA;
204     MCTPtr->DctData[Dct].ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr;
205     MCTPtr->DctData[Dct].ChData[0].ChannelID = Dct;
206     AllocHeapParams.BufferPtr += MAX_CHANNELS_PER_DCT_DA * sizeof (CH_DEF_STRUCT);
207     for (Channel = 0; Channel < MAX_CHANNELS_PER_DCT_DA; Channel++) {
208       MCTPtr->DctData[Dct].ChData[Channel].RcvEnDlys = (UINT16 *) AllocHeapParams.BufferPtr;
209       AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS) * 2;
210       MCTPtr->DctData[Dct].ChData[Channel].WrDqsDlys = AllocHeapParams.BufferPtr;
211       MCTPtr->DctData[Dct].ChData[Channel].Dct = Dct;
212       AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS);
213     }
214   }
215
216   //
217   //  Initialize NB block's variables
218   //
219   NBPtr->NBRegTable = (TSEFO *) AllocHeapParams.BufferPtr;
220   NBPtr->MemPtr = MemPtr;
221   NBPtr->RefPtr = MemPtr->ParameterListPtr;
222   NBPtr->MCTPtr = MCTPtr;
223   NBPtr->SPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL];
224   NBPtr->AllNodeSPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL];
225
226   NBPtr->DctCachePtr = NBPtr->DctCache;
227
228   MemRecNInitNBRegTablePh (NBPtr->NBRegTable);
229   NBPtr->Dct = 0;
230   NBPtr->Channel = 0;
231   NBPtr->VarMtrrHiMsk = MemRecGetVarMtrrHiMsk (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
232
233   LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &NBPtr->MemPtr->StdHeader);
234   LibAmdMemFill (NBPtr->IsSupported, FALSE, sizeof (NBPtr->IsSupported), &NBPtr->MemPtr->StdHeader);
235   for (i = 0; i < NumberOfHooks; i++) {
236     NBPtr->FamilySpecificHook[i] = (BOOLEAN (*) (MEM_NB_BLOCK *, VOID *)) MemRecDefTrue;
237   }
238
239   NBPtr->InitRecovery = MemRecNMemInitNb;
240
241   NBPtr->RecModeDefRegArray = RecModeDefRegArrayPh;
242
243   NBPtr->SwitchNodeRec = (VOID (*) (MEM_NB_BLOCK *, UINT8)) MemRecDefRet;
244   NBPtr->SwitchDCT = MemRecNSwitchDctPh;
245   NBPtr->SwitchChannel = MemRecNSwitchChannelPh;
246   NBPtr->SetMaxLatency = MemRecNSetMaxLatencyNb;
247   NBPtr->GetSysAddrRec = MemRecNGetMCTSysAddrNb;
248   NBPtr->SendMrsCmd = MemRecNSendMrsCmdNb;
249   NBPtr->sendZQCmd = MemRecNSendZQCmdNb;
250   NBPtr->SetDramOdtRec = MemRecNSetDramOdtNb;
251
252   NBPtr->GetBitField = MemRecNGetBitFieldNb;
253   NBPtr->SetBitField = MemRecNSetBitFieldNb;
254   NBPtr->GetTrainDly = MemRecNGetTrainDlyNb;
255   NBPtr->SetTrainDly = MemRecNSetTrainDlyNb;
256   NBPtr->MemRecNCmnGetSetFieldNb = MemRecNCmnGetSetFieldPh;
257   NBPtr->MemRecNcmnGetSetTrainDlyNb = MemRecNcmnGetSetTrainDlyPh;
258   NBPtr->MemRecNSwitchDctNb = MemRecNSwitchDctPh;
259   NBPtr->TrainingFlow = MemNRecTrainingFlowNb;
260   NBPtr->MemRecNInitializeMctNb = MemRecNInitializeMctDA;
261   NBPtr->MemRecNFinalizeMctNb = MemRecNFinalizeMctDA;
262   NBPtr->IsSupported[DramModeBeforeDimmPres] = TRUE;
263   NBPtr->IsSupported[CheckClearOnDimmMirror] = TRUE;
264   MemRecNSwitchDctPh (NBPtr, 0);
265
266   return TRUE;
267 }
268
269 /* -----------------------------------------------------------------------------*/
270 /**
271  *
272  *   This function sets the current DCT to work on.
273  *   Should be called before accessing a certain DCT
274  *   All data structures will be updated to point to the current DCT
275  *
276  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
277  *     @param[in]   Dct - ID of the target DCT
278  *
279  */
280
281 VOID
282 MemRecNSwitchDctPh (
283   IN OUT   MEM_NB_BLOCK *NBPtr,
284   IN       UINT8 Dct
285   )
286 {
287   NBPtr->Dct = Dct & 1;
288   NBPtr->SPDPtr = &(NBPtr->AllNodeSPDPtr[Dct * MAX_DIMMS_PER_CHANNEL]);
289   NBPtr->DCTPtr = &(NBPtr->MCTPtr->DctData[NBPtr->Dct]);
290
291   MemRecNSwitchChannelPh (NBPtr, NBPtr->Channel);
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 MemRecNSwitchChannelPh (
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 MemRecNcmnGetSetTrainDlyPh (
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 MemRecNCmnGetSetFieldPh (
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 MemRecNInitNBRegTablePh (
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),  6,  6, BFOdtSwizzle);
620   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 15, 8, BFCtrlWordCS);
621
622   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110),  8, 8, BFDramEnabled);
623   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 31, 0, BFDctSelBaseAddrReg);
624   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x114), 31, 0, BFDctSelBaseOffsetReg);
625
626   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C),  6,  2, BFMctWrLimit);
627   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 12, 12, BFPrefCpuDis);
628   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 13, 13, BFPrefIoDis);
629   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 29, 29, BFFlushWrOnStpGnt);
630
631   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 31,  0, BFODCControl);
632   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x04, 31,  0, BFAddrTmgControl);
633
634   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08,  0,  0, BFWrtLvTrEn);
635   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08,  1,  1, BFWrtLvTrMode);
636   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08,  5,  4, BFTrDimmSel);
637   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 11,  8, BFWrLvOdt);
638   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 12, 12, BFWrLvOdtEn);
639   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 30, 30, BFDisAutoComp);
640
641 }
642
643 /*-----------------------------------------------------------------------------*/
644 /**
645  *     MemRecNIsIdSupportedPh
646  *      This function matches the CPU_LOGICAL_ID with certain criteria to
647  *      determine if it is supported by this NBBlock.
648  *
649  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
650  *     @param[in]       *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID
651  *
652  */
653 BOOLEAN
654 STATIC
655 MemRecNIsIdSupportedPh (
656   IN OUT   MEM_NB_BLOCK *NBPtr,
657   IN       CPU_LOGICAL_ID *LogicalIdPtr
658   )
659 {
660
661   if ((LogicalIdPtr->Revision & AMD_F10_PH_ALL) != 0) {
662     return TRUE;
663   } else {
664     return FALSE;
665   }
666 }