summaryrefslogtreecommitdiffstats
path: root/cfe/cfe/arch/mips/common/src/ui_memtest.c
diff options
context:
space:
mode:
Diffstat (limited to 'cfe/cfe/arch/mips/common/src/ui_memtest.c')
-rw-r--r--cfe/cfe/arch/mips/common/src/ui_memtest.c282
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
+
+
+
+