sandbox: Allow reading/writing of RAM buffer
authorSimon Glass <sjg@chromium.org>
Sun, 10 Nov 2013 17:27:03 +0000 (10:27 -0700)
committerSimon Glass <sjg@chromium.org>
Thu, 9 Jan 2014 00:25:03 +0000 (17:25 -0700)
It is useful to be able to save and restore the RAM contents of sandbox
U-Boot either for setting up tests, for later analysys, or for chaining
together multiple tests which need to keep the same memory contents.

Add a function to provide a memory file for U-Boot. This is read on
start-up and written when shutting down. If the file does not exist
on start-up, it will be created when shutting down.

Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Simon Glass <sjg@chromium.org>
arch/sandbox/cpu/cpu.c
arch/sandbox/cpu/os.c
arch/sandbox/cpu/start.c
arch/sandbox/cpu/state.c
arch/sandbox/include/asm/global_data.h
arch/sandbox/include/asm/state.h
common/board_f.c
include/os.h

index bc7641a8081f07a6a8778a493ccaa7a5835bb58a..38019e0b48e57585b0e89f23ab929c9cad5f2edc 100644 (file)
@@ -5,11 +5,15 @@
 
 #include <common.h>
 #include <os.h>
+#include <asm/state.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
 void reset_cpu(ulong ignored)
 {
+       if (state_uninit())
+               os_exit(2);
+
        /* This is considered normal termination for now */
        os_exit(0);
 }
index ef6a651a60327906fd4c9d29cfd419464cf23bce..725b505177d33938cee5cf4ce8308bb13bf11c9a 100644 (file)
@@ -399,3 +399,42 @@ void os_puts(const char *str)
        while (*str)
                os_putc(*str++);
 }
+
+int os_write_ram_buf(const char *fname)
+{
+       struct sandbox_state *state = state_get_current();
+       int fd, ret;
+
+       fd = open(fname, O_CREAT | O_WRONLY, 0777);
+       if (fd < 0)
+               return -ENOENT;
+       ret = write(fd, state->ram_buf, state->ram_size);
+       close(fd);
+       if (ret != state->ram_size)
+               return -EIO;
+
+       return 0;
+}
+
+int os_read_ram_buf(const char *fname)
+{
+       struct sandbox_state *state = state_get_current();
+       int fd, ret;
+       int size;
+
+       size = os_get_filesize(fname);
+       if (size < 0)
+               return -ENOENT;
+       if (size != state->ram_size)
+               return -ENOSPC;
+       fd = open(fname, O_RDONLY);
+       if (fd < 0)
+               return -ENOENT;
+
+       ret = read(fd, state->ram_buf, state->ram_size);
+       close(fd);
+       if (ret != state->ram_size)
+               return -EIO;
+
+       return 0;
+}
index 579ece44711ea40e7134f6b70750e0a48157cec2..452f2a98f3609d9c36ec64234f5f371ac8b90821 100644 (file)
@@ -4,12 +4,11 @@
  */
 
 #include <common.h>
+#include <os.h>
 #include <asm/getopt.h>
 #include <asm/sections.h>
 #include <asm/state.h>
 
-#include <os.h>
-
 DECLARE_GLOBAL_DATA_PTR;
 
 int sandbox_early_getopt_check(void)
