1 /* The common simulator framework for GDB, the GNU Debugger.
3 Copyright 2002-2023 Free Software Foundation, Inc.
5 Contributed by Andrew Cagney and Red Hat.
7 This file is part of GDB.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
23 #ifndef _SIM_EVENTS_C_
24 #define _SIM_EVENTS_C_
26 /* This must come before any other includes. */
29 #include <signal.h> /* For SIGPROCMASK et al. */
34 #include "libiberty.h"
37 #include "sim-assert.h"
43 /* core - target byte order */
48 /* core - big-endian */
53 /* core - little-endian */
59 /* sim - host byte order */
64 /* sim - big-endian */
69 /* sim - little-endian */
83 } sim_event_watchpoints
;
87 sim_event_watchpoints watching
;
89 sim_event_handler
*handler
;
91 int64_t time_of_event
;
92 /* watch wallclock event */
94 /* watch core address */
95 address_word core_addr
;
99 /* watch core/sim range */
100 int is_within
; /* 0/1 */
105 /* trace info (if any) */
112 /* The event queue maintains a single absolute time using two
115 TIME_OF_EVENT: this holds the time at which the next event is ment
116 to occur. If no next event it will hold the time of the last
119 TIME_FROM_EVENT: The current distance from TIME_OF_EVENT. A value
120 <= 0 (except when poll-event is being processed) indicates that
121 event processing is due. This variable is decremented once for
122 each iteration of a clock cycle.
124 Initially, the clock is started at time one (0) with TIME_OF_EVENT
125 == 0 and TIME_FROM_EVENT == 0 and with NR_TICKS_TO_PROCESS == 1.
127 Clearly there is a bug in that this code assumes that the absolute
128 time counter will never become greater than 2^62.
130 To avoid the need to use 64bit arithmetic, the event queue always
131 contains at least one event scheduled every 16 000 ticks. This
132 limits the time from event counter to values less than
136 #if !defined (SIM_EVENTS_POLL_RATE)
137 #define SIM_EVENTS_POLL_RATE 0x1000
141 #define _ETRACE sd, NULL
144 #define ETRACE(ARGS) \
147 if (STRACE_EVENTS_P (sd)) \
149 if (STRACE_DEBUG_P (sd)) \
150 trace_printf (sd, NULL, "%s:%d: ", lbasename (__FILE__), __LINE__); \
157 /* event queue iterator - don't iterate over the held queue. */
159 #if EXTERN_SIM_EVENTS_P
161 next_event_queue (SIM_DESC sd
,
165 return &STATE_EVENTS (sd
)->queue
;
166 else if (queue
== &STATE_EVENTS (sd
)->queue
)
167 return &STATE_EVENTS (sd
)->watchpoints
;
168 else if (queue
== &STATE_EVENTS (sd
)->watchpoints
)
169 return &STATE_EVENTS (sd
)->watchedpoints
;
170 else if (queue
== &STATE_EVENTS (sd
)->watchedpoints
)
173 sim_io_error (sd
, "next_event_queue - bad queue");
179 STATIC_INLINE_SIM_EVENTS\
181 sim_events_poll (SIM_DESC sd
,
184 /* just re-schedule in 1000 million ticks time */
185 sim_events_schedule (sd
, SIM_EVENTS_POLL_RATE
, sim_events_poll
, sd
);
186 sim_io_poll_quit (sd
);
190 /* "events" module install handler.
191 This is called via sim_module_install to install the "events" subsystem
192 into the simulator. */
194 #if EXTERN_SIM_EVENTS_P
195 STATIC_SIM_EVENTS (MODULE_UNINSTALL_FN
) sim_events_uninstall
;
196 STATIC_SIM_EVENTS (MODULE_INIT_FN
) sim_events_init
;
197 STATIC_SIM_EVENTS (MODULE_RESUME_FN
) sim_events_resume
;
198 STATIC_SIM_EVENTS (MODULE_SUSPEND_FN
) sim_events_suspend
;
201 #if EXTERN_SIM_EVENTS_P
203 sim_events_install (SIM_DESC sd
)
205 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
206 sim_module_add_uninstall_fn (sd
, sim_events_uninstall
);
207 sim_module_add_init_fn (sd
, sim_events_init
);
208 sim_module_add_resume_fn (sd
, sim_events_resume
);
209 sim_module_add_suspend_fn (sd
, sim_events_suspend
);
215 /* Suspend/resume the event queue manager when the simulator is not
218 #if EXTERN_SIM_EVENTS_P
220 sim_events_resume (SIM_DESC sd
)
222 sim_events
*events
= STATE_EVENTS (sd
);
223 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
224 SIM_ASSERT (events
->resume_wallclock
== 0);
225 events
->resume_wallclock
= sim_elapsed_time_get ();
230 #if EXTERN_SIM_EVENTS_P
232 sim_events_suspend (SIM_DESC sd
)
234 sim_events
*events
= STATE_EVENTS (sd
);
235 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
236 SIM_ASSERT (events
->resume_wallclock
!= 0);
237 events
->elapsed_wallclock
+= sim_elapsed_time_since (events
->resume_wallclock
);
238 events
->resume_wallclock
= 0;
244 /* Uninstall the "events" subsystem from the simulator. */
246 #if EXTERN_SIM_EVENTS_P
248 sim_events_uninstall (SIM_DESC sd
)
250 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
251 /* FIXME: free buffers, etc. */
258 #if EXTERN_SIM_EVENTS_P
260 sim_events_zalloc (SIM_DESC sd
)
262 sim_events
*events
= STATE_EVENTS (sd
);
263 sim_event
*new = events
->free_list
;
266 events
->free_list
= new->next
;
267 memset (new, 0, sizeof (*new));
271 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
275 sigfillset (&new_mask
);
276 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
278 new = ZALLOC (sim_event
);
279 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
281 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
288 STATIC_INLINE_SIM_EVENTS\
290 sim_events_free (SIM_DESC sd
,
293 sim_events
*events
= STATE_EVENTS (sd
);
294 dead
->next
= events
->free_list
;
295 events
->free_list
= dead
;
296 if (dead
->trace
!= NULL
)
298 free (dead
->trace
); /* NB: asprintf returns a `free' buf */
304 /* Initialize the simulator event manager */
306 #if EXTERN_SIM_EVENTS_P
308 sim_events_init (SIM_DESC sd
)
310 sim_events
*events
= STATE_EVENTS (sd
);
312 /* drain the interrupt queue */
314 if (events
->held
== NULL
)
315 events
->held
= NZALLOC (sim_event
, MAX_NR_SIGNAL_SIM_EVENTS
);
317 /* drain the normal queues */
319 sim_event
**queue
= NULL
;
320 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
322 if (queue
== NULL
) break;
323 while (*queue
!= NULL
)
325 sim_event
*dead
= *queue
;
327 sim_events_free (sd
, dead
);
333 /* wind time back to zero */
334 events
->nr_ticks_to_process
= 1; /* start by doing queue */
335 events
->time_of_event
= 0;
336 events
->time_from_event
= 0;
337 events
->elapsed_wallclock
= 0;
338 events
->resume_wallclock
= 0;
340 /* schedule our initial counter event */
341 sim_events_schedule (sd
, 0, sim_events_poll
, sd
);
343 /* from now on, except when the large-int event is being processed
344 the event queue is non empty */
345 SIM_ASSERT (events
->queue
!= NULL
);
354 sim_events_time (SIM_DESC sd
)
356 sim_events
*events
= STATE_EVENTS (sd
);
357 return (events
->time_of_event
- events
->time_from_event
);
363 sim_events_elapsed_time (SIM_DESC sd
)
365 unsigned long elapsed
= STATE_EVENTS (sd
)->elapsed_wallclock
;
367 /* Are we being called inside sim_resume?
368 (Is there a simulation in progress?) */
369 if (STATE_EVENTS (sd
)->resume_wallclock
!= 0)
370 elapsed
+= sim_elapsed_time_since (STATE_EVENTS (sd
)->resume_wallclock
);
376 /* Returns the time that remains before the event is raised. */
379 sim_events_remain_time (SIM_DESC sd
, sim_event
*event
)
384 return (event
->time_of_event
- sim_events_time (sd
));
389 STATIC_INLINE_SIM_EVENTS\
391 update_time_from_event (SIM_DESC sd
)
393 sim_events
*events
= STATE_EVENTS (sd
);
394 int64_t current_time
= sim_events_time (sd
);
395 if (events
->queue
!= NULL
)
397 events
->time_of_event
= events
->queue
->time_of_event
;
398 events
->time_from_event
= (events
->queue
->time_of_event
- current_time
);
402 events
->time_of_event
= current_time
- 1;
403 events
->time_from_event
= -1;
405 if (STRACE_EVENTS_P (sd
))
409 for (event
= events
->queue
, i
= 0;
411 event
= event
->next
, i
++)
414 "event time-from-event - "
415 "time %" PRIi64
", delta %" PRIi64
" - "
416 "event %i, tag %p, time %" PRIi64
", handler %p, data "
419 events
->time_from_event
,
422 event
->time_of_event
,
425 (event
->trace
!= NULL
) ? ", " : "",
426 (event
->trace
!= NULL
) ? event
->trace
: ""));
429 SIM_ASSERT (current_time
== sim_events_time (sd
));
433 #if EXTERN_SIM_EVENTS_P
435 insert_sim_event (SIM_DESC sd
,
436 sim_event
*new_event
,
439 sim_events
*events
= STATE_EVENTS (sd
);
442 int64_t time_of_event
;
445 sim_io_error (sd
, "what is past is past!\n");
447 /* compute when the event should occur */
448 time_of_event
= sim_events_time (sd
) + delta
;
450 /* find the queue insertion point - things are time ordered */
451 prev
= &events
->queue
;
452 curr
= events
->queue
;
453 while (curr
!= NULL
&& time_of_event
>= curr
->time_of_event
)
455 SIM_ASSERT (curr
->next
== NULL
456 || curr
->time_of_event
<= curr
->next
->time_of_event
);
460 SIM_ASSERT (curr
== NULL
|| time_of_event
< curr
->time_of_event
);
463 new_event
->next
= curr
;
465 new_event
->time_of_event
= time_of_event
;
467 /* adjust the time until the first event */
468 update_time_from_event (sd
);
473 #if EXTERN_SIM_EVENTS_P
475 sim_events_schedule (SIM_DESC sd
,
477 sim_event_handler
*handler
,
480 return sim_events_schedule_tracef (sd
, delta_time
, handler
, data
, NULL
);
485 #if EXTERN_SIM_EVENTS_P
487 sim_events_schedule_tracef (SIM_DESC sd
,
489 sim_event_handler
*handler
,
494 sim_event
*new_event
;
497 new_event
= sim_events_schedule_vtracef (sd
, delta_time
, handler
, data
, fmt
, ap
);
504 #if EXTERN_SIM_EVENTS_P
506 sim_events_schedule_vtracef (SIM_DESC sd
,
508 sim_event_handler
*handler
,
513 sim_event
*new_event
= sim_events_zalloc (sd
);
514 new_event
->data
= data
;
515 new_event
->handler
= handler
;
516 new_event
->watching
= watch_timer
;
517 if (fmt
== NULL
|| !STRACE_EVENTS_P (sd
) || vasprintf (&new_event
->trace
, fmt
, ap
) < 0)
518 new_event
->trace
= NULL
;
519 insert_sim_event (sd
, new_event
, delta_time
);
521 "event scheduled at %" PRIi64
" - "
522 "tag %p - time %" PRIi64
", handler %p, data %p%s%s\n",
523 sim_events_time (sd
),
525 new_event
->time_of_event
,
528 (new_event
->trace
!= NULL
) ? ", " : "",
529 (new_event
->trace
!= NULL
) ? new_event
->trace
: ""));
535 #if EXTERN_SIM_EVENTS_P
537 sim_events_schedule_after_signal (SIM_DESC sd
,
539 sim_event_handler
*handler
,
542 sim_events
*events
= STATE_EVENTS (sd
);
543 sim_event
*new_event
;
544 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
548 sigfillset (&new_mask
);
549 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
552 /* allocate an event entry from the signal buffer */
553 new_event
= &events
->held
[events
->nr_held
];
555 if (events
->nr_held
> MAX_NR_SIGNAL_SIM_EVENTS
)
557 sim_engine_abort (NULL
, NULL
, NULL_CIA
,
558 "sim_events_schedule_after_signal - buffer overflow");
561 new_event
->data
= data
;
562 new_event
->handler
= handler
;
563 new_event
->time_of_event
= delta_time
; /* work it out later */
564 new_event
->next
= NULL
;
566 events
->work_pending
= 1; /* notify main process */
568 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
570 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
574 "signal scheduled at %" PRIi64
" - "
575 "tag %p - time %" PRIi64
", handler %p, data %p\n",
576 sim_events_time (sd
),
578 new_event
->time_of_event
,
585 #if EXTERN_SIM_EVENTS_P
587 sim_events_watch_clock (SIM_DESC sd
,
588 unsigned delta_ms_time
,
589 sim_event_handler
*handler
,
592 sim_events
*events
= STATE_EVENTS (sd
);
593 sim_event
*new_event
= sim_events_zalloc (sd
);
595 new_event
->watching
= watch_clock
;
597 new_event
->data
= data
;
598 new_event
->handler
= handler
;
600 if (events
->resume_wallclock
== 0)
601 new_event
->wallclock
= (events
->elapsed_wallclock
+ delta_ms_time
);
603 new_event
->wallclock
= (events
->elapsed_wallclock
604 + sim_elapsed_time_since (events
->resume_wallclock
)
607 new_event
->next
= events
->watchpoints
;
608 events
->watchpoints
= new_event
;
609 events
->work_pending
= 1;
611 "event watching clock at %" PRIi64
" - "
612 "tag %p - wallclock %u, handler %p, data %p\n",
613 sim_events_time (sd
),
615 new_event
->wallclock
,
623 #if EXTERN_SIM_EVENTS_P
625 sim_events_watch_pc (SIM_DESC sd
,
629 sim_event_handler
*handler
,
632 sim_events
*events
= STATE_EVENTS (sd
);
633 sim_event
*new_event
= sim_events_zalloc (sd
);
635 new_event
->watching
= watch_pc
;
637 new_event
->data
= data
;
638 new_event
->handler
= handler
;
641 new_event
->lb64
= lb
;
643 new_event
->ub64
= ub
;
644 new_event
->is_within
= (is_within
!= 0);
646 new_event
->next
= events
->watchpoints
;
647 events
->watchpoints
= new_event
;
648 events
->work_pending
= 1;
650 "event watching pc at %" PRIi64
" - "
651 "tag %p - pc 0x%x..0x%x, handler %p, data %p\n",
652 sim_events_time (sd
),
663 #if EXTERN_SIM_EVENTS_P
665 sim_events_watch_sim (SIM_DESC sd
,
668 enum bfd_endian byte_order
,
672 sim_event_handler
*handler
,
675 sim_events
*events
= STATE_EVENTS (sd
);
676 sim_event
*new_event
= sim_events_zalloc (sd
);
680 case BFD_ENDIAN_UNKNOWN
:
683 case 1: new_event
->watching
= watch_sim_host_1
; break;
684 case 2: new_event
->watching
= watch_sim_host_2
; break;
685 case 4: new_event
->watching
= watch_sim_host_4
; break;
686 case 8: new_event
->watching
= watch_sim_host_8
; break;
687 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
693 case 1: new_event
->watching
= watch_sim_be_1
; break;
694 case 2: new_event
->watching
= watch_sim_be_2
; break;
695 case 4: new_event
->watching
= watch_sim_be_4
; break;
696 case 8: new_event
->watching
= watch_sim_be_8
; break;
697 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
700 case BFD_ENDIAN_LITTLE
:
703 case 1: new_event
->watching
= watch_sim_le_1
; break;
704 case 2: new_event
->watching
= watch_sim_le_2
; break;
705 case 4: new_event
->watching
= watch_sim_le_4
; break;
706 case 8: new_event
->watching
= watch_sim_le_8
; break;
707 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
711 sim_io_error (sd
, "sim_events_watch_sim - invalid byte order");
714 new_event
->data
= data
;
715 new_event
->handler
= handler
;
717 new_event
->host_addr
= host_addr
;
719 new_event
->lb64
= lb
;
721 new_event
->ub64
= ub
;
722 new_event
->is_within
= (is_within
!= 0);
724 new_event
->next
= events
->watchpoints
;
725 events
->watchpoints
= new_event
;
726 events
->work_pending
= 1;
728 "event watching host at %" PRIi64
" - "
729 "tag %p - host-addr %p, 0x%x..0x%x, handler %p, data %p\n",
730 sim_events_time (sd
),
732 new_event
->host_addr
,
742 #if EXTERN_SIM_EVENTS_P
744 sim_events_watch_core (SIM_DESC sd
,
745 address_word core_addr
,
748 enum bfd_endian byte_order
,
752 sim_event_handler
*handler
,
755 sim_events
*events
= STATE_EVENTS (sd
);
756 sim_event
*new_event
= sim_events_zalloc (sd
);
760 case BFD_ENDIAN_UNKNOWN
:
763 case 1: new_event
->watching
= watch_core_targ_1
; break;
764 case 2: new_event
->watching
= watch_core_targ_2
; break;
765 case 4: new_event
->watching
= watch_core_targ_4
; break;
766 case 8: new_event
->watching
= watch_core_targ_8
; break;
767 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
773 case 1: new_event
->watching
= watch_core_be_1
; break;
774 case 2: new_event
->watching
= watch_core_be_2
; break;
775 case 4: new_event
->watching
= watch_core_be_4
; break;
776 case 8: new_event
->watching
= watch_core_be_8
; break;
777 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
780 case BFD_ENDIAN_LITTLE
:
783 case 1: new_event
->watching
= watch_core_le_1
; break;
784 case 2: new_event
->watching
= watch_core_le_2
; break;
785 case 4: new_event
->watching
= watch_core_le_4
; break;
786 case 8: new_event
->watching
= watch_core_le_8
; break;
787 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
791 sim_io_error (sd
, "sim_events_watch_core - invalid byte order");
794 new_event
->data
= data
;
795 new_event
->handler
= handler
;
797 new_event
->core_addr
= core_addr
;
798 new_event
->core_map
= core_map
;
800 new_event
->lb64
= lb
;
802 new_event
->ub64
= ub
;
803 new_event
->is_within
= (is_within
!= 0);
805 new_event
->next
= events
->watchpoints
;
806 events
->watchpoints
= new_event
;
807 events
->work_pending
= 1;
809 "event watching host at %" PRIi64
" - "
810 "tag %p - host-addr %p, 0x%x..0x%x, handler %p, data %p\n",
811 sim_events_time (sd
),
813 new_event
->host_addr
,
823 #if EXTERN_SIM_EVENTS_P
825 sim_events_deschedule (SIM_DESC sd
,
826 sim_event
*event_to_remove
)
828 sim_events
*events
= STATE_EVENTS (sd
);
829 sim_event
*to_remove
= (sim_event
*)event_to_remove
;
830 if (event_to_remove
!= NULL
)
832 sim_event
**queue
= NULL
;
833 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
835 sim_event
**ptr_to_current
;
836 for (ptr_to_current
= queue
;
837 *ptr_to_current
!= NULL
&& *ptr_to_current
!= to_remove
;
838 ptr_to_current
= &(*ptr_to_current
)->next
);
839 if (*ptr_to_current
== to_remove
)
841 sim_event
*dead
= *ptr_to_current
;
842 *ptr_to_current
= dead
->next
;
844 "event/watch descheduled at %" PRIi64
" - "
845 "tag %p - time %" PRIi64
", handler %p, data %p%s%s\n",
846 sim_events_time (sd
),
851 (dead
->trace
!= NULL
) ? ", " : "",
852 (dead
->trace
!= NULL
) ? dead
->trace
: ""));
853 sim_events_free (sd
, dead
);
854 update_time_from_event (sd
);
855 SIM_ASSERT ((events
->time_from_event
>= 0) == (events
->queue
!= NULL
));
861 "event/watch descheduled at %" PRIi64
" - tag %p - not found\n",
862 sim_events_time (sd
),
868 STATIC_INLINE_SIM_EVENTS\
870 sim_watch_valid (SIM_DESC sd
,
873 switch (to_do
->watching
)
876 #define WATCH_CORE(N,OP,EXT) \
878 unsigned_##N word = 0; \
879 int nr_read = sim_core_read_buffer (sd, NULL, to_do->core_map, &word, \
880 to_do->core_addr, sizeof (word)); \
882 ok = (nr_read == sizeof (unsigned_##N) \
883 && (to_do->is_within \
884 == (word >= to_do->lb##EXT \
885 && word <= to_do->ub##EXT)));
887 case watch_core_targ_1
:
889 WATCH_CORE (1, T2H
,);
892 case watch_core_targ_2
:
894 WATCH_CORE (2, T2H
,);
897 case watch_core_targ_4
:
899 WATCH_CORE (4, T2H
,);
902 case watch_core_targ_8
:
904 WATCH_CORE (8, T2H
,64);
908 case watch_core_be_1
:
910 WATCH_CORE (1, BE2H
,);
913 case watch_core_be_2
:
915 WATCH_CORE (2, BE2H
,);
918 case watch_core_be_4
:
920 WATCH_CORE (4, BE2H
,);
923 case watch_core_be_8
:
925 WATCH_CORE (8, BE2H
,64);
929 case watch_core_le_1
:
931 WATCH_CORE (1, LE2H
,);
934 case watch_core_le_2
:
936 WATCH_CORE (2, LE2H
,);
939 case watch_core_le_4
:
941 WATCH_CORE (4, LE2H
,);
944 case watch_core_le_8
:
946 WATCH_CORE (8, LE2H
,64);
951 #define WATCH_SIM(N,OP,EXT) \
953 unsigned_##N word = *(unsigned_##N*)to_do->host_addr; \
955 ok = (to_do->is_within \
956 == (word >= to_do->lb##EXT \
957 && word <= to_do->ub##EXT));
959 case watch_sim_host_1
:
961 WATCH_SIM (1, word
= ,);
964 case watch_sim_host_2
:
966 WATCH_SIM (2, word
= ,);
969 case watch_sim_host_4
:
971 WATCH_SIM (4, word
= ,);
974 case watch_sim_host_8
:
976 WATCH_SIM (8, word
= ,64);
982 WATCH_SIM (1, BE2H
,);
987 WATCH_SIM (2, BE2H
,);
992 WATCH_SIM (4, BE2H
,);
997 WATCH_SIM (8, BE2H
,64);
1001 case watch_sim_le_1
:
1003 WATCH_SIM (1, LE2H
,);
1006 case watch_sim_le_2
:
1008 WATCH_SIM (1, LE2H
,);
1011 case watch_sim_le_4
:
1013 WATCH_SIM (1, LE2H
,);
1016 case watch_sim_le_8
:
1018 WATCH_SIM (1, LE2H
,64);
1027 for (c
= 0; c
< MAX_NR_PROCESSORS
; ++c
)
1029 sim_cpu
*cpu
= STATE_CPU (sd
, c
);
1030 sim_cia cia
= sim_pc_get (cpu
);
1032 if (to_do
->is_within
== (cia
>= to_do
->lb64
&& cia
<= to_do
->ub64
))
1038 case watch_clock
: /* wallclock */
1040 unsigned long elapsed_time
= sim_events_elapsed_time (sd
);
1041 return (elapsed_time
>= to_do
->wallclock
);
1045 sim_io_error (sd
, "sim_watch_valid - bad switch");
1055 sim_events_tick (SIM_DESC sd
)
1057 sim_events
*events
= STATE_EVENTS (sd
);
1059 /* this should only be called after the previous ticks have been
1062 /* Advance the time but *only* if there is nothing to process */
1063 if (events
->work_pending
1064 || events
->time_from_event
== 0)
1066 events
->nr_ticks_to_process
+= 1;
1071 events
->time_from_event
-= 1;
1079 sim_events_tickn (SIM_DESC sd
,
1082 sim_events
*events
= STATE_EVENTS (sd
);
1085 /* this should only be called after the previous ticks have been
1088 /* Advance the time but *only* if there is nothing to process */
1089 if (events
->work_pending
|| events
->time_from_event
< n
)
1091 events
->nr_ticks_to_process
+= n
;
1096 events
->time_from_event
-= n
;
1104 sim_events_slip (SIM_DESC sd
,
1107 sim_events
*events
= STATE_EVENTS (sd
);
1108 SIM_ASSERT (slip
> 0);
1110 /* Flag a ready event with work_pending instead of number of ticks
1111 to process so that the time continues to be correct */
1112 if (events
->time_from_event
< slip
)
1114 events
->work_pending
= 1;
1116 events
->time_from_event
-= slip
;
1122 sim_events_preprocess (SIM_DESC sd
,
1123 int events_were_last
,
1124 int events_were_next
)
1126 sim_events
*events
= STATE_EVENTS (sd
);
1127 if (events_were_last
)
1129 /* Halted part way through event processing */
1130 ASSERT (events
->nr_ticks_to_process
!= 0);
1131 /* The external world can't tell if the event that stopped the
1132 simulator was the last event to process. */
1133 ASSERT (events_were_next
);
1134 sim_events_process (sd
);
1136 else if (events_were_next
)
1138 /* Halted by the last processor */
1139 if (sim_events_tick (sd
))
1140 sim_events_process (sd
);
1147 sim_events_process (SIM_DESC sd
)
1149 sim_events
*events
= STATE_EVENTS (sd
);
1150 int64_t event_time
= sim_events_time (sd
);
1152 /* Clear work_pending before checking nr_held. Clearing
1153 work_pending after nr_held (with out a lock could loose an
1155 events
->work_pending
= 0;
1157 /* move any events that were asynchronously queued by any signal
1158 handlers onto the real event queue. */
1159 if (events
->nr_held
> 0)
1163 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1167 sigfillset (&new_mask
);
1168 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
1171 for (i
= 0; i
< events
->nr_held
; i
++)
1173 sim_event
*entry
= &events
->held
[i
];
1174 sim_events_schedule (sd
,
1175 entry
->time_of_event
,
1179 events
->nr_held
= 0;
1181 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1183 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
1188 /* Process any watchpoints. Be careful to allow a watchpoint to
1189 appear/disappear under our feet.
1190 To ensure that watchpoints are processed only once per cycle,
1191 they are moved onto a watched queue, this returned to the
1192 watchpoint queue when all queue processing has been
1194 while (events
->watchpoints
!= NULL
)
1196 sim_event
*to_do
= events
->watchpoints
;
1197 events
->watchpoints
= to_do
->next
;
1198 if (sim_watch_valid (sd
, to_do
))
1200 sim_event_handler
*handler
= to_do
->handler
;
1201 void *data
= to_do
->data
;
1203 "event issued at %" PRIi64
" - "
1204 "tag %p - handler %p, data %p%s%s\n",
1209 (to_do
->trace
!= NULL
) ? ", " : "",
1210 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1211 sim_events_free (sd
, to_do
);
1216 to_do
->next
= events
->watchedpoints
;
1217 events
->watchedpoints
= to_do
;
1221 /* consume all events for this or earlier times. Be careful to
1222 allow an event to appear/disappear under our feet */
1223 while (events
->queue
->time_of_event
<
1224 (event_time
+ events
->nr_ticks_to_process
))
1226 sim_event
*to_do
= events
->queue
;
1227 sim_event_handler
*handler
= to_do
->handler
;
1228 void *data
= to_do
->data
;
1229 events
->queue
= to_do
->next
;
1230 update_time_from_event (sd
);
1232 "event issued at %" PRIi64
" - tag %p - handler %p, data %p%s%s\n",
1237 (to_do
->trace
!= NULL
) ? ", " : "",
1238 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1239 sim_events_free (sd
, to_do
);
1243 /* put things back where they belong ready for the next iteration */
1244 events
->watchpoints
= events
->watchedpoints
;
1245 events
->watchedpoints
= NULL
;
1246 if (events
->watchpoints
!= NULL
)
1247 events
->work_pending
= 1;
1249 /* advance the time */
1250 SIM_ASSERT (events
->time_from_event
>= events
->nr_ticks_to_process
);
1251 SIM_ASSERT (events
->queue
!= NULL
); /* always poll event */
1252 events
->time_from_event
-= events
->nr_ticks_to_process
;
1254 /* this round of processing complete */
1255 events
->nr_ticks_to_process
= 0;