/* Hardware event manager.
   Copyright (C) 1998-2023 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 <stdarg.h>
#include <string.h>

#include "sim/callback.h"

#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,
			 int64_t 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,
				int64_t 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,
				 int64_t 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;
	}
    }
}


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

/* Returns the time that remains before the event is raised. */
int64_t
hw_event_remain_time (struct hw *me, struct hw_event *event)
{
  int64_t 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 <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "sim-main.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
