diff options
Diffstat (limited to 'cfe/cfe/arch/mips/common/src/ui_memtest.c')
-rw-r--r-- | cfe/cfe/arch/mips/common/src/ui_memtest.c | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/cfe/cfe/arch/mips/common/src/ui_memtest.c b/cfe/cfe/arch/mips/common/src/ui_memtest.c new file mode 100644 index 0000000..5388fd8 --- /dev/null +++ b/cfe/cfe/arch/mips/common/src/ui_memtest.c @@ -0,0 +1,282 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * Test commands File: ui_memtest.c + * + * A simple memory test + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + + +#include "sbmips.h" + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" + +#include "cfe_iocb.h" +#include "cfe_device.h" +#include "cfe_console.h" +#include "cfe_devfuncs.h" + +#include "cfe_error.h" + +#include "ui_command.h" +#include "cfe.h" + +#include "bsp_config.h" + +#include "cfe_mem.h" + + +#ifdef __long64 +static int ui_cmd_memorytest(ui_cmdline_t *cmd,int argc,char *argv[]); +#endif + +#ifndef _SB_MAKE64 +#define _SB_MAKE64(x) ((uint64_t)(x)) +#endif +#ifndef _SB_MAKEMASK +#define _SB_MAKEMASK(v,n) (_SB_MAKE64((_SB_MAKE64(1)<<(v))-1) << _SB_MAKE64(n)) +#endif +#ifndef _SB_MAKEMASK1 +#define _SB_MAKEMASK1(n) (_SB_MAKE64(1) << _SB_MAKE64(n)) +#endif + + +int ui_init_memtestcmds(void); + +int ui_init_memtestcmds(void) +{ +#ifdef __long64 + cmd_addcmd("memorytest", + ui_cmd_memorytest, + NULL, + "Tests all available memory", + "", + "-loop;Loop forever or until keypress|" + "-stoponerror;Stop if error occurs while looping|" + "-cca=*;Use specified cacheability attribute|" + "-arena=*;Test only specified arena index"); +#endif + return 0; +} + + +#ifdef __long64 +/* extensive memory tests */ + +static void inline uacwrite(volatile long *srcadr,long *dstadr) +{ +__asm __volatile ("ld $8, 0(%0) ; " + "ld $9, 8(%0) ; " + "ld $10, 16(%0) ; " + "ld $11, 24(%0) ; " + "sync ; " + "sd $8, 0(%1) ; " + "sd $9, 8(%1) ; " + "sd $10, 16(%1) ; " + "sd $11, 24(%1) ; " + "sync" :: "r"(srcadr),"r"(dstadr) : "$8","$9","$10","$11"); +} + + +#define TEST_DATA_LEN 4 +#define CACHE_LINE_LEN 32 + +static int ui_cmd_memorytest(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + + static volatile long test_data[TEST_DATA_LEN] = { + 0xaaaaaaaaaaaaaaaa, 0x5555555555555555, 0xcccccccccccccccc, 0x3333333333333333, /* one cache line */ + }; + int arena, exitLoop; + int error; + int arena_type; + uint64_t arena_start, arena_size; + long phys_addr, offset, mem_base, cache_mem_base, i; + long *dst_adr, *cache_dst_adr; + long cda,tda; + int forever; + int passcnt; + int stoponerr = 0; + int cca = K_CALG_UNCACHED_ACCEL; + int arenanum = -1; + char *x; + + arena = 0; + exitLoop = 0; + offset = 0; + mem_base = 0; + passcnt = 0; + error = 0; + + forever = cmd_sw_isset(cmd,"-loop"); + stoponerr = cmd_sw_isset(cmd,"-stoponerror"); + if (cmd_sw_value(cmd,"-cca",&x)) cca = atoi(x); + if (cmd_sw_value(cmd,"-arena",&x)) arenanum = atoi(x); + + printf("Available memory arenas:\n"); + while (cfe_arena_enum(arena, &arena_type, &arena_start, &arena_size, FALSE) == 0) { + phys_addr = (long) arena_start; /* actual physical address */ + mem_base = PHYS_TO_XKPHYS(cca, phys_addr); /* virtual address */ + xprintf("phys = %016llX, virt = %016llX, size = %016llX\n", phys_addr, mem_base, arena_size); + arena++; + } + + printf("\nTesting memory.\n"); + do { + + passcnt++; + if (forever) { + if (console_status()) break; + printf("***** Iteration %d *****\n",passcnt); + } + + arena = 0; + exitLoop = 0; + error = 0; + + while (cfe_arena_enum(arena, &arena_type, &arena_start, &arena_size, FALSE) == 0) { + + if ((arenanum >= 0) && (arena != arenanum)) { + arena++; + continue; + } + + test_data[0] = 0xAAAAAAAAAAAAAAAA; + test_data[1] = 0x5555555555555555; + test_data[2] = 0xCCCCCCCCCCCCCCCC; + test_data[3] = 0x3333333333333333; + + phys_addr = (long) arena_start; /* actual physical address */ + mem_base = PHYS_TO_XKPHYS(cca, phys_addr); /* virtual address */ + cache_mem_base = PHYS_TO_K0(phys_addr); + + xprintf("\n"); + xprintf("Testing: phys = %016llX, virt = %016llX, size = %016llX\n", phys_addr, mem_base, arena_size); + + xprintf("Writing: a/5/c/3\n"); + + for (offset = 0; (offset < arena_size); offset += CACHE_LINE_LEN) { + dst_adr = (long*)(mem_base+offset); + uacwrite(test_data, dst_adr); + } + + xprintf("Reading: a/5/c/3\n"); + + for (offset = 0; (offset < arena_size); offset += CACHE_LINE_LEN) { + dst_adr = (long*)(mem_base+offset); + cache_dst_adr = (long*)(mem_base+offset); + for (i = 0; i < TEST_DATA_LEN; i++) { + cda = cache_dst_adr[i]; + tda = test_data[i]; + if (cda != tda) { + xprintf("mem[%016llX] %016llX != %016llX\n", + mem_base+offset+(i*8), cda, tda); + exitLoop = 1; + } + } + if (exitLoop) break; + } + + + if (exitLoop) { + exitLoop = 0; + error++; + arena++; + continue; + } + + xprintf("Writing: address|5555/inv/aaaa|address\n"); + exitLoop = 0; + + for (offset = 0; (offset < arena_size); offset += CACHE_LINE_LEN) { + dst_adr = (long*)(mem_base+offset); + test_data[0] = ((long)dst_adr<<32)|0x55555555; + test_data[1] = ~test_data[0]; + test_data[2] = 0xaaaaaaaa00000000|((long)dst_adr & 0xffffffff); + test_data[3] = ~test_data[2]; + uacwrite(test_data, dst_adr); + } + + xprintf("Reading: address|5555/inv/aaaa|address\n"); + + for (offset = 0; (offset < arena_size); offset += CACHE_LINE_LEN) { + dst_adr = (long*)(mem_base+offset); + test_data[0] = ((long)dst_adr<<32)|0x55555555; + test_data[1] = ~test_data[0]; + test_data[2] = 0xaaaaaaaa00000000|((long)dst_adr & 0xffffffff); + test_data[3] = ~test_data[2]; + cache_dst_adr = (long*)(mem_base+offset); + for (i = 0; i < TEST_DATA_LEN; i++) { + cda = cache_dst_adr[i]; + tda = test_data[i]; + if (cda != tda) { + xprintf("mem[%016llX] %016llX != %016llX\n", + mem_base+offset+(i*8),cda,tda); + exitLoop = 1; + } + } + if (exitLoop) break; + } + + if (exitLoop) { + error++; + exitLoop = 0; + if (stoponerr) forever = 0; + } + + arena++; + } + } while (forever); + + if (error) printf("Failing address: %016llX\n",mem_base+offset); + + return error ? -1 : 0; +} + +#endif + + + + |