Passify GCC. Convert 0x0LL to something more portable in the FP code.
[binutils-gdb.git] / sim / common / sim-events.c
1 /* This file is part of the program psim.
2
3 Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20
21
22 #ifndef _SIM_EVENTS_C_
23 #define _SIM_EVENTS_C_
24
25 #include "sim-main.h"
26 #include "sim-assert.h"
27
28 #ifdef HAVE_STRING_H
29 #include <string.h>
30 #else
31 #ifdef HAVE_STRINGS_H
32 #include <strings.h>
33 #endif
34 #endif
35
36 #include <signal.h>
37
38
39 typedef enum {
40 watch_invalid,
41
42 /* core - target byte order */
43 watch_core_targ_1,
44 watch_core_targ_2,
45 watch_core_targ_4,
46 watch_core_targ_8,
47 /* core - big-endian */
48 watch_core_be_1,
49 watch_core_be_2,
50 watch_core_be_4,
51 watch_core_be_8,
52 /* core - little-endian */
53 watch_core_le_1,
54 watch_core_le_2,
55 watch_core_le_4,
56 watch_core_le_8,
57
58 /* sim - host byte order */
59 watch_sim_host_1,
60 watch_sim_host_2,
61 watch_sim_host_4,
62 watch_sim_host_8,
63 /* sim - big-endian */
64 watch_sim_be_1,
65 watch_sim_be_2,
66 watch_sim_be_4,
67 watch_sim_be_8,
68 /* sim - little-endian */
69 watch_sim_le_1,
70 watch_sim_le_2,
71 watch_sim_le_4,
72 watch_sim_le_8,
73
74 /* wallclock */
75 watch_clock,
76
77 /* timer */
78 watch_timer,
79 } sim_event_watchpoints;
80
81
82 struct _sim_event {
83 sim_event_watchpoints watching;
84 void *data;
85 sim_event_handler *handler;
86 /* timer event */
87 signed64 time_of_event;
88 /* watch wallclock event */
89 unsigned wallclock;
90 /* watch core address */
91 address_word core_addr;
92 sim_core_maps core_map;
93 /* watch sim addr */
94 void *host_addr;
95 /* watch core/sim range */
96 int is_within; /* 0/1 */
97 unsigned ub;
98 unsigned lb;
99 unsigned64 ub64;
100 unsigned64 lb64;
101 /* list */
102 sim_event *next;
103 };
104
105
106 /* The event queue maintains a single absolute time using two
107 variables.
108
109 TIME_OF_EVENT: this holds the time at which the next event is ment
110 to occure. If no next event it will hold the time of the last
111 event.
112
113 TIME_FROM_EVENT: The current distance from TIME_OF_EVENT. If an
114 event is pending, this will be positive. If no future event is
115 pending (eg when poll-event is being processed) this will be
116 negative. This variable is decremented once for each iteration of
117 a clock cycle.
118
119 Initially, the clock is started at time one (0) with TIME_OF_EVENT
120 == 0 and TIME_FROM_EVENT == 0.
121
122 Clearly there is a bug in that this code assumes that the absolute
123 time counter will never become greater than 2^62.
124
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
128 16 000. */
129
130
131 #if !defined (SIM_EVENTS_POLL_RATE)
132 #define SIM_EVENTS_POLL_RATE 0x100000
133 #endif
134
135
136 #define _ETRACE sd
137
138 #undef ETRACE
139 #define ETRACE(ARGS) \
140 do \
141 { \
142 if (WITH_TRACE) \
143 { \
144 if (STATE_EVENTS (sd)->trace) \
145 { \
146 const char *file; \
147 SIM_FILTER_PATH (file, __FILE__); \
148 sim_io_printf (sd, "%s:%d: ", file, __LINE__); \
149 sim_io_printf ARGS; \
150 } \
151 } \
152 } \
153 while (0)
154
155
156 /* event queue iterator - don't iterate over the held queue. */
157
158 STATIC_INLINE_SIM_EVENTS\
159 (sim_event **)
160 next_event_queue (SIM_DESC sd,
161 sim_event **queue)
162 {
163 if (queue == NULL)
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)
170 return NULL;
171 else
172 sim_io_error (sd, "next_event_queue - bad queue");
173 return NULL;
174 }
175
176
177 STATIC_INLINE_SIM_EVENTS\
178 (void)
179 sim_events_poll (SIM_DESC sd,
180 void *data)
181 {
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);
185 }
186
187
188 /* "events" module install handler.
189 This is called via sim_module_install to install the "events" subsystem
190 into the simulator. */
191
192 EXTERN_SIM_EVENTS\
193 (SIM_RC)
194 sim_events_install (SIM_DESC sd)
195 {
196 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
197 sim_module_add_uninstall_fn (sd, sim_events_uninstall);
198 sim_module_add_init_fn (sd, sim_events_init);
199 return SIM_RC_OK;
200 }
201
202
203 /* Uninstall the "events" subsystem from the simulator. */
204
205 EXTERN_SIM_EVENTS\
206 (void)
207 sim_events_uninstall (SIM_DESC sd)
208 {
209 /* FIXME: free buffers, etc. */
210 }
211
212
213 /* malloc/free */
214
215 STATIC_INLINE_SIM_EVENTS\
216 (sim_event *)
217 sim_events_zalloc (SIM_DESC sd)
218 {
219 sim_events *events = STATE_EVENTS (sd);
220 sim_event *new = events->free_list;
221 if (new != NULL)
222 {
223 events->free_list = new->next;
224 memset (new, 0, sizeof (*new));
225 }
226 else
227 {
228 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
229 /*-LOCK-*/
230 sigset_t old_mask;
231 sigset_t new_mask;
232 sigfillset(&new_mask);
233 sigprocmask (SIG_SETMASK, &new_mask, &old_mask);
234 #endif
235 new = ZALLOC (sim_event);
236 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
237 /*-UNLOCK-*/
238 sigprocmask (SIG_SETMASK, &old_mask, NULL);
239 #endif
240 }
241 return new;
242 }
243
244 STATIC_INLINE_SIM_EVENTS\
245 (void)
246 sim_events_free (SIM_DESC sd,
247 sim_event *dead)
248 {
249 sim_events *events = STATE_EVENTS (sd);
250 dead->next = events->free_list;
251 events->free_list = dead;
252 }
253
254
255 /* Initialize the simulator event manager */
256
257 EXTERN_SIM_EVENTS\
258 (SIM_RC)
259 sim_events_init (SIM_DESC sd)
260 {
261 sim_events *events = STATE_EVENTS (sd);
262
263 /* drain the interrupt queue */
264 events->nr_held = 0;
265 if (events->held == NULL)
266 events->held = zalloc (sizeof (sim_event) * MAX_NR_SIGNAL_SIM_EVENTS);
267
268 /* drain the normal queues */
269 {
270 sim_event **queue = NULL;
271 while ((queue = next_event_queue (sd, queue)) != NULL)
272 {
273 if (queue == NULL) break;
274 while (*queue != NULL)
275 {
276 sim_event *dead = *queue;
277 *queue = dead->next;
278 sim_events_free (sd, dead);
279 }
280 *queue = NULL;
281 }
282 }
283
284 /* wind time back to zero */
285 events->nr_ticks_to_process = 1; /* start by doing queue */
286 events->time_of_event = 0;
287 events->time_from_event = 0;
288 events->initial_wallclock = sim_elapsed_time_get ();
289
290 /* schedule our initial counter event */
291 sim_events_schedule (sd, 0, sim_events_poll, sd);
292
293 /* from now on, except when the large-int event is being processed
294 the event queue is non empty */
295 SIM_ASSERT (events->queue != NULL);
296
297 return SIM_RC_OK;
298 }
299
300
301 INLINE_SIM_EVENTS\
302 (signed64)
303 sim_events_time (SIM_DESC sd)
304 {
305 sim_events *events = STATE_EVENTS (sd);
306 return events->time_of_event - events->time_from_event;
307 }
308
309
310 STATIC_INLINE_SIM_EVENTS\
311 (void)
312 update_time_from_event (SIM_DESC sd)
313 {
314 sim_events *events = STATE_EVENTS (sd);
315 signed64 current_time = sim_events_time (sd);
316 if (events->queue != NULL)
317 {
318 events->time_from_event = (events->queue->time_of_event - current_time);
319 events->time_of_event = events->queue->time_of_event;
320 }
321 else
322 {
323 events->time_of_event = current_time - 1;
324 events->time_from_event = -1;
325 }
326 SIM_ASSERT (current_time == sim_events_time (sd));
327 SIM_ASSERT ((events->time_from_event >= 0) == (events->queue != NULL));
328 }
329
330
331 STATIC_INLINE_SIM_EVENTS\
332 (void)
333 insert_sim_event (SIM_DESC sd,
334 sim_event *new_event,
335 signed64 delta)
336 {
337 sim_events *events = STATE_EVENTS (sd);
338 sim_event *curr;
339 sim_event **prev;
340 signed64 time_of_event;
341
342 if (delta < 0)
343 sim_io_error (sd, "what is past is past!\n");
344
345 /* compute when the event should occure */
346 time_of_event = sim_events_time (sd) + delta;
347
348 /* find the queue insertion point - things are time ordered */
349 prev = &events->queue;
350 curr = events->queue;
351 while (curr != NULL && time_of_event >= curr->time_of_event)
352 {
353 SIM_ASSERT (curr->next == NULL
354 || curr->time_of_event <= curr->next->time_of_event);
355 prev = &curr->next;
356 curr = curr->next;
357 }
358 SIM_ASSERT (curr == NULL || time_of_event < curr->time_of_event);
359
360 /* insert it */
361 new_event->next = curr;
362 *prev = new_event;
363 new_event->time_of_event = time_of_event;
364
365 /* adjust the time until the first event */
366 update_time_from_event (sd);
367 }
368
369
370 EXTERN_SIM_EVENTS\
371 (sim_event *)
372 sim_events_schedule (SIM_DESC sd,
373 signed64 delta_time,
374 sim_event_handler *handler,
375 void *data)
376 {
377 sim_event *new_event = sim_events_zalloc (sd);
378 new_event->data = data;
379 new_event->handler = handler;
380 new_event->watching = watch_timer;
381 insert_sim_event(sd, new_event, delta_time);
382 ETRACE((_ETRACE,
383 "event scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
384 (long)sim_events_time(sd),
385 (long)new_event,
386 (long)new_event->time_of_event,
387 (long)new_event->handler,
388 (long)new_event->data));
389 return new_event;
390 }
391
392
393 EXTERN_SIM_EVENTS\
394 (void)
395 sim_events_schedule_after_signal (SIM_DESC sd,
396 signed64 delta_time,
397 sim_event_handler *handler,
398 void *data)
399 {
400 sim_events *events = STATE_EVENTS (sd);
401 sim_event *new_event;
402 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
403 /*-LOCK-*/
404 sigset_t old_mask;
405 sigset_t new_mask;
406 sigfillset(&new_mask);
407 sigprocmask (SIG_SETMASK, &new_mask, &old_mask);
408 #endif
409
410 /* allocate an event entry from the signal buffer */
411 new_event = &events->held [events->nr_held];
412 events->nr_held ++;
413 if (events->nr_held > MAX_NR_SIGNAL_SIM_EVENTS)
414 {
415 sim_engine_abort (NULL, NULL, NULL_CIA,
416 "sim_events_schedule_after_signal - buffer oveflow");
417 }
418
419 new_event->data = data;
420 new_event->handler = handler;
421 new_event->time_of_event = delta_time; /* work it out later */
422 new_event->next = NULL;
423
424 events->work_pending = 1; /* notify main process */
425
426 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
427 /*-UNLOCK-*/
428 sigprocmask (SIG_SETMASK, &old_mask, NULL);
429 #endif
430
431 ETRACE ((_ETRACE,
432 "signal scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
433 (long)sim_events_time(sd),
434 (long)new_event,
435 (long)new_event->time_of_event,
436 (long)new_event->handler,
437 (long)new_event->data));
438 }
439
440
441 EXTERN_SIM_EVENTS\
442 (sim_event *)
443 sim_events_watch_clock (SIM_DESC sd,
444 unsigned delta_ms_time,
445 sim_event_handler *handler,
446 void *data)
447 {
448 sim_events *events = STATE_EVENTS (sd);
449 sim_event *new_event = sim_events_zalloc (sd);
450 /* type */
451 new_event->watching = watch_clock;
452 /* handler */
453 new_event->data = data;
454 new_event->handler = handler;
455 /* data */
456 new_event->wallclock = (sim_elapsed_time_since (events->initial_wallclock) + delta_ms_time);
457 /* insert */
458 new_event->next = events->watchpoints;
459 events->watchpoints = new_event;
460 events->work_pending = 1;
461 ETRACE ((_ETRACE,
462 "event watching clock at %ld - tag 0x%lx - wallclock %ld, handler 0x%lx, data 0x%lx\n",
463 (long)sim_events_time (sd),
464 (long)new_event,
465 (long)new_event->wallclock,
466 (long)new_event->handler,
467 (long)new_event->data));
468 return new_event;
469 }
470
471
472 EXTERN_SIM_EVENTS\
473 (sim_event *)
474 sim_events_watch_sim (SIM_DESC sd,
475 void *host_addr,
476 int nr_bytes,
477 int byte_order,
478 int is_within,
479 unsigned64 lb,
480 unsigned64 ub,
481 sim_event_handler *handler,
482 void *data)
483 {
484 sim_events *events = STATE_EVENTS (sd);
485 sim_event *new_event = sim_events_zalloc (sd);
486 /* type */
487 switch (byte_order)
488 {
489 case 0:
490 switch (nr_bytes)
491 {
492 case 1: new_event->watching = watch_sim_host_1; break;
493 case 2: new_event->watching = watch_sim_host_2; break;
494 case 4: new_event->watching = watch_sim_host_4; break;
495 case 8: new_event->watching = watch_sim_host_8; break;
496 default: sim_io_error (sd, "sim_events_watch_sim - invalid nr bytes");
497 }
498 break;
499 case BIG_ENDIAN:
500 switch (nr_bytes)
501 {
502 case 1: new_event->watching = watch_sim_be_1; break;
503 case 2: new_event->watching = watch_sim_be_2; break;
504 case 4: new_event->watching = watch_sim_be_4; break;
505 case 8: new_event->watching = watch_sim_be_8; break;
506 default: sim_io_error (sd, "sim_events_watch_sim - invalid nr bytes");
507 }
508 break;
509 case LITTLE_ENDIAN:
510 switch (nr_bytes)
511 {
512 case 1: new_event->watching = watch_sim_le_1; break;
513 case 2: new_event->watching = watch_sim_le_2; break;
514 case 4: new_event->watching = watch_sim_le_4; break;
515 case 8: new_event->watching = watch_sim_le_8; break;
516 default: sim_io_error (sd, "sim_events_watch_sim - invalid nr bytes");
517 }
518 break;
519 default:
520 sim_io_error (sd, "sim_events_watch_sim - invalid byte order");
521 }
522 /* handler */
523 new_event->data = data;
524 new_event->handler = handler;
525 /* data */
526 new_event->host_addr = host_addr;
527 new_event->lb = lb;
528 new_event->lb64 = lb;
529 new_event->ub = ub;
530 new_event->ub64 = ub;
531 new_event->is_within = (is_within != 0);
532 /* insert */
533 new_event->next = events->watchpoints;
534 events->watchpoints = new_event;
535 events->work_pending = 1;
536 ETRACE ((_ETRACE,
537 "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
538 (long)sim_events_time (sd),
539 (long)new_event,
540 (long)new_event->host_addr,
541 (long)new_event->lb,
542 (long)new_event->ub,
543 (long)new_event->handler,
544 (long)new_event->data));
545 return new_event;
546 }
547
548
549 EXTERN_SIM_EVENTS\
550 (sim_event *)
551 sim_events_watch_core (SIM_DESC sd,
552 address_word core_addr,
553 sim_core_maps core_map,
554 int nr_bytes,
555 int byte_order,
556 int is_within,
557 unsigned64 lb,
558 unsigned64 ub,
559 sim_event_handler *handler,
560 void *data)
561 {
562 sim_events *events = STATE_EVENTS (sd);
563 sim_event *new_event = sim_events_zalloc (sd);
564 /* type */
565 switch (byte_order)
566 {
567 case 0:
568 switch (nr_bytes)
569 {
570 case 1: new_event->watching = watch_core_targ_1; break;
571 case 2: new_event->watching = watch_core_targ_2; break;
572 case 4: new_event->watching = watch_core_targ_4; break;
573 case 8: new_event->watching = watch_core_targ_8; break;
574 default: sim_io_error (sd, "sim_events_watch_core - invalid nr bytes");
575 }
576 break;
577 case BIG_ENDIAN:
578 switch (nr_bytes)
579 {
580 case 1: new_event->watching = watch_core_be_1; break;
581 case 2: new_event->watching = watch_core_be_2; break;
582 case 4: new_event->watching = watch_core_be_4; break;
583 case 8: new_event->watching = watch_core_be_8; break;
584 default: sim_io_error (sd, "sim_events_watch_core - invalid nr bytes");
585 }
586 break;
587 case LITTLE_ENDIAN:
588 switch (nr_bytes)
589 {
590 case 1: new_event->watching = watch_core_le_1; break;
591 case 2: new_event->watching = watch_core_le_2; break;
592 case 4: new_event->watching = watch_core_le_4; break;
593 case 8: new_event->watching = watch_core_le_8; break;
594 default: sim_io_error (sd, "sim_events_watch_core - invalid nr bytes");
595 }
596 break;
597 default:
598 sim_io_error (sd, "sim_events_watch_core - invalid byte order");
599 }
600 /* handler */
601 new_event->data = data;
602 new_event->handler = handler;
603 /* data */
604 new_event->core_addr = core_addr;
605 new_event->core_map = core_map;
606 new_event->lb = lb;
607 new_event->lb64 = lb;
608 new_event->ub = ub;
609 new_event->ub64 = ub;
610 new_event->is_within = (is_within != 0);
611 /* insert */
612 new_event->next = events->watchpoints;
613 events->watchpoints = new_event;
614 events->work_pending = 1;
615 ETRACE ((_ETRACE,
616 "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
617 (long)sim_events_time (sd),
618 (long)new_event,
619 (long)new_event->host_addr,
620 (long)new_event->lb,
621 (long)new_event->ub,
622 (long)new_event->handler,
623 (long)new_event->data));
624 return new_event;
625 }
626
627
628 EXTERN_SIM_EVENTS\
629 (void)
630 sim_events_deschedule (SIM_DESC sd,
631 sim_event *event_to_remove)
632 {
633 sim_events *events = STATE_EVENTS (sd);
634 sim_event *to_remove = (sim_event*)event_to_remove;
635 SIM_ASSERT ((events->time_from_event >= 0) == (events->queue != NULL));
636 if (event_to_remove != NULL)
637 {
638 sim_event **queue = NULL;
639 while ((queue = next_event_queue (sd, queue)) != NULL)
640 {
641 sim_event **ptr_to_current;
642 for (ptr_to_current = queue;
643 *ptr_to_current != NULL && *ptr_to_current != to_remove;
644 ptr_to_current = &(*ptr_to_current)->next);
645 if (*ptr_to_current == to_remove)
646 {
647 sim_event *dead = *ptr_to_current;
648 *ptr_to_current = dead->next;
649 ETRACE ((_ETRACE,
650 "event/watch descheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
651 (long) sim_events_time (sd),
652 (long) event_to_remove,
653 (long) dead->time_of_event,
654 (long) dead->handler,
655 (long) dead->data));
656 sim_events_free (sd, dead);
657 update_time_from_event (sd);
658 SIM_ASSERT ((events->time_from_event >= 0) == (events->queue != NULL));
659 return;
660 }
661 }
662 }
663 ETRACE ((_ETRACE,
664 "event/watch descheduled at %ld - tag 0x%lx - not found\n",
665 (long) sim_events_time (sd),
666 (long) event_to_remove));
667 }
668
669
670 STATIC_INLINE_SIM_EVENTS\
671 (int)
672 sim_watch_valid (SIM_DESC sd,
673 sim_event *to_do)
674 {
675 switch (to_do->watching)
676 {
677
678 #define WATCH_CORE(N,OP,EXT) \
679 int ok; \
680 unsigned_##N word = 0; \
681 int nr_read = sim_core_read_buffer (sd, NULL, to_do->core_map, &word, \
682 to_do->core_addr, sizeof (word)); \
683 OP (word); \
684 ok = (nr_read == sizeof (unsigned_##N) \
685 && (to_do->is_within \
686 == (word >= to_do->lb##EXT \
687 && word <= to_do->ub##EXT)));
688
689 case watch_core_targ_1:
690 {
691 WATCH_CORE (1, T2H,);
692 return ok;
693 }
694 case watch_core_targ_2:
695 {
696 WATCH_CORE (2, T2H,);
697 return ok;
698 }
699 case watch_core_targ_4:
700 {
701 WATCH_CORE (4, T2H,);
702 return ok;
703 }
704 case watch_core_targ_8:
705 {
706 WATCH_CORE (8, T2H,64);
707 return ok;
708 }
709
710 case watch_core_be_1:
711 {
712 WATCH_CORE (1, BE2H,);
713 return ok;
714 }
715 case watch_core_be_2:
716 {
717 WATCH_CORE (2, BE2H,);
718 return ok;
719 }
720 case watch_core_be_4:
721 {
722 WATCH_CORE (4, BE2H,);
723 return ok;
724 }
725 case watch_core_be_8:
726 {
727 WATCH_CORE (8, BE2H,64);
728 return ok;
729 }
730
731 case watch_core_le_1:
732 {
733 WATCH_CORE (1, LE2H,);
734 return ok;
735 }
736 case watch_core_le_2:
737 {
738 WATCH_CORE (2, LE2H,);
739 return ok;
740 }
741 case watch_core_le_4:
742 {
743 WATCH_CORE (4, LE2H,);
744 return ok;
745 }
746 case watch_core_le_8:
747 {
748 WATCH_CORE (8, LE2H,64);
749 return ok;
750 }
751 #undef WATCH_CORE
752
753 #define WATCH_SIM(N,OP,EXT) \
754 int ok; \
755 unsigned_##N word = *(unsigned_##N*)to_do->host_addr; \
756 OP (word); \
757 ok = (to_do->is_within \
758 == (word >= to_do->lb##EXT \
759 && word <= to_do->ub##EXT));
760
761 case watch_sim_host_1:
762 {
763 WATCH_SIM (1, word = ,);
764 return ok;
765 }
766 case watch_sim_host_2:
767 {
768 WATCH_SIM (2, word = ,);
769 return ok;
770 }
771 case watch_sim_host_4:
772 {
773 WATCH_SIM (4, word = ,);
774 return ok;
775 }
776 case watch_sim_host_8:
777 {
778 WATCH_SIM (8, word = ,64);
779 return ok;
780 }
781
782 case watch_sim_be_1:
783 {
784 WATCH_SIM (1, BE2H,);
785 return ok;
786 }
787 case watch_sim_be_2:
788 {
789 WATCH_SIM (2, BE2H,);
790 return ok;
791 }
792 case watch_sim_be_4:
793 {
794 WATCH_SIM (4, BE2H,);
795 return ok;
796 }
797 case watch_sim_be_8:
798 {
799 WATCH_SIM (8, BE2H,64);
800 return ok;
801 }
802
803 case watch_sim_le_1:
804 {
805 WATCH_SIM (1, LE2H,);
806 return ok;
807 }
808 case watch_sim_le_2:
809 {
810 WATCH_SIM (1, LE2H,);
811 return ok;
812 }
813 case watch_sim_le_4:
814 {
815 WATCH_SIM (1, LE2H,);
816 return ok;
817 }
818 case watch_sim_le_8:
819 {
820 WATCH_SIM (1, LE2H,64);
821 return ok;
822 }
823 #undef WATCH_SIM
824
825 case watch_clock: /* wallclock */
826 {
827 unsigned long elapsed_time = sim_elapsed_time_since (STATE_EVENTS (sd)->initial_wallclock);
828 return (elapsed_time >= to_do->wallclock);
829 }
830
831 default:
832 sim_io_error (sd, "sim_watch_valid - bad switch");
833 break;
834
835 }
836 return 1;
837 }
838
839
840 INLINE_SIM_EVENTS\
841 (int)
842 sim_events_tick (SIM_DESC sd)
843 {
844 sim_events *events = STATE_EVENTS (sd);
845
846 /* this should only be called after the previous ticks have been
847 fully processed */
848 SIM_ASSERT (events->nr_ticks_to_process == 0);
849
850 /* Advance the time but *only* if there is nothing to process */
851 if (events->work_pending
852 || events->time_from_event == 0)
853 {
854 events->nr_ticks_to_process = 1;
855 return 1;
856 }
857 else {
858 events->time_from_event -= 1;
859 return 0;
860 }
861 }
862
863
864 INLINE_SIM_EVENTS\
865 (int)
866 sim_events_tickn (SIM_DESC sd,
867 int n)
868 {
869 sim_events *events = STATE_EVENTS (sd);
870
871 /* this should only be called after the previous ticks have been
872 fully processed */
873 SIM_ASSERT (events->nr_ticks_to_process == 0);
874 SIM_ASSERT (n > 0);
875
876 /* Advance the time but *only* if there is nothing to process */
877 if (events->work_pending
878 || events->time_from_event < n)
879 {
880 events->nr_ticks_to_process = n;
881 return 1;
882 }
883 else {
884 events->time_from_event -= n;
885 return 0;
886 }
887 }
888
889
890 INLINE_SIM_EVENTS\
891 (void)
892 sim_events_preprocess (SIM_DESC sd,
893 int events_were_last,
894 int events_were_next)
895 {
896 sim_events *events = STATE_EVENTS(sd);
897 if (events->nr_ticks_to_process != 0)
898 {
899 /* Halted midway through event processing */
900 ASSERT (events_were_last && events_were_next);
901 sim_events_process (sd);
902 }
903 else if (events_were_next)
904 {
905 /* Halted by the last processor */
906 ASSERT (events->nr_ticks_to_process == 0 && !events_were_last);
907 if (sim_events_tick (sd))
908 sim_events_process (sd);
909 }
910 }
911
912
913 INLINE_SIM_EVENTS\
914 (void)
915 sim_events_process (SIM_DESC sd)
916 {
917 sim_events *events = STATE_EVENTS(sd);
918 signed64 event_time = sim_events_time(sd);
919
920 ASSERT (events->nr_ticks_to_process != 0);
921
922 /* move any events that were queued by any signal handlers onto
923 the real event queue. */
924 if (events->nr_held > 0)
925 {
926 int i;
927
928 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
929 /*-LOCK-*/
930 sigset_t old_mask;
931 sigset_t new_mask;
932 sigfillset(&new_mask);
933 sigprocmask(SIG_SETMASK, &new_mask, &old_mask);
934 #endif
935
936 for (i = 0; i < events->nr_held; i++)
937 {
938 sim_event *entry = &events->held [i];
939 sim_events_schedule (sd,
940 entry->time_of_event,
941 entry->handler,
942 entry->data);
943 }
944 events->nr_held = 0;
945
946 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
947 /*-UNLOCK-*/
948 sigprocmask(SIG_SETMASK, &old_mask, NULL);
949 #endif
950
951 }
952
953 /* Process any watchpoints. Be careful to allow a watchpoint to
954 appear/disappear under our feet.
955 To ensure that watchpoints are processed only once per cycle,
956 they are moved onto a watched queue, this returned to the
957 watchpoint queue when all queue processing has been
958 completed. */
959 while (events->watchpoints != NULL)
960 {
961 sim_event *to_do = events->watchpoints;
962 events->watchpoints = to_do->next;
963 if (sim_watch_valid (sd, to_do))
964 {
965 sim_event_handler *handler = to_do->handler;
966 void *data = to_do->data;
967 ETRACE((_ETRACE,
968 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx\n",
969 (long) event_time,
970 (long) to_do,
971 (long) handler,
972 (long) data));
973 sim_events_free (sd, to_do);
974 handler (sd, data);
975 }
976 else
977 {
978 to_do->next = events->watchedpoints;
979 events->watchedpoints = to_do;
980 }
981 }
982
983 /* consume all events for this or earlier times. Be careful to
984 allow an event to appear/disappear under our feet */
985 while (events->queue->time_of_event <
986 (event_time + events->nr_ticks_to_process))
987 {
988 sim_event *to_do = events->queue;
989 sim_event_handler *handler = to_do->handler;
990 void *data = to_do->data;
991 events->queue = to_do->next;
992 ETRACE((_ETRACE,
993 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx\n",
994 (long) event_time,
995 (long) to_do,
996 (long) handler,
997 (long) data));
998 sim_events_free (sd, to_do);
999 handler (sd, data);
1000 }
1001
1002 /* put things back where they belong ready for the next iteration */
1003 events->watchpoints = events->watchedpoints;
1004 events->watchedpoints = NULL;
1005 if (events->watchpoints != NULL)
1006 events->work_pending = 1;
1007
1008 /* re-caculate time for new events then advance the time */
1009 update_time_from_event(sd);
1010 SIM_ASSERT (events->time_from_event >= events->nr_ticks_to_process);
1011 SIM_ASSERT (events->queue != NULL); /* always poll event */
1012 events->time_from_event -= events->nr_ticks_to_process;
1013
1014 /* this round of processing complete */
1015 events->nr_ticks_to_process = 0;
1016 }
1017
1018 #endif