diff options
author | Simon Glass <sjg@chromium.org> | 2013-11-10 10:27:03 -0700 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2014-01-08 17:25:03 -0700 |
commit | 5c2859cdc30287b3593d9df88f48c31eecb0bbed (patch) | |
tree | 3d6552f961488657bf74869027e7ad4daf66dd73 /arch | |
parent | c5a62d4a7b4a971a1fb17d595f7c1e98a936a974 (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.c | 4 | ||||
-rw-r--r-- | arch/sandbox/cpu/os.c | 39 | ||||
-rw-r--r-- | arch/sandbox/cpu/start.c | 22 | ||||
-rw-r--r-- | arch/sandbox/cpu/state.c | 22 | ||||
-rw-r--r-- | arch/sandbox/include/asm/global_data.h | 2 | ||||
-rw-r--r-- | arch/sandbox/include/asm/state.h | 12 |
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 |