o Add modulo argument to sim_core_attach

o	Add sim-memopt module - memory option processing.
This commit is contained in:
Andrew Cagney 1997-09-04 03:47:39 +00:00
parent 600d83316c
commit a34abff813
18 changed files with 769 additions and 225 deletions

View file

@ -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

View file

@ -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.

View file

@ -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)

View file

@ -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;

View file

@ -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. */

View file

@ -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);
}

View file

@ -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
View 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
View 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

View file

@ -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,

View file

@ -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),

View file

@ -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
}

View file

@ -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;
}

View file

@ -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.

View file

@ -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)

View file

@ -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

View file

@ -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 \

View file

@ -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