1// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause 2/* 3 * Copyright (C) 2019, STMicroelectronics - All Rights Reserved 4 */ 5 6#define LOG_CATEGORY UCLASS_RAM 7 8#include <common.h> 9#include <console.h> 10#include <init.h> 11#include <log.h> 12#include <rand.h> 13#include <watchdog.h> 14#include <asm/global_data.h> 15#include <asm/io.h> 16#include <linux/log2.h> 17#include "stm32mp1_tests.h" 18 19#define ADDR_INVALID 0xFFFFFFFF 20 21#define PATTERN_DEFAULT "-" 22 23DECLARE_GLOBAL_DATA_PTR; 24 25static int get_bufsize(char *string, int argc, char *argv[], int arg_nb, 26 size_t *bufsize, size_t default_size, size_t min_size) 27{ 28 unsigned long value; 29 30 if (argc > arg_nb) { 31 if (strict_strtoul(argv[arg_nb], 0, &value) < 0) { 32 sprintf(string, "invalid %d parameter %s", 33 arg_nb, argv[arg_nb]); 34 return -1; 35 } 36 if (value > STM32_DDR_SIZE || value < min_size) { 37 sprintf(string, "invalid size %s (min=%d)", 38 argv[arg_nb], min_size); 39 return -1; 40 } 41 if (value & (min_size - 1)) { 42 sprintf(string, "unaligned size %s (min=%d)", 43 argv[arg_nb], min_size); 44 return -1; 45 } 46 *bufsize = value; 47 } else { 48 if (default_size != STM32_DDR_SIZE) 49 *bufsize = default_size; 50 else 51 *bufsize = get_ram_size((long *)STM32_DDR_BASE, 52 STM32_DDR_SIZE); 53 } 54 return 0; 55} 56 57static int get_nb_loop(char *string, int argc, char *argv[], int arg_nb, 58 u32 *nb_loop, u32 default_nb_loop) 59{ 60 unsigned long value; 61 62 if (argc > arg_nb) { 63 if (strict_strtoul(argv[arg_nb], 0, &value) < 0) { 64 sprintf(string, "invalid %d parameter %s", 65 arg_nb, argv[arg_nb]); 66 return -1; 67 } 68 if (value == 0) 69 printf("WARNING: infinite loop requested\n"); 70 *nb_loop = value; 71 } else { 72 *nb_loop = default_nb_loop; 73 } 74 75 return 0; 76} 77 78static int get_addr(char *string, int argc, char *argv[], int arg_nb, 79 u32 *addr) 80{ 81 unsigned long value; 82 83 if (argc > arg_nb) { 84 if (strict_strtoul(argv[arg_nb], 16, &value) < 0) { 85 sprintf(string, "invalid %d parameter %s", 86 arg_nb, argv[arg_nb]); 87 return -1; 88 } 89 if (value < STM32_DDR_BASE) { 90 sprintf(string, "too low address %s", argv[arg_nb]); 91 return -1; 92 } 93 if (value & 0x3 && value != ADDR_INVALID) { 94 sprintf(string, "unaligned address %s", 95 argv[arg_nb]); 96 return -1; 97 } 98 *addr = value; 99 } else { 100 *addr = STM32_DDR_BASE; 101 } 102 103 return 0; 104} 105 106static int get_pattern(char *string, int argc, char *argv[], int arg_nb, 107 u32 *pattern, u32 default_pattern) 108{ 109 unsigned long value; 110 111 if (argc > arg_nb) { 112 if (!strcmp(argv[arg_nb], PATTERN_DEFAULT)) { 113 *pattern = default_pattern; 114 return 0; 115 } 116 if (strict_strtoul(argv[arg_nb], 16, &value) < 0) { 117 sprintf(string, "invalid %d parameter %s", 118 arg_nb, argv[arg_nb]); 119 return -1; 120 } 121 *pattern = value; 122 } else { 123 *pattern = default_pattern; 124 } 125 126 return 0; 127} 128 129static u32 check_addr(u32 addr, u32 value) 130{ 131 u32 data = readl(addr); 132 133 if (value != data) { 134 printf("0x%08x: 0x%08x <=> 0x%08x", addr, data, value); 135 data = readl(addr); 136 printf("(2nd read: 0x%08x)", data); 137 if (value == data) 138 printf("- read error"); 139 else 140 printf("- write error"); 141 printf("\n"); 142 return -1; 143 } 144 return 0; 145} 146 147static int progress(u32 offset) 148{ 149 if (!(offset & 0xFFFFFF)) { 150 putc('.'); 151 if (ctrlc()) { 152 printf("\ntest interrupted!\n"); 153 return 1; 154 } 155 } 156 return 0; 157} 158 159static int test_loop_end(u32 *loop, u32 nb_loop, u32 progress) 160{ 161 (*loop)++; 162 if (nb_loop && *loop >= nb_loop) 163 return 1; 164 if ((*loop) % progress) 165 return 0; 166 /* allow to interrupt the test only for progress step */ 167 if (ctrlc()) { 168 printf("test interrupted!\n"); 169 return 1; 170 } 171 printf("loop #%d\n", *loop); 172 schedule(); 173 174 return 0; 175} 176 177/********************************************************************** 178 * 179 * Function: memTestDataBus() 180 * 181 * Description: Test the data bus wiring in a memory region by 182 * performing a walking 1's test at a fixed address 183 * within that region. The address is selected 184 * by the caller. 185 * 186 * Notes: 187 * 188 * Returns: 0 if the test succeeds. 189 * A non-zero result is the first pattern that failed. 190 * 191 **********************************************************************/ 192static u32 databus(u32 *address) 193{ 194 u32 pattern; 195 u32 read_value; 196 197 /* Perform a walking 1's test at the given address. */ 198 for (pattern = 1; pattern != 0; pattern <<= 1) { 199 /* Write the test pattern. */ 200 writel(pattern, address); 201 202 /* Read it back (immediately is okay for this test). */ 203 read_value = readl(address); 204 log_debug("%x: %x <=> %x\n", 205 (u32)address, read_value, pattern); 206 207 if (read_value != pattern) 208 return pattern; 209 } 210 211 return 0; 212} 213 214/********************************************************************** 215 * 216 * Function: memTestAddressBus() 217 * 218 * Description: Test the address bus wiring in a memory region by 219 * performing a walking 1's test on the relevant bits 220 * of the address and checking for aliasing. This test 221 * will find single-bit address failures such as stuck 222 * -high, stuck-low, and shorted pins. The base address 223 * and size of the region are selected by the caller. 224 * 225 * Notes: For best results, the selected base address should 226 * have enough LSB 0's to guarantee single address bit 227 * changes. For example, to test a 64-Kbyte region, 228 * select a base address on a 64-Kbyte boundary. Also, 229 * select the region size as a power-of-two--if at all 230 * possible. 231 * 232 * Returns: NULL if the test succeeds. 233 * A non-zero result is the first address at which an 234 * aliasing problem was uncovered. By examining the 235 * contents of memory, it may be possible to gather 236 * additional information about the problem. 237 * 238 **********************************************************************/ 239static u32 *addressbus(u32 *address, u32 nb_bytes) 240{ 241 u32 mask = (nb_bytes / sizeof(u32) - 1); 242 u32 offset; 243 u32 test_offset; 244 u32 read_value; 245 246 u32 pattern = 0xAAAAAAAA; 247 u32 antipattern = 0x55555555; 248 249 /* Write the default pattern at each of the power-of-two offsets. */ 250 for (offset = 1; (offset & mask) != 0; offset <<= 1) 251 writel(pattern, &address[offset]); 252 253 /* Check for address bits stuck high. */ 254 test_offset = 0; 255 writel(antipattern, &address[test_offset]); 256 257 for (offset = 1; (offset & mask) != 0; offset <<= 1) { 258 read_value = readl(&address[offset]); 259 log_debug("%x: %x <=> %x\n", 260 (u32)&address[offset], read_value, pattern); 261 if (read_value != pattern) 262 return &address[offset]; 263 } 264 265 writel(pattern, &address[test_offset]); 266 267 /* Check for address bits stuck low or shorted. */ 268 for (test_offset = 1; (test_offset & mask) != 0; test_offset <<= 1) { 269 writel(antipattern, &address[test_offset]); 270 if (readl(&address[0]) != pattern) 271 return &address[test_offset]; 272 273 for (offset = 1; (offset & mask) != 0; offset <<= 1) { 274 if (readl(&address[offset]) != pattern && 275 offset != test_offset) 276 return &address[test_offset]; 277 } 278 writel(pattern, &address[test_offset]); 279 } 280 281 return NULL; 282} 283 284/********************************************************************** 285 * 286 * Function: memTestDevice() 287 * 288 * Description: Test the integrity of a physical memory device by 289 * performing an increment/decrement test over the 290 * entire region. In the process every storage bit 291 * in the device is tested as a zero and a one. The 292 * base address and the size of the region are 293 * selected by the caller. 294 * 295 * Notes: 296 * 297 * Returns: NULL if the test succeeds. 298 * 299 * A non-zero result is the first address at which an 300 * incorrect value was read back. By examining the 301 * contents of memory, it may be possible to gather 302 * additional information about the problem. 303 * 304 **********************************************************************/ 305static u32 *memdevice(u32 *address, u32 nb_bytes) 306{ 307 u32 offset; 308 u32 nb_words = nb_bytes / sizeof(u32); 309 310 u32 pattern; 311 u32 antipattern; 312 313 puts("Fill with pattern"); 314 /* Fill memory with a known pattern. */ 315 for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) { 316 writel(pattern, &address[offset]); 317 if (progress(offset)) 318 return NULL; 319 } 320 321 puts("\nCheck and invert pattern"); 322 /* Check each location and invert it for the second pass. */ 323 for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) { 324 if (readl(&address[offset]) != pattern) 325 return &address[offset]; 326 327 antipattern = ~pattern; 328 writel(antipattern, &address[offset]); 329 if (progress(offset)) 330 return NULL; 331 } 332 333 puts("\nCheck inverted pattern"); 334 /* Check each location for the inverted pattern and zero it. */ 335 for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) { 336 antipattern = ~pattern; 337 if (readl(&address[offset]) != antipattern) 338 return &address[offset]; 339 if (progress(offset)) 340 return NULL; 341 } 342 printf("\n"); 343 344 return NULL; 345} 346 347static enum test_result databuswalk0(struct stm32mp1_ddrctl *ctl, 348 struct stm32mp1_ddrphy *phy, 349 char *string, int argc, char *argv[]) 350{ 351 int i; 352 u32 loop = 0, nb_loop; 353 u32 addr; 354 u32 error = 0; 355 u32 data; 356 357 if (get_nb_loop(string, argc, argv, 0, &nb_loop, 100)) 358 return TEST_ERROR; 359 if (get_addr(string, argc, argv, 1, &addr)) 360 return TEST_ERROR; 361 362 printf("running %d loops at 0x%x\n", nb_loop, addr); 363 while (!error) { 364 for (i = 0; i < 32; i++) 365 writel(~(1 << i), addr + 4 * i); 366 for (i = 0; i < 32; i++) { 367 data = readl(addr + 4 * i); 368 if (~(1 << i) != data) { 369 error |= 1 << i; 370 log_debug("%x: error %x expected %x => error:%x\n", 371 addr + 4 * i, data, ~(1 << i), error); 372 } 373 } 374 if (test_loop_end(&loop, nb_loop, 1000)) 375 break; 376 for (i = 0; i < 32; i++) 377 writel(0, addr + 4 * i); 378 } 379 if (error) { 380 sprintf(string, "loop %d: error for bits 0x%x", 381 loop, error); 382 return TEST_FAILED; 383 } 384 sprintf(string, "no error for %d loops", loop); 385 return TEST_PASSED; 386} 387 388static enum test_result databuswalk1(struct stm32mp1_ddrctl *ctl, 389 struct stm32mp1_ddrphy *phy, 390 char *string, int argc, char *argv[]) 391{ 392 int i; 393 u32 loop = 0, nb_loop; 394 u32 addr; 395 u32 error = 0; 396 u32 data; 397 398 if (get_nb_loop(string, argc, argv, 0, &nb_loop, 100)) 399 return TEST_ERROR; 400 if (get_addr(string, argc, argv, 1, &addr)) 401 return TEST_ERROR; 402 printf("running %d loops at 0x%x\n", nb_loop, addr); 403 while (!error) { 404 for (i = 0; i < 32; i++) 405 writel(1 << i, addr + 4 * i); 406 for (i = 0; i < 32; i++) { 407 data = readl(addr + 4 * i); 408 if ((1 << i) != data) { 409 error |= 1 << i; 410 log_debug("%x: error %x expected %x => error:%x\n", 411 addr + 4 * i, data, (1 << i), error); 412 } 413 } 414 if (test_loop_end(&loop, nb_loop, 1000)) 415 break; 416 for (i = 0; i < 32; i++) 417 writel(0, addr + 4 * i); 418 } 419 if (error) { 420 sprintf(string, "loop %d: error for bits 0x%x", 421 loop, error); 422 return TEST_FAILED; 423 } 424 sprintf(string, "no error for %d loops", loop); 425 return TEST_PASSED; 426} 427 428static enum test_result test_databus(struct stm32mp1_ddrctl *ctl, 429 struct stm32mp1_ddrphy *phy, 430 char *string, int argc, char *argv[]) 431{ 432 u32 addr; 433 u32 error; 434 435 if (get_addr(string, argc, argv, 0, &addr)) 436 return TEST_ERROR; 437 error = databus((u32 *)addr); 438 if (error) { 439 sprintf(string, "0x%x: error for bits 0x%x", 440 addr, error); 441 return TEST_FAILED; 442 } 443 sprintf(string, "address 0x%x", addr); 444 return TEST_PASSED; 445} 446 447static enum test_result test_addressbus(struct stm32mp1_ddrctl *ctl, 448 struct stm32mp1_ddrphy *phy, 449 char *string, int argc, char *argv[]) 450{ 451 u32 addr; 452 u32 bufsize; 453 u32 error; 454 455 if (get_bufsize(string, argc, argv, 0, &bufsize, STM32_DDR_SIZE, 4)) 456 return TEST_ERROR; 457 if (!is_power_of_2(bufsize)) { 458 sprintf(string, "size 0x%x is not a power of 2", 459 (u32)bufsize); 460 return TEST_ERROR; 461 } 462 if (get_addr(string, argc, argv, 1, &addr)) 463 return TEST_ERROR; 464 465 printf("running at 0x%08x length 0x%x\n", addr, bufsize); 466 error = (u32)addressbus((u32 *)addr, bufsize); 467 if (error) { 468 sprintf(string, "0x%x: error for address 0x%x", 469 addr, error); 470 return TEST_FAILED; 471 } 472 sprintf(string, "address 0x%x, size 0x%x", 473 addr, bufsize); 474 return TEST_PASSED; 475} 476 477static enum test_result test_memdevice(struct stm32mp1_ddrctl *ctl, 478 struct stm32mp1_ddrphy *phy, 479 char *string, int argc, char *argv[]) 480{ 481 u32 addr; 482 size_t bufsize; 483 u32 error; 484 485 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4)) 486 return TEST_ERROR; 487 if (get_addr(string, argc, argv, 1, &addr)) 488 return TEST_ERROR; 489 error = (u32)memdevice((u32 *)addr, (unsigned long)bufsize); 490 if (error) { 491 sprintf(string, "0x%x: error for address 0x%x", 492 addr, error); 493 return TEST_FAILED; 494 } 495 sprintf(string, "address 0x%x, size 0x%x", 496 addr, bufsize); 497 return TEST_PASSED; 498} 499 500/********************************************************************** 501 * 502 * Function: sso 503 * 504 * Description: Test the Simultaneous Switching Output. 505 * Verifies succes sive reads and writes to the same memory word, 506 * holding one bit constant while toggling all other data bits 507 * simultaneously 508 * => stress the data bus over an address range 509 * 510 * The CPU writes to each address in the given range. 511 * For each bit, first the CPU holds the bit at 1 while 512 * toggling the other bits, and then the CPU holds the bit at 0 513 * while toggling the other bits. 514 * After each write, the CPU reads the address that was written 515 * to verify that it contains the correct data 516 * 517 **********************************************************************/ 518static enum test_result test_sso(struct stm32mp1_ddrctl *ctl, 519 struct stm32mp1_ddrphy *phy, 520 char *string, int argc, char *argv[]) 521{ 522 int i, j; 523 u32 addr, bufsize, remaining, offset; 524 u32 error = 0; 525 u32 data; 526 527 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4)) 528 return TEST_ERROR; 529 if (get_addr(string, argc, argv, 1, &addr)) 530 return TEST_ERROR; 531 532 printf("running sso at 0x%x length 0x%x", addr, bufsize); 533 offset = addr; 534 remaining = bufsize; 535 while (remaining) { 536 for (i = 0; i < 32; i++) { 537 /* write pattern. */ 538 for (j = 0; j < 6; j++) { 539 switch (j) { 540 case 0: 541 case 2: 542 data = 1 << i; 543 break; 544 case 3: 545 case 5: 546 data = ~(1 << i); 547 break; 548 case 1: 549 data = ~0x0; 550 break; 551 case 4: 552 data = 0x0; 553 break; 554 } 555 556 writel(data, offset); 557 error = check_addr(offset, data); 558 if (error) 559 goto end; 560 } 561 } 562 offset += 4; 563 remaining -= 4; 564 if (progress(offset << 7)) 565 goto end; 566 } 567 puts("\n"); 568 569end: 570 if (error) { 571 sprintf(string, "error for pattern 0x%x @0x%x", 572 data, offset); 573 return TEST_FAILED; 574 } 575 sprintf(string, "no error for sso at 0x%x length 0x%x", addr, bufsize); 576 return TEST_PASSED; 577} 578 579/********************************************************************** 580 * 581 * Function: Random 582 * 583 * Description: Verifies r/w with pseudo-ramdom value on one region 584 * + write the region (individual access) 585 * + memcopy to the 2nd region (try to use burst) 586 * + verify the 2 regions 587 * 588 **********************************************************************/ 589static enum test_result test_random(struct stm32mp1_ddrctl *ctl, 590 struct stm32mp1_ddrphy *phy, 591 char *string, int argc, char *argv[]) 592{ 593 u32 addr, offset, value = 0; 594 size_t bufsize; 595 u32 loop = 0, nb_loop; 596 u32 error = 0; 597 unsigned int seed; 598 599 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 8)) 600 return TEST_ERROR; 601 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) 602 return TEST_ERROR; 603 if (get_addr(string, argc, argv, 2, &addr)) 604 return TEST_ERROR; 605 606 bufsize /= 2; 607 printf("running %d loops copy from 0x%x to 0x%x (buffer size=0x%x)\n", 608 nb_loop, addr, addr + bufsize, bufsize); 609 while (!error) { 610 seed = rand(); 611 for (offset = 0; offset < bufsize; offset += 4) 612 writel(rand(), addr + offset); 613 614 memcpy((void *)addr + bufsize, (void *)addr, bufsize); 615 616 srand(seed); 617 for (offset = 0; offset < 2 * bufsize; offset += 4) { 618 if (offset == bufsize) 619 srand(seed); 620 value = rand(); 621 error = check_addr(addr + offset, value); 622 if (error) 623 break; 624 if (progress(offset)) 625 return TEST_FAILED; 626 } 627 if (test_loop_end(&loop, nb_loop, 100)) 628 break; 629 } 630 putc('\n'); 631 632 if (error) { 633 sprintf(string, 634 "loop %d: error for address 0x%x: 0x%x expected 0x%x", 635 loop, offset, readl(offset), value); 636 return TEST_FAILED; 637 } 638 sprintf(string, "no error for %d loops, size 0x%x", 639 loop, bufsize); 640 return TEST_PASSED; 641} 642 643/********************************************************************** 644 * 645 * Function: noise 646 * 647 * Description: Verifies r/w while forcing switching of all data bus lines. 648 * optimised 4 iteration write/read/write/read cycles... 649 * for pattern and inversed pattern 650 * 651 **********************************************************************/ 652void do_noise(u32 addr, u32 pattern, u32 *result) 653{ 654 __asm__("push {R0-R11}"); 655 __asm__("mov r0, %0" : : "r" (addr)); 656 __asm__("mov r1, %0" : : "r" (pattern)); 657 __asm__("mov r11, %0" : : "r" (result)); 658 659 __asm__("mvn r2, r1"); 660 661 __asm__("str r1, [r0]"); 662 __asm__("ldr r3, [r0]"); 663 __asm__("str r2, [r0]"); 664 __asm__("ldr r4, [r0]"); 665 666 __asm__("str r1, [r0]"); 667 __asm__("ldr r5, [r0]"); 668 __asm__("str r2, [r0]"); 669 __asm__("ldr r6, [r0]"); 670 671 __asm__("str r1, [r0]"); 672 __asm__("ldr r7, [r0]"); 673 __asm__("str r2, [r0]"); 674 __asm__("ldr r8, [r0]"); 675 676 __asm__("str r1, [r0]"); 677 __asm__("ldr r9, [r0]"); 678 __asm__("str r2, [r0]"); 679 __asm__("ldr r10, [r0]"); 680 681 __asm__("stmia R11!, {R3-R10}"); 682 683 __asm__("pop {R0-R11}"); 684} 685 686static enum test_result test_noise(struct stm32mp1_ddrctl *ctl, 687 struct stm32mp1_ddrphy *phy, 688 char *string, int argc, char *argv[]) 689{ 690 u32 addr, pattern; 691 u32 result[8]; 692 int i; 693 enum test_result res = TEST_PASSED; 694 695 if (get_pattern(string, argc, argv, 0, &pattern, 0xFFFFFFFF)) 696 return TEST_ERROR; 697 if (get_addr(string, argc, argv, 1, &addr)) 698 return TEST_ERROR; 699 700 printf("running noise for 0x%x at 0x%x\n", pattern, addr); 701 702 do_noise(addr, pattern, result); 703 704 for (i = 0; i < 0x8;) { 705 if (check_addr((u32)&result[i++], pattern)) 706 res = TEST_FAILED; 707 if (check_addr((u32)&result[i++], ~pattern)) 708 res = TEST_FAILED; 709 } 710 711 return res; 712} 713 714/********************************************************************** 715 * 716 * Function: noise_burst 717 * 718 * Description: Verifies r/w while forcing switching of all data bus lines. 719 * optimised write loop witrh store multiple to use burst 720 * for pattern and inversed pattern 721 * 722 **********************************************************************/ 723void do_noise_burst(u32 addr, u32 pattern, size_t bufsize) 724{ 725 __asm__("push {R0-R9}"); 726 __asm__("mov r0, %0" : : "r" (addr)); 727 __asm__("mov r1, %0" : : "r" (pattern)); 728 __asm__("mov r9, %0" : : "r" (bufsize)); 729 730 __asm__("mvn r2, r1"); 731 __asm__("mov r3, r1"); 732 __asm__("mov r4, r2"); 733 __asm__("mov r5, r1"); 734 __asm__("mov r6, r2"); 735 __asm__("mov r7, r1"); 736 __asm__("mov r8, r2"); 737 738 __asm__("loop1:"); 739 __asm__("stmia R0!, {R1-R8}"); 740 __asm__("stmia R0!, {R1-R8}"); 741 __asm__("stmia R0!, {R1-R8}"); 742 __asm__("stmia R0!, {R1-R8}"); 743 __asm__("subs r9, r9, #128"); 744 __asm__("bge loop1"); 745 __asm__("pop {R0-R9}"); 746} 747 748/* chunk size enough to allow interruption with Ctrl-C*/ 749#define CHUNK_SIZE 0x8000000 750static enum test_result test_noise_burst(struct stm32mp1_ddrctl *ctl, 751 struct stm32mp1_ddrphy *phy, 752 char *string, int argc, char *argv[]) 753{ 754 u32 addr, offset, pattern; 755 size_t bufsize, remaining, size; 756 int i; 757 enum test_result res = TEST_PASSED; 758 759 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 128)) 760 return TEST_ERROR; 761 if (get_pattern(string, argc, argv, 1, &pattern, 0xFFFFFFFF)) 762 return TEST_ERROR; 763 if (get_addr(string, argc, argv, 2, &addr)) 764 return TEST_ERROR; 765 766 printf("running noise burst for 0x%x at 0x%x + 0x%x", 767 pattern, addr, bufsize); 768 769 offset = addr; 770 remaining = bufsize; 771 size = CHUNK_SIZE; 772 while (remaining) { 773 if (remaining < size) 774 size = remaining; 775 do_noise_burst(offset, pattern, size); 776 remaining -= size; 777 offset += size; 778 if (progress(offset)) { 779 res = TEST_FAILED; 780 goto end; 781 } 782 } 783 puts("\ncheck buffer"); 784 for (i = 0; i < bufsize;) { 785 if (check_addr(addr + i, pattern)) 786 res = TEST_FAILED; 787 i += 4; 788 if (check_addr(addr + i, ~pattern)) 789 res = TEST_FAILED; 790 i += 4; 791 if (progress(i)) { 792 res = TEST_FAILED; 793 goto end; 794 } 795 } 796end: 797 puts("\n"); 798 return res; 799} 800 801/********************************************************************** 802 * 803 * Function: pattern test 804 * 805 * Description: optimized loop for read/write pattern (array of 8 u32) 806 * 807 **********************************************************************/ 808#define PATTERN_SIZE 8 809static enum test_result test_loop(const u32 *pattern, u32 *address, 810 const u32 bufsize) 811{ 812 int i; 813 int j; 814 enum test_result res = TEST_PASSED; 815 u32 offset, testsize, remaining; 816 817 offset = (u32)address; 818 remaining = bufsize; 819 while (remaining) { 820 testsize = bufsize > 0x1000000 ? 0x1000000 : bufsize; 821 822 __asm__("push {R0-R10}"); 823 __asm__("mov r0, %0" : : "r" (pattern)); 824 __asm__("mov r1, %0" : : "r" (offset)); 825 __asm__("mov r2, %0" : : "r" (testsize)); 826 __asm__("ldmia r0!, {R3-R10}"); 827 828 __asm__("loop2:"); 829 __asm__("stmia r1!, {R3-R10}"); 830 __asm__("stmia r1!, {R3-R10}"); 831 __asm__("stmia r1!, {R3-R10}"); 832 __asm__("stmia r1!, {R3-R10}"); 833 __asm__("subs r2, r2, #128"); 834 __asm__("bge loop2"); 835 __asm__("pop {R0-R10}"); 836 837 offset += testsize; 838 remaining -= testsize; 839 if (progress((u32)offset)) { 840 res = TEST_FAILED; 841 goto end; 842 } 843 } 844 845 puts("\ncheck buffer"); 846 for (i = 0; i < bufsize; i += PATTERN_SIZE * 4) { 847 for (j = 0; j < PATTERN_SIZE; j++, address++) 848 if (check_addr((u32)address, pattern[j])) { 849 res = TEST_FAILED; 850 goto end; 851 } 852 if (progress(i)) { 853 res = TEST_FAILED; 854 goto end; 855 } 856 } 857 858end: 859 puts("\n"); 860 return res; 861} 862 863const u32 pattern_div1_x16[PATTERN_SIZE] = { 864 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 865 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF 866}; 867 868const u32 pattern_div2_x16[PATTERN_SIZE] = { 869 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 870 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000 871}; 872 873const u32 pattern_div4_x16[PATTERN_SIZE] = { 874 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 875 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000 876}; 877 878const u32 pattern_div4_x32[PATTERN_SIZE] = { 879 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 880 0x00000000, 0x00000000, 0x00000000, 0x00000000 881}; 882 883const u32 pattern_mostly_zero_x16[PATTERN_SIZE] = { 884 0x00000000, 0x00000000, 0x00000000, 0x0000FFFF, 885 0x00000000, 0x00000000, 0x00000000, 0x00000000 886}; 887 888const u32 pattern_mostly_zero_x32[PATTERN_SIZE] = { 889 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 890 0x00000000, 0x00000000, 0x00000000, 0x00000000 891}; 892 893const u32 pattern_mostly_one_x16[PATTERN_SIZE] = { 894 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000FFFF, 895 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF 896}; 897 898const u32 pattern_mostly_one_x32[PATTERN_SIZE] = { 899 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 900 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF 901}; 902 903#define NB_PATTERN 5 904static enum test_result test_freq_pattern(struct stm32mp1_ddrctl *ctl, 905 struct stm32mp1_ddrphy *phy, 906 char *string, int argc, char *argv[]) 907{ 908 const u32 * const patterns_x16[NB_PATTERN] = { 909 pattern_div1_x16, 910 pattern_div2_x16, 911 pattern_div4_x16, 912 pattern_mostly_zero_x16, 913 pattern_mostly_one_x16, 914 }; 915 const u32 * const patterns_x32[NB_PATTERN] = { 916 pattern_div2_x16, 917 pattern_div4_x16, 918 pattern_div4_x32, 919 pattern_mostly_zero_x32, 920 pattern_mostly_one_x32 921 }; 922 const char *patterns_comments[NB_PATTERN] = { 923 "switching at frequency F/1", 924 "switching at frequency F/2", 925 "switching at frequency F/4", 926 "mostly zero", 927 "mostly one" 928 }; 929 930 enum test_result res = TEST_PASSED, pattern_res; 931 int i, bus_width; 932 const u32 **patterns; 933 u32 bufsize, addr; 934 935 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 128)) 936 return TEST_ERROR; 937 if (get_addr(string, argc, argv, 1, &addr)) 938 return TEST_ERROR; 939 940 switch (readl(&ctl->mstr) & DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK) { 941 case DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF: 942 case DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER: 943 bus_width = 16; 944 break; 945 default: 946 bus_width = 32; 947 break; 948 } 949 950 printf("running test pattern at 0x%08x length 0x%x width = %d\n", 951 addr, bufsize, bus_width); 952 953 patterns = 954 (const u32 **)(bus_width == 16 ? patterns_x16 : patterns_x32); 955 956 for (i = 0; i < NB_PATTERN; i++) { 957 printf("test data pattern %s:", patterns_comments[i]); 958 pattern_res = test_loop(patterns[i], (u32 *)addr, bufsize); 959 if (pattern_res != TEST_PASSED) { 960 printf("Failed\n"); 961 return pattern_res; 962 } 963 printf("Passed\n"); 964 } 965 966 return res; 967} 968 969/********************************************************************** 970 * 971 * Function: pattern test with size 972 * 973 * Description: loop for write pattern 974 * 975 **********************************************************************/ 976 977static enum test_result test_loop_size(const u32 *pattern, u32 size, 978 u32 *address, 979 const u32 bufsize) 980{ 981 int i, j; 982 enum test_result res = TEST_PASSED; 983 u32 *p = address; 984 985 for (i = 0; i < bufsize; i += size * 4) { 986 for (j = 0; j < size ; j++, p++) 987 *p = pattern[j]; 988 if (progress(i)) { 989 res = TEST_FAILED; 990 goto end; 991 } 992 } 993 994 puts("\ncheck buffer"); 995 p = address; 996 for (i = 0; i < bufsize; i += size * 4) { 997 for (j = 0; j < size; j++, p++) 998 if (check_addr((u32)p, pattern[j])) { 999 res = TEST_FAILED; 1000 goto end; 1001 } 1002 if (progress(i)) { 1003 res = TEST_FAILED; 1004 goto end; 1005 } 1006 } 1007 1008end: 1009 puts("\n"); 1010 return res; 1011} 1012 1013static enum test_result test_checkboard(struct stm32mp1_ddrctl *ctl, 1014 struct stm32mp1_ddrphy *phy, 1015 char *string, int argc, char *argv[]) 1016{ 1017 enum test_result res = TEST_PASSED; 1018 u32 bufsize, nb_loop, loop = 0, addr; 1019 int i; 1020 1021 u32 checkboard[2] = {0x55555555, 0xAAAAAAAA}; 1022 1023 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 8)) 1024 return TEST_ERROR; 1025 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) 1026 return TEST_ERROR; 1027 if (get_addr(string, argc, argv, 2, &addr)) 1028 return TEST_ERROR; 1029 1030 printf("running %d loops at 0x%08x length 0x%x\n", 1031 nb_loop, addr, bufsize); 1032 while (1) { 1033 for (i = 0; i < 2; i++) { 1034 res = test_loop_size(checkboard, 2, (u32 *)addr, 1035 bufsize); 1036 if (res) 1037 return res; 1038 checkboard[0] = ~checkboard[0]; 1039 checkboard[1] = ~checkboard[1]; 1040 } 1041 if (test_loop_end(&loop, nb_loop, 1)) 1042 break; 1043 } 1044 sprintf(string, "no error for %d loops at 0x%08x length 0x%x", 1045 loop, addr, bufsize); 1046 1047 return res; 1048} 1049 1050static enum test_result test_blockseq(struct stm32mp1_ddrctl *ctl, 1051 struct stm32mp1_ddrphy *phy, 1052 char *string, int argc, char *argv[]) 1053{ 1054 enum test_result res = TEST_PASSED; 1055 u32 bufsize, nb_loop, loop = 0, addr, value; 1056 int i; 1057 1058 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4)) 1059 return TEST_ERROR; 1060 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) 1061 return TEST_ERROR; 1062 if (get_addr(string, argc, argv, 2, &addr)) 1063 return TEST_ERROR; 1064 1065 printf("running %d loops at 0x%08x length 0x%x\n", 1066 nb_loop, addr, bufsize); 1067 while (1) { 1068 for (i = 0; i < 256; i++) { 1069 value = i | i << 8 | i << 16 | i << 24; 1070 printf("pattern = %08x", value); 1071 res = test_loop_size(&value, 1, (u32 *)addr, bufsize); 1072 if (res != TEST_PASSED) 1073 return res; 1074 } 1075 if (test_loop_end(&loop, nb_loop, 1)) 1076 break; 1077 } 1078 sprintf(string, "no error for %d loops at 0x%08x length 0x%x", 1079 loop, addr, bufsize); 1080 1081 return res; 1082} 1083 1084static enum test_result test_walkbit0(struct stm32mp1_ddrctl *ctl, 1085 struct stm32mp1_ddrphy *phy, 1086 char *string, int argc, char *argv[]) 1087{ 1088 enum test_result res = TEST_PASSED; 1089 u32 bufsize, nb_loop, loop = 0, addr, value; 1090 int i; 1091 1092 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4)) 1093 return TEST_ERROR; 1094 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) 1095 return TEST_ERROR; 1096 if (get_addr(string, argc, argv, 2, &addr)) 1097 return TEST_ERROR; 1098 1099 printf("running %d loops at 0x%08x length 0x%x\n", 1100 nb_loop, addr, bufsize); 1101 while (1) { 1102 for (i = 0; i < 64; i++) { 1103 if (i < 32) 1104 value = 1 << i; 1105 else 1106 value = 1 << (63 - i); 1107 1108 printf("pattern = %08x", value); 1109 res = test_loop_size(&value, 1, (u32 *)addr, bufsize); 1110 if (res != TEST_PASSED) 1111 return res; 1112 } 1113 if (test_loop_end(&loop, nb_loop, 1)) 1114 break; 1115 } 1116 sprintf(string, "no error for %d loops at 0x%08x length 0x%x", 1117 loop, addr, bufsize); 1118 1119 return res; 1120} 1121 1122static enum test_result test_walkbit1(struct stm32mp1_ddrctl *ctl, 1123 struct stm32mp1_ddrphy *phy, 1124 char *string, int argc, char *argv[]) 1125{ 1126 enum test_result res = TEST_PASSED; 1127 u32 bufsize, nb_loop, loop = 0, addr, value; 1128 int i; 1129 1130 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 4)) 1131 return TEST_ERROR; 1132 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) 1133 return TEST_ERROR; 1134 if (get_addr(string, argc, argv, 2, &addr)) 1135 return TEST_ERROR; 1136 1137 printf("running %d loops at 0x%08x length 0x%x\n", 1138 nb_loop, addr, bufsize); 1139 while (1) { 1140 for (i = 0; i < 64; i++) { 1141 if (i < 32) 1142 value = ~(1 << i); 1143 else 1144 value = ~(1 << (63 - i)); 1145 1146 printf("pattern = %08x", value); 1147 res = test_loop_size(&value, 1, (u32 *)addr, bufsize); 1148 if (res != TEST_PASSED) 1149 return res; 1150 } 1151 if (test_loop_end(&loop, nb_loop, 1)) 1152 break; 1153 } 1154 sprintf(string, "no error for %d loops at 0x%08x length 0x%x", 1155 loop, addr, bufsize); 1156 1157 return res; 1158} 1159 1160/* 1161 * try to catch bad bits which are dependent on the current values of 1162 * surrounding bits in either the same word32 1163 */ 1164static enum test_result test_bitspread(struct stm32mp1_ddrctl *ctl, 1165 struct stm32mp1_ddrphy *phy, 1166 char *string, int argc, char *argv[]) 1167{ 1168 enum test_result res = TEST_PASSED; 1169 u32 bufsize, nb_loop, loop = 0, addr, bitspread[4]; 1170 int i, j; 1171 1172 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 32)) 1173 return TEST_ERROR; 1174 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) 1175 return TEST_ERROR; 1176 if (get_addr(string, argc, argv, 2, &addr)) 1177 return TEST_ERROR; 1178 1179 printf("running %d loops at 0x%08x length 0x%x\n", 1180 nb_loop, addr, bufsize); 1181 while (1) { 1182 for (i = 1; i < 32; i++) { 1183 for (j = 0; j < i; j++) { 1184 if (i < 32) 1185 bitspread[0] = (1 << i) | (1 << j); 1186 else 1187 bitspread[0] = (1 << (63 - i)) | 1188 (1 << (63 - j)); 1189 bitspread[1] = bitspread[0]; 1190 bitspread[2] = ~bitspread[0]; 1191 bitspread[3] = ~bitspread[0]; 1192 printf("pattern = %08x", bitspread[0]); 1193 1194 res = test_loop_size(bitspread, 4, (u32 *)addr, 1195 bufsize); 1196 if (res != TEST_PASSED) 1197 return res; 1198 } 1199 } 1200 if (test_loop_end(&loop, nb_loop, 1)) 1201 break; 1202 } 1203 sprintf(string, "no error for %d loops at 0x%08x length 0x%x", 1204 loop, addr, bufsize); 1205 1206 return res; 1207} 1208 1209static enum test_result test_bitflip(struct stm32mp1_ddrctl *ctl, 1210 struct stm32mp1_ddrphy *phy, 1211 char *string, int argc, char *argv[]) 1212{ 1213 enum test_result res = TEST_PASSED; 1214 u32 bufsize, nb_loop, loop = 0, addr; 1215 int i; 1216 1217 u32 bitflip[4]; 1218 1219 if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024, 32)) 1220 return TEST_ERROR; 1221 if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1)) 1222 return TEST_ERROR; 1223 if (get_addr(string, argc, argv, 2, &addr)) 1224 return TEST_ERROR; 1225 1226 printf("running %d loops at 0x%08x length 0x%x\n", 1227 nb_loop, addr, bufsize); 1228 while (1) { 1229 for (i = 0; i < 32; i++) { 1230 bitflip[0] = 1 << i; 1231 bitflip[1] = bitflip[0]; 1232 bitflip[2] = ~bitflip[0]; 1233 bitflip[3] = bitflip[2]; 1234 printf("pattern = %08x", bitflip[0]); 1235 1236 res = test_loop_size(bitflip, 4, (u32 *)addr, bufsize); 1237 if (res != TEST_PASSED) 1238 return res; 1239 } 1240 if (test_loop_end(&loop, nb_loop, 1)) 1241 break; 1242 } 1243 sprintf(string, "no error for %d loops at 0x%08x length 0x%x", 1244 loop, addr, bufsize); 1245 1246 return res; 1247} 1248 1249/********************************************************************** 1250 * 1251 * Function: infinite read access to DDR 1252 * 1253 * Description: continuous read the same pattern at the same address 1254 * 1255 **********************************************************************/ 1256static enum test_result test_read(struct stm32mp1_ddrctl *ctl, 1257 struct stm32mp1_ddrphy *phy, 1258 char *string, int argc, char *argv[]) 1259{ 1260 u32 *addr; 1261 u32 data; 1262 u32 loop = 0; 1263 int i, size = 1024 * 1024; 1264 bool random = false; 1265 1266 if (get_addr(string, argc, argv, 0, (u32 *)&addr)) 1267 return TEST_ERROR; 1268 1269 if (get_pattern(string, argc, argv, 1, &data, 0xA5A5AA55)) 1270 return TEST_ERROR; 1271 1272 if ((u32)addr == ADDR_INVALID) { 1273 printf("running random\n"); 1274 random = true; 1275 } else { 1276 printf("running at 0x%08x with pattern=0x%08x\n", 1277 (u32)addr, data); 1278 writel(data, addr); 1279 } 1280 1281 while (1) { 1282 for (i = 0; i < size; i++) { 1283 if (random) 1284 addr = (u32 *)(STM32_DDR_BASE + 1285 (rand() & (STM32_DDR_SIZE - 1) & ~0x3)); 1286 data = readl(addr); 1287 } 1288 if (test_loop_end(&loop, 0, 1)) 1289 break; 1290 } 1291 if (random) 1292 sprintf(string, "%d loops random", loop); 1293 else 1294 sprintf(string, "%d loops at 0x%x: %x", loop, (u32)addr, data); 1295 1296 return TEST_PASSED; 1297} 1298 1299/********************************************************************** 1300 * 1301 * Function: infinite write access to DDR 1302 * 1303 * Description: continuous write the same pattern at the same address 1304 * 1305 **********************************************************************/ 1306static enum test_result test_write(struct stm32mp1_ddrctl *ctl, 1307 struct stm32mp1_ddrphy *phy, 1308 char *string, int argc, char *argv[]) 1309{ 1310 u32 *addr; 1311 u32 data; 1312 u32 loop = 0; 1313 int i, size = 1024 * 1024; 1314 bool random = false; 1315 1316 if (get_addr(string, argc, argv, 0, (u32 *)&addr)) 1317 return TEST_ERROR; 1318 1319 if (get_pattern(string, argc, argv, 1, &data, 0xA5A5AA55)) 1320 return TEST_ERROR; 1321 1322 if ((u32)addr == ADDR_INVALID) { 1323 printf("running random\n"); 1324 random = true; 1325 } else { 1326 printf("running at 0x%08x with pattern 0x%08x\n", 1327 (u32)addr, data); 1328 } 1329 1330 while (1) { 1331 for (i = 0; i < size; i++) { 1332 if (random) { 1333 addr = (u32 *)(STM32_DDR_BASE + 1334 (rand() & (STM32_DDR_SIZE - 1) & ~0x3)); 1335 data = rand(); 1336 } 1337 writel(data, addr); 1338 } 1339 if (test_loop_end(&loop, 0, 1)) 1340 break; 1341 } 1342 if (random) 1343 sprintf(string, "%d loops random", loop); 1344 else 1345 sprintf(string, "%d loops at 0x%x: %x", loop, (u32)addr, data); 1346 1347 return TEST_PASSED; 1348} 1349 1350#define NB_TEST_INFINITE 2 1351static enum test_result test_all(struct stm32mp1_ddrctl *ctl, 1352 struct stm32mp1_ddrphy *phy, 1353 char *string, int argc, char *argv[]) 1354{ 1355 enum test_result res = TEST_PASSED, result; 1356 int i, j, nb_error = 0, len; 1357 u32 loop = 0, nb_loop; 1358 int argc_test; 1359 char *argv_test[4]; 1360 char loop_string[] = "1"; 1361 char pattern_string[] = PATTERN_DEFAULT; 1362 u32 *addr; 1363 1364 if (get_nb_loop(string, argc, argv, 0, &nb_loop, 1)) 1365 return TEST_ERROR; 1366 1367 if (get_addr(string, argc, argv, 2, (u32 *)&addr)) 1368 return TEST_ERROR; 1369 1370 while (!nb_error) { 1371 /* execute all the test except the lasts which are infinite */ 1372 for (i = 1; i < test_nb - NB_TEST_INFINITE; i++) { 1373 argc_test = 0; 1374 j = 0; 1375 len = strlen(test[i].usage); 1376 if (argc > 1 && j < len && 1377 !strncmp("[size]", &test[i].usage[j], 6)) { 1378 argv_test[argc_test++] = argv[1]; 1379 j += 7; 1380 } 1381 if (argc > 2) { 1382 if (j < len && 1383 !strncmp("[loop]", &test[i].usage[j], 6)) { 1384 argv_test[argc_test++] = loop_string; 1385 j += 7; 1386 } 1387 if (j < len && 1388 !strncmp("[pattern]", &test[i].usage[j], 1389 9)) { 1390 argv_test[argc_test++] = pattern_string; 1391 j += 10; 1392 } 1393 if (j < len && 1394 !strncmp("[addr]", &test[i].usage[j], 6)) { 1395 argv_test[argc_test++] = argv[2]; 1396 j += 7; 1397 } 1398 } 1399 printf("execute %d:%s\n", (int)i, test[i].name); 1400 result = test[i].fct(ctl, phy, string, 1401 argc_test, argv_test); 1402 printf("result %d:%s = ", (int)i, test[i].name); 1403 if (result != TEST_PASSED) { 1404 nb_error++; 1405 res = TEST_FAILED; 1406 puts("Failed"); 1407 } else { 1408 puts("Passed"); 1409 } 1410 puts("\n\n"); 1411 } 1412 printf("loop %d: %d/%d test failed\n\n\n", 1413 loop + 1, nb_error, test_nb - NB_TEST_INFINITE); 1414 if (test_loop_end(&loop, nb_loop, 1)) 1415 break; 1416 } 1417 if (res != TEST_PASSED) { 1418 sprintf(string, "loop %d: %d/%d test failed", loop, nb_error, 1419 test_nb - NB_TEST_INFINITE); 1420 } else { 1421 sprintf(string, "loop %d: %d tests passed", loop, 1422 test_nb - NB_TEST_INFINITE); 1423 } 1424 return res; 1425} 1426 1427/**************************************************************** 1428 * TEST Description 1429 ****************************************************************/ 1430 1431const struct test_desc test[] = { 1432 {test_all, "All", "[loop] [size] [addr]", "Execute all tests", 3 }, 1433 {test_databus, "Simple DataBus", "[addr]", 1434 "Verifies each data line by walking 1 on fixed address", 1435 1 1436 }, 1437 {databuswalk0, "DataBusWalking0", "[loop] [addr]", 1438 "Verifies each data bus signal can be driven low (32 word burst)", 1439 2 1440 }, 1441 {databuswalk1, "DataBusWalking1", "[loop] [addr]", 1442 "Verifies each data bus signal can be driven high (32 word burst)", 1443 2 1444 }, 1445 {test_addressbus, "AddressBus", "[size] [addr]", 1446 "Verifies each relevant bits of the address and checking for aliasing", 1447 2 1448 }, 1449 {test_memdevice, "MemDevice", "[size] [addr]", 1450 "Test the integrity of a physical memory (test every storage bit in the region)", 1451 2 1452 }, 1453 {test_sso, "SimultaneousSwitchingOutput", "[size] [addr] ", 1454 "Stress the data bus over an address range", 1455 2 1456 }, 1457 {test_noise, "Noise", "[pattern] [addr]", 1458 "Verifies r/w while forcing switching of all data bus lines.", 1459 3 1460 }, 1461 {test_noise_burst, "NoiseBurst", "[size] [pattern] [addr]", 1462 "burst transfers while forcing switching of the data bus lines", 1463 3 1464 }, 1465 {test_random, "Random", "[size] [loop] [addr]", 1466 "Verifies r/w and memcopy(burst for pseudo random value.", 1467 3 1468 }, 1469 {test_freq_pattern, "FrequencySelectivePattern", "[size] [addr]", 1470 "write & test patterns: Mostly Zero, Mostly One and F/n", 1471 2 1472 }, 1473 {test_blockseq, "BlockSequential", "[size] [loop] [addr]", 1474 "test incremental pattern", 1475 3 1476 }, 1477 {test_checkboard, "Checkerboard", "[size] [loop] [addr]", 1478 "test checker pattern", 1479 3 1480 }, 1481 {test_bitspread, "BitSpread", "[size] [loop] [addr]", 1482 "test Bit Spread pattern", 1483 3 1484 }, 1485 {test_bitflip, "BitFlip", "[size] [loop] [addr]", 1486 "test Bit Flip pattern", 1487 3 1488 }, 1489 {test_walkbit0, "WalkingOnes", "[size] [loop] [addr]", 1490 "test Walking Ones pattern", 1491 3 1492 }, 1493 {test_walkbit1, "WalkingZeroes", "[size] [loop] [addr]", 1494 "test Walking Zeroes pattern", 1495 3 1496 }, 1497 /* need to the the 2 last one (infinite) : skipped for test all */ 1498 {test_read, "infinite read", "[addr] [pattern]", 1499 "basic test : infinite read access (random: addr=0xFFFFFFFF)", 2}, 1500 {test_write, "infinite write", "[addr] [pattern]", 1501 "basic test : infinite write access (random: addr=0xFFFFFFFF)", 2}, 1502}; 1503 1504const int test_nb = ARRAY_SIZE(test); 1505