AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / Recovery / Mem / NB / OR / mrnor.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * mrnor.c
6  *
7  * Common Northbridge  functions for Orochi Recovery
8  *
9  * @xrefitem bom "File Content Label" "Release Content"
10  * @e project: AGESA
11  * @e sub-project: (Proc/Recovery/Mem)
12  * @e \$Revision: 49896 $ @e \$Date: 2011-03-30 02:18:18 -0600 (Wed, 30 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 "mrport.h"
59 #include "cpuFamRegisters.h"
60 #include "cpuRegisters.h"
61 #include "cpuFamilyTranslation.h"
62 #include "mm.h"
63 #include "mn.h"
64 #include "mrnor.h"
65 #include "heapManager.h"
66 #include "AdvancedApi.h"
67 #include "Filecode.h"
68 CODE_GROUP (G3_DXE)
69 RDATA_GROUP (G3_DXE)
70 #define FILECODE PROC_RECOVERY_MEM_NB_OR_MRNOR_FILECODE
71 /*----------------------------------------------------------------------------
72  *                          DEFINITIONS AND MACROS
73  *
74  *----------------------------------------------------------------------------
75  */
76
77 #define MAX_DCTS_PER_DIE 2
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 MemRecNInitNBRegTableOr (
98   IN OUT   TSEFO *NBRegTable
99   );
100
101 UINT32
102 STATIC
103 MemRecNCmnGetSetFieldOr (
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 MemRecNcmnGetSetTrainDlyOr (
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 MemRecNIsIdSupportedOr (
123   IN OUT   MEM_NB_BLOCK *NBPtr,
124   IN       CPU_LOGICAL_ID *LogicalIdPtr
125   );
126
127 VOID
128 STATIC
129 MemRecNSwitchNodeOr (
130   IN OUT   MEM_NB_BLOCK *NBPtr,
131   IN       UINT8 NodeID
132   );
133
134
135 /*----------------------------------------------------------------------------
136  *                            EXPORTED FUNCTIONS
137  *
138  *----------------------------------------------------------------------------
139  */
140 STATIC CONST UINT32 RecModeDefRegArrayOR[] = {
141   BFDramBankAddrReg, 0x00001111,
142   BFTref,            0x00000002,
143   BFDramTimingLoReg, 0x00000000,
144   BFDramTiming0,     0x0F060606,
145   BFDramTiming1,     0x04100415,
146   BFDramTiming2,     0x05050505,
147   BFDramTiming3,     0x00000405,
148   BFDramTiming4,     0x000B0B0B,
149   BFDramTiming5,     0x0B0B0B0B,
150   BFDramTiming6,     0x00171600,
151   BFDramTiming10,    0x00000006,
152   BFDramNBP0,        0x32000006,
153   BFDramConfigHiReg, 0x00180800,
154   BFDramODTCtlReg,   0x00006061,
155   BFPhyFence,        0x000056B5,
156   BFSwNbPstateLoDis, 0x00000001,
157   NULL
158 };
159
160 /* -----------------------------------------------------------------------------*/
161 /**
162  *
163  *   This function initializes the northbridge block
164  *
165  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
166  *     @param[in,out]   *MemPtr  - Pointer to the MEM_DATA_STRUCT
167  *     @param[in]       NodeID   - Node ID for this NB block
168  *
169  *     @return          TRUE  - This node is a Orochi and this NB block has been initialized
170  *     @return          FALSE - This node is not a Orochi
171  */
172
173 BOOLEAN
174 MemRecConstructNBBlockOr (
175   IN OUT   MEM_NB_BLOCK *NBPtr,
176   IN OUT   MEM_DATA_STRUCT *MemPtr,
177   IN       UINT8 NodeID
178   )
179 {
180   UINT8 i;
181   UINT8 Dct;
182   UINT8 Channel;
183   DIE_STRUCT *MCTPtr;
184   ALLOCATE_HEAP_PARAMS AllocHeapParams;
185
186   //
187   // Determine if this is the expected NB Type
188   //
189   GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
190   if (!MemRecNIsIdSupportedOr (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) {
191     return FALSE;
192   }
193
194   //
195   // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs
196   //
197   MCTPtr = &MemPtr->DiesPerSystem[NodeID];
198   AllocHeapParams.RequestedBufferSize = MAX_DCTS_PER_NODE_OR * (
199                                           sizeof (DCT_STRUCT) + (
200                                             MAX_CHANNELS_PER_DCT_OR * (
201                                               sizeof (CH_DEF_STRUCT) + (
202                                                 MAX_DIMMS * MAX_DELAYS * NUMBER_OF_DELAY_TABLES
203                                               )
204                                             )
205                                           )
206                                         ) + sizeof (MEM_PS_BLOCK) + (sizeof (TSEFO) * BFEndOfList);
207   AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0);
208   AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
209   if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) {
210     return FALSE;
211   }
212
213   MemPtr->DieCount = MAX_DIES_PER_SOCKET_OR;
214   MCTPtr->DctCount = MAX_DCTS_PER_NODE_OR;
215   MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr;
216   MemPtr->DiesPerSystem[NodeID + 1].DctCount = MAX_DCTS_PER_NODE_OR;
217   MemPtr->DiesPerSystem[NodeID + 1].DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr;
218   AllocHeapParams.BufferPtr += MAX_DCTS_PER_NODE_OR * sizeof (DCT_STRUCT);
219   for (Dct = 0; Dct < MAX_DCTS_PER_NODE_OR; Dct++) {
220     MCTPtr->DctData[Dct].Dct = Dct;
221     MCTPtr->DctData[Dct].ChannelCount = MAX_CHANNELS_PER_DCT_OR;
222     MCTPtr->DctData[Dct].ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr;
223     MCTPtr->DctData[Dct].ChData[0].ChannelID = (MCTPtr->DieId * 2) + Dct;
224     AllocHeapParams.BufferPtr += MAX_CHANNELS_PER_DCT_OR * sizeof (CH_DEF_STRUCT);
225     for (Channel = 0; Channel < MAX_CHANNELS_PER_DCT_OR; Channel++) {
226       MCTPtr->DctData[Dct].ChData[Channel].RcvEnDlys = (UINT16 *) AllocHeapParams.BufferPtr;
227       AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS) * 2;
228       MCTPtr->DctData[Dct].ChData[Channel].WrDqsDlys = AllocHeapParams.BufferPtr;
229       MCTPtr->DctData[Dct].ChData[Channel].Dct = Dct;
230       AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS);
231     }
232   }
233   NBPtr->PsPtr = (MEM_PS_BLOCK *) AllocHeapParams.BufferPtr;
234   AllocHeapParams.BufferPtr += sizeof (MEM_PS_BLOCK);
235
236   //
237   //  Initialize NB block's variables
238   //
239   NBPtr->NBRegTable = (TSEFO *) AllocHeapParams.BufferPtr;
240   NBPtr->MemPtr = MemPtr;
241   NBPtr->RefPtr = MemPtr->ParameterListPtr;
242   NBPtr->MCTPtr = MCTPtr;
243   NBPtr->AllNodeMCTPtr = &MemPtr->DiesPerSystem[NodeID];
244   NBPtr->SPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL];
245   NBPtr->AllNodeSPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL];
246
247   NBPtr->DctCachePtr = NBPtr->DctCache;
248
249   MemRecNInitNBRegTableOr (NBPtr->NBRegTable);
250   NBPtr->Dct = 0;
251   NBPtr->Channel = 0;
252   NBPtr->VarMtrrHiMsk = MemRecGetVarMtrrHiMsk (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader));
253
254   LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &NBPtr->MemPtr->StdHeader);
255   LibAmdMemFill (NBPtr->IsSupported, FALSE, sizeof (NBPtr->IsSupported), &NBPtr->MemPtr->StdHeader);
256   for (i = 0; i < NumberOfHooks; i++) {
257     NBPtr->FamilySpecificHook[i] = (BOOLEAN (*) (MEM_NB_BLOCK *, VOID *)) MemRecDefTrue;
258   }
259
260   NBPtr->InitRecovery = MemRecNMemInitOr;
261
262   NBPtr->RecModeDefRegArray = RecModeDefRegArrayOR;
263
264   NBPtr->SwitchNodeRec = MemRecNSwitchNodeOr;
265   NBPtr->SwitchDCT = MemRecNSwitchDctOr;
266   NBPtr->SwitchChannel = MemRecNSwitchChannelOr;
267   NBPtr->SetMaxLatency = MemRecNSetMaxLatencyOr;
268   NBPtr->GetSysAddrRec = MemRecNGetMCTSysAddrNb;
269   NBPtr->SendMrsCmd = MemRecNSendMrsCmdNb;
270   NBPtr->sendZQCmd = MemRecNSendZQCmdNb;
271   NBPtr->SetDramOdtRec = MemRecNSetDramOdtOr;
272
273   NBPtr->GetBitField = MemRecNGetBitFieldNb;
274   NBPtr->SetBitField = MemRecNSetBitFieldNb;
275   NBPtr->GetTrainDly = MemRecNGetTrainDlyNb;
276   NBPtr->SetTrainDly = MemRecNSetTrainDlyNb;
277
278   NBPtr->MemRecNCmnGetSetFieldNb = MemRecNCmnGetSetFieldOr;
279   NBPtr->MemRecNcmnGetSetTrainDlyNb = MemRecNcmnGetSetTrainDlyOr;
280   NBPtr->MemRecNSwitchDctNb = MemRecNSwitchDctOr;
281   NBPtr->TrainingFlow = MemNRecTrainingFlowUnb;
282   NBPtr->ReadPattern = MemRecNContReadPatternUnb;
283   NBPtr->WritePattern = MemRecNContWritePatternUnb;
284   NBPtr->CompareTestPattern = MemRecNCompareTestPatternUnb;
285
286   NBPtr->IsSupported[CheckDramTerm] = TRUE;
287   NBPtr->IsSupported[CheckDramTermDyn] = TRUE;
288   MemRecNSwitchDctOr (NBPtr, 0);
289
290   return TRUE;
291 }
292
293 /* -----------------------------------------------------------------------------*/
294 /**
295  *
296  *
297  *   This function sets the current die to work on.
298  *   Should be called before accessing a certain die
299  *   All data structures will be updated to point to the current node
300  *
301  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
302  *     @param[in]   NodeID - ID of the target die
303  *
304  */
305
306 VOID
307 STATIC
308 MemRecNSwitchNodeOr (
309   IN OUT   MEM_NB_BLOCK *NBPtr,
310   IN       UINT8 NodeID
311   )
312 {
313   NBPtr->MCTPtr = &(NBPtr->AllNodeMCTPtr[NodeID]);
314   NBPtr->Node = NodeID;
315   NBPtr->MCTPtr->NodeId = NodeID;
316   MemRecNSwitchDctOr (NBPtr, NBPtr->Dct);
317 }
318
319 /* -----------------------------------------------------------------------------*/
320 /**
321  *
322  *   This function sets the current DCT to work on.
323  *   Should be called before accessing a certain DCT
324  *   All data structures will be updated to point to the current DCT
325  *
326  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
327  *     @param[in]   Dct - ID of the target DCT
328  *
329  */
330
331 VOID
332 MemRecNSwitchDctOr (
333   IN OUT   MEM_NB_BLOCK *NBPtr,
334   IN       UINT8 Dct
335   )
336 {
337   NBPtr->Dct = Dct & 1;
338   NBPtr->SPDPtr = &(NBPtr->AllNodeSPDPtr[(NBPtr->MCTPtr->NodeId * MAX_DCTS_PER_DIE + Dct) * MAX_DIMMS_PER_CHANNEL]);
339   NBPtr->DCTPtr = &(NBPtr->MCTPtr->DctData[NBPtr->Dct]);
340
341   MemRecNSwitchChannelOr (NBPtr, 0);
342 }
343
344 /* -----------------------------------------------------------------------------*/
345 /**
346  *
347  *   This function sets the current channel to work on.
348  *   Should be called before accessing a certain channel
349  *   All data structures will be updated to point to the current channel
350  *
351  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
352  *     @param[in]   Channel - ID of the target channel
353  *
354  */
355
356 VOID
357 MemRecNSwitchChannelOr (
358   IN OUT   MEM_NB_BLOCK *NBPtr,
359   IN       UINT8 Channel
360   )
361 {
362   NBPtr->Channel = 0;
363   NBPtr->ChannelPtr = &(NBPtr->DCTPtr->ChData[0]);
364 }
365
366 /*----------------------------------------------------------------------------
367  *                              LOCAL FUNCTIONS
368  *
369  *----------------------------------------------------------------------------
370  */
371
372 /* -----------------------------------------------------------------------------*/
373 /**
374  *
375  *   This function gets or set DQS timing during training.
376  *
377  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
378  *     @param[in]   TrnDly - type of delay to be set
379  *     @param[in]   DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed
380  *                  (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding
381  *     @param[in]   Field - Value to be programmed
382  *     @param[in]   IsSet - Indicates if the function will set or get
383  *
384  *     @return      value read, if the function is used as a "get"
385  */
386
387 UINT32
388 STATIC
389 MemRecNcmnGetSetTrainDlyOr (
390   IN OUT   MEM_NB_BLOCK *NBPtr,
391   IN       UINT8 IsSet,
392   IN       TRN_DLY_TYPE TrnDly,
393   IN       DRBN DrbnVar,
394   IN       UINT16 Field
395   )
396 {
397   UINT16 index;
398   UINT16 offset;
399   UINT32 value;
400   UINT32 address;
401   UINT8 DIMM;
402   UINT8 Byte;
403   UINT32 mask;
404
405   DIMM = DRBN_DIMM (DrbnVar);
406   Byte = DRBN_BYTE (DrbnVar);
407
408   mask = 0xFF;
409
410   switch (TrnDly) {
411   case AccessRcvEnDly:
412     mask = 0x1FF;
413     index = 0x10;
414     break;
415   case AccessWrDqsDly:
416     index = 0x30;
417     break;
418   case AccessWrDatDly:
419     index = 0x01;
420     break;
421   case AccessRdDqsDly:
422     index = 0x05;
423     break;
424   case AccessPhRecDly:
425     index = 0x50;
426     break;
427   default:
428     index = 0;
429     IDS_ERROR_TRAP;
430   }
431
432   switch (TrnDly) {
433   case AccessRcvEnDly:
434   case AccessWrDqsDly:
435     index += (DIMM * 3);
436     if ((Byte & 0x04) != 0) {
437       // if byte 4,5,6,7
438       index += 0x10;
439     }
440     if ((Byte & 0x02) != 0) {
441       // if byte 2,3,6,7
442       index++;
443     }
444     offset = 16 * (Byte % 2);
445     break;
446
447   case AccessRdDqsDly:
448   case AccessWrDatDly:
449     index += (DIMM * 0x100);
450     // break is not being used here because AccessRdDqsDly and AccessWrDatDly also need
451     // to run AccessPhRecDly sequence.
452   case AccessPhRecDly:
453     index += (Byte / 4);
454     offset = 8 * (Byte % 4);
455     break;
456   default:
457     offset = 0;
458     IDS_ERROR_TRAP;
459   }
460
461   address = index;
462   MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, address);
463   while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
464   value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
465
466   if (IsSet != 0) {
467     if (TrnDly == AccessPhRecDly) {
468       value = NBPtr->DctCachePtr->PhRecReg[index & 0x03];
469     }
470
471     value = ((UINT32)Field << offset) | (value & (~(mask << offset)));
472     MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, value);
473     address |= DCT_ACCESS_WRITE;
474     MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, address);
475     while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
476
477     if (TrnDly == AccessPhRecDly) {
478       NBPtr->DctCachePtr->PhRecReg[index & 0x03] = value;
479     }
480   } else {
481     value = (value >> offset) & mask;
482   }
483
484   return value;
485 }
486
487 /* -----------------------------------------------------------------------------*/
488 /**
489  *
490  *   This function gets or sets a value to a bit field in a PCI register.
491  *
492  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
493  *     @param[in]   FieldName - Name of Field to be set
494  *     @param[in]   Field - Value to be programmed
495  *     @param[in]   IsSet - Indicates if the function will set or get
496  *
497  *     @return      value read, if the function is used as a "get"
498  */
499
500 UINT32
501 STATIC
502 MemRecNCmnGetSetFieldOr (
503   IN OUT   MEM_NB_BLOCK *NBPtr,
504   IN       UINT8 IsSet,
505   IN       BIT_FIELD_NAME FieldName,
506   IN       UINT32 Field
507   )
508 {
509   TSEFO Address;
510   PCI_ADDR PciAddr;
511   UINT8 Type;
512   UINT32 Value;
513   UINT32 Highbit;
514   UINT32 Lowbit;
515   UINT32 Mask;
516
517   Value = 0;
518   if (FieldName < BFEndOfList) {
519     Address = NBPtr->NBRegTable[FieldName];
520     if (Address != 0) {
521       Lowbit = TSEFO_END (Address);
522       Highbit = TSEFO_START (Address);
523       Type = TSEFO_TYPE (Address);
524
525       // If Fn2 and DCT1 selected, set Address to be 1xx
526       if ((Type == NB_ACCESS) && ((Address & 0xF000) == 0x2000)) {
527         MemRecNSetBitFieldNb (NBPtr, BFDctCfgSel, NBPtr->Dct);
528       }
529       if ((Address >> 29) == ((DCT_PHY_ACCESS << 1) | 1)) {
530         // Special DCT Phy access
531         Address &= 0x0FFFFFFF;
532         Lowbit = 0;
533         Highbit = 16;
534       } else {
535         // Normal DCT Phy access
536         Address = TSEFO_OFFSET (Address);
537       }
538
539
540       if (Type == NB_ACCESS) {
541         // Address |= (((UINT32) (24 + 0)) << 15);
542         PciAddr.AddressValue = Address;
543         // Fix for MCM
544         PciAddr.Address.Device = NBPtr->MemPtr->DiesPerSystem[NBPtr->Node].PciAddr.Address.Device;
545         PciAddr.Address.Bus = NBPtr->MemPtr->DiesPerSystem[NBPtr->Node].PciAddr.Address.Bus;
546         PciAddr.Address.Segment = NBPtr->MemPtr->DiesPerSystem[NBPtr->Node].PciAddr.Address.Segment;
547         Address = PciAddr.AddressValue;
548         LibAmdPciRead (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader);
549         IDS_HDT_CONSOLE (MEM_GETREG, "~Dev%x Dct%d Fn%d_%03x = %x\n",
550                          NBPtr->PciAddr.Address.Device, NBPtr->Dct,
551                          (Address >> 12) & 0xF, Address & 0xFFF, Value);
552       } else if (Type == DCT_PHY_ACCESS) {
553         MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
554         while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
555
556         Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg);
557       } else {
558         IDS_ERROR_TRAP;
559       }
560
561       if (IsSet != 0) {
562         // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
563         if ((Highbit - Lowbit) != 31) {
564           Mask = (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
565         } else {
566           Mask = (UINT32)0xFFFFFFFF;
567         }
568         Value &= ~(Mask << Lowbit);
569         Value |= (Field & Mask) << Lowbit;
570
571         if (Type == NB_ACCESS) {
572           PciAddr.AddressValue = Address;
573           LibAmdPciWrite (AccessWidth32, PciAddr , &Value, &NBPtr->MemPtr->StdHeader);
574           IDS_HDT_CONSOLE (MEM_SETREG, "~Dev%x Dct%d Fn%d_%03x [%d:%d] = %x\n",
575                            NBPtr->PciAddr.Address.Device, NBPtr->Dct,
576                            (Address >> 12) & 0xF, Address & 0xFFF, Highbit, Lowbit, Field);
577         } else if (Type == DCT_PHY_ACCESS) {
578           MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value);
579           Address |= DCT_ACCESS_WRITE;
580
581           MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address);
582           while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {}
583         } else {
584           IDS_ERROR_TRAP;
585         }
586       } else {
587         Value = Value >> Lowbit;  // Shift
588         // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case
589         if ((Highbit - Lowbit) != 31) {
590           Value &= (((UINT32)1 << (Highbit - Lowbit + 1)) - 1);
591         }
592       }
593     }
594   } else {
595     IDS_ERROR_TRAP;   // Invalid bit field index
596   }
597   return Value;
598 }
599
600
601 /* -----------------------------------------------------------------------------*/
602 /**
603  *
604  *   This function initializes bit field translation table
605  *
606 *     @param[in,out]   *NBRegTable   - Pointer to the NB Table *
607  */
608
609 VOID
610 STATIC
611 MemRecNInitNBRegTableOr (
612   IN OUT   TSEFO *NBRegTable
613   )
614 {
615   UINT16 i;
616   for (i = 0; i <= BFEndOfList; i++) {
617     NBRegTable[i] = 0;
618   }
619
620   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x40), 31,  0, BFDramBaseReg0);
621   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x44), 31,  0, BFDramLimitReg0);
622
623   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x10C), 0,  0, BFDctCfgSel);
624
625   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x40), 31,  0, BFCSBaseAddr0Reg);
626   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x44), 31,  0, BFCSBaseAddr1Reg);
627   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x48), 31,  0, BFCSBaseAddr2Reg);
628   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x4C), 31,  0, BFCSBaseAddr3Reg);
629   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x50), 31,  0, BFCSBaseAddr4Reg);
630   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x54), 31,  0, BFCSBaseAddr5Reg);
631   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x58), 31,  0, BFCSBaseAddr6Reg);
632   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x5C), 31,  0, BFCSBaseAddr7Reg);
633
634   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x60), 31,  0, BFCSMask0Reg);
635   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x64), 31,  0, BFCSMask1Reg);
636   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x68), 31,  0, BFCSMask2Reg);
637   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x6C), 31,  0, BFCSMask3Reg);
638
639   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31,  0, BFDramInitRegReg);
640   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x80), 31,  0, BFDramBankAddrReg);
641   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x88), 31,  0, BFDramTimingLoReg);
642   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 31,  0, BFDramConfigLoReg);
643   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 31,  0, BFDramConfigHiReg);
644   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31,  0, BFDctAddlOffsetReg);
645   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x9C), 31,  0, BFDctAddlDataReg);
646   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 31, BFDctAccessDone);
647
648   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 17,  0, BFMrsAddress);
649   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 20, 18, BFMrsBank);
650   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 23, 21, BFMrsChipSel);
651   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 26, 26, BFSendMrsCmd);
652   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 27, 27, BFDeassertMemRstX);
653   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 28, 28, BFAssertCke);
654   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 29, 29, BFSendZQCmd);
655   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 30, 30, BFSendCtrlWord);
656   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 31, BFEnDramInit);
657
658   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C),  7,  7, BFLevel);
659   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 12, 12, BFMrsQoff);
660
661   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 17, 16, BFTref);
662   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 18, 18, BFDisAutoRefresh);
663
664   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 15, 12, BFX4Dimm);
665   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 16, 16, BFUnBuffDimm);
666
667   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94),  4,  0, BFMemClkFreq);
668   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94),  7,  7, BFMemClkFreqVal);
669   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 11, 10, BFZqcsInterval);
670   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 14, 14, BFDisDramInterface);
671   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 21, 21, BFFreqChgInProg);
672
673   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8),  5,  5, BFSubMemclkRegDly);
674   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 15,  8, BFCtrlWordCS);
675
676   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 31, 0, BFDctSelBaseAddrReg);
677   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x114), 31, 0, BFDctSelBaseOffsetReg);
678
679   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x200), 31,  0, BFDramTiming0);
680   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x204), 31,  0, BFDramTiming1);
681   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x208), 31,  0, BFDramTiming2);
682   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x20C), 31,  0, BFDramTiming3);
683   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x210), 31,  0, BFDramNBP0);
684   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x210), 31, 22, BFMaxLatency);
685   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x214), 31,  0, BFDramTiming4);
686   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x218), 31,  0, BFDramTiming5);
687   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x21C), 31,  0, BFDramTiming6);
688   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x22C), 31,  0, BFDramTiming10);
689
690   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x230), 31,  0, BFPhyRODTCSLow);
691   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x234), 31,  0, BFPhyRODTCSHigh);
692   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x238), 31,  0, BFPhyWODTCSLow);
693   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x23C), 31,  0, BFPhyWODTCSHigh);
694
695   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x240), 31,  0, BFDramODTCtlReg);
696
697   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x250),  3,  2, BFCmdTestEnable);
698   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x250),  7,  5, BFCmdType);
699   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x250), 10, 10, BFTestStatus);
700   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x250), 11, 11, BFSendCmd);
701   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x250), 12, 12, BFCmdSendInProg);
702
703   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x254), 26, 24, BFTgtChipSelectA );
704
705   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x260), 20,  0, BFCmdCount);
706
707   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x268), 17,  0, BFNibbleErrSts);
708
709   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x270), 18,  0, BFDataPrbsSeed);
710
711   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x28C), 31,  0, BFDramCmd2Reg);
712
713   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x160),  5,  1, BFNbFid);
714   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x160),  7,  7, BFNbDid);
715   MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (5, 0x170), 14, 14, BFSwNbPstateLoDis);
716
717   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 31,  0, BFODCControl);
718   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x04, 31,  0, BFAddrTmgControl);
719
720   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08,  0,  0, BFWrtLvTrEn);
721   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08,  1,  1, BFWrtLvTrMode);
722   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08,  5,  4, BFTrDimmSel);
723   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 11,  8, BFWrLvOdt);
724   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 12, 12, BFWrLvOdtEn);
725   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 13, 13, BFDqsRcvTrEn);
726
727   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0B, 31,  0, BFDramPhyStatusReg);
728
729   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0C, 31, 16, BFPhyFence);
730
731   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS,  0x0D0FE013, _NOT_USED_, _NOT_USED_, BFPllRegWaitTime);
732   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS,  0x0D0FE006, _NOT_USED_, _NOT_USED_, BFPllLockTime);
733
734   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS,  0x0D0F0F1F, _NOT_USED_, _NOT_USED_, BFDataRxVioLvl);
735   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS,  0x0D0F2F1F, _NOT_USED_, _NOT_USED_, BFClkRxVioLvl);
736   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS,  0x0D0F4009, _NOT_USED_, _NOT_USED_, BFCmpVioLvl);
737   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS,  0x0D0F8F1F, _NOT_USED_, _NOT_USED_, BFCmdRxVioLvl);
738   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS,  0x0D0FC01F, _NOT_USED_, _NOT_USED_, BFAddrRxVioLvl);
739
740   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS,  0x0D0F0F30, _NOT_USED_, _NOT_USED_, BFBlockRxDqsLock);
741 //DMACH
742   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS,  0x0D0FE003, _NOT_USED_, _NOT_USED_, BFDisablePredriverCal);
743
744   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00,  2,  0, BFCkeDrvStren);
745   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00,  6,  4, BFCsOdtDrvStren);
746   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 10,  8, BFAddrCmdDrvStren);
747   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 14, 12, BFClkDrvStren);
748   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 18, 16, BFDataDrvStren);
749   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 22, 20, BFDqsDrvStren);
750
751   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D08E003, _NOT_USED_, _NOT_USED_, BFDisablePredriverCal);
752   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D0F0F02, _NOT_USED_, _NOT_USED_, BFDataByteTxPreDriverCal);
753   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D0F0F06, _NOT_USED_, _NOT_USED_, BFDataByteTxPreDriverCal2Pad1);
754   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D0F0F0A, _NOT_USED_, _NOT_USED_, BFDataByteTxPreDriverCal2Pad2);
755   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D0F8006, _NOT_USED_, _NOT_USED_, BFCmdAddr0TxPreDriverCal2Pad1);
756   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D0F800A, _NOT_USED_, _NOT_USED_, BFCmdAddr0TxPreDriverCal2Pad2);
757   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D0F8106, _NOT_USED_, _NOT_USED_, BFCmdAddr1TxPreDriverCal2Pad1);
758   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D0F810A, _NOT_USED_, _NOT_USED_, BFCmdAddr1TxPreDriverCal2Pad2);
759   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D0FC006, _NOT_USED_, _NOT_USED_, BFAddrTxPreDriverCal2Pad1);
760   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D0FC00A, _NOT_USED_, _NOT_USED_, BFAddrTxPreDriverCal2Pad2);
761   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D0FC00E, _NOT_USED_, _NOT_USED_, BFAddrTxPreDriverCal2Pad3);
762   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D0FC012, _NOT_USED_, _NOT_USED_, BFAddrTxPreDriverCal2Pad4);
763   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D0F8002, _NOT_USED_, _NOT_USED_, BFCmdAddr0TxPreDriverCalPad0);
764   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D0F8102, _NOT_USED_, _NOT_USED_, BFCmdAddr1TxPreDriverCalPad0);
765   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D0FC002, _NOT_USED_, _NOT_USED_, BFAddrTxPreDriverCalPad0);
766   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D0F2002, _NOT_USED_, _NOT_USED_, BFClock0TxPreDriverCalPad0);
767   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D0F2102, _NOT_USED_, _NOT_USED_, BFClock1TxPreDriverCalPad0);
768   MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x0D0F2202, _NOT_USED_, _NOT_USED_, BFClock2TxPreDriverCalPad0);
769 }
770
771 /*-----------------------------------------------------------------------------*/
772 /**
773  *     MemRecNIsIdSupportedOr
774  *      This function matches the CPU_LOGICAL_ID with certain criteria to
775  *      determine if it is supported by this NBBlock.
776  *
777  *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
778  *     @param[in]       *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID
779  *
780  *     @return          TRUE -  This node is a Orochi.
781  *     @return          FALSE - This node is not a Orochi.
782  *
783  */
784 BOOLEAN
785 STATIC
786 MemRecNIsIdSupportedOr (
787   IN OUT   MEM_NB_BLOCK *NBPtr,
788   IN       CPU_LOGICAL_ID *LogicalIdPtr
789   )
790 {
791   if (((LogicalIdPtr->Family & AMD_FAMILY_15_OR) != 0)
792       && ((LogicalIdPtr->Revision & AMD_F15_ALL) != 0)) {
793     return TRUE;
794   } else {
795     return FALSE;
796   }
797 }
798