#include <stdlib.h>
#endif
+/* Memory fill byte */
+static unsigned8 fill_byte_value;
+static int fill_byte_flag = 0;
+
/* Memory command line options. */
enum {
OPTION_MEMORY_INFO,
OPTION_MEMORY_ALIAS,
OPTION_MEMORY_CLEAR,
+ OPTION_MEMORY_FILL
};
static DECLARE_OPTION_HANDLER (memory_option_handler);
'\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 },
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);
(*entry)->addr = addr;
(*entry)->nr_bytes = nr_bytes;
(*entry)->modulo = modulo;
- (*entry)->buffer = buffer;
+ (*entry)->buffer = free_buffer;
+
return (*entry);
}
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,
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 == '@')
{
/* 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 == ',')
{
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;
}
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;
+ }
}