aboutsummaryrefslogtreecommitdiff
path: root/sim/common
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>1997-09-04 03:47:39 +0000
committerAndrew Cagney <cagney@redhat.com>1997-09-04 03:47:39 +0000
commita34abff813f4fdd5f289ea45de9e874e31e7edf3 (patch)
treef6d3be383893c3adaae166e570d5eccd71f08427 /sim/common
parent600d83316cfa68f72666d792244890789812b51a (diff)
downloadfsf-binutils-gdb-a34abff813f4fdd5f289ea45de9e874e31e7edf3.zip
fsf-binutils-gdb-a34abff813f4fdd5f289ea45de9e874e31e7edf3.tar.gz
fsf-binutils-gdb-a34abff813f4fdd5f289ea45de9e874e31e7edf3.tar.bz2
o Add modulo argument to sim_core_attach
o Add sim-memopt module - memory option processing.
Diffstat (limited to 'sim/common')
-rw-r--r--sim/common/.Sanitize2
-rw-r--r--sim/common/ChangeLog37
-rw-r--r--sim/common/Make-common.in5
-rw-r--r--sim/common/sim-base.h6
-rw-r--r--sim/common/sim-basics.h39
-rw-r--r--sim/common/sim-core.c349
-rw-r--r--sim/common/sim-core.h130
-rw-r--r--sim/common/sim-memopt.c261
-rw-r--r--sim/common/sim-memopt.h44
-rw-r--r--sim/common/sim-module.c4
-rw-r--r--sim/common/sim-n-core.h8
-rw-r--r--sim/common/sim-utils.c8
-rw-r--r--sim/common/sim-watch.c40
13 files changed, 729 insertions, 204 deletions
diff --git a/sim/common/.Sanitize b/sim/common/.Sanitize
index 7c8de96..2f802cb 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 f3679c4..39fce64 100644
--- a/sim/common/ChangeLog
+++ b/sim/common/ChangeLog
@@ -1,3 +1,40 @@
+Thu Sep 4 09:27:54 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * 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 <dje@seba.cygnus.com>
* 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 79ffb95..c345d61 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 ef5f1ce..988eb29 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 149e6a0..e94075c 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 d819258..34fd05f 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;
}
@@ -51,18 +55,10 @@ 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 5821b8c..a2d5ed9 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 0000000..be98a4a
--- /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 <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#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 0000000..717c570
--- /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 9292c37..e58e6f3 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 4aefd2d..50c0e24 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 c72a1ab..6a7c5ba 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 9a0b1bc..881144d 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;
}