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_
27 #include "sim-assert.h"
29 #include "libiberty.h"
33 #include <signal.h> /* For SIGPROCMASK et al. */
38 /* core - target byte order */
43 /* core - big-endian */
48 /* core - little-endian */
54 /* sim - host byte order */
59 /* sim - big-endian */
64 /* sim - little-endian */
78 } sim_event_watchpoints
;
82 sim_event_watchpoints watching
;
84 sim_event_handler
*handler
;
86 signed64 time_of_event
;
87 /* watch wallclock event */
89 /* watch core address */
90 address_word core_addr
;
94 /* watch core/sim range */
95 int is_within
; /* 0/1 */
100 /* trace info (if any) */
107 /* The event queue maintains a single absolute time using two
110 TIME_OF_EVENT: this holds the time at which the next event is ment
111 to occur. If no next event it will hold the time of the last
114 TIME_FROM_EVENT: The current distance from TIME_OF_EVENT. A value
115 <= 0 (except when poll-event is being processed) indicates that
116 event processing is due. This variable is decremented once for
117 each iteration of a clock cycle.
119 Initially, the clock is started at time one (0) with TIME_OF_EVENT
120 == 0 and TIME_FROM_EVENT == 0 and with NR_TICKS_TO_PROCESS == 1.
122 Clearly there is a bug in that this code assumes that the absolute
123 time counter will never become greater than 2^62.
125 To avoid the need to use 64bit arithmetic, the event queue always
126 contains at least one event scheduled every 16 000 ticks. This
127 limits the time from event counter to values less than
131 #if !defined (SIM_EVENTS_POLL_RATE)
132 #define SIM_EVENTS_POLL_RATE 0x1000
136 #define _ETRACE sd, NULL
139 #define ETRACE(ARGS) \
142 if (STRACE_EVENTS_P (sd)) \
144 if (STRACE_DEBUG_P (sd)) \
145 trace_printf (sd, NULL, "%s:%d: ", lbasename (__FILE__), __LINE__); \
152 /* event queue iterator - don't iterate over the held queue. */
154 #if EXTERN_SIM_EVENTS_P
156 next_event_queue (SIM_DESC sd
,
160 return &STATE_EVENTS (sd
)->queue
;
161 else if (queue
== &STATE_EVENTS (sd
)->queue
)
162 return &STATE_EVENTS (sd
)->watchpoints
;
163 else if (queue
== &STATE_EVENTS (sd
)->watchpoints
)
164 return &STATE_EVENTS (sd
)->watchedpoints
;
165 else if (queue
== &STATE_EVENTS (sd
)->watchedpoints
)
168 sim_io_error (sd
, "next_event_queue - bad queue");
174 STATIC_INLINE_SIM_EVENTS\
176 sim_events_poll (SIM_DESC sd
,
179 /* just re-schedule in 1000 million ticks time */
180 sim_events_schedule (sd
, SIM_EVENTS_POLL_RATE
, sim_events_poll
, sd
);
181 sim_io_poll_quit (sd
);
185 /* "events" module install handler.
186 This is called via sim_module_install to install the "events" subsystem
187 into the simulator. */
189 #if EXTERN_SIM_EVENTS_P
190 STATIC_SIM_EVENTS (MODULE_UNINSTALL_FN
) sim_events_uninstall
;
191 STATIC_SIM_EVENTS (MODULE_INIT_FN
) sim_events_init
;
192 STATIC_SIM_EVENTS (MODULE_RESUME_FN
) sim_events_resume
;
193 STATIC_SIM_EVENTS (MODULE_SUSPEND_FN
) sim_events_suspend
;
196 #if EXTERN_SIM_EVENTS_P
198 sim_events_install (SIM_DESC sd
)
200 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
201 sim_module_add_uninstall_fn (sd
, sim_events_uninstall
);
202 sim_module_add_init_fn (sd
, sim_events_init
);
203 sim_module_add_resume_fn (sd
, sim_events_resume
);
204 sim_module_add_suspend_fn (sd
, sim_events_suspend
);
210 /* Suspend/resume the event queue manager when the simulator is not
213 #if EXTERN_SIM_EVENTS_P
215 sim_events_resume (SIM_DESC sd
)
217 sim_events
*events
= STATE_EVENTS (sd
);
218 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
219 SIM_ASSERT (events
->resume_wallclock
== 0);
220 events
->resume_wallclock
= sim_elapsed_time_get ();
225 #if EXTERN_SIM_EVENTS_P
227 sim_events_suspend (SIM_DESC sd
)
229 sim_events
*events
= STATE_EVENTS (sd
);
230 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
231 SIM_ASSERT (events
->resume_wallclock
!= 0);
232 events
->elapsed_wallclock
+= sim_elapsed_time_since (events
->resume_wallclock
);
233 events
->resume_wallclock
= 0;
239 /* Uninstall the "events" subsystem from the simulator. */
241 #if EXTERN_SIM_EVENTS_P
243 sim_events_uninstall (SIM_DESC sd
)
245 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
246 /* FIXME: free buffers, etc. */
253 #if EXTERN_SIM_EVENTS_P
255 sim_events_zalloc (SIM_DESC sd
)
257 sim_events
*events
= STATE_EVENTS (sd
);
258 sim_event
*new = events
->free_list
;
261 events
->free_list
= new->next
;
262 memset (new, 0, sizeof (*new));
266 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
270 sigfillset (&new_mask
);
271 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
273 new = ZALLOC (sim_event
);
274 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
276 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
283 STATIC_INLINE_SIM_EVENTS\
285 sim_events_free (SIM_DESC sd
,
288 sim_events
*events
= STATE_EVENTS (sd
);
289 dead
->next
= events
->free_list
;
290 events
->free_list
= dead
;
291 if (dead
->trace
!= NULL
)
293 free (dead
->trace
); /* NB: asprintf returns a `free' buf */
299 /* Initialize the simulator event manager */
301 #if EXTERN_SIM_EVENTS_P
303 sim_events_init (SIM_DESC sd
)
305 sim_events
*events
= STATE_EVENTS (sd
);
307 /* drain the interrupt queue */
309 if (events
->held
== NULL
)
310 events
->held
= NZALLOC (sim_event
, MAX_NR_SIGNAL_SIM_EVENTS
);
312 /* drain the normal queues */
314 sim_event
**queue
= NULL
;
315 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
317 if (queue
== NULL
) break;
318 while (*queue
!= NULL
)
320 sim_event
*dead
= *queue
;
322 sim_events_free (sd
, dead
);
328 /* wind time back to zero */
329 events
->nr_ticks_to_process
= 1; /* start by doing queue */
330 events
->time_of_event
= 0;
331 events
->time_from_event
= 0;
332 events
->elapsed_wallclock
= 0;
333 events
->resume_wallclock
= 0;
335 /* schedule our initial counter event */
336 sim_events_schedule (sd
, 0, sim_events_poll
, sd
);
338 /* from now on, except when the large-int event is being processed
339 the event queue is non empty */
340 SIM_ASSERT (events
->queue
!= NULL
);
349 sim_events_time (SIM_DESC sd
)
351 sim_events
*events
= STATE_EVENTS (sd
);
352 return (events
->time_of_event
- events
->time_from_event
);
358 sim_events_elapsed_time (SIM_DESC sd
)
360 unsigned long elapsed
= STATE_EVENTS (sd
)->elapsed_wallclock
;
362 /* Are we being called inside sim_resume?
363 (Is there a simulation in progress?) */
364 if (STATE_EVENTS (sd
)->resume_wallclock
!= 0)
365 elapsed
+= sim_elapsed_time_since (STATE_EVENTS (sd
)->resume_wallclock
);
371 /* Returns the time that remains before the event is raised. */
374 sim_events_remain_time (SIM_DESC sd
, sim_event
*event
)
379 return (event
->time_of_event
- sim_events_time (sd
));
384 STATIC_INLINE_SIM_EVENTS\
386 update_time_from_event (SIM_DESC sd
)
388 sim_events
*events
= STATE_EVENTS (sd
);
389 signed64 current_time
= sim_events_time (sd
);
390 if (events
->queue
!= NULL
)
392 events
->time_of_event
= events
->queue
->time_of_event
;
393 events
->time_from_event
= (events
->queue
->time_of_event
- current_time
);
397 events
->time_of_event
= current_time
- 1;
398 events
->time_from_event
= -1;
400 if (STRACE_EVENTS_P (sd
))
404 for (event
= events
->queue
, i
= 0;
406 event
= event
->next
, i
++)
409 "event time-from-event - time %ld, delta %ld - event %d, tag 0x%lx, time %ld, handler 0x%lx, data 0x%lx%s%s\n",
411 (long)events
->time_from_event
,
414 (long)event
->time_of_event
,
415 (long)event
->handler
,
417 (event
->trace
!= NULL
) ? ", " : "",
418 (event
->trace
!= NULL
) ? event
->trace
: ""));
421 SIM_ASSERT (current_time
== sim_events_time (sd
));
425 #if EXTERN_SIM_EVENTS_P
427 insert_sim_event (SIM_DESC sd
,
428 sim_event
*new_event
,
431 sim_events
*events
= STATE_EVENTS (sd
);
434 signed64 time_of_event
;
437 sim_io_error (sd
, "what is past is past!\n");
439 /* compute when the event should occur */
440 time_of_event
= sim_events_time (sd
) + delta
;
442 /* find the queue insertion point - things are time ordered */
443 prev
= &events
->queue
;
444 curr
= events
->queue
;
445 while (curr
!= NULL
&& time_of_event
>= curr
->time_of_event
)
447 SIM_ASSERT (curr
->next
== NULL
448 || curr
->time_of_event
<= curr
->next
->time_of_event
);
452 SIM_ASSERT (curr
== NULL
|| time_of_event
< curr
->time_of_event
);
455 new_event
->next
= curr
;
457 new_event
->time_of_event
= time_of_event
;
459 /* adjust the time until the first event */
460 update_time_from_event (sd
);
465 #if EXTERN_SIM_EVENTS_P
467 sim_events_schedule (SIM_DESC sd
,
469 sim_event_handler
*handler
,
472 return sim_events_schedule_tracef (sd
, delta_time
, handler
, data
, NULL
);
477 #if EXTERN_SIM_EVENTS_P
479 sim_events_schedule_tracef (SIM_DESC sd
,
481 sim_event_handler
*handler
,
486 sim_event
*new_event
;
489 new_event
= sim_events_schedule_vtracef (sd
, delta_time
, handler
, data
, fmt
, ap
);
496 #if EXTERN_SIM_EVENTS_P
498 sim_events_schedule_vtracef (SIM_DESC sd
,
500 sim_event_handler
*handler
,
505 sim_event
*new_event
= sim_events_zalloc (sd
);
506 new_event
->data
= data
;
507 new_event
->handler
= handler
;
508 new_event
->watching
= watch_timer
;
509 if (fmt
== NULL
|| !STRACE_EVENTS_P (sd
) || vasprintf (&new_event
->trace
, fmt
, ap
) < 0)
510 new_event
->trace
= NULL
;
511 insert_sim_event (sd
, new_event
, delta_time
);
513 "event scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
514 (long)sim_events_time (sd
),
516 (long)new_event
->time_of_event
,
517 (long)new_event
->handler
,
518 (long)new_event
->data
,
519 (new_event
->trace
!= NULL
) ? ", " : "",
520 (new_event
->trace
!= NULL
) ? new_event
->trace
: ""));
526 #if EXTERN_SIM_EVENTS_P
528 sim_events_schedule_after_signal (SIM_DESC sd
,
530 sim_event_handler
*handler
,
533 sim_events
*events
= STATE_EVENTS (sd
);
534 sim_event
*new_event
;
535 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
539 sigfillset (&new_mask
);
540 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
543 /* allocate an event entry from the signal buffer */
544 new_event
= &events
->held
[events
->nr_held
];
546 if (events
->nr_held
> MAX_NR_SIGNAL_SIM_EVENTS
)
548 sim_engine_abort (NULL
, NULL
, NULL_CIA
,
549 "sim_events_schedule_after_signal - buffer overflow");
552 new_event
->data
= data
;
553 new_event
->handler
= handler
;
554 new_event
->time_of_event
= delta_time
; /* work it out later */
555 new_event
->next
= NULL
;
557 events
->work_pending
= 1; /* notify main process */
559 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
561 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
565 "signal scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
566 (long)sim_events_time (sd
),
568 (long)new_event
->time_of_event
,
569 (long)new_event
->handler
,
570 (long)new_event
->data
));
575 #if EXTERN_SIM_EVENTS_P
577 sim_events_watch_clock (SIM_DESC sd
,
578 unsigned delta_ms_time
,
579 sim_event_handler
*handler
,
582 sim_events
*events
= STATE_EVENTS (sd
);
583 sim_event
*new_event
= sim_events_zalloc (sd
);
585 new_event
->watching
= watch_clock
;
587 new_event
->data
= data
;
588 new_event
->handler
= handler
;
590 if (events
->resume_wallclock
== 0)
591 new_event
->wallclock
= (events
->elapsed_wallclock
+ delta_ms_time
);
593 new_event
->wallclock
= (events
->elapsed_wallclock
594 + sim_elapsed_time_since (events
->resume_wallclock
)
597 new_event
->next
= events
->watchpoints
;
598 events
->watchpoints
= new_event
;
599 events
->work_pending
= 1;
601 "event watching clock at %ld - tag 0x%lx - wallclock %ld, handler 0x%lx, data 0x%lx\n",
602 (long)sim_events_time (sd
),
604 (long)new_event
->wallclock
,
605 (long)new_event
->handler
,
606 (long)new_event
->data
));
612 #if EXTERN_SIM_EVENTS_P
614 sim_events_watch_pc (SIM_DESC sd
,
618 sim_event_handler
*handler
,
621 sim_events
*events
= STATE_EVENTS (sd
);
622 sim_event
*new_event
= sim_events_zalloc (sd
);
624 new_event
->watching
= watch_pc
;
626 new_event
->data
= data
;
627 new_event
->handler
= handler
;
630 new_event
->lb64
= lb
;
632 new_event
->ub64
= ub
;
633 new_event
->is_within
= (is_within
!= 0);
635 new_event
->next
= events
->watchpoints
;
636 events
->watchpoints
= new_event
;
637 events
->work_pending
= 1;
639 "event watching pc at %ld - tag 0x%lx - pc 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
640 (long)sim_events_time (sd
),
644 (long)new_event
->handler
,
645 (long)new_event
->data
));
651 #if EXTERN_SIM_EVENTS_P
653 sim_events_watch_sim (SIM_DESC sd
,
656 enum bfd_endian byte_order
,
660 sim_event_handler
*handler
,
663 sim_events
*events
= STATE_EVENTS (sd
);
664 sim_event
*new_event
= sim_events_zalloc (sd
);
668 case BFD_ENDIAN_UNKNOWN
:
671 case 1: new_event
->watching
= watch_sim_host_1
; break;
672 case 2: new_event
->watching
= watch_sim_host_2
; break;
673 case 4: new_event
->watching
= watch_sim_host_4
; break;
674 case 8: new_event
->watching
= watch_sim_host_8
; break;
675 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
681 case 1: new_event
->watching
= watch_sim_be_1
; break;
682 case 2: new_event
->watching
= watch_sim_be_2
; break;
683 case 4: new_event
->watching
= watch_sim_be_4
; break;
684 case 8: new_event
->watching
= watch_sim_be_8
; break;
685 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
688 case BFD_ENDIAN_LITTLE
:
691 case 1: new_event
->watching
= watch_sim_le_1
; break;
692 case 2: new_event
->watching
= watch_sim_le_2
; break;
693 case 4: new_event
->watching
= watch_sim_le_4
; break;
694 case 8: new_event
->watching
= watch_sim_le_8
; break;
695 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
699 sim_io_error (sd
, "sim_events_watch_sim - invalid byte order");
702 new_event
->data
= data
;
703 new_event
->handler
= handler
;
705 new_event
->host_addr
= host_addr
;
707 new_event
->lb64
= lb
;
709 new_event
->ub64
= ub
;
710 new_event
->is_within
= (is_within
!= 0);
712 new_event
->next
= events
->watchpoints
;
713 events
->watchpoints
= new_event
;
714 events
->work_pending
= 1;
716 "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
717 (long)sim_events_time (sd
),
719 (long)new_event
->host_addr
,
722 (long)new_event
->handler
,
723 (long)new_event
->data
));
729 #if EXTERN_SIM_EVENTS_P
731 sim_events_watch_core (SIM_DESC sd
,
732 address_word core_addr
,
735 enum bfd_endian byte_order
,
739 sim_event_handler
*handler
,
742 sim_events
*events
= STATE_EVENTS (sd
);
743 sim_event
*new_event
= sim_events_zalloc (sd
);
747 case BFD_ENDIAN_UNKNOWN
:
750 case 1: new_event
->watching
= watch_core_targ_1
; break;
751 case 2: new_event
->watching
= watch_core_targ_2
; break;
752 case 4: new_event
->watching
= watch_core_targ_4
; break;
753 case 8: new_event
->watching
= watch_core_targ_8
; break;
754 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
760 case 1: new_event
->watching
= watch_core_be_1
; break;
761 case 2: new_event
->watching
= watch_core_be_2
; break;
762 case 4: new_event
->watching
= watch_core_be_4
; break;
763 case 8: new_event
->watching
= watch_core_be_8
; break;
764 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
767 case BFD_ENDIAN_LITTLE
:
770 case 1: new_event
->watching
= watch_core_le_1
; break;
771 case 2: new_event
->watching
= watch_core_le_2
; break;
772 case 4: new_event
->watching
= watch_core_le_4
; break;
773 case 8: new_event
->watching
= watch_core_le_8
; break;
774 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
778 sim_io_error (sd
, "sim_events_watch_core - invalid byte order");
781 new_event
->data
= data
;
782 new_event
->handler
= handler
;
784 new_event
->core_addr
= core_addr
;
785 new_event
->core_map
= core_map
;
787 new_event
->lb64
= lb
;
789 new_event
->ub64
= ub
;
790 new_event
->is_within
= (is_within
!= 0);
792 new_event
->next
= events
->watchpoints
;
793 events
->watchpoints
= new_event
;
794 events
->work_pending
= 1;
796 "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
797 (long)sim_events_time (sd
),
799 (long)new_event
->host_addr
,
802 (long)new_event
->handler
,
803 (long)new_event
->data
));
809 #if EXTERN_SIM_EVENTS_P
811 sim_events_deschedule (SIM_DESC sd
,
812 sim_event
*event_to_remove
)
814 sim_events
*events
= STATE_EVENTS (sd
);
815 sim_event
*to_remove
= (sim_event
*)event_to_remove
;
816 if (event_to_remove
!= NULL
)
818 sim_event
**queue
= NULL
;
819 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
821 sim_event
**ptr_to_current
;
822 for (ptr_to_current
= queue
;
823 *ptr_to_current
!= NULL
&& *ptr_to_current
!= to_remove
;
824 ptr_to_current
= &(*ptr_to_current
)->next
);
825 if (*ptr_to_current
== to_remove
)
827 sim_event
*dead
= *ptr_to_current
;
828 *ptr_to_current
= dead
->next
;
830 "event/watch descheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
831 (long) sim_events_time (sd
),
832 (long) event_to_remove
,
833 (long) dead
->time_of_event
,
834 (long) dead
->handler
,
836 (dead
->trace
!= NULL
) ? ", " : "",
837 (dead
->trace
!= NULL
) ? dead
->trace
: ""));
838 sim_events_free (sd
, dead
);
839 update_time_from_event (sd
);
840 SIM_ASSERT ((events
->time_from_event
>= 0) == (events
->queue
!= NULL
));
846 "event/watch descheduled at %ld - tag 0x%lx - not found\n",
847 (long) sim_events_time (sd
),
848 (long) event_to_remove
));
853 STATIC_INLINE_SIM_EVENTS\
855 sim_watch_valid (SIM_DESC sd
,
858 switch (to_do
->watching
)
861 #define WATCH_CORE(N,OP,EXT) \
863 unsigned_##N word = 0; \
864 int nr_read = sim_core_read_buffer (sd, NULL, to_do->core_map, &word, \
865 to_do->core_addr, sizeof (word)); \
867 ok = (nr_read == sizeof (unsigned_##N) \
868 && (to_do->is_within \
869 == (word >= to_do->lb##EXT \
870 && word <= to_do->ub##EXT)));
872 case watch_core_targ_1
:
874 WATCH_CORE (1, T2H
,);
877 case watch_core_targ_2
:
879 WATCH_CORE (2, T2H
,);
882 case watch_core_targ_4
:
884 WATCH_CORE (4, T2H
,);
887 case watch_core_targ_8
:
889 WATCH_CORE (8, T2H
,64);
893 case watch_core_be_1
:
895 WATCH_CORE (1, BE2H
,);
898 case watch_core_be_2
:
900 WATCH_CORE (2, BE2H
,);
903 case watch_core_be_4
:
905 WATCH_CORE (4, BE2H
,);
908 case watch_core_be_8
:
910 WATCH_CORE (8, BE2H
,64);
914 case watch_core_le_1
:
916 WATCH_CORE (1, LE2H
,);
919 case watch_core_le_2
:
921 WATCH_CORE (2, LE2H
,);
924 case watch_core_le_4
:
926 WATCH_CORE (4, LE2H
,);
929 case watch_core_le_8
:
931 WATCH_CORE (8, LE2H
,64);
936 #define WATCH_SIM(N,OP,EXT) \
938 unsigned_##N word = *(unsigned_##N*)to_do->host_addr; \
940 ok = (to_do->is_within \
941 == (word >= to_do->lb##EXT \
942 && word <= to_do->ub##EXT));
944 case watch_sim_host_1
:
946 WATCH_SIM (1, word
= ,);
949 case watch_sim_host_2
:
951 WATCH_SIM (2, word
= ,);
954 case watch_sim_host_4
:
956 WATCH_SIM (4, word
= ,);
959 case watch_sim_host_8
:
961 WATCH_SIM (8, word
= ,64);
967 WATCH_SIM (1, BE2H
,);
972 WATCH_SIM (2, BE2H
,);
977 WATCH_SIM (4, BE2H
,);
982 WATCH_SIM (8, BE2H
,64);
988 WATCH_SIM (1, LE2H
,);
993 WATCH_SIM (1, LE2H
,);
998 WATCH_SIM (1, LE2H
,);
1001 case watch_sim_le_8
:
1003 WATCH_SIM (1, LE2H
,64);
1012 for (c
= 0; c
< MAX_NR_PROCESSORS
; ++c
)
1014 sim_cpu
*cpu
= STATE_CPU (sd
, c
);
1015 sim_cia cia
= sim_pc_get (cpu
);
1017 if (to_do
->is_within
== (cia
>= to_do
->lb64
&& cia
<= to_do
->ub64
))
1023 case watch_clock
: /* wallclock */
1025 unsigned long elapsed_time
= sim_events_elapsed_time (sd
);
1026 return (elapsed_time
>= to_do
->wallclock
);
1030 sim_io_error (sd
, "sim_watch_valid - bad switch");
1040 sim_events_tick (SIM_DESC sd
)
1042 sim_events
*events
= STATE_EVENTS (sd
);
1044 /* this should only be called after the previous ticks have been
1047 /* Advance the time but *only* if there is nothing to process */
1048 if (events
->work_pending
1049 || events
->time_from_event
== 0)
1051 events
->nr_ticks_to_process
+= 1;
1056 events
->time_from_event
-= 1;
1064 sim_events_tickn (SIM_DESC sd
,
1067 sim_events
*events
= STATE_EVENTS (sd
);
1070 /* this should only be called after the previous ticks have been
1073 /* Advance the time but *only* if there is nothing to process */
1074 if (events
->work_pending
|| events
->time_from_event
< n
)
1076 events
->nr_ticks_to_process
+= n
;
1081 events
->time_from_event
-= n
;
1089 sim_events_slip (SIM_DESC sd
,
1092 sim_events
*events
= STATE_EVENTS (sd
);
1093 SIM_ASSERT (slip
> 0);
1095 /* Flag a ready event with work_pending instead of number of ticks
1096 to process so that the time continues to be correct */
1097 if (events
->time_from_event
< slip
)
1099 events
->work_pending
= 1;
1101 events
->time_from_event
-= slip
;
1107 sim_events_preprocess (SIM_DESC sd
,
1108 int events_were_last
,
1109 int events_were_next
)
1111 sim_events
*events
= STATE_EVENTS (sd
);
1112 if (events_were_last
)
1114 /* Halted part way through event processing */
1115 ASSERT (events
->nr_ticks_to_process
!= 0);
1116 /* The external world can't tell if the event that stopped the
1117 simulator was the last event to process. */
1118 ASSERT (events_were_next
);
1119 sim_events_process (sd
);
1121 else if (events_were_next
)
1123 /* Halted by the last processor */
1124 if (sim_events_tick (sd
))
1125 sim_events_process (sd
);
1132 sim_events_process (SIM_DESC sd
)
1134 sim_events
*events
= STATE_EVENTS (sd
);
1135 signed64 event_time
= sim_events_time (sd
);
1137 /* Clear work_pending before checking nr_held. Clearing
1138 work_pending after nr_held (with out a lock could loose an
1140 events
->work_pending
= 0;
1142 /* move any events that were asynchronously queued by any signal
1143 handlers onto the real event queue. */
1144 if (events
->nr_held
> 0)
1148 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1152 sigfillset (&new_mask
);
1153 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
1156 for (i
= 0; i
< events
->nr_held
; i
++)
1158 sim_event
*entry
= &events
->held
[i
];
1159 sim_events_schedule (sd
,
1160 entry
->time_of_event
,
1164 events
->nr_held
= 0;
1166 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1168 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
1173 /* Process any watchpoints. Be careful to allow a watchpoint to
1174 appear/disappear under our feet.
1175 To ensure that watchpoints are processed only once per cycle,
1176 they are moved onto a watched queue, this returned to the
1177 watchpoint queue when all queue processing has been
1179 while (events
->watchpoints
!= NULL
)
1181 sim_event
*to_do
= events
->watchpoints
;
1182 events
->watchpoints
= to_do
->next
;
1183 if (sim_watch_valid (sd
, to_do
))
1185 sim_event_handler
*handler
= to_do
->handler
;
1186 void *data
= to_do
->data
;
1188 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
1193 (to_do
->trace
!= NULL
) ? ", " : "",
1194 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1195 sim_events_free (sd
, to_do
);
1200 to_do
->next
= events
->watchedpoints
;
1201 events
->watchedpoints
= to_do
;
1205 /* consume all events for this or earlier times. Be careful to
1206 allow an event to appear/disappear under our feet */
1207 while (events
->queue
->time_of_event
<
1208 (event_time
+ events
->nr_ticks_to_process
))
1210 sim_event
*to_do
= events
->queue
;
1211 sim_event_handler
*handler
= to_do
->handler
;
1212 void *data
= to_do
->data
;
1213 events
->queue
= to_do
->next
;
1214 update_time_from_event (sd
);
1216 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
1221 (to_do
->trace
!= NULL
) ? ", " : "",
1222 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1223 sim_events_free (sd
, to_do
);
1227 /* put things back where they belong ready for the next iteration */
1228 events
->watchpoints
= events
->watchedpoints
;
1229 events
->watchedpoints
= NULL
;
1230 if (events
->watchpoints
!= NULL
)
1231 events
->work_pending
= 1;
1233 /* advance the time */
1234 SIM_ASSERT (events
->time_from_event
>= events
->nr_ticks_to_process
);
1235 SIM_ASSERT (events
->queue
!= NULL
); /* always poll event */
1236 events
->time_from_event
-= events
->nr_ticks_to_process
;
1238 /* this round of processing complete */
1239 events
->nr_ticks_to_process
= 0;