1 /* The common simulator framework for GDB, the GNU Debugger.
3 Copyright 2002-2021 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. */
30 #include "sim-assert.h"
32 #include "libiberty.h"
36 #include <signal.h> /* For SIGPROCMASK et al. */
41 /* core - target byte order */
46 /* core - big-endian */
51 /* core - little-endian */
57 /* sim - host byte order */
62 /* sim - big-endian */
67 /* sim - little-endian */
81 } sim_event_watchpoints
;
85 sim_event_watchpoints watching
;
87 sim_event_handler
*handler
;
89 signed64 time_of_event
;
90 /* watch wallclock event */
92 /* watch core address */
93 address_word core_addr
;
97 /* watch core/sim range */
98 int is_within
; /* 0/1 */
103 /* trace info (if any) */
110 /* The event queue maintains a single absolute time using two
113 TIME_OF_EVENT: this holds the time at which the next event is ment
114 to occur. If no next event it will hold the time of the last
117 TIME_FROM_EVENT: The current distance from TIME_OF_EVENT. A value
118 <= 0 (except when poll-event is being processed) indicates that
119 event processing is due. This variable is decremented once for
120 each iteration of a clock cycle.
122 Initially, the clock is started at time one (0) with TIME_OF_EVENT
123 == 0 and TIME_FROM_EVENT == 0 and with NR_TICKS_TO_PROCESS == 1.
125 Clearly there is a bug in that this code assumes that the absolute
126 time counter will never become greater than 2^62.
128 To avoid the need to use 64bit arithmetic, the event queue always
129 contains at least one event scheduled every 16 000 ticks. This
130 limits the time from event counter to values less than
134 #if !defined (SIM_EVENTS_POLL_RATE)
135 #define SIM_EVENTS_POLL_RATE 0x1000
139 #define _ETRACE sd, NULL
142 #define ETRACE(ARGS) \
145 if (STRACE_EVENTS_P (sd)) \
147 if (STRACE_DEBUG_P (sd)) \
148 trace_printf (sd, NULL, "%s:%d: ", lbasename (__FILE__), __LINE__); \
155 /* event queue iterator - don't iterate over the held queue. */
157 #if EXTERN_SIM_EVENTS_P
159 next_event_queue (SIM_DESC sd
,
163 return &STATE_EVENTS (sd
)->queue
;
164 else if (queue
== &STATE_EVENTS (sd
)->queue
)
165 return &STATE_EVENTS (sd
)->watchpoints
;
166 else if (queue
== &STATE_EVENTS (sd
)->watchpoints
)
167 return &STATE_EVENTS (sd
)->watchedpoints
;
168 else if (queue
== &STATE_EVENTS (sd
)->watchedpoints
)
171 sim_io_error (sd
, "next_event_queue - bad queue");
177 STATIC_INLINE_SIM_EVENTS\
179 sim_events_poll (SIM_DESC sd
,
182 /* just re-schedule in 1000 million ticks time */
183 sim_events_schedule (sd
, SIM_EVENTS_POLL_RATE
, sim_events_poll
, sd
);
184 sim_io_poll_quit (sd
);
188 /* "events" module install handler.
189 This is called via sim_module_install to install the "events" subsystem
190 into the simulator. */
192 #if EXTERN_SIM_EVENTS_P
193 STATIC_SIM_EVENTS (MODULE_UNINSTALL_FN
) sim_events_uninstall
;
194 STATIC_SIM_EVENTS (MODULE_INIT_FN
) sim_events_init
;
195 STATIC_SIM_EVENTS (MODULE_RESUME_FN
) sim_events_resume
;
196 STATIC_SIM_EVENTS (MODULE_SUSPEND_FN
) sim_events_suspend
;
199 #if EXTERN_SIM_EVENTS_P
201 sim_events_install (SIM_DESC sd
)
203 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
204 sim_module_add_uninstall_fn (sd
, sim_events_uninstall
);
205 sim_module_add_init_fn (sd
, sim_events_init
);
206 sim_module_add_resume_fn (sd
, sim_events_resume
);
207 sim_module_add_suspend_fn (sd
, sim_events_suspend
);
213 /* Suspend/resume the event queue manager when the simulator is not
216 #if EXTERN_SIM_EVENTS_P
218 sim_events_resume (SIM_DESC sd
)
220 sim_events
*events
= STATE_EVENTS (sd
);
221 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
222 SIM_ASSERT (events
->resume_wallclock
== 0);
223 events
->resume_wallclock
= sim_elapsed_time_get ();
228 #if EXTERN_SIM_EVENTS_P
230 sim_events_suspend (SIM_DESC sd
)
232 sim_events
*events
= STATE_EVENTS (sd
);
233 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
234 SIM_ASSERT (events
->resume_wallclock
!= 0);
235 events
->elapsed_wallclock
+= sim_elapsed_time_since (events
->resume_wallclock
);
236 events
->resume_wallclock
= 0;
242 /* Uninstall the "events" subsystem from the simulator. */
244 #if EXTERN_SIM_EVENTS_P
246 sim_events_uninstall (SIM_DESC sd
)
248 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
249 /* FIXME: free buffers, etc. */
256 #if EXTERN_SIM_EVENTS_P
258 sim_events_zalloc (SIM_DESC sd
)
260 sim_events
*events
= STATE_EVENTS (sd
);
261 sim_event
*new = events
->free_list
;
264 events
->free_list
= new->next
;
265 memset (new, 0, sizeof (*new));
269 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
273 sigfillset (&new_mask
);
274 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
276 new = ZALLOC (sim_event
);
277 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
279 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
286 STATIC_INLINE_SIM_EVENTS\
288 sim_events_free (SIM_DESC sd
,
291 sim_events
*events
= STATE_EVENTS (sd
);
292 dead
->next
= events
->free_list
;
293 events
->free_list
= dead
;
294 if (dead
->trace
!= NULL
)
296 free (dead
->trace
); /* NB: asprintf returns a `free' buf */
302 /* Initialize the simulator event manager */
304 #if EXTERN_SIM_EVENTS_P
306 sim_events_init (SIM_DESC sd
)
308 sim_events
*events
= STATE_EVENTS (sd
);
310 /* drain the interrupt queue */
312 if (events
->held
== NULL
)
313 events
->held
= NZALLOC (sim_event
, MAX_NR_SIGNAL_SIM_EVENTS
);
315 /* drain the normal queues */
317 sim_event
**queue
= NULL
;
318 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
320 if (queue
== NULL
) break;
321 while (*queue
!= NULL
)
323 sim_event
*dead
= *queue
;
325 sim_events_free (sd
, dead
);
331 /* wind time back to zero */
332 events
->nr_ticks_to_process
= 1; /* start by doing queue */
333 events
->time_of_event
= 0;
334 events
->time_from_event
= 0;
335 events
->elapsed_wallclock
= 0;
336 events
->resume_wallclock
= 0;
338 /* schedule our initial counter event */
339 sim_events_schedule (sd
, 0, sim_events_poll
, sd
);
341 /* from now on, except when the large-int event is being processed
342 the event queue is non empty */
343 SIM_ASSERT (events
->queue
!= NULL
);
352 sim_events_time (SIM_DESC sd
)
354 sim_events
*events
= STATE_EVENTS (sd
);
355 return (events
->time_of_event
- events
->time_from_event
);
361 sim_events_elapsed_time (SIM_DESC sd
)
363 unsigned long elapsed
= STATE_EVENTS (sd
)->elapsed_wallclock
;
365 /* Are we being called inside sim_resume?
366 (Is there a simulation in progress?) */
367 if (STATE_EVENTS (sd
)->resume_wallclock
!= 0)
368 elapsed
+= sim_elapsed_time_since (STATE_EVENTS (sd
)->resume_wallclock
);
374 /* Returns the time that remains before the event is raised. */
377 sim_events_remain_time (SIM_DESC sd
, sim_event
*event
)
382 return (event
->time_of_event
- sim_events_time (sd
));
387 STATIC_INLINE_SIM_EVENTS\
389 update_time_from_event (SIM_DESC sd
)
391 sim_events
*events
= STATE_EVENTS (sd
);
392 signed64 current_time
= sim_events_time (sd
);
393 if (events
->queue
!= NULL
)
395 events
->time_of_event
= events
->queue
->time_of_event
;
396 events
->time_from_event
= (events
->queue
->time_of_event
- current_time
);
400 events
->time_of_event
= current_time
- 1;
401 events
->time_from_event
= -1;
403 if (STRACE_EVENTS_P (sd
))
407 for (event
= events
->queue
, i
= 0;
409 event
= event
->next
, i
++)
412 "event time-from-event - "
413 "time %" PRIi64
", delta %" PRIi64
" - "
414 "event %i, tag %p, time %" PRIi64
", handler %p, data "
417 events
->time_from_event
,
420 event
->time_of_event
,
423 (event
->trace
!= NULL
) ? ", " : "",
424 (event
->trace
!= NULL
) ? event
->trace
: ""));
427 SIM_ASSERT (current_time
== sim_events_time (sd
));
431 #if EXTERN_SIM_EVENTS_P
433 insert_sim_event (SIM_DESC sd
,
434 sim_event
*new_event
,
437 sim_events
*events
= STATE_EVENTS (sd
);
440 signed64 time_of_event
;
443 sim_io_error (sd
, "what is past is past!\n");
445 /* compute when the event should occur */
446 time_of_event
= sim_events_time (sd
) + delta
;
448 /* find the queue insertion point - things are time ordered */
449 prev
= &events
->queue
;
450 curr
= events
->queue
;
451 while (curr
!= NULL
&& time_of_event
>= curr
->time_of_event
)
453 SIM_ASSERT (curr
->next
== NULL
454 || curr
->time_of_event
<= curr
->next
->time_of_event
);
458 SIM_ASSERT (curr
== NULL
|| time_of_event
< curr
->time_of_event
);
461 new_event
->next
= curr
;
463 new_event
->time_of_event
= time_of_event
;
465 /* adjust the time until the first event */
466 update_time_from_event (sd
);
471 #if EXTERN_SIM_EVENTS_P
473 sim_events_schedule (SIM_DESC sd
,
475 sim_event_handler
*handler
,
478 return sim_events_schedule_tracef (sd
, delta_time
, handler
, data
, NULL
);
483 #if EXTERN_SIM_EVENTS_P
485 sim_events_schedule_tracef (SIM_DESC sd
,
487 sim_event_handler
*handler
,
492 sim_event
*new_event
;
495 new_event
= sim_events_schedule_vtracef (sd
, delta_time
, handler
, data
, fmt
, ap
);
502 #if EXTERN_SIM_EVENTS_P
504 sim_events_schedule_vtracef (SIM_DESC sd
,
506 sim_event_handler
*handler
,
511 sim_event
*new_event
= sim_events_zalloc (sd
);
512 new_event
->data
= data
;
513 new_event
->handler
= handler
;
514 new_event
->watching
= watch_timer
;
515 if (fmt
== NULL
|| !STRACE_EVENTS_P (sd
) || vasprintf (&new_event
->trace
, fmt
, ap
) < 0)
516 new_event
->trace
= NULL
;
517 insert_sim_event (sd
, new_event
, delta_time
);
519 "event scheduled at %" PRIi64
" - "
520 "tag %p - time %" PRIi64
", handler %p, data %p%s%s\n",
521 sim_events_time (sd
),
523 new_event
->time_of_event
,
526 (new_event
->trace
!= NULL
) ? ", " : "",
527 (new_event
->trace
!= NULL
) ? new_event
->trace
: ""));
533 #if EXTERN_SIM_EVENTS_P
535 sim_events_schedule_after_signal (SIM_DESC sd
,
537 sim_event_handler
*handler
,
540 sim_events
*events
= STATE_EVENTS (sd
);
541 sim_event
*new_event
;
542 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
546 sigfillset (&new_mask
);
547 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
550 /* allocate an event entry from the signal buffer */
551 new_event
= &events
->held
[events
->nr_held
];
553 if (events
->nr_held
> MAX_NR_SIGNAL_SIM_EVENTS
)
555 sim_engine_abort (NULL
, NULL
, NULL_CIA
,
556 "sim_events_schedule_after_signal - buffer overflow");
559 new_event
->data
= data
;
560 new_event
->handler
= handler
;
561 new_event
->time_of_event
= delta_time
; /* work it out later */
562 new_event
->next
= NULL
;
564 events
->work_pending
= 1; /* notify main process */
566 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
568 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
572 "signal scheduled at %" PRIi64
" - "
573 "tag %p - time %" PRIi64
", handler %p, data %p\n",
574 sim_events_time (sd
),
576 new_event
->time_of_event
,
583 #if EXTERN_SIM_EVENTS_P
585 sim_events_watch_clock (SIM_DESC sd
,
586 unsigned delta_ms_time
,
587 sim_event_handler
*handler
,
590 sim_events
*events
= STATE_EVENTS (sd
);
591 sim_event
*new_event
= sim_events_zalloc (sd
);
593 new_event
->watching
= watch_clock
;
595 new_event
->data
= data
;
596 new_event
->handler
= handler
;
598 if (events
->resume_wallclock
== 0)
599 new_event
->wallclock
= (events
->elapsed_wallclock
+ delta_ms_time
);
601 new_event
->wallclock
= (events
->elapsed_wallclock
602 + sim_elapsed_time_since (events
->resume_wallclock
)
605 new_event
->next
= events
->watchpoints
;
606 events
->watchpoints
= new_event
;
607 events
->work_pending
= 1;
609 "event watching clock at %" PRIi64
" - "
610 "tag %p - wallclock %u, handler %p, data %p\n",
611 sim_events_time (sd
),
613 new_event
->wallclock
,
621 #if EXTERN_SIM_EVENTS_P
623 sim_events_watch_pc (SIM_DESC sd
,
627 sim_event_handler
*handler
,
630 sim_events
*events
= STATE_EVENTS (sd
);
631 sim_event
*new_event
= sim_events_zalloc (sd
);
633 new_event
->watching
= watch_pc
;
635 new_event
->data
= data
;
636 new_event
->handler
= handler
;
639 new_event
->lb64
= lb
;
641 new_event
->ub64
= ub
;
642 new_event
->is_within
= (is_within
!= 0);
644 new_event
->next
= events
->watchpoints
;
645 events
->watchpoints
= new_event
;
646 events
->work_pending
= 1;
648 "event watching pc at %" PRIi64
" - "
649 "tag %p - pc 0x%x..0x%x, handler %p, data %p\n",
650 sim_events_time (sd
),
661 #if EXTERN_SIM_EVENTS_P
663 sim_events_watch_sim (SIM_DESC sd
,
666 enum bfd_endian byte_order
,
670 sim_event_handler
*handler
,
673 sim_events
*events
= STATE_EVENTS (sd
);
674 sim_event
*new_event
= sim_events_zalloc (sd
);
678 case BFD_ENDIAN_UNKNOWN
:
681 case 1: new_event
->watching
= watch_sim_host_1
; break;
682 case 2: new_event
->watching
= watch_sim_host_2
; break;
683 case 4: new_event
->watching
= watch_sim_host_4
; break;
684 case 8: new_event
->watching
= watch_sim_host_8
; break;
685 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
691 case 1: new_event
->watching
= watch_sim_be_1
; break;
692 case 2: new_event
->watching
= watch_sim_be_2
; break;
693 case 4: new_event
->watching
= watch_sim_be_4
; break;
694 case 8: new_event
->watching
= watch_sim_be_8
; break;
695 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
698 case BFD_ENDIAN_LITTLE
:
701 case 1: new_event
->watching
= watch_sim_le_1
; break;
702 case 2: new_event
->watching
= watch_sim_le_2
; break;
703 case 4: new_event
->watching
= watch_sim_le_4
; break;
704 case 8: new_event
->watching
= watch_sim_le_8
; break;
705 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
709 sim_io_error (sd
, "sim_events_watch_sim - invalid byte order");
712 new_event
->data
= data
;
713 new_event
->handler
= handler
;
715 new_event
->host_addr
= host_addr
;
717 new_event
->lb64
= lb
;
719 new_event
->ub64
= ub
;
720 new_event
->is_within
= (is_within
!= 0);
722 new_event
->next
= events
->watchpoints
;
723 events
->watchpoints
= new_event
;
724 events
->work_pending
= 1;
726 "event watching host at %" PRIi64
" - "
727 "tag %p - host-addr %p, 0x%x..0x%x, handler %p, data %p\n",
728 sim_events_time (sd
),
730 new_event
->host_addr
,
740 #if EXTERN_SIM_EVENTS_P
742 sim_events_watch_core (SIM_DESC sd
,
743 address_word core_addr
,
746 enum bfd_endian byte_order
,
750 sim_event_handler
*handler
,
753 sim_events
*events
= STATE_EVENTS (sd
);
754 sim_event
*new_event
= sim_events_zalloc (sd
);
758 case BFD_ENDIAN_UNKNOWN
:
761 case 1: new_event
->watching
= watch_core_targ_1
; break;
762 case 2: new_event
->watching
= watch_core_targ_2
; break;
763 case 4: new_event
->watching
= watch_core_targ_4
; break;
764 case 8: new_event
->watching
= watch_core_targ_8
; break;
765 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
771 case 1: new_event
->watching
= watch_core_be_1
; break;
772 case 2: new_event
->watching
= watch_core_be_2
; break;
773 case 4: new_event
->watching
= watch_core_be_4
; break;
774 case 8: new_event
->watching
= watch_core_be_8
; break;
775 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
778 case BFD_ENDIAN_LITTLE
:
781 case 1: new_event
->watching
= watch_core_le_1
; break;
782 case 2: new_event
->watching
= watch_core_le_2
; break;
783 case 4: new_event
->watching
= watch_core_le_4
; break;
784 case 8: new_event
->watching
= watch_core_le_8
; break;
785 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
789 sim_io_error (sd
, "sim_events_watch_core - invalid byte order");
792 new_event
->data
= data
;
793 new_event
->handler
= handler
;
795 new_event
->core_addr
= core_addr
;
796 new_event
->core_map
= core_map
;
798 new_event
->lb64
= lb
;
800 new_event
->ub64
= ub
;
801 new_event
->is_within
= (is_within
!= 0);
803 new_event
->next
= events
->watchpoints
;
804 events
->watchpoints
= new_event
;
805 events
->work_pending
= 1;
807 "event watching host at %" PRIi64
" - "
808 "tag %p - host-addr %p, 0x%x..0x%x, handler %p, data %p\n",
809 sim_events_time (sd
),
811 new_event
->host_addr
,
821 #if EXTERN_SIM_EVENTS_P
823 sim_events_deschedule (SIM_DESC sd
,
824 sim_event
*event_to_remove
)
826 sim_events
*events
= STATE_EVENTS (sd
);
827 sim_event
*to_remove
= (sim_event
*)event_to_remove
;
828 if (event_to_remove
!= NULL
)
830 sim_event
**queue
= NULL
;
831 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
833 sim_event
**ptr_to_current
;
834 for (ptr_to_current
= queue
;
835 *ptr_to_current
!= NULL
&& *ptr_to_current
!= to_remove
;
836 ptr_to_current
= &(*ptr_to_current
)->next
);
837 if (*ptr_to_current
== to_remove
)
839 sim_event
*dead
= *ptr_to_current
;
840 *ptr_to_current
= dead
->next
;
842 "event/watch descheduled at %" PRIi64
" - "
843 "tag %p - time %" PRIi64
", handler %p, data %p%s%s\n",
844 sim_events_time (sd
),
849 (dead
->trace
!= NULL
) ? ", " : "",
850 (dead
->trace
!= NULL
) ? dead
->trace
: ""));
851 sim_events_free (sd
, dead
);
852 update_time_from_event (sd
);
853 SIM_ASSERT ((events
->time_from_event
>= 0) == (events
->queue
!= NULL
));
859 "event/watch descheduled at %" PRIi64
" - tag %p - not found\n",
860 sim_events_time (sd
),
866 STATIC_INLINE_SIM_EVENTS\
868 sim_watch_valid (SIM_DESC sd
,
871 switch (to_do
->watching
)
874 #define WATCH_CORE(N,OP,EXT) \
876 unsigned_##N word = 0; \
877 int nr_read = sim_core_read_buffer (sd, NULL, to_do->core_map, &word, \
878 to_do->core_addr, sizeof (word)); \
880 ok = (nr_read == sizeof (unsigned_##N) \
881 && (to_do->is_within \
882 == (word >= to_do->lb##EXT \
883 && word <= to_do->ub##EXT)));
885 case watch_core_targ_1
:
887 WATCH_CORE (1, T2H
,);
890 case watch_core_targ_2
:
892 WATCH_CORE (2, T2H
,);
895 case watch_core_targ_4
:
897 WATCH_CORE (4, T2H
,);
900 case watch_core_targ_8
:
902 WATCH_CORE (8, T2H
,64);
906 case watch_core_be_1
:
908 WATCH_CORE (1, BE2H
,);
911 case watch_core_be_2
:
913 WATCH_CORE (2, BE2H
,);
916 case watch_core_be_4
:
918 WATCH_CORE (4, BE2H
,);
921 case watch_core_be_8
:
923 WATCH_CORE (8, BE2H
,64);
927 case watch_core_le_1
:
929 WATCH_CORE (1, LE2H
,);
932 case watch_core_le_2
:
934 WATCH_CORE (2, LE2H
,);
937 case watch_core_le_4
:
939 WATCH_CORE (4, LE2H
,);
942 case watch_core_le_8
:
944 WATCH_CORE (8, LE2H
,64);
949 #define WATCH_SIM(N,OP,EXT) \
951 unsigned_##N word = *(unsigned_##N*)to_do->host_addr; \
953 ok = (to_do->is_within \
954 == (word >= to_do->lb##EXT \
955 && word <= to_do->ub##EXT));
957 case watch_sim_host_1
:
959 WATCH_SIM (1, word
= ,);
962 case watch_sim_host_2
:
964 WATCH_SIM (2, word
= ,);
967 case watch_sim_host_4
:
969 WATCH_SIM (4, word
= ,);
972 case watch_sim_host_8
:
974 WATCH_SIM (8, word
= ,64);
980 WATCH_SIM (1, BE2H
,);
985 WATCH_SIM (2, BE2H
,);
990 WATCH_SIM (4, BE2H
,);
995 WATCH_SIM (8, BE2H
,64);
1001 WATCH_SIM (1, LE2H
,);
1004 case watch_sim_le_2
:
1006 WATCH_SIM (1, LE2H
,);
1009 case watch_sim_le_4
:
1011 WATCH_SIM (1, LE2H
,);
1014 case watch_sim_le_8
:
1016 WATCH_SIM (1, LE2H
,64);
1025 for (c
= 0; c
< MAX_NR_PROCESSORS
; ++c
)
1027 sim_cpu
*cpu
= STATE_CPU (sd
, c
);
1028 sim_cia cia
= sim_pc_get (cpu
);
1030 if (to_do
->is_within
== (cia
>= to_do
->lb64
&& cia
<= to_do
->ub64
))
1036 case watch_clock
: /* wallclock */
1038 unsigned long elapsed_time
= sim_events_elapsed_time (sd
);
1039 return (elapsed_time
>= to_do
->wallclock
);
1043 sim_io_error (sd
, "sim_watch_valid - bad switch");
1053 sim_events_tick (SIM_DESC sd
)
1055 sim_events
*events
= STATE_EVENTS (sd
);
1057 /* this should only be called after the previous ticks have been
1060 /* Advance the time but *only* if there is nothing to process */
1061 if (events
->work_pending
1062 || events
->time_from_event
== 0)
1064 events
->nr_ticks_to_process
+= 1;
1069 events
->time_from_event
-= 1;
1077 sim_events_tickn (SIM_DESC sd
,
1080 sim_events
*events
= STATE_EVENTS (sd
);
1083 /* this should only be called after the previous ticks have been
1086 /* Advance the time but *only* if there is nothing to process */
1087 if (events
->work_pending
|| events
->time_from_event
< n
)
1089 events
->nr_ticks_to_process
+= n
;
1094 events
->time_from_event
-= n
;
1102 sim_events_slip (SIM_DESC sd
,
1105 sim_events
*events
= STATE_EVENTS (sd
);
1106 SIM_ASSERT (slip
> 0);
1108 /* Flag a ready event with work_pending instead of number of ticks
1109 to process so that the time continues to be correct */
1110 if (events
->time_from_event
< slip
)
1112 events
->work_pending
= 1;
1114 events
->time_from_event
-= slip
;
1120 sim_events_preprocess (SIM_DESC sd
,
1121 int events_were_last
,
1122 int events_were_next
)
1124 sim_events
*events
= STATE_EVENTS (sd
);
1125 if (events_were_last
)
1127 /* Halted part way through event processing */
1128 ASSERT (events
->nr_ticks_to_process
!= 0);
1129 /* The external world can't tell if the event that stopped the
1130 simulator was the last event to process. */
1131 ASSERT (events_were_next
);
1132 sim_events_process (sd
);
1134 else if (events_were_next
)
1136 /* Halted by the last processor */
1137 if (sim_events_tick (sd
))
1138 sim_events_process (sd
);
1145 sim_events_process (SIM_DESC sd
)
1147 sim_events
*events
= STATE_EVENTS (sd
);
1148 signed64 event_time
= sim_events_time (sd
);
1150 /* Clear work_pending before checking nr_held. Clearing
1151 work_pending after nr_held (with out a lock could loose an
1153 events
->work_pending
= 0;
1155 /* move any events that were asynchronously queued by any signal
1156 handlers onto the real event queue. */
1157 if (events
->nr_held
> 0)
1161 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1165 sigfillset (&new_mask
);
1166 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
1169 for (i
= 0; i
< events
->nr_held
; i
++)
1171 sim_event
*entry
= &events
->held
[i
];
1172 sim_events_schedule (sd
,
1173 entry
->time_of_event
,
1177 events
->nr_held
= 0;
1179 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1181 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
1186 /* Process any watchpoints. Be careful to allow a watchpoint to
1187 appear/disappear under our feet.
1188 To ensure that watchpoints are processed only once per cycle,
1189 they are moved onto a watched queue, this returned to the
1190 watchpoint queue when all queue processing has been
1192 while (events
->watchpoints
!= NULL
)
1194 sim_event
*to_do
= events
->watchpoints
;
1195 events
->watchpoints
= to_do
->next
;
1196 if (sim_watch_valid (sd
, to_do
))
1198 sim_event_handler
*handler
= to_do
->handler
;
1199 void *data
= to_do
->data
;
1201 "event issued at %" PRIi64
" - "
1202 "tag %p - handler %p, data %p%s%s\n",
1207 (to_do
->trace
!= NULL
) ? ", " : "",
1208 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1209 sim_events_free (sd
, to_do
);
1214 to_do
->next
= events
->watchedpoints
;
1215 events
->watchedpoints
= to_do
;
1219 /* consume all events for this or earlier times. Be careful to
1220 allow an event to appear/disappear under our feet */
1221 while (events
->queue
->time_of_event
<
1222 (event_time
+ events
->nr_ticks_to_process
))
1224 sim_event
*to_do
= events
->queue
;
1225 sim_event_handler
*handler
= to_do
->handler
;
1226 void *data
= to_do
->data
;
1227 events
->queue
= to_do
->next
;
1228 update_time_from_event (sd
);
1230 "event issued at %" PRIi64
" - tag %p - handler %p, data %p%s%s\n",
1235 (to_do
->trace
!= NULL
) ? ", " : "",
1236 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1237 sim_events_free (sd
, to_do
);
1241 /* put things back where they belong ready for the next iteration */
1242 events
->watchpoints
= events
->watchedpoints
;
1243 events
->watchedpoints
= NULL
;
1244 if (events
->watchpoints
!= NULL
)
1245 events
->work_pending
= 1;
1247 /* advance the time */
1248 SIM_ASSERT (events
->time_from_event
>= events
->nr_ticks_to_process
);
1249 SIM_ASSERT (events
->queue
!= NULL
); /* always poll event */
1250 events
->time_from_event
-= events
->nr_ticks_to_process
;
1252 /* this round of processing complete */
1253 events
->nr_ticks_to_process
= 0;