1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * Test commands File: ui_memtest.c 5 * 6 * A simple memory test 7 * 8 * Author: Mitch Lichtenberg (mpl@broadcom.com) 9 * 10 ********************************************************************* 11 * 12 * Copyright 2000,2001,2002,2003 13 * Broadcom Corporation. All rights reserved. 14 * 15 * This software is furnished under license and may be used and 16 * copied only in accordance with the following terms and 17 * conditions. Subject to these conditions, you may download, 18 * copy, install, use, modify and distribute modified or unmodified 19 * copies of this software in source and/or binary form. No title 20 * or ownership is transferred hereby. 21 * 22 * 1) Any source code used, modified or distributed must reproduce 23 * and retain this copyright notice and list of conditions 24 * as they appear in the source file. 25 * 26 * 2) No right is granted to use any trade name, trademark, or 27 * logo of Broadcom Corporation. The "Broadcom Corporation" 28 * name may not be used to endorse or promote products derived 29 * from this software without the prior written permission of 30 * Broadcom Corporation. 31 * 32 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 33 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 34 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 35 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 36 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 37 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 38 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 39 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 40 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 41 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 42 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 43 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 44 * THE POSSIBILITY OF SUCH DAMAGE. 45 ********************************************************************* */ 46 47 48#include "sbmips.h" 49 50#include "lib_types.h" 51#include "lib_string.h" 52#include "lib_queue.h" 53#include "lib_malloc.h" 54#include "lib_printf.h" 55 56#include "cfe_iocb.h" 57#include "cfe_device.h" 58#include "cfe_console.h" 59#include "cfe_devfuncs.h" 60 61#include "cfe_error.h" 62 63#include "ui_command.h" 64#include "cfe.h" 65 66#include "bsp_config.h" 67 68#include "cfe_mem.h" 69 70 71#ifdef __long64 72static int ui_cmd_memorytest(ui_cmdline_t *cmd,int argc,char *argv[]); 73#endif 74 75#ifndef _SB_MAKE64 76#define _SB_MAKE64(x) ((uint64_t)(x)) 77#endif 78#ifndef _SB_MAKEMASK 79#define _SB_MAKEMASK(v,n) (_SB_MAKE64((_SB_MAKE64(1)<<(v))-1) << _SB_MAKE64(n)) 80#endif 81#ifndef _SB_MAKEMASK1 82#define _SB_MAKEMASK1(n) (_SB_MAKE64(1) << _SB_MAKE64(n)) 83#endif 84 85 86int ui_init_memtestcmds(void); 87 88int ui_init_memtestcmds(void) 89{ 90#ifdef __long64 91 cmd_addcmd("memorytest", 92 ui_cmd_memorytest, 93 NULL, 94 "Tests all available memory", 95 "", 96 "-loop;Loop forever or until keypress|" 97 "-stoponerror;Stop if error occurs while looping|" 98 "-cca=*;Use specified cacheability attribute|" 99 "-arena=*;Test only specified arena index"); 100#endif 101 return 0; 102} 103 104 105#ifdef __long64 106/* extensive memory tests */ 107 108static void inline uacwrite(volatile long *srcadr,long *dstadr) 109{ 110__asm __volatile ("ld $8, 0(%0) ; " 111 "ld $9, 8(%0) ; " 112 "ld $10, 16(%0) ; " 113 "ld $11, 24(%0) ; " 114 "sync ; " 115 "sd $8, 0(%1) ; " 116 "sd $9, 8(%1) ; " 117 "sd $10, 16(%1) ; " 118 "sd $11, 24(%1) ; " 119 "sync" :: "r"(srcadr),"r"(dstadr) : "$8","$9","$10","$11"); 120} 121 122 123#define TEST_DATA_LEN 4 124#define CACHE_LINE_LEN 32 125 126static int ui_cmd_memorytest(ui_cmdline_t *cmd,int argc,char *argv[]) 127{ 128 129 static volatile long test_data[TEST_DATA_LEN] = { 130 0xaaaaaaaaaaaaaaaa, 0x5555555555555555, 0xcccccccccccccccc, 0x3333333333333333, /* one cache line */ 131 }; 132 int arena, exitLoop; 133 int error; 134 int arena_type; 135 uint64_t arena_start, arena_size; 136 long phys_addr, offset, mem_base, cache_mem_base, i; 137 long *dst_adr, *cache_dst_adr; 138 long cda,tda; 139 int forever; 140 int passcnt; 141 int stoponerr = 0; 142 int cca = K_CALG_UNCACHED_ACCEL; 143 int arenanum = -1; 144 char *x; 145 146 arena = 0; 147 exitLoop = 0; 148 offset = 0; 149 mem_base = 0; 150 passcnt = 0; 151 error = 0; 152 153 forever = cmd_sw_isset(cmd,"-loop"); 154 stoponerr = cmd_sw_isset(cmd,"-stoponerror"); 155 if (cmd_sw_value(cmd,"-cca",&x)) cca = atoi(x); 156 if (cmd_sw_value(cmd,"-arena",&x)) arenanum = atoi(x); 157 158 printf("Available memory arenas:\n"); 159 while (cfe_arena_enum(arena, &arena_type, &arena_start, &arena_size, FALSE) == 0) { 160 phys_addr = (long) arena_start; /* actual physical address */ 161 mem_base = PHYS_TO_XKPHYS(cca, phys_addr); /* virtual address */ 162 xprintf("phys = %016llX, virt = %016llX, size = %016llX\n", phys_addr, mem_base, arena_size); 163 arena++; 164 } 165 166 printf("\nTesting memory.\n"); 167 do { 168 169 passcnt++; 170 if (forever) { 171 if (console_status()) break; 172 printf("***** Iteration %d *****\n",passcnt); 173 } 174 175 arena = 0; 176 exitLoop = 0; 177 error = 0; 178 179 while (cfe_arena_enum(arena, &arena_type, &arena_start, &arena_size, FALSE) == 0) { 180 181 if ((arenanum >= 0) && (arena != arenanum)) { 182 arena++; 183 continue; 184 } 185 186 test_data[0] = 0xAAAAAAAAAAAAAAAA; 187 test_data[1] = 0x5555555555555555; 188 test_data[2] = 0xCCCCCCCCCCCCCCCC; 189 test_data[3] = 0x3333333333333333; 190 191 phys_addr = (long) arena_start; /* actual physical address */ 192 mem_base = PHYS_TO_XKPHYS(cca, phys_addr); /* virtual address */ 193 cache_mem_base = PHYS_TO_K0(phys_addr); 194 195 xprintf("\n"); 196 xprintf("Testing: phys = %016llX, virt = %016llX, size = %016llX\n", phys_addr, mem_base, arena_size); 197 198 xprintf("Writing: a/5/c/3\n"); 199 200 for (offset = 0; (offset < arena_size); offset += CACHE_LINE_LEN) { 201 dst_adr = (long*)(mem_base+offset); 202 uacwrite(test_data, dst_adr); 203 } 204 205 xprintf("Reading: a/5/c/3\n"); 206 207 for (offset = 0; (offset < arena_size); offset += CACHE_LINE_LEN) { 208 dst_adr = (long*)(mem_base+offset); 209 cache_dst_adr = (long*)(mem_base+offset); 210 for (i = 0; i < TEST_DATA_LEN; i++) { 211 cda = cache_dst_adr[i]; 212 tda = test_data[i]; 213 if (cda != tda) { 214 xprintf("mem[%016llX] %016llX != %016llX\n", 215 mem_base+offset+(i*8), cda, tda); 216 exitLoop = 1; 217 } 218 } 219 if (exitLoop) break; 220 } 221 222 223 if (exitLoop) { 224 exitLoop = 0; 225 error++; 226 arena++; 227 continue; 228 } 229 230 xprintf("Writing: address|5555/inv/aaaa|address\n"); 231 exitLoop = 0; 232 233 for (offset = 0; (offset < arena_size); offset += CACHE_LINE_LEN) { 234 dst_adr = (long*)(mem_base+offset); 235 test_data[0] = ((long)dst_adr<<32)|0x55555555; 236 test_data[1] = ~test_data[0]; 237 test_data[2] = 0xaaaaaaaa00000000|((long)dst_adr & 0xffffffff); 238 test_data[3] = ~test_data[2]; 239 uacwrite(test_data, dst_adr); 240 } 241 242 xprintf("Reading: address|5555/inv/aaaa|address\n"); 243 244 for (offset = 0; (offset < arena_size); offset += CACHE_LINE_LEN) { 245 dst_adr = (long*)(mem_base+offset); 246 test_data[0] = ((long)dst_adr<<32)|0x55555555; 247 test_data[1] = ~test_data[0]; 248 test_data[2] = 0xaaaaaaaa00000000|((long)dst_adr & 0xffffffff); 249 test_data[3] = ~test_data[2]; 250 cache_dst_adr = (long*)(mem_base+offset); 251 for (i = 0; i < TEST_DATA_LEN; i++) { 252 cda = cache_dst_adr[i]; 253 tda = test_data[i]; 254 if (cda != tda) { 255 xprintf("mem[%016llX] %016llX != %016llX\n", 256 mem_base+offset+(i*8),cda,tda); 257 exitLoop = 1; 258 } 259 } 260 if (exitLoop) break; 261 } 262 263 if (exitLoop) { 264 error++; 265 exitLoop = 0; 266 if (stoponerr) forever = 0; 267 } 268 269 arena++; 270 } 271 } while (forever); 272 273 if (error) printf("Failing address: %016llX\n",mem_base+offset); 274 275 return error ? -1 : 0; 276} 277 278#endif 279