Merge branch 'master' of git://git.denx.de/u-boot-sh
authorTom Rini <trini@ti.com>
Thu, 20 Dec 2012 17:53:20 +0000 (10:53 -0700)
committerTom Rini <trini@ti.com>
Thu, 20 Dec 2012 17:53:20 +0000 (10:53 -0700)
README
boards.cfg
common/cmd_setexpr.c
common/cmd_sf.c
include/configs/eb_cpu5282.h
tools/env/fw_env.c
tools/env/fw_env_main.c

diff --git a/README b/README
index f386041..1d2e129 100644 (file)
--- a/README
+++ b/README
@@ -2390,6 +2390,11 @@ CBFS (Coreboot Filesystem) support
                CONFIG_SF_DEFAULT_MODE          (see include/spi.h)
                CONFIG_SF_DEFAULT_SPEED         in Hz
 
+               CONFIG_CMD_SF_TEST
+
+               Define this option to include a destructive SPI flash
+               test ('sf test').
+
 - SystemACE Support:
                CONFIG_SYSTEMACE
 
index 1d042ec..2acc941 100644 (file)
@@ -373,8 +373,8 @@ M5235EVB                     m68k        mcf523x     m5235evb            freesca
 M5235EVB_Flash32             m68k        mcf523x     m5235evb            freescale      -           M5235EVB:NORFLASH_PS32BIT,SYS_TEXT_BASE=0xFFC00000
 cobra5272                    m68k        mcf52x2     cobra5272           -
 idmr                         m68k        mcf52x2
-eb_cpu5282                   m68k        mcf52x2     eb_cpu5282          BuS            -           eb_cpu5282:SYS_TEXT_BASE=0xFF000000
-eb_cpu5282_internal          m68k        mcf52x2     eb_cpu5282          BuS            -           eb_cpu5282:SYS_TEXT_BASE=0xF0000000
+eb_cpu5282                   m68k        mcf52x2     eb_cpu5282          BuS            -           eb_cpu5282:SYS_TEXT_BASE=0xFF000000,SYS_MONITOR_BASE=0xFF000400
+eb_cpu5282_internal          m68k        mcf52x2     eb_cpu5282          BuS            -           eb_cpu5282:SYS_TEXT_BASE=0xF0000000,SYS_MONITOR_BASE=0xF0000418
 TASREG                       m68k        mcf52x2     tasreg              esd
 M5208EVBE                    m68k        mcf52x2     m5208evbe           freescale
 M5249EVB                     m68k        mcf52x2     m5249evb            freescale
index 7b140de..5a04295 100644 (file)
@@ -57,12 +57,22 @@ static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        int w;
 
        /* Validate arguments */
-       if ((argc != 5) || (strlen(argv[3]) != 1))
+       if (argc != 5 && argc != 3)
+               return CMD_RET_USAGE;
+       if (argc == 5 && strlen(argv[3]) != 1)
                return CMD_RET_USAGE;
 
        w = cmd_get_data_size(argv[0], 4);
 
        a = get_arg(argv[2], w);
+
+       if (argc == 3) {
+               sprintf(buf, "%lx", a);
+               setenv(argv[1], buf);
+
+               return 0;
+       }
+
        b = get_arg(argv[4], w);
 
        switch (argv[3][0]) {
@@ -87,8 +97,11 @@ static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 U_BOOT_CMD(
        setexpr, 5, 0, do_setexpr,
        "set environment variable as the result of eval expression",
-       "[.b, .w, .l] name value1 <op> value2\n"
+       "[.b, .w, .l] name [*]value1 <op> [*]value2\n"
        "    - set environment variable 'name' to the result of the evaluated\n"
        "      express specified by <op>.  <op> can be &, |, ^, +, -, *, /, %\n"
-       "      size argument is only meaningful if value1 and/or value2 are memory addresses"
+       "      size argument is only meaningful if value1 and/or value2 are\n"
+       "      memory addresses (*)\n"
+       "setexpr[.b, .w, .l] name *value\n"
+       "    - load a memory address into a variable"
 );
index 5ac1d0c..b175358 100644 (file)
@@ -5,6 +5,7 @@
  * Licensed under the GPL-2 or later.
  */
 
+#include <div64.h>
 #include <common.h>
 #include <malloc.h>
 #include <spi_flash.h>
@@ -67,6 +68,23 @@ static int sf_parse_len_arg(char *arg, ulong *len)
        return 1;
 }
 
