/* The common simulator framework for GDB, the GNU Debugger.

   Copyright 2002-2022 Free Software Foundation, Inc.

   Contributed by Andrew Cagney and Red Hat.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */


#ifndef SIM_EVENTS_H
#define SIM_EVENTS_H

#include <stdarg.h>

#include "ansidecl.h"

/* Notes:

   When scheduling an event, the a delta of zero/one refers to the
   timeline as follows:

   epoch   0|1              1|2              2|3              3|
   **queue**|--insn--|*queue*|--insn--|*queue*|--insn--|*queue*|
     |   ^               ^        |       ^                ^
     `- +0 ------------ +1 --..   `----- +0 ------------- +1 --..

   When the queue is initialized, the time is set to zero with a
   number of initialization events scheduled.  Consequently, as also
   illustrated above, the event queue should be processed before the
   first instruction.  That instruction being executed during tick 1.

   The simulator main loop may take a form similar to:

       if (halt-/restart-setjmp)
         {

	   .... // Determine who should go next
	   last-cpu-nr = get-last-cpu-nr (sd);
	   next-cpu-nr = get-next-cpu-nr (sd);
	   events-were-last? = (last-cpu-nr >= nr-cpus);
	   events-were-next? = (next-cpu-nr >= nr-cpus);

           .... // process any outstanding events
           sim_events_preprocess (sd, events-were-last?, events-were-next?);
	   if (events-were-next)
	     next-cpu-nr = 0;

           .... // prime main loop

           while (1)
             {
	        .... // model one insn of next-cpu-nr .. nr-cpus
                if (sim_events_tick (sd))
	          sim_events_process (sd);
                next-cpu-nr = 0
	     }
         }

   NB.  In the above pseudo code it is assumed that any cpu-nr >=
   nr-cpus is a marker for the event queue. */


typedef void sim_event_handler(SIM_DESC sd, void *data);

typedef struct _sim_event sim_event;

typedef struct _sim_events sim_events;
struct _sim_events {
  int nr_ticks_to_process;
  sim_event *queue;
  sim_event *watchpoints;
  sim_event *watchedpoints;
  sim_event *free_list;
  /* flag additional work needed */
  volatile int work_pending;
  /* the asynchronous event queue */
#ifndef MAX_NR_SIGNAL_SIM_EVENTS
#define MAX_NR_SIGNAL_SIM_EVENTS 2
#endif
  sim_event *held;
  volatile int nr_held;
  /* timekeeping */
  unsigned long elapsed_wallclock;
  SIM_ELAPSED_TIME resume_wallclock;
  int64_t time_of_event;
  int64_t time_from_event;
};



/* Install the "events" module.  */

extern SIM_RC sim_events_install (SIM_DESC sd);


/* Schedule an event DELTA_TIME ticks into the future */

extern sim_event *sim_events_schedule
(SIM_DESC sd,
 int64_t delta_time,
 sim_event_handler *handler,
 void *data);

extern sim_event *sim_events_schedule_tracef
(SIM_DESC sd,
 int64_t delta_time,
 sim_event_handler *handler,
 void *data,
 const char *fmt,
 ...) ATTRIBUTE_NULL_PRINTF (5, 6);

extern sim_event *sim_events_schedule_vtracef
(SIM_DESC sd,
 int64_t delta_time,
 sim_event_handler *handler,
 void *data,
 const char *fmt,
 va_list ap) ATTRIBUTE_NULL_PRINTF (5, 0);


extern void sim_events_schedule_after_signal
(SIM_DESC sd,
 int64_t delta_time,
 sim_event_handler *handler,
 void *data);

/* NB: signal level events can't have trace strings as malloc isn't
   available */



/* Schedule an event milli-seconds from NOW.  The exact interpretation
   of wallclock is host dependant. */

extern sim_event *sim_events_watch_clock
(SIM_DESC sd,
 unsigned delta_ms_time,
 sim_event_handler *handler,
 void *data);


