2 HTE handling routines for MRC use.
4 Copyright (c) 2013-2015 Intel Corporation.
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "memory_options.h"
24 VOID
delay_n(UINT32 nanoseconds
);
25 #define MySimStall(a) delay_n(a/1000)
28 STATIC VOID
EnableAllHteErrors(
34 This function enables to HTE to detect all possible errors for
35 the given training parameters (per-bit or full byte lane).
43 isbW32m(HTE
, 0x000200A2, 0xFFFFFFFF);
44 isbW32m(HTE
, 0x000200A3, 0x000000FF);
45 isbW32m(HTE
, 0x000200A4, 0x00000000);
48 STATIC UINT32
CheckHteErrors(
54 This function goes and reads the HTE register in order to find any error
58 The errors detected in the HTE status register
62 return isbR32m(HTE
, 0x000200A7);
65 STATIC VOID
WaitForHteComplete(
71 This function waits until HTE finishes
89 MySimStall (35000); // 35 ns delay
91 } while (0 != (isbR32m(HTE
, 0x00020012) & BIT30
));
93 Tmp
= isbR32m(HTE
, 0x00020011);
95 Tmp
= Tmp
& ~(BIT13
| BIT12
);
96 isbW32m(HTE
, 0x00020011, Tmp
);
101 STATIC VOID
ClearHteErrorRegisters(
107 Clears registers related with errors in the HTE.
118 // Clear all HTE errors and enable error checking
119 // for burst and chunk.
121 Tmp
= isbR32m(HTE
, 0x000200A1);
123 isbW32m(HTE
, 0x000200A1, Tmp
);
127 MRC_PARAMS
*CurrentMrcData
,
129 UINT8 HaltHteEngineOnError
)
135 Uses HW HTE engine to initialize or test all memory attached to a given DUNIT.
136 If MemInitFlag is 1, this routine writes 0s to all memory locations to initialize
138 If MemInitFlag is 0, this routine will send an 5AA55AA5 pattern to all memory
139 locations on the RankMask and then read it back. Then it sends an A55AA55A
140 pattern to all memory locations on the RankMask and reads it back.
144 CurrentMrcData: Host struture for all MRC global data.
145 MemInitFlag: 0 for memtest, 1 for meminit.
146 HaltHteEngineOnError: Halt the HTE engine on first error observed, or keep
147 running to see how many errors are found.
150 Errors register showing HTE failures.
151 Also prints out which rank failed the HTE test if failure occurs.
152 For rank detection to work, the address map must be left in its default
153 state. If MRC changes the address map, this function must be modified
154 to change it back to default at the beginning, then restore it at the end.
163 // Clear out the error registers at the start of each memory
164 // init or memory test run.
166 ClearHteErrorRegisters();
168 isbW32m(HTE
, 0x00020062, 0x00000015);
170 for (Offset
= 0x80; Offset
<= 0x8F; Offset
++)
172 isbW32m(HTE
, Offset
, ((Offset
& 1) ? 0xA55A : 0x5AA5));
175 isbW32m(HTE
, 0x00020021, 0x00000000);
177 // Just do 4 cache lines for simulation memtest to save time.
178 isbW32m(HTE
, 0x00020022, 4-1);
180 isbW32m(HTE
, 0x00020022, (CurrentMrcData
->mem_size
>> 6) - 1);
183 isbW32m(HTE
, 0x00020063, 0xAAAAAAAA);
184 isbW32m(HTE
, 0x00020064, 0xCCCCCCCC);
185 isbW32m(HTE
, 0x00020065, 0xF0F0F0F0);
186 isbW32m(HTE
, 0x00020066, 0x03000000);
191 TestNum
= 1; // Only 1 write pass through memory is needed to initialize ECC.
194 TestNum
= 4; // Write/read then write/read with inverted pattern.
197 DPF(D_INFO
, "Unknown parameter for MemInitFlag: %d\n", MemInitFlag
);
202 DPF(D_INFO
, "HteMemInit");
203 for (i
= 0; i
< TestNum
; i
++)
209 isbW32m(HTE
, 0x00020061, 0x00000000);
210 isbW32m(HTE
, 0x00020020, 0x00110010);
214 isbW32m(HTE
, 0x00020061, 0x00000000);
215 isbW32m(HTE
, 0x00020020, 0x00010010);
219 isbW32m(HTE
, 0x00020061, 0x00010100);
220 isbW32m(HTE
, 0x00020020, 0x00110010);
224 isbW32m(HTE
, 0x00020061, 0x00010100);
225 isbW32m(HTE
, 0x00020020, 0x00010010);
228 isbW32m(HTE
, 0x00020011, 0x00111000);
229 isbW32m(HTE
, 0x00020011, 0x00111100);
231 WaitForHteComplete();
234 // If this is a READ pass, check for errors at the end.
239 // Return immediately if error.
241 if (CheckHteErrors())
248 DPF(D_INFO
, "done\n", i
);
249 return CheckHteErrors();
252 STATIC UINT16
BasicDataCompareHte(
253 MRC_PARAMS
*CurrentMrcData
,
261 Execute basic single cache line memory write/read/verify test using simple constant
262 pattern (different for READ_RAIN and WRITE_TRAIN modes.
263 See BasicWriteReadHTE which is external visible wrapper.
267 CurrentMrcData: Host struture for all MRC global data.
268 Address: memory adress being tested (must hit specific channel/rank)
269 FirstRun: If set then hte registers are configured, otherwise
270 it is assumed configuration is done and just re-run the test.
271 Mode: READ_TRAIN or WRITE_TRAIN (the difference is in the pattern)
274 Returns byte lane failure on each bit (for Quark only bit0 and bit1)
283 isbW32m(HTE
, 0x00020020, 0x01B10021);
284 isbW32m(HTE
, 0x00020021, 0x06000000);
285 isbW32m(HTE
, 0x00020022, Address
>> 6);
286 isbW32m(HTE
, 0x00020062, 0x00800015);
287 isbW32m(HTE
, 0x00020063, 0xAAAAAAAA);
288 isbW32m(HTE
, 0x00020064, 0xCCCCCCCC);
289 isbW32m(HTE
, 0x00020065, 0xF0F0F0F0);
290 isbW32m(HTE
, 0x00020061, 0x00030008);
292 if (Mode
== WRITE_TRAIN
)
294 Pattern
= 0xC33C0000;
298 Pattern
= 0xAA5555AA;
301 for (Offset
= 0x80; Offset
<= 0x8F; Offset
++)
303 isbW32m(HTE
, Offset
, Pattern
);
307 isbW32m(HTE
, 0x000200A1, 0xFFFF1000);
309 isbW32m(HTE
, 0x00020011, 0x00011000);
310 isbW32m(HTE
, 0x00020011, 0x00011100);
312 WaitForHteComplete();
315 // Return bits 15:8 of HTE_CH0_ERR_XSTAT to check for any bytelane errors.
317 return ((CheckHteErrors() >> 8) & 0xFF);
320 STATIC UINT16
ReadWriteDataCompareHte(
321 MRC_PARAMS
*CurrentMrcData
,
324 UINT32 LfsrSeedVictim
,
325 UINT32 LfsrSeedAggressor
,
332 Examines single cache line memory with write/read/verify test using
333 multiple data patterns (victim-aggressor algorithm).
334 See WriteStressBitLanesHTE which is external visible wrapper.
338 CurrentMrcData: host struture for all MRC global data.
339 Address: memory adress being tested (must hit specific channel/rank)
340 LoopCount: number of test iterations
341 LfsrSeedXxx: victim aggressor data pattern seed
342 VictimBit: should be 0 as auto rotate feature is in use.
343 FirstRun: If set then hte registers are configured, otherwise
344 it is assumed configuration is done and just re-run the test.
347 Returns byte lane failure on each bit (for Quark only bit0 and bit1)
356 isbW32m(HTE
, 0x00020020, 0x00910024);
357 isbW32m(HTE
, 0x00020023, 0x00810024);
358 isbW32m(HTE
, 0x00020021, 0x06070000);
359 isbW32m(HTE
, 0x00020024, 0x06070000);
360 isbW32m(HTE
, 0x00020022, Address
>> 6);
361 isbW32m(HTE
, 0x00020025, Address
>> 6);
362 isbW32m(HTE
, 0x00020062, 0x0000002A);
363 isbW32m(HTE
, 0x00020063, LfsrSeedVictim
);
364 isbW32m(HTE
, 0x00020064, LfsrSeedAggressor
);
365 isbW32m(HTE
, 0x00020065, LfsrSeedVictim
);
368 // Write the pattern buffers to select the victim bit. Start with bit0.
370 for (Offset
= 0x80; Offset
<= 0x8F; Offset
++)
372 if ((Offset
% 8) == VictimBit
)
374 isbW32m(HTE
, Offset
, 0x55555555);
378 isbW32m(HTE
, Offset
, 0xCCCCCCCC);
382 isbW32m(HTE
, 0x00020061, 0x00000000);
383 isbW32m(HTE
, 0x00020066, 0x03440000);
384 isbW32m(HTE
, 0x000200A1, 0xFFFF1000);
387 Tmp
= 0x10001000 | (LoopCount
<< 16);
388 isbW32m(HTE
, 0x00020011, Tmp
);
389 isbW32m(HTE
, 0x00020011, Tmp
| BIT8
);
391 WaitForHteComplete();
393 return (CheckHteErrors() >> 8) & 0xFF;
396 UINT16
BasicWriteReadHTE(
397 MRC_PARAMS
*CurrentMrcData
,
405 Execute basic single cache line memory write/read/verify test using simple constant
406 pattern (different for READ_RAIN and WRITE_TRAIN modes.
410 CurrentMrcData: Host struture for all MRC global data.
411 Address: memory adress being tested (must hit specific channel/rank)
412 FirstRun: If set then hte registers are configured, otherwise
413 it is assumed configuration is done and just re-run the test.
414 Mode: READ_TRAIN or WRITE_TRAIN (the difference is in the pattern)
417 Returns byte lane failure on each bit (for Quark only bit0 and bit1)
421 UINT16 ByteLaneErrors
;
426 // Enable all error reporting in preparation for HTE test.
428 EnableAllHteErrors(0xFF);
429 ClearHteErrorRegisters();
431 ByteLaneErrors
= BasicDataCompareHte(CurrentMrcData
, Address
, FirstRun
,
435 return ByteLaneErrors
;
438 UINT16
WriteStressBitLanesHTE(
439 MRC_PARAMS
*CurrentMrcData
,
446 Examines single cache line memory with write/read/verify test using
447 multiple data patterns (victim-aggressor algorithm).
451 CurrentMrcData: host struture for all MRC global data.
452 Address: memory adress being tested (must hit specific channel/rank)
453 FirstRun: If set then hte registers are configured, otherwise
454 it is assumed configuration is done and just re-run the test.
457 Returns byte lane failure on each bit (for Quark only bit0 and bit1)
461 UINT16 ByteLaneErrors
;
467 // Enable all error reporting in preparation for HTE test.
469 EnableAllHteErrors(0xFF);
470 ClearHteErrorRegisters();
473 // Loop through each bit in the bytelane. Each pass creates a victim bit
474 // while keeping all other bits the same - as aggressors.
475 // AVN HTE adds an auto-rotate feature which allows us to program the entire victim/aggressor
476 // sequence in 1 step. The victim bit rotates on each pass so no need to have software implement
477 // a victim bit loop like on VLV.
479 ByteLaneErrors
= ReadWriteDataCompareHte(CurrentMrcData
, Address
,
480 HTE_LOOP_CNT
, HTE_LFSR_VICTIM_SEED
, HTE_LFSR_AGRESSOR_SEED
, VictimBit
,
484 return ByteLaneErrors
;
495 Execute basic single cache line memory write or read.
496 This is just for receive enable / fine write levelling purpose.
500 CurrentMrcData: Host structure for all MRC global data.
501 Address: memory address used (must hit specific channel/rank)
502 FirstRun: If set then hte registers are configured, otherwise
503 it is assumed configuration is done and just re-run the test.
504 IsWrite: When non-zero memory write operation executed, otherwise read
514 EnableAllHteErrors(0xFF);
515 ClearHteErrorRegisters();
519 Tmp
= IsWrite
? 0x01110021 : 0x01010021;
520 isbW32m(HTE
, 0x00020020, Tmp
);
522 isbW32m(HTE
, 0x00020021, 0x06000000);
523 isbW32m(HTE
, 0x00020022, Address
>> 6);
524 isbW32m(HTE
, 0x00020062, 0x00800015);
525 isbW32m(HTE
, 0x00020063, 0xAAAAAAAA);
526 isbW32m(HTE
, 0x00020064, 0xCCCCCCCC);
527 isbW32m(HTE
, 0x00020065, 0xF0F0F0F0);
528 isbW32m(HTE
, 0x00020061, 0x00030008);
530 for (Offset
= 0x80; Offset
<= 0x8F; Offset
++)
532 isbW32m(HTE
, Offset
, 0xC33C0000);
536 isbW32m(HTE
, 0x000200A1, 0xFFFF1000);
537 isbW32m(HTE
, 0x00020011, 0x00011000);
538 isbW32m(HTE
, 0x00020011, 0x00011100);
540 WaitForHteComplete();