diff options
Diffstat (limited to 'sim/common/sim-memopt.c')
-rw-r--r-- | sim/common/sim-memopt.c | 124 |
1 files changed, 98 insertions, 26 deletions
diff --git a/sim/common/sim-memopt.c b/sim/common/sim-memopt.c index a8263b1..9b3553f 100644 --- a/sim/common/sim-memopt.c +++ b/sim/common/sim-memopt.c @@ -33,6 +33,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <stdlib.h> #endif +/* Memory fill byte */ +static unsigned8 fill_byte_value; +static int fill_byte_flag = 0; + /* Memory command line options. */ enum { @@ -42,6 +46,7 @@ enum { OPTION_MEMORY_INFO, OPTION_MEMORY_ALIAS, OPTION_MEMORY_CLEAR, + OPTION_MEMORY_FILL }; static DECLARE_OPTION_HANDLER (memory_option_handler); @@ -67,8 +72,12 @@ static const OPTION memory_options[] = '\0', "SIZE", "Add memory at address zero", memory_option_handler }, + { {"memory-fill", required_argument, NULL, OPTION_MEMORY_FILL }, + '\0', "VALUE", "Fill subsequently added memory regions", + memory_option_handler }, + { {"memory-clear", no_argument, NULL, OPTION_MEMORY_CLEAR }, - '\0', NULL, "Clear all memory regions", + '\0', NULL, "Clear subsequently added memory regions", memory_option_handler }, { {"memory-info", no_argument, NULL, OPTION_MEMORY_INFO }, @@ -92,9 +101,45 @@ do_memopt_add (SIM_DESC sd, sim_memopt **entry, void *buffer) { - sim_core_attach (sd, NULL, - level, access_read_write_exec, space, - addr, nr_bytes, modulo, NULL, buffer); + void *fill_buffer; + unsigned fill_length; + void *free_buffer; + + if (buffer != NULL) + { + /* Buffer already given. sim_memory_uninstall will free it. */ + sim_core_attach (sd, NULL, + level, access_read_write_exec, space, + addr, nr_bytes, modulo, NULL, buffer); + + free_buffer = buffer; + fill_buffer = buffer; + fill_length = (modulo == 0) ? nr_bytes : modulo; + } + else + { + /* Allocate new well-aligned buffer, just as sim_core_attach(). */ + void *aligned_buffer; + int padding = (addr % sizeof (unsigned64)); + unsigned long bytes = (modulo == 0 ? nr_bytes : modulo) + padding; + + free_buffer = zalloc (bytes); + aligned_buffer = (char*) free_buffer + padding; + + sim_core_attach (sd, NULL, + level, access_read_write_exec, space, + addr, nr_bytes, modulo, NULL, aligned_buffer); + + fill_buffer = aligned_buffer; + fill_length = (modulo == 0) ? nr_bytes : modulo; + } + + if (fill_byte_flag) + { + ASSERT (fill_buffer != 0); + memset ((char*) fill_buffer, fill_byte_value, fill_length); + } + while ((*entry) != NULL) entry = &(*entry)->next; (*entry) = ZALLOC (sim_memopt); @@ -103,7 +148,8 @@ do_memopt_add (SIM_DESC sd, (*entry)->addr = addr; (*entry)->nr_bytes = nr_bytes; (*entry)->modulo = modulo; - (*entry)->buffer = buffer; + (*entry)->buffer = free_buffer; + return (*entry); } @@ -157,6 +203,13 @@ parse_size (char *chp, return chp; } +static char * +parse_ulong_value (char *chp, + unsigned long *value) +{ + *value = strtoul (chp, &chp, 0); + return chp; +} static char * parse_addr (char *chp, @@ -165,11 +218,11 @@ parse_addr (char *chp, address_word *addr) { /* [ <space> ": " ] <addr> [ "@" <level> ] */ - *addr = strtoul (chp, &chp, 0); + *addr = (unsigned long) strtoul (chp, &chp, 0); if (*chp == ':') { *space = *addr; - *addr = strtoul (chp + 1, &chp, 0); + *addr = (unsigned long) strtoul (chp + 1, &chp, 0); } if (*chp == '@') { @@ -250,7 +303,7 @@ memory_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt, /* try to attach/insert the main record */ entry = do_memopt_add (sd, level, space, addr, nr_bytes, modulo, &STATE_MEMOPT (sd), - zalloc (modulo ? modulo : nr_bytes)); + NULL); /* now attach all the aliases */ while (*chp == ',') { @@ -281,25 +334,23 @@ memory_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt, case OPTION_MEMORY_CLEAR: { - sim_memopt *entry; - for (entry = STATE_MEMOPT (sd); entry != NULL; entry = entry->next) + fill_byte_value = (unsigned8) 0; + fill_byte_flag = 1; + return SIM_RC_OK; + break; + } + + case OPTION_MEMORY_FILL: + { + unsigned long fill_value; + parse_ulong_value (arg, &fill_value); + if (fill_value > 255) { - sim_memopt *alias; - for (alias = entry; alias != NULL; alias = alias->next) - { - unsigned8 zero = 0; - address_word nr_bytes; - if (alias->modulo != 0) - nr_bytes = alias->modulo; - else - nr_bytes = alias->nr_bytes; - sim_core_write_buffer (sd, NULL, sim_core_write_map, - &zero, - alias->addr + nr_bytes, - sizeof (zero)); - - } + sim_io_eprintf (sd, "Missing fill value between 0 and 255\n"); + return SIM_RC_FAIL; } + fill_byte_value = (unsigned8) fill_value; + fill_byte_flag = 1; return SIM_RC_OK; break; } @@ -375,7 +426,28 @@ sim_memopt_install (SIM_DESC sd) static void sim_memory_uninstall (SIM_DESC sd) { - /* FIXME: free buffers, etc. */ + sim_memopt **entry = &STATE_MEMOPT (sd); + sim_memopt *alias; + + while ((*entry) != NULL) + { + /* delete any buffer */ + if ((*entry)->buffer != NULL) + zfree ((*entry)->buffer); + + /* delete it and its aliases */ + alias = *entry; + while (alias != NULL) + { + sim_memopt *dead = alias; + alias = alias->alias; + sim_core_detach (sd, NULL, dead->level, dead->space, dead->addr); + zfree (dead); + } + + /* next victim */ + *entry = (*entry)->next; + } } |