/* Schedule an event when a PC matches a range.  */

extern sim_event *sim_events_watch_pc
(SIM_DESC sd,
 int is_within,
 uint64_t lb,
 uint64_t ub,
 sim_event_handler *handler,
 void *data);


/* Schedule an event when the test (IS_WITHIN == (VAL >= LB && VAL <=
   UB)) of the NR_BYTES value at HOST_ADDR with BYTE_ORDER endian is
   true.

   HOST_ADDR: pointer into the host address space.
   BYTE_ORDER: BFD_ENDIAN_UNKNOWN - host endian; BFD_ENDIAN_BIG;
	       BFD_ENDIAN_LITTLE.  */

extern sim_event *sim_events_watch_sim
(SIM_DESC sd,
 void *host_addr,
 int nr_bytes,
 enum bfd_endian byte_order,
 int is_within,
 uint64_t lb,
 uint64_t ub,
 sim_event_handler *handler,
 void *data);


/* Schedule an event when the test (IS_WITHIN == (VAL >= LB && VAL <=
   UB)) of the NR_BYTES value at CORE_ADDR in BYTE_ORDER endian is
   true.

   CORE_ADDR/MAP: pointer into the target address space.
   BYTE_ORDER: BFD_ENDIAN_UNKNOWN - host endian; BFD_ENDIAN_BIG;
	       BFD_ENDIAN_LITTLE.  */

extern sim_event *sim_events_watch_core
(SIM_DESC sd,
 address_word core_addr,
 unsigned map,
 int nr_bytes,
 enum bfd_endian byte_order,
 int is_within,
 uint64_t lb,
 uint64_t ub,
 sim_event_handler *handler,
 void *data);

/* Deschedule the specified event */

extern void sim_events_deschedule
(SIM_DESC sd,
 sim_event *event_to_remove);


/* Prepare for main simulator loop.  Ensure that the next thing to do
   is not event processing.

   If the simulator halted part way through event processing then both
   EVENTS_WERE_LAST and EVENTS_WERE_NEXT shall be true.

   If the simulator halted after processing the last cpu, then only
   EVENTS_WERE_NEXT shall be true. */

INLINE_SIM_EVENTS\
(void) sim_events_preprocess
(SIM_DESC sd,
 int events_were_last,
 int events_were_next);


/* Progress time.

   Separated into two parts so that the main loop can save its context
   before the event queue is processed.  When sim_events_tick*()
   returns true, any simulation context should be saved and
   sim_events_process() called.

   SIM_EVENTS_TICK advances the clock by 1 cycle.

   SIM_EVENTS_TICKN advances the clock by N cycles (1..MAXINT). */

INLINE_SIM_EVENTS\
(int) sim_events_tick
(SIM_DESC sd);

INLINE_SIM_EVENTS\
(int) sim_events_tickn
(SIM_DESC sd,
 int n);

INLINE_SIM_EVENTS\
(void) sim_events_process
(SIM_DESC sd);


/* Advance the clock by an additional SLIP cycles at the next call to
   sim_events_tick*().  For multiple calls, the effect is
   accumulative. */

INLINE_SIM_EVENTS\
(void) sim_events_slip
(SIM_DESC sd,
 int slip);


/* Progress time such that an event shall occur upon the next call to
   sim_events tick */

#if 0
INLINE_SIM_EVENTS\
(void) sim_events_timewarp
(SIM_DESC sd);
#endif


/* local concept of elapsed target time */

INLINE_SIM_EVENTS\
(int64_t) sim_events_time
(SIM_DESC sd);


/* local concept of elapsed host time (milliseconds) */

INLINE_SIM_EVENTS\
(unsigned long) sim_events_elapsed_time
(SIM_DESC sd);

/* Returns the time that remains before the event is raised. */
INLINE_SIM_EVENTS\
(int64_t) sim_events_remain_time
(SIM_DESC sd, sim_event *event);


#endif
