/* Hardware event manager.
   Copyright (C) 1998-2016 Free Software Foundation, Inc.
   Contributed by Cygnus Support.

This file is part of GDB, the GNU debugger.

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/>.  */


#include "hw-main.h"
#include "hw-base.h"

#include "sim-events.h"


/* The hw-events object is implemented using sim-events */

struct hw_event
{
  void *data;
  struct hw *me;
  hw_event_callback *callback;
  sim_event *real;
  struct hw_event_data *entry;
};

struct hw_event_data
{
  struct hw_event event;
  struct hw_event_data *next;
};

void
create_hw_event_data (struct hw *me)
{
  if (me->events_of_hw != NULL)
    hw_abort (me, "stray events");
  /* NOP */
}

void
delete_hw_event_data (struct hw *me)
{
  /* Remove the scheduled event.  */
  while (me->events_of_hw)
    hw_event_queue_deschedule (me, &me->events_of_hw->event);
}


/* Pass the H/W event onto the real callback */

static void
bounce_hw_event (SIM_DESC sd,
		 void *data)
{
  /* save the data */
  struct hw_event_data *entry = (struct hw_event_data *) data;
  struct hw *me = entry->event.me;
  void *event_data = entry->event.data;
  hw_event_callback *callback = entry->event.callback;
  struct hw_event_data **prev = &me->events_of_hw;
  while ((*prev) != entry)
    prev = &(*prev)->next;
  (*prev) = entry->next;
  hw_free (me, entry);
  callback (me, event_data); /* may not return */
}



/* Map onto the event functions */

struct hw_event *
hw_event_queue_schedule (struct hw *me,
			 signed64 delta_time,
			 hw_event_callback *callback,
			 void *data)
{
  struct hw_event *event;
  va_list dummy;
  memset (&dummy, 0, sizeof dummy);
  event = hw_event_queue_schedule_vtracef (me, delta_time, callback, data,
					   NULL, dummy);
  return event;
}

struct hw_event *
hw_event_queue_schedule_tracef (struct hw *me,
				signed64 delta_time,
				hw_event_callback *callback,
				void *data,
				const char *fmt,
				...)
{
  struct hw_event *event;
  va_list ap;
  va_start (ap, fmt);
  event = hw_event_queue_schedule_vtracef (me, delta_time, callback, data, fmt, ap);
  va_end (ap);
  return event;
}

struct hw_event *
hw_event_queue_schedule_vtracef (struct hw *me,
				 signed64 delta_time,
				 hw_event_callback *callback,
				 void *data,
				 const char *fmt,
				 va_list ap)
{
  struct hw_event_data *entry = HW_ZALLOC (me, struct hw_event_data);
  entry->next = me->events_of_hw;
  me->events_of_hw = entry;
  /* fill it in */
  entry->event.entry = entry;
  entry->event.data = data;
  entry->event.callback = callback;
  entry->event.me = me;
  entry->event.real = sim_events_schedule_vtracef (hw_system (me),
						   delta_time,
						   bounce_hw_event,
						   entry,
						   fmt, ap);
  return &entry->event;
}


void
hw_event_queue_deschedule (struct hw *me,
			   struct hw_event *event_to_remove)
{
/* ZAP the event but only if it is still in the event queue.  Note
   that event_to_remove is only de-referenced after its validity has
   been confirmed.  */
  struct hw_event_data **prev;
  for (prev = &me->events_of_hw;
       (*prev) != NULL;
       prev = &(*prev)->next)
    {
      struct hw_event_data *entry = (*prev);
      if (&entry->event == event_to_remove)
	{
	  sim_events_deschedule (hw_system (me),
				 entry->event.real);
	  (*prev) = entry->next;
	  hw_free (me, entry);
	  return;
	}
    }
}


signed64
hw_event_queue_time (struct hw *me)
{
  return sim_events_time (hw_system (me));
}

/* Returns the time that remains before the event is raised. */
signed64
hw_event_remain_time (struct hw *me, struct hw_event *event)
{
  signed64 t;

  t = sim_events_remain_time (hw_system (me), event->real);
  return t;
}

/* Only worry about this compling on ANSI systems.
   Build with `make test-hw-events' in sim/<cpu> directory*/

#if defined (MAIN)
#include "sim-main.h"
#include <string.h>
#include <stdio.h>

static void
test_handler (struct hw *me,
	      void *data)
{
  int *n = data;
  if (*n != hw_event_queue_time (me))
    abort ();
  *n = -(*n);
}

int
main (int argc,
      char **argv)
{
  host_callback *cb = ZALLOC (host_callback);
  struct sim_state *sd = sim_state_alloc (0, cb);
  struct hw *me = ZALLOC (struct hw);
  sim_pre_argv_init (sd, "test-hw-events");
  sim_post_argv_init (sd);
  me->system_of_hw = sd;

  printf ("Create hw-event-data\n");
  {
    create_hw_alloc_data (me);
    create_hw_event_data (me);
    delete_hw_event_data (me);
    delete_hw_alloc_data (me);
  }

  printf ("Create hw-events\n");
  {
    struct hw_event *a;
    struct hw_event *b;
    struct hw_event *c;
    struct hw_event *d;
    create_hw_alloc_data (me);
    create_hw_event_data (me);
    a = hw_event_queue_schedule (me, 0, NULL, NULL);
    b = hw_event_queue_schedule (me, 1, NULL, NULL);
    c = hw_event_queue_schedule (me, 2, NULL, NULL);
    d = hw_event_queue_schedule (me, 1, NULL, NULL);
    hw_event_queue_deschedule (me, c);
    hw_event_queue_deschedule (me, b);
    hw_event_queue_deschedule (me, a);
    hw_event_queue_deschedule (me, d);
    c = HW_ZALLOC (me, struct hw_event);
    hw_event_queue_deschedule (me, b); /* OOPS! */
    hw_free (me, c);
    delete_hw_event_data (me);
    delete_hw_alloc_data (me);
  }

  printf ("Schedule hw-events\n");
  {
    struct hw_event **e;
    int *n;
    int i;
    int nr = 4;
    e = HW_NZALLOC (me, struct hw_event *, nr);
    n = HW_NZALLOC (me, int, nr);
    create_hw_alloc_data (me);
    create_hw_event_data (me);
    for (i = 0; i < nr; i++)
      {
	n[i] = i;
	e[i] = hw_event_queue_schedule (me, i, test_handler, &n[i]);
      }
    sim_events_preprocess (sd, 1, 1);
    for (i = 0; i < nr; i++)
      {
	if (sim_events_tick (sd))
	  sim_events_process (sd);
      }
    for (i = 0; i < nr; i++)
      {
	if (n[i] != -i)
	  abort ();
	hw_event_queue_deschedule (me, e[i]);
      }
    hw_free (me, n);
    hw_free (me, e);
    delete_hw_event_data (me);
    delete_hw_alloc_data (me);
  }

  return 0;
}
#endif
