Make memory regions layered (just like existing device regions) so

that overlapping regions can be defined.
Allow the layer (level) of a memory region to be specified as part of
an address parameter to memory options.
Update simulators.
This commit is contained in:
Andrew Cagney 1997-10-31 08:49:10 +00:00
parent d3e9ca1a88
commit fcc86d82f7
4 changed files with 224 additions and 124 deletions

View File

@ -1,3 +1,26 @@
Fri Oct 31 13:03:33 1997 Andrew Cagney <cagney@b1.cygnus.com>
* sim-memopt.c (do_memopt_add, do_memopt_delete): Add level and
space params.
(parse_size, parse_addr): New functions
(memory_option_handler, memory_options): Parse address & size
using new functions. Pass level, space, modulo to do_memopt_add &
do_memopt_del.
* sim-memopt.h (struct _sim_memopt): Add level & space fields.
* sim-core.h (sim_core_arrach, sim_core_detach): Replace
`attach_type attach' argument with `unsigned level' argument.
Document.
* sim-core.c (new_sim_core_mapping, sim_core_map_attach,
sim_core_attach): Replace argument attach with level. Update
verification of arguments.
(sim_core_map_detach, sim_core_detach): Replace argument attach
with level.
* sim-basics.h (enum _attach_type): Delete.
Thu Oct 30 13:45:00 1997 Doug Evans <devans@seba.cygnus.com>
* sim-core.h (sim_core_write_8): Define.

View File

