Extend xor-endian and per-cpu support in core module.
[deliverable/binutils-gdb.git] / sim / common / sim-events.c
CommitLineData
8517f62b
AC
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
50a2a691
AC
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
8517f62b
AC
36#include <signal.h>
37
50a2a691 38
f03b093c
AC
39typedef 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,
50a2a691 79} sim_event_watchpoints;
f03b093c
AC
80
81
82struct _sim_event {
50a2a691 83 sim_event_watchpoints watching;
f03b093c
AC
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 */
2f2e6c5d 96 int is_within; /* 0/1 */
f03b093c
AC
97 unsigned ub;
98 unsigned lb;
99 unsigned64 ub64;
100 unsigned64 lb64;
101 /* list */
102 sim_event *next;
103};
104
8517f62b
AC
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
50a2a691
AC
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.
8517f62b
AC
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)
50a2a691 132#define SIM_EVENTS_POLL_RATE 0x100000
8517f62b
AC
133#endif
134
135
136#define _ETRACE sd
137
138#undef ETRACE
139#define ETRACE(ARGS) \
140do \
141 { \
142 if (WITH_TRACE) \
143 { \
f03b093c 144 if (STATE_EVENTS (sd)->trace) \
8517f62b
AC
145 { \
146 const char *file; \
f03b093c 147 SIM_FILTER_PATH (file, __FILE__); \
8517f62b
AC
148 sim_io_printf (sd, "%s:%d: ", file, __LINE__); \
149 sim_io_printf ARGS; \
150 } \
151 } \
152 } \
153while (0)
154
155
50a2a691
AC
156/* event queue iterator - don't iterate over the held queue. */
157
f03b093c
AC
158STATIC_INLINE_SIM_EVENTS\
159(sim_event **)
160next_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
8517f62b
AC
177STATIC_INLINE_SIM_EVENTS\
178(void)
f03b093c
AC
179sim_events_poll (SIM_DESC sd,
180 void *data)
8517f62b
AC
181{
182 /* just re-schedule in 1000 million ticks time */
f03b093c 183 sim_events_schedule (sd, SIM_EVENTS_POLL_RATE, sim_events_poll, sd);
8517f62b
AC
184 sim_io_poll_quit (sd);
185}
186
187
f03b093c
AC
188/* "events" module install handler.
189 This is called via sim_module_install to install the "events" subsystem
190 into the simulator. */
191
192EXTERN_SIM_EVENTS\
193(SIM_RC)
194sim_events_install (SIM_DESC sd)
195{
50a2a691 196 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
f03b093c
AC
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
205EXTERN_SIM_EVENTS\
8517f62b 206(void)
f03b093c 207sim_events_uninstall (SIM_DESC sd)
8517f62b 208{
f03b093c
AC
209 /* FIXME: free buffers, etc. */
210}
211
212
50a2a691
AC
213/* malloc/free */
214
215STATIC_INLINE_SIM_EVENTS\
216(sim_event *)
217sim_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
244STATIC_INLINE_SIM_EVENTS\
245(void)
246sim_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
f03b093c
AC
255/* Initialize the simulator event manager */
256
257EXTERN_SIM_EVENTS\
258(SIM_RC)
259sim_events_init (SIM_DESC sd)
260{
261 sim_events *events = STATE_EVENTS (sd);
8517f62b
AC
262
263 /* drain the interrupt queue */
50a2a691
AC
264 events->nr_held = 0;
265 if (events->held == NULL)
266 events->held = zalloc (sizeof (sim_event) * MAX_NR_SIGNAL_SIM_EVENTS);
8517f62b 267
f03b093c
AC
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;
50a2a691 278 sim_events_free (sd, dead);
f03b093c
AC
279 }
280 *queue = NULL;
281 }
8517f62b 282 }
f03b093c 283
8517f62b 284 /* wind time back to zero */
50a2a691 285 events->nr_ticks_to_process = 1; /* start by doing queue */
8517f62b
AC
286 events->time_of_event = 0;
287 events->time_from_event = 0;
f03b093c 288 events->initial_wallclock = sim_elapsed_time_get ();
8517f62b
AC
289
290 /* schedule our initial counter event */
f03b093c 291 sim_events_schedule (sd, 0, sim_events_poll, sd);
8517f62b
AC
292
293 /* from now on, except when the large-int event is being processed
294 the event queue is non empty */
f03b093c
AC
295 SIM_ASSERT (events->queue != NULL);
296
297 return SIM_RC_OK;
8517f62b
AC
298}
299
f03b093c 300
8517f62b
AC
301INLINE_SIM_EVENTS\
302(signed64)
f03b093c 303sim_events_time (SIM_DESC sd)
8517f62b 304{
f03b093c 305 sim_events *events = STATE_EVENTS (sd);
8517f62b
AC
306 return events->time_of_event - events->time_from_event;
307}
308
f03b093c 309
8517f62b
AC
310STATIC_INLINE_SIM_EVENTS\
311(void)
f03b093c 312update_time_from_event (SIM_DESC sd)
8517f62b 313{
f03b093c
AC
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));
8517f62b
AC
328}
329
f03b093c 330
8517f62b
AC
331STATIC_INLINE_SIM_EVENTS\
332(void)
f03b093c
AC
333insert_sim_event (SIM_DESC sd,
334 sim_event *new_event,
335 signed64 delta)
8517f62b 336{
f03b093c 337 sim_events *events = STATE_EVENTS (sd);
8517f62b
AC
338 sim_event *curr;
339 sim_event **prev;
340 signed64 time_of_event;
341
342 if (delta < 0)
f03b093c
AC
343 sim_io_error (sd, "what is past is past!\n");
344
8517f62b 345 /* compute when the event should occure */
f03b093c
AC
346 time_of_event = sim_events_time (sd) + delta;
347
8517f62b
AC
348 /* find the queue insertion point - things are time ordered */
349 prev = &events->queue;
350 curr = events->queue;
f03b093c
AC
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
8517f62b
AC
360 /* insert it */
361 new_event->next = curr;
362 *prev = new_event;
363 new_event->time_of_event = time_of_event;
f03b093c 364
8517f62b 365 /* adjust the time until the first event */
f03b093c 366 update_time_from_event (sd);
8517f62b
AC
367}
368
f03b093c
AC
369
370EXTERN_SIM_EVENTS\
8517f62b 371(sim_event *)
f03b093c
AC
372sim_events_schedule (SIM_DESC sd,
373 signed64 delta_time,
374 sim_event_handler *handler,
375 void *data)
8517f62b 376{
50a2a691 377 sim_event *new_event = sim_events_zalloc (sd);
8517f62b
AC
378 new_event->data = data;
379 new_event->handler = handler;
f03b093c 380 new_event->watching = watch_timer;
8517f62b
AC
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
f03b093c 393EXTERN_SIM_EVENTS\
50a2a691
AC
394(void)
395sim_events_schedule_after_signal (SIM_DESC sd,
396 signed64 delta_time,
397 sim_event_handler *handler,
398 void *data)
8517f62b 399{
f03b093c 400 sim_events *events = STATE_EVENTS (sd);
50a2a691
AC
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 }
f03b093c 418
8517f62b
AC
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;
50a2a691
AC
423
424 events->work_pending = 1; /* notify main process */
425
f03b093c 426#if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
50a2a691
AC
427 /*-UNLOCK-*/
428 sigprocmask (SIG_SETMASK, &old_mask, NULL);
8517f62b 429#endif
f03b093c
AC
430
431 ETRACE ((_ETRACE,
50a2a691 432 "signal scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
f03b093c
AC
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));
f03b093c 438}
8517f62b 439
8517f62b 440
f03b093c
AC
441EXTERN_SIM_EVENTS\
442(sim_event *)
443sim_events_watch_clock (SIM_DESC sd,
50a2a691 444 unsigned delta_ms_time,
f03b093c
AC
445 sim_event_handler *handler,
446 void *data)
447{
448 sim_events *events = STATE_EVENTS (sd);
50a2a691 449 sim_event *new_event = sim_events_zalloc (sd);
f03b093c
AC
450 /* type */
451 new_event->watching = watch_clock;
452 /* handler */
453 new_event->data = data;
454 new_event->handler = handler;
455 /* data */
50a2a691 456 new_event->wallclock = (sim_elapsed_time_since (events->initial_wallclock) + delta_ms_time);
f03b093c
AC
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));
8517f62b
AC
468 return new_event;
469}
470
471
f03b093c
AC
472EXTERN_SIM_EVENTS\
473(sim_event *)
474sim_events_watch_sim (SIM_DESC sd,
475 void *host_addr,
476 int nr_bytes,
477 int byte_order,
2f2e6c5d 478 int is_within,
f03b093c
AC
479 unsigned64 lb,
480 unsigned64 ub,
481 sim_event_handler *handler,
482 void *data)
483{
484 sim_events *events = STATE_EVENTS (sd);
50a2a691 485 sim_event *new_event = sim_events_zalloc (sd);
f03b093c
AC
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;
2f2e6c5d 531 new_event->is_within = (is_within != 0);
f03b093c
AC
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
549EXTERN_SIM_EVENTS\
550(sim_event *)
551sim_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,
2f2e6c5d 556 int is_within,
f03b093c
AC
557 unsigned64 lb,
558 unsigned64 ub,
559 sim_event_handler *handler,
560 void *data)
561{
562 sim_events *events = STATE_EVENTS (sd);
50a2a691 563 sim_event *new_event = sim_events_zalloc (sd);
f03b093c
AC
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;
2f2e6c5d 610 new_event->is_within = (is_within != 0);
f03b093c
AC
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
628EXTERN_SIM_EVENTS\
8517f62b 629(void)
f03b093c
AC
630sim_events_deschedule (SIM_DESC sd,
631 sim_event *event_to_remove)
8517f62b 632{
f03b093c 633 sim_events *events = STATE_EVENTS (sd);
8517f62b 634 sim_event *to_remove = (sim_event*)event_to_remove;
f03b093c
AC
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));
50a2a691 656 sim_events_free (sd, dead);
f03b093c
AC
657 update_time_from_event (sd);
658 SIM_ASSERT ((events->time_from_event >= 0) == (events->queue != NULL));
659 return;
660 }
661 }
8517f62b 662 }
f03b093c
AC
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));
8517f62b
AC
667}
668
669
f03b093c
AC
670STATIC_INLINE_SIM_EVENTS\
671(int)
672sim_watch_valid (SIM_DESC sd,
673 sim_event *to_do)
674{
675 switch (to_do->watching)
676 {
677
50a2a691 678#define WATCH_CORE(N,OP,EXT) \
f03b093c 679 { \
2f2e6c5d
AC
680 unsigned_##N word = 0; \
681 int nr_read = sim_core_read_buffer (sd, NULL, to_do->core_map, &word, to_do->core_addr, sizeof (word)); \
f03b093c 682 OP (word); \
2f2e6c5d
AC
683 return (nr_read == sizeof (unsigned_##N) \
684 && (to_do->is_within \
685 == (word >= to_do->lb##EXT \
686 && word <= to_do->ub##EXT))); \
f03b093c 687 }
50a2a691
AC
688 case watch_core_targ_1: WATCH_CORE (1, T2H,);
689 case watch_core_targ_2: WATCH_CORE (2, T2H,);
690 case watch_core_targ_4: WATCH_CORE (4, T2H,);
691 case watch_core_targ_8: WATCH_CORE (8, T2H,64);
692
693 case watch_core_be_1: WATCH_CORE (1, BE2H,);
694 case watch_core_be_2: WATCH_CORE (2, BE2H,);
695 case watch_core_be_4: WATCH_CORE (4, BE2H,);
696 case watch_core_be_8: WATCH_CORE (8, BE2H,64);
697
698 case watch_core_le_1: WATCH_CORE (1, LE2H,);
699 case watch_core_le_2: WATCH_CORE (2, LE2H,);
700 case watch_core_le_4: WATCH_CORE (4, LE2H,);
701 case watch_core_le_8: WATCH_CORE (8, LE2H,64);
f03b093c
AC
702#undef WATCH_CORE
703
50a2a691 704#define WATCH_SIM(N,OP,EXT) \
f03b093c
AC
705 { \
706 unsigned_##N word = *(unsigned_##N*)to_do->host_addr; \
707 OP (word); \
2f2e6c5d
AC
708 return (to_do->is_within \
709 == (word >= to_do->lb##EXT \
710 && word <= to_do->ub##EXT)); \
f03b093c
AC
711 }
712
50a2a691
AC
713 case watch_sim_host_1: WATCH_SIM (1, word = ,);
714 case watch_sim_host_2: WATCH_SIM (2, word = ,);
715 case watch_sim_host_4: WATCH_SIM (4, word = ,);
716 case watch_sim_host_8: WATCH_SIM (8, word = ,64);
f03b093c 717
50a2a691
AC
718 case watch_sim_be_1: WATCH_SIM (1, BE2H,);
719 case watch_sim_be_2: WATCH_SIM (2, BE2H,);
720 case watch_sim_be_4: WATCH_SIM (4, BE2H,);
721 case watch_sim_be_8: WATCH_SIM (8, BE2H,64);
f03b093c 722
50a2a691
AC
723 case watch_sim_le_1: WATCH_SIM (1, LE2H,);
724 case watch_sim_le_2: WATCH_SIM (1, LE2H,);
725 case watch_sim_le_4: WATCH_SIM (1, LE2H,);
726 case watch_sim_le_8: WATCH_SIM (1, LE2H,64);
f03b093c
AC
727#undef WATCH_SIM
728
729 case watch_clock: /* wallclock */
50a2a691
AC
730 {
731 unsigned long elapsed_time = sim_elapsed_time_since (STATE_EVENTS (sd)->initial_wallclock);
732 return (elapsed_time >= to_do->wallclock);
733 }
f03b093c 734
50a2a691 735 default:
f03b093c
AC
736 sim_io_error (sd, "sim_watch_valid - bad switch");
737 break;
738
739 }
740 return 1;
741}
8517f62b
AC
742
743
744INLINE_SIM_EVENTS\
745(int)
f03b093c 746sim_events_tick (SIM_DESC sd)
8517f62b 747{
f03b093c 748 sim_events *events = STATE_EVENTS (sd);
8517f62b 749
50a2a691
AC
750 /* this should only be called after the previous ticks have been
751 fully processed */
752 SIM_ASSERT (events->nr_ticks_to_process == 0);
8517f62b
AC
753
754 /* Advance the time but *only* if there is nothing to process */
f03b093c
AC
755 if (events->work_pending
756 || events->time_from_event == 0)
757 {
50a2a691 758 events->nr_ticks_to_process = 1;
f03b093c
AC
759 return 1;
760 }
8517f62b
AC
761 else {
762 events->time_from_event -= 1;
763 return 0;
764 }
765}
766
767
50a2a691
AC
768INLINE_SIM_EVENTS\
769(int)
770sim_events_tickn (SIM_DESC sd,
771 unsigned n)
772{
773 sim_events *events = STATE_EVENTS (sd);
774
775 /* this should only be called after the previous ticks have been
776 fully processed */
777 SIM_ASSERT (events->nr_ticks_to_process == 0);
778 SIM_ASSERT (n > 0);
779
780 /* Advance the time but *only* if there is nothing to process */
781 if (events->work_pending
782 || events->time_from_event < n)
783 {
784 events->nr_ticks_to_process = n;
785 return 1;
786 }
787 else {
788 events->time_from_event -= n;
789 return 0;
790 }
791}
792
793
f03b093c
AC
794INLINE_SIM_EVENTS\
795(void)
796sim_events_preprocess (SIM_DESC sd,
797 int events_were_last,
798 int events_were_next)
799{
800 sim_events *events = STATE_EVENTS(sd);
50a2a691 801 if (events->nr_ticks_to_process != 0)
f03b093c
AC
802 {
803 /* Halted midway through event processing */
804 ASSERT (events_were_last && events_were_next);
805 sim_events_process (sd);
806 }
807 else if (events_were_next)
808 {
809 /* Halted by the last processor */
50a2a691 810 ASSERT (events->nr_ticks_to_process == 0 && !events_were_last);
f03b093c
AC
811 if (sim_events_tick (sd))
812 sim_events_process (sd);
813 }
814}
815
8517f62b
AC
816
817INLINE_SIM_EVENTS\
818(void)
f03b093c 819sim_events_process (SIM_DESC sd)
8517f62b 820{
f03b093c 821 sim_events *events = STATE_EVENTS(sd);
8517f62b
AC
822 signed64 event_time = sim_events_time(sd);
823
50a2a691 824 ASSERT (events->nr_ticks_to_process != 0);
8517f62b 825
f03b093c
AC
826 /* move any events that were queued by any signal handlers onto
827 the real event queue. */
50a2a691 828 if (events->nr_held > 0)
f03b093c 829 {
50a2a691 830 int i;
f03b093c 831
8517f62b 832#if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
f03b093c
AC
833 /*-LOCK-*/
834 sigset_t old_mask;
835 sigset_t new_mask;
836 sigfillset(&new_mask);
837 sigprocmask(SIG_SETMASK, &new_mask, &old_mask);
8517f62b 838#endif
f03b093c 839
50a2a691
AC
840 for (i = 0; i < events->nr_held; i++)
841 {
842 sim_event *entry = &events->held [i];
843 sim_events_schedule (sd,
844 entry->time_of_event,
845 entry->handler,
846 entry->data);
847 }
848 events->nr_held = 0;
f03b093c 849
8517f62b 850#if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
f03b093c
AC
851 /*-UNLOCK-*/
852 sigprocmask(SIG_SETMASK, &old_mask, NULL);
8517f62b 853#endif
f03b093c 854
f03b093c
AC
855 }
856
857 /* Process any watchpoints. Be careful to allow a watchpoint to
858 appear/disappear under our feet.
859 To ensure that watchpoints are processed only once per cycle,
860 they are moved onto a watched queue, this returned to the
861 watchpoint queue when all queue processing has been
862 completed. */
863 while (events->watchpoints != NULL)
864 {
865 sim_event *to_do = events->watchpoints;
866 events->watchpoints = to_do->next;
867 if (sim_watch_valid (sd, to_do))
868 {
869 sim_event_handler *handler = to_do->handler;
870 void *data = to_do->data;
871 events->queue = to_do->next;
872 ETRACE((_ETRACE,
873 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx\n",
874 (long) event_time,
875 (long) to_do,
876 (long) handler,
877 (long) data));
50a2a691 878 sim_events_free (sd, to_do);
f03b093c
AC
879 handler (sd, data);
880 }
881 else
882 {
883 to_do->next = events->watchedpoints;
884 events->watchedpoints = to_do;
885 }
886 }
887
8517f62b 888 /* consume all events for this or earlier times. Be careful to
f03b093c 889 allow an event to appear/disappear under our feet */
50a2a691
AC
890 while (events->queue->time_of_event <
891 (event_time + events->nr_ticks_to_process))
f03b093c
AC
892 {
893 sim_event *to_do = events->queue;
894 sim_event_handler *handler = to_do->handler;
895 void *data = to_do->data;
896 events->queue = to_do->next;
897 ETRACE((_ETRACE,
898 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx\n",
899 (long) event_time,
900 (long) to_do,
901 (long) handler,
902 (long) data));
50a2a691 903 sim_events_free (sd, to_do);
f03b093c
AC
904 handler (sd, data);
905 }
906
907 /* put things back where they belong ready for the next iteration */
908 events->watchpoints = events->watchedpoints;
909 events->watchedpoints = NULL;
910 if (events->watchpoints != NULL)
911 events->work_pending = 1;
912
50a2a691 913 /* re-caculate time for new events then advance the time */
8517f62b 914 update_time_from_event(sd);
50a2a691
AC
915 SIM_ASSERT (events->time_from_event >= events->nr_ticks_to_process);
916 SIM_ASSERT (events->queue != NULL); /* always poll event */
917 events->time_from_event -= events->nr_ticks_to_process;
918
919 /* this round of processing complete */
920 events->nr_ticks_to_process = 0;
8517f62b
AC
921}
922
923#endif
This page took 0.06358 seconds and 4 git commands to generate.