summaryrefslogtreecommitdiff
path: root/sim/common/sim-events.c
diff options
context:
space:
mode:
Diffstat (limited to 'sim/common/sim-events.c')
-rw-r--r--sim/common/sim-events.c1201
1 files changed, 0 insertions, 1201 deletions
diff --git a/sim/common/sim-events.c b/sim/common/sim-events.c
deleted file mode 100644
index 1866b2dccd7..00000000000
--- a/sim/common/sim-events.c
+++ /dev/null
@@ -1,1201 +0,0 @@
-/* This file is part of the program psim.
-
- Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
-
- 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 of the License, 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_EVENTS_C_
-#define _SIM_EVENTS_C_
-
-#include "sim-main.h"
-#include "sim-assert.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
-
-#include <signal.h> /* For SIGPROCMASK et.al. */
-
-typedef enum {
- watch_invalid,
-
- /* core - target byte order */
- watch_core_targ_1,
- watch_core_targ_2,
- watch_core_targ_4,
- watch_core_targ_8,
- /* core - big-endian */
- watch_core_be_1,
- watch_core_be_2,
- watch_core_be_4,
- watch_core_be_8,
- /* core - little-endian */
- watch_core_le_1,
- watch_core_le_2,
- watch_core_le_4,
- watch_core_le_8,
-
- /* sim - host byte order */
- watch_sim_host_1,
- watch_sim_host_2,
- watch_sim_host_4,
- watch_sim_host_8,
- /* sim - big-endian */
- watch_sim_be_1,
- watch_sim_be_2,
- watch_sim_be_4,
- watch_sim_be_8,
- /* sim - little-endian */
- watch_sim_le_1,
- watch_sim_le_2,
- watch_sim_le_4,
- watch_sim_le_8,
-
- /* wallclock */
- watch_clock,
-
- /* timer */
- watch_timer,
-} sim_event_watchpoints;
-
-
-struct _sim_event {
- sim_event_watchpoints watching;
- void *data;
- sim_event_handler *handler;
- /* timer event */
- signed64 time_of_event;
- /* watch wallclock event */
- unsigned wallclock;
- /* watch core address */
- address_word core_addr;
- unsigned core_map;
- /* watch sim addr */
- void *host_addr;
- /* watch core/sim range */
- int is_within; /* 0/1 */
- unsigned ub;
- unsigned lb;
- unsigned64 ub64;
- unsigned64 lb64;
- /* trace info (if any) */
- char *trace;
- /* list */
- sim_event *next;
-};
-
-
-/* The event queue maintains a single absolute time using two
- variables.
-
- TIME_OF_EVENT: this holds the time at which the next event is ment
- to occure. If no next event it will hold the time of the last
- event.
-
- TIME_FROM_EVENT: The current distance from TIME_OF_EVENT. A value
- <= 0 (except when poll-event is being processed) indicates that
- event processing is due. This variable is decremented once for
- each iteration of a clock cycle.
-
- Initially, the clock is started at time one (0) with TIME_OF_EVENT
- == 0 and TIME_FROM_EVENT == 0 and with NR_TICKS_TO_PROCESS == 1.
-
- Clearly there is a bug in that this code assumes that the absolute
- time counter will never become greater than 2^62.
-
- To avoid the need to use 64bit arithmetic, the event queue always
- contains at least one event scheduled every 16 000 ticks. This
- limits the time from event counter to values less than
- 16 000. */
-
-
-#if !defined (SIM_EVENTS_POLL_RATE)
-#define SIM_EVENTS_POLL_RATE 0x1000
-#endif
-
-
-#define _ETRACE sd, NULL
-
-#undef ETRACE_P
-#define ETRACE_P (WITH_TRACE && STATE_EVENTS (sd)->trace)
-
-#undef ETRACE
-#define ETRACE(ARGS) \
-do \
- { \
- if (ETRACE_P) \
- { \
- if (STRACE_DEBUG_P (sd)) \
- { \
- const char *file; \
- SIM_FILTER_PATH (file, __FILE__); \
- trace_printf (sd, NULL, "%s:%d: ", file, __LINE__); \
- } \
- trace_printf ARGS; \
- } \
- } \
-while (0)
-
-
-/* event queue iterator - don't iterate over the held queue. */
-
-#if EXTERN_SIM_EVENTS_P
-static sim_event **
-next_event_queue (SIM_DESC sd,
- sim_event **queue)
-{
- if (queue == NULL)
- return &STATE_EVENTS (sd)->queue;
- else if (queue == &STATE_EVENTS (sd)->queue)
- return &STATE_EVENTS (sd)->watchpoints;
- else if (queue == &STATE_EVENTS (sd)->watchpoints)
- return &STATE_EVENTS (sd)->watchedpoints;
- else if (queue == &STATE_EVENTS (sd)->watchedpoints)
- return NULL;
- else
- sim_io_error (sd, "next_event_queue - bad queue");
- return NULL;
-}
-#endif
-
-
-STATIC_INLINE_SIM_EVENTS\
-(void)
-sim_events_poll (SIM_DESC sd,
- void *data)
-{
- /* just re-schedule in 1000 million ticks time */
- sim_events_schedule (sd, SIM_EVENTS_POLL_RATE, sim_events_poll, sd);
- sim_io_poll_quit (sd);
-}
-
-
-/* "events" module install handler.
- This is called via sim_module_install to install the "events" subsystem
- into the simulator. */
-
-#if EXTERN_SIM_EVENTS_P
-STATIC_SIM_EVENTS (MODULE_UNINSTALL_FN) sim_events_uninstall;
-STATIC_SIM_EVENTS (MODULE_INIT_FN) sim_events_init;
-STATIC_SIM_EVENTS (MODULE_RESUME_FN) sim_events_resume;
-STATIC_SIM_EVENTS (MODULE_SUSPEND_FN) sim_events_suspend;
-#endif
-
-#if EXTERN_SIM_EVENTS_P
-SIM_RC
-sim_events_install (SIM_DESC sd)
-{
- SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
- sim_module_add_uninstall_fn (sd, sim_events_uninstall);
- sim_module_add_init_fn (sd, sim_events_init);
- sim_module_add_resume_fn (sd, sim_events_resume);
- sim_module_add_suspend_fn (sd, sim_events_suspend);
- return SIM_RC_OK;
-}
-#endif
-
-
-/* Suspend/resume the event queue manager when the simulator is not
- running */
-
-#if EXTERN_SIM_EVENTS_P
-static SIM_RC
-sim_events_resume (SIM_DESC sd)
-{
- sim_events *events = STATE_EVENTS (sd);
- SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
- SIM_ASSERT (events->resume_wallclock == 0);
- events->resume_wallclock = sim_elapsed_time_get ();
- return SIM_RC_OK;
-}
-#endif
-
-#if EXTERN_SIM_EVENTS_P
-static SIM_RC
-sim_events_suspend (SIM_DESC sd)
-{
- sim_events *events = STATE_EVENTS (sd);
- SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
- SIM_ASSERT (events->resume_wallclock != 0);
- events->elapsed_wallclock += sim_elapsed_time_since (events->resume_wallclock);
- events->resume_wallclock = 0;
- return SIM_RC_OK;
-}
-#endif
-
-
-/* Uninstall the "events" subsystem from the simulator. */
-
-#if EXTERN_SIM_EVENTS_P
-static void
-sim_events_uninstall (SIM_DESC sd)
-{
- SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
- /* FIXME: free buffers, etc. */
-}
-#endif
-
-
-/* malloc/free */
-
-#if EXTERN_SIM_EVENTS_P
-static sim_event *
-sim_events_zalloc (SIM_DESC sd)
-{
- sim_events *events = STATE_EVENTS (sd);
- sim_event *new = events->free_list;
- if (new != NULL)
- {
- events->free_list = new->next;
- memset (new, 0, sizeof (*new));
- }
- else
- {
-#if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
- /*-LOCK-*/
- sigset_t old_mask;
- sigset_t new_mask;
- sigfillset(&new_mask);
- sigprocmask (SIG_SETMASK, &new_mask, &old_mask);
-#endif
- new = ZALLOC (sim_event);
-#if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
- /*-UNLOCK-*/
- sigprocmask (SIG_SETMASK, &old_mask, NULL);
-#endif
- }
- return new;
-}
-#endif
-
-STATIC_INLINE_SIM_EVENTS\
-(void)
-sim_events_free (SIM_DESC sd,
- sim_event *dead)
-{
- sim_events *events = STATE_EVENTS (sd);
- dead->next = events->free_list;
- events->free_list = dead;
- if (dead->trace != NULL)
- {
- free (dead->trace); /* NB: asprintf returns a `free' buf */
- dead->trace = NULL;
- }
-}
-
-
-/* Initialize the simulator event manager */
-
-#if EXTERN_SIM_EVENTS_P
-SIM_RC
-sim_events_init (SIM_DESC sd)
-{
- sim_events *events = STATE_EVENTS (sd);
-
- /* drain the interrupt queue */
- events->nr_held = 0;
- if (events->held == NULL)
- events->held = NZALLOC (sim_event, MAX_NR_SIGNAL_SIM_EVENTS);
-
- /* drain the normal queues */
- {
- sim_event **queue = NULL;
- while ((queue = next_event_queue (sd, queue)) != NULL)
- {
- if (queue == NULL) break;
- while (*queue != NULL)
- {
- sim_event *dead = *queue;
- *queue = dead->next;
- sim_events_free (sd, dead);
- }
- *queue = NULL;
- }
- }
-
- /* wind time back to zero */
- events->nr_ticks_to_process = 1; /* start by doing queue */
- events->time_of_event = 0;
- events->time_from_event = 0;
- events->elapsed_wallclock = 0;
- events->resume_wallclock = 0;
-
- /* schedule our initial counter event */
- sim_events_schedule (sd, 0, sim_events_poll, sd);
-
- /* from now on, except when the large-int event is being processed
- the event queue is non empty */
- SIM_ASSERT (events->queue != NULL);
-
- return SIM_RC_OK;
-}
-#endif
-
-
-INLINE_SIM_EVENTS\
-(signed64)
-sim_events_time (SIM_DESC sd)
-{
- sim_events *events = STATE_EVENTS (sd);
- return (events->time_of_event - events->time_from_event);
-}
-
-
-INLINE_SIM_EVENTS\
-(unsigned long)
-sim_events_elapsed_time (SIM_DESC sd)
-{
- unsigned long elapsed = STATE_EVENTS (sd)->elapsed_wallclock;
-
- /* Are we being called inside sim_resume?
- (Is there a simulation in progress?) */
- if (STATE_EVENTS (sd)->resume_wallclock != 0)
- elapsed += sim_elapsed_time_since (STATE_EVENTS (sd)->resume_wallclock);
-
- return elapsed;
-}
-
-
-/* Returns the time that remains before the event is raised. */
-INLINE_SIM_EVENTS\
-(signed64)
-sim_events_remain_time (SIM_DESC sd, sim_event *event)
-{
- if (event == 0)
- return 0;
-
- return (event->time_of_event - sim_events_time (sd));
-}
-
-
-
-STATIC_INLINE_SIM_EVENTS\
-(void)
-update_time_from_event (SIM_DESC sd)
-{
- sim_events *events = STATE_EVENTS (sd);
- signed64 current_time = sim_events_time (sd);
- if (events->queue != NULL)
- {
- events->time_of_event = events->queue->time_of_event;
- events->time_from_event = (events->queue->time_of_event - current_time);
- }
- else
- {
- events->time_of_event = current_time - 1;
- events->time_from_event = -1;
- }
- if (ETRACE_P)
- {
- sim_event *event;
- int i;
- for (event = events->queue, i = 0;
- event != NULL;
- event = event->next, i++)
- {
- ETRACE ((_ETRACE,
- "event time-from-event - time %ld, delta %ld - event %d, tag 0x%lx, time %ld, handler 0x%lx, data 0x%lx%s%s\n",
- (long)current_time,
- (long)events->time_from_event,
- i,
- (long)event,
- (long)event->time_of_event,
- (long)event->handler,
- (long)event->data,
- (event->trace != NULL) ? ", " : "",
- (event->trace != NULL) ? event->trace : ""));
- }
- }
- SIM_ASSERT (current_time == sim_events_time (sd));
-}
-
-
-#if EXTERN_SIM_EVENTS_P
-static void
-insert_sim_event (SIM_DESC sd,
- sim_event *new_event,
- signed64 delta)
-{
- sim_events *events = STATE_EVENTS (sd);
- sim_event *curr;
- sim_event **prev;
- signed64 time_of_event;
-
- if (delta < 0)
- sim_io_error (sd, "what is past is past!\n");
-
- /* compute when the event should occure */
- time_of_event = sim_events_time (sd) + delta;
-
- /* find the queue insertion point - things are time ordered */
- prev = &events->queue;
- curr = events->queue;
- while (curr != NULL && time_of_event >= curr->time_of_event)
- {
- SIM_ASSERT (curr->next == NULL
- || curr->time_of_event <= curr->next->time_of_event);
- prev = &curr->next;
- curr = curr->next;
- }
- SIM_ASSERT (curr == NULL || time_of_event < curr->time_of_event);
-
- /* insert it */
- new_event->next = curr;
- *prev = new_event;
- new_event->time_of_event = time_of_event;
-
- /* adjust the time until the first event */
- update_time_from_event (sd);
-}
-#endif
-
-
-#if EXTERN_SIM_EVENTS_P
-sim_event *
-sim_events_schedule (SIM_DESC sd,
- signed64 delta_time,
- sim_event_handler *handler,
- void *data)
-{
- va_list dummy;
- return sim_events_schedule_vtracef (sd, delta_time, handler, data,
- NULL, dummy);
-}
-#endif
-
-
-#if EXTERN_SIM_EVENTS_P
-sim_event *
-sim_events_schedule_tracef (SIM_DESC sd,
- signed64 delta_time,
- sim_event_handler *handler,
- void *data,
- const char *fmt,
- ...)
-{
- sim_event *new_event;
- va_list ap;
- va_start (ap, fmt);
- new_event = sim_events_schedule_vtracef (sd, delta_time, handler, data, fmt, ap);
- va_end (ap);
- return new_event;
-}
-#endif
-
-
-#if EXTERN_SIM_EVENTS_P
-sim_event *
-sim_events_schedule_vtracef (SIM_DESC sd,
- signed64 delta_time,
- sim_event_handler *handler,
- void *data,
- const char *fmt,
- va_list ap)
-{
- sim_event *new_event = sim_events_zalloc (sd);
- new_event->data = data;
- new_event->handler = handler;
- new_event->watching = watch_timer;
- if (fmt == NULL || !ETRACE_P || vasprintf (&new_event->trace, fmt, ap) < 0)
- new_event->trace = NULL;
- insert_sim_event(sd, new_event, delta_time);
- ETRACE((_ETRACE,
- "event scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
- (long)sim_events_time(sd),
- (long)new_event,
- (long)new_event->time_of_event,
- (long)new_event->handler,
- (long)new_event->data,
- (new_event->trace != NULL) ? ", " : "",
- (new_event->trace != NULL) ? new_event->trace : ""));
- return new_event;
-}
-#endif
-
-
-#if EXTERN_SIM_EVENTS_P
-void
-sim_events_schedule_after_signal (SIM_DESC sd,
- signed64 delta_time,
- sim_event_handler *handler,
- void *data)
-{
- sim_events *events = STATE_EVENTS (sd);
- sim_event *new_event;
-#if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
- /*-LOCK-*/
- sigset_t old_mask;
- sigset_t new_mask;
- sigfillset(&new_mask);
- sigprocmask (SIG_SETMASK, &new_mask, &old_mask);
-#endif
-
- /* allocate an event entry from the signal buffer */
- new_event = &events->held [events->nr_held];
- events->nr_held ++;
- if (events->nr_held > MAX_NR_SIGNAL_SIM_EVENTS)
- {
- sim_engine_abort (NULL, NULL, NULL_CIA,
- "sim_events_schedule_after_signal - buffer oveflow");
- }
-
- new_event->data = data;
- new_event->handler = handler;
- new_event->time_of_event = delta_time; /* work it out later */
- new_event->next = NULL;
-
- events->work_pending = 1; /* notify main process */
-
-#if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
- /*-UNLOCK-*/
- sigprocmask (SIG_SETMASK, &old_mask, NULL);
-#endif
-
- ETRACE ((_ETRACE,
- "signal scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
- (long)sim_events_time(sd),
- (long)new_event,
- (long)new_event->time_of_event,
- (long)new_event->handler,
- (long)new_event->data));
-}
-#endif
-
-
-#if EXTERN_SIM_EVENTS_P
-sim_event *
-sim_events_watch_clock (SIM_DESC sd,
- unsigned delta_ms_time,
- sim_event_handler *handler,
- void *data)
-{
- sim_events *events = STATE_EVENTS (sd);
- sim_event *new_event = sim_events_zalloc (sd);
- /* type */
- new_event->watching = watch_clock;
- /* handler */
- new_event->data = data;
- new_event->handler = handler;
- /* data */
- if (events->resume_wallclock == 0)
- new_event->wallclock = (events->elapsed_wallclock + delta_ms_time);
- else
- new_event->wallclock = (events->elapsed_wallclock
- + sim_elapsed_time_since (events->resume_wallclock)
- + delta_ms_time);
- /* insert */
- new_event->next = events->watchpoints;
- events->watchpoints = new_event;
- events->work_pending = 1;
- ETRACE ((_ETRACE,
- "event watching clock at %ld - tag 0x%lx - wallclock %ld, handler 0x%lx, data 0x%lx\n",
- (long)sim_events_time (sd),
- (long)new_event,
- (long)new_event->wallclock,
- (long)new_event->handler,
- (long)new_event->data));
- return new_event;
-}
-#endif
-
-
-#if EXTERN_SIM_EVENTS_P
-sim_event *
-sim_events_watch_sim (SIM_DESC sd,
- void *host_addr,
- int nr_bytes,
- int byte_order,
- int is_within,
- unsigned64 lb,
- unsigned64 ub,
- sim_event_handler *handler,
- void *data)
-{
- sim_events *events = STATE_EVENTS (sd);
- sim_event *new_event = sim_events_zalloc (sd);
- /* type */
- switch (byte_order)
- {
- case 0:
- switch (nr_bytes)
- {
- case 1: new_event->watching = watch_sim_host_1; break;
- case 2: new_event->watching = watch_sim_host_2; break;
- case 4: new_event->watching = watch_sim_host_4; break;
- case 8: new_event->watching = watch_sim_host_8; break;
- default: sim_io_error (sd, "sim_events_watch_sim - invalid nr bytes");
- }
- break;
- case BIG_ENDIAN:
- switch (nr_bytes)
- {
- case 1: new_event->watching = watch_sim_be_1; break;
- case 2: new_event->watching = watch_sim_be_2; break;
- case 4: new_event->watching = watch_sim_be_4; break;
- case 8: new_event->watching = watch_sim_be_8; break;
- default: sim_io_error (sd, "sim_events_watch_sim - invalid nr bytes");
- }
- break;
- case LITTLE_ENDIAN:
- switch (nr_bytes)
- {
- case 1: new_event->watching = watch_sim_le_1; break;
- case 2: new_event->watching = watch_sim_le_2; break;
- case 4: new_event->watching = watch_sim_le_4; break;
- case 8: new_event->watching = watch_sim_le_8; break;
- default: sim_io_error (sd, "sim_events_watch_sim - invalid nr bytes");
- }
- break;
- default:
- sim_io_error (sd, "sim_events_watch_sim - invalid byte order");
- }
- /* handler */
- new_event->data = data;
- new_event->handler = handler;
- /* data */
- new_event->host_addr = host_addr;
- new_event->lb = lb;
- new_event->lb64 = lb;
- new_event->ub = ub;
- new_event->ub64 = ub;
- new_event->is_within = (is_within != 0);
- /* insert */
- new_event->next = events->watchpoints;
- events->watchpoints = new_event;
- events->work_pending = 1;
- ETRACE ((_ETRACE,
- "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
- (long)sim_events_time (sd),
- (long)new_event,
- (long)new_event->host_addr,
- (long)new_event->lb,
- (long)new_event->ub,
- (long)new_event->handler,
- (long)new_event->data));
- return new_event;
-}
-#endif
-
-
-#if EXTERN_SIM_EVENTS_P
-sim_event *
-sim_events_watch_core (SIM_DESC sd,
- address_word core_addr,
- unsigned core_map,
- int nr_bytes,
- int byte_order,
- int is_within,
- unsigned64 lb,
- unsigned64 ub,
- sim_event_handler *handler,
- void *data)
-{
- sim_events *events = STATE_EVENTS (sd);
- sim_event *new_event = sim_events_zalloc (sd);
- /* type */
- switch (byte_order)
- {
- case 0:
- switch (nr_bytes)
- {
- case 1: new_event->watching = watch_core_targ_1; break;
- case 2: new_event->watching = watch_core_targ_2; break;
- case 4: new_event->watching = watch_core_targ_4; break;
- case 8: new_event->watching = watch_core_targ_8; break;
- default: sim_io_error (sd, "sim_events_watch_core - invalid nr bytes");
- }
- break;
- case BIG_ENDIAN:
- switch (nr_bytes)
- {
- case 1: new_event->watching = watch_core_be_1; break;
- case 2: new_event->watching = watch_core_be_2; break;
- case 4: new_event->watching = watch_core_be_4; break;
- case 8: new_event->watching = watch_core_be_8; break;
- default: sim_io_error (sd, "sim_events_watch_core - invalid nr bytes");
- }
- break;
- case LITTLE_ENDIAN:
- switch (nr_bytes)
- {
- case 1: new_event->watching = watch_core_le_1; break;
- case 2: new_event->watching = watch_core_le_2; break;
- case 4: new_event->watching = watch_core_le_4; break;
- case 8: new_event->watching = watch_core_le_8; break;
- default: sim_io_error (sd, "sim_events_watch_core - invalid nr bytes");
- }
- break;
- default:
- sim_io_error (sd, "sim_events_watch_core - invalid byte order");
- }
- /* handler */
- new_event->data = data;
- new_event->handler = handler;
- /* data */
- new_event->core_addr = core_addr;
- new_event->core_map = core_map;
- new_event->lb = lb;
- new_event->lb64 = lb;
- new_event->ub = ub;
- new_event->ub64 = ub;
- new_event->is_within = (is_within != 0);
- /* insert */
- new_event->next = events->watchpoints;
- events->watchpoints = new_event;
- events->work_pending = 1;
- ETRACE ((_ETRACE,
- "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
- (long)sim_events_time (sd),
- (long)new_event,
- (long)new_event->host_addr,
- (long)new_event->lb,
- (long)new_event->ub,
- (long)new_event->handler,
- (long)new_event->data));
- return new_event;
-}
-#endif
-
-
-#if EXTERN_SIM_EVENTS_P
-void
-sim_events_deschedule (SIM_DESC sd,
- sim_event *event_to_remove)
-{
- sim_events *events = STATE_EVENTS (sd);
- sim_event *to_remove = (sim_event*)event_to_remove;
- if (event_to_remove != NULL)
- {
- sim_event **queue = NULL;
- while ((queue = next_event_queue (sd, queue)) != NULL)
- {
- sim_event **ptr_to_current;
- for (ptr_to_current = queue;
- *ptr_to_current != NULL && *ptr_to_current != to_remove;
- ptr_to_current = &(*ptr_to_current)->next);
- if (*ptr_to_current == to_remove)
- {
- sim_event *dead = *ptr_to_current;
- *ptr_to_current = dead->next;
- ETRACE ((_ETRACE,
- "event/watch descheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
- (long) sim_events_time (sd),
- (long) event_to_remove,
- (long) dead->time_of_event,
- (long) dead->handler,
- (long) dead->data,
- (dead->trace != NULL) ? ", " : "",
- (dead->trace != NULL) ? dead->trace : ""));
- sim_events_free (sd, dead);
- update_time_from_event (sd);
- SIM_ASSERT ((events->time_from_event >= 0) == (events->queue != NULL));
- return;
- }
- }
- }
- ETRACE ((_ETRACE,
- "event/watch descheduled at %ld - tag 0x%lx - not found\n",
- (long) sim_events_time (sd),
- (long) event_to_remove));
-}
-#endif
-
-
-STATIC_INLINE_SIM_EVENTS\
-(int)
-sim_watch_valid (SIM_DESC sd,
- sim_event *to_do)
-{
- switch (to_do->watching)
- {
-
-#define WATCH_CORE(N,OP,EXT) \
- int ok; \
- unsigned_##N word = 0; \
- int nr_read = sim_core_read_buffer (sd, NULL, to_do->core_map, &word, \
- to_do->core_addr, sizeof (word)); \
- OP (word); \
- ok = (nr_read == sizeof (unsigned_##N) \
- && (to_do->is_within \
- == (word >= to_do->lb##EXT \
- && word <= to_do->ub##EXT)));
-
- case watch_core_targ_1:
- {
- WATCH_CORE (1, T2H,);
- return ok;
- }
- case watch_core_targ_2:
- {
- WATCH_CORE (2, T2H,);
- return ok;
- }
- case watch_core_targ_4:
- {
- WATCH_CORE (4, T2H,);
- return ok;
- }
- case watch_core_targ_8:
- {
- WATCH_CORE (8, T2H,64);
- return ok;
- }
-
- case watch_core_be_1:
- {
- WATCH_CORE (1, BE2H,);
- return ok;
- }
- case watch_core_be_2:
- {
- WATCH_CORE (2, BE2H,);
- return ok;
- }
- case watch_core_be_4:
- {
- WATCH_CORE (4, BE2H,);
- return ok;
- }
- case watch_core_be_8:
- {
- WATCH_CORE (8, BE2H,64);
- return ok;
- }
-
- case watch_core_le_1:
- {
- WATCH_CORE (1, LE2H,);
- return ok;
- }
- case watch_core_le_2:
- {
- WATCH_CORE (2, LE2H,);
- return ok;
- }
- case watch_core_le_4:
- {
- WATCH_CORE (4, LE2H,);
- return ok;
- }
- case watch_core_le_8:
- {
- WATCH_CORE (8, LE2H,64);
- return ok;
- }
-#undef WATCH_CORE
-
-#define WATCH_SIM(N,OP,EXT) \
- int ok; \
- unsigned_##N word = *(unsigned_##N*)to_do->host_addr; \
- OP (word); \
- ok = (to_do->is_within \
- == (word >= to_do->lb##EXT \
- && word <= to_do->ub##EXT));
-
- case watch_sim_host_1:
- {
- WATCH_SIM (1, word = ,);
- return ok;
- }
- case watch_sim_host_2:
- {
- WATCH_SIM (2, word = ,);
- return ok;
- }
- case watch_sim_host_4:
- {
- WATCH_SIM (4, word = ,);
- return ok;
- }
- case watch_sim_host_8:
- {
- WATCH_SIM (8, word = ,64);
- return ok;
- }
-
- case watch_sim_be_1:
- {
- WATCH_SIM (1, BE2H,);
- return ok;
- }
- case watch_sim_be_2:
- {
- WATCH_SIM (2, BE2H,);
- return ok;
- }
- case watch_sim_be_4:
- {
- WATCH_SIM (4, BE2H,);
- return ok;
- }
- case watch_sim_be_8:
- {
- WATCH_SIM (8, BE2H,64);
- return ok;
- }
-
- case watch_sim_le_1:
- {
- WATCH_SIM (1, LE2H,);
- return ok;
- }
- case watch_sim_le_2:
- {
- WATCH_SIM (1, LE2H,);
- return ok;
- }
- case watch_sim_le_4:
- {
- WATCH_SIM (1, LE2H,);
- return ok;
- }
- case watch_sim_le_8:
- {
- WATCH_SIM (1, LE2H,64);
- return ok;
- }
-#undef WATCH_SIM
-
- case watch_clock: /* wallclock */
- {
- unsigned long elapsed_time = sim_events_elapsed_time (sd);
- return (elapsed_time >= to_do->wallclock);
- }
-
- default:
- sim_io_error (sd, "sim_watch_valid - bad switch");
- break;
-
- }
- return 1;
-}
-
-
-INLINE_SIM_EVENTS\
-(int)
-sim_events_tick (SIM_DESC sd)
-{
- sim_events *events = STATE_EVENTS (sd);
-
- /* this should only be called after the previous ticks have been
- fully processed */
-
- /* Advance the time but *only* if there is nothing to process */
- if (events->work_pending
- || events->time_from_event == 0)
- {
- events->nr_ticks_to_process += 1;
- return 1;
- }
- else
- {
- events->time_from_event -= 1;
- return 0;
- }
-}
-
-
-INLINE_SIM_EVENTS\
-(int)
-sim_events_tickn (SIM_DESC sd,
- int n)
-{
- sim_events *events = STATE_EVENTS (sd);
- SIM_ASSERT (n > 0);
-
- /* this should only be called after the previous ticks have been
- fully processed */
-
- /* Advance the time but *only* if there is nothing to process */
- if (events->work_pending || events->time_from_event < n)
- {
- events->nr_ticks_to_process += n;
- return 1;
- }
- else
- {
- events->time_from_event -= n;
- return 0;
- }
-}
-
-
-INLINE_SIM_EVENTS\
-(void)
-sim_events_slip (SIM_DESC sd,
- int slip)
-{
- sim_events *events = STATE_EVENTS (sd);
- SIM_ASSERT (slip > 0);
-
- /* Flag a ready event with work_pending instead of number of ticks
- to process so that the time continues to be correct */
- if (events->time_from_event < slip)
- {
- events->work_pending = 1;
- }
- events->time_from_event -= slip;
-}
-
-
-INLINE_SIM_EVENTS\
-(void)
-sim_events_preprocess (SIM_DESC sd,
- int events_were_last,
- int events_were_next)
-{
- sim_events *events = STATE_EVENTS(sd);
- if (events_were_last)
- {
- /* Halted part way through event processing */
- ASSERT (events->nr_ticks_to_process != 0);
- /* The external world can't tell if the event that stopped the
- simulator was the last event to process. */
- ASSERT (events_were_next);
- sim_events_process (sd);
- }
- else if (events_were_next)
- {
- /* Halted by the last processor */
- if (sim_events_tick (sd))
- sim_events_process (sd);
- }
-}
-
-
-INLINE_SIM_EVENTS\
-(void)
-sim_events_process (SIM_DESC sd)
-{
- sim_events *events = STATE_EVENTS(sd);
- signed64 event_time = sim_events_time(sd);
-
- /* Clear work_pending before checking nr_held. Clearing
- work_pending after nr_held (with out a lock could loose an
- event). */
- events->work_pending = 0;
-
- /* move any events that were asynchronously queued by any signal
- handlers onto the real event queue. */
- if (events->nr_held > 0)
- {
- int i;
-
-#if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
- /*-LOCK-*/
- sigset_t old_mask;
- sigset_t new_mask;
- sigfillset(&new_mask);
- sigprocmask(SIG_SETMASK, &new_mask, &old_mask);
-#endif
-
- for (i = 0; i < events->nr_held; i++)
- {
- sim_event *entry = &events->held [i];
- sim_events_schedule (sd,
- entry->time_of_event,
- entry->handler,
- entry->data);
- }
- events->nr_held = 0;
-
-#if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
- /*-UNLOCK-*/
- sigprocmask(SIG_SETMASK, &old_mask, NULL);
-#endif
-
- }
-
- /* Process any watchpoints. Be careful to allow a watchpoint to
- appear/disappear under our feet.
- To ensure that watchpoints are processed only once per cycle,
- they are moved onto a watched queue, this returned to the
- watchpoint queue when all queue processing has been
- completed. */
- while (events->watchpoints != NULL)
- {
- sim_event *to_do = events->watchpoints;
- events->watchpoints = to_do->next;
- if (sim_watch_valid (sd, to_do))
- {
- sim_event_handler *handler = to_do->handler;
- void *data = to_do->data;
- ETRACE((_ETRACE,
- "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
- (long) event_time,
- (long) to_do,
- (long) handler,
- (long) data,
- (to_do->trace != NULL) ? ", " : "",
- (to_do->trace != NULL) ? to_do->trace : ""));
- sim_events_free (sd, to_do);
- handler (sd, data);
- }
- else
- {
- to_do->next = events->watchedpoints;
- events->watchedpoints = to_do;
- }
- }
-
- /* consume all events for this or earlier times. Be careful to
- allow an event to appear/disappear under our feet */
- while (events->queue->time_of_event <
- (event_time + events->nr_ticks_to_process))
- {
- sim_event *to_do = events->queue;
- sim_event_handler *handler = to_do->handler;
- void *data = to_do->data;
- events->queue = to_do->next;
- update_time_from_event (sd);
- ETRACE((_ETRACE,
- "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
- (long) event_time,
- (long) to_do,
- (long) handler,
- (long) data,
- (to_do->trace != NULL) ? ", " : "",
- (to_do->trace != NULL) ? to_do->trace : ""));
- sim_events_free (sd, to_do);
- handler (sd, data);
- }
-
- /* put things back where they belong ready for the next iteration */
- events->watchpoints = events->watchedpoints;
- events->watchedpoints = NULL;
- if (events->watchpoints != NULL)
- events->work_pending = 1;
-
- /* advance the time */
- SIM_ASSERT (events->time_from_event >= events->nr_ticks_to_process);
- SIM_ASSERT (events->queue != NULL); /* always poll event */
- events->time_from_event -= events->nr_ticks_to_process;
-
- /* this round of processing complete */
- events->nr_ticks_to_process = 0;
-}
-
-#endif