/* Hardware event manager.
   Copyright (C) 1998-2021 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/>.  */

/* This must come before any other includes.  */
#include "defs.h"

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

#include "sim-events.h"

#include <string.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)
{
  return hw_event_queue_schedule_tracef (me, delta_time, callback, data, NULL);
}

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>
#include <stdlib.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
