summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2013-11-10 10:27:03 -0700
committerSimon Glass <sjg@chromium.org>2014-01-08 17:25:03 -0700
commit5c2859cdc30287b3593d9df88f48c31eecb0bbed (patch)
tree3d6552f961488657bf74869027e7ad4daf66dd73 /arch
parentc5a62d4a7b4a971a1fb17d595f7c1e98a936a974 (diff)
sandbox: Allow reading/writing of RAM buffer
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/sandbox/cpu/cpu.c4
-rw-r--r--arch/sandbox/cpu/os.c39
-rw-r--r--arch/sandbox/cpu/start.c22
-rw-r--r--arch/sandbox/cpu/state.c22
-rw-r--r--arch/sandbox/include/asm/global_data.h2
-rw-r--r--arch/sandbox/include/asm/state.h12
6 files changed, 98 insertions, 3 deletions
diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c
index bc7641a8081..38019e0b48e 100644
--- a/arch/sandbox/cpu/cpu.c
+++ b/arch/sandbox/cpu/cpu.c
@@ -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);
}
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index ef6a651a603..725b505177d 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -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;
+}
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index 579ece44711..452f2a98f36 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -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;
diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c
index 56d5041411c..0380fe27918 100644
--- a/arch/sandbox/cpu/state.c
+++ b/arch/sandbox/cpu/state.c
@@ -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;
+}
diff --git a/arch/sandbox/include/asm/global_data.h b/arch/sandbox/include/asm/global_data.h
index d70532aa4d7..b2e9b488f13 100644
--- a/arch/sandbox/include/asm/global_data.h
+++ b/arch/sandbox/include/asm/global_data.h
@@ -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>
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index df196b79f6d..e4b4c724632 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -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