1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * Test commands File: ui_memtest.c 5 * 6 * Modified by : Khin Zaw 7 * 8 * a complete memory test 9 * 10 * A simple memory test 11 * 12 * Author: Mitch Lichtenberg 13 * 14 ********************************************************************* 15 * 16 * Copyright 2000,2001,2002,2003 17 * Broadcom Corporation. All rights reserved. 18 * 19 * This software is furnished under license and may be used and 20 * copied only in accordance with the following terms and 21 * conditions. Subject to these conditions, you may download, 22 * copy, install, use, modify and distribute modified or unmodified 23 * copies of this software in source and/or binary form. No title 24 * or ownership is transferred hereby. 25 * 26 * 1) Any source code used, modified or distributed must reproduce 27 * and retain this copyright notice and list of conditions 28 * as they appear in the source file. 29 * 30 * 2) No right is granted to use any trade name, trademark, or 31 * logo of Broadcom Corporation. The "Broadcom Corporation" 32 * name may not be used to endorse or promote products derived 33 * from this software without the prior written permission of 34 * Broadcom Corporation. 35 * 36 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 37 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 38 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 39 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 40 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 41 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 42 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 43 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 44 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 45 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 46 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 47 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 48 * THE POSSIBILITY OF SUCH DAMAGE. 49 ********************************************************************* */ 50 51 52#include "cfe.h" 53#include "sbmips.h" 54 55#include "ui_command.h" 56 57#include "cfe_mem.h" 58#include "lib_hssubr.h" 59#include "exception.h" 60 61#ifdef _BIGSUR_ 62#include "bcm1480_regs.h" 63#include "bcm1480_scd.h" 64#endif 65 66static int ui_cmd_memorytest(ui_cmdline_t *cmd,int argc,char *argv[]); 67#ifndef BCM47XX 68static int ui_cmd_randmemtest(ui_cmdline_t *cmd,int argc,char *argv[]); 69#endif 70 71#ifndef _SB_MAKE64 72#define _SB_MAKE64(x) ((uint64_t)(x)) 73#endif 74#ifndef _SB_MAKEMASK 75#define _SB_MAKEMASK(v,n) (_SB_MAKE64((_SB_MAKE64(1)<<(v))-1) << _SB_MAKE64(n)) 76#endif 77#ifndef _SB_MAKEMASK1 78#define _SB_MAKEMASK1(n) (_SB_MAKE64(1) << _SB_MAKE64(n)) 79#endif 80 81 82int ui_init_memtestcmds(void); 83 84int ui_init_memtestcmds(void) 85{ 86 cmd_addcmd("memorytest", 87 ui_cmd_memorytest, 88 NULL, 89 "Tests all available memory", 90 "", 91 "-loop;Loop forever or until keypress|" 92 "-stoponerror;Stop if error occurs while looping|" 93 "-cca=*;Use specified cacheability attribute|" 94 "-arena=*;Test only specified arena index"); 95 96#ifndef BCM47XX 97 cmd_addcmd("randmemtest", 98 ui_cmd_randmemtest, 99 NULL, 100 "Tests memory using random access pattern", 101 "randmemtest [num_mb]", 102 "-loop;Loop forever or until keypress|" 103 "-stoponerror;Stop if error occurs while looping|" 104 "-cca=*;Use specified cacheability attribute|" 105 "-ignoreerror;Ignore errors, don't print anything|" 106 "-arena=*;Test only specified arena index"); 107#endif /* BCM47XX */ 108 return 0; 109} 110 111 112/* extensive memory tests */ 113 114static void inline uacwrite(volatile uint64_t *srcadr,hsaddr_t dstadr) 115{ 116__asm __volatile ("ld $8, 0(%0) ; " 117 "ld $9, 8(%0) ; " 118 "ld $10, 16(%0) ; " 119 "ld $11, 24(%0) ; " 120 "sync ; " 121 ".align 4 ; " 122 "sd $8, 0(%1) ; " 123 "sd $9, 8(%1) ; " 124 "sd $10, 16(%1) ; " 125 "sd $11, 24(%1) ; " 126 "sync" :: "r"(srcadr),"r"(dstadr) : "$8","$9","$10","$11"); 127} 128 129static void inline readline(hsaddr_t srcadr,volatile uint64_t *dstadr) 130{ 131__asm __volatile ("ld $8, 0(%0) ; " 132 "ld $9, 8(%0) ; " 133 "ld $10, 16(%0) ; " 134 "ld $11, 24(%0) ; " 135 "sd $8, 0(%1) ; " 136 "sd $9, 8(%1) ; " 137 "sd $10, 16(%1) ; " 138 "sd $11, 24(%1) ; " 139 :: "r"(srcadr),"r"(dstadr) : "$8","$9","$10","$11"); 140} 141 142 143#define TEST_DATA_LEN 4 144#define CACHE_LINE_LEN 32 145 146static int test_arena(hsaddr_t arena_start,hsaddr_t arena_size,int cca,int stoponerror); 147 148 149static int ui_cmd_memorytest(ui_cmdline_t *cmd,int argc,char *argv[]) 150{ 151 int arena; 152 int error; 153 int arena_type; 154 uint64_t arena_start, arena_size; 155 int forever; 156 int passcnt; 157 int stoponerr = 0; 158 hsaddr_t phys_addr; 159 hsaddr_t mem_base; 160 int cca = K_CALG_UNCACHED_ACCEL; 161 int arenanum = -1; 162 char *x; 163 int res; 164 165 forever = cmd_sw_isset(cmd,"-loop"); 166 stoponerr = cmd_sw_isset(cmd,"-stoponerror"); 167 if (cmd_sw_value(cmd,"-cca",&x)) cca = atoi(x); 168 if (cmd_sw_value(cmd,"-arena",&x)) arenanum = atoi(x); 169 170 printf("Available memory arenas:\n"); 171 arena = 0; 172 while (cfe_arena_enum(arena, &arena_type, &arena_start, &arena_size, FALSE) == 0) { 173 phys_addr = arena_start; /* actual physical address */ 174#if CPUCFG_REGS64 175 mem_base = PHYS_TO_XKPHYS(cca, phys_addr); /* virtual address */ 176#else 177 mem_base = PHYS_TO_K1(phys_addr); /* virtual address */ 178#endif 179 xprintf("phys = %016llX, virt = %016llX, size = %016llX\n", phys_addr, mem_base, arena_size); 180 arena++; 181 } 182 183 passcnt = 0; 184 res = 0; 185 186 printf("\nTesting memory.\n"); 187 do { 188 189 passcnt++; 190 if (forever) { 191 if (console_status()) break; 192 printf("***** Iteration %d *****\n",passcnt); 193 } 194 195 arena = 0; 196 error = 0; 197 198 while (cfe_arena_enum(arena, &arena_type, &arena_start, &arena_size, FALSE) == 0) { 199 200 /* 201 * See if we were asked to do just one part of memory. 202 */ 203 204 if ((arenanum >= 0) && (arena != arenanum)) { 205 arena++; 206 continue; 207 } 208 209 /* 210 * If we enumerated the locore area, avoid it. 211 */ 212 213 if (arena_start == 0) { 214 arena_start += CFE_LOCORE_GLOBAL_END; 215 arena_size -= CFE_LOCORE_GLOBAL_END; 216 } 217 218 res = test_arena(arena_start,arena_size,cca,stoponerr); 219 220 if (stoponerr && (res < 0)) { 221 forever = 0; 222 break; 223 } 224 arena++; 225 } 226 227 } while (forever); 228 229 return res; 230} 231 232static int test_arena(hsaddr_t arena_start,hsaddr_t arena_size,int cca,int stoponerr) 233{ 234 235 static volatile uint64_t test_data[TEST_DATA_LEN]; 236 static volatile uint64_t check_data[TEST_DATA_LEN]; 237 int exitLoop; 238 int error; 239 hsaddr_t phys_addr; 240 hsaddr_t offset; 241 hsaddr_t mem_base; 242 long i; 243 hsaddr_t dst_adr, cache_dst_adr; 244 long cda,tda; 245 246 phys_addr = arena_start; /* actual physical address */ 247#if CPUCFG_REGS64 248 mem_base = PHYS_TO_XKPHYS(cca, phys_addr); /* virtual address */ 249#else 250 mem_base = PHYS_TO_K1(phys_addr); /* virtual address */ 251#endif 252 253 xprintf("\n"); 254 xprintf("Testing: phys = %016llX, virt = %016llX, size = %016llX\n", 255 phys_addr, mem_base, arena_size); 256 257int testno, patno ; 258 259#define NUMTESTNO 12 260 261typedef struct testinfo_s { 262 char *testname; 263 int num_patterns; 264 uint64_t test_pattern[64]; 265} testinfo_t; 266 267const testinfo_t test_patterns[] = { 268 {"All Zeros",4, {0,0,0,0}}, 269 {"All Ones",4, {0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL}} , 270 {"Alternate Zeros/Ones",4, {0ULL,0xFFFFFFFFFFFFFFFFULL,0ULL,0xFFFFFFFFFFFFFFFFULL}} , 271 {"Checker Board",4, {0xAAAAAAAAAAAAAAAAULL,0x5555555555555555ULL,0xAAAAAAAAAAAAAAAAULL,0x5555555555555555ULL}} , 272 {"Walking 1 byte(8)",8, {0x0101010101010101ULL,0x0202020202020202ULL,0x0404040404040404ULL,0x0808080808080808ULL, 273 0x1010101010101010ULL,0x2020202020202020ULL,0x4040404040404040ULL,0x8080808080808080ULL}} , 274 {"Walking 1 word(16)",16,{0x0001000100010001ULL,0x0002000200020002ULL,0x0004000400040004ULL,0x0008000800080008ULL, 275 0x0010001000100010ULL,0x0020002000200020ULL,0x0040004000400040ULL,0x0080008000800080ULL, 276 0x0100010001000100ULL,0x0200020002000200ULL,0x0400040004000400ULL,0x0800080008000800ULL, 277 0x1000100010001000ULL,0x2000200020002000ULL,0x4000400040004000ULL,0x8000800080008000ULL}} , 278 {"Walking 0 byte(8)",8, {0xFEFEFEFEFEFEFEFEULL,0xFDFDFDFDFDFDFDFDULL,0xFBFBFBFBFBFBFBFBULL,0xF7F7F7F7F7F7F7F7ULL, 279 0xEFEFEFEFEFEFEFEFULL,0xDFDFDFDFDFDFDFDFULL,0xBFBFBFBFBFBFBFBFULL,0x7F7F7F7F7F7F7F7FULL}} , 280 {"Walking 0 word(16)",16,{0xFFFEFFFEFFFEFFFEULL,0xFFFDFFFDFFFDFFFDULL,0xFFFBFFFBFFFBFFFBULL,0xFFF7FFF7FFF7FFF7ULL, 281 0xFFEFFFEFFFEFFFEFULL,0xFFDFFFDFFFDFFFDFULL,0xFFBFFFBFFFBFFFBFULL,0xFF7FFF7FFF7FFF7FULL, 282 0xFEFFFEFFFEFFFEFFULL,0xFDFFFDFFFDFFFDFFULL,0xFBFFFBFFFBFFFBFFULL,0xF7FFF7FFF7FFF7FFULL, 283 0xEFFFEFFFEFFFEFFFULL,0xDFFFDFFFDFFFDFFFULL,0xBFFFBFFFBFFFBFFFULL,0x7FFF7FFF7FFF7FFFULL}}, 284 {"Walking ECC8 0 ",8, {0x0000004000808082ULL,0x0000004000808084ULL,0x0000004000808090ULL,0x0000004000800001ULL, // fe fd fb f7 285 0x0000004000008001ULL,0x0000000000808001ULL,0x0000000000000080ULL,0x0000004000808081ULL}} ,// ef df bf 7f 286 {"Walking ECC8 1 ",8, {0x0000004000808014ULL,0x0000004000808012ULL,0x0000004000808006ULL,0x0000004000800097ULL, // 01 02 04 08 287 0x0000004000008097ULL,0x0000000000808097ULL,0x0000000000000016ULL,0x0000004000808017ULL}} ,// 10 20 40 80 288 {"Crosstalk 1",64, {0x0001000100010001ULL,0xFFFFFFFFFFFFFFFFULL,0x0001000100010001ULL,0xFFFFFFFFFFFFFFFFULL, 289 0x0002000200020002ULL,0xFFFFFFFFFFFFFFFFULL,0x0002000200020002ULL,0xFFFFFFFFFFFFFFFFULL, 290 0x0004000400040004ULL,0xFFFFFFFFFFFFFFFFULL,0x0004000400040004ULL,0xFFFFFFFFFFFFFFFFULL, 291 0x0008000800080008ULL,0xFFFFFFFFFFFFFFFFULL,0x0008000800080008ULL,0xFFFFFFFFFFFFFFFFULL, 292 0x0010001000100010ULL,0xFFFFFFFFFFFFFFFFULL,0x0010001000100010ULL,0xFFFFFFFFFFFFFFFFULL, 293 0x0020002000200020ULL,0xFFFFFFFFFFFFFFFFULL,0x0020002000200020ULL,0xFFFFFFFFFFFFFFFFULL, 294 0x0040004000400040ULL,0xFFFFFFFFFFFFFFFFULL,0x0040004000400040ULL,0xFFFFFFFFFFFFFFFFULL, 295 0x0080008000800080ULL,0xFFFFFFFFFFFFFFFFULL,0x0080008000800080ULL,0xFFFFFFFFFFFFFFFFULL, 296 0x0100010001000100ULL,0xFFFFFFFFFFFFFFFFULL,0x0100010001000100ULL,0xFFFFFFFFFFFFFFFFULL, 297 0x0200020002000200ULL,0xFFFFFFFFFFFFFFFFULL,0x0200020002000200ULL,0xFFFFFFFFFFFFFFFFULL, 298 0x0400040004000400ULL,0xFFFFFFFFFFFFFFFFULL,0x0400040004000400ULL,0xFFFFFFFFFFFFFFFFULL, 299 0x0800080008000800ULL,0xFFFFFFFFFFFFFFFFULL,0x0800080008000800ULL,0xFFFFFFFFFFFFFFFFULL, 300 0x1000100010001000ULL,0xFFFFFFFFFFFFFFFFULL,0x1000100010001000ULL,0xFFFFFFFFFFFFFFFFULL, 301 0x2000200020002000ULL,0xFFFFFFFFFFFFFFFFULL,0x2000200020002000ULL,0xFFFFFFFFFFFFFFFFULL, 302 0x4000400040004000ULL,0xFFFFFFFFFFFFFFFFULL,0x4000400040004000ULL,0xFFFFFFFFFFFFFFFFULL, 303 0x8000800080008000ULL,0xFFFFFFFFFFFFFFFFULL,0x8000800080008000ULL,0xFFFFFFFFFFFFFFFFULL }} , 304 {"Crosstalk 0",64, {0xFFFEFFFEFFFEFFFEULL,0,0xFFFEFFFEFFFEFFFEULL,0, 305 0xFFFDFFFDFFFDFFFDULL,0,0xFFFDFFFDFFFDFFFDULL,0, 306 0xFFFBFFFBFFFBFFFBULL,0,0xFFFBFFFBFFFBFFFBULL,0, 307 0xFFF7FFF7FFF7FFF7ULL,0,0xFFF7FFF7FFF7FFF7ULL,0, 308 0xFFEFFFEFFFEFFFEFULL,0,0xFFEFFFEFFFEFFFEFULL,0, 309 0xFFDFFFDFFFDFFFDFULL,0,0xFFDFFFDFFFDFFFDFULL,0, 310 0xFFBFFFBFFFBFFFBFULL,0,0xFFBFFFBFFFBFFFBFULL,0, 311 0xFF7FFF7FFF7FFF7FULL,0,0xFF7FFF7FFF7FFF7FULL,0, 312 0xFEFFFEFFFEFFFEFFULL,0,0xFEFFFEFFFEFFFEFFULL,0, 313 0xFDFFFDFFFDFFFDFFULL,0,0xFDFFFDFFFDFFFDFFULL,0, 314 0xFBFFFBFFFBFFFBFFULL,0,0xFBFFFBFFFBFFFBFFULL,0, 315 0xF7FFF7FFF7FFF7FFULL,0,0xF7FFF7FFF7FFF7FFULL,0, 316 0xEFFFEFFFEFFFEFFFULL,0,0xEFFFEFFFEFFFEFFFULL,0, 317 0xDFFFDFFFDFFFDFFFULL,0,0xDFFFDFFFDFFFDFFFULL,0, 318 0xBFFFBFFFBFFFBFFFULL,0,0xBFFFBFFFBFFFBFFFULL,0, 319 0x7FFF7FFF7FFF7FFFULL,0,0x7FFF7FFF7FFF7FFFULL,0}} 320} ; 321// address test 322 xprintf("Address test :Writing: [address|5555][~][aaaa|address][~] "); 323 exitLoop = 0; 324 325 for (offset = 0; (offset < arena_size); offset += CACHE_LINE_LEN) { 326 dst_adr = (mem_base+offset); 327 test_data[0] = ((uint64_t)dst_adr<<32)|0x55555555; 328 test_data[1] = ~test_data[0]; 329 test_data[2] = 0xaaaaaaaa00000000ULL|(dst_adr & 0xffffffff); 330 test_data[3] = ~test_data[2]; 331 uacwrite(test_data, dst_adr); 332 if ((dst_adr>>28)&((dst_adr&0xfffffff)==0)) xprintf("."); 333 } 334 335 xprintf("Reading: "); 336 337 error = 0; 338 for (offset = 0; (offset < arena_size); offset += CACHE_LINE_LEN) { 339 dst_adr = (mem_base+offset); 340 test_data[0] = ((uint64_t)dst_adr<<32)|0x55555555; 341 test_data[1] = ~test_data[0]; 342 test_data[2] = 0xaaaaaaaa00000000ULL|(dst_adr & 0xffffffff); 343 test_data[3] = ~test_data[2]; 344 cache_dst_adr = (mem_base+offset); 345 readline(cache_dst_adr,check_data); 346 if ((dst_adr>>28)&((dst_adr&0xfffffff)==0)) xprintf("."); 347 for (i = 0; i < TEST_DATA_LEN; i++) { 348 cda = check_data[i]; 349 tda = test_data[i]; 350 if (cda != tda) { 351 xprintf("mem[%016llX] %016llX != %016llX\n", 352 mem_base+offset+(i*8),cda,tda); 353 error++; 354 } 355 } 356 if (error) break; 357 } 358 xprintf("Done!\n"); 359 360 if (error) return -1; 361 // data test 362 for (testno = 0 ; testno < NUMTESTNO ; testno++ ) { 363 364 xprintf("Data Test %d : writing %s. ",testno,test_patterns[testno].testname); 365 366 patno = 0 ; 367 for (offset = 0; (offset < arena_size); offset += CACHE_LINE_LEN) { 368 dst_adr = (mem_base+offset); 369 test_data[0] = test_patterns[testno].test_pattern[patno]; 370 test_data[1] = test_patterns[testno].test_pattern[patno+1]; 371 test_data[2] = test_patterns[testno].test_pattern[patno+2]; 372 test_data[3] = test_patterns[testno].test_pattern[patno+3]; 373 uacwrite(test_data, dst_adr); 374 //if (testno==6) xprintf("W[%016llx]=%016llx,%016llx %016llx,%016llx\n",dst_adr,test_data[0],test_data[1],test_data[2],test_data[3]); 375 if (patno+4 < test_patterns[testno].num_patterns) patno+=4; 376 else patno = 0 ; 377 } 378 379 380 xprintf("Reading and checking :"); 381 382 error = 0; 383 patno=0 ; 384 for (offset = 0; (offset < arena_size); offset += CACHE_LINE_LEN) { 385 dst_adr = (mem_base+offset); 386 cache_dst_adr = (mem_base+offset); 387 test_data[0] = test_patterns[testno].test_pattern[patno]; 388 test_data[1] = test_patterns[testno].test_pattern[patno+1]; 389 test_data[2] = test_patterns[testno].test_pattern[patno+2]; 390 test_data[3] = test_patterns[testno].test_pattern[patno+3]; 391 //if (testno==6) xprintf("R[%016llx]=%016llx,%016llx %016llx,%016llx\n",dst_adr,test_data[0],test_data[1],test_data[2],test_data[3]); 392 if(patno+4 < test_patterns[testno].num_patterns) patno+=4; 393 else patno = 0 ; 394 395 readline(cache_dst_adr,check_data); 396 for (i = 0; i < TEST_DATA_LEN; i++) { 397 cda = check_data[i]; 398 tda = test_data[i]; 399 if (cda != tda) { 400 xprintf("mem[%016llX] %016llX != %016llX\n", 401 mem_base+offset+(i*8), cda, tda); 402 error++; 403 if (error > 25) return -1; 404 } 405 if (error) break; 406 } 407 } 408 xprintf(" Done!\n"); 409// end of patterns 410 } 411// 412 return error ? -1 : 0; 413} 414 415#define LFSR_M 22 416#define LFSR_TAP 21 417//#define LFSR_PERIOD 0x3fff80 418#define LFSR_PERIOD 0x3ffff 419 420static inline unsigned long nextval(unsigned long regval) 421{ 422 unsigned long newbit; 423 424 newbit = (regval & 1) ^ ((regval & (1<<(LFSR_M - LFSR_TAP))) != 0); 425 426 regval = (regval >> 1) | (newbit << (LFSR_M-1)); 427 428 return regval; 429} 430 431 432#ifndef BCM47XX 433#define START_PHYS 0x1000 434static int randmemtest(int num_mb,int high_mb,int cca,int stoponerr,int ignoreerr) 435{ 436#if CPUCFG_REGS64 437 hsaddr_t membase = PHYS_TO_XKPHYS(cca,START_PHYS); 438#else 439 hsaddr_t membase = PHYS_TO_K1(START_PHYS); /* UNCACHED virtual address */ 440#endif 441 unsigned long lfsr; 442 uint64_t idx; 443 uint64_t maxidx; 444 uint64_t highlfsr; 445 int error = 0; 446 register uint64_t pattern0,pattern1,pattern2,pattern3,x; 447 448 highlfsr = (high_mb << 15); 449 if (highlfsr == 0) highlfsr = 0x3fff80; 450 451 maxidx = (uint64_t) ((num_mb << 15)-1); 452 453 printf("Highest physaddr is %016llX\n",highlfsr<<5); 454 printf("Writing (memory base %016llX)\n",membase); 455 lfsr = (1<<LFSR_M)-1; 456 for (idx = 0; idx < maxidx; idx++) { 457 pattern0 = 0x5555555555555555ULL ^ (lfsr | (lfsr << LFSR_M)); pattern1 = ~pattern0; 458 pattern3 = 0xaaaaaaaaaaaaaaaaULL ^ (idx | (idx << LFSR_M)) ; pattern2 = ~pattern3; 459 460 if (lfsr < highlfsr) { 461 __asm __volatile ( " .align 4 ; " 462 " sd %0,0(%4) ; " 463 " sd %1,8(%4) ; " 464 " sd %2,16(%4) ; " 465 " sd %3,24(%4) ; " 466 : : "r"(pattern0),"r"(pattern1),"r"(pattern2),"r"(pattern3), 467 "r"(membase+(hsaddr_t)(lfsr << 5))); 468 } 469 lfsr = nextval(lfsr); 470 } 471 472 printf("Reading.\n"); 473 lfsr = (1<<LFSR_M)-1; 474 for (idx = 0; idx < maxidx; idx++) { 475 476 if (lfsr < highlfsr) { /* stay within 128MB */ 477 hsaddr_t addr = (membase + (hsaddr_t)(lfsr<<5)); 478 __asm __volatile ( " ld %0,0(%4) ; " 479 " ld %1,8(%4) ; " 480 " ld %2,16(%4) ; " 481 " ld %3,24(%4)" 482 : "=r"(pattern0),"=r"(pattern1),"=r"(pattern2),"=r"(pattern3) : "r"(addr)); 483 484 if (!ignoreerr) { 485 x = 0x5555555555555555ULL ^ (lfsr | (lfsr << LFSR_M)); 486 if (pattern0 != x) { 487 printf("mem[%016llX] %016llX should be %016llX (%016llX)\n",addr,pattern0,x,pattern0^x); 488 error++; 489 if (console_status()) break; 490 } 491 492 x = ~x; 493 if (pattern1 != x) { 494 printf("mem[%016llX] %016llX should be %016llX (%016llX)\n",addr+8,pattern1,x,pattern1^x); 495 error++; 496 if (console_status()) break; 497 } 498 499 x = 0xaaaaaaaaaaaaaaaaULL ^ (idx | (idx << LFSR_M)); 500 if (pattern3 != x) { 501 printf("mem[%016llX] %016llX should be %016llX (%016llX)\n",addr+24,pattern3,x,pattern3^x); 502 error++; 503 if (console_status()) break; 504 } 505 506 x = ~x; 507 if (pattern2 != x) { 508 printf("mem[%016llX] %016llX should be %016llX (%016llX)\n",addr+16,pattern2,x,pattern2^x); 509 error++; 510 if (console_status()) break; 511 } 512 } 513 514 if (error && stoponerr) break; 515 } 516 lfsr = nextval(lfsr); 517 } 518 return error; 519} 520 521static int ui_cmd_randmemtest(ui_cmdline_t *cmd,int argc,char *argv[]) 522{ 523 int stoponerr = 1; 524 int ignoreerr = 0; 525 char *x; 526 int cca = K_CALG_UNCACHED_ACCEL; 527 int forever; 528 int error = 0; 529 int res; 530 int num_mb = 128; 531 int high_mb = 128; 532 533 ignoreerr = cmd_sw_isset(cmd,"-ignoreerror"); 534 stoponerr = cmd_sw_isset(cmd,"-stoponerror"); 535 if (cmd_sw_value(cmd,"-cca",&x)) cca = atoi(x); 536 forever = cmd_sw_isset(cmd,"-loop"); 537 538 if ((x = cmd_getarg(cmd,0))) num_mb = atoi(x); 539 if (num_mb > 128) num_mb = 128; 540 541 if ((x = cmd_getarg(cmd,1))) high_mb = atoi(x); 542 if (high_mb > 128) high_mb = 128; 543 544 do { 545#ifdef _BIGSUR_ 546 SBWRITECSR(A_BUS_L2_ERRORS,0); 547 SBWRITECSR(A_BUS_MEM_IO_ERRORS,0); 548#endif 549 res = randmemtest(num_mb,high_mb,cca,stoponerr,ignoreerr); 550 if (res != 0) error = -1; 551 if ((res != 0) && stoponerr) break; 552#ifdef _BIGSUR_ 553 do { 554 uint64_t l2reg,memreg; 555 l2reg = SBREADCSR(A_BUS_L2_ERRORS); 556 memreg = SBREADCSR(A_BUS_MEM_IO_ERRORS); 557 printf("L2: CorrECC=%d BadECC=%d Mem: CorrECC=%d BadECC=%d\n", 558 (int)G_SCD_L2ECC_CORR_D(l2reg),(int)G_SCD_L2ECC_BAD_D(l2reg), 559 (int)G_SCD_MEM_ECC_CORR(memreg),(int)G_SCD_MEM_ECC_BAD(memreg)); 560 } while (0); 561#endif 562 } while (forever && !console_status()); 563 564 return error; 565} 566#endif /* !BCM47XX */ 567 568