o Add modulo argument to sim_core_attach
o Add sim-memopt module - memory option processing.
This commit is contained in:
parent
600d83316c
commit
a34abff813
18 changed files with 769 additions and 225 deletions
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
else {
|
||||
buffer = optional_buffer;
|
||||
|
||||
/* verify the attach type */
|
||||
if (attach == attach_raw_memory)
|
||||
{
|
||||
if (WITH_MODULO_MEMORY && modulo != 0)
|
||||
{
|
||||
unsigned mask = modulo - 1;
|
||||
if (mask < 7) /* 8 is minimum modulo */
|
||||
mask = 0;
|
||||
while (mask > 1) /* no zero bits */
|
||||
if ((mask & 1) == 0)
|
||||
mask = 0;
|
||||
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 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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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\
|
||||
|
|
261
sim/common/sim-memopt.c
Normal file
261
sim/common/sim-memopt.c
Normal file
|
@ -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;
|
||||
}
|
44
sim/common/sim-memopt.h
Normal file
44
sim/common/sim-memopt.h
Normal file
|
@ -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
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
Thu Sep 4 10:30:02 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* sim-if.c (sim_open): Pass zero modulo arg to sim_core_attach.
|
||||
|
||||
Wed Aug 27 18:13:22 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* configure: Regenerated to track ../common/aclocal.m4 changes.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
Thu Sep 4 10:48:57 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* 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 <cagney@b1.cygnus.com>
|
||||
|
||||
* sim-calls.c (sim_open): Use sim_state_alloc
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue