diff options
author | Andrew Cagney <cagney@redhat.com> | 1997-05-19 03:42:33 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 1997-05-19 03:42:33 +0000 |
commit | f03b093cd34bc352ad89334a43a34b00a5e5c60c (patch) | |
tree | b9d428d2bdf6dd5f5f5a25a7df7580c3836af9e4 /sim/common/sim-events.h | |
parent | 11ab132f168d3c24d4b4d743d86599973b17e3f2 (diff) | |
download | fsf-binutils-gdb-f03b093cd34bc352ad89334a43a34b00a5e5c60c.zip fsf-binutils-gdb-f03b093cd34bc352ad89334a43a34b00a5e5c60c.tar.gz fsf-binutils-gdb-f03b093cd34bc352ad89334a43a34b00a5e5c60c.tar.bz2 |
o Implement generic halt/restart/abort module.
Use in tic80 and d30v simulators.
o Add signal hook to sim-core module
Diffstat (limited to 'sim/common/sim-events.h')
-rw-r--r-- | sim/common/sim-events.h | 162 |
1 files changed, 98 insertions, 64 deletions
diff --git a/sim/common/sim-events.h b/sim/common/sim-events.h index 05b28b5..8c41927 100644 --- a/sim/common/sim-events.h +++ b/sim/common/sim-events.h @@ -38,49 +38,84 @@ illustrated above, the event queue should be processed before the first instruction. That instruction being executed during tick 1. - The event queue is processed using: + The simulator main loop may take a form similar to: - if (sim_events_tick (sd)) { - sim_events_process (sd); - } + if (halt-/restart-setjmp) + { - */ - + .... // Determine who should go next + last-cpu-nr = get-last-cpu-nr (sd); + next-cpu-nr = get-next-cpu-nr (sd); + events-were-last? = (last-cpu-nr >= nr-cpus); + events-were-next? = (next-cpu-nr >= nr-cpus); -typedef void sim_event_handler(void *data); + .... // process any outstanding events + sim_events_preprocess (sd, events-were-last?, events-were-next?); + if (events-were-next) + next-cpu-nr = 0; + + .... // prime main loop + + while (1) + { + .... // model one insn of next-cpu-nr .. nr-cpus + if (sim_events_tick (sd)) + sim_events_process (sd); + next-cpu-nr = 0 + } + } + + NB. In the above pseudo code it is assumed that any cpu-nr >= + nr-cpus is a marker for the event queue. */ + + +typedef void sim_event_handler(SIM_DESC sd, void *data); typedef struct _sim_event sim_event; -struct _sim_event { - void *data; - sim_event_handler *handler; - signed64 time_of_event; - sim_event *next; -}; typedef struct _sim_events sim_events; struct _sim_events { int processing; sim_event *queue; + sim_event *watchpoints; + sim_event *watchedpoints; + /* flag additional work needed */ + volatile int work_pending; + /* the asynchronous event queue */ sim_event *volatile held; sim_event *volatile *volatile held_end; + /* timekeeping */ + SIM_ELAPSED_TIME initial_wallclock; signed64 time_of_event; int time_from_event; - void *path_to_halt_or_restart; int trace; }; +/* Install the "events" module. */ + +EXTERN_SIM_EVENTS\ +(SIM_RC) sim_events_install (SIM_DESC sd); + + +/* Uninstall the "events" subsystem. */ + +EXTERN_SIM_EVENTS\ +(void) +sim_events_uninstall (SIM_DESC sd); + + + /* Initialization */ -INLINE_SIM_EVENTS\ -(void) sim_events_init -(SIM_DESC sd); +EXTERN_SIM_EVENTS\ +(SIM_RC) sim_events_init (SIM_DESC sd); /* Set Tracing Level */ -INLINE_SIM_EVENTS\ +EXTERN_SIM_EVENTS\ (void) sim_events_set_trace (SIM_DESC sd, int level); @@ -88,14 +123,14 @@ INLINE_SIM_EVENTS\ /* Schedule an event DELTA_TIME ticks into the future */ -INLINE_SIM_EVENTS\ +EXTERN_SIM_EVENTS\ (sim_event *) sim_events_schedule (SIM_DESC sd, signed64 delta_time, sim_event_handler *handler, void *data); -INLINE_SIM_EVENTS\ +EXTERN_SIM_EVENTS\ (sim_event *) sim_events_schedule_after_signal (SIM_DESC sd, signed64 delta_time, @@ -107,79 +142,77 @@ INLINE_SIM_EVENTS\ simulation. The exact interpretation of wallclock is host dependant. */ -INLINE_SIM_EVENTS\ -(void) sim_events_wallclock_schedule +EXTERN_SIM_EVENTS\ +(sim_event *) sim_events_watch_clock (SIM_DESC sd, - signed64 wallclock_ms_time, + unsigned wallclock_ms_time, sim_event_handler *handler, void *data); -#if 0 -/* Schedule an event when the value at ADDR lies between LB..UB */ - -typedef enum { - /* value host byte ordered */ - watch_host_1, - watch_host_2, - watch_host_4, - watch_host_8, - /* value target byte ordered */ - watch_targ_1, - watch_targ_2, - watch_targ_4, - watch_targ_8, - /* value big-endian */ - watch_bend_1, - watch_bend_2, - watch_bend_4, - watch_bend_8, - /* value little-endian */ - watch_lend_1, - watch_lend_2, - watch_lend_4, - watch_lend_8, -} sim_watchpoint; +/* Schedule an event when the NR_BYTES value at HOST_ADDR with + BYTE_ORDER lies within LB..UB (unsigned). -INLINE_SIM_EVENTS\ -(void) sim_events_watchpoint_schedule + HOST_ADDR: pointer into the host address space. + BYTE_ORDER: 0 - host endian; BIG_ENDIAN; LITTLE_ENDIAN */ + +EXTERN_SIM_EVENTS\ +(sim_event*) sim_events_watch_sim (SIM_DESC sd, - sim_watchpoint type, - void *addr, + void *host_addr, + int nr_bytes, + int byte_order, unsigned64 lb, unsigned64 ub, sim_event_handler *handler, void *data); -#endif -#if 0 -/* Schedule an event when the value in CORE lies between LB..UB */ +/* Schedule an event when the NR_BYTES value at CORE_ADDR with BYTE_ORDER + lies between LB..UB. -INLINE_SIM_EVENTS\ -(void) sim_events_watchcore_schedule + CORE_ADDR/MAP: pointer into the target address space. + BYTE_ORDER: 0 - current target endian; BIG_ENDIAN; LITTLE_ENDIAN */ + +EXTERN_SIM_EVENTS\ +(sim_event*) sim_events_watch_core (SIM_DESC sd, - sim_watchpoint type, - address_word addr, - sim_core_maps map, + address_word core_addr, + sim_core_maps core_map, + int nr_bytes, + int byte_order, unsigned64 lb, unsigned64 ub, sim_event_handler *handler, void *data); -#endif /* Deschedule the specified event */ -INLINE_SIM_EVENTS\ +EXTERN_SIM_EVENTS\ (void) sim_events_deschedule (SIM_DESC sd, sim_event *event_to_remove); +/* Prepare for main simulator loop. Ensure that the next thing to do + is not event processing. + + If the simulator halted part way through event processing then both + EVENTS_WERE_LAST and EVENTS_WERE_FIRST shall be true. + + If the simulator halted after processing the last cpu, then only + EVENTS_WERE_NEXT shall be true. */ + +INLINE_SIM_EVENTS\ +(void) sim_events_preprocess +(SIM_DESC sd, + int events_were_last, + int events_were_next); -/* progress time. Broken into two parts so that if something is - pending, the caller has a chance to save any cached state */ + +/* Progress time - separated into two parts so that the main loop can + save its context before the event queue is processed */ INLINE_SIM_EVENTS\ (int) sim_events_tick @@ -190,6 +223,7 @@ INLINE_SIM_EVENTS\ (SIM_DESC sd); + /* local concept of time */ INLINE_SIM_EVENTS\ |