From fcc86d82f7864c9609d2a02acb1a25074e9902ed Mon Sep 17 00:00:00 2001 From: Andrew Cagney Date: Fri, 31 Oct 1997 08:49:10 +0000 Subject: 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. --- sim/common/ChangeLog | 23 +++++++ sim/common/sim-core.c | 129 ++++++++++++++++++------------------- sim/common/sim-core.h | 29 +++++++-- sim/common/sim-memopt.c | 165 ++++++++++++++++++++++++++++++++++-------------- 4 files changed, 223 insertions(+), 123 deletions(-) diff --git a/sim/common/ChangeLog b/sim/common/ChangeLog index e54afde..350a8ab 100644 --- a/sim/common/ChangeLog +++ b/sim/common/ChangeLog @@ -1,3 +1,26 @@ +Fri Oct 31 13:03:33 1997 Andrew Cagney + + * 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 * sim-core.h (sim_core_write_8): Define. diff --git a/sim/common/sim-core.c b/sim/common/sim-core.c index 7346bf9..f79c7c3 100644 --- a/sim/common/sim-core.c +++ b/sim/common/sim-core.c @@ -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); - } + new_mapping->buffer = buffer; + new_mapping->free_buffer = free_buffer; + new_mapping->device = device; 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,38 +287,55 @@ sim_core_attach (SIM_DESC sd, #endif } - /* verify the attach type */ - if (attach == attach_raw_memory) + /* verify modulo memory */ + if (!WITH_MODULO_MEMORY && modulo != 0) { - 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"); + device_error (client, "sim_core_attach - internal error - modulo memory disabled"); #else - sim_io_error (sd, "sim_core_attach - internal error - modulo not power of two"); + 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; } - else if (!WITH_MODULO_MEMORY && modulo != 0) + if (mask != sizeof (unsigned64) - 1) { #if (WITH_DEVICES) - device_error (client, "sim_core_attach - internal error - modulo memory disabled"); + 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 memory disabled"); + 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 diff --git a/sim/common/sim-core.h b/sim/common/sim-core.h index 8209bfa..ef6b3f1 100644 --- a/sim/common/sim-core.h +++ b/sim/common/sim-core.h @@ -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); diff --git a/sim/common/sim-memopt.c b/sim/common/sim-memopt.c index 3481c21..82578c0 100644 --- a/sim/common/sim-memopt.c +++ b/sim/common/sim-memopt.c @@ -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 = 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) +{ + /* [ ": " ] [ "@" ] */ + *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, - (long) entry->nr_bytes); - if (entry->modulo != 0) - sim_io_printf (sd, ",0x%lx", (long) entry->modulo); - } + 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); + for (alias = entry->alias; + alias != NULL; + alias = alias->next) { - sim_io_printf (sd, " alias 0x%08lx,0x%lx", - (long) entry->addr, - (long) entry->nr_bytes); - for (alias = entry->alias; - alias != NULL; - alias = alias->next) - sim_io_printf (sd, ",0x%08lx", alias->addr); + 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"); } -- cgit v1.1