2 HTE handling routines for MRC use.
4 Copyright (c) 2013-2015 Intel Corporation.
6 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include "memory_options.h"
18 VOID
delay_n(UINT32 nanoseconds
);
19 #define MySimStall(a) delay_n(a/1000)
22 STATIC VOID
EnableAllHteErrors(
28 This function enables to HTE to detect all possible errors for
29 the given training parameters (per-bit or full byte lane).
37 isbW32m(HTE
, 0x000200A2, 0xFFFFFFFF);
38 isbW32m(HTE
, 0x000200A3, 0x000000FF);
39 isbW32m(HTE
, 0x000200A4, 0x00000000);
42 STATIC UINT32
CheckHteErrors(
48 This function goes and reads the HTE register in order to find any error
52 The errors detected in the HTE status register
56 return isbR32m(HTE
, 0x000200A7);
59 STATIC VOID
WaitForHteComplete(
65 This function waits until HTE finishes
83 MySimStall (35000); // 35 ns delay
85 } while (0 != (isbR32m(HTE
, 0x00020012) & BIT30
));
87 Tmp
= isbR32m(HTE
, 0x00020011);
89 Tmp
= Tmp
& ~(BIT13
| BIT12
);
90 isbW32m(HTE
, 0x00020011, Tmp
);
95 STATIC VOID
ClearHteErrorRegisters(
101 Clears registers related with errors in the HTE.
112 // Clear all HTE errors and enable error checking
113 // for burst and chunk.
115 Tmp
= isbR32m(HTE
, 0x000200A1);
117 isbW32m(HTE
, 0x000200A1, Tmp
);
121 MRC_PARAMS
*CurrentMrcData
,
123 UINT8 HaltHteEngineOnError
)
129 Uses HW HTE engine to initialize or test all memory attached to a given DUNIT.
130 If MemInitFlag is 1, this routine writes 0s to all memory locations to initialize
132 If MemInitFlag is 0, this routine will send an 5AA55AA5 pattern to all memory
133 locations on the RankMask and then read it back. Then it sends an A55AA55A
134 pattern to all memory locations on the RankMask and reads it back.
138 CurrentMrcData: Host struture for all MRC global data.
139 MemInitFlag: 0 for memtest, 1 for meminit.
140 HaltHteEngineOnError: Halt the HTE engine on first error observed, or keep
141 running to see how many errors are found.
144 Errors register showing HTE failures.
145 Also prints out which rank failed the HTE test if failure occurs.
146 For rank detection to work, the address map must be left in its default
147 state. If MRC changes the address map, this function must be modified
148 to change it back to default at the beginning, then restore it at the end.
157 // Clear out the error registers at the start of each memory
158 // init or memory test run.
160 ClearHteErrorRegisters();
162 isbW32m(HTE
, 0x00020062, 0x00000015);
164 for (Offset
= 0x80; Offset
<= 0x8F; Offset
++)
166 isbW32m(HTE
, Offset
, ((Offset
& 1) ? 0xA55A : 0x5AA5));
169 isbW32m(HTE
, 0x00020021, 0x00000000);
171 // Just do 4 cache lines for simulation memtest to save time.
172 isbW32m(HTE
, 0x00020022, 4-1);
174 isbW32m(HTE
, 0x00020022, (CurrentMrcData
->mem_size
>> 6) - 1);
177 isbW32m(HTE
, 0x00020063, 0xAAAAAAAA);
178 isbW32m(HTE
, 0x00020064, 0xCCCCCCCC);
179 isbW32m(HTE
, 0x00020065, 0xF0F0F0F0);
180 isbW32m(HTE
, 0x00020066, 0x03000000);
185 TestNum
= 1; // Only 1 write pass through memory is needed to initialize ECC.
188 TestNum
= 4; // Write/read then write/read with inverted pattern.
191 DPF(D_INFO
, "Unknown parameter for MemInitFlag: %d\n", MemInitFlag
);
196 DPF(D_INFO
, "HteMemInit");
197 for (i
= 0; i
< TestNum
; i
++)
203 isbW32m(HTE
, 0x00020061, 0x00000000);
204 isbW32m(HTE
, 0x00020020, 0x00110010);
208 isbW32m(HTE
, 0x00020061, 0x00000000);
209 isbW32m(HTE
, 0x00020020, 0x00010010);
213 isbW32m(HTE
, 0x00020061, 0x00010100);
214 isbW32m(HTE
, 0x00020020, 0x00110010);
218 isbW32m(HTE
, 0x00020061, 0x00010100);
219 isbW32m(HTE
, 0x00020020, 0x00010010);
222 isbW32m(HTE
, 0x00020011, 0x00111000);
223 isbW32m(HTE
, 0x00020011, 0x00111100);
225 WaitForHteComplete();
228 // If this is a READ pass, check for errors at the end.
233 // Return immediately if error.
235 if (CheckHteErrors())
242 DPF(D_INFO
, "done\n", i
);
243 return CheckHteErrors();
246 STATIC UINT16
BasicDataCompareHte(
247 MRC_PARAMS
*CurrentMrcData
,
255 Execute basic single cache line memory write/read/verify test using simple constant
256 pattern (different for READ_RAIN and WRITE_TRAIN modes.
257 See BasicWriteReadHTE which is external visible wrapper.
261 CurrentMrcData: Host struture for all MRC global data.
262 Address: memory adress being tested (must hit specific channel/rank)
263 FirstRun: If set then hte registers are configured, otherwise
264 it is assumed configuration is done and just re-run the test.
265 Mode: READ_TRAIN or WRITE_TRAIN (the difference is in the pattern)
268 Returns byte lane failure on each bit (for Quark only bit0 and bit1)
277 isbW32m(HTE
, 0x00020020, 0x01B10021);
278 isbW32m(HTE
, 0x00020021, 0x06000000);
279 isbW32m(HTE
, 0x00020022, Address
>> 6);
280 isbW32m(HTE
, 0x00020062, 0x00800015);
281 isbW32m(HTE
, 0x00020063, 0xAAAAAAAA);
282 isbW32m(HTE
, 0x00020064, 0xCCCCCCCC);
283 isbW32m(HTE
, 0x00020065, 0xF0F0F0F0);
284 isbW32m(HTE
, 0x00020061, 0x00030008);
286 if (Mode
== WRITE_TRAIN
)
288 Pattern
= 0xC33C0000;
292 Pattern
= 0xAA5555AA;
295 for (Offset
= 0x80; Offset
<= 0x8F; Offset
++)
297 isbW32m(HTE
, Offset
, Pattern
);
301 isbW32m(HTE
, 0x000200A1, 0xFFFF1000);
303 isbW32m(HTE
, 0x00020011, 0x00011000);
304 isbW32m(HTE
, 0x00020011, 0x00011100);
306 WaitForHteComplete();
309 // Return bits 15:8 of HTE_CH0_ERR_XSTAT to check for any bytelane errors.
311 return ((CheckHteErrors() >> 8) & 0xFF);
314 STATIC UINT16
ReadWriteDataCompareHte(
315 MRC_PARAMS
*CurrentMrcData
,
318 UINT32 LfsrSeedVictim
,
319 UINT32 LfsrSeedAggressor
,
326 Examines single cache line memory with write/read/verify test using
327 multiple data patterns (victim-aggressor algorithm).
328 See WriteStressBitLanesHTE which is external visible wrapper.
332 CurrentMrcData: host struture for all MRC global data.
333 Address: memory adress being tested (must hit specific channel/rank)
334 LoopCount: number of test iterations
335 LfsrSeedXxx: victim aggressor data pattern seed
336 VictimBit: should be 0 as auto rotate feature is in use.
337 FirstRun: If set then hte registers are configured, otherwise
338 it is assumed configuration is done and just re-run the test.
341 Returns byte lane failure on each bit (for Quark only bit0 and bit1)
350 isbW32m(HTE
, 0x00020020, 0x00910024);
351 isbW32m(HTE
, 0x00020023, 0x00810024);
352 isbW32m(HTE
, 0x00020021, 0x06070000);
353 isbW32m(HTE
, 0x00020024, 0x06070000);
354 isbW32m(HTE
, 0x00020022, Address
>> 6);
355 isbW32m(HTE
, 0x00020025, Address
>> 6);
356 isbW32m(HTE
, 0x00020062, 0x0000002A);
357 isbW32m(HTE
, 0x00020063, LfsrSeedVictim
);
358 isbW32m(HTE
, 0x00020064, LfsrSeedAggressor
);
359 isbW32m(HTE
, 0x00020065, LfsrSeedVictim
);
362 // Write the pattern buffers to select the victim bit. Start with bit0.
364 for (Offset
= 0x80; Offset
<= 0x8F; Offset
++)
366 if ((Offset
% 8) == VictimBit
)
368 isbW32m(HTE
, Offset
, 0x55555555);
372 isbW32m(HTE
, Offset
, 0xCCCCCCCC);
376 isbW32m(HTE
, 0x00020061, 0x00000000);
377 isbW32m(HTE
, 0x00020066, 0x03440000);
378 isbW32m(HTE
, 0x000200A1, 0xFFFF1000);
381 Tmp
= 0x10001000 | (LoopCount
<< 16);
382 isbW32m(HTE
, 0x00020011, Tmp
);
383 isbW32m(HTE
, 0x00020011, Tmp
| BIT8
);
385 WaitForHteComplete();
387 return (CheckHteErrors() >> 8) & 0xFF;
390 UINT16
BasicWriteReadHTE(
391 MRC_PARAMS
*CurrentMrcData
,
399 Execute basic single cache line memory write/read/verify test using simple constant
400 pattern (different for READ_RAIN and WRITE_TRAIN modes.
404 CurrentMrcData: Host struture for all MRC global data.
405 Address: memory adress being tested (must hit specific channel/rank)
406 FirstRun: If set then hte registers are configured, otherwise
407 it is assumed configuration is done and just re-run the test.
408 Mode: READ_TRAIN or WRITE_TRAIN (the difference is in the pattern)
411 Returns byte lane failure on each bit (for Quark only bit0 and bit1)
415 UINT16 ByteLaneErrors
;
420 // Enable all error reporting in preparation for HTE test.
422 EnableAllHteErrors(0xFF);
423 ClearHteErrorRegisters();
425 ByteLaneErrors
= BasicDataCompareHte(CurrentMrcData
, Address
, FirstRun
,
429 return ByteLaneErrors
;
432 UINT16
WriteStressBitLanesHTE(
433 MRC_PARAMS
*CurrentMrcData
,
440 Examines single cache line memory with write/read/verify test using
441 multiple data patterns (victim-aggressor algorithm).
445 CurrentMrcData: host struture for all MRC global data.
446 Address: memory adress being tested (must hit specific channel/rank)
447 FirstRun: If set then hte registers are configured, otherwise
448 it is assumed configuration is done and just re-run the test.
451 Returns byte lane failure on each bit (for Quark only bit0 and bit1)
455 UINT16 ByteLaneErrors
;
461 // Enable all error reporting in preparation for HTE test.
463 EnableAllHteErrors(0xFF);
464 ClearHteErrorRegisters();
467 // Loop through each bit in the bytelane. Each pass creates a victim bit
468 // while keeping all other bits the same - as aggressors.
469 // AVN HTE adds an auto-rotate feature which allows us to program the entire victim/aggressor
470 // sequence in 1 step. The victim bit rotates on each pass so no need to have software implement
471 // a victim bit loop like on VLV.
473 ByteLaneErrors
= ReadWriteDataCompareHte(CurrentMrcData
, Address
,
474 HTE_LOOP_CNT
, HTE_LFSR_VICTIM_SEED
, HTE_LFSR_AGRESSOR_SEED
, VictimBit
,
478 return ByteLaneErrors
;
489 Execute basic single cache line memory write or read.
490 This is just for receive enable / fine write levelling purpose.
494 CurrentMrcData: Host structure for all MRC global data.
495 Address: memory address used (must hit specific channel/rank)
496 FirstRun: If set then hte registers are configured, otherwise
497 it is assumed configuration is done and just re-run the test.
498 IsWrite: When non-zero memory write operation executed, otherwise read
508 EnableAllHteErrors(0xFF);
509 ClearHteErrorRegisters();
513 Tmp
= IsWrite
? 0x01110021 : 0x01010021;
514 isbW32m(HTE
, 0x00020020, Tmp
);
516 isbW32m(HTE
, 0x00020021, 0x06000000);
517 isbW32m(HTE
, 0x00020022, Address
>> 6);
518 isbW32m(HTE
, 0x00020062, 0x00800015);
519 isbW32m(HTE
, 0x00020063, 0xAAAAAAAA);
520 isbW32m(HTE
, 0x00020064, 0xCCCCCCCC);
521 isbW32m(HTE
, 0x00020065, 0xF0F0F0F0);
522 isbW32m(HTE
, 0x00020061, 0x00030008);
524 for (Offset
= 0x80; Offset
<= 0x8F; Offset
++)
526 isbW32m(HTE
, Offset
, 0xC33C0000);
530 isbW32m(HTE
, 0x000200A1, 0xFFFF1000);
531 isbW32m(HTE
, 0x00020011, 0x00011000);
532 isbW32m(HTE
, 0x00020011, 0x00011100);
534 WaitForHteComplete();