blob: 101c3ecbb7b90c475c386f31d14dce27747d19bd [file] [log] [blame]
Frank Vibrans2b4c8312011-02-14 18:30:54 +00001/* $NoKeywords:$ */
2/**
3 * @file
4 *
5 * mnreg.c
6 *
7 * Common Northbridge register access functions
8 *
9 * @xrefitem bom "File Content Label" "Release Content"
10 * @e project: AGESA
11 * @e sub-project: (Mem/NB/)
12 * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
13 *
14 **/
15/*
16 *****************************************************************************
17 *
18 * Copyright (c) 2011, Advanced Micro Devices, Inc.
19 * All rights reserved.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100020 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000021 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions are met:
23 * * Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * * Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100028 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
29 * its contributors may be used to endorse or promote products derived
Frank Vibrans2b4c8312011-02-14 18:30:54 +000030 * from this software without specific prior written permission.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100031 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000032 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
36 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100042 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000043 * ***************************************************************************
44 *
45 */
46/*
47 *----------------------------------------------------------------------------
48 * MODULES USED
49 *
50 *----------------------------------------------------------------------------
51 */
52
53
54
55#include "AGESA.h"
56#include "AdvancedApi.h"
57#include "amdlib.h"
58#include "Ids.h"
59#include "mm.h"
60#include "mn.h"
61#include "merrhdl.h"
62#include "Filecode.h"
63#include "GeneralServices.h"
64CODE_GROUP (G1_PEICC)
65RDATA_GROUP (G1_PEICC)
66
67#define FILECODE PROC_MEM_NB_MNREG_FILECODE
68
69
70/*----------------------------------------------------------------------------
71 * DEFINITIONS AND MACROS
72 *
73 *----------------------------------------------------------------------------
74 */
75/*----------------------------------------------------------------------------
76 * TYPEDEFS AND STRUCTURES
77 *
78 *----------------------------------------------------------------------------
79 */
80
81/*----------------------------------------------------------------------------
82 * PROTOTYPES OF LOCAL FUNCTIONS
83 *
84 *----------------------------------------------------------------------------
85 */
86
87/*----------------------------------------------------------------------------
88 * EXPORTED FUNCTIONS
89 *
90 *----------------------------------------------------------------------------
91 */
92
93/* -----------------------------------------------------------------------------*/
94/**
95 *
96 *
97 * This function sets the current DCT to work on.
98 * Should be called before accessing a certain DCT
99 * All data structures will be updated to point to the current DCT
100 *
101 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
102 * @param[in] Dct - ID of the target DCT
103 *
104 */
105
106VOID
107MemNSwitchDCTNb (
108 IN OUT MEM_NB_BLOCK *NBPtr,
109 IN UINT8 Dct
110 )
111{
112 ASSERT (NBPtr->DctCount > Dct);
113 //
114 // Set the DctCfgSel to new DCT
115 //
116 NBPtr->FamilySpecificHook[DCTSelectSwitch] (NBPtr, &Dct);
117 NBPtr->Dct = Dct ? 1 : 0;
118 NBPtr->MCTPtr->Dct = NBPtr->Dct;
119 NBPtr->DCTPtr = &(NBPtr->MCTPtr->DctData[NBPtr->Dct]);
120 NBPtr->PsPtr = &(NBPtr->PSBlock[NBPtr->Dct]);
121 NBPtr->DctCachePtr = &(NBPtr->DctCache[NBPtr->Dct]);
122
123 MemNSwitchChannelNb (NBPtr, NBPtr->Channel);
124}
125
126/* -----------------------------------------------------------------------------*/
127/**
128 *
129 * This function is used by families that use a separate DctCfgSel bit to
130 * select the current DCT which will be accessed by function 2.
131 * NOTE: This function must be called BEFORE the NBPtr->Dct variable is
132 * updated.
133 *
134 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
135 * @param[in] *Dct - Pointer to ID of the target DCT
136 *
137 */
138
139BOOLEAN
140MemNDctCfgSelectUnb (
141 IN OUT MEM_NB_BLOCK *NBPtr,
142 IN VOID *Dct
143 )
144{
145 //
146 // Sanity check the current DctCfgSel setting
147 //
148 ASSERT (NBPtr->Dct == NBPtr->GetBitField (NBPtr, BFDctCfgSel));
149 //
150 // Set the DctCfgSel to new DCT
151 //
152 NBPtr->SetBitField (NBPtr, BFDctCfgSel, *(UINT8*)Dct);
153
154 return TRUE;
155}
156
157
158/* -----------------------------------------------------------------------------*/
159/**
160 *
161 *
162 * This function sets the current channel to work on.
163 * Should be called before accessing a certain channel
164 * All data structures will be updated to point to the current channel
165 *
166 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
167 * @param[in] Channel - ID of the target channel
168 *
169 */
170
171VOID
172MemNSwitchChannelNb (
173 IN OUT MEM_NB_BLOCK *NBPtr,
174 IN UINT8 Channel
175 )
176{
177 NBPtr->Channel = Channel ? 1 : 0;
178 NBPtr->ChannelPtr = &(NBPtr->DCTPtr->ChData[NBPtr->Channel]);
179}
180
181/* -----------------------------------------------------------------------------*/
182/**
183 *
184 *
185 * This function gets a bit field from PCI register
186 *
187 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
188 * @param[in] FieldName - Field name
189 *
190 * @return Bit field value
191 */
192
193UINT32
194MemNGetBitFieldNb (
195 IN OUT MEM_NB_BLOCK *NBPtr,
196 IN BIT_FIELD_NAME FieldName
197 )
198{
199 UINT32 Value;
200
201 ASSERT (FieldName < BFEndOfList);
202 Value = NBPtr->MemNCmnGetSetFieldNb (NBPtr, 0, FieldName, 0);
203 return Value;
204}
205
206/* -----------------------------------------------------------------------------*/
207/**
208 *
209 *
210 * This function sets a bit field from PCI register
211 *
212 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
213 * @param[in] FieldName - Field name
214 * @param[in] Field - Value to be stored in PCT register
215 *
216 */
217
218VOID
219MemNSetBitFieldNb (
220 IN OUT MEM_NB_BLOCK *NBPtr,
221 IN BIT_FIELD_NAME FieldName,
222 IN UINT32 Field
223 )
224{
225 ASSERT (FieldName < BFEndOfList);
226 NBPtr->MemNCmnGetSetFieldNb (NBPtr, 1, FieldName, Field);
227}
228
229/* -----------------------------------------------------------------------------*/
230/**
231 *
232 * Check if bitfields of all enabled DCTs on a die have the expected value. Ignore
233 * DCTs that are disabled.
234 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
235 * @param[in] FieldName - Bit Field name
236 * @param[in] Field - Value to be checked
237 *
238 * @return TRUE - All enabled DCTs have the expected value on the bitfield.
239 * @return FALSE - Not all enabled DCTs have the expected value on the bitfield.
240 *
241 * ----------------------------------------------------------------------------
242 */
243BOOLEAN
244MemNBrdcstCheckNb (
245 IN OUT MEM_NB_BLOCK *NBPtr,
246 IN BIT_FIELD_NAME FieldName,
247 IN UINT32 Field
248 )
249{
250 UINT8 Dct;
251 UINT8 CurrentDCT;
252 Dct = NBPtr->Dct;
253 for (CurrentDCT = 0; CurrentDCT < NBPtr->DctCount; CurrentDCT++) {
254 MemNSwitchDCTNb (NBPtr, CurrentDCT);
255 if ((NBPtr->DCTPtr->Timings.DctMemSize != 0) && !((CurrentDCT == 1) && NBPtr->Ganged)) {
256 if (MemNGetBitFieldNb (NBPtr, FieldName) != Field) {
257 MemNSwitchDCTNb (NBPtr, Dct);
258 return FALSE;
259 }
260 }
261 }
262 MemNSwitchDCTNb (NBPtr, Dct);
263 return TRUE;
264}
265
266/* -----------------------------------------------------------------------------*/
267/**
268 *
269 * Set bitfields of all enabled DCTs on a die to a value. Ignore
270 * DCTs that are disabled.
271 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
272 * @param[in] FieldName - Bit Field name
273 * @param[in] Field - Value to be set
274 *
275 * ----------------------------------------------------------------------------
276 */
277VOID
278MemNBrdcstSetNb (
279 IN OUT MEM_NB_BLOCK *NBPtr,
280 IN BIT_FIELD_NAME FieldName,
281 IN UINT32 Field
282 )
283{
284 UINT8 Dct;
285 UINT8 CurrentDCT;
286 Dct = NBPtr->Dct;
287 for (CurrentDCT = 0; CurrentDCT < NBPtr->DctCount; CurrentDCT++) {
288 MemNSwitchDCTNb (NBPtr, CurrentDCT);
289 if ((NBPtr->DCTPtr->Timings.DctMemSize != 0) && !((CurrentDCT == 1) && NBPtr->Ganged)) {
290 MemNSetBitFieldNb (NBPtr, FieldName, Field);
291 }
292 }
293 MemNSwitchDCTNb (NBPtr, Dct);
294}
295
296/*-----------------------------------------------------------------------------*/
297/**
298 * This function calculates the memory channel index relative to the
299 * socket, taking the Die number, the Dct, and the channel.
300 *
301 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
302 * @param[in] Dct
303 * @param[in] Channel
304 *
305 */
306UINT8
307MemNGetSocketRelativeChannelNb (
308 IN OUT MEM_NB_BLOCK *NBPtr,
309 IN UINT8 Dct,
310 IN UINT8 Channel
311 )
312{
313 return ((NBPtr->MCTPtr->DieId *NBPtr->DctCount) + Dct);
314}
315
316/* -----------------------------------------------------------------------------*/
317/**
318 *
319 * Poll a bitfield. If the bitfield does not get set to the target value within
320 * specified microseconds, it times out.
321 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
322 * @param[in] FieldName - Bit Field name
323 * @param[in] Field - Value to be set
324 * @param[in] MicroSecond - Number of microsecond to wait
325 * @param[in] IfBroadCast - Need to broadcast to both DCT or not
326 *
327 * ----------------------------------------------------------------------------
328 */
329VOID
330MemNPollBitFieldNb (
331 IN OUT MEM_NB_BLOCK *NBPtr,
332 IN BIT_FIELD_NAME FieldName,
333 IN UINT32 Field,
334 IN UINT32 MicroSecond,
335 IN BOOLEAN IfBroadCast
336 )
337{
338 UINT8 ExcludeDCT;
339 UINT16 ExcludeChipSelMask;
340 UINT32 EventInfo;
341 UINT64 InitTSC;
342 UINT64 CurrentTSC;
343 UINT64 TimeOut;
344 AGESA_STATUS EventClass;
345 MEM_DATA_STRUCT *MemPtr;
346 DIE_STRUCT *MCTPtr;
347 BOOLEAN TimeoutEn;
348
349 MemPtr = NBPtr->MemPtr;
350 MCTPtr = NBPtr->MCTPtr;
351 ExcludeDCT = EXCLUDE_ALL_DCT;
352 ExcludeChipSelMask = EXCLUDE_ALL_CHIPSEL;
353 TimeoutEn = TRUE;
354 IDS_TIMEOUT_CTL (&TimeoutEn);
355
356 CurrentTSC = 0;
357 LibAmdMsrRead (TSC, &InitTSC, &MemPtr->StdHeader);
358 TimeOut = InitTSC + ((UINT64) MicroSecond * 1600);
359
360 while ((CurrentTSC < TimeOut) || !TimeoutEn) {
361 if (IfBroadCast) {
362 if (NBPtr->BrdcstCheck (NBPtr, FieldName, Field)) {
363 break;
364 }
365 } else {
366 if (MemNGetBitFieldNb (NBPtr, FieldName) == Field) {
367 break;
368 }
369 }
370 LibAmdMsrRead (TSC, &CurrentTSC, &MemPtr->StdHeader);
371 }
372
373 if ((CurrentTSC >= TimeOut) && TimeoutEn) {
374 // Default event class
375 // If different event class is needed in one entry, override it.
376 EventClass = AGESA_ERROR;
377 switch (FieldName) {
378 case BFDramEnabled:
379 EventInfo = MEM_ERROR_DRAM_ENABLED_TIME_OUT;
380 break;
381 case BFDctAccessDone:
382 EventInfo = MEM_ERROR_DCT_ACCESS_DONE_TIME_OUT;
383 ExcludeDCT = NBPtr->Dct;
384 break;
385 case BFSendCtrlWord:
386 EventInfo = MEM_ERROR_SEND_CTRL_WORD_TIME_OUT;
387 ExcludeDCT = NBPtr->Dct;
388 break;
389 case BFPrefDramTrainMode:
390 EventInfo = MEM_ERROR_PREF_DRAM_TRAIN_MODE_TIME_OUT;
391 ExcludeDCT = NBPtr->Dct;
392 break;
393 case BFEnterSelfRef:
394 EventInfo = MEM_ERROR_ENTER_SELF_REF_TIME_OUT;
395 break;
396 case BFFreqChgInProg:
397 EventInfo = MEM_ERROR_FREQ_CHG_IN_PROG_TIME_OUT;
398 ExcludeDCT = NBPtr->Dct;
399 break;
400 case BFExitSelfRef:
401 EventInfo = MEM_ERROR_EXIT_SELF_REF_TIME_OUT;
402 break;
403 case BFSendMrsCmd:
404 EventInfo = MEM_ERROR_SEND_MRS_CMD_TIME_OUT;
405 ExcludeDCT = NBPtr->Dct;
406 break;
407 case BFSendZQCmd:
408 EventInfo = MEM_ERROR_SEND_ZQ_CMD_TIME_OUT;
409 ExcludeDCT = NBPtr->Dct;
410 break;
411 case BFDctExtraAccessDone:
412 EventInfo = MEM_ERROR_DCT_EXTRA_ACCESS_DONE_TIME_OUT;
413 ExcludeDCT = NBPtr->Dct;
414 break;
415 case BFMemClrBusy:
416 EventInfo = MEM_ERROR_MEM_CLR_BUSY_TIME_OUT;
417 break;
418 case BFMemCleared:
419 EventInfo = MEM_ERROR_MEM_CLEARED_TIME_OUT;
420 break;
421 case BFFlushWr:
422 EventInfo = MEM_ERROR_FLUSH_WR_TIME_OUT;
423 ExcludeDCT = NBPtr->Dct;
424 break;
425 default:
426 EventClass = 0;
427 EventInfo = 0;
428 IDS_ERROR_TRAP;
429 }
430
431 PutEventLog (EventClass, EventInfo, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &MemPtr->StdHeader);
432 SetMemError (EventClass, MCTPtr);
433 MemPtr->ErrorHandling (MCTPtr, ExcludeDCT, ExcludeChipSelMask, &MemPtr->StdHeader);
434 }
435}
436
437