+/**
+ * This function takes a byte length and a delta unit of time to compute the
+ * approximate bytes per second
+ *
+ * @param len          amount of bytes currently processed
+ * @param start_ms     start time of processing in ms
+ * @return bytes per second if OK, 0 on error
+ */
+static ulong bytes_per_second(unsigned int len, ulong start_ms)
+{
+       /* less accurate but avoids overflow */
+       if (len >= ((unsigned int) -1) / 1024)
+               return len / (max(get_timer(start_ms) / 1024, 1));
+       else
+               return 1024 * len / max(get_timer(start_ms), 1);
+}
+
 static int do_spi_flash_probe(int argc, char * const argv[])
 {
        unsigned int bus = CONFIG_SF_DEFAULT_BUS;
@@ -167,11 +185,26 @@ static int spi_flash_update(struct spi_flash *flash, u32 offset,
        const char *end = buf + len;
        size_t todo;            /* number of bytes to do in this pass */
        size_t skipped = 0;     /* statistics */
+       const ulong start_time = get_timer(0);
+       size_t scale = 1;
+       const char *start_buf = buf;
+       ulong delta;
 
+       if (end - buf >= 200)
+               scale = (end - buf) / 100;
        cmp_buf = malloc(flash->sector_size);
        if (cmp_buf) {
+               ulong last_update = get_timer(0);
+
                for (; buf < end && !err_oper; buf += todo, offset += todo) {
                        todo = min(end - buf, flash->sector_size);
+                       if (get_timer(last_update) > 100) {
+                               printf("   \rUpdating, %zu%% %lu B/s",
+                                       100 - (end - buf) / scale,
+                                       bytes_per_second(buf - start_buf,
+                                                        start_time));
+                               last_update = get_timer(0);
+                       }
                        err_oper = spi_flash_update_block(flash, offset, todo,
                                        buf, cmp_buf, &skipped);
                }
@@ -179,12 +212,17 @@ static int spi_flash_update(struct spi_flash *flash, u32 offset,
                err_oper = "malloc";
        }
        free(cmp_buf);
+       putc('\r');
        if (err_oper) {
                printf("SPI flash failed in %s step\n", err_oper);
                return 1;
        }
-       printf("%zu bytes written, %zu bytes skipped\n", len - skipped,
-              skipped);
+
+       delta = get_timer(start_time);
+       printf("%zu bytes written, %zu bytes skipped", len - skipped,
+               skipped);
+       printf(" in %ld.%lds, speed %ld B/s\n",
+               delta / 1000, delta % 1000, bytes_per_second(len, start_time));
 
        return 0;
 }
@@ -275,6 +313,161 @@ static int do_spi_flash_erase(int argc, char * const argv[])
        return 0;
 }
 
+#ifdef CONFIG_CMD_SF_TEST
+enum {
+       STAGE_ERASE,
+       STAGE_CHECK,
+       STAGE_WRITE,
+       STAGE_READ,
+
+       STAGE_COUNT,
+};
+
+static char *stage_name[STAGE_COUNT] = {
+       "erase",
+       "check",
+       "write",
+       "read",
+};
+
+struct test_info {
+       int stage;
+       int bytes;
+       unsigned base_ms;
+       unsigned time_ms[STAGE_COUNT];
+};
+
+static void show_time(struct test_info *test, int stage)
+{
+       uint64_t speed; /* KiB/s */
+       int bps;        /* Bits per second */
+
+       speed = (long long)test->bytes * 1000;
+       do_div(speed, test->time_ms[stage] * 1024);
+       bps = speed * 8;
+
+       printf("%d %s: %d ticks, %d KiB/s %d.%03d Mbps\n", stage,
+              stage_name[stage], test->time_ms[stage],
+              (int)speed, bps / 1000, bps % 1000);
+}
+
+static void spi_test_next_stage(struct test_info *test)
+{
+       test->time_ms[test->stage] = get_timer(test->base_ms);
+       show_time(test, test->stage);
+       test->base_ms = get_timer(0);
+       test->stage++;
+}
+
+/**
+ * Run a test on the SPI flash
+ *
+ * @param flash                SPI flash to use
+ * @param buf          Source buffer for data to write
+ * @param len          Size of data to read/write
+ * @param offset       Offset within flash to check
+ * @param vbuf         Verification buffer
+ * @return 0 if ok, -1 on error
+ */
+static int spi_flash_test(struct spi_flash *flash, char *buf, ulong len,
+                          ulong offset, char *vbuf)
+{
+       struct test_info test;
+       int i;
+
+       printf("SPI flash test:\n");
+       memset(&test, '\0', sizeof(test));
+       test.base_ms = get_timer(0);
+       test.bytes = len;
+       if (spi_flash_erase(flash, offset, len)) {
+               printf("Erase failed\n");
+               return -1;
+       }
+       spi_test_next_stage(&test);
+
+       if (spi_flash_read(flash, offset, len, vbuf)) {
+               printf("Check read failed\n");
+               return -1;
+       }
+       for (i = 0; i < len; i++) {
+               if (vbuf[i] != 0xff) {
+                       printf("Check failed at %d\n", i);
+                       print_buffer(i, vbuf + i, 1, min(len - i, 0x40), 0);
+                       return -1;
+               }
+       }
+       spi_test_next_stage(&test);
+
+       if (spi_flash_write(flash, offset, len, buf)) {
+               printf("Write failed\n");
+               return -1;
+       }
+       memset(vbuf, '\0', len);
+       spi_test_next_stage(&test);
+
+       if (spi_flash_read(flash, offset, len, vbuf)) {
+               printf("Read failed\n");
+               return -1;
+       }
+       spi_test_next_stage(&test);
+
+       for (i = 0; i < len; i++) {
+               if (buf[i] != vbuf[i]) {
+                       printf("Verify failed at %d, good data:\n", i);
+                       print_buffer(i, buf + i, 1, min(len - i, 0x40), 0);
+                       printf("Bad data:\n");
+                       print_buffer(i, vbuf + i, 1, min(len - i, 0x40), 0);
+                       return -1;
+               }
+       }
+       printf("Test passed\n");
+       for (i = 0; i < STAGE_COUNT; i++)
+               show_time(&test, i);
+
+       return 0;
+}
+
+static int do_spi_flash_test(int argc, char * const argv[])
+{
+       unsigned long offset;
+       unsigned long len;
+       char *buf = (char *)CONFIG_SYS_TEXT_BASE;
+       char *endp;
+       char *vbuf;
+       int ret;
+
+       offset = simple_strtoul(argv[1], &endp, 16);
+       if (*argv[1] == 0 || *endp != 0)
+               return -1;
+       len = simple_strtoul(argv[2], &endp, 16);
+       if (*argv[2] == 0 || *endp != 0)
+               return -1;
+
+       vbuf = malloc(len);
+       if (!vbuf) {
+               printf("Cannot allocate memory\n");
+               return 1;
+       }
+       buf = malloc(len);
+       if (!buf) {
+               free(vbuf);
+               printf("Cannot allocate memory\n");
+               return 1;
+       }
+
+       memcpy(buf, (char *)CONFIG_SYS_TEXT_BASE, len);
+       ret = spi_flash_test(flash, buf, len, offset, vbuf);
+       free(vbuf);
+       free(buf);
+       if (ret) {
+               printf("Test failed\n");
+               return 1;
+       }
+
+       return 0;
+}
+#endif /* CONFIG_CMD_SF_TEST */
+
 static int do_spi_flash(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
        const char *cmd;
@@ -304,6 +497,10 @@ static int do_spi_flash(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[
                ret = do_spi_flash_read_write(argc, argv);
        else if (strcmp(cmd, "erase") == 0)
                ret = do_spi_flash_erase(argc, argv);
+#ifdef CONFIG_CMD_SF_TEST
+       else if (!strcmp(cmd, "test"))
+               ret = do_spi_flash_test(argc, argv);
+#endif
        else
                ret = -1;
 
@@ -315,6 +512,13 @@ usage:
        return CMD_RET_USAGE;
 }
 
+#ifdef CONFIG_CMD_SF_TEST
+#define SF_TEST_HELP "\nsf test offset len             " \
+               "- run a very basic destructive test"
+#else
+#define SF_TEST_HELP
+#endif
+
 U_BOOT_CMD(
        sf,     5,      1,      do_spi_flash,
        "SPI flash sub-system",
@@ -328,4 +532,5 @@ U_BOOT_CMD(
        "                                 `+len' round up `len' to block size\n"
        "sf update addr offset len      - erase and write `len' bytes from memory\n"
        "                                 at `addr' to flash at `offset'"
+       SF_TEST_HELP
 );
index 5a0d321..459f568 100644 (file)
 #define CONFIG_SYS_SDRAM_BASE          CONFIG_SYS_SDRAM_BASE0
 #define        CONFIG_SYS_SDRAM_SIZE           CONFIG_SYS_SDRAM_SIZE0
 
-/* If M5282 port is fully implemented the monitor base will be behind
- * the vector table. */
-#if (CONFIG_SYS_TEXT_BASE !=  CONFIG_SYS_INT_FLASH_BASE)
-#define CONFIG_SYS_MONITOR_BASE        (CONFIG_SYS_TEXT_BASE + 0x400)
-#else
-#define CONFIG_SYS_MONITOR_BASE        (CONFIG_SYS_TEXT_BASE + 0x418) /* 24 Byte for CFM-Config */
-#endif
-
 #define CONFIG_SYS_MONITOR_LEN         0x20000
 #define CONFIG_SYS_MALLOC_LEN          (256 << 10)
 #define CONFIG_SYS_BOOTPARAMS_LEN      64*1024
index 90c7a5d..37b60b8 100644 (file)
@@ -429,7 +429,8 @@ int fw_env_write(char *name, char *value)
  */
 int fw_setenv(int argc, char *argv[])
 {
-       int i, len;
+       int i;
+       size_t len;
        char *name;
        char *value = NULL;
 
index c855f4c..40ea3f6 100644 (file)
@@ -94,7 +94,7 @@ int main(int argc, char *argv[])
        int lockfd = -1;
        int retval = EXIT_SUCCESS;
 
-       lockfd = open(lockname, O_WRONLY | O_CREAT | O_TRUNC);
+       lockfd = open(lockname, O_WRONLY | O_CREAT | O_TRUNC, 0666);
        if (-1 == lockfd) {
                fprintf(stderr, "Error opening lock file %s\n", lockname);
                return EXIT_FAILURE;