bios: move memtest from liblitedram to libbase
authorJędrzej Boczar <jboczar@antmicro.com>
Wed, 24 Jun 2020 10:21:34 +0000 (12:21 +0200)
committerJędrzej Boczar <jboczar@antmicro.com>
Wed, 24 Jun 2020 12:53:18 +0000 (14:53 +0200)
litex/soc/software/bios/cmds/cmd_litedram.c
litex/soc/software/bios/cmds/cmd_mem.c
litex/soc/software/include/base/lfsr.h [new file with mode: 0644]
litex/soc/software/include/base/memtest.h [new file with mode: 0644]
litex/soc/software/libbase/Makefile
litex/soc/software/libbase/memtest.c [new file with mode: 0644]
litex/soc/software/liblitedram/lfsr.h [deleted file]
litex/soc/software/liblitedram/sdram.c
litex/soc/software/liblitedram/sdram.h

index 4c14d98b69c12b1c06b7371fe82d16b22112de49..d07cf750edc134253670e6899959b9a8a87c27dc 100644 (file)
@@ -216,16 +216,6 @@ define_command(sdrwloff, sdrwloff, "Disable write leveling", LITEDRAM_CMDS);
 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"
  *
index 01c607e1fc6cb91777101365bd102d2b0bb6cf5b..ad1638169b0b5aff6e8a538c94b6fa93b650eb61 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <memtest.h>
 
 #include <generated/csr.h>
 
@@ -137,3 +138,175 @@ static void mc(int nb_params, char **params)
 }
 
 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
diff --git a/litex/soc/software/include/base/lfsr.h b/litex/soc/software/include/base/lfsr.h
new file mode 100644 (file)
index 0000000..50dfccf
--- /dev/null
@@ -0,0 +1,109 @@
+#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;
+}
diff --git a/litex/soc/software/include/base/memtest.h b/litex/soc/software/include/base/memtest.h
new file mode 100644 (file)
index 0000000..1119608
--- /dev/null
@@ -0,0 +1,13 @@
+#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 */
index 1094ac5730b9599976f87a7623808f782e31df05..9aebad8e1604ea63e364305b822e27e5b5b466ca 100755 (executable)
@@ -17,7 +17,8 @@ OBJECTS = exception.o \
        strcasecmp.o      \
        i2c.o             \
        div64.o           \
-       progress.o
+       progress.o        \
+       memtest.o
 
 all: crt0.o libbase.a libbase-nofloat.a
 
diff --git a/litex/soc/software/libbase/memtest.c b/litex/soc/software/libbase/memtest.c
new file mode 100644 (file)
index 0000000..d3193da
--- /dev/null
@@ -0,0 +1,228 @@
+#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;
+       }
+}
diff --git a/litex/soc/software/liblitedram/lfsr.h b/litex/soc/software/liblitedram/lfsr.h
deleted file mode 100644 (file)
index 50dfccf..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-#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;
-}
index 3d35d1b40e2666dd81b5a6f90e0dfc370e123324..64ed5f1e1902e08da73b27b1455f19e61748f19a 100644 (file)
@@ -12,6 +12,8 @@
 
 #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)
 {
@@ -725,227 +729,8 @@ static void read_level(int module)
 
 #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
 
@@ -1051,7 +836,7 @@ int sdrinit(void)
 #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);
index 21433c03cf8cffa91b908e88031a1697d257cac1..565e9b5154d00c86fe88e381655b2e1d6076a823 100644 (file)
@@ -17,8 +17,6 @@ int write_level(void);
 
 int sdrlevel(void);
 
-int memtest_silent(void);
-int memtest(void);
 int sdrinit(void);
 
 #if defined(DDRPHY_CMD_DELAY) || defined(USDDRPHY_DEBUG)