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 - time %ld, delta %ld - event %d, tag 0x%lx, time %ld, handler 0x%lx, data 0x%lx%s%s\n",
414 (long)events
->time_from_event
,
417 (long)event
->time_of_event
,
418 (long)event
->handler
,
420 (event
->trace
!= NULL
) ? ", " : "",
421 (event
->trace
!= NULL
) ? event
->trace
: ""));
424 SIM_ASSERT (current_time
== sim_events_time (sd
));
428 #if EXTERN_SIM_EVENTS_P
430 insert_sim_event (SIM_DESC sd
,
431 sim_event
*new_event
,
434 sim_events
*events
= STATE_EVENTS (sd
);
437 signed64 time_of_event
;
440 sim_io_error (sd
, "what is past is past!\n");
442 /* compute when the event should occur */
443 time_of_event
= sim_events_time (sd
) + delta
;
445 /* find the queue insertion point - things are time ordered */
446 prev
= &events
->queue
;
447 curr
= events
->queue
;
448 while (curr
!= NULL
&& time_of_event
>= curr
->time_of_event
)
450 SIM_ASSERT (curr
->next
== NULL
451 || curr
->time_of_event
<= curr
->next
->time_of_event
);
455 SIM_ASSERT (curr
== NULL
|| time_of_event
< curr
->time_of_event
);
458 new_event
->next
= curr
;
460 new_event
->time_of_event
= time_of_event
;
462 /* adjust the time until the first event */
463 update_time_from_event (sd
);
468 #if EXTERN_SIM_EVENTS_P
470 sim_events_schedule (SIM_DESC sd
,
472 sim_event_handler
*handler
,
475 return sim_events_schedule_tracef (sd
, delta_time
, handler
, data
, NULL
);
480 #if EXTERN_SIM_EVENTS_P
482 sim_events_schedule_tracef (SIM_DESC sd
,
484 sim_event_handler
*handler
,
489 sim_event
*new_event
;
492 new_event
= sim_events_schedule_vtracef (sd
, delta_time
, handler
, data
, fmt
, ap
);
499 #if EXTERN_SIM_EVENTS_P
501 sim_events_schedule_vtracef (SIM_DESC sd
,
503 sim_event_handler
*handler
,
508 sim_event
*new_event
= sim_events_zalloc (sd
);
509 new_event
->data
= data
;
510 new_event
->handler
= handler
;
511 new_event
->watching
= watch_timer
;
512 if (fmt
== NULL
|| !STRACE_EVENTS_P (sd
) || vasprintf (&new_event
->trace
, fmt
, ap
) < 0)
513 new_event
->trace
= NULL
;
514 insert_sim_event (sd
, new_event
, delta_time
);
516 "event scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
517 (long)sim_events_time (sd
),
519 (long)new_event
->time_of_event
,
520 (long)new_event
->handler
,
521 (long)new_event
->data
,
522 (new_event
->trace
!= NULL
) ? ", " : "",
523 (new_event
->trace
!= NULL
) ? new_event
->trace
: ""));
529 #if EXTERN_SIM_EVENTS_P
531 sim_events_schedule_after_signal (SIM_DESC sd
,
533 sim_event_handler
*handler
,
536 sim_events
*events
= STATE_EVENTS (sd
);
537 sim_event
*new_event
;
538 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
542 sigfillset (&new_mask
);
543 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
546 /* allocate an event entry from the signal buffer */
547 new_event
= &events
->held
[events
->nr_held
];
549 if (events
->nr_held
> MAX_NR_SIGNAL_SIM_EVENTS
)
551 sim_engine_abort (NULL
, NULL
, NULL_CIA
,
552 "sim_events_schedule_after_signal - buffer overflow");
555 new_event
->data
= data
;
556 new_event
->handler
= handler
;
557 new_event
->time_of_event
= delta_time
; /* work it out later */
558 new_event
->next
= NULL
;
560 events
->work_pending
= 1; /* notify main process */
562 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
564 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
568 "signal scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
569 (long)sim_events_time (sd
),
571 (long)new_event
->time_of_event
,
572 (long)new_event
->handler
,
573 (long)new_event
->data
));
578 #if EXTERN_SIM_EVENTS_P
580 sim_events_watch_clock (SIM_DESC sd
,
581 unsigned delta_ms_time
,
582 sim_event_handler
*handler
,
585 sim_events
*events
= STATE_EVENTS (sd
);
586 sim_event
*new_event
= sim_events_zalloc (sd
);
588 new_event
->watching
= watch_clock
;
590 new_event
->data
= data
;
591 new_event
->handler
= handler
;
593 if (events
->resume_wallclock
== 0)
594 new_event
->wallclock
= (events
->elapsed_wallclock
+ delta_ms_time
);
596 new_event
->wallclock
= (events
->elapsed_wallclock
597 + sim_elapsed_time_since (events
->resume_wallclock
)
600 new_event
->next
= events
->watchpoints
;
601 events
->watchpoints
= new_event
;
602 events
->work_pending
= 1;
604 "event watching clock at %ld - tag 0x%lx - wallclock %ld, handler 0x%lx, data 0x%lx\n",
605 (long)sim_events_time (sd
),
607 (long)new_event
->wallclock
,
608 (long)new_event
->handler
,
609 (long)new_event
->data
));
615 #if EXTERN_SIM_EVENTS_P
617 sim_events_watch_pc (SIM_DESC sd
,
621 sim_event_handler
*handler
,
624 sim_events
*events
= STATE_EVENTS (sd
);
625 sim_event
*new_event
= sim_events_zalloc (sd
);
627 new_event
->watching
= watch_pc
;
629 new_event
->data
= data
;
630 new_event
->handler
= handler
;
633 new_event
->lb64
= lb
;
635 new_event
->ub64
= ub
;
636 new_event
->is_within
= (is_within
!= 0);
638 new_event
->next
= events
->watchpoints
;
639 events
->watchpoints
= new_event
;
640 events
->work_pending
= 1;
642 "event watching pc at %ld - tag 0x%lx - pc 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
643 (long)sim_events_time (sd
),
647 (long)new_event
->handler
,
648 (long)new_event
->data
));
654 #if EXTERN_SIM_EVENTS_P
656 sim_events_watch_sim (SIM_DESC sd
,
659 enum bfd_endian byte_order
,
663 sim_event_handler
*handler
,
666 sim_events
*events
= STATE_EVENTS (sd
);
667 sim_event
*new_event
= sim_events_zalloc (sd
);
671 case BFD_ENDIAN_UNKNOWN
:
674 case 1: new_event
->watching
= watch_sim_host_1
; break;
675 case 2: new_event
->watching
= watch_sim_host_2
; break;
676 case 4: new_event
->watching
= watch_sim_host_4
; break;
677 case 8: new_event
->watching
= watch_sim_host_8
; break;
678 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
684 case 1: new_event
->watching
= watch_sim_be_1
; break;
685 case 2: new_event
->watching
= watch_sim_be_2
; break;
686 case 4: new_event
->watching
= watch_sim_be_4
; break;
687 case 8: new_event
->watching
= watch_sim_be_8
; break;
688 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
691 case BFD_ENDIAN_LITTLE
:
694 case 1: new_event
->watching
= watch_sim_le_1
; break;
695 case 2: new_event
->watching
= watch_sim_le_2
; break;
696 case 4: new_event
->watching
= watch_sim_le_4
; break;
697 case 8: new_event
->watching
= watch_sim_le_8
; break;
698 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
702 sim_io_error (sd
, "sim_events_watch_sim - invalid byte order");
705 new_event
->data
= data
;
706 new_event
->handler
= handler
;
708 new_event
->host_addr
= host_addr
;
710 new_event
->lb64
= lb
;
712 new_event
->ub64
= ub
;
713 new_event
->is_within
= (is_within
!= 0);
715 new_event
->next
= events
->watchpoints
;
716 events
->watchpoints
= new_event
;
717 events
->work_pending
= 1;
719 "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
720 (long)sim_events_time (sd
),
722 (long)new_event
->host_addr
,
725 (long)new_event
->handler
,
726 (long)new_event
->data
));
732 #if EXTERN_SIM_EVENTS_P
734 sim_events_watch_core (SIM_DESC sd
,
735 address_word core_addr
,
738 enum bfd_endian byte_order
,
742 sim_event_handler
*handler
,
745 sim_events
*events
= STATE_EVENTS (sd
);
746 sim_event
*new_event
= sim_events_zalloc (sd
);
750 case BFD_ENDIAN_UNKNOWN
:
753 case 1: new_event
->watching
= watch_core_targ_1
; break;
754 case 2: new_event
->watching
= watch_core_targ_2
; break;
755 case 4: new_event
->watching
= watch_core_targ_4
; break;
756 case 8: new_event
->watching
= watch_core_targ_8
; break;
757 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
763 case 1: new_event
->watching
= watch_core_be_1
; break;
764 case 2: new_event
->watching
= watch_core_be_2
; break;
765 case 4: new_event
->watching
= watch_core_be_4
; break;
766 case 8: new_event
->watching
= watch_core_be_8
; break;
767 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
770 case BFD_ENDIAN_LITTLE
:
773 case 1: new_event
->watching
= watch_core_le_1
; break;
774 case 2: new_event
->watching
= watch_core_le_2
; break;
775 case 4: new_event
->watching
= watch_core_le_4
; break;
776 case 8: new_event
->watching
= watch_core_le_8
; break;
777 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
781 sim_io_error (sd
, "sim_events_watch_core - invalid byte order");
784 new_event
->data
= data
;
785 new_event
->handler
= handler
;
787 new_event
->core_addr
= core_addr
;
788 new_event
->core_map
= core_map
;
790 new_event
->lb64
= lb
;
792 new_event
->ub64
= ub
;
793 new_event
->is_within
= (is_within
!= 0);
795 new_event
->next
= events
->watchpoints
;
796 events
->watchpoints
= new_event
;
797 events
->work_pending
= 1;
799 "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
800 (long)sim_events_time (sd
),
802 (long)new_event
->host_addr
,
805 (long)new_event
->handler
,
806 (long)new_event
->data
));
812 #if EXTERN_SIM_EVENTS_P
814 sim_events_deschedule (SIM_DESC sd
,
815 sim_event
*event_to_remove
)
817 sim_events
*events
= STATE_EVENTS (sd
);
818 sim_event
*to_remove
= (sim_event
*)event_to_remove
;
819 if (event_to_remove
!= NULL
)
821 sim_event
**queue
= NULL
;
822 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
824 sim_event
**ptr_to_current
;
825 for (ptr_to_current
= queue
;
826 *ptr_to_current
!= NULL
&& *ptr_to_current
!= to_remove
;
827 ptr_to_current
= &(*ptr_to_current
)->next
);
828 if (*ptr_to_current
== to_remove
)
830 sim_event
*dead
= *ptr_to_current
;
831 *ptr_to_current
= dead
->next
;
833 "event/watch descheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
834 (long) sim_events_time (sd
),
835 (long) event_to_remove
,
836 (long) dead
->time_of_event
,
837 (long) dead
->handler
,
839 (dead
->trace
!= NULL
) ? ", " : "",
840 (dead
->trace
!= NULL
) ? dead
->trace
: ""));
841 sim_events_free (sd
, dead
);
842 update_time_from_event (sd
);
843 SIM_ASSERT ((events
->time_from_event
>= 0) == (events
->queue
!= NULL
));
849 "event/watch descheduled at %ld - tag 0x%lx - not found\n",
850 (long) sim_events_time (sd
),
851 (long) event_to_remove
));
856 STATIC_INLINE_SIM_EVENTS\
858 sim_watch_valid (SIM_DESC sd
,
861 switch (to_do
->watching
)
864 #define WATCH_CORE(N,OP,EXT) \
866 unsigned_##N word = 0; \
867 int nr_read = sim_core_read_buffer (sd, NULL, to_do->core_map, &word, \
868 to_do->core_addr, sizeof (word)); \
870 ok = (nr_read == sizeof (unsigned_##N) \
871 && (to_do->is_within \
872 == (word >= to_do->lb##EXT \
873 && word <= to_do->ub##EXT)));
875 case watch_core_targ_1
:
877 WATCH_CORE (1, T2H
,);
880 case watch_core_targ_2
:
882 WATCH_CORE (2, T2H
,);
885 case watch_core_targ_4
:
887 WATCH_CORE (4, T2H
,);
890 case watch_core_targ_8
:
892 WATCH_CORE (8, T2H
,64);
896 case watch_core_be_1
:
898 WATCH_CORE (1, BE2H
,);
901 case watch_core_be_2
:
903 WATCH_CORE (2, BE2H
,);
906 case watch_core_be_4
:
908 WATCH_CORE (4, BE2H
,);
911 case watch_core_be_8
:
913 WATCH_CORE (8, BE2H
,64);
917 case watch_core_le_1
:
919 WATCH_CORE (1, LE2H
,);
922 case watch_core_le_2
:
924 WATCH_CORE (2, LE2H
,);
927 case watch_core_le_4
:
929 WATCH_CORE (4, LE2H
,);
932 case watch_core_le_8
:
934 WATCH_CORE (8, LE2H
,64);
939 #define WATCH_SIM(N,OP,EXT) \
941 unsigned_##N word = *(unsigned_##N*)to_do->host_addr; \
943 ok = (to_do->is_within \
944 == (word >= to_do->lb##EXT \
945 && word <= to_do->ub##EXT));
947 case watch_sim_host_1
:
949 WATCH_SIM (1, word
= ,);
952 case watch_sim_host_2
:
954 WATCH_SIM (2, word
= ,);
957 case watch_sim_host_4
:
959 WATCH_SIM (4, word
= ,);
962 case watch_sim_host_8
:
964 WATCH_SIM (8, word
= ,64);
970 WATCH_SIM (1, BE2H
,);
975 WATCH_SIM (2, BE2H
,);
980 WATCH_SIM (4, BE2H
,);
985 WATCH_SIM (8, BE2H
,64);
991 WATCH_SIM (1, LE2H
,);
996 WATCH_SIM (1, LE2H
,);
1001 WATCH_SIM (1, LE2H
,);
1004 case watch_sim_le_8
:
1006 WATCH_SIM (1, LE2H
,64);
1015 for (c
= 0; c
< MAX_NR_PROCESSORS
; ++c
)
1017 sim_cpu
*cpu
= STATE_CPU (sd
, c
);
1018 sim_cia cia
= sim_pc_get (cpu
);
1020 if (to_do
->is_within
== (cia
>= to_do
->lb64
&& cia
<= to_do
->ub64
))
1026 case watch_clock
: /* wallclock */
1028 unsigned long elapsed_time
= sim_events_elapsed_time (sd
);
1029 return (elapsed_time
>= to_do
->wallclock
);
1033 sim_io_error (sd
, "sim_watch_valid - bad switch");
1043 sim_events_tick (SIM_DESC sd
)
1045 sim_events
*events
= STATE_EVENTS (sd
);
1047 /* this should only be called after the previous ticks have been
1050 /* Advance the time but *only* if there is nothing to process */
1051 if (events
->work_pending
1052 || events
->time_from_event
== 0)
1054 events
->nr_ticks_to_process
+= 1;
1059 events
->time_from_event
-= 1;
1067 sim_events_tickn (SIM_DESC sd
,
1070 sim_events
*events
= STATE_EVENTS (sd
);
1073 /* this should only be called after the previous ticks have been
1076 /* Advance the time but *only* if there is nothing to process */
1077 if (events
->work_pending
|| events
->time_from_event
< n
)
1079 events
->nr_ticks_to_process
+= n
;
1084 events
->time_from_event
-= n
;
1092 sim_events_slip (SIM_DESC sd
,
1095 sim_events
*events
= STATE_EVENTS (sd
);
1096 SIM_ASSERT (slip
> 0);
1098 /* Flag a ready event with work_pending instead of number of ticks
1099 to process so that the time continues to be correct */
1100 if (events
->time_from_event
< slip
)
1102 events
->work_pending
= 1;
1104 events
->time_from_event
-= slip
;
1110 sim_events_preprocess (SIM_DESC sd
,
1111 int events_were_last
,
1112 int events_were_next
)
1114 sim_events
*events
= STATE_EVENTS (sd
);
1115 if (events_were_last
)
1117 /* Halted part way through event processing */
1118 ASSERT (events
->nr_ticks_to_process
!= 0);
1119 /* The external world can't tell if the event that stopped the
1120 simulator was the last event to process. */
1121 ASSERT (events_were_next
);
1122 sim_events_process (sd
);
1124 else if (events_were_next
)
1126 /* Halted by the last processor */
1127 if (sim_events_tick (sd
))
1128 sim_events_process (sd
);
1135 sim_events_process (SIM_DESC sd
)
1137 sim_events
*events
= STATE_EVENTS (sd
);
1138 signed64 event_time
= sim_events_time (sd
);
1140 /* Clear work_pending before checking nr_held. Clearing
1141 work_pending after nr_held (with out a lock could loose an
1143 events
->work_pending
= 0;
1145 /* move any events that were asynchronously queued by any signal
1146 handlers onto the real event queue. */
1147 if (events
->nr_held
> 0)
1151 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1155 sigfillset (&new_mask
);
1156 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
1159 for (i
= 0; i
< events
->nr_held
; i
++)
1161 sim_event
*entry
= &events
->held
[i
];
1162 sim_events_schedule (sd
,
1163 entry
->time_of_event
,
1167 events
->nr_held
= 0;
1169 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1171 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
1176 /* Process any watchpoints. Be careful to allow a watchpoint to
1177 appear/disappear under our feet.
1178 To ensure that watchpoints are processed only once per cycle,
1179 they are moved onto a watched queue, this returned to the
1180 watchpoint queue when all queue processing has been
1182 while (events
->watchpoints
!= NULL
)
1184 sim_event
*to_do
= events
->watchpoints
;
1185 events
->watchpoints
= to_do
->next
;
1186 if (sim_watch_valid (sd
, to_do
))
1188 sim_event_handler
*handler
= to_do
->handler
;
1189 void *data
= to_do
->data
;
1191 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
1196 (to_do
->trace
!= NULL
) ? ", " : "",
1197 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1198 sim_events_free (sd
, to_do
);
1203 to_do
->next
= events
->watchedpoints
;
1204 events
->watchedpoints
= to_do
;
1208 /* consume all events for this or earlier times. Be careful to
1209 allow an event to appear/disappear under our feet */
1210 while (events
->queue
->time_of_event
<
1211 (event_time
+ events
->nr_ticks_to_process
))
1213 sim_event
*to_do
= events
->queue
;
1214 sim_event_handler
*handler
= to_do
->handler
;
1215 void *data
= to_do
->data
;
1216 events
->queue
= to_do
->next
;
1217 update_time_from_event (sd
);
1219 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
1224 (to_do
->trace
!= NULL
) ? ", " : "",
1225 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1226 sim_events_free (sd
, to_do
);
1230 /* put things back where they belong ready for the next iteration */
1231 events
->watchpoints
= events
->watchedpoints
;
1232 events
->watchedpoints
= NULL
;
1233 if (events
->watchpoints
!= NULL
)
1234 events
->work_pending
= 1;
1236 /* advance the time */
1237 SIM_ASSERT (events
->time_from_event
>= events
->nr_ticks_to_process
);
1238 SIM_ASSERT (events
->queue
!= NULL
); /* always poll event */
1239 events
->time_from_event
-= events
->nr_ticks_to_process
;
1241 /* this round of processing complete */
1242 events
->nr_ticks_to_process
= 0;