define_command(sdrlevel, sdrlevel, "Perform read/write leveling", LITEDRAM_CMDS);
#endif
-/**
- * Command "memtest"
- *
- * Run a memory test
- *
- */
-#ifdef CSR_SDRAM_BASE
-define_command(memtest, memtest, "Run a memory test", LITEDRAM_CMDS);
-#endif
-
/**
* Command "spdread"
*
#include <stdio.h>
#include <stdlib.h>
+#include <memtest.h>
#include <generated/csr.h>
}
define_command(mc, mc, "Copy address space", MEM_CMDS);
+
+/**
+ * Command "memtest"
+ *
+ * Run a memory test
+ *
+ */
+static void memtest_handler(int nb_params, char **params)
+{
+ char *c;
+ unsigned int *addr;
+ unsigned long maxsize = ~0uL;
+
+ if (nb_params < 1) {
+ printf("memtest <addr> [<maxsize>]");
+ return;
+ }
+
+ addr = (unsigned int *)strtoul(params[0], &c, 0);
+ if (*c != 0) {
+ printf("Incorrect address");
+ return;
+ }
+
+ if (nb_params >= 2) {
+ maxsize = strtoul(params[1], &c, 0);
+ if (*c != 0) {
+ printf("Incorrect max size");
+ return;
+ }
+
+ }
+
+ memtest(addr, maxsize);
+}
+define_command(memtest, memtest_handler, "Run a memory test", MEM_CMDS);
+
+/**
+ * Command "memspeed"
+ *
+ * Run a memory speed test
+ *
+ */
+static void memspeed_handler(int nb_params, char **params)
+{
+ char *c;
+ unsigned int *addr;
+ unsigned long size;
+ bool read_only = false;
+
+ if (nb_params < 1) {
+ printf("memspeed <addr> <size> [<readonly>]");
+ return;
+ }
+
+ addr = (unsigned int *)strtoul(params[0], &c, 0);
+ if (*c != 0) {
+ printf("Incorrect address");
+ return;
+ }
+
+ size = strtoul(params[1], &c, 0);
+ if (*c != 0) {
+ printf("Incorrect size");
+ return;
+ }
+
+ if (nb_params >= 3) {
+ read_only = (bool) strtoul(params[2], &c, 0);
+ if (*c != 0) {
+ printf("Incorrect readonly value");
+ return;
+ }
+ }
+
+ memspeed(addr, size, read_only);
+}
+define_command(memspeed, memspeed_handler, "Run a memory speed test", MEM_CMDS);
+
+#ifdef CSR_DEBUG_PRINTER
+/**
+ * Command "csrprint"
+ *
+ * Print CSR values
+ *
+ */
+static void csrprint(int nb_params, char **params)
+{
+ print_csrs();
+}
+define_command(csrprint, csrprint, "Print CSR values", MEM_CMDS);
+#endif
+
+
+#ifdef CSR_WB_SOFTCONTROL_BASE
+static void wbr(int nb_params, char **params)
+{
+ char *c;
+ unsigned int *addr;
+ unsigned int length;
+ unsigned int i;
+
+ if (nb_params < 1) {
+ printf("mr <address> [length]");
+ return;
+ }
+ addr = (unsigned int *)strtoul(params[0], &c, 0);
+ if (*c != 0) {
+ printf("Incorrect address");
+ return;
+ }
+ if (nb_params == 1) {
+ length = 4;
+ } else {
+ length = strtoul(params[1], &c, 0);
+ if(*c != 0) {
+ printf("\nIncorrect length");
+ return;
+ }
+ }
+
+ for (i = 0; i < length; ++i) {
+ wb_softcontrol_adr_write((unsigned long)(addr + i));
+ wb_softcontrol_read_write(1);
+ printf("0x%08x: 0x%08x\n", (unsigned long)(addr + i), wb_softcontrol_data_read());
+ }
+}
+define_command(wbr, wbr, "Read using softcontrol wishbone controller", MEM_CMDS);
+
+static void wbw(int nb_params, char **params)
+{
+ char *c;
+ unsigned int *addr;
+ unsigned int value;
+ unsigned int count;
+ unsigned int i;
+
+ if (nb_params < 2) {
+ printf("mw <address> <value> [count]");
+ return;
+ }
+
+ addr = (unsigned int *)strtoul(params[0], &c, 0);
+ if (*c != 0) {
+ printf("Incorrect address");
+ return;
+ }
+
+ value = strtoul(params[1], &c, 0);
+ if(*c != 0) {
+ printf("Incorrect value");
+ return;
+ }
+
+ if (nb_params == 2) {
+ count = 1;
+ } else {
+ count = strtoul(params[2], &c, 0);
+ if(*c != 0) {
+ printf("Incorrect count");
+ return;
+ }
+ }
+
+ wb_softcontrol_data_write(value);
+ for (i = 0; i < count; i++) {
+ wb_softcontrol_adr_write((unsigned long)(addr + i));
+ wb_softcontrol_write_write(1);
+ }
+}
+define_command(wbw, wbw, "Write using softcontrol wishbone controller", MEM_CMDS);
+#endif
--- /dev/null
+#include <limits.h>
+
+/*
+ * Copyright (C) 2020, Anton Blanchard <anton@linux.ibm.com>, IBM
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY 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) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Galois LFSR
+ *
+ * Polynomials verified with https://bitbucket.org/gallen/mlpolygen/
+ */
+static inline unsigned long lfsr(unsigned long bits, unsigned long prev)
+{
+ static const unsigned long lfsr_taps[] = {
+ 0x0,
+ 0x0,
+ 0x3,
+ 0x6,
+ 0xc,
+ 0x14,
+ 0x30,
+ 0x60,
+ 0xb8,
+ 0x110,
+ 0x240,
+ 0x500,
+ 0x829,
+ 0x100d,
+ 0x2015,
+ 0x6000,
+ 0xd008,
+ 0x12000,
+ 0x20400,
+ 0x40023,
+ 0x90000,
+ 0x140000,
+ 0x300000,
+ 0x420000,
+ 0xe10000,
+ 0x1200000,
+ 0x2000023,
+ 0x4000013,
+ 0x9000000,
+ 0x14000000,
+ 0x20000029,
+ 0x48000000,
+ 0x80200003,
+#if __WORDSIZE == 64
+ 0x100080000,
+ 0x204000003,
+ 0x500000000,
+ 0x801000000,
+ 0x100000001f,
+ 0x2000000031,
+ 0x4400000000,
+ 0xa000140000,
+ 0x12000000000,
+ 0x300000c0000,
+ 0x63000000000,
+ 0xc0000030000,
+ 0x1b0000000000,
+ 0x300003000000,
+ 0x420000000000,
+ 0xc00000180000,
+ 0x1008000000000,
+ 0x3000000c00000,
+ 0x6000c00000000,
+ 0x9000000000000,
+ 0x18003000000000,
+ 0x30000000030000,
+ 0x40000040000000,
+ 0xc0000600000000,
+ 0x102000000000000,
+ 0x200004000000000,
+ 0x600003000000000,
+ 0xc00000000000000,
+ 0x1800300000000000,
+ 0x3000000000000030,
+ 0x6000000000000000,
+ 0x800000000000000d
+#endif
+ };
+ unsigned long lsb = prev & 1;
+
+ prev >>= 1;
+ prev ^= (-lsb) & lfsr_taps[bits];
+
+ return prev;
+}
--- /dev/null
+#ifndef __MEMTEST_H
+#define __MEMTEST_H
+
+#include <stdbool.h>
+
+int memtest(unsigned int *addr, unsigned long maxsize);
+void memspeed(unsigned int *addr, unsigned long size, bool read_only);
+
+int memtest_addr(unsigned int *addr, unsigned long size, int random);
+int memtest_data(unsigned int *addr, unsigned long size, int random);
+int memtest_bus(unsigned int *addr, unsigned long size);
+
+#endif /* __MEMTEST_H */
strcasecmp.o \
i2c.o \
div64.o \
- progress.o
+ progress.o \
+ memtest.o
all: crt0.o libbase.a libbase-nofloat.a
--- /dev/null
+#include "memtest.h"
+
+#include <stdio.h>
+#include <lfsr.h>
+
+#include <system.h>
+#include <generated/soc.h>
+#include <generated/csr.h>
+
+// #define MEMTEST_BUS_DEBUG
+// #define MEMTEST_DATA_DEBUG
+// #define MEMTEST_ADDR_DEBUG
+
+#ifndef MEMTEST_BUS_SIZE
+#define MEMTEST_BUS_SIZE (512)
+#endif
+
+#ifndef MEMTEST_DATA_SIZE
+#define MEMTEST_DATA_SIZE (2*1024*1024)
+#endif
+#define MEMTEST_DATA_RANDOM 1
+
+#ifndef MEMTEST_ADDR_SIZE
+#define MEMTEST_ADDR_SIZE (32*1024)
+#endif
+#define MEMTEST_ADDR_RANDOM 0
+
+#define ONEZERO 0xAAAAAAAA
+#define ZEROONE 0x55555555
+
+static unsigned int seed_to_data_32(unsigned int seed, int random)
+{
+ return random ? lfsr(32, seed) : seed + 1;
+}
+
+static unsigned short seed_to_data_16(unsigned short seed, int random)
+{
+ return random ? lfsr(16, seed) : seed + 1;
+}
+
+int memtest_bus(unsigned int *addr, unsigned long size)
+{
+ volatile unsigned int *array = addr;
+ int i, errors;
+ unsigned int rdata;
+
+ errors = 0;
+
+ for(i = 0; i < size/4;i++) {
+ array[i] = ONEZERO;
+ }
+ flush_cpu_dcache();
+#ifdef CONFIG_L2_SIZE
+ flush_l2_cache();
+#endif
+ for(i = 0; i < size/4; i++) {
+ rdata = array[i];
+ if(rdata != ONEZERO) {
+ errors++;
+#ifdef MEMTEST_BUS_DEBUG
+ printf("[bus: 0x%0x]: 0x%08x vs 0x%08x\n", i, rdata, ONEZERO);
+#endif
+ }
+ }
+
+ for(i = 0; i < size/4; i++) {
+ array[i] = ZEROONE;
+ }
+ flush_cpu_dcache();
+#ifdef CONFIG_L2_SIZE
+ flush_l2_cache();
+#endif
+ for(i = 0; i < size/4; i++) {
+ rdata = array[i];
+ if(rdata != ZEROONE) {
+ errors++;
+#ifdef MEMTEST_BUS_DEBUG
+ printf("[bus 0x%0x]: 0x%08x vs 0x%08x\n", i, rdata, ZEROONE);
+#endif
+ }
+ }
+
+ return errors;
+}
+
+int memtest_data(unsigned int *addr, unsigned long size, int random)
+{
+ volatile unsigned int *array = addr;
+ int i, errors;
+ unsigned int seed_32;
+ unsigned int rdata;
+
+ errors = 0;
+ seed_32 = 1;
+
+ for(i = 0; i < size/4; i++) {
+ seed_32 = seed_to_data_32(seed_32, random);
+ array[i] = seed_32;
+ }
+
+ seed_32 = 1;
+ flush_cpu_dcache();
+#ifdef CONFIG_L2_SIZE
+ flush_l2_cache();
+#endif
+ for(i = 0; i < size/4; i++) {
+ seed_32 = seed_to_data_32(seed_32, random);
+ rdata = array[i];
+ if(rdata != seed_32) {
+ errors++;
+#ifdef MEMTEST_DATA_DEBUG
+ printf("[data 0x%0x]: 0x%08x vs 0x%08x\n", i, rdata, seed_32);
+#endif
+ }
+ }
+
+ return errors;
+}
+
+int memtest_addr(unsigned int *addr, unsigned long size, int random)
+{
+ volatile unsigned int *array = addr;
+ int i, errors;
+ unsigned short seed_16;
+ unsigned short rdata;
+
+ errors = 0;
+ seed_16 = 1;
+
+ for(i = 0; i < size/4; i++) {
+ seed_16 = seed_to_data_16(seed_16, random);
+ array[(unsigned int) seed_16] = i;
+ }
+
+ seed_16 = 1;
+ flush_cpu_dcache();
+#ifdef CONFIG_L2_SIZE
+ flush_l2_cache();
+#endif
+ for(i = 0; i < size/4; i++) {
+ seed_16 = seed_to_data_16(seed_16, random);
+ rdata = array[(unsigned int) seed_16];
+ if(rdata != i) {
+ errors++;
+#ifdef MEMTEST_ADDR_DEBUG
+ printf("[addr 0x%0x]: 0x%08x vs 0x%08x\n", i, rdata, i);
+#endif
+ }
+ }
+
+ return errors;
+}
+
+void memspeed(unsigned int *addr, unsigned long size, bool read_only)
+{
+ volatile unsigned int *array = addr;
+ int i;
+ unsigned int start, end;
+ unsigned long write_speed = 0;
+ unsigned long read_speed;
+ __attribute__((unused)) unsigned long data;
+ const unsigned int sz = sizeof(unsigned long);
+
+ /* init timer */
+ timer0_en_write(0);
+ timer0_reload_write(0);
+ timer0_load_write(0xffffffff);
+ timer0_en_write(1);
+
+ /* write speed */
+ if (!read_only) {
+ timer0_update_value_write(1);
+ start = timer0_value_read();
+ for(i = 0; i < size/sz; i++) {
+ array[i] = i;
+ }
+ timer0_update_value_write(1);
+ end = timer0_value_read();
+ write_speed = (8*size*(CONFIG_CLOCK_FREQUENCY/1000000))/(start - end);
+ }
+
+ /* flush CPU and L2 caches */
+ flush_cpu_dcache();
+#ifdef CONFIG_L2_SIZE
+ flush_l2_cache();
+#endif
+
+ /* read speed */
+ timer0_en_write(1);
+ timer0_update_value_write(1);
+ start = timer0_value_read();
+ for(i = 0; i < size/sz; i++) {
+ data = array[i];
+ }
+ timer0_update_value_write(1);
+ end = timer0_value_read();
+ read_speed = (8*size*(CONFIG_CLOCK_FREQUENCY/1000000))/(start - end);
+
+ printf("Memspeed Writes: %ldMbps Reads: %ldMbps\n", write_speed, read_speed);
+}
+
+int memtest(unsigned int *addr, unsigned long maxsize)
+{
+ int bus_errors, data_errors, addr_errors;
+ unsigned long bus_size = MEMTEST_BUS_SIZE < maxsize ? MEMTEST_BUS_SIZE : maxsize;
+ unsigned long data_size = MEMTEST_DATA_SIZE < maxsize ? MEMTEST_DATA_SIZE : maxsize;
+ unsigned long addr_size = MEMTEST_ADDR_SIZE < maxsize ? MEMTEST_ADDR_SIZE : maxsize;
+
+ bus_errors = memtest_bus(addr, bus_size);
+ if(bus_errors != 0)
+ printf("Memtest bus failed: %d/%d errors\n", bus_errors, bus_size/4);
+
+ data_errors = memtest_data(addr, data_size, MEMTEST_DATA_RANDOM);
+ if(data_errors != 0)
+ printf("Memtest data failed: %d/%d errors\n", data_errors, data_size/4);
+
+ addr_errors = memtest_addr(addr, addr_size, MEMTEST_ADDR_RANDOM);
+ if(addr_errors != 0)
+ printf("Memtest addr failed: %d/%d errors\n", addr_errors, addr_size/4);
+
+ if(bus_errors + data_errors + addr_errors != 0)
+ return 0;
+ else {
+ printf("Memtest OK\n");
+ memspeed(addr, data_size, false);
+ return 1;
+ }
+}
+++ /dev/null
-#include <limits.h>
-
-/*
- * Copyright (C) 2020, Anton Blanchard <anton@linux.ibm.com>, IBM
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
-
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY 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) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Galois LFSR
- *
- * Polynomials verified with https://bitbucket.org/gallen/mlpolygen/
- */
-static inline unsigned long lfsr(unsigned long bits, unsigned long prev)
-{
- static const unsigned long lfsr_taps[] = {
- 0x0,
- 0x0,
- 0x3,
- 0x6,
- 0xc,
- 0x14,
- 0x30,
- 0x60,
- 0xb8,
- 0x110,
- 0x240,
- 0x500,
- 0x829,
- 0x100d,
- 0x2015,
- 0x6000,
- 0xd008,
- 0x12000,
- 0x20400,
- 0x40023,
- 0x90000,
- 0x140000,
- 0x300000,
- 0x420000,
- 0xe10000,
- 0x1200000,
- 0x2000023,
- 0x4000013,
- 0x9000000,
- 0x14000000,
- 0x20000029,
- 0x48000000,
- 0x80200003,
-#if __WORDSIZE == 64
- 0x100080000,
- 0x204000003,
- 0x500000000,
- 0x801000000,
- 0x100000001f,
- 0x2000000031,
- 0x4400000000,
- 0xa000140000,
- 0x12000000000,
- 0x300000c0000,
- 0x63000000000,
- 0xc0000030000,
- 0x1b0000000000,
- 0x300003000000,
- 0x420000000000,
- 0xc00000180000,
- 0x1008000000000,
- 0x3000000c00000,
- 0x6000c00000000,
- 0x9000000000000,
- 0x18003000000000,
- 0x30000000030000,
- 0x40000040000000,
- 0xc0000600000000,
- 0x102000000000000,
- 0x200004000000000,
- 0x600003000000000,
- 0xc00000000000000,
- 0x1800300000000000,
- 0x3000000000000030,
- 0x6000000000000000,
- 0x800000000000000d
-#endif
- };
- unsigned long lsb = prev & 1;
-
- prev >>= 1;
- prev ^= (-lsb) & lfsr_taps[bits];
-
- return prev;
-}
#include <stdio.h>
#include <stdlib.h>
+#include <memtest.h>
+#include <lfsr.h>
#ifdef CSR_SDRAM_BASE
#include <generated/sdram_phy.h>
#include <system.h>
#include "sdram.h"
-#include "lfsr.h"
// FIXME(hack): If we don't have main ram, just target the sram instead.
#ifndef MAIN_RAM_BASE
#define MAIN_RAM_BASE SRAM_BASE
#endif
+#ifndef MAIN_RAM_SIZE
+#define MAIN_RAM_SIZE SRAM_SIZE
+#endif
__attribute__((unused)) static void cdelay(int i)
{
#endif /* CSR_SDRAM_BASE */
-static unsigned int seed_to_data_32(unsigned int seed, int random)
-{
- if (random)
- return lfsr(32, seed);
- else
- return seed + 1;
-}
-
-static unsigned short seed_to_data_16(unsigned short seed, int random)
-{
- if (random)
- return lfsr(16, seed);
- else
- return seed + 1;
-}
-
-#define ONEZERO 0xAAAAAAAA
-#define ZEROONE 0x55555555
-
-#ifndef MEMTEST_BUS_SIZE
-#define MEMTEST_BUS_SIZE (512)
-#endif
-
-//#define MEMTEST_BUS_DEBUG
-
-static int memtest_bus(void)
-{
- volatile unsigned int *array = (unsigned int *)MAIN_RAM_BASE;
- int i, errors;
- unsigned int rdata;
-
- errors = 0;
-
- for(i=0;i<MEMTEST_BUS_SIZE/4;i++) {
- array[i] = ONEZERO;
- }
- flush_cpu_dcache();
-#ifdef CONFIG_L2_SIZE
- flush_l2_cache();
-#endif
- for(i=0;i<MEMTEST_BUS_SIZE/4;i++) {
- rdata = array[i];
- if(rdata != ONEZERO) {
- errors++;
-#ifdef MEMTEST_BUS_DEBUG
- printf("[bus: 0x%0x]: 0x%08x vs 0x%08x\n", i, rdata, ONEZERO);
-#endif
- }
- }
-
- for(i=0;i<MEMTEST_BUS_SIZE/4;i++) {
- array[i] = ZEROONE;
- }
- flush_cpu_dcache();
-#ifdef CONFIG_L2_SIZE
- flush_l2_cache();
-#endif
- for(i=0;i<MEMTEST_BUS_SIZE/4;i++) {
- rdata = array[i];
- if(rdata != ZEROONE) {
- errors++;
-#ifdef MEMTEST_BUS_DEBUG
- printf("[bus 0x%0x]: 0x%08x vs 0x%08x\n", i, rdata, ZEROONE);
-#endif
- }
- }
-
- return errors;
-}
-
-#ifndef MEMTEST_DATA_SIZE
-#define MEMTEST_DATA_SIZE (2*1024*1024)
-#endif
-#define MEMTEST_DATA_RANDOM 1
-
-//#define MEMTEST_DATA_DEBUG
-
-static int memtest_data(void)
-{
- volatile unsigned int *array = (unsigned int *)MAIN_RAM_BASE;
- int i, errors;
- unsigned int seed_32;
- unsigned int rdata;
-
- errors = 0;
- seed_32 = 1;
-
- for(i=0;i<MEMTEST_DATA_SIZE/4;i++) {
- seed_32 = seed_to_data_32(seed_32, MEMTEST_DATA_RANDOM);
- array[i] = seed_32;
- }
-
- seed_32 = 1;
- flush_cpu_dcache();
-#ifdef CONFIG_L2_SIZE
- flush_l2_cache();
-#endif
- for(i=0;i<MEMTEST_DATA_SIZE/4;i++) {
- seed_32 = seed_to_data_32(seed_32, MEMTEST_DATA_RANDOM);
- rdata = array[i];
- if(rdata != seed_32) {
- errors++;
-#ifdef MEMTEST_DATA_DEBUG
- printf("[data 0x%0x]: 0x%08x vs 0x%08x\n", i, rdata, seed_32);
-#endif
- }
- }
-
- return errors;
-}
-#ifndef MEMTEST_ADDR_SIZE
-#define MEMTEST_ADDR_SIZE (32*1024)
-#endif
-#define MEMTEST_ADDR_RANDOM 0
-//#define MEMTEST_ADDR_DEBUG
-
-static int memtest_addr(void)
-{
- volatile unsigned int *array = (unsigned int *)MAIN_RAM_BASE;
- int i, errors;
- unsigned short seed_16;
- unsigned short rdata;
- errors = 0;
- seed_16 = 1;
-
- for(i=0;i<MEMTEST_ADDR_SIZE/4;i++) {
- seed_16 = seed_to_data_16(seed_16, MEMTEST_ADDR_RANDOM);
- array[(unsigned int) seed_16] = i;
- }
-
- seed_16 = 1;
- flush_cpu_dcache();
-#ifdef CONFIG_L2_SIZE
- flush_l2_cache();
-#endif
- for(i=0;i<MEMTEST_ADDR_SIZE/4;i++) {
- seed_16 = seed_to_data_16(seed_16, MEMTEST_ADDR_RANDOM);
- rdata = array[(unsigned int) seed_16];
- if(rdata != i) {
- errors++;
-#ifdef MEMTEST_ADDR_DEBUG
- printf("[addr 0x%0x]: 0x%08x vs 0x%08x\n", i, rdata, i);
-#endif
- }
- }
-
- return errors;
-}
-
-static void memspeed(void)
-{
- volatile unsigned long *array = (unsigned long *)MAIN_RAM_BASE;
- int i;
- unsigned int start, end;
- unsigned long write_speed;
- unsigned long read_speed;
- __attribute__((unused)) unsigned long data;
- const unsigned int sz = sizeof(unsigned long);
-
- /* init timer */
- timer0_en_write(0);
- timer0_reload_write(0);
- timer0_load_write(0xffffffff);
- timer0_en_write(1);
-
- /* write speed */
- timer0_update_value_write(1);
- start = timer0_value_read();
- for(i=0;i<MEMTEST_DATA_SIZE/sz;i++) {
- array[i] = i;
- }
- timer0_update_value_write(1);
- end = timer0_value_read();
- write_speed = (8*MEMTEST_DATA_SIZE*(CONFIG_CLOCK_FREQUENCY/1000000))/(start - end);
-
- /* flush CPU and L2 caches */
- flush_cpu_dcache();
-#ifdef CONFIG_L2_SIZE
- flush_l2_cache();
-#endif
-
- /* read speed */
- timer0_en_write(1);
- timer0_update_value_write(1);
- start = timer0_value_read();
- for(i=0;i<MEMTEST_DATA_SIZE/sz;i++) {
- data = array[i];
- }
- timer0_update_value_write(1);
- end = timer0_value_read();
- read_speed = (8*MEMTEST_DATA_SIZE*(CONFIG_CLOCK_FREQUENCY/1000000))/(start - end);
-
- printf("Memspeed Writes: %ldMbps Reads: %ldMbps\n", write_speed, read_speed);
-}
-
-int memtest(void)
-{
- int bus_errors, data_errors, addr_errors;
-
- bus_errors = memtest_bus();
- if(bus_errors != 0)
- printf("Memtest bus failed: %d/%d errors\n", bus_errors, 2*128);
-
- data_errors = memtest_data();
- if(data_errors != 0)
- printf("Memtest data failed: %d/%d errors\n", data_errors, MEMTEST_DATA_SIZE/4);
-
- addr_errors = memtest_addr();
- if(addr_errors != 0)
- printf("Memtest addr failed: %d/%d errors\n", addr_errors, MEMTEST_ADDR_SIZE/4);
-
- if(bus_errors + data_errors + addr_errors != 0)
- return 0;
- else {
- printf("Memtest OK\n");
- memspeed();
- return 1;
- }
-}
#ifdef CSR_SDRAM_BASE
#endif
#endif
sdrhw();
- if(!memtest()) {
+ if(!memtest((unsigned int *) MAIN_RAM_BASE, MAIN_RAM_SIZE)) {
#ifdef CSR_DDRCTRL_BASE
ddrctrl_init_done_write(1);
ddrctrl_init_error_write(1);
int sdrlevel(void);
-int memtest_silent(void);
-int memtest(void);
int sdrinit(void);
#if defined(DDRPHY_CMD_DELAY) || defined(USDDRPHY_DEBUG)