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. */
29 #include <signal.h> /* For SIGPROCMASK et al. */
33 #include "libiberty.h"
36 #include "sim-assert.h"
42 /* core - target byte order */
47 /* core - big-endian */
52 /* core - little-endian */
58 /* sim - host byte order */
63 /* sim - big-endian */
68 /* sim - little-endian */
82 } sim_event_watchpoints
;
86 sim_event_watchpoints watching
;
88 sim_event_handler
*handler
;
90 signed64 time_of_event
;
91 /* watch wallclock event */
93 /* watch core address */
94 address_word core_addr
;
98 /* watch core/sim range */
99 int is_within
; /* 0/1 */
104 /* trace info (if any) */
111 /* The event queue maintains a single absolute time using two
114 TIME_OF_EVENT: this holds the time at which the next event is ment
115 to occur. If no next event it will hold the time of the last
118 TIME_FROM_EVENT: The current distance from TIME_OF_EVENT. A value
119 <= 0 (except when poll-event is being processed) indicates that
120 event processing is due. This variable is decremented once for
121 each iteration of a clock cycle.
123 Initially, the clock is started at time one (0) with TIME_OF_EVENT
124 == 0 and TIME_FROM_EVENT == 0 and with NR_TICKS_TO_PROCESS == 1.
126 Clearly there is a bug in that this code assumes that the absolute
127 time counter will never become greater than 2^62.
129 To avoid the need to use 64bit arithmetic, the event queue always
130 contains at least one event scheduled every 16 000 ticks. This
131 limits the time from event counter to values less than
135 #if !defined (SIM_EVENTS_POLL_RATE)
136 #define SIM_EVENTS_POLL_RATE 0x1000
140 #define _ETRACE sd, NULL
143 #define ETRACE(ARGS) \
146 if (STRACE_EVENTS_P (sd)) \
148 if (STRACE_DEBUG_P (sd)) \
149 trace_printf (sd, NULL, "%s:%d: ", lbasename (__FILE__), __LINE__); \
156 /* event queue iterator - don't iterate over the held queue. */
158 #if EXTERN_SIM_EVENTS_P
160 next_event_queue (SIM_DESC sd
,
164 return &STATE_EVENTS (sd
)->queue
;
165 else if (queue
== &STATE_EVENTS (sd
)->queue
)
166 return &STATE_EVENTS (sd
)->watchpoints
;
167 else if (queue
== &STATE_EVENTS (sd
)->watchpoints
)
168 return &STATE_EVENTS (sd
)->watchedpoints
;
169 else if (queue
== &STATE_EVENTS (sd
)->watchedpoints
)
172 sim_io_error (sd
, "next_event_queue - bad queue");
178 STATIC_INLINE_SIM_EVENTS\
180 sim_events_poll (SIM_DESC sd
,
183 /* just re-schedule in 1000 million ticks time */
184 sim_events_schedule (sd
, SIM_EVENTS_POLL_RATE
, sim_events_poll
, sd
);
185 sim_io_poll_quit (sd
);
189 /* "events" module install handler.
190 This is called via sim_module_install to install the "events" subsystem
191 into the simulator. */
193 #if EXTERN_SIM_EVENTS_P
194 STATIC_SIM_EVENTS (MODULE_UNINSTALL_FN
) sim_events_uninstall
;
195 STATIC_SIM_EVENTS (MODULE_INIT_FN
) sim_events_init
;
196 STATIC_SIM_EVENTS (MODULE_RESUME_FN
) sim_events_resume
;
197 STATIC_SIM_EVENTS (MODULE_SUSPEND_FN
) sim_events_suspend
;
200 #if EXTERN_SIM_EVENTS_P
202 sim_events_install (SIM_DESC sd
)
204 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
205 sim_module_add_uninstall_fn (sd
, sim_events_uninstall
);
206 sim_module_add_init_fn (sd
, sim_events_init
);
207 sim_module_add_resume_fn (sd
, sim_events_resume
);
208 sim_module_add_suspend_fn (sd
, sim_events_suspend
);
214 /* Suspend/resume the event queue manager when the simulator is not
217 #if EXTERN_SIM_EVENTS_P
219 sim_events_resume (SIM_DESC sd
)
221 sim_events
*events
= STATE_EVENTS (sd
);
222 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
223 SIM_ASSERT (events
->resume_wallclock
== 0);
224 events
->resume_wallclock
= sim_elapsed_time_get ();
229 #if EXTERN_SIM_EVENTS_P
231 sim_events_suspend (SIM_DESC sd
)
233 sim_events
*events
= STATE_EVENTS (sd
);
234 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
235 SIM_ASSERT (events
->resume_wallclock
!= 0);
236 events
->elapsed_wallclock
+= sim_elapsed_time_since (events
->resume_wallclock
);
237 events
->resume_wallclock
= 0;
243 /* Uninstall the "events" subsystem from the simulator. */
245 #if EXTERN_SIM_EVENTS_P
247 sim_events_uninstall (SIM_DESC sd
)
249 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
250 /* FIXME: free buffers, etc. */
257 #if EXTERN_SIM_EVENTS_P
259 sim_events_zalloc (SIM_DESC sd
)
261 sim_events
*events
= STATE_EVENTS (sd
);
262 sim_event
*new = events
->free_list
;
265 events
->free_list
= new->next
;
266 memset (new, 0, sizeof (*new));
270 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
274 sigfillset (&new_mask
);
275 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
277 new = ZALLOC (sim_event
);
278 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
280 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
287 STATIC_INLINE_SIM_EVENTS\
289 sim_events_free (SIM_DESC sd
,
292 sim_events
*events
= STATE_EVENTS (sd
);
293 dead
->next
= events
->free_list
;
294 events
->free_list
= dead
;
295 if (dead
->trace
!= NULL
)
297 free (dead
->trace
); /* NB: asprintf returns a `free' buf */
303 /* Initialize the simulator event manager */
305 #if EXTERN_SIM_EVENTS_P
307 sim_events_init (SIM_DESC sd
)
309 sim_events
*events
= STATE_EVENTS (sd
);
311 /* drain the interrupt queue */
313 if (events
->held
== NULL
)
314 events
->held
= NZALLOC (sim_event
, MAX_NR_SIGNAL_SIM_EVENTS
);
316 /* drain the normal queues */
318 sim_event
**queue
= NULL
;
319 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
321 if (queue
== NULL
) break;
322 while (*queue
!= NULL
)
324 sim_event
*dead
= *queue
;
326 sim_events_free (sd
, dead
);
332 /* wind time back to zero */
333 events
->nr_ticks_to_process
= 1; /* start by doing queue */
334 events
->time_of_event
= 0;
335 events
->time_from_event
= 0;
336 events
->elapsed_wallclock
= 0;
337 events
->resume_wallclock
= 0;
339 /* schedule our initial counter event */
340 sim_events_schedule (sd
, 0, sim_events_poll
, sd
);
342 /* from now on, except when the large-int event is being processed
343 the event queue is non empty */
344 SIM_ASSERT (events
->queue
!= NULL
);
353 sim_events_time (SIM_DESC sd
)
355 sim_events
*events
= STATE_EVENTS (sd
);
356 return (events
->time_of_event
- events
->time_from_event
);
362 sim_events_elapsed_time (SIM_DESC sd
)
364 unsigned long elapsed
= STATE_EVENTS (sd
)->elapsed_wallclock
;
366 /* Are we being called inside sim_resume?
367 (Is there a simulation in progress?) */
368 if (STATE_EVENTS (sd
)->resume_wallclock
!= 0)
369 elapsed
+= sim_elapsed_time_since (STATE_EVENTS (sd
)->resume_wallclock
);
375 /* Returns the time that remains before the event is raised. */
378 sim_events_remain_time (SIM_DESC sd
, sim_event
*event
)
383 return (event
->time_of_event
- sim_events_time (sd
));
388 STATIC_INLINE_SIM_EVENTS\
390 update_time_from_event (SIM_DESC sd
)
392 sim_events
*events
= STATE_EVENTS (sd
);
393 signed64 current_time
= sim_events_time (sd
);
394 if (events
->queue
!= NULL
)
396 events
->time_of_event
= events
->queue
->time_of_event
;
397 events
->time_from_event
= (events
->queue
->time_of_event
- current_time
);
401 events
->time_of_event
= current_time
- 1;
402 events
->time_from_event
= -1;
404 if (STRACE_EVENTS_P (sd
))
408 for (event
= events
->queue
, i
= 0;
410 event
= event
->next
, i
++)
413 "event time-from-event - "
414 "time %" PRIi64
", delta %" PRIi64
" - "
415 "event %i, tag %p, time %" PRIi64
", handler %p, data "
418 events
->time_from_event
,
421 event
->time_of_event
,
424 (event
->trace
!= NULL
) ? ", " : "",
425 (event
->trace
!= NULL
) ? event
->trace
: ""));
428 SIM_ASSERT (current_time
== sim_events_time (sd
));
432 #if EXTERN_SIM_EVENTS_P
434 insert_sim_event (SIM_DESC sd
,
435 sim_event
*new_event
,
438 sim_events
*events
= STATE_EVENTS (sd
);
441 signed64 time_of_event
;
444 sim_io_error (sd
, "what is past is past!\n");
446 /* compute when the event should occur */
447 time_of_event
= sim_events_time (sd
) + delta
;
449 /* find the queue insertion point - things are time ordered */
450 prev
= &events
->queue
;
451 curr
= events
->queue
;
452 while (curr
!= NULL
&& time_of_event
>= curr
->time_of_event
)
454 SIM_ASSERT (curr
->next
== NULL
455 || curr
->time_of_event
<= curr
->next
->time_of_event
);
459 SIM_ASSERT (curr
== NULL
|| time_of_event
< curr
->time_of_event
);
462 new_event
->next
= curr
;
464 new_event
->time_of_event
= time_of_event
;
466 /* adjust the time until the first event */
467 update_time_from_event (sd
);
472 #if EXTERN_SIM_EVENTS_P
474 sim_events_schedule (SIM_DESC sd
,
476 sim_event_handler
*handler
,
479 return sim_events_schedule_tracef (sd
, delta_time
, handler
, data
, NULL
);
484 #if EXTERN_SIM_EVENTS_P
486 sim_events_schedule_tracef (SIM_DESC sd
,
488 sim_event_handler
*handler
,
493 sim_event
*new_event
;
496 new_event
= sim_events_schedule_vtracef (sd
, delta_time
, handler
, data
, fmt
, ap
);
503 #if EXTERN_SIM_EVENTS_P
505 sim_events_schedule_vtracef (SIM_DESC sd
,
507 sim_event_handler
*handler
,
512 sim_event
*new_event
= sim_events_zalloc (sd
);
513 new_event
->data
= data
;
514 new_event
->handler
= handler
;
515 new_event
->watching
= watch_timer
;
516 if (fmt
== NULL
|| !STRACE_EVENTS_P (sd
) || vasprintf (&new_event
->trace
, fmt
, ap
) < 0)
517 new_event
->trace
= NULL
;
518 insert_sim_event (sd
, new_event
, delta_time
);
520 "event scheduled at %" PRIi64
" - "
521 "tag %p - time %" PRIi64
", handler %p, data %p%s%s\n",
522 sim_events_time (sd
),
524 new_event
->time_of_event
,
527 (new_event
->trace
!= NULL
) ? ", " : "",
528 (new_event
->trace
!= NULL
) ? new_event
->trace
: ""));
534 #if EXTERN_SIM_EVENTS_P
536 sim_events_schedule_after_signal (SIM_DESC sd
,
538 sim_event_handler
*handler
,
541 sim_events
*events
= STATE_EVENTS (sd
);
542 sim_event
*new_event
;
543 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
547 sigfillset (&new_mask
);
548 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
551 /* allocate an event entry from the signal buffer */
552 new_event
= &events
->held
[events
->nr_held
];
554 if (events
->nr_held
> MAX_NR_SIGNAL_SIM_EVENTS
)
556 sim_engine_abort (NULL
, NULL
, NULL_CIA
,
557 "sim_events_schedule_after_signal - buffer overflow");
560 new_event
->data
= data
;
561 new_event
->handler
= handler
;
562 new_event
->time_of_event
= delta_time
; /* work it out later */
563 new_event
->next
= NULL
;
565 events
->work_pending
= 1; /* notify main process */
567 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
569 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
573 "signal scheduled at %" PRIi64
" - "
574 "tag %p - time %" PRIi64
", handler %p, data %p\n",
575 sim_events_time (sd
),
577 new_event
->time_of_event
,
584 #if EXTERN_SIM_EVENTS_P
586 sim_events_watch_clock (SIM_DESC sd
,
587 unsigned delta_ms_time
,
588 sim_event_handler
*handler
,
591 sim_events
*events
= STATE_EVENTS (sd
);
592 sim_event
*new_event
= sim_events_zalloc (sd
);
594 new_event
->watching
= watch_clock
;
596 new_event
->data
= data
;
597 new_event
->handler
= handler
;
599 if (events
->resume_wallclock
== 0)
600 new_event
->wallclock
= (events
->elapsed_wallclock
+ delta_ms_time
);
602 new_event
->wallclock
= (events
->elapsed_wallclock
603 + sim_elapsed_time_since (events
->resume_wallclock
)
606 new_event
->next
= events
->watchpoints
;
607 events
->watchpoints
= new_event
;
608 events
->work_pending
= 1;
610 "event watching clock at %" PRIi64
" - "
611 "tag %p - wallclock %u, handler %p, data %p\n",
612 sim_events_time (sd
),
614 new_event
->wallclock
,
622 #if EXTERN_SIM_EVENTS_P
624 sim_events_watch_pc (SIM_DESC sd
,
628 sim_event_handler
*handler
,
631 sim_events
*events
= STATE_EVENTS (sd
);
632 sim_event
*new_event
= sim_events_zalloc (sd
);
634 new_event
->watching
= watch_pc
;
636 new_event
->data
= data
;
637 new_event
->handler
= handler
;
640 new_event
->lb64
= lb
;
642 new_event
->ub64
= ub
;
643 new_event
->is_within
= (is_within
!= 0);
645 new_event
->next
= events
->watchpoints
;
646 events
->watchpoints
= new_event
;
647 events
->work_pending
= 1;
649 "event watching pc at %" PRIi64
" - "
650 "tag %p - pc 0x%x..0x%x, handler %p, data %p\n",
651 sim_events_time (sd
),
662 #if EXTERN_SIM_EVENTS_P
664 sim_events_watch_sim (SIM_DESC sd
,
667 enum bfd_endian byte_order
,
671 sim_event_handler
*handler
,
674 sim_events
*events
= STATE_EVENTS (sd
);
675 sim_event
*new_event
= sim_events_zalloc (sd
);
679 case BFD_ENDIAN_UNKNOWN
:
682 case 1: new_event
->watching
= watch_sim_host_1
; break;
683 case 2: new_event
->watching
= watch_sim_host_2
; break;
684 case 4: new_event
->watching
= watch_sim_host_4
; break;
685 case 8: new_event
->watching
= watch_sim_host_8
; break;
686 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
692 case 1: new_event
->watching
= watch_sim_be_1
; break;
693 case 2: new_event
->watching
= watch_sim_be_2
; break;
694 case 4: new_event
->watching
= watch_sim_be_4
; break;
695 case 8: new_event
->watching
= watch_sim_be_8
; break;
696 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
699 case BFD_ENDIAN_LITTLE
:
702 case 1: new_event
->watching
= watch_sim_le_1
; break;
703 case 2: new_event
->watching
= watch_sim_le_2
; break;
704 case 4: new_event
->watching
= watch_sim_le_4
; break;
705 case 8: new_event
->watching
= watch_sim_le_8
; break;
706 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
710 sim_io_error (sd
, "sim_events_watch_sim - invalid byte order");
713 new_event
->data
= data
;
714 new_event
->handler
= handler
;
716 new_event
->host_addr
= host_addr
;
718 new_event
->lb64
= lb
;
720 new_event
->ub64
= ub
;
721 new_event
->is_within
= (is_within
!= 0);
723 new_event
->next
= events
->watchpoints
;
724 events
->watchpoints
= new_event
;
725 events
->work_pending
= 1;
727 "event watching host at %" PRIi64
" - "
728 "tag %p - host-addr %p, 0x%x..0x%x, handler %p, data %p\n",
729 sim_events_time (sd
),
731 new_event
->host_addr
,
741 #if EXTERN_SIM_EVENTS_P
743 sim_events_watch_core (SIM_DESC sd
,
744 address_word core_addr
,
747 enum bfd_endian byte_order
,
751 sim_event_handler
*handler
,
754 sim_events
*events
= STATE_EVENTS (sd
);
755 sim_event
*new_event
= sim_events_zalloc (sd
);
759 case BFD_ENDIAN_UNKNOWN
:
762 case 1: new_event
->watching
= watch_core_targ_1
; break;
763 case 2: new_event
->watching
= watch_core_targ_2
; break;
764 case 4: new_event
->watching
= watch_core_targ_4
; break;
765 case 8: new_event
->watching
= watch_core_targ_8
; break;
766 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
772 case 1: new_event
->watching
= watch_core_be_1
; break;
773 case 2: new_event
->watching
= watch_core_be_2
; break;
774 case 4: new_event
->watching
= watch_core_be_4
; break;
775 case 8: new_event
->watching
= watch_core_be_8
; break;
776 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
779 case BFD_ENDIAN_LITTLE
:
782 case 1: new_event
->watching
= watch_core_le_1
; break;
783 case 2: new_event
->watching
= watch_core_le_2
; break;
784 case 4: new_event
->watching
= watch_core_le_4
; break;
785 case 8: new_event
->watching
= watch_core_le_8
; break;
786 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
790 sim_io_error (sd
, "sim_events_watch_core - invalid byte order");
793 new_event
->data
= data
;
794 new_event
->handler
= handler
;
796 new_event
->core_addr
= core_addr
;
797 new_event
->core_map
= core_map
;
799 new_event
->lb64
= lb
;
801 new_event
->ub64
= ub
;
802 new_event
->is_within
= (is_within
!= 0);
804 new_event
->next
= events
->watchpoints
;
805 events
->watchpoints
= new_event
;
806 events
->work_pending
= 1;
808 "event watching host at %" PRIi64
" - "
809 "tag %p - host-addr %p, 0x%x..0x%x, handler %p, data %p\n",
810 sim_events_time (sd
),
812 new_event
->host_addr
,
822 #if EXTERN_SIM_EVENTS_P
824 sim_events_deschedule (SIM_DESC sd
,
825 sim_event
*event_to_remove
)
827 sim_events
*events
= STATE_EVENTS (sd
);
828 sim_event
*to_remove
= (sim_event
*)event_to_remove
;
829 if (event_to_remove
!= NULL
)
831 sim_event
**queue
= NULL
;
832 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
834 sim_event
**ptr_to_current
;
835 for (ptr_to_current
= queue
;
836 *ptr_to_current
!= NULL
&& *ptr_to_current
!= to_remove
;
837 ptr_to_current
= &(*ptr_to_current
)->next
);
838 if (*ptr_to_current
== to_remove
)
840 sim_event
*dead
= *ptr_to_current
;
841 *ptr_to_current
= dead
->next
;
843 "event/watch descheduled at %" PRIi64
" - "
844 "tag %p - time %" PRIi64
", handler %p, data %p%s%s\n",
845 sim_events_time (sd
),
850 (dead
->trace
!= NULL
) ? ", " : "",
851 (dead
->trace
!= NULL
) ? dead
->trace
: ""));
852 sim_events_free (sd
, dead
);
853 update_time_from_event (sd
);
854 SIM_ASSERT ((events
->time_from_event
>= 0) == (events
->queue
!= NULL
));
860 "event/watch descheduled at %" PRIi64
" - tag %p - not found\n",
861 sim_events_time (sd
),
867 STATIC_INLINE_SIM_EVENTS\
869 sim_watch_valid (SIM_DESC sd
,
872 switch (to_do
->watching
)
875 #define WATCH_CORE(N,OP,EXT) \
877 unsigned_##N word = 0; \
878 int nr_read = sim_core_read_buffer (sd, NULL, to_do->core_map, &word, \
879 to_do->core_addr, sizeof (word)); \
881 ok = (nr_read == sizeof (unsigned_##N) \
882 && (to_do->is_within \
883 == (word >= to_do->lb##EXT \
884 && word <= to_do->ub##EXT)));
886 case watch_core_targ_1
:
888 WATCH_CORE (1, T2H
,);
891 case watch_core_targ_2
:
893 WATCH_CORE (2, T2H
,);
896 case watch_core_targ_4
:
898 WATCH_CORE (4, T2H
,);
901 case watch_core_targ_8
:
903 WATCH_CORE (8, T2H
,64);
907 case watch_core_be_1
:
909 WATCH_CORE (1, BE2H
,);
912 case watch_core_be_2
:
914 WATCH_CORE (2, BE2H
,);
917 case watch_core_be_4
:
919 WATCH_CORE (4, BE2H
,);
922 case watch_core_be_8
:
924 WATCH_CORE (8, BE2H
,64);
928 case watch_core_le_1
:
930 WATCH_CORE (1, LE2H
,);
933 case watch_core_le_2
:
935 WATCH_CORE (2, LE2H
,);
938 case watch_core_le_4
:
940 WATCH_CORE (4, LE2H
,);
943 case watch_core_le_8
:
945 WATCH_CORE (8, LE2H
,64);
950 #define WATCH_SIM(N,OP,EXT) \
952 unsigned_##N word = *(unsigned_##N*)to_do->host_addr; \
954 ok = (to_do->is_within \
955 == (word >= to_do->lb##EXT \
956 && word <= to_do->ub##EXT));
958 case watch_sim_host_1
:
960 WATCH_SIM (1, word
= ,);
963 case watch_sim_host_2
:
965 WATCH_SIM (2, word
= ,);
968 case watch_sim_host_4
:
970 WATCH_SIM (4, word
= ,);
973 case watch_sim_host_8
:
975 WATCH_SIM (8, word
= ,64);
981 WATCH_SIM (1, BE2H
,);
986 WATCH_SIM (2, BE2H
,);
991 WATCH_SIM (4, BE2H
,);
996 WATCH_SIM (8, BE2H
,64);
1000 case watch_sim_le_1
:
1002 WATCH_SIM (1, LE2H
,);
1005 case watch_sim_le_2
:
1007 WATCH_SIM (1, LE2H
,);
1010 case watch_sim_le_4
:
1012 WATCH_SIM (1, LE2H
,);
1015 case watch_sim_le_8
:
1017 WATCH_SIM (1, LE2H
,64);
1026 for (c
= 0; c
< MAX_NR_PROCESSORS
; ++c
)
1028 sim_cpu
*cpu
= STATE_CPU (sd
, c
);
1029 sim_cia cia
= sim_pc_get (cpu
);
1031 if (to_do
->is_within
== (cia
>= to_do
->lb64
&& cia
<= to_do
->ub64
))
1037 case watch_clock
: /* wallclock */
1039 unsigned long elapsed_time
= sim_events_elapsed_time (sd
);
1040 return (elapsed_time
>= to_do
->wallclock
);
1044 sim_io_error (sd
, "sim_watch_valid - bad switch");
1054 sim_events_tick (SIM_DESC sd
)
1056 sim_events
*events
= STATE_EVENTS (sd
);
1058 /* this should only be called after the previous ticks have been
1061 /* Advance the time but *only* if there is nothing to process */
1062 if (events
->work_pending
1063 || events
->time_from_event
== 0)
1065 events
->nr_ticks_to_process
+= 1;
1070 events
->time_from_event
-= 1;
1078 sim_events_tickn (SIM_DESC sd
,
1081 sim_events
*events
= STATE_EVENTS (sd
);
1084 /* this should only be called after the previous ticks have been
1087 /* Advance the time but *only* if there is nothing to process */
1088 if (events
->work_pending
|| events
->time_from_event
< n
)
1090 events
->nr_ticks_to_process
+= n
;
1095 events
->time_from_event
-= n
;
1103 sim_events_slip (SIM_DESC sd
,
1106 sim_events
*events
= STATE_EVENTS (sd
);
1107 SIM_ASSERT (slip
> 0);
1109 /* Flag a ready event with work_pending instead of number of ticks
1110 to process so that the time continues to be correct */
1111 if (events
->time_from_event
< slip
)
1113 events
->work_pending
= 1;
1115 events
->time_from_event
-= slip
;
1121 sim_events_preprocess (SIM_DESC sd
,
1122 int events_were_last
,
1123 int events_were_next
)
1125 sim_events
*events
= STATE_EVENTS (sd
);
1126 if (events_were_last
)
1128 /* Halted part way through event processing */
1129 ASSERT (events
->nr_ticks_to_process
!= 0);
1130 /* The external world can't tell if the event that stopped the
1131 simulator was the last event to process. */
1132 ASSERT (events_were_next
);
1133 sim_events_process (sd
);
1135 else if (events_were_next
)
1137 /* Halted by the last processor */
1138 if (sim_events_tick (sd
))
1139 sim_events_process (sd
);
1146 sim_events_process (SIM_DESC sd
)
1148 sim_events
*events
= STATE_EVENTS (sd
);
1149 signed64 event_time
= sim_events_time (sd
);
1151 /* Clear work_pending before checking nr_held. Clearing
1152 work_pending after nr_held (with out a lock could loose an
1154 events
->work_pending
= 0;
1156 /* move any events that were asynchronously queued by any signal
1157 handlers onto the real event queue. */
1158 if (events
->nr_held
> 0)
1162 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1166 sigfillset (&new_mask
);
1167 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
1170 for (i
= 0; i
< events
->nr_held
; i
++)
1172 sim_event
*entry
= &events
->held
[i
];
1173 sim_events_schedule (sd
,
1174 entry
->time_of_event
,
1178 events
->nr_held
= 0;
1180 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1182 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
1187 /* Process any watchpoints. Be careful to allow a watchpoint to
1188 appear/disappear under our feet.
1189 To ensure that watchpoints are processed only once per cycle,
1190 they are moved onto a watched queue, this returned to the
1191 watchpoint queue when all queue processing has been
1193 while (events
->watchpoints
!= NULL
)
1195 sim_event
*to_do
= events
->watchpoints
;
1196 events
->watchpoints
= to_do
->next
;
1197 if (sim_watch_valid (sd
, to_do
))
1199 sim_event_handler
*handler
= to_do
->handler
;
1200 void *data
= to_do
->data
;
1202 "event issued at %" PRIi64
" - "
1203 "tag %p - handler %p, data %p%s%s\n",
1208 (to_do
->trace
!= NULL
) ? ", " : "",
1209 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1210 sim_events_free (sd
, to_do
);
1215 to_do
->next
= events
->watchedpoints
;
1216 events
->watchedpoints
= to_do
;
1220 /* consume all events for this or earlier times. Be careful to
1221 allow an event to appear/disappear under our feet */
1222 while (events
->queue
->time_of_event
<
1223 (event_time
+ events
->nr_ticks_to_process
))
1225 sim_event
*to_do
= events
->queue
;
1226 sim_event_handler
*handler
= to_do
->handler
;
1227 void *data
= to_do
->data
;
1228 events
->queue
= to_do
->next
;
1229 update_time_from_event (sd
);
1231 "event issued at %" PRIi64
" - tag %p - handler %p, data %p%s%s\n",
1236 (to_do
->trace
!= NULL
) ? ", " : "",
1237 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1238 sim_events_free (sd
, to_do
);
1242 /* put things back where they belong ready for the next iteration */
1243 events
->watchpoints
= events
->watchedpoints
;
1244 events
->watchedpoints
= NULL
;
1245 if (events
->watchpoints
!= NULL
)
1246 events
->work_pending
= 1;
1248 /* advance the time */
1249 SIM_ASSERT (events
->time_from_event
>= events
->nr_ticks_to_process
);
1250 SIM_ASSERT (events
->queue
!= NULL
); /* always poll event */
1251 events
->time_from_event
-= events
->nr_ticks_to_process
;
1253 /* this round of processing complete */
1254 events
->nr_ticks_to_process
= 0;