From: Andrew Cagney Date: Thu, 4 Sep 1997 03:47:39 +0000 (+0000) Subject: o Add modulo argument to sim_core_attach X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a34abff813f4fdd5f289ea45de9e874e31e7edf3;p=binutils-gdb.git o Add modulo argument to sim_core_attach o Add sim-memopt module - memory option processing. --- diff --git a/sim/common/.Sanitize b/sim/common/.Sanitize index 7c8de96c953..2f802cb0872 100644 --- a/sim/common/.Sanitize +++ b/sim/common/.Sanitize @@ -71,6 +71,8 @@ sim-inline.h sim-io.c sim-io.h sim-load.c +sim-memopt.c +sim-memopt.h sim-model.c sim-model.h sim-module.c diff --git a/sim/common/ChangeLog b/sim/common/ChangeLog index f3679c40a55..39fce64ddf6 100644 --- a/sim/common/ChangeLog +++ b/sim/common/ChangeLog @@ -1,3 +1,40 @@ +Thu Sep 4 09:27:54 1997 Andrew Cagney + + * sim-utils.c (sim_elapsed_time_get): Never return zero. + + * sim-core.c (sim_core_detach): New function. + (sim_core_map_detach): New function. Perform the actual detach. + (sim_core_init): Move initialization code from here. + (sim_core_install): To here. + (sim_core_uninstall): And here. + + * sim-module.c: Add memopt module. + + * sim-base.h (STATE_MEMOPT, STATE_MEMOPT_P): Add memopt to + simulator base type. + + * Make-common.in (sim_main_headers): Add sim-memopt.h + (sim-memopt.o): New target. + + * sim-core.c (sim_core_install): Add core_options to the option + table. + + * sim-watch.c (watch_options): Make --delete-watch a synonym for + --watch-delete. + + * sim-config.h (WITH_MODULO_MEMORY): Define as 0. Update + comments. + + * sim-core.h (struct _sim_core_mapping): Change nr_bytes to type + address_word, add mask member. + + * sim-core.h, sim-core.c (sim_core_attach): Make nr_bytes of type + address_word, allow for 64bit targets in 32bit host. Add modulo + argument. + (sim_core_map_attach): Ditto. + (new_sim_core_mapping): Ditto. + (sim_core_translate): Mask address when modulo memory. + Wed Sep 3 17:32:54 1997 Doug Evans * sim-hload.c (sim_load): Add assert for SIM_MAGIC_NUMBER. diff --git a/sim/common/Make-common.in b/sim/common/Make-common.in index 79ffb952a4f..c345d6126e3 100644 --- a/sim/common/Make-common.in +++ b/sim/common/Make-common.in @@ -176,6 +176,7 @@ sim_main_headers = \ $(srcdir)/../common/sim-config.h \ $(srcdir)/../common/sim-base.h \ $(srcdir)/../common/sim-basics.h \ + $(srcdir)/../common/sim-memopt.h \ $(srcdir)/../common/sim-model.h \ $(srcdir)/../common/sim-module.h \ $(srcdir)/../common/sim-trace.h \ @@ -258,6 +259,10 @@ sim-io.o: $(srcdir)/../common/sim-io.c $(sim_main_headers) $(sim-io_h) \ $(SIM_EXTRA_DEPS) $(CC) -c $(srcdir)/../common/sim-io.c $(ALL_CFLAGS) +sim-memopt.o: $(srcdir)/../common/sim-memopt.c $(sim_main_headers) \ + $(sim-io_h) $(SIM_EXTRA_DEPS) + $(CC) -c $(srcdir)/../common/sim-memopt.c $(ALL_CFLAGS) + sim-module.o: $(srcdir)/../common/sim-module.c $(sim_main_headers) \ $(sim-io_h) $(SIM_EXTRA_DEPS) $(CC) -c $(srcdir)/../common/sim-module.c $(ALL_CFLAGS) diff --git a/sim/common/sim-base.h b/sim/common/sim-base.h index ef5f1ce941d..988eb2901e7 100644 --- a/sim/common/sim-base.h +++ b/sim/common/sim-base.h @@ -77,6 +77,7 @@ typedef struct _sim_cpu sim_cpu; #include "sim-io.h" #include "sim-engine.h" #include "sim-watch.h" +#include "sim-memopt.h" /* Global pointer to current state while sim_resume is running. @@ -199,6 +200,11 @@ typedef struct { #define STATE_CORE(sd) (&(sd)->base.core) sim_core core; + /* memory-options for managing the core */ +#define STATE_MEMOPT(sd) ((sd)->base.memopt) +#define STATE_MEMOPT_P(sd) (STATE_MEMOPT (sd) != NULL) + sim_memopt *memopt; + /* event handler */ #define STATE_EVENTS(sd) (&(sd)->base.events) sim_events events; diff --git a/sim/common/sim-basics.h b/sim/common/sim-basics.h index 149e6a0687e..e94075cf491 100644 --- a/sim/common/sim-basics.h +++ b/sim/common/sim-basics.h @@ -52,32 +52,6 @@ #endif - -/* Memory management with an allocator that clears memory before use. */ - -void *zalloc (unsigned long size); - -#define ZALLOC(TYPE) (TYPE*)zalloc(sizeof (TYPE)) - -void zfree(void*); - - -/* Turn VALUE into a string with commas. */ -char *sim_add_commas (char *, int, unsigned long); - - -/* Utilities for elapsed time reporting. */ - -/* Opaque type, known only inside sim_elapsed_time_foo fns. */ -typedef unsigned long SIM_ELAPSED_TIME; - -/* Get reference point for future call to sim_time_elapsed. */ -SIM_ELAPSED_TIME sim_elapsed_time_get (void); - -/* Elapsed time in milliseconds since START. */ -unsigned long sim_elapsed_time_since (SIM_ELAPSED_TIME start); - - /* Global types that code manipulates */ typedef struct _device device; @@ -97,14 +71,21 @@ typedef enum _access_type { /* Address attachement types */ -typedef enum _attach_type { +typedef enum _attach_type +{ attach_invalid, attach_raw_memory, attach_callback, - /* ... */ + /* attach_callback + 1, attach_callback + 2, ... */ } attach_type; +/* Memory transfer types */ +typedef enum _transfer_type { + read_transfer, + write_transfer, +} transfer_type; + /* Basic definitions - ordered so that nothing calls what comes after it */ @@ -124,6 +105,8 @@ typedef enum _attach_type { #include "sim-bits.h" #include "sim-endian.h" +#include "sim-utils.h" + /* Note: Only the simpler interfaces are defined here. More heavy weight objects, such as core and events, are defined in the more serious sim-base.h header. */ diff --git a/sim/common/sim-core.c b/sim/common/sim-core.c index d81925866cb..34fd05f615b 100644 --- a/sim/common/sim-core.c +++ b/sim/common/sim-core.c @@ -39,8 +39,12 @@ EXTERN_SIM_CORE\ sim_core_install (SIM_DESC sd) { SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); + + /* establish the other handlers */ sim_module_add_uninstall_fn (sd, sim_core_uninstall); sim_module_add_init_fn (sd, sim_core_init); + + /* establish any initial data structures - none */ return SIM_RC_OK; } @@ -50,19 +54,11 @@ sim_core_install (SIM_DESC sd) STATIC_SIM_CORE\ (void) sim_core_uninstall (SIM_DESC sd) -{ - /* FIXME: free buffers, etc. */ -} - - -STATIC_SIM_CORE\ -(SIM_RC) -sim_core_init (SIM_DESC sd) { sim_core *core = STATE_CORE(sd); sim_core_maps map; + /* blow away any mappings */ for (map = 0; map < nr_sim_core_maps; map++) { - /* blow away old mappings */ sim_core_mapping *curr = core->common.map[map].first; while (curr != NULL) { sim_core_mapping *tbd = curr; @@ -75,20 +71,14 @@ sim_core_init (SIM_DESC sd) } core->common.map[map].first = NULL; } - core->byte_xor = 0; - /* Just copy this map to each of the processor specific data structures. - FIXME - later this will be replaced by true processor specific - maps. */ - { - int i; - for (i = 0; i < MAX_NR_PROCESSORS; i++) - { - int j; - CPU_CORE (STATE_CPU (sd, i))->common = STATE_CORE (sd)->common; - for (j = 0; j < WITH_XOR_ENDIAN; j++) - CPU_CORE (STATE_CPU (sd, i))->xor [j] = 0; - } - } +} + + +STATIC_SIM_CORE\ +(SIM_RC) +sim_core_init (SIM_DESC sd) +{ + /* Nothing to do */ return SIM_RC_OK; } @@ -143,14 +133,15 @@ 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 space, - address_word addr, - unsigned nr_bytes, - device *device, - void *buffer, - int free_buffer) +new_sim_core_mapping (SIM_DESC sd, + attach_type attach, + int space, + address_word addr, + address_word nr_bytes, + unsigned modulo, + device *device, + void *buffer, + int free_buffer) { sim_core_mapping *new_mapping = ZALLOC(sim_core_mapping); /* common */ @@ -159,16 +150,22 @@ new_sim_core_mapping(SIM_DESC sd, new_mapping->base = addr; new_mapping->nr_bytes = nr_bytes; new_mapping->bound = addr + (nr_bytes - 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; - } + if (modulo == 0) + 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); + attach); } return new_mapping; } @@ -176,32 +173,36 @@ new_sim_core_mapping(SIM_DESC sd, STATIC_SIM_CORE\ (void) -sim_core_map_attach(SIM_DESC sd, - sim_core_map *access_map, - attach_type attach, - int space, - address_word addr, - unsigned nr_bytes, /* host limited */ - device *client, /*callback/default*/ - void *buffer, /*raw_memory*/ - int free_buffer) /*raw_memory*/ +sim_core_map_attach (SIM_DESC sd, + sim_core_map *access_map, + attach_type attach, + int space, + address_word addr, + address_word nr_bytes, + unsigned modulo, + device *client, /*callback/default*/ + void *buffer, /*raw_memory*/ + int free_buffer) /*raw_memory*/ { /* find the insertion point for this additional mapping and then insert */ sim_core_mapping *next_mapping; sim_core_mapping **last_mapping; - SIM_ASSERT((attach >= attach_callback && client != NULL && buffer == NULL && !free_buffer) - || (attach == attach_raw_memory && client == NULL && buffer != NULL)); + SIM_ASSERT ((attach >= attach_callback) + <= (client != NULL && buffer == NULL && !free_buffer)); + SIM_ASSERT ((attach == attach_raw_memory) + <= (client == NULL && buffer != NULL)); /* actually do occasionally get a zero size map */ - if (nr_bytes == 0) { + if (nr_bytes == 0) + { #if (WITH_DEVICES) - device_error(client, "called on sim_core_map_attach with size zero"); + device_error(client, "called on sim_core_map_attach with size zero"); #else - sim_io_error (sd, "called on sim_core_map_attach with size zero"); + sim_io_error (sd, "called on sim_core_map_attach with size zero"); #endif - } + } /* find the insertion point (between last/next) */ next_mapping = access_map->first; @@ -209,14 +210,15 @@ sim_core_map_attach(SIM_DESC sd, while(next_mapping != NULL && (next_mapping->level < (int) attach || (next_mapping->level == (int) attach - && next_mapping->bound < addr))) { - /* provided levels are the same */ - /* assert: next_mapping->base > all bases before next_mapping */ - /* assert: next_mapping->bound >= all bounds before next_mapping */ - last_mapping = &next_mapping->next; - next_mapping = next_mapping->next; - } - + && next_mapping->bound < addr))) + { + /* provided levels are the same */ + /* assert: next_mapping->base > all bases before next_mapping */ + /* assert: next_mapping->bound >= all bounds before next_mapping */ + last_mapping = &next_mapping->next; + next_mapping = next_mapping->next; + } + /* check insertion point correct */ SIM_ASSERT (next_mapping == NULL || next_mapping->level >= (int) attach); if (next_mapping != NULL && next_mapping->level == (int) attach @@ -248,7 +250,7 @@ sim_core_map_attach(SIM_DESC sd, /* create/insert the new mapping */ *last_mapping = new_sim_core_mapping(sd, attach, - space, addr, nr_bytes, + space, addr, nr_bytes, modulo, client, buffer, free_buffer); (*last_mapping)->next = next_mapping; } @@ -256,15 +258,16 @@ sim_core_map_attach(SIM_DESC sd, EXTERN_SIM_CORE\ (void) -sim_core_attach(SIM_DESC sd, - sim_cpu *cpu, - attach_type attach, - access_type access, - int space, - address_word addr, - unsigned nr_bytes, /* host limited */ - device *client, - void *optional_buffer) +sim_core_attach (SIM_DESC sd, + sim_cpu *cpu, + attach_type attach, + access_type access, + int space, + address_word addr, + address_word nr_bytes, + unsigned modulo, + device *client, + void *optional_buffer) { sim_core *memory = STATE_CORE(sd); sim_core_maps map; @@ -276,72 +279,107 @@ sim_core_attach(SIM_DESC sd, sim_io_error (sd, "sim_core_map_attach - processor specific memory map not yet supported"); if ((access & access_read_write_exec) == 0 - || (access & ~access_read_write_exec) != 0) { + || (access & ~access_read_write_exec) != 0) + { #if (WITH_DEVICES) - device_error(client, "invalid access for core attach"); + device_error(client, "invalid access for core attach"); #else - sim_io_error (sd, "invalid access for core attach"); + sim_io_error (sd, "invalid access for core attach"); #endif - } + } + /* verify the attach type */ - if (attach == attach_raw_memory) { - if (optional_buffer == NULL) { - buffer = zalloc(nr_bytes); - buffer_freed = 0; + 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; + 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) + { +#if (WITH_DEVICES) + device_error (client, "sim_core_attach - internal error - modulo memory disabled"); +#else + sim_io_error (sd, "sim_core_attach - internal error - modulo memory disabled"); +#endif + } + if (optional_buffer == NULL) + { + buffer = zalloc (modulo == 0 ? nr_bytes : modulo); + buffer_freed = 0; + } + else + { + buffer = optional_buffer; + buffer_freed = 1; + } } - else { - buffer = optional_buffer; + else if (attach >= attach_callback) + { + buffer = NULL; buffer_freed = 1; } - } - else if (attach >= attach_callback) { - buffer = NULL; - buffer_freed = 1; - } - else { + else + { #if (WITH_DEVICES) - device_error(client, "sim_core_attach - conflicting buffer and attach arguments"); + device_error (client, "sim_core_attach - internal error - conflicting buffer and attach arguments"); #else - sim_io_error (sd, "sim_core_attach - conflicting buffer and attach arguments"); + sim_io_error (sd, "sim_core_attach - internal error - conflicting buffer and attach arguments"); #endif - buffer = NULL; - buffer_freed = 1; - } + buffer = NULL; + buffer_freed = 1; + } + /* attach the region to all applicable access maps */ for (map = 0; map < nr_sim_core_maps; - map++) { - switch (map) { - case sim_core_read_map: - if (access & access_read) - sim_core_map_attach(sd, &memory->common.map[map], - attach, - space, addr, nr_bytes, - client, buffer, !buffer_freed); - buffer_freed ++; - break; - case sim_core_write_map: - if (access & access_write) - sim_core_map_attach(sd, &memory->common.map[map], - attach, - space, addr, nr_bytes, - client, buffer, !buffer_freed); - buffer_freed ++; - break; - case sim_core_execute_map: - if (access & access_exec) - sim_core_map_attach(sd, &memory->common.map[map], - attach, - space, addr, nr_bytes, - client, buffer, !buffer_freed); - buffer_freed ++; - break; - case nr_sim_core_maps: - sim_io_error (sd, "sim_core_attach - internal error - bad switch"); - break; + map++) + { + switch (map) + { + case sim_core_read_map: + if (access & access_read) + sim_core_map_attach (sd, &memory->common.map[map], + attach, + space, addr, nr_bytes, modulo, + client, buffer, !buffer_freed); + buffer_freed ++; + 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, + client, buffer, !buffer_freed); + buffer_freed ++; + 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, + client, buffer, !buffer_freed); + buffer_freed ++; + break; + case nr_sim_core_maps: + sim_io_error (sd, "sim_core_attach - internal error - bad switch"); + break; + } } - } - + /* Just copy this map to each of the processor specific data structures. FIXME - later this will be replaced by true processor specific maps. */ @@ -355,6 +393,62 @@ sim_core_attach(SIM_DESC sd, } +/* Remove any memory reference related to this address */ +STATIC_INLINE_SIM_CORE\ +(void) +sim_core_map_detach (SIM_DESC sd, + sim_core_map *access_map, + attach_type attach, + int space, + address_word addr) +{ + sim_core_mapping **entry; + for (entry = &access_map->first; + (*entry) != NULL; + entry = &(*entry)->next) + { + if ((*entry)->base == addr + && (*entry)->level == attach + && (*entry)->space == space) + { + sim_core_mapping *dead = (*entry); + (*entry) = dead->next; + if (dead->free_buffer) + zfree (dead->buffer); + zfree (dead); + return; + } + } +} + +EXTERN_SIM_CORE\ +(void) +sim_core_detach (SIM_DESC sd, + sim_cpu *cpu, + attach_type attach, + int address_space, + address_word addr) +{ + sim_core *memory = STATE_CORE (sd); + sim_core_maps map; + for (map = 0; map < nr_sim_core_maps; map++) + { + sim_core_map_detach (sd, &memory->common.map[map], + attach, address_space, addr); + } + /* Just copy this update to each of the processor specific data + structures. FIXME - later this will be replaced by true + processor specific maps. */ + { + int i; + for (i = 0; i < MAX_NR_PROCESSORS; i++) + { + CPU_CORE (STATE_CPU (sd, i))->common = STATE_CORE (sd)->common; + } + } +} + + STATIC_INLINE_SIM_CORE\ (sim_core_mapping *) sim_core_find_mapping(sim_core_common *core, @@ -391,7 +485,12 @@ STATIC_INLINE_SIM_CORE\ sim_core_translate (sim_core_mapping *mapping, address_word addr) { - return (void *)(((char *)mapping->buffer) + addr - mapping->base); + if (WITH_MODULO_MEMORY) + return (void *)((unsigned8 *) mapping->buffer + + ((addr - mapping->base) & mapping->mask)); + else + return (void *)((unsigned8 *) mapping->buffer + + addr - mapping->base); } diff --git a/sim/common/sim-core.h b/sim/common/sim-core.h index 5821b8c8907..a2d5ed9e07c 100644 --- a/sim/common/sim-core.h +++ b/sim/common/sim-core.h @@ -31,7 +31,8 @@ typedef enum { nr_sim_core_signals, } sim_core_signals; -/* define SIM_CORE_SIGNAL to catch these signals - see sim-core.c for details */ +/* define SIM_CORE_SIGNAL to catch these signals - see sim-core.c for + details */ @@ -44,7 +45,8 @@ struct _sim_core_mapping { int space; unsigned_word base; unsigned_word bound; - unsigned nr_bytes; + unsigned_word nr_bytes; + unsigned mask; /* memory map */ int free_buffer; void *buffer; @@ -69,12 +71,17 @@ typedef enum { } sim_core_maps; +typedef struct _sim_core_common { + sim_core_map map[nr_sim_core_maps]; +} sim_core_common; + + /* Main core structure */ typedef struct _sim_core sim_core; struct _sim_core { - int trace; - sim_core_map map[nr_sim_core_maps]; + sim_core_common common; + address_word byte_xor; /* apply xor universally */ }; @@ -82,7 +89,7 @@ struct _sim_core { mostly a clone of the global core data structure. */ typedef struct _sim_cpu_core { - sim_core common; + sim_core_common common; address_word xor[WITH_XOR_ENDIAN]; } sim_cpu_core; @@ -94,27 +101,12 @@ EXTERN_SIM_CORE\ -/* Configure the per-cpu core's XOR endian transfer mode. Only - applicable when WITH_XOR_ENDIAN is enabled. - - Targets suporting XOR endian, shall notify the core of any changes - in state via this call. - - FIXME - XOR endian memory transfers currently only work when made - through a correctly aligned cpu load/store. */ - -EXTERN_SIM_CORE\ -(void) sim_core_set_xor\ -(sim_cpu *cpu, - sim_cia cia, - int is_xor); - - - /* 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) */ + the memory space is to be attached to. (UNIMPLEMENTED). + + */ EXTERN_SIM_CORE\ (void) sim_core_attach @@ -124,21 +116,41 @@ EXTERN_SIM_CORE\ access_type access, int address_space, address_word addr, - unsigned nr_bytes, /* host limited */ + address_word nr_bytes, + unsigned modulo, /* Power of two, zero for none. */ device *client, void *optional_buffer); +/* Delete a memory space within the core. + + */ + +EXTERN_SIM_CORE\ +(void) sim_core_detach +(SIM_DESC sd, + sim_cpu *cpu, + attach_type attach, + int address_space, + address_word addr); /* Variable sized read/write Transfer a variable sized block of raw data between the host and target. Should any problems occure, the number of bytes - successfully transfered is returned. */ + successfully transfered is returned. + + No host/target byte endian conversion is performed. No xor-endian + conversion is performed. + + If CPU argument, when non NULL, specifies the processor specific + address map that is to be used in the transfer. */ + EXTERN_SIM_CORE\ (unsigned) sim_core_read_buffer (SIM_DESC sd, + sim_cpu *cpu, sim_core_maps map, void *buffer, address_word addr, @@ -147,22 +159,80 @@ EXTERN_SIM_CORE\ EXTERN_SIM_CORE\ (unsigned) sim_core_write_buffer (SIM_DESC sd, + sim_cpu *cpu, sim_core_maps map, const void *buffer, address_word addr, unsigned nr_bytes); + +/* Configure the core's XOR endian transfer mode. Only applicable + when WITH_XOR_ENDIAN is enabled. + + Targets suporting XOR endian, shall notify the core of any changes + in state via this call. + + The CPU argument, when non NULL, specifes the single processor that + the xor-endian configuration is to be applied to. */ + +EXTERN_SIM_CORE\ +(void) sim_core_set_xor\ +(SIM_DESC sd, + sim_cpu *cpu, + int is_xor); + + +/* XOR version of variable sized read/write. + + Transfer a variable sized block of raw data between the host and + target. Should any problems occure, the number of bytes + successfully transfered is returned. + + No host/target byte endian conversion is performed. If applicable + (WITH_XOR_ENDIAN and xor-endian set), xor-endian conversion *is* + performed. + + If CPU argument, when non NULL, specifies the processor specific + address map that is to be used in the transfer. */ + +EXTERN_SIM_CORE\ +(unsigned) sim_core_xor_read_buffer +(SIM_DESC sd, + sim_cpu *cpu, + sim_core_maps map, + void *buffer, + address_word addr, + unsigned nr_bytes); + +EXTERN_SIM_CORE\ +(unsigned) sim_core_xor_write_buffer +(SIM_DESC sd, + sim_cpu *cpu, + sim_core_maps map, + const void *buffer, + address_word addr, + unsigned nr_bytes); + + + /* Fixed sized, processor oriented, read/write. Transfer a fixed amout of memory between the host and target. The data transfered is translated from/to host to/from target byte - order. Should the transfer fail, the operation shall abort (no - return). The aligned alternative makes the assumption that that - the address is N byte aligned (no alignment checks are made). The - unaligned alternative checks the address for correct byte + order (including xor endian). Should the transfer fail, the + operation shall abort (no return). + + The aligned alternative makes the assumption that that the address + is N byte aligned (no alignment checks are made). + + The unaligned alternative checks the address for correct byte alignment. Action, as defined by WITH_ALIGNMENT, being taken - should the check fail. */ + should the check fail. + + Misaligned xor-endian accesses are broken into a sequence of + transfers each <= WITH_XOR_ENDIAN bytes */ + #define DECLARE_SIM_CORE_WRITE_N(ALIGNMENT,N) \ INLINE_SIM_CORE\ diff --git a/sim/common/sim-memopt.c b/sim/common/sim-memopt.c new file mode 100644 index 00000000000..be98a4a7100 --- /dev/null +++ b/sim/common/sim-memopt.c @@ -0,0 +1,261 @@ +/* Simulator memory option handling. + Copyright (C) 1996, 1997 Free Software Foundation, Inc. + Contributed by Cygnus Support. + +This file is part of GDB, the GNU debugger. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "sim-main.h" +#include "sim-assert.h" +#include "sim-options.h" + +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif +#ifdef HAVE_STDLIB_H +#include +#endif + +/* "core" command line options. */ + +enum { + OPTION_MEMORY_DELETE = OPTION_START, + OPTION_MEMORY_REGION, + OPTION_MEMORY_SIZE, + OPTION_MEMORY_INFO, + OPTION_MEMORY_ALIAS, + OPTION_MEMORY_CLEAR, +}; + +static DECLARE_OPTION_HANDLER (memory_option_handler); + +static const OPTION memory_options[] = +{ + { {"delete-memory", required_argument, NULL, OPTION_MEMORY_DELETE }, + '\0', "ADDRESS", "Delete memory at ADDRESS", + memory_option_handler }, + + { {"memory-region", required_argument, NULL, OPTION_MEMORY_REGION }, + '\0', "ADDRESS,SIZE[,MODULO]", "Add a memory region", + memory_option_handler }, + + { {"memory-alias", required_argument, NULL, OPTION_MEMORY_ALIAS }, + '\0', "ADDRESS,SIZE{,ADDRESS}", "Add memory shadow", + memory_option_handler }, + + { {"memory-size", required_argument, NULL, OPTION_MEMORY_SIZE }, + '\0', "SIZE", "Add memory at address zero", + memory_option_handler }, + + { {"memory-clear", no_argument, NULL, OPTION_MEMORY_CLEAR }, + '\0', NULL, "Clear all memory regions", + memory_option_handler }, + + { {"info-memory", no_argument, NULL, OPTION_MEMORY_INFO }, + '\0', NULL, "Add memory at address zero", + memory_option_handler }, + + { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL } +}; + + +static SIM_RC +memory_option_handler (sd, opt, arg, is_command) + SIM_DESC sd; + int opt; + char *arg; + int is_command; +{ + switch (opt) + { + + case OPTION_MEMORY_DELETE: + { + address_word addr = strtoul (arg, NULL, 0); + sim_memopt **entry = &STATE_MEMOPT (sd); + sim_memopt *alias; + while ((*entry) != NULL && (*entry)->addr != addr) + entry = &(*entry)->next; + if ((*entry) == NULL) + { + sim_io_eprintf (sd, "Memory at 0x%lx not found, not deleted\n", + (long) addr); + return SIM_RC_FAIL; + } + /* delete any buffer */ + if ((*entry)->buf != NULL) + zfree ((*entry)->buf); + /* delete it and its aliases */ + alias = *entry; + *entry = alias->next; + while (alias != NULL) + { + sim_memopt *dead = alias; + alias = alias->alias; + sim_core_detach (sd, NULL, attach_raw_memory, 0, dead->addr); + zfree (dead); + } + return SIM_RC_OK; + } + + case OPTION_MEMORY_REGION: + { + char *chp = arg; + address_word addr = 0; + address_word nr_bytes = 0; + unsigned modulo = 0; + sim_memopt **entry = &STATE_MEMOPT (sd); + /* parse the arguments */ + addr = strtoul (chp, &chp, 0); + if (*chp != ',') + { + sim_io_eprintf (sd, "Missing size for memory-region\n"); + return SIM_RC_FAIL; + } + chp++; + nr_bytes = strtoul (chp, &chp, 0); + if (*chp == ',') + modulo = strtoul (chp + 1, NULL, 0); + /* try to attach it */ + sim_core_attach (sd, NULL, + attach_raw_memory, access_read_write_exec, 0, + addr, nr_bytes, modulo, NULL, NULL); + /* ok, so insert it */ + while ((*entry) != NULL) + entry = &(*entry)->next; + (*entry) = ZALLOC (sim_memopt); + (*entry)->addr = addr; + (*entry)->nr_bytes = nr_bytes; + (*entry)->modulo = modulo; + return SIM_RC_OK; + } + + case OPTION_MEMORY_ALIAS: + { + sim_io_eprintf (sd, "memory-alias not supported for for this simulator\n"); + break; + } + + case OPTION_MEMORY_SIZE: + { + sim_io_eprintf (sd, "memory-size not supported for for this simulator\n"); + return SIM_RC_FAIL; + break; + } + + case OPTION_MEMORY_CLEAR: + { + sim_memopt *entry; + for (entry = STATE_MEMOPT (sd); entry != NULL; entry = entry->next) + { + 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)); + + } + } + return SIM_RC_OK; + break; + } + + case OPTION_MEMORY_INFO: + { + sim_memopt *entry; + sim_io_printf (sd, "Memory maps:\n"); + for (entry = STATE_MEMOPT (sd); entry != NULL; entry = entry->next) + { + 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); + } + else + { + 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", entry->addr); + } + sim_io_printf (sd, "\n"); + } + return SIM_RC_OK; + break; + } + + default: + sim_io_eprintf (sd, "Unknown watch option %d\n", opt); + return SIM_RC_FAIL; + + } + + return SIM_RC_FAIL; +} + + +/* "memory" module install handler. + + This is called via sim_module_install to install the "memory" subsystem + into the simulator. */ + +static MODULE_INIT_FN sim_memory_init; +static MODULE_UNINSTALL_FN sim_memory_uninstall; + +SIM_RC +sim_memopt_install (SIM_DESC sd) +{ + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); + sim_add_option_table (sd, memory_options); + sim_module_add_uninstall_fn (sd, sim_memory_uninstall); + sim_module_add_init_fn (sd, sim_memory_init); + return SIM_RC_OK; +} + + +/* Uninstall the "memory" subsystem from the simulator. */ + +static void +sim_memory_uninstall (SIM_DESC sd) +{ + /* FIXME: free buffers, etc. */ +} + + +static SIM_RC +sim_memory_init (SIM_DESC sd) +{ + /* FIXME: anything needed? */ + return SIM_RC_OK; +} diff --git a/sim/common/sim-memopt.h b/sim/common/sim-memopt.h new file mode 100644 index 00000000000..717c5704216 --- /dev/null +++ b/sim/common/sim-memopt.h @@ -0,0 +1,44 @@ +/* Header file for simulator memory argument handling. + Copyright (C) 1997 Free Software Foundation, Inc. + Contributed by Cygnus Support. + +This file is part of GDB, the GNU debugger. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef SIM_MEMOPT_H +#define SIM_MEMOPT_H + +/* Provides a command line interface for manipulating the memory core */ + +typedef struct _sim_memopt sim_memopt; +struct _sim_memopt { + unsigned_word addr; + unsigned_word nr_bytes; + unsigned modulo; + void *buf; + sim_memopt *alias; /* linked list */ + sim_memopt *next; +}; + + +/* Install the "memopt" module. */ + +SIM_RC sim_memopt_install (SIM_DESC sd); + + +/* Was there a memory command? */ + +#endif diff --git a/sim/common/sim-module.c b/sim/common/sim-module.c index 9292c370273..e58e6f3c57f 100644 --- a/sim/common/sim-module.c +++ b/sim/common/sim-module.c @@ -38,6 +38,10 @@ static MODULE_INSTALL_FN * const modules[] = { profile_install, #endif sim_core_install, +#ifndef SIM_HAVE_FLATMEM + /* FIXME: should handle flatmem as well FLATMEM */ + sim_memopt_install, +#endif sim_events_install, #if WITH_WATCHPOINTS sim_watchpoint_install, diff --git a/sim/common/sim-n-core.h b/sim/common/sim-n-core.h index 4aefd2df0d1..50c0e249c24 100644 --- a/sim/common/sim-n-core.h +++ b/sim/common/sim-n-core.h @@ -77,7 +77,7 @@ sim_core_read_aligned_N(sim_cpu *cpu, if (TRACE_P (cpu, TRACE_CORE_IDX)) if (sizeof (unsigned_N) > 4) trace_printf (CPU_STATE (cpu), cpu, - "sim-n-core.c:%d: read-%d %s:0x%08lx -> 0x%08lx%08lx\n", + "sim-n-core.h:%d: read-%d %s:0x%08lx -> 0x%08lx%08lx\n", __LINE__, sizeof (unsigned_N), sim_core_map_to_str (map), @@ -86,7 +86,7 @@ sim_core_read_aligned_N(sim_cpu *cpu, (unsigned long) val); else trace_printf (CPU_STATE (cpu), cpu, - "sim-n-core.c:%d: read-%d %s:0x%08lx -> 0x%0*lx\n", + "sim-n-core.h:%d: read-%d %s:0x%08lx -> 0x%0*lx\n", __LINE__, sizeof (unsigned_N), sim_core_map_to_str (map), @@ -190,7 +190,7 @@ sim_core_write_aligned_N(sim_cpu *cpu, if (TRACE_P (cpu, TRACE_CORE_IDX)) if (sizeof (unsigned_N) > 4) trace_printf (CPU_STATE (cpu), cpu, - "sim-n-core.c:%d: write-%d %s:0x%08lx <- 0x%08lx%08lx\n", + "sim-n-core.h:%d: write-%d %s:0x%08lx <- 0x%08lx%08lx\n", __LINE__, sizeof (unsigned_N), sim_core_map_to_str (map), @@ -199,7 +199,7 @@ sim_core_write_aligned_N(sim_cpu *cpu, (unsigned long) val); else trace_printf (CPU_STATE (cpu), cpu, - "sim-n-core.c:%d: write-%d %s:0x%08lx <- 0x%0*lx\n", + "sim-n-core.h:%d: write-%d %s:0x%08lx <- 0x%0*lx\n", __LINE__, sizeof (unsigned_N), sim_core_map_to_str (map), diff --git a/sim/common/sim-utils.c b/sim/common/sim-utils.c index c72a1ab34d9..6a7c5baf6d9 100644 --- a/sim/common/sim-utils.c +++ b/sim/common/sim-utils.c @@ -193,13 +193,13 @@ sim_elapsed_time_get () #ifdef HAVE_GETRUSAGE struct rusage mytime; if (getrusage (RUSAGE_SELF, &mytime) == 0) - return (SIM_ELAPSED_TIME) (((double) mytime.ru_utime.tv_sec * 1000) + (((double) mytime.ru_utime.tv_usec + 500) / 1000)); - return 0; + return 1 + (SIM_ELAPSED_TIME) (((double) mytime.ru_utime.tv_sec * 1000) + (((double) mytime.ru_utime.tv_usec + 500) / 1000)); + return 1; #else #ifdef HAVE_TIME - return (SIM_ELAPSED_TIME) time ((time_t) 0); + return 1 + (SIM_ELAPSED_TIME) time ((time_t) 0); #else - return 0; + return 1; #endif #endif } diff --git a/sim/common/sim-watch.c b/sim/common/sim-watch.c index 9a0b1bc0988..881144d0e27 100644 --- a/sim/common/sim-watch.c +++ b/sim/common/sim-watch.c @@ -69,13 +69,15 @@ static SIM_RC schedule_watchpoint (SIM_DESC sd, watchpoint_type type, unsigned long arg, + int is_within, int is_command) { sim_watchpoints *watch = STATE_WATCHPOINTS (sd); sim_watch_point *point = &watch->points[type]; if (point->event != NULL) - delete_watchpoint (sd, type); + sim_events_deschedule (sd, point->event); point->arg = arg; + point->is_within = is_within; if (point->action == invalid_watchpoint_action) point->action = break_watchpoint_action; if (is_command) @@ -84,6 +86,7 @@ schedule_watchpoint (SIM_DESC sd, case pc_watchpoint: point->event = sim_events_watch_sim (sd, watch->pc, watch->sizeof_pc, 0/* host-endian */, + point->is_within, point->arg, point->arg, /* PC == arg? */ handle_watchpoint, point); @@ -125,7 +128,7 @@ handle_watchpoint (SIM_DESC sd, void *data) case n_interrupt_watchpoint_action: /* First reschedule this event */ - schedule_watchpoint (sd, type, point->arg, 1/*is-command*/); + schedule_watchpoint (sd, type, point->arg, point->is_within, 1/*is-command*/); /* FALL-THROUGH */ case interrupt_watchpoint_action: @@ -133,8 +136,8 @@ handle_watchpoint (SIM_DESC sd, void *data) break; default: - sim_engine_abort (sd, NULL, NULL_CIA, - "handle_watchpoint - internal error - bad switch"); + sim_engine_abort (sd, NULL, NULL_CIA, + "handle_watchpoint - internal error - bad switch"); } } @@ -145,11 +148,11 @@ action_watchpoint (SIM_DESC sd, watchpoint_type type, const char *arg) { sim_watchpoints *watch = STATE_WATCHPOINTS (sd); sim_watch_point *point = &watch->points[type]; - if (strcmp (arg, "break") == NULL) + if (strcmp (arg, "break") == 0) { point->action = break_watchpoint_action; } - else if (strcmp (arg, "int") == NULL) + else if (strcmp (arg, "int") == 0) { if (watch->interrupt_handler == NULL) { @@ -181,9 +184,12 @@ static const OPTION watch_options[] = { {"watch-delete", required_argument, NULL, OPTION_WATCH_DELETE }, '\0', "all|pc|cycles|clock", "Delete a watchpoint", watch_option_handler }, + { {"delete-watch", required_argument, NULL, OPTION_WATCH_DELETE }, + '\0', "all|pc|cycles|clock", NULL, + watch_option_handler }, { {"watch-pc", required_argument, NULL, OPTION_WATCH_PC }, - '\0', "VALUE", "Watch the PC (break)", + '\0', "[!] VALUE", "Watch the PC (break)", watch_option_handler }, { {"watch-clock", required_argument, NULL, OPTION_WATCH_CLOCK }, '\0', "TIME-IN-MS", "Watch the clock (break)", @@ -244,19 +250,24 @@ watch_option_handler (sd, opt, arg, is_command) sim_io_eprintf (sd, "PC watchpoints are not supported for this simulator\n"); return SIM_RC_FAIL; } - return schedule_watchpoint (sd, pc_watchpoint, strtoul (arg, NULL, 0), is_command); + if (arg[0] == '!') + return schedule_watchpoint (sd, pc_watchpoint, strtoul (arg + 1, NULL, 0), + 0 /* !is_within */, is_command); + else + return schedule_watchpoint (sd, pc_watchpoint, strtoul (arg, NULL, 0), + 1 /* is_within */, is_command); case OPTION_WATCH_CLOCK: - return schedule_watchpoint (sd, clock_watchpoint, strtoul (arg, NULL, 0), is_command); + return schedule_watchpoint (sd, clock_watchpoint, strtoul (arg, NULL, 0), 0, is_command); case OPTION_WATCH_CYCLES: - return schedule_watchpoint (sd, cycles_watchpoint, strtoul (arg, NULL, 0), is_command); + return schedule_watchpoint (sd, cycles_watchpoint, strtoul (arg, NULL, 0), 0, is_command); case OPTION_ACTION_PC: - return action_watchpoint (sd, cycles_watchpoint, arg); + return action_watchpoint (sd, pc_watchpoint, arg); case OPTION_ACTION_CLOCK: - return action_watchpoint (sd, cycles_watchpoint, arg); + return action_watchpoint (sd, clock_watchpoint, arg); case OPTION_ACTION_CYCLES: return action_watchpoint (sd, cycles_watchpoint, arg); @@ -279,7 +290,10 @@ sim_watchpoint_init (SIM_DESC sd) for (type = 0; type < nr_watchpoint_types; type++) { if (watch->points[type].action != invalid_watchpoint_action) - schedule_watchpoint (sd, type, watch->points[type].arg, 1/*is-command*/); + schedule_watchpoint (sd, type, + watch->points[type].arg, + watch->points[type].is_within, + 1 /*is-command*/); } return SIM_RC_OK; } diff --git a/sim/m32r/ChangeLog b/sim/m32r/ChangeLog index b695a253c00..9faeeb8df1c 100644 --- a/sim/m32r/ChangeLog +++ b/sim/m32r/ChangeLog @@ -1,3 +1,7 @@ +Thu Sep 4 10:30:02 1997 Andrew Cagney + + * sim-if.c (sim_open): Pass zero modulo arg to sim_core_attach. + Wed Aug 27 18:13:22 1997 Andrew Cagney * configure: Regenerated to track ../common/aclocal.m4 changes. diff --git a/sim/m32r/sim-if.c b/sim/m32r/sim-if.c index a273347398d..28f06375b47 100644 --- a/sim/m32r/sim-if.c +++ b/sim/m32r/sim-if.c @@ -81,7 +81,7 @@ sim_open (kind, callback, abfd, argv) /* FIXME:wip */ sim_core_attach (sd, NULL, attach_raw_memory, access_read_write_exec, - 0, 0, M32R_DEFAULT_MEM_SIZE, NULL, NULL); + 0, 0, M32R_DEFAULT_MEM_SIZE, 0, NULL, NULL); /* Only needed for profiling, but the structure member is small. */ for (i = 0; i < MAX_NR_PROCESSORS; ++i) diff --git a/sim/tic80/ChangeLog b/sim/tic80/ChangeLog index 0ac08b222f0..6a5102b042b 100644 --- a/sim/tic80/ChangeLog +++ b/sim/tic80/ChangeLog @@ -1,3 +1,14 @@ +Thu Sep 4 10:48:57 1997 Andrew Cagney + + * sim-calls.c (sim_open): Use sim_do_command to add memory, only + add memory if none already present. + (sim_open): Move init of registers from here. + (sim_create_inferior): To here. Init modules. + + * Makefile.in (SIM_OBJS): Add sim-memopt.o module. + + * sim-calls.c (sim_open): Add zero modulo arg to sim_core_attach. + Mon Sep 1 11:06:30 1997 Andrew Cagney * sim-calls.c (sim_open): Use sim_state_alloc diff --git a/sim/tic80/Makefile.in b/sim/tic80/Makefile.in index 570f20801f3..f15b68f969b 100644 --- a/sim/tic80/Makefile.in +++ b/sim/tic80/Makefile.in @@ -19,6 +19,7 @@ SIM_OBJS = sim-endian.o sim-bits.o sim-config.o \ sim-io.o \ sim-utils.o \ sim-load.o \ + sim-memopt.o \ sim-module.o \ sim-options.o \ sim-trace.o \ diff --git a/sim/tic80/sim-calls.c b/sim/tic80/sim-calls.c index 32da79b5259..7d4c6a9f915 100644 --- a/sim/tic80/sim-calls.c +++ b/sim/tic80/sim-calls.c @@ -92,28 +92,22 @@ sim_open (SIM_OPEN_KIND kind, return 0; } - /* Initialize the main processor */ - memset (&STATE_CPU (sd, 0)->reg, 0, sizeof STATE_CPU (sd, 0)->reg); - memset (&STATE_CPU (sd, 0)->acc, 0, sizeof STATE_CPU (sd, 0)->acc); - memset (&STATE_CPU (sd, 0)->cr, 0, sizeof STATE_CPU (sd, 0)->cr); - STATE_CPU (sd, 0)->is_user_mode = 0; - memset (&STATE_CPU (sd, 0)->cia, 0, sizeof STATE_CPU (sd, 0)->cia); - CPU_STATE (STATE_CPU (sd, 0)) = sd; - #define TIC80_MEM_START 0x2000000 #define TIC80_MEM_SIZE 0x100000 - /* external memory */ - sim_core_attach(sd, - NULL, - attach_raw_memory, - access_read_write_exec, - 0, TIC80_MEM_START, TIC80_MEM_SIZE, NULL, NULL); - sim_core_attach(sd, - NULL, - attach_raw_memory, - access_read_write_exec, - 0, 0, TIC80_MEM_SIZE, NULL, NULL); + if (!STATE_MEMOPT_P (sd)) + { + char *buf; + /* main memory */ + asprintf (&buf, "memory region 0x%lx,0x%lx", + TIC80_MEM_START, TIC80_MEM_SIZE); + sim_do_command (sd, buf); + free (buf); + /* interrupt memory */ + sim_do_command (sd, "memory region 0x1010000,0x1000"); + /* some memory at zero */ + sim_do_command (sd, "memory region 0,0x100000"); + } /* FIXME: for now */ return sd; @@ -206,6 +200,15 @@ sim_create_inferior (SIM_DESC sd, char **argv, char **envp) { + /* clear all registers */ + memset (&STATE_CPU (sd, 0)->reg, 0, sizeof (STATE_CPU (sd, 0)->reg)); + memset (&STATE_CPU (sd, 0)->acc, 0, sizeof (STATE_CPU (sd, 0)->acc)); + memset (&STATE_CPU (sd, 0)->cr, 0, sizeof (STATE_CPU (sd, 0)->cr)); + STATE_CPU (sd, 0)->is_user_mode = 0; + memset (&STATE_CPU (sd, 0)->cia, 0, sizeof (STATE_CPU (sd, 0)->cia)); + /* initialize any modules */ + sim_module_init (sd); + /* set the stack-pointer/program counter */ if (abfd != NULL) STATE_CPU (sd, 0)->cia.ip = bfd_get_start_address (abfd); else