@@ -108,6 +107,25 @@ static int sandbox_cmdline_cb_interactive(struct sandbox_state *state,
 
 SANDBOX_CMDLINE_OPT_SHORT(interactive, 'i', 0, "Enter interactive mode");
 
+static int sandbox_cmdline_cb_memory(struct sandbox_state *state,
+                                    const char *arg)
+{
+       int err;
+
+       /* For now assume we always want to write it */
+       state->write_ram_buf = true;
+       state->ram_buf_fname = arg;
+
+       if (os_read_ram_buf(arg)) {
+               printf("Failed to read RAM buffer\n");
+               return err;
+       }
+
+       return 0;
+}
+SANDBOX_CMDLINE_OPT_SHORT(memory, 'm', 1,
+                         "Read/write ram_buf memory contents from file");
+
 int main(int argc, char *argv[])
 {
        struct sandbox_state *state;
index 56d5041411c77b993bf0a5622106dcf863a32385..0380fe279182a687101dbd96293b2e377b8ecba9 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <common.h>
+#include <os.h>
 #include <asm/state.h>
 
 /* Main state record for the sandbox */
@@ -25,6 +26,10 @@ int state_init(void)
 {
        state = &main_state;
 
+       state->ram_size = CONFIG_SYS_SDRAM_SIZE;
+       state->ram_buf = os_malloc(state->ram_size);
+       assert(state->ram_buf);
+
        /*
         * Example of how to use GPIOs:
         *
@@ -33,3 +38,20 @@ int state_init(void)
         */
        return 0;
 }
+
+int state_uninit(void)
+{
+       int err;
+
+       state = &main_state;
+
+       if (state->write_ram_buf) {
+               err = os_write_ram_buf(state->ram_buf_fname);
+               if (err) {
+                       printf("Failed to write RAM buffer\n");
+                       return err;
+               }
+       }
+
+       return 0;
+}
index d70532aa4d7a6bca2b38d68573f6e476bf0ffdc3..b2e9b488f13be33563b07bb5435a999ddfb99521 100644 (file)
@@ -12,7 +12,7 @@
 
 /* Architecture-specific global data */
 struct arch_global_data {
-       u8              *ram_buf;       /* emulated RAM buffer */
+       uint8_t         *ram_buf;       /* emulated RAM buffer */
 };
 
 #include <asm-generic/global_data.h>
index df196b79f6dfd8a3a2796c1e3aba994c90e8d299..e4b4c724632534877b25a7ccffe3b36a4682ab9a 100644 (file)
@@ -30,6 +30,10 @@ struct sandbox_state {
        const char *parse_err;          /* Error to report from parsing */
        int argc;                       /* Program arguments */
        char **argv;
+       uint8_t *ram_buf;               /* Emulated RAM buffer */
+       unsigned int ram_size;          /* Size of RAM buffer */
+       const char *ram_buf_fname;      /* Filename to use for RAM buffer */
+       bool write_ram_buf;             /* Write RAM buffer on exit */
 
        /* Pointer to information for each SPI bus/cs */
        struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS]
@@ -55,4 +59,12 @@ struct sandbox_state *state_get_current(void);
  */
 int state_init(void);
 
+/**
+ * Uninitialize the test system state, writing out state if configured to
+ * do so.
+ *
+ * @return 0 if OK, -ve on error
+ */
+int state_uninit(void);
+
 #endif
index 6f77e1d1295a1e66841ebe41bb0a9f23ebb97e9d..c2f47bc18892a2f381d24ea8b114833c0c96484d 100644 (file)
@@ -347,9 +347,10 @@ done:
 #ifdef CONFIG_SANDBOX
 static int setup_ram_buf(void)
 {
-       gd->arch.ram_buf = os_malloc(CONFIG_SYS_SDRAM_SIZE);
-       assert(gd->arch.ram_buf);
-       gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
+       struct sandbox_state *state = state_get_current();
+
+       gd->arch.ram_buf = state->ram_buf;
+       gd->ram_size = state->ram_size;
 
        return 0;
 }
index d302b3685bb56e41f1ddd2fcf9e9daa6033d6a4f..b65fba430144d2587c068756fd8bfbd001799354 100644 (file)
@@ -229,4 +229,20 @@ void os_putc(int ch);
  */
 void os_puts(const char *str);
 
+/**
+ * Write the sandbox RAM buffer to a existing file
+ *
+ * @param fname                Filename to write memory to (simple binary format)
+ * @return 0 if OK, -ve on error
+ */
+int os_write_ram_buf(const char *fname);
+
+/**
+ * Read the sandbox RAM buffer from an existing file
+ *
+ * @param fname                Filename containing memory (simple binary format)
+ * @return 0 if OK, -ve on error
+ */
+int os_read_ram_buf(const char *fname);
+
 #endif