/* Simulator hardware option handling.
   Copyright (C) 1998-2022 Free Software Foundation, Inc.
   Contributed by Cygnus Support and Andrew Cagney.

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 <ctype.h>
#include <errno.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

#include "sim-main.h"
#include "sim-assert.h"
#include "sim-options.h"
#include "sim/callback.h"

#include "sim-hw.h"

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

struct sim_hw {
  struct hw *tree;
  int trace_p;
  int info_p;
  /* if called from a processor */
  sim_cpu *cpu;
  sim_cia cia;
};


struct hw *
sim_hw_parse (struct sim_state *sd,
	      const char *fmt,
	      ...)
{
  struct hw *current;
  va_list ap;
  va_start (ap, fmt);
  current = hw_tree_vparse (STATE_HW (sd)->tree, fmt, ap);
  va_end (ap);
  return current;
}

struct printer {
  struct sim_state *file;
  void (*print) (struct sim_state *, const char *, va_list ap);
};

static void
do_print (void *file, const char *fmt, ...)
{
  struct printer *p = file;
  va_list ap;
  va_start (ap, fmt);
  p->print (p->file, fmt, ap);
  va_end (ap);
}

void
sim_hw_print (struct sim_state *sd,
	      void (*print) (struct sim_state *, const char *, va_list ap))
{
  struct printer p;
  p.file = sd;
  p.print = print;
  hw_tree_print (STATE_HW (sd)->tree, do_print, &p);
}




/* command line options. */

enum {
  OPTION_HW_INFO = OPTION_START,
  OPTION_HW_TRACE,
  OPTION_HW_DEVICE,
  OPTION_HW_LIST,
  OPTION_HW_FILE,
};

static DECLARE_OPTION_HANDLER (hw_option_handler);

static const OPTION hw_options[] =
{
  { {"hw-info", no_argument, NULL, OPTION_HW_INFO },
      '\0', NULL, "List configurable hw regions",
      hw_option_handler, NULL },
  { {"info-hw", no_argument, NULL, OPTION_HW_INFO },
      '\0', NULL, NULL,
      hw_option_handler, NULL },

  { {"hw-trace", optional_argument, NULL, OPTION_HW_TRACE },
      '\0', "on|off", "Trace all hardware devices",
      hw_option_handler, NULL },
  { {"trace-hw", optional_argument, NULL, OPTION_HW_TRACE },
      '\0', NULL, NULL,
      hw_option_handler, NULL },

  { {"hw-device", required_argument, NULL, OPTION_HW_DEVICE },
      '\0', "DEVICE", "Add the specified device",
      hw_option_handler, NULL },

  { {"hw-list", no_argument, NULL, OPTION_HW_LIST },
      '\0', NULL, "List the device tree",
      hw_option_handler, NULL },

  { {"hw-file", required_argument, NULL, OPTION_HW_FILE },
      '\0', "FILE", "Add the devices listed in the file",
      hw_option_handler, NULL },

  { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
};



/* Copied from ../ppc/psim.c:psim_merge_device_file() */

static SIM_RC
merge_device_file (struct sim_state *sd,
		   const char *file_name)
{
  FILE *description;
  struct hw *current = STATE_HW (sd)->tree;
  char *device_path = NULL;
  size_t buf_size = 0;
  ssize_t device_path_len;

  /* try opening the file */
  description = fopen (file_name, "r");
  if (description == NULL)
    {
      perror (file_name);
      return SIM_RC_FAIL;
    }

  while ((device_path_len = getline (&device_path, &buf_size, description)) > 0)
    {
      char *device;
      char *next_line = NULL;

      if (device_path[device_path_len - 1] == '\n')
	device_path[--device_path_len] = '\0';

      /* skip comments ("#" or ";") and blank lines lines */
      for (device = device_path;
	   *device != '\0' && isspace (*device);
	   device++);
      if (device[0] == '#'
	  || device[0] == ';'
	  || device[0] == '\0')
	continue;

      /* merge any appended lines */
      while (device_path[device_path_len - 1] == '\\')
	{
	  size_t next_buf_size = 0;
	  ssize_t next_line_len;

	  /* zap the `\' at the end of the line */
	  device_path[--device_path_len] = '\0';

	  /* get the next line */
	  next_line_len = getline (&next_line, &next_buf_size, description);
	  if (next_line_len <= 0)
	    break;

	  if (next_line[next_line_len - 1] == '\n')
	    next_line[--next_line_len] = '\0';

	  /* append the next line */
	  if (buf_size - device_path_len <= next_line_len)
	    {
	      ptrdiff_t offset = device - device_path;

	      buf_size += next_buf_size;
	      device_path = xrealloc (device_path, buf_size);
	      device = device_path + offset;
	    }
	  memcpy (device_path + device_path_len, next_line,
		  next_line_len + 1);
	  device_path_len += next_line_len;
	}
      free (next_line);

      /* parse this line */
      current = hw_tree_parse (current, "%s", device);
    }

  free (device_path);
  fclose (description);
  return SIM_RC_OK;
}


static SIM_RC
hw_option_handler (struct sim_state *sd, sim_cpu *cpu, int opt,
		   char *arg, int is_command)
{
  switch (opt)
    {

    case OPTION_HW_INFO:
      {
	/* delay info until after the tree is finished */
	STATE_HW (sd)->info_p = 1;
	return SIM_RC_OK;
	break;
      }

    case OPTION_HW_TRACE:
      {
	if (arg == NULL)
	  {
	    STATE_HW (sd)->trace_p = 1;
	  }
	else if (strcmp (arg, "yes") == 0
		 || strcmp (arg, "on") == 0)
	  {
	    STATE_HW (sd)->trace_p = 1;
	  }
	else if (strcmp (arg, "no") == 0
		 || strcmp (arg, "off") == 0)
	  {
	    STATE_HW (sd)->trace_p = 0;
	  }
	else
	  {
	    sim_io_eprintf (sd, "Option --hw-trace ignored\n");
	    /* set tracing on all devices */
	    return SIM_RC_FAIL;
	  }
	/* FIXME: Not very nice - see also hw-base.c */
	if (STATE_HW (sd)->trace_p)
	  hw_tree_parse (STATE_HW (sd)->tree, "/global-trace? true");
	return SIM_RC_OK;
	break;
      }

    case OPTION_HW_DEVICE:
      {
	hw_tree_parse (STATE_HW (sd)->tree, "%s", arg);
	return SIM_RC_OK;
      }

    case OPTION_HW_LIST:
      {
	sim_hw_print (sd, sim_io_vprintf);
	return SIM_RC_OK;
      }

    case OPTION_HW_FILE:
      {
	return merge_device_file (sd, arg);
      }

    default:
      sim_io_eprintf (sd, "Unknown hw option %d\n", opt);
      return SIM_RC_FAIL;

    }

  return SIM_RC_FAIL;
}


/* "hw" module install handler.

   This is called via sim_module_install to install the "hw" subsystem
   into the simulator.  */

static MODULE_INIT_FN sim_hw_init;
static MODULE_UNINSTALL_FN sim_hw_uninstall;

/* Provide a prototype to silence -Wmissing-prototypes.  */
SIM_RC sim_install_hw (struct sim_state *sd);

/* Establish this object.  */
SIM_RC
sim_install_hw (struct sim_state *sd)
{
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  sim_add_option_table (sd, NULL, hw_options);
  sim_module_add_uninstall_fn (sd, sim_hw_uninstall);
  sim_module_add_init_fn (sd, sim_hw_init);
  STATE_HW (sd) = ZALLOC (struct sim_hw);
  STATE_HW (sd)->tree = hw_tree_create (sd, "core");
  return SIM_RC_OK;
}


static SIM_RC
sim_hw_init (struct sim_state *sd)
{
  /* FIXME: anything needed? */
  hw_tree_finish (STATE_HW (sd)->tree);
  if (STATE_HW (sd)->info_p)
    sim_hw_print (sd, sim_io_vprintf);
  return SIM_RC_OK;
}

/* Uninstall the "hw" subsystem from the simulator.  */

static void
sim_hw_uninstall (struct sim_state *sd)
{
  hw_tree_delete (STATE_HW (sd)->tree);
  free (STATE_HW (sd));
  STATE_HW (sd) = NULL;
}



/* Data transfers to/from the hardware device tree.  There are several
   cases. */


/* CPU: The simulation is running and the current CPU/CIA
   initiates a data transfer. */

void
sim_cpu_hw_io_read_buffer (sim_cpu *cpu,
			   sim_cia cia,
			   struct hw *hw,
			   void *dest,
			   int space,
			   unsigned_word addr,
			   unsigned nr_bytes)
{
  SIM_DESC sd = CPU_STATE (cpu);
  STATE_HW (sd)->cpu = cpu;
  STATE_HW (sd)->cia = cia;
  if (hw_io_read_buffer (hw, dest, space, addr, nr_bytes) != nr_bytes)
    sim_engine_abort (sd, cpu, cia, "broken CPU read");
}

void
sim_cpu_hw_io_write_buffer (sim_cpu *cpu,
			    sim_cia cia,
			    struct hw *hw,
			    const void *source,
			    int space,
			    unsigned_word addr,
			    unsigned nr_bytes)
{
  SIM_DESC sd = CPU_STATE (cpu);
  STATE_HW (sd)->cpu = cpu;
  STATE_HW (sd)->cia = cia;
  if (hw_io_write_buffer (hw, source, space, addr, nr_bytes) != nr_bytes)
    sim_engine_abort (sd, cpu, cia, "broken CPU write");
}




/* SYSTEM: A data transfer is being initiated by the system. */

unsigned
sim_hw_io_read_buffer (struct sim_state *sd,
		       struct hw *hw,
		       void *dest,
		       int space,
		       unsigned_word addr,
		       unsigned nr_bytes)
{
  STATE_HW (sd)->cpu = NULL;
  return hw_io_read_buffer (hw, dest, space, addr, nr_bytes);
}

unsigned
sim_hw_io_write_buffer (struct sim_state *sd,
			struct hw *hw,
			const void *source,
			int space,
			unsigned_word addr,
			unsigned nr_bytes)
{
  STATE_HW (sd)->cpu = NULL;
  return hw_io_write_buffer (hw, source, space, addr, nr_bytes);
}



/* Abort the simulation specifying HW as the reason */

void
hw_vabort (struct hw *me,
	   const char *fmt,
	   va_list ap)
{
  const char *name;
  char *msg;
  /* find an identity */
  if (me != NULL && hw_path (me) != NULL && hw_path (me) [0] != '\0')
    name = hw_path (me);
  else if (me != NULL && hw_name (me) != NULL && hw_name (me)[0] != '\0')
    name = hw_name (me);
  else if (me != NULL && hw_family (me) != NULL && hw_family (me)[0] != '\0')
    name = hw_family (me);
  else
    name = "device";
  /* construct an updated format string */
  msg = alloca (strlen (name) + strlen (": ") + strlen (fmt) + 1);
  strcpy (msg, name);
  strcat (msg, ": ");
  strcat (msg, fmt);
  /* report the problem */
  sim_engine_vabort (hw_system (me),
		     STATE_HW (hw_system (me))->cpu,
		     STATE_HW (hw_system (me))->cia,
		     msg, ap);
}

void
hw_abort (struct hw *me,
	  const char *fmt,
	  ...)
{
  va_list ap;
  /* report the problem */
  va_start (ap, fmt);
  hw_vabort (me, fmt, ap);
  va_end (ap);
}

void
sim_hw_abort (struct sim_state *sd,
	      struct hw *me,
	      const char *fmt,
	      ...)
{
  va_list ap;
  va_start (ap, fmt);
  if (me == NULL)
    sim_engine_vabort (sd, NULL, NULL_CIA, fmt, ap);
  else
    hw_vabort (me, fmt, ap);
  va_end (ap);
}


/* MISC routines to tie HW into the rest of the system */

void
hw_halt (struct hw *me,
	 int reason,
	 int status)
{
  struct sim_state *sd = hw_system (me);
  struct sim_hw *sim = STATE_HW (sd);
  sim_engine_halt (sd, sim->cpu, NULL, sim->cia, reason, status);
}

struct _sim_cpu *
hw_system_cpu (struct hw *me)
{
  return STATE_HW (hw_system (me))->cpu;
}

void
hw_trace (struct hw *me,
	  const char *fmt,
	  ...)
{
  if (hw_trace_p (me)) /* to be sure, to be sure */
    {
      va_list ap;
      va_start (ap, fmt);
      sim_io_eprintf (hw_system (me), "%s: ", hw_path (me));
      sim_io_evprintf (hw_system (me), fmt, ap);
      sim_io_eprintf (hw_system (me), "\n");
      va_end (ap);
    }
}


/* Based on gdb-4.17/sim/ppc/main.c:sim_io_read_stdin() */

int
do_hw_poll_read (struct hw *me,
		 do_hw_poll_read_method *read,
		 int sim_io_fd,
		 void *buf,
		 unsigned sizeof_buf)
{
  int status = read (hw_system (me), sim_io_fd, buf, sizeof_buf);
  if (status > 0)
    return status;
  else if (status == 0 && sizeof_buf == 0)
    return 0;
  else if (status == 0)
    return HW_IO_EOF;
  else /* status < 0 */
    {
#ifdef EAGAIN
      if (STATE_CALLBACK (hw_system (me))->last_errno == EAGAIN)
	return HW_IO_NOT_READY;
      else
	return HW_IO_EOF;
#else
      return HW_IO_EOF;
#endif
    }
}