@ -145,7 +145,7 @@ sim_core_map_to_str (sim_core_maps map)
STATIC_SIM_CORE\
(sim_core_mapping *)
new_sim_core_mapping (SIM_DESC sd,
attach_type attach,
int level,
int space,
address_word addr,
address_word nr_bytes,
@ -156,7 +156,7 @@ new_sim_core_mapping (SIM_DESC sd,
{
sim_core_mapping *new_mapping = ZALLOC(sim_core_mapping);
/* common */
new_mapping->level = attach;
new_mapping->level = level;
new_mapping->space = space;
new_mapping->base = addr;
new_mapping->nr_bytes = nr_bytes;
@ -165,19 +165,9 @@ new_sim_core_mapping (SIM_DESC sd,
new_mapping->mask = (unsigned) 0 - 1;
else
new_mapping->mask = modulo - 1;
if (attach == attach_raw_memory)
{
new_mapping->buffer = buffer;
new_mapping->free_buffer = free_buffer;
}
else if (attach >= attach_callback)
{
new_mapping->device = device;
}
else {
sim_io_error (sd, "new_sim_core_mapping - internal error - unknown attach type %d\n",
attach);
}
return new_mapping;
}
@ -186,7 +176,7 @@ STATIC_SIM_CORE\
(void)
sim_core_map_attach (SIM_DESC sd,
sim_core_map *access_map,
attach_type attach,
int level,
int space,
address_word addr,
address_word nr_bytes,
@ -200,10 +190,8 @@ sim_core_map_attach (SIM_DESC sd,
sim_core_mapping *next_mapping;
sim_core_mapping **last_mapping;
SIM_ASSERT ((attach >= attach_callback)
<= (client != NULL && buffer == NULL && free_buffer == NULL));
SIM_ASSERT ((attach == attach_raw_memory)
<= (client == NULL && buffer != NULL));
SIM_ASSERT ((client == NULL) != (buffer == NULL));
SIM_ASSERT ((client == NULL) >= (free_buffer != NULL));
/* actually do occasionally get a zero size map */
if (nr_bytes == 0)
@ -219,8 +207,8 @@ sim_core_map_attach (SIM_DESC sd,
next_mapping = access_map->first;
last_mapping = &access_map->first;
while(next_mapping != NULL
&& (next_mapping->level < (int) attach
|| (next_mapping->level == (int) attach
&& (next_mapping->level < level
|| (next_mapping->level == level
&& next_mapping->bound < addr)))
{
/* provided levels are the same */
@ -231,8 +219,8 @@ sim_core_map_attach (SIM_DESC sd,
}
/* check insertion point correct */
SIM_ASSERT (next_mapping == NULL || next_mapping->level >= (int) attach);
if (next_mapping != NULL && next_mapping->level == (int) attach
SIM_ASSERT (next_mapping == NULL || next_mapping->level >= level);
if (next_mapping != NULL && next_mapping->level == level
&& next_mapping->base < (addr + (nr_bytes - 1)))
{
#if (WITH_DEVICES)
@ -260,7 +248,7 @@ sim_core_map_attach (SIM_DESC sd,
/* create/insert the new mapping */
*last_mapping = new_sim_core_mapping(sd,
attach,
level,
space, addr, nr_bytes, modulo,
client, buffer, free_buffer);
(*last_mapping)->next = next_mapping;
@ -271,7 +259,7 @@ EXTERN_SIM_CORE\
(void)
sim_core_attach (SIM_DESC sd,
sim_cpu *cpu,
attach_type attach,
int level,
access_type access,
int space,
address_word addr,
@ -299,31 +287,8 @@ sim_core_attach (SIM_DESC sd,
#endif
}
/* verify the attach type */
if (attach == attach_raw_memory)
{
if (WITH_MODULO_MEMORY && modulo != 0)
{
unsigned mask = modulo - 1;
if (mask < 7) /* 8 is minimum modulo */
mask = 0;
while (mask > 1) /* no zero bits */
{
if ((mask & 1) == 0)
mask = 0;
else
mask >>= 1;
}
if (mask == 0)
{
#if (WITH_DEVICES)
device_error (client, "sim_core_attach - internal error - modulo not power of two");
#else
sim_io_error (sd, "sim_core_attach - internal error - modulo not power of two");
#endif
}
}
else if (!WITH_MODULO_MEMORY && modulo != 0)
/* verify modulo memory */
if (!WITH_MODULO_MEMORY && modulo != 0)
{
#if (WITH_DEVICES)
device_error (client, "sim_core_attach - internal error - modulo memory disabled");
@ -331,6 +296,46 @@ sim_core_attach (SIM_DESC sd,
sim_io_error (sd, "sim_core_attach - internal error - modulo memory disabled");
#endif
}
if (client != NULL && modulo != 0)
{
#if (WITH_DEVICES)
device_error (client, "sim_core_attach - internal error - modulo and callback memory conflict");
#else
sim_io_error (sd, "sim_core_attach - internal error - modulo and callback memory conflict");
#endif
}
if (modulo != 0)
{
unsigned mask = modulo - 1;
/* any zero bits */
while (mask >= sizeof (unsigned64)) /* minimum modulo */
{
if ((mask & 1) == 0)
mask = 0;
else
mask >>= 1;
}
if (mask != sizeof (unsigned64) - 1)
{
#if (WITH_DEVICES)
device_error (client, "sim_core_attach - internal error - modulo %lx not power of two", (long) modulo);
#else
sim_io_error (sd, "sim_core_attach - internal error - modulo %lx not power of two", (long) modulo);
#endif
}
}
/* verify consistency between device and buffer */
if (client != NULL && optional_buffer != NULL)
{
#if (WITH_DEVICES)
device_error (client, "sim_core_attach - internal error - conflicting buffer and attach arguments");
#else
sim_io_error (sd, "sim_core_attach - internal error - conflicting buffer and attach arguments");
#endif
}
if (client == NULL)
{
if (optional_buffer == NULL)
{
int padding = (addr % sizeof (unsigned64));
@ -343,18 +348,9 @@ sim_core_attach (SIM_DESC sd,
free_buffer = NULL;
}
}
else if (attach >= attach_callback)
{
buffer = NULL;
free_buffer = NULL;
}
else
{
#if (WITH_DEVICES)
device_error (client, "sim_core_attach - internal error - conflicting buffer and attach arguments");
#else
sim_io_error (sd, "sim_core_attach - internal error - conflicting buffer and attach arguments");
#endif
/* a device */
buffer = NULL;
free_buffer = NULL;
}
@ -369,24 +365,21 @@ sim_core_attach (SIM_DESC sd,
case sim_core_read_map:
if (access & access_read)
sim_core_map_attach (sd, &memory->common.map[map],
attach,
space, addr, nr_bytes, modulo,
level, space, addr, nr_bytes, modulo,
client, buffer, free_buffer);
free_buffer = NULL;
break;
case sim_core_write_map:
if (access & access_write)
sim_core_map_attach (sd, &memory->common.map[map],
attach,
space, addr, nr_bytes, modulo,
level, space, addr, nr_bytes, modulo,
client, buffer, free_buffer);
free_buffer = NULL;
break;
case sim_core_execute_map:
if (access & access_exec)
sim_core_map_attach (sd, &memory->common.map[map],
attach,
space, addr, nr_bytes, modulo,
level, space, addr, nr_bytes, modulo,
client, buffer, free_buffer);
free_buffer = NULL;
break;
@ -414,7 +407,7 @@ STATIC_INLINE_SIM_CORE\
(void)
sim_core_map_detach (SIM_DESC sd,
sim_core_map *access_map,
attach_type attach,
int level,
int space,
address_word addr)
{
@ -424,7 +417,7 @@ sim_core_map_detach (SIM_DESC sd,
entry = &(*entry)->next)
{
if ((*entry)->base == addr
&& (*entry)->level == (int) attach
&& (*entry)->level == level
&& (*entry)->space == space)
{
sim_core_mapping *dead = (*entry);
@ -441,7 +434,7 @@ EXTERN_SIM_CORE\
(void)
sim_core_detach (SIM_DESC sd,
sim_cpu *cpu,
attach_type attach,
int level,
int address_space,
address_word addr)
{
@ -450,7 +443,7 @@ sim_core_detach (SIM_DESC sd,
for (map = 0; map < nr_sim_core_maps; map++)
{
sim_core_map_detach (sd, &memory->common.map[map],
attach, address_space, addr);
level, address_space, addr);
}
/* Just copy this update to each of the processor specific data
structures. FIXME - later this will be replaced by true

View File

@ -103,24 +103,41 @@ EXTERN_SIM_CORE\
/* Create a memory space within the core.
The CPU option (when non NULL) specifes the single processor that
the memory space is to be attached to. (UNIMPLEMENTED).
CPU, when non NULL, specifes the single processor that the memory
space is to be attached to. (UNIMPLEMENTED).
*/
LEVEL specifies the ordering of the memory region. Lower regions
are searched first. Within a level, memory regions can not
overlap.
DEVICE, when non NULL, specifies a callback memory space.
(UNIMPLEMENTED, see the ppc simulator for an example).
MODULO, when the simulator has been configured WITH_MODULO support
and is greater than zero, specifies that accesses to the region
[ADDR .. ADDR+NR_BYTES) should be mapped onto the sub region [ADDR
.. ADDR+MODULO). The modulo value must be a power of two.
OPTIONAL_BUFFER, when non NULL, specifies the buffer to use for
data read & written to the region. Normally a more efficient
internal structure is used. It is assumed that buffer is allocated
such that the byte alignmed of OPTIONAL_BUFFER matches ADDR vis
(OPTIONAL_BUFFER % 8) == (ADDR % 8)) */
EXTERN_SIM_CORE\
(void) sim_core_attach
(SIM_DESC sd,
sim_cpu *cpu,
attach_type attach,
int level,
access_type access,
int address_space,
address_word addr,
address_word nr_bytes,
unsigned modulo, /* Power of two, zero for none. */
unsigned modulo,
device *client,
void *optional_buffer);
/* Delete a memory space within the core.
*/
@ -129,7 +146,7 @@ EXTERN_SIM_CORE\
(void) sim_core_detach
(SIM_DESC sd,
sim_cpu *cpu,
attach_type attach,
int level,
int address_space,
address_word addr);

View File

@ -48,8 +48,8 @@ static DECLARE_OPTION_HANDLER (memory_option_handler);
static const OPTION memory_options[] =
{
{ {"memory-delete", optional_argument, NULL, OPTION_MEMORY_DELETE },
'\0', "ADDRESS", "Delete memory at ADDRESS (all addresses)",
{ {"memory-delete", required_argument, NULL, OPTION_MEMORY_DELETE },
'\0', "ADDRESS|all", "Delete memory at ADDRESS (all addresses)",
memory_option_handler },
{ {"delete-memory", required_argument, NULL, OPTION_MEMORY_DELETE },
'\0', "ADDRESS", NULL,
@ -83,20 +83,23 @@ static const OPTION memory_options[] =
static sim_memopt *
do_memopt_add (sd, addr, nr_bytes, modulo, entry, buffer)
SIM_DESC sd;
address_word addr;
address_word nr_bytes;
unsigned modulo;
sim_memopt **entry;
void *buffer;
do_memopt_add (SIM_DESC sd,
int level,
int space,
address_word addr,
address_word nr_bytes,
unsigned modulo,
sim_memopt **entry,
void *buffer)
{
sim_core_attach (sd, NULL,
attach_raw_memory, access_read_write_exec, 0,
level, access_read_write_exec, space,
addr, nr_bytes, modulo, NULL, buffer);
while ((*entry) != NULL)
entry = &(*entry)->next;
(*entry) = ZALLOC (sim_memopt);
(*entry)->level = level;
(*entry)->space = space;
(*entry)->addr = addr;
(*entry)->nr_bytes = nr_bytes;
(*entry)->modulo = modulo;
@ -105,13 +108,17 @@ do_memopt_add (sd, addr, nr_bytes, modulo, entry, buffer)
}
static SIM_RC
do_memopt_delete (sd, addr)
SIM_DESC sd;
address_word addr;
do_memopt_delete (SIM_DESC sd,
int level,
int space,
address_word addr)
{
sim_memopt **entry = &STATE_MEMOPT (sd);
sim_memopt *alias;
while ((*entry) != NULL && (*entry)->addr != addr)
while ((*entry) != NULL
&& ((*entry)->level != level
|| (*entry)->space != space
|| (*entry)->addr != addr))
entry = &(*entry)->next;
if ((*entry) == NULL)
{
@ -124,18 +131,54 @@ do_memopt_delete (sd, addr)
zfree ((*entry)->buffer);
/* delete it and its aliases */
alias = *entry;
*entry = alias->next;
*entry = (*entry)->next;
while (alias != NULL)
{
sim_memopt *dead = alias;
alias = alias->alias;
sim_core_detach (sd, NULL, attach_raw_memory, 0, dead->addr);
sim_core_detach (sd, NULL, dead->level, dead->space, dead->addr);
zfree (dead);
}
return SIM_RC_OK;
}
static char *
parse_size (char *chp,
address_word *nr_bytes,
unsigned *modulo)
{
/* <nr_bytes> [ "%" <modulo> ] */
*nr_bytes = strtoul (chp, &chp, 0);
if (*chp == '%')
{
*modulo = strtoul (chp + 1, &chp, 0);
}
return chp;
}
static char *
parse_addr (char *chp,
int *level,
int *space,
address_word *addr)
{
/* [ <space> ": " ] <addr> [ "@" <level> ] */
*addr = strtoul (chp, &chp, 0);
if (*chp == ':')
{
*space = *addr;
*addr = strtoul (chp + 1, &chp, 0);
}
if (*chp == '@')
{
*level = strtoul (chp + 1, &chp, 0);
}
return chp;
}
static SIM_RC
memory_option_handler (sd, opt, arg, is_command)
SIM_DESC sd;
@ -147,65 +190,77 @@ memory_option_handler (sd, opt, arg, is_command)
{
case OPTION_MEMORY_DELETE:
if (arg == NULL)
if (strcasecmp (arg, "all") == 0)
{
while (STATE_MEMOPT (sd) != NULL)
do_memopt_delete (sd, STATE_MEMOPT (sd)->addr);
do_memopt_delete (sd,
STATE_MEMOPT (sd)->level,
STATE_MEMOPT (sd)->space,
STATE_MEMOPT (sd)->addr);
return SIM_RC_OK;
}
else
{
address_word addr = strtoul (arg, NULL, 0);
return do_memopt_delete (sd, addr);
int level = 0;
int space = 0;
address_word addr = 0;
parse_addr (arg, &level, &space, &addr);
return do_memopt_delete (sd, level, space, addr);
}
case OPTION_MEMORY_REGION:
{
char *chp = arg;
int level = 0;
int space = 0;
address_word addr = 0;
address_word nr_bytes = 0;
unsigned modulo = 0;
/* parse the arguments */
addr = strtoul (chp, &chp, 0);
chp = parse_addr (chp, &level, &space, &addr);
if (*chp != ',')
{
sim_io_eprintf (sd, "Missing size for memory-region\n");
return SIM_RC_FAIL;
}
chp++;
nr_bytes = strtoul (chp, &chp, 0);
chp = parse_size (chp + 1, &nr_bytes, &modulo);
/* old style */
if (*chp == ',')
modulo = strtoul (chp + 1, NULL, 0);
modulo = strtoul (chp + 1, &chp, 0);
/* try to attach/insert it */
do_memopt_add (sd, addr, nr_bytes, modulo, &STATE_MEMOPT (sd), NULL);
do_memopt_add (sd, level, space, addr, nr_bytes, modulo,
&STATE_MEMOPT (sd), NULL);
return SIM_RC_OK;
}
case OPTION_MEMORY_ALIAS:
{
char *chp = arg;
int level = 0;
int space = 0;
address_word addr = 0;
address_word nr_bytes = 0;
unsigned modulo = 0;
sim_memopt *entry;
/* parse the arguments */
addr = strtoul (chp, &chp, 0);
chp = parse_addr (chp, &level, &space, &addr);
if (*chp != ',')
{
sim_io_eprintf (sd, "Missing size for memory-region\n");
return SIM_RC_FAIL;
}
chp++;
nr_bytes = strtoul (chp, &chp, 0);
chp = parse_size (chp + 1, &nr_bytes, &modulo);
/* try to attach/insert the main record */
entry = do_memopt_add (sd, addr, nr_bytes, 0/*modulo*/,
entry = do_memopt_add (sd, level, space, addr, nr_bytes, modulo,
&STATE_MEMOPT (sd), zalloc (nr_bytes));
/* now attach all the aliases */
while (*chp == ',')
{
address_word alias;
chp++;
alias = strtoul (chp, &chp, 0);
do_memopt_add (sd, alias, nr_bytes, 0/*modulo*/,
int a_level = level;
int a_space = space;
address_word a_addr = addr;
chp = parse_addr (chp, &a_level, &a_space, &a_addr);
do_memopt_add (sd, a_level, a_space, a_addr, nr_bytes, modulo,
&entry->alias, entry->buffer);
}
return SIM_RC_OK;
@ -213,9 +268,15 @@ memory_option_handler (sd, opt, arg, is_command)
case OPTION_MEMORY_SIZE:
{
address_word nr_bytes = strtoul (arg, NULL, 0);
int level = 0;
int space = 0;
address_word addr = 0;
address_word nr_bytes = 0;
unsigned modulo = 0;
/* parse the arguments */
parse_size (arg, &nr_bytes, &modulo);
/* try to attach/insert it */
do_memopt_add (sd, 0/*addr*/, nr_bytes, 0/*modulo*/,
do_memopt_add (sd, level, space, addr, nr_bytes, modulo,
&STATE_MEMOPT (sd), NULL);
return SIM_RC_OK;
}
@ -254,22 +315,28 @@ memory_option_handler (sd, opt, arg, is_command)
sim_memopt *alias;
sim_io_printf (sd, " memory");
if (entry->alias == NULL)
{
sim_io_printf (sd, " region 0x%08lx,0x%lx",
(long) entry->addr,
sim_io_printf (sd, " region ");
else
sim_io_printf (sd, " alias ");
if (entry->space != 0)
sim_io_printf (sd, "0x%lx:", (long) entry->space);
sim_io_printf (sd, "0x%08lx",
(long) entry->addr);
if (entry->level != 0)
sim_io_printf (sd, "@0x%lx", (long) entry->level);
sim_io_printf (sd, ",0x%lx",
(long) entry->nr_bytes);
if (entry->modulo != 0)
sim_io_printf (sd, ",0x%lx", (long) entry->modulo);
}
else
{
sim_io_printf (sd, " alias 0x%08lx,0x%lx",
(long) entry->addr,
(long) entry->nr_bytes);
sim_io_printf (sd, "%%0x%lx", (long) entry->modulo);
for (alias = entry->alias;
alias != NULL;
alias = alias->next)
{
if (alias->space != 0)
sim_io_printf (sd, "0x%lx:", (long) alias->space);
sim_io_printf (sd, ",0x%08lx", alias->addr);
if (alias->level != 0)
sim_io_printf (sd, "@0x%lx", (long) alias->level);
}
sim_io_printf (sd, "\n");
}