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>
This commit is contained in:
Simon Glass 2013-11-10 10:27:03 -07:00
parent c5a62d4a7b
commit 5c2859cdc3
8 changed files with 118 additions and 6 deletions

View File

@ -5,11 +5,15 @@
#include <common.h> #include <common.h>
#include <os.h> #include <os.h>
#include <asm/state.h>
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
void reset_cpu(ulong ignored) void reset_cpu(ulong ignored)
{ {
if (state_uninit())
os_exit(2);
/* This is considered normal termination for now */ /* This is considered normal termination for now */
os_exit(0); os_exit(0);
} }

View File

@ -399,3 +399,42 @@ void os_puts(const char *str)
while (*str) while (*str)
os_putc(*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;
}

View File

@ -4,12 +4,11 @@
*/ */
#include <common.h> #include <common.h>
#include <os.h>
#include <asm/getopt.h> #include <asm/getopt.h>
#include <asm/sections.h> #include <asm/sections.h>
#include <asm/state.h> #include <asm/state.h>
#include <os.h>
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
int sandbox_early_getopt_check(void) 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"); 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[]) int main(int argc, char *argv[])
{ {
struct sandbox_state *state; struct sandbox_state *state;

View File

@ -4,6 +4,7 @@
*/ */
#include <common.h> #include <common.h>
#include <os.h>
#include <asm/state.h> #include <asm/state.h>
/* Main state record for the sandbox */ /* Main state record for the sandbox */
@ -25,6 +26,10 @@ int state_init(void)
{ {
state = &main_state; 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: * Example of how to use GPIOs:
* *
@ -33,3 +38,20 @@ int state_init(void)
*/ */
return 0; 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;
}

View File

@ -12,7 +12,7 @@
/* Architecture-specific global data */ /* Architecture-specific global data */
struct arch_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> #include <asm-generic/global_data.h>

View File

@ -30,6 +30,10 @@ struct sandbox_state {
const char *parse_err; /* Error to report from parsing */ const char *parse_err; /* Error to report from parsing */
int argc; /* Program arguments */ int argc; /* Program arguments */
char **argv; 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 */ /* Pointer to information for each SPI bus/cs */
struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS] 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); 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 #endif

View File

@ -347,9 +347,10 @@ done:
#ifdef CONFIG_SANDBOX #ifdef CONFIG_SANDBOX
static int setup_ram_buf(void) static int setup_ram_buf(void)
{ {
gd->arch.ram_buf = os_malloc(CONFIG_SYS_SDRAM_SIZE); struct sandbox_state *state = state_get_current();
assert(gd->arch.ram_buf);
gd->ram_size = CONFIG_SYS_SDRAM_SIZE; gd->arch.ram_buf = state->ram_buf;
gd->ram_size = state->ram_size;
return 0; return 0;
} }

View File

@ -229,4 +229,20 @@ void os_putc(int ch);
*/ */
void os_puts(const char *str); 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 #endif