📄 sim-events.c
字号:
new_event->data = data; new_event->handler = handler; /* data */ if (events->resume_wallclock == 0) new_event->wallclock = (events->elapsed_wallclock + delta_ms_time); else new_event->wallclock = (events->elapsed_wallclock + sim_elapsed_time_since (events->resume_wallclock) + delta_ms_time); /* insert */ new_event->next = events->watchpoints; events->watchpoints = new_event; events->work_pending = 1; ETRACE ((_ETRACE, "event watching clock at %ld - tag 0x%lx - wallclock %ld, handler 0x%lx, data 0x%lx\n", (long)sim_events_time (sd), (long)new_event, (long)new_event->wallclock, (long)new_event->handler, (long)new_event->data)); return new_event;}#endif#if EXTERN_SIM_EVENTS_Psim_event *sim_events_watch_sim (SIM_DESC sd, void *host_addr, int nr_bytes, int byte_order, int is_within, unsigned64 lb, unsigned64 ub, sim_event_handler *handler, void *data){ sim_events *events = STATE_EVENTS (sd); sim_event *new_event = sim_events_zalloc (sd); /* type */ switch (byte_order) { case 0: switch (nr_bytes) { case 1: new_event->watching = watch_sim_host_1; break; case 2: new_event->watching = watch_sim_host_2; break; case 4: new_event->watching = watch_sim_host_4; break; case 8: new_event->watching = watch_sim_host_8; break; default: sim_io_error (sd, "sim_events_watch_sim - invalid nr bytes"); } break; case BIG_ENDIAN: switch (nr_bytes) { case 1: new_event->watching = watch_sim_be_1; break; case 2: new_event->watching = watch_sim_be_2; break; case 4: new_event->watching = watch_sim_be_4; break; case 8: new_event->watching = watch_sim_be_8; break; default: sim_io_error (sd, "sim_events_watch_sim - invalid nr bytes"); } break; case LITTLE_ENDIAN: switch (nr_bytes) { case 1: new_event->watching = watch_sim_le_1; break; case 2: new_event->watching = watch_sim_le_2; break; case 4: new_event->watching = watch_sim_le_4; break; case 8: new_event->watching = watch_sim_le_8; break; default: sim_io_error (sd, "sim_events_watch_sim - invalid nr bytes"); } break; default: sim_io_error (sd, "sim_events_watch_sim - invalid byte order"); } /* handler */ new_event->data = data; new_event->handler = handler; /* data */ new_event->host_addr = host_addr; new_event->lb = lb; new_event->lb64 = lb; new_event->ub = ub; new_event->ub64 = ub; new_event->is_within = (is_within != 0); /* insert */ new_event->next = events->watchpoints; events->watchpoints = new_event; events->work_pending = 1; ETRACE ((_ETRACE, "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n", (long)sim_events_time (sd), (long)new_event, (long)new_event->host_addr, (long)new_event->lb, (long)new_event->ub, (long)new_event->handler, (long)new_event->data)); return new_event;}#endif#if EXTERN_SIM_EVENTS_Psim_event *sim_events_watch_core (SIM_DESC sd, address_word core_addr, unsigned core_map, int nr_bytes, int byte_order, int is_within, unsigned64 lb, unsigned64 ub, sim_event_handler *handler, void *data){ sim_events *events = STATE_EVENTS (sd); sim_event *new_event = sim_events_zalloc (sd); /* type */ switch (byte_order) { case 0: switch (nr_bytes) { case 1: new_event->watching = watch_core_targ_1; break; case 2: new_event->watching = watch_core_targ_2; break; case 4: new_event->watching = watch_core_targ_4; break; case 8: new_event->watching = watch_core_targ_8; break; default: sim_io_error (sd, "sim_events_watch_core - invalid nr bytes"); } break; case BIG_ENDIAN: switch (nr_bytes) { case 1: new_event->watching = watch_core_be_1; break; case 2: new_event->watching = watch_core_be_2; break; case 4: new_event->watching = watch_core_be_4; break; case 8: new_event->watching = watch_core_be_8; break; default: sim_io_error (sd, "sim_events_watch_core - invalid nr bytes"); } break; case LITTLE_ENDIAN: switch (nr_bytes) { case 1: new_event->watching = watch_core_le_1; break; case 2: new_event->watching = watch_core_le_2; break; case 4: new_event->watching = watch_core_le_4; break; case 8: new_event->watching = watch_core_le_8; break; default: sim_io_error (sd, "sim_events_watch_core - invalid nr bytes"); } break; default: sim_io_error (sd, "sim_events_watch_core - invalid byte order"); } /* handler */ new_event->data = data; new_event->handler = handler; /* data */ new_event->core_addr = core_addr; new_event->core_map = core_map; new_event->lb = lb; new_event->lb64 = lb; new_event->ub = ub; new_event->ub64 = ub; new_event->is_within = (is_within != 0); /* insert */ new_event->next = events->watchpoints; events->watchpoints = new_event; events->work_pending = 1; ETRACE ((_ETRACE, "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n", (long)sim_events_time (sd), (long)new_event, (long)new_event->host_addr, (long)new_event->lb, (long)new_event->ub, (long)new_event->handler, (long)new_event->data)); return new_event;}#endif#if EXTERN_SIM_EVENTS_Pvoidsim_events_deschedule (SIM_DESC sd, sim_event *event_to_remove){ sim_events *events = STATE_EVENTS (sd); sim_event *to_remove = (sim_event*)event_to_remove; if (event_to_remove != NULL) { sim_event **queue = NULL; while ((queue = next_event_queue (sd, queue)) != NULL) { sim_event **ptr_to_current; for (ptr_to_current = queue; *ptr_to_current != NULL && *ptr_to_current != to_remove; ptr_to_current = &(*ptr_to_current)->next); if (*ptr_to_current == to_remove) { sim_event *dead = *ptr_to_current; *ptr_to_current = dead->next; ETRACE ((_ETRACE, "event/watch descheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n", (long) sim_events_time (sd), (long) event_to_remove, (long) dead->time_of_event, (long) dead->handler, (long) dead->data, (dead->trace != NULL) ? ", " : "", (dead->trace != NULL) ? dead->trace : "")); sim_events_free (sd, dead); update_time_from_event (sd); SIM_ASSERT ((events->time_from_event >= 0) == (events->queue != NULL)); return; } } } ETRACE ((_ETRACE, "event/watch descheduled at %ld - tag 0x%lx - not found\n", (long) sim_events_time (sd), (long) event_to_remove));}#endifSTATIC_INLINE_SIM_EVENTS\(int)sim_watch_valid (SIM_DESC sd, sim_event *to_do){ switch (to_do->watching) {#define WATCH_CORE(N,OP,EXT) \ int ok; \ unsigned_##N word = 0; \ int nr_read = sim_core_read_buffer (sd, NULL, to_do->core_map, &word, \ to_do->core_addr, sizeof (word)); \ OP (word); \ ok = (nr_read == sizeof (unsigned_##N) \ && (to_do->is_within \ == (word >= to_do->lb##EXT \ && word <= to_do->ub##EXT))); case watch_core_targ_1: { WATCH_CORE (1, T2H,); return ok; } case watch_core_targ_2: { WATCH_CORE (2, T2H,); return ok; } case watch_core_targ_4: { WATCH_CORE (4, T2H,); return ok; } case watch_core_targ_8: { WATCH_CORE (8, T2H,64); return ok; } case watch_core_be_1: { WATCH_CORE (1, BE2H,); return ok; } case watch_core_be_2: { WATCH_CORE (2, BE2H,); return ok; } case watch_core_be_4: { WATCH_CORE (4, BE2H,); return ok; } case watch_core_be_8: { WATCH_CORE (8, BE2H,64); return ok; } case watch_core_le_1: { WATCH_CORE (1, LE2H,); return ok; } case watch_core_le_2: { WATCH_CORE (2, LE2H,); return ok; } case watch_core_le_4: { WATCH_CORE (4, LE2H,); return ok; } case watch_core_le_8: { WATCH_CORE (8, LE2H,64); return ok; }#undef WATCH_CORE#define WATCH_SIM(N,OP,EXT) \ int ok; \ unsigned_##N word = *(unsigned_##N*)to_do->host_addr; \ OP (word); \ ok = (to_do->is_within \ == (word >= to_do->lb##EXT \ && word <= to_do->ub##EXT)); case watch_sim_host_1: { WATCH_SIM (1, word = ,); return ok; } case watch_sim_host_2: { WATCH_SIM (2, word = ,); return ok; } case watch_sim_host_4: { WATCH_SIM (4, word = ,); return ok; } case watch_sim_host_8: { WATCH_SIM (8, word = ,64); return ok; } case watch_sim_be_1: { WATCH_SIM (1, BE2H,); return ok; } case watch_sim_be_2: { WATCH_SIM (2, BE2H,); return ok; } case watch_sim_be_4: { WATCH_SIM (4, BE2H,); return ok; } case watch_sim_be_8: { WATCH_SIM (8, BE2H,64); return ok; } case watch_sim_le_1: { WATCH_SIM (1, LE2H,); return ok; } case watch_sim_le_2: { WATCH_SIM (1, LE2H,); return ok; } case watch_sim_le_4: { WATCH_SIM (1, LE2H,); return ok; } case watch_sim_le_8: { WATCH_SIM (1, LE2H,64); return ok; }#undef WATCH_SIM case watch_clock: /* wallclock */ { unsigned long elapsed_time = sim_events_elapsed_time (sd); return (elapsed_time >= to_do->wallclock); } default: sim_io_error (sd, "sim_watch_valid - bad switch"); break; } return 1;}INLINE_SIM_EVENTS\(int)sim_events_tick (SIM_DESC sd){ sim_events *events = STATE_EVENTS (sd); /* this should only be called after the previous ticks have been fully processed */ /* Advance the time but *only* if there is nothing to process */ if (events->work_pending || events->time_from_event == 0) { events->nr_ticks_to_process += 1; return 1; } else { events->time_from_event -= 1; return 0; }}INLINE_SIM_EVENTS\(int)sim_events_tickn (SIM_DESC sd, int n){ sim_events *events = STATE_EVENTS (sd); SIM_ASSERT (n > 0); /* this should only be called after the previous ticks have been fully processed */ /* Advance the time but *only* if there is nothing to process */ if (events->work_pending || events->time_from_event < n) { events->nr_ticks_to_process += n; return 1; } else { events->time_from_event -= n; return 0; }}INLINE_SIM_EVENTS\(void)sim_events_slip (SIM_DESC sd, int slip){ sim_events *events = STATE_EVENTS (sd); SIM_ASSERT (slip > 0); /* Flag a ready event with work_pending instead of number of ticks to process so that the time continues to be correct */ if (events->time_from_event < slip) { events->work_pending = 1; } events->time_from_event -= slip;}INLINE_SIM_EVENTS\(void)sim_events_preprocess (SIM_DESC sd, int events_were_last, int events_were_next){ sim_events *events = STATE_EVENTS(sd); if (events_were_last) { /* Halted part way through event processing */ ASSERT (events->nr_ticks_to_process != 0); /* The external world can't tell if the event that stopped the simulator was the last event to process. */ ASSERT (events_were_next); sim_events_process (sd); } else if (events_were_next) { /* Halted by the last processor */ if (sim_events_tick (sd)) sim_events_process (sd); }}INLINE_SIM_EVENTS\(void)sim_events_process (SIM_DESC sd){ sim_events *events = STATE_EVENTS(sd); signed64 event_time = sim_events_time(sd); /* Clear work_pending before checking nr_held. Clearing work_pending after nr_held (with out a lock could loose an event). */ events->work_pending = 0; /* move any events that were asynchronously queued by any signal handlers onto the real event queue. */ if (events->nr_held > 0) { int i; #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK) /*-LOCK-*/ sigset_t old_mask; sigset_t new_mask; sigfillset(&new_mask); sigprocmask(SIG_SETMASK, &new_mask, &old_mask);#endif for (i = 0; i < events->nr_held; i++) { sim_event *entry = &events->held [i]; sim_events_schedule (sd, entry->time_of_event, entry->handler, entry->data); } events->nr_held = 0; #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK) /*-UNLOCK-*/ sigprocmask(SIG_SETMASK, &old_mask, NULL);#endif } /* Process any watchpoints. Be careful to allow a watchpoint to appear/disappear under our feet. To ensure that watchpoints are processed only once per cycle, they are moved onto a watched queue, this returned to the watchpoint queue when all queue processing has been completed. */ while (events->watchpoints != NULL) { sim_event *to_do = events->watchpoints; events->watchpoints = to_do->next; if (sim_watch_valid (sd, to_do)) { sim_event_handler *handler = to_do->handler; void *data = to_do->data; ETRACE((_ETRACE, "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n", (long) event_time, (long) to_do, (long) handler, (long) data, (to_do->trace != NULL) ? ", " : "", (to_do->trace != NULL) ? to_do->trace : "")); sim_events_free (sd, to_do); handler (sd, data); } else { to_do->next = events->watchedpoints; events->watchedpoints = to_do; } } /* consume all events for this or earlier times. Be careful to allow an event to appear/disappear under our feet */ while (events->queue->time_of_event < (event_time + events->nr_ticks_to_process)) { sim_event *to_do = events->queue; sim_event_handler *handler = to_do->handler; void *data = to_do->data; events->queue = to_do->next; update_time_from_event (sd); ETRACE((_ETRACE, "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n", (long) event_time, (long) to_do, (long) handler, (long) data, (to_do->trace != NULL) ? ", " : "", (to_do->trace != NULL) ? to_do->trace : "")); sim_events_free (sd, to_do); handler (sd, data); } /* put things back where they belong ready for the next iteration */ events->watchpoints = events->watchedpoints; events->watchedpoints = NULL; if (events->watchpoints != NULL) events->work_pending = 1; /* advance the time */ SIM_ASSERT (events->time_from_event >= events->nr_ticks_to_process); SIM_ASSERT (events->queue != NULL); /* always poll event */ events->time_from_event -= events->nr_ticks_to_process; /* this round of processing complete */ events->nr_ticks_to_process = 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -