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

   Copyright 2002-2013 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/>.  */

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

#include "sim-io.h"
#include "sim-assert.h"

#ifdef HAVE_STRING_H
#include <string.h>
#else
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#endif

/* property entries */

struct hw_property_data
{
  struct hw_property_data *next;
  struct hw_property *property;
  const void *init_array;
  unsigned sizeof_init_array;
};

void
create_hw_property_data (struct hw *me)
{
}

void
delete_hw_property_data (struct hw *me)
{
}


/* Device Properties: */

static struct hw_property_data *
find_property_data (struct hw *me,
		    const char *property)
{
  struct hw_property_data *entry;
  ASSERT (property != NULL);
  entry = me->properties_of_hw;
  while (entry != NULL)
    {
      if (strcmp (entry->property->name, property) == 0)
	return entry;
      entry = entry->next;
    }
  return NULL;
}


static void
hw_add_property (struct hw *me,
		 const char *property,
		 hw_property_type type,
		 const void *init_array,
		 unsigned sizeof_init_array,
		 const void *array,
		 unsigned sizeof_array,
		 const struct hw_property *original,
		 object_disposition disposition)
{
  struct hw_property_data *new_entry = NULL;
  struct hw_property *new_value = NULL;

  /* find the list end */
  struct hw_property_data **insertion_point = &me->properties_of_hw;
  while (*insertion_point != NULL)
    {
      if (strcmp ((*insertion_point)->property->name, property) == 0)
	return;
      insertion_point = &(*insertion_point)->next;
    }

  /* create a new value */
  new_value = HW_ZALLOC (me, struct hw_property);
  new_value->name = (char *) strdup (property);
  new_value->type = type;
  if (sizeof_array > 0)
    {
      void *new_array = hw_zalloc (me, sizeof_array);
      memcpy (new_array, array, sizeof_array);
      new_value->array = new_array;
      new_value->sizeof_array = sizeof_array;
    }
  new_value->owner = me;
  new_value->original = original;
  new_value->disposition = disposition;

  /* insert the value into the list */
  new_entry = HW_ZALLOC (me, struct hw_property_data);
  *insertion_point = new_entry;
  if (sizeof_init_array > 0)
    {
      void *new_init_array = hw_zalloc (me, sizeof_init_array);
      memcpy (new_init_array, init_array, sizeof_init_array);
      new_entry->init_array = new_init_array;
      new_entry->sizeof_init_array = sizeof_init_array;
    }
  new_entry->property = new_value;
}


static void
hw_set_property (struct hw *me,
		 const char *property,
		 hw_property_type type,
		 const void *array,
		 int sizeof_array)
{
  /* find the property */
  struct hw_property_data *entry = find_property_data (me, property);
  if (entry != NULL)
    {
      /* existing property - update it */
      void *new_array = 0;
      struct hw_property *value = entry->property;
      /* check the type matches */
      if (value->type != type)
	hw_abort (me, "conflict between type of new and old value for property %s", property);
      /* replace its value */
      if (value->array != NULL)
	hw_free (me, (void*)value->array);
      new_array = (sizeof_array > 0
		   ? hw_zalloc (me, sizeof_array)
		   : (void*)0);
      value->array = new_array;
      value->sizeof_array = sizeof_array;
      if (sizeof_array > 0)
	memcpy (new_array, array, sizeof_array);
      return;
    }
  else
    {
      /* new property - create it */
      hw_add_property (me, property, type,
		       NULL, 0, array, sizeof_array,
		       NULL, temporary_object);
    }
}


#if 0
static void
clean_hw_properties (struct hw *me)
{
  struct hw_property_data **delete_point = &me->properties_of_hw;
  while (*delete_point != NULL)
    {
      struct hw_property_data *current = *delete_point;
      switch (current->property->disposition)
	{
	case permenant_object:
	  /* zap the current value, will be initialized later */
	  ASSERT (current->init_array != NULL);
	  if (current->property->array != NULL)
	    {
	      hw_free (me, (void*)current->property->array);
	      current->property->array = NULL;
	    }
	  delete_point = &(*delete_point)->next;
	  break;
	case temporary_object:
	  /* zap the actual property, was created during simulation run */
	  ASSERT (current->init_array == NULL);
	  *delete_point = current->next;
	  if (current->property->array != NULL)
	    hw_free (me, (void*)current->property->array);
	  hw_free (me, current->property);
	  hw_free (me, current);
	  break;
	}
    }
}
#endif

#if 0
void
hw_init_static_properties (SIM_DESC sd,
			   struct hw *me,
			   void *data)
{
  struct hw_property_data *property;
  for (property = me->properties_of_hw;
       property != NULL;
       property = property->next)
    {
      ASSERT (property->init_array != NULL);
      ASSERT (property->property->array == NULL);
      ASSERT (property->property->disposition == permenant_object);
      switch (property->property->type)
	{
	case array_property:
	case boolean_property:
	case range_array_property:
	case reg_array_property:
	case string_property:
	case string_array_property:
	case integer_property:
	  /* delete the property, and replace it with the original */
	  hw_set_property (me, property->property->name,
			   property->property->type,
			   property->init_array,
			   property->sizeof_init_array);
	  break;
#if 0
	case ihandle_property:
	  break;
#endif
	}
    }
}
#endif


#if 0
void
hw_init_runtime_properties (SIM_DESC sd,
			    struct hw *me,
			    void *data)
{
  struct hw_property_data *property;
  for (property = me->properties_of_hw;
       property != NULL;
       property = property->next)
    {
      switch (property->property->disposition)
	{
	case permenant_object:
	  switch (property->property->type)
	    {
#if 0
	    case ihandle_property:
	      {
		struct hw_instance *ihandle;
		ihandle_runtime_property_spec spec;
		ASSERT (property->init_array != NULL);
		ASSERT (property->property->array == NULL);
		hw_find_ihandle_runtime_property (me, property->property->name, &spec);
		ihandle = tree_instance (me, spec.full_path);
		hw_set_ihandle_property (me, property->property->name, ihandle);
		break;
	      }
#endif
	    case array_property:
	    case boolean_property:
	    case range_array_property:
	    case integer_property:
	    case reg_array_property:
	    case string_property:
	    case string_array_property:
	      ASSERT (property->init_array != NULL);
	      ASSERT (property->property->array != NULL);
	      break;
	    }
	  break;
	case temporary_object:
	  ASSERT (property->init_array == NULL);
	  ASSERT (property->property->array != NULL);
	  break;
	}
    }
}
#endif



const struct hw_property *
hw_next_property (const struct hw_property *property)
{
  /* find the property in the list */
  struct hw *owner = property->owner;
  struct hw_property_data *entry = owner->properties_of_hw;
  while (entry != NULL && entry->property != property)
    entry = entry->next;
  /* now return the following property */
  ASSERT (entry != NULL); /* must be a member! */
  if (entry->next != NULL)
    return entry->next->property;
  else
    return NULL;
}


const struct hw_property *
hw_find_property (struct hw *me,
		  const char *property)
{
  if (me == NULL)
    {
      return NULL;
    }
  else if (property == NULL || strcmp (property, "") == 0)
    {
      if (me->properties_of_hw == NULL)
	return NULL;
      else
	return me->properties_of_hw->property;
    }
  else
    {
      struct hw_property_data *entry = find_property_data (me, property);
      if (entry != NULL)
	return entry->property;
    }
  return NULL;
}


void
hw_add_array_property (struct hw *me,
		       const char *property,
		       const void *array,
		       int sizeof_array)
{
  hw_add_property (me, property, array_property,
		   array, sizeof_array, array, sizeof_array,
		   NULL, permenant_object);
}

void
hw_set_array_property (struct hw *me,
		       const char *property,
		       const void *array,
		       int sizeof_array)
{
  hw_set_property (me, property, array_property, array, sizeof_array);
}

const struct hw_property *
hw_find_array_property (struct hw *me,
			const char *property)
{
  const struct hw_property *node;
  node = hw_find_property (me, property);
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != array_property)
    hw_abort (me, "property \"%s\" of wrong type (array)", property);
  return node;
}



void
hw_add_boolean_property (struct hw *me,
			 const char *property,
			 int boolean)
{
  signed32 new_boolean = (boolean ? -1 : 0);
  hw_add_property (me, property, boolean_property,
		   &new_boolean, sizeof (new_boolean),
		   &new_boolean, sizeof (new_boolean),
		   NULL, permenant_object);
}

int
hw_find_boolean_property (struct hw *me,
			  const char *property)
{
  const struct hw_property *node;
  unsigned_cell boolean;
  node = hw_find_property (me, property);
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != boolean_property)
    hw_abort (me, "property \"%s\" of wrong type (boolean)", property);
  ASSERT (sizeof (boolean) == node->sizeof_array);
  memcpy (&boolean, node->array, sizeof (boolean));
  return boolean;
}



#if 0
void
hw_add_ihandle_runtime_property (struct hw *me,
				 const char *property,
				 const ihandle_runtime_property_spec *ihandle)
{
  /* enter the full path as the init array */
  hw_add_property (me, property, ihandle_property,
		   ihandle->full_path, strlen (ihandle->full_path) + 1,
		   NULL, 0,
		   NULL, permenant_object);
}
#endif

#if 0
void
hw_find_ihandle_runtime_property (struct hw *me,
				  const char *property,
				  ihandle_runtime_property_spec *ihandle)
{
  struct hw_property_data *entry = find_property_data (me, property);
  HW_TRACE ((me, "hw_find_ihandle_runtime_property(property=%s)\n", property));
  if (entry == NULL)
    hw_abort (me, "property \"%s\" not found", property);
  if (entry->property->type != ihandle_property
      || entry->property->disposition != permenant_object)
    hw_abort (me, "property \"%s\" of wrong type", property);
  ASSERT (entry->init_array != NULL);
  /* the full path */
  ihandle->full_path = entry->init_array;
}
#endif



#if 0
void
hw_set_ihandle_property (struct hw *me,
			 const char *property,
			 hw_instance *ihandle)
{
  unsigned_cell cells;
  cells = H2BE_cell (hw_instance_to_external (ihandle));
  hw_set_property (me, property, ihandle_property,
		   &cells, sizeof (cells));

}
#endif

#if 0
hw_instance *
hw_find_ihandle_property (struct hw *me,
			  const char *property)
{
  const hw_property_data *node;
  unsigned_cell ihandle;
  hw_instance *instance;

  node = hw_find_property (me, property);
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != ihandle_property)
    hw_abort (me, "property \"%s\" of wrong type (ihandle)", property);
  if (node->array == NULL)
    hw_abort (me, "runtime property \"%s\" not yet initialized", property);

  ASSERT (sizeof (ihandle) == node->sizeof_array);
  memcpy (&ihandle, node->array, sizeof (ihandle));
  instance = external_to_hw_instance (me, BE2H_cell (ihandle));
  ASSERT (instance != NULL);
  return instance;
}
#endif


void
hw_add_integer_property (struct hw *me,
			 const char *property,
			 signed_cell integer)
{
  H2BE (integer);
  hw_add_property (me, property, integer_property,
		   &integer, sizeof (integer),
		   &integer, sizeof (integer),
		   NULL, permenant_object);
}

signed_cell
hw_find_integer_property (struct hw *me,
			  const char *property)
{
  const struct hw_property *node;
  signed_cell integer;
  HW_TRACE ((me, "hw_find_integer(property=%s)\n", property));
  node = hw_find_property (me, property);
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != integer_property)
    hw_abort (me, "property \"%s\" of wrong type (integer)", property);
  ASSERT (sizeof (integer) == node->sizeof_array);
  memcpy (&integer, node->array, sizeof (integer));
  return BE2H_cell (integer);
}

int
hw_find_integer_array_property (struct hw *me,
				const char *property,
				unsigned index,
				signed_cell *integer)
{
  const struct hw_property *node;
  int sizeof_integer = sizeof (*integer);
  signed_cell *cell;
  HW_TRACE ((me, "hw_find_integer(property=%s)\n", property));

  /* check things sane */
  node = hw_find_property (me, property);
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != integer_property
      && node->type != array_property)
    hw_abort (me, "property \"%s\" of wrong type (integer or array)", property);
  if ((node->sizeof_array % sizeof_integer) != 0)
    hw_abort (me, "property \"%s\" contains an incomplete number of cells", property);
  if (node->sizeof_array <= sizeof_integer * index)
    return 0;

  /* Find and convert the value */
  cell = ((signed_cell*)node->array) + index;
  *integer = BE2H_cell (*cell);

  return node->sizeof_array / sizeof_integer;
}


static unsigned_cell *
unit_address_to_cells (const hw_unit *unit,
		       unsigned_cell *cell,
		       int nr_cells)
{
  int i;
  ASSERT (nr_cells == unit->nr_cells);
  for (i = 0; i < unit->nr_cells; i++)
    {
      *cell = H2BE_cell (unit->cells[i]);
      cell += 1;
    }
  return cell;
}


static const unsigned_cell *
cells_to_unit_address (const unsigned_cell *cell,
		       hw_unit *unit,
		       int nr_cells)
{
  int i;
  memset (unit, 0, sizeof (*unit));
  unit->nr_cells = nr_cells;
  for (i = 0; i < unit->nr_cells; i++)
    {
      unit->cells[i] = BE2H_cell (*cell);
      cell += 1;
    }
  return cell;
}


static unsigned
nr_range_property_cells (struct hw *me,
			 int nr_ranges)
{
  return ((hw_unit_nr_address_cells (me)
	   + hw_unit_nr_address_cells (hw_parent (me))
	   + hw_unit_nr_size_cells (me))
	  ) * nr_ranges;
}

void
hw_add_range_array_property (struct hw *me,
			     const char *property,
			     const range_property_spec *ranges,
			     unsigned nr_ranges)
{
  unsigned sizeof_cells = (nr_range_property_cells (me, nr_ranges)
			   * sizeof (unsigned_cell));
  unsigned_cell *cells = hw_zalloc (me, sizeof_cells);
  unsigned_cell *cell;
  int i;

  /* copy the property elements over */
  cell = cells;
  for (i = 0; i < nr_ranges; i++)
    {
      const range_property_spec *range = &ranges[i];
      /* copy the child address */
      cell = unit_address_to_cells (&range->child_address, cell,
				    hw_unit_nr_address_cells (me));
      /* copy the parent address */
      cell = unit_address_to_cells (&range->parent_address, cell,
				    hw_unit_nr_address_cells (hw_parent (me)));
      /* copy the size */
      cell = unit_address_to_cells (&range->size, cell,
				    hw_unit_nr_size_cells (me));
    }
  ASSERT (cell == &cells[nr_range_property_cells (me, nr_ranges)]);

  /* add it */
  hw_add_property (me, property, range_array_property,
		   cells, sizeof_cells,
		   cells, sizeof_cells,
		   NULL, permenant_object);

  hw_free (me, cells);
}

int
hw_find_range_array_property (struct hw *me,
			      const char *property,
			      unsigned index,
			      range_property_spec *range)
{
  const struct hw_property *node;
  unsigned sizeof_entry = (nr_range_property_cells (me, 1)
			   * sizeof (unsigned_cell));
  const unsigned_cell *cells;

  /* locate the property */
  node = hw_find_property (me, property);
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != range_array_property)
    hw_abort (me, "property \"%s\" of wrong type (range array)", property);

  /* aligned ? */
  if ((node->sizeof_array % sizeof_entry) != 0)
    hw_abort (me, "property \"%s\" contains an incomplete number of entries",
	      property);

  /* within bounds? */
  if (node->sizeof_array < sizeof_entry * (index + 1))
    return 0;

  /* find the range of interest */
  cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index);

  /* copy the child address out - converting as we go */
  cells = cells_to_unit_address (cells, &range->child_address,
				 hw_unit_nr_address_cells (me));

  /* copy the parent address out - converting as we go */
  cells = cells_to_unit_address (cells, &range->parent_address,
				 hw_unit_nr_address_cells (hw_parent (me)));

  /* copy the size - converting as we go */
  cells = cells_to_unit_address (cells, &range->size,
				 hw_unit_nr_size_cells (me));

  return node->sizeof_array / sizeof_entry;
}


static unsigned
nr_reg_property_cells (struct hw *me,
		       int nr_regs)
{
  return (hw_unit_nr_address_cells (hw_parent (me))
	  + hw_unit_nr_size_cells (hw_parent (me))
	  ) * nr_regs;
}

void
hw_add_reg_array_property (struct hw *me,
			   const char *property,
			   const reg_property_spec *regs,
			   unsigned nr_regs)
{
  unsigned sizeof_cells = (nr_reg_property_cells (me, nr_regs)
			   * sizeof (unsigned_cell));
  unsigned_cell *cells = hw_zalloc (me, sizeof_cells);
  unsigned_cell *cell;
  int i;

  /* copy the property elements over */
  cell = cells;
  for (i = 0; i < nr_regs; i++)
    {
      const reg_property_spec *reg = &regs[i];
      /* copy the address */
      cell = unit_address_to_cells (&reg->address, cell,
				    hw_unit_nr_address_cells (hw_parent (me)));
      /* copy the size */
      cell = unit_address_to_cells (&reg->size, cell,
				    hw_unit_nr_size_cells (hw_parent (me)));
    }
  ASSERT (cell == &cells[nr_reg_property_cells (me, nr_regs)]);

  /* add it */
  hw_add_property (me, property, reg_array_property,
		   cells, sizeof_cells,
		   cells, sizeof_cells,
		   NULL, permenant_object);

  hw_free (me, cells);
}

int
hw_find_reg_array_property (struct hw *me,
			    const char *property,
			    unsigned index,
			    reg_property_spec *reg)
{
  const struct hw_property *node;
  unsigned sizeof_entry = (nr_reg_property_cells (me, 1)
			   * sizeof (unsigned_cell));
  const unsigned_cell *cells;

  /* locate the property */
  node = hw_find_property (me, property);
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != reg_array_property)
    hw_abort (me, "property \"%s\" of wrong type (reg array)", property);

  /* aligned ? */
  if ((node->sizeof_array % sizeof_entry) != 0)
    hw_abort (me, "property \"%s\" contains an incomplete number of entries",
	      property);

  /* within bounds? */
  if (node->sizeof_array < sizeof_entry * (index + 1))
    return 0;

  /* find the range of interest */
  cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index);

  /* copy the address out - converting as we go */
  cells = cells_to_unit_address (cells, &reg->address,
				 hw_unit_nr_address_cells (hw_parent (me)));

  /* copy the size out - converting as we go */
  cells = cells_to_unit_address (cells, &reg->size,
				 hw_unit_nr_size_cells (hw_parent (me)));

  return node->sizeof_array / sizeof_entry;
}


void
hw_add_string_property (struct hw *me,
			const char *property,
			const char *string)
{
  hw_add_property (me, property, string_property,
		   string, strlen (string) + 1,
		   string, strlen (string) + 1,
		   NULL, permenant_object);
}

const char *
hw_find_string_property (struct hw *me,
			 const char *property)
{
  const struct hw_property *node;
  const char *string;
  node = hw_find_property (me, property);
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != string_property)
    hw_abort (me, "property \"%s\" of wrong type (string)", property);
  string = node->array;
  ASSERT (strlen (string) + 1 == node->sizeof_array);
  return string;
}

void
hw_add_string_array_property (struct hw *me,
			      const char *property,
			      const string_property_spec *strings,
			      unsigned nr_strings)
{
  int sizeof_array;
  int string_nr;
  char *array;
  char *chp;
  if (nr_strings == 0)
    hw_abort (me, "property \"%s\" must be non-null", property);
  /* total up the size of the needed array */
  for (sizeof_array = 0, string_nr = 0;
       string_nr < nr_strings;
       string_nr ++)
    {
      sizeof_array += strlen (strings[string_nr]) + 1;
    }
  /* create the array */
  array = (char*) hw_zalloc (me, sizeof_array);
  chp = array;
  for (string_nr = 0;
       string_nr < nr_strings;
       string_nr++)
    {
      strcpy (chp, strings[string_nr]);
      chp += strlen (chp) + 1;
    }
  ASSERT (chp == array + sizeof_array);
  /* now enter it */
  hw_add_property (me, property, string_array_property,
		   array, sizeof_array,
		   array, sizeof_array,
		   NULL, permenant_object);
}

int
hw_find_string_array_property (struct hw *me,
			       const char *property,
			       unsigned index,
			       string_property_spec *string)
{
  const struct hw_property *node;
  node = hw_find_property (me, property);
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
  switch (node->type)
    {
    default:
      hw_abort (me, "property \"%s\" of wrong type", property);
      break;
    case string_property:
      if (index == 0)
	{
	  *string = node->array;
	  ASSERT (strlen (*string) + 1 == node->sizeof_array);
	  return 1;
	}
      break;
    case array_property:
      if (node->sizeof_array == 0
	  || ((char*)node->array)[node->sizeof_array - 1] != '\0')
	hw_abort (me, "property \"%s\" invalid for string array", property);
      /* FALL THROUGH */
    case string_array_property:
      ASSERT (node->sizeof_array > 0);
      ASSERT (((char*)node->array)[node->sizeof_array - 1] == '\0');
      {
	const char *chp = node->array;
	int nr_entries = 0;
	/* count the number of strings, keeping an eye out for the one
	   we're looking for */
	*string = chp;
	do
	  {
	    if (*chp == '\0')
	      {
		/* next string */
		nr_entries++;
		chp++;
		if (nr_entries == index)
		  *string = chp;
	      }
	    else
	      {
		chp++;
	      }
	  } while (chp < (char*)node->array + node->sizeof_array);
	if (index < nr_entries)
	  return nr_entries;
	else
	  {
	    *string = NULL;
	    return 0;
	  }
      }
      break;
    }
  return 0;
}

void
hw_add_duplicate_property (struct hw *me,
			   const char *property,
			   const struct hw_property *original)
{
  struct hw_property_data *master;
  HW_TRACE ((me, "hw_add_duplicate_property(property=%s, ...)\n", property));
  if (original->disposition != permenant_object)
    hw_abort (me, "Can only duplicate permenant objects");
  /* find the original's master */
  master = original->owner->properties_of_hw;
  while (master->property != original)
    {
      master = master->next;
      ASSERT (master != NULL);
    }
  /* now duplicate it */
  hw_add_property (me, property,
		   original->type,
		   master->init_array, master->sizeof_init_array,
		   original->array, original->sizeof_array,
		   original, permenant_object);
}
