OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [sim/] [common/] [hw-properties.c] - Diff between revs 227 and 816

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 227 Rev 816
/* The common simulator framework for GDB, the GNU Debugger.
/* The common simulator framework for GDB, the GNU Debugger.
 
 
   Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
   Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
 
   Contributed by Andrew Cagney and Red Hat.
   Contributed by Andrew Cagney and Red Hat.
 
 
   This file is part of GDB.
   This file is part of GDB.
 
 
   This program is free software; you can redistribute it and/or modify
   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
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
#include "hw-main.h"
#include "hw-main.h"
#include "hw-base.h"
#include "hw-base.h"
 
 
#include "sim-io.h"
#include "sim-io.h"
#include "sim-assert.h"
#include "sim-assert.h"
 
 
#ifdef HAVE_STRING_H
#ifdef HAVE_STRING_H
#include <string.h>
#include <string.h>
#else
#else
#ifdef HAVE_STRINGS_H
#ifdef HAVE_STRINGS_H
#include <strings.h>
#include <strings.h>
#endif
#endif
#endif
#endif
 
 
#define TRACE(A,B)
#define TRACE(A,B)
 
 
/* property entries */
/* property entries */
 
 
struct hw_property_data {
struct hw_property_data {
  struct hw_property_data *next;
  struct hw_property_data *next;
  struct hw_property *property;
  struct hw_property *property;
  const void *init_array;
  const void *init_array;
  unsigned sizeof_init_array;
  unsigned sizeof_init_array;
};
};
 
 
void
void
create_hw_property_data (struct hw *me)
create_hw_property_data (struct hw *me)
{
{
}
}
 
 
void
void
delete_hw_property_data (struct hw *me)
delete_hw_property_data (struct hw *me)
{
{
}
}
 
 
 
 
/* Device Properties: */
/* Device Properties: */
 
 
static struct hw_property_data *
static struct hw_property_data *
find_property_data (struct hw *me,
find_property_data (struct hw *me,
                    const char *property)
                    const char *property)
{
{
  struct hw_property_data *entry;
  struct hw_property_data *entry;
  ASSERT (property != NULL);
  ASSERT (property != NULL);
  entry = me->properties_of_hw;
  entry = me->properties_of_hw;
  while (entry != NULL)
  while (entry != NULL)
    {
    {
      if (strcmp (entry->property->name, property) == 0)
      if (strcmp (entry->property->name, property) == 0)
        return entry;
        return entry;
      entry = entry->next;
      entry = entry->next;
    }
    }
  return NULL;
  return NULL;
}
}
 
 
 
 
static void
static void
hw_add_property (struct hw *me,
hw_add_property (struct hw *me,
                 const char *property,
                 const char *property,
                 hw_property_type type,
                 hw_property_type type,
                 const void *init_array,
                 const void *init_array,
                 unsigned sizeof_init_array,
                 unsigned sizeof_init_array,
                 const void *array,
                 const void *array,
                 unsigned sizeof_array,
                 unsigned sizeof_array,
                 const struct hw_property *original,
                 const struct hw_property *original,
                 object_disposition disposition)
                 object_disposition disposition)
{
{
  struct hw_property_data *new_entry = NULL;
  struct hw_property_data *new_entry = NULL;
  struct hw_property *new_value = NULL;
  struct hw_property *new_value = NULL;
 
 
  /* find the list end */
  /* find the list end */
  struct hw_property_data **insertion_point = &me->properties_of_hw;
  struct hw_property_data **insertion_point = &me->properties_of_hw;
  while (*insertion_point != NULL)
  while (*insertion_point != NULL)
    {
    {
      if (strcmp ((*insertion_point)->property->name, property) == 0)
      if (strcmp ((*insertion_point)->property->name, property) == 0)
        return;
        return;
      insertion_point = &(*insertion_point)->next;
      insertion_point = &(*insertion_point)->next;
    }
    }
 
 
  /* create a new value */
  /* create a new value */
  new_value = HW_ZALLOC (me, struct hw_property);
  new_value = HW_ZALLOC (me, struct hw_property);
  new_value->name = (char *) strdup (property);
  new_value->name = (char *) strdup (property);
  new_value->type = type;
  new_value->type = type;
  if (sizeof_array > 0)
  if (sizeof_array > 0)
    {
    {
      void *new_array = hw_zalloc (me, sizeof_array);
      void *new_array = hw_zalloc (me, sizeof_array);
      memcpy (new_array, array, sizeof_array);
      memcpy (new_array, array, sizeof_array);
      new_value->array = new_array;
      new_value->array = new_array;
      new_value->sizeof_array = sizeof_array;
      new_value->sizeof_array = sizeof_array;
    }
    }
  new_value->owner = me;
  new_value->owner = me;
  new_value->original = original;
  new_value->original = original;
  new_value->disposition = disposition;
  new_value->disposition = disposition;
 
 
  /* insert the value into the list */
  /* insert the value into the list */
  new_entry = HW_ZALLOC (me, struct hw_property_data);
  new_entry = HW_ZALLOC (me, struct hw_property_data);
  *insertion_point = new_entry;
  *insertion_point = new_entry;
  if (sizeof_init_array > 0)
  if (sizeof_init_array > 0)
    {
    {
      void *new_init_array = hw_zalloc (me, sizeof_init_array);
      void *new_init_array = hw_zalloc (me, sizeof_init_array);
      memcpy (new_init_array, init_array, sizeof_init_array);
      memcpy (new_init_array, init_array, sizeof_init_array);
      new_entry->init_array = new_init_array;
      new_entry->init_array = new_init_array;
      new_entry->sizeof_init_array = sizeof_init_array;
      new_entry->sizeof_init_array = sizeof_init_array;
    }
    }
  new_entry->property = new_value;
  new_entry->property = new_value;
}
}
 
 
 
 
static void
static void
hw_set_property (struct hw *me,
hw_set_property (struct hw *me,
                 const char *property,
                 const char *property,
                 hw_property_type type,
                 hw_property_type type,
                 const void *array,
                 const void *array,
                 int sizeof_array)
                 int sizeof_array)
{
{
  /* find the property */
  /* find the property */
  struct hw_property_data *entry = find_property_data (me, property);
  struct hw_property_data *entry = find_property_data (me, property);
  if (entry != NULL)
  if (entry != NULL)
    {
    {
      /* existing property - update it */
      /* existing property - update it */
      void *new_array = 0;
      void *new_array = 0;
      struct hw_property *value = entry->property;
      struct hw_property *value = entry->property;
      /* check the type matches */
      /* check the type matches */
      if (value->type != type)
      if (value->type != type)
        hw_abort (me, "conflict between type of new and old value for property %s", property);
        hw_abort (me, "conflict between type of new and old value for property %s", property);
      /* replace its value */
      /* replace its value */
      if (value->array != NULL)
      if (value->array != NULL)
        hw_free (me, (void*)value->array);
        hw_free (me, (void*)value->array);
      new_array = (sizeof_array > 0
      new_array = (sizeof_array > 0
                   ? hw_zalloc (me, sizeof_array)
                   ? hw_zalloc (me, sizeof_array)
                   : (void*)0);
                   : (void*)0);
      value->array = new_array;
      value->array = new_array;
      value->sizeof_array = sizeof_array;
      value->sizeof_array = sizeof_array;
      if (sizeof_array > 0)
      if (sizeof_array > 0)
        memcpy (new_array, array, sizeof_array);
        memcpy (new_array, array, sizeof_array);
      return;
      return;
    }
    }
  else
  else
    {
    {
      /* new property - create it */
      /* new property - create it */
      hw_add_property (me, property, type,
      hw_add_property (me, property, type,
                       NULL, 0, array, sizeof_array,
                       NULL, 0, array, sizeof_array,
                       NULL, temporary_object);
                       NULL, temporary_object);
    }
    }
}
}
 
 
 
 
#if 0
#if 0
static void
static void
clean_hw_properties (struct hw *me)
clean_hw_properties (struct hw *me)
{
{
  struct hw_property_data **delete_point = &me->properties_of_hw;
  struct hw_property_data **delete_point = &me->properties_of_hw;
  while (*delete_point != NULL)
  while (*delete_point != NULL)
    {
    {
      struct hw_property_data *current = *delete_point;
      struct hw_property_data *current = *delete_point;
      switch (current->property->disposition)
      switch (current->property->disposition)
        {
        {
        case permenant_object:
        case permenant_object:
          /* zap the current value, will be initialized later */
          /* zap the current value, will be initialized later */
          ASSERT (current->init_array != NULL);
          ASSERT (current->init_array != NULL);
          if (current->property->array != NULL)
          if (current->property->array != NULL)
            {
            {
              hw_free (me, (void*)current->property->array);
              hw_free (me, (void*)current->property->array);
              current->property->array = NULL;
              current->property->array = NULL;
            }
            }
          delete_point = &(*delete_point)->next;
          delete_point = &(*delete_point)->next;
          break;
          break;
        case temporary_object:
        case temporary_object:
          /* zap the actual property, was created during simulation run */
          /* zap the actual property, was created during simulation run */
          ASSERT (current->init_array == NULL);
          ASSERT (current->init_array == NULL);
          *delete_point = current->next;
          *delete_point = current->next;
          if (current->property->array != NULL)
          if (current->property->array != NULL)
            hw_free (me, (void*)current->property->array);
            hw_free (me, (void*)current->property->array);
          hw_free (me, current->property);
          hw_free (me, current->property);
          hw_free (me, current);
          hw_free (me, current);
          break;
          break;
        }
        }
    }
    }
}
}
#endif
#endif
 
 
#if 0
#if 0
void
void
hw_init_static_properties (SIM_DESC sd,
hw_init_static_properties (SIM_DESC sd,
                           struct hw *me,
                           struct hw *me,
                           void *data)
                           void *data)
{
{
  struct hw_property_data *property;
  struct hw_property_data *property;
  for (property = me->properties_of_hw;
  for (property = me->properties_of_hw;
       property != NULL;
       property != NULL;
       property = property->next)
       property = property->next)
    {
    {
      ASSERT (property->init_array != NULL);
      ASSERT (property->init_array != NULL);
      ASSERT (property->property->array == NULL);
      ASSERT (property->property->array == NULL);
      ASSERT(property->property->disposition == permenant_object);
      ASSERT(property->property->disposition == permenant_object);
      switch (property->property->type)
      switch (property->property->type)
        {
        {
        case array_property:
        case array_property:
        case boolean_property:
        case boolean_property:
        case range_array_property:
        case range_array_property:
        case reg_array_property:
        case reg_array_property:
        case string_property:
        case string_property:
        case string_array_property:
        case string_array_property:
        case integer_property:
        case integer_property:
          /* delete the property, and replace it with the original */
          /* delete the property, and replace it with the original */
          hw_set_property (me, property->property->name,
          hw_set_property (me, property->property->name,
                           property->property->type,
                           property->property->type,
                           property->init_array,
                           property->init_array,
                           property->sizeof_init_array);
                           property->sizeof_init_array);
          break;
          break;
#if 0
#if 0
        case ihandle_property:
        case ihandle_property:
          break;
          break;
#endif
#endif
        }
        }
    }
    }
}
}
#endif
#endif
 
 
 
 
#if 0
#if 0
void
void
hw_init_runtime_properties (SIM_DESC sd,
hw_init_runtime_properties (SIM_DESC sd,
                            struct hw *me,
                            struct hw *me,
                            void *data)
                            void *data)
{
{
  struct hw_property_data *property;
  struct hw_property_data *property;
  for (property = me->properties_of_hw;
  for (property = me->properties_of_hw;
       property != NULL;
       property != NULL;
       property = property->next)
       property = property->next)
    {
    {
      switch (property->property->disposition)
      switch (property->property->disposition)
        {
        {
        case permenant_object:
        case permenant_object:
          switch (property->property->type)
          switch (property->property->type)
            {
            {
#if 0
#if 0
            case ihandle_property:
            case ihandle_property:
              {
              {
                struct hw_instance *ihandle;
                struct hw_instance *ihandle;
                ihandle_runtime_property_spec spec;
                ihandle_runtime_property_spec spec;
                ASSERT (property->init_array != NULL);
                ASSERT (property->init_array != NULL);
                ASSERT (property->property->array == NULL);
                ASSERT (property->property->array == NULL);
                hw_find_ihandle_runtime_property (me, property->property->name, &spec);
                hw_find_ihandle_runtime_property (me, property->property->name, &spec);
                ihandle = tree_instance (me, spec.full_path);
                ihandle = tree_instance (me, spec.full_path);
                hw_set_ihandle_property (me, property->property->name, ihandle);
                hw_set_ihandle_property (me, property->property->name, ihandle);
                break;
                break;
              }
              }
#endif
#endif
            case array_property:
            case array_property:
            case boolean_property:
            case boolean_property:
            case range_array_property:
            case range_array_property:
            case integer_property:
            case integer_property:
            case reg_array_property:
            case reg_array_property:
            case string_property:
            case string_property:
            case string_array_property:
            case string_array_property:
              ASSERT (property->init_array != NULL);
              ASSERT (property->init_array != NULL);
              ASSERT (property->property->array != NULL);
              ASSERT (property->property->array != NULL);
              break;
              break;
            }
            }
          break;
          break;
        case temporary_object:
        case temporary_object:
          ASSERT (property->init_array == NULL);
          ASSERT (property->init_array == NULL);
          ASSERT (property->property->array != NULL);
          ASSERT (property->property->array != NULL);
          break;
          break;
        }
        }
    }
    }
}
}
#endif
#endif
 
 
 
 
 
 
const struct hw_property *
const struct hw_property *
hw_next_property (const struct hw_property *property)
hw_next_property (const struct hw_property *property)
{
{
  /* find the property in the list */
  /* find the property in the list */
  struct hw *owner = property->owner;
  struct hw *owner = property->owner;
  struct hw_property_data *entry = owner->properties_of_hw;
  struct hw_property_data *entry = owner->properties_of_hw;
  while (entry != NULL && entry->property != property)
  while (entry != NULL && entry->property != property)
    entry = entry->next;
    entry = entry->next;
  /* now return the following property */
  /* now return the following property */
  ASSERT (entry != NULL); /* must be a member! */
  ASSERT (entry != NULL); /* must be a member! */
  if (entry->next != NULL)
  if (entry->next != NULL)
    return entry->next->property;
    return entry->next->property;
  else
  else
    return NULL;
    return NULL;
}
}
 
 
 
 
const struct hw_property *
const struct hw_property *
hw_find_property (struct hw *me,
hw_find_property (struct hw *me,
                  const char *property)
                  const char *property)
{
{
  if (me == NULL)
  if (me == NULL)
    {
    {
      return NULL;
      return NULL;
    }
    }
  else if (property == NULL || strcmp (property, "") == 0)
  else if (property == NULL || strcmp (property, "") == 0)
    {
    {
      if (me->properties_of_hw == NULL)
      if (me->properties_of_hw == NULL)
        return NULL;
        return NULL;
      else
      else
        return me->properties_of_hw->property;
        return me->properties_of_hw->property;
    }
    }
  else
  else
    {
    {
      struct hw_property_data *entry = find_property_data (me, property);
      struct hw_property_data *entry = find_property_data (me, property);
      if (entry != NULL)
      if (entry != NULL)
        return entry->property;
        return entry->property;
    }
    }
  return NULL;
  return NULL;
}
}
 
 
 
 
void
void
hw_add_array_property (struct hw *me,
hw_add_array_property (struct hw *me,
                       const char *property,
                       const char *property,
                       const void *array,
                       const void *array,
                       int sizeof_array)
                       int sizeof_array)
{
{
  hw_add_property (me, property, array_property,
  hw_add_property (me, property, array_property,
                   array, sizeof_array, array, sizeof_array,
                   array, sizeof_array, array, sizeof_array,
                   NULL, permenant_object);
                   NULL, permenant_object);
}
}
 
 
void
void
hw_set_array_property (struct hw *me,
hw_set_array_property (struct hw *me,
                       const char *property,
                       const char *property,
                       const void *array,
                       const void *array,
                       int sizeof_array)
                       int sizeof_array)
{
{
  hw_set_property (me, property, array_property, array, sizeof_array);
  hw_set_property (me, property, array_property, array, sizeof_array);
}
}
 
 
const struct hw_property *
const struct hw_property *
hw_find_array_property (struct hw *me,
hw_find_array_property (struct hw *me,
                        const char *property)
                        const char *property)
{
{
  const struct hw_property *node;
  const struct hw_property *node;
  node = hw_find_property (me, property);
  node = hw_find_property (me, property);
  if (node == NULL)
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != array_property)
  if (node->type != array_property)
    hw_abort (me, "property \"%s\" of wrong type (array)", property);
    hw_abort (me, "property \"%s\" of wrong type (array)", property);
  return node;
  return node;
}
}
 
 
 
 
 
 
void
void
hw_add_boolean_property (struct hw *me,
hw_add_boolean_property (struct hw *me,
                         const char *property,
                         const char *property,
                         int boolean)
                         int boolean)
{
{
  signed32 new_boolean = (boolean ? -1 : 0);
  signed32 new_boolean = (boolean ? -1 : 0);
  hw_add_property (me, property, boolean_property,
  hw_add_property (me, property, boolean_property,
                   &new_boolean, sizeof(new_boolean),
                   &new_boolean, sizeof(new_boolean),
                   &new_boolean, sizeof(new_boolean),
                   &new_boolean, sizeof(new_boolean),
                   NULL, permenant_object);
                   NULL, permenant_object);
}
}
 
 
int
int
hw_find_boolean_property (struct hw *me,
hw_find_boolean_property (struct hw *me,
                          const char *property)
                          const char *property)
{
{
  const struct hw_property *node;
  const struct hw_property *node;
  unsigned_cell boolean;
  unsigned_cell boolean;
  node = hw_find_property (me, property);
  node = hw_find_property (me, property);
  if (node == NULL)
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != boolean_property)
  if (node->type != boolean_property)
    hw_abort (me, "property \"%s\" of wrong type (boolean)", property);
    hw_abort (me, "property \"%s\" of wrong type (boolean)", property);
  ASSERT (sizeof (boolean) == node->sizeof_array);
  ASSERT (sizeof (boolean) == node->sizeof_array);
  memcpy (&boolean, node->array, sizeof (boolean));
  memcpy (&boolean, node->array, sizeof (boolean));
  return boolean;
  return boolean;
}
}
 
 
 
 
 
 
#if 0
#if 0
void
void
hw_add_ihandle_runtime_property (struct hw *me,
hw_add_ihandle_runtime_property (struct hw *me,
                                 const char *property,
                                 const char *property,
                                 const ihandle_runtime_property_spec *ihandle)
                                 const ihandle_runtime_property_spec *ihandle)
{
{
  /* enter the full path as the init array */
  /* enter the full path as the init array */
  hw_add_property (me, property, ihandle_property,
  hw_add_property (me, property, ihandle_property,
                   ihandle->full_path, strlen(ihandle->full_path) + 1,
                   ihandle->full_path, strlen(ihandle->full_path) + 1,
                   NULL, 0,
                   NULL, 0,
                   NULL, permenant_object);
                   NULL, permenant_object);
}
}
#endif
#endif
 
 
#if 0
#if 0
void
void
hw_find_ihandle_runtime_property (struct hw *me,
hw_find_ihandle_runtime_property (struct hw *me,
                                  const char *property,
                                  const char *property,
                                  ihandle_runtime_property_spec *ihandle)
                                  ihandle_runtime_property_spec *ihandle)
{
{
  struct hw_property_data *entry = find_property_data (me, property);
  struct hw_property_data *entry = find_property_data (me, property);
  TRACE (trace_devices,
  TRACE (trace_devices,
         ("hw_find_ihandle_runtime_property(me=0x%lx, property=%s)\n",
         ("hw_find_ihandle_runtime_property(me=0x%lx, property=%s)\n",
          (long)me, property));
          (long)me, property));
  if (entry == NULL)
  if (entry == NULL)
    hw_abort (me, "property \"%s\" not found", property);
    hw_abort (me, "property \"%s\" not found", property);
  if (entry->property->type != ihandle_property
  if (entry->property->type != ihandle_property
      || entry->property->disposition != permenant_object)
      || entry->property->disposition != permenant_object)
    hw_abort (me, "property \"%s\" of wrong type", property);
    hw_abort (me, "property \"%s\" of wrong type", property);
  ASSERT (entry->init_array != NULL);
  ASSERT (entry->init_array != NULL);
  /* the full path */
  /* the full path */
  ihandle->full_path = entry->init_array;
  ihandle->full_path = entry->init_array;
}
}
#endif
#endif
 
 
 
 
 
 
#if 0
#if 0
void
void
hw_set_ihandle_property (struct hw *me,
hw_set_ihandle_property (struct hw *me,
                         const char *property,
                         const char *property,
                         hw_instance *ihandle)
                         hw_instance *ihandle)
{
{
  unsigned_cell cells;
  unsigned_cell cells;
  cells = H2BE_cell (hw_instance_to_external (ihandle));
  cells = H2BE_cell (hw_instance_to_external (ihandle));
  hw_set_property (me, property, ihandle_property,
  hw_set_property (me, property, ihandle_property,
                   &cells, sizeof (cells));
                   &cells, sizeof (cells));
 
 
}
}
#endif
#endif
 
 
#if 0
#if 0
hw_instance *
hw_instance *
hw_find_ihandle_property (struct hw *me,
hw_find_ihandle_property (struct hw *me,
                          const char *property)
                          const char *property)
{
{
  const hw_property_data *node;
  const hw_property_data *node;
  unsigned_cell ihandle;
  unsigned_cell ihandle;
  hw_instance *instance;
  hw_instance *instance;
 
 
  node = hw_find_property (me, property);
  node = hw_find_property (me, property);
  if (node == NULL)
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != ihandle_property)
  if (node->type != ihandle_property)
    hw_abort(me, "property \"%s\" of wrong type (ihandle)", property);
    hw_abort(me, "property \"%s\" of wrong type (ihandle)", property);
  if (node->array == NULL)
  if (node->array == NULL)
    hw_abort(me, "runtime property \"%s\" not yet initialized", property);
    hw_abort(me, "runtime property \"%s\" not yet initialized", property);
 
 
  ASSERT (sizeof(ihandle) == node->sizeof_array);
  ASSERT (sizeof(ihandle) == node->sizeof_array);
  memcpy (&ihandle, node->array, sizeof(ihandle));
  memcpy (&ihandle, node->array, sizeof(ihandle));
  instance = external_to_hw_instance (me, BE2H_cell(ihandle));
  instance = external_to_hw_instance (me, BE2H_cell(ihandle));
  ASSERT (instance != NULL);
  ASSERT (instance != NULL);
  return instance;
  return instance;
}
}
#endif
#endif
 
 
 
 
void
void
hw_add_integer_property (struct hw *me,
hw_add_integer_property (struct hw *me,
                         const char *property,
                         const char *property,
                         signed_cell integer)
                         signed_cell integer)
{
{
  H2BE (integer);
  H2BE (integer);
  hw_add_property (me, property, integer_property,
  hw_add_property (me, property, integer_property,
                   &integer, sizeof(integer),
                   &integer, sizeof(integer),
                   &integer, sizeof(integer),
                   &integer, sizeof(integer),
                   NULL, permenant_object);
                   NULL, permenant_object);
}
}
 
 
signed_cell
signed_cell
hw_find_integer_property (struct hw *me,
hw_find_integer_property (struct hw *me,
                          const char *property)
                          const char *property)
{
{
  const struct hw_property *node;
  const struct hw_property *node;
  signed_cell integer;
  signed_cell integer;
  TRACE (trace_devices,
  TRACE (trace_devices,
         ("hw_find_integer(me=0x%lx, property=%s)\n",
         ("hw_find_integer(me=0x%lx, property=%s)\n",
          (long)me, property));
          (long)me, property));
  node = hw_find_property (me, property);
  node = hw_find_property (me, property);
  if (node == NULL)
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != integer_property)
  if (node->type != integer_property)
    hw_abort (me, "property \"%s\" of wrong type (integer)", property);
    hw_abort (me, "property \"%s\" of wrong type (integer)", property);
  ASSERT (sizeof(integer) == node->sizeof_array);
  ASSERT (sizeof(integer) == node->sizeof_array);
  memcpy (&integer, node->array, sizeof (integer));
  memcpy (&integer, node->array, sizeof (integer));
  return BE2H_cell (integer);
  return BE2H_cell (integer);
}
}
 
 
int
int
hw_find_integer_array_property (struct hw *me,
hw_find_integer_array_property (struct hw *me,
                                const char *property,
                                const char *property,
                                unsigned index,
                                unsigned index,
                                signed_cell *integer)
                                signed_cell *integer)
{
{
  const struct hw_property *node;
  const struct hw_property *node;
  int sizeof_integer = sizeof (*integer);
  int sizeof_integer = sizeof (*integer);
  signed_cell *cell;
  signed_cell *cell;
  TRACE (trace_devices,
  TRACE (trace_devices,
         ("hw_find_integer(me=0x%lx, property=%s)\n",
         ("hw_find_integer(me=0x%lx, property=%s)\n",
          (long)me, property));
          (long)me, property));
 
 
  /* check things sane */
  /* check things sane */
  node = hw_find_property (me, property);
  node = hw_find_property (me, property);
  if (node == NULL)
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != integer_property
  if (node->type != integer_property
      && node->type != array_property)
      && node->type != array_property)
    hw_abort (me, "property \"%s\" of wrong type (integer or array)", property);
    hw_abort (me, "property \"%s\" of wrong type (integer or array)", property);
  if ((node->sizeof_array % sizeof_integer) != 0)
  if ((node->sizeof_array % sizeof_integer) != 0)
    hw_abort (me, "property \"%s\" contains an incomplete number of cells", property);
    hw_abort (me, "property \"%s\" contains an incomplete number of cells", property);
  if (node->sizeof_array <= sizeof_integer * index)
  if (node->sizeof_array <= sizeof_integer * index)
    return 0;
    return 0;
 
 
  /* Find and convert the value */
  /* Find and convert the value */
  cell = ((signed_cell*)node->array) + index;
  cell = ((signed_cell*)node->array) + index;
  *integer = BE2H_cell (*cell);
  *integer = BE2H_cell (*cell);
 
 
  return node->sizeof_array / sizeof_integer;
  return node->sizeof_array / sizeof_integer;
}
}
 
 
 
 
static unsigned_cell *
static unsigned_cell *
unit_address_to_cells (const hw_unit *unit,
unit_address_to_cells (const hw_unit *unit,
                       unsigned_cell *cell,
                       unsigned_cell *cell,
                       int nr_cells)
                       int nr_cells)
{
{
  int i;
  int i;
  ASSERT(nr_cells == unit->nr_cells);
  ASSERT(nr_cells == unit->nr_cells);
  for (i = 0; i < unit->nr_cells; i++)
  for (i = 0; i < unit->nr_cells; i++)
    {
    {
      *cell = H2BE_cell (unit->cells[i]);
      *cell = H2BE_cell (unit->cells[i]);
      cell += 1;
      cell += 1;
    }
    }
  return cell;
  return cell;
}
}
 
 
 
 
static const unsigned_cell *
static const unsigned_cell *
cells_to_unit_address (const unsigned_cell *cell,
cells_to_unit_address (const unsigned_cell *cell,
                       hw_unit *unit,
                       hw_unit *unit,
                       int nr_cells)
                       int nr_cells)
{
{
  int i;
  int i;
  memset(unit, 0, sizeof(*unit));
  memset(unit, 0, sizeof(*unit));
  unit->nr_cells = nr_cells;
  unit->nr_cells = nr_cells;
  for (i = 0; i < unit->nr_cells; i++)
  for (i = 0; i < unit->nr_cells; i++)
    {
    {
      unit->cells[i] = BE2H_cell (*cell);
      unit->cells[i] = BE2H_cell (*cell);
      cell += 1;
      cell += 1;
    }
    }
  return cell;
  return cell;
}
}
 
 
 
 
static unsigned
static unsigned
nr_range_property_cells (struct hw *me,
nr_range_property_cells (struct hw *me,
                         int nr_ranges)
                         int nr_ranges)
{
{
  return ((hw_unit_nr_address_cells (me)
  return ((hw_unit_nr_address_cells (me)
           + hw_unit_nr_address_cells (hw_parent (me))
           + hw_unit_nr_address_cells (hw_parent (me))
           + hw_unit_nr_size_cells (me))
           + hw_unit_nr_size_cells (me))
          ) * nr_ranges;
          ) * nr_ranges;
}
}
 
 
void
void
hw_add_range_array_property (struct hw *me,
hw_add_range_array_property (struct hw *me,
                             const char *property,
                             const char *property,
                             const range_property_spec *ranges,
                             const range_property_spec *ranges,
                             unsigned nr_ranges)
                             unsigned nr_ranges)
{
{
  unsigned sizeof_cells = (nr_range_property_cells (me, nr_ranges)
  unsigned sizeof_cells = (nr_range_property_cells (me, nr_ranges)
                           * sizeof (unsigned_cell));
                           * sizeof (unsigned_cell));
  unsigned_cell *cells = hw_zalloc (me, sizeof_cells);
  unsigned_cell *cells = hw_zalloc (me, sizeof_cells);
  unsigned_cell *cell;
  unsigned_cell *cell;
  int i;
  int i;
 
 
  /* copy the property elements over */
  /* copy the property elements over */
  cell = cells;
  cell = cells;
  for (i = 0; i < nr_ranges; i++)
  for (i = 0; i < nr_ranges; i++)
    {
    {
      const range_property_spec *range = &ranges[i];
      const range_property_spec *range = &ranges[i];
      /* copy the child address */
      /* copy the child address */
      cell = unit_address_to_cells (&range->child_address, cell,
      cell = unit_address_to_cells (&range->child_address, cell,
                                    hw_unit_nr_address_cells (me));
                                    hw_unit_nr_address_cells (me));
      /* copy the parent address */
      /* copy the parent address */
      cell = unit_address_to_cells (&range->parent_address, cell,
      cell = unit_address_to_cells (&range->parent_address, cell,
                                    hw_unit_nr_address_cells (hw_parent (me)));
                                    hw_unit_nr_address_cells (hw_parent (me)));
      /* copy the size */
      /* copy the size */
      cell = unit_address_to_cells (&range->size, cell,
      cell = unit_address_to_cells (&range->size, cell,
                                    hw_unit_nr_size_cells (me));
                                    hw_unit_nr_size_cells (me));
    }
    }
  ASSERT (cell == &cells[nr_range_property_cells (me, nr_ranges)]);
  ASSERT (cell == &cells[nr_range_property_cells (me, nr_ranges)]);
 
 
  /* add it */
  /* add it */
  hw_add_property (me, property, range_array_property,
  hw_add_property (me, property, range_array_property,
                   cells, sizeof_cells,
                   cells, sizeof_cells,
                   cells, sizeof_cells,
                   cells, sizeof_cells,
                   NULL, permenant_object);
                   NULL, permenant_object);
 
 
  hw_free (me, cells);
  hw_free (me, cells);
}
}
 
 
int
int
hw_find_range_array_property (struct hw *me,
hw_find_range_array_property (struct hw *me,
                              const char *property,
                              const char *property,
                              unsigned index,
                              unsigned index,
                              range_property_spec *range)
                              range_property_spec *range)
{
{
  const struct hw_property *node;
  const struct hw_property *node;
  unsigned sizeof_entry = (nr_range_property_cells (me, 1)
  unsigned sizeof_entry = (nr_range_property_cells (me, 1)
                           * sizeof (unsigned_cell));
                           * sizeof (unsigned_cell));
  const unsigned_cell *cells;
  const unsigned_cell *cells;
 
 
  /* locate the property */
  /* locate the property */
  node = hw_find_property (me, property);
  node = hw_find_property (me, property);
  if (node == NULL)
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != range_array_property)
  if (node->type != range_array_property)
    hw_abort (me, "property \"%s\" of wrong type (range array)", property);
    hw_abort (me, "property \"%s\" of wrong type (range array)", property);
 
 
  /* aligned ? */
  /* aligned ? */
  if ((node->sizeof_array % sizeof_entry) != 0)
  if ((node->sizeof_array % sizeof_entry) != 0)
    hw_abort (me, "property \"%s\" contains an incomplete number of entries",
    hw_abort (me, "property \"%s\" contains an incomplete number of entries",
              property);
              property);
 
 
  /* within bounds? */
  /* within bounds? */
  if (node->sizeof_array < sizeof_entry * (index + 1))
  if (node->sizeof_array < sizeof_entry * (index + 1))
    return 0;
    return 0;
 
 
  /* find the range of interest */
  /* find the range of interest */
  cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index);
  cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index);
 
 
  /* copy the child address out - converting as we go */
  /* copy the child address out - converting as we go */
  cells = cells_to_unit_address (cells, &range->child_address,
  cells = cells_to_unit_address (cells, &range->child_address,
                                 hw_unit_nr_address_cells (me));
                                 hw_unit_nr_address_cells (me));
 
 
  /* copy the parent address out - converting as we go */
  /* copy the parent address out - converting as we go */
  cells = cells_to_unit_address (cells, &range->parent_address,
  cells = cells_to_unit_address (cells, &range->parent_address,
                                 hw_unit_nr_address_cells (hw_parent (me)));
                                 hw_unit_nr_address_cells (hw_parent (me)));
 
 
  /* copy the size - converting as we go */
  /* copy the size - converting as we go */
  cells = cells_to_unit_address (cells, &range->size,
  cells = cells_to_unit_address (cells, &range->size,
                                 hw_unit_nr_size_cells (me));
                                 hw_unit_nr_size_cells (me));
 
 
  return node->sizeof_array / sizeof_entry;
  return node->sizeof_array / sizeof_entry;
}
}
 
 
 
 
static unsigned
static unsigned
nr_reg_property_cells (struct hw *me,
nr_reg_property_cells (struct hw *me,
                       int nr_regs)
                       int nr_regs)
{
{
  return (hw_unit_nr_address_cells (hw_parent(me))
  return (hw_unit_nr_address_cells (hw_parent(me))
          + hw_unit_nr_size_cells (hw_parent(me))
          + hw_unit_nr_size_cells (hw_parent(me))
          ) * nr_regs;
          ) * nr_regs;
}
}
 
 
void
void
hw_add_reg_array_property (struct hw *me,
hw_add_reg_array_property (struct hw *me,
                           const char *property,
                           const char *property,
                           const reg_property_spec *regs,
                           const reg_property_spec *regs,
                           unsigned nr_regs)
                           unsigned nr_regs)
{
{
  unsigned sizeof_cells = (nr_reg_property_cells (me, nr_regs)
  unsigned sizeof_cells = (nr_reg_property_cells (me, nr_regs)
                           * sizeof (unsigned_cell));
                           * sizeof (unsigned_cell));
  unsigned_cell *cells = hw_zalloc (me, sizeof_cells);
  unsigned_cell *cells = hw_zalloc (me, sizeof_cells);
  unsigned_cell *cell;
  unsigned_cell *cell;
  int i;
  int i;
 
 
  /* copy the property elements over */
  /* copy the property elements over */
  cell = cells;
  cell = cells;
  for (i = 0; i < nr_regs; i++)
  for (i = 0; i < nr_regs; i++)
    {
    {
      const reg_property_spec *reg = &regs[i];
      const reg_property_spec *reg = &regs[i];
      /* copy the address */
      /* copy the address */
      cell = unit_address_to_cells (&reg->address, cell,
      cell = unit_address_to_cells (&reg->address, cell,
                                    hw_unit_nr_address_cells (hw_parent (me)));
                                    hw_unit_nr_address_cells (hw_parent (me)));
      /* copy the size */
      /* copy the size */
      cell = unit_address_to_cells (&reg->size, cell,
      cell = unit_address_to_cells (&reg->size, cell,
                                    hw_unit_nr_size_cells (hw_parent (me)));
                                    hw_unit_nr_size_cells (hw_parent (me)));
    }
    }
  ASSERT (cell == &cells[nr_reg_property_cells (me, nr_regs)]);
  ASSERT (cell == &cells[nr_reg_property_cells (me, nr_regs)]);
 
 
  /* add it */
  /* add it */
  hw_add_property (me, property, reg_array_property,
  hw_add_property (me, property, reg_array_property,
                   cells, sizeof_cells,
                   cells, sizeof_cells,
                   cells, sizeof_cells,
                   cells, sizeof_cells,
                   NULL, permenant_object);
                   NULL, permenant_object);
 
 
  hw_free (me, cells);
  hw_free (me, cells);
}
}
 
 
int
int
hw_find_reg_array_property (struct hw *me,
hw_find_reg_array_property (struct hw *me,
                            const char *property,
                            const char *property,
                            unsigned index,
                            unsigned index,
                            reg_property_spec *reg)
                            reg_property_spec *reg)
{
{
  const struct hw_property *node;
  const struct hw_property *node;
  unsigned sizeof_entry = (nr_reg_property_cells (me, 1)
  unsigned sizeof_entry = (nr_reg_property_cells (me, 1)
                           * sizeof (unsigned_cell));
                           * sizeof (unsigned_cell));
  const unsigned_cell *cells;
  const unsigned_cell *cells;
 
 
  /* locate the property */
  /* locate the property */
  node = hw_find_property (me, property);
  node = hw_find_property (me, property);
  if (node == NULL)
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != reg_array_property)
  if (node->type != reg_array_property)
    hw_abort (me, "property \"%s\" of wrong type (reg array)", property);
    hw_abort (me, "property \"%s\" of wrong type (reg array)", property);
 
 
  /* aligned ? */
  /* aligned ? */
  if ((node->sizeof_array % sizeof_entry) != 0)
  if ((node->sizeof_array % sizeof_entry) != 0)
    hw_abort (me, "property \"%s\" contains an incomplete number of entries",
    hw_abort (me, "property \"%s\" contains an incomplete number of entries",
              property);
              property);
 
 
  /* within bounds? */
  /* within bounds? */
  if (node->sizeof_array < sizeof_entry * (index + 1))
  if (node->sizeof_array < sizeof_entry * (index + 1))
    return 0;
    return 0;
 
 
  /* find the range of interest */
  /* find the range of interest */
  cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index);
  cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index);
 
 
  /* copy the address out - converting as we go */
  /* copy the address out - converting as we go */
  cells = cells_to_unit_address (cells, &reg->address,
  cells = cells_to_unit_address (cells, &reg->address,
                                 hw_unit_nr_address_cells (hw_parent (me)));
                                 hw_unit_nr_address_cells (hw_parent (me)));
 
 
  /* copy the size out - converting as we go */
  /* copy the size out - converting as we go */
  cells = cells_to_unit_address (cells, &reg->size,
  cells = cells_to_unit_address (cells, &reg->size,
                                 hw_unit_nr_size_cells (hw_parent (me)));
                                 hw_unit_nr_size_cells (hw_parent (me)));
 
 
  return node->sizeof_array / sizeof_entry;
  return node->sizeof_array / sizeof_entry;
}
}
 
 
 
 
void
void
hw_add_string_property (struct hw *me,
hw_add_string_property (struct hw *me,
                        const char *property,
                        const char *property,
                        const char *string)
                        const char *string)
{
{
  hw_add_property (me, property, string_property,
  hw_add_property (me, property, string_property,
                   string, strlen(string) + 1,
                   string, strlen(string) + 1,
                   string, strlen(string) + 1,
                   string, strlen(string) + 1,
                   NULL, permenant_object);
                   NULL, permenant_object);
}
}
 
 
const char *
const char *
hw_find_string_property (struct hw *me,
hw_find_string_property (struct hw *me,
                         const char *property)
                         const char *property)
{
{
  const struct hw_property *node;
  const struct hw_property *node;
  const char *string;
  const char *string;
  node = hw_find_property (me, property);
  node = hw_find_property (me, property);
  if (node == NULL)
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
    hw_abort (me, "property \"%s\" not found", property);
  if (node->type != string_property)
  if (node->type != string_property)
    hw_abort (me, "property \"%s\" of wrong type (string)", property);
    hw_abort (me, "property \"%s\" of wrong type (string)", property);
  string = node->array;
  string = node->array;
  ASSERT (strlen(string) + 1 == node->sizeof_array);
  ASSERT (strlen(string) + 1 == node->sizeof_array);
  return string;
  return string;
}
}
 
 
void
void
hw_add_string_array_property (struct hw *me,
hw_add_string_array_property (struct hw *me,
                              const char *property,
                              const char *property,
                              const string_property_spec *strings,
                              const string_property_spec *strings,
                              unsigned nr_strings)
                              unsigned nr_strings)
{
{
  int sizeof_array;
  int sizeof_array;
  int string_nr;
  int string_nr;
  char *array;
  char *array;
  char *chp;
  char *chp;
  if (nr_strings == 0)
  if (nr_strings == 0)
    hw_abort (me, "property \"%s\" must be non-null", property);
    hw_abort (me, "property \"%s\" must be non-null", property);
  /* total up the size of the needed array */
  /* total up the size of the needed array */
  for (sizeof_array = 0, string_nr = 0;
  for (sizeof_array = 0, string_nr = 0;
       string_nr < nr_strings;
       string_nr < nr_strings;
       string_nr ++)
       string_nr ++)
    {
    {
      sizeof_array += strlen (strings[string_nr]) + 1;
      sizeof_array += strlen (strings[string_nr]) + 1;
    }
    }
  /* create the array */
  /* create the array */
  array = (char*) hw_zalloc (me, sizeof_array);
  array = (char*) hw_zalloc (me, sizeof_array);
  chp = array;
  chp = array;
  for (string_nr = 0;
  for (string_nr = 0;
       string_nr < nr_strings;
       string_nr < nr_strings;
       string_nr++)
       string_nr++)
    {
    {
      strcpy (chp, strings[string_nr]);
      strcpy (chp, strings[string_nr]);
      chp += strlen (chp) + 1;
      chp += strlen (chp) + 1;
    }
    }
  ASSERT (chp == array + sizeof_array);
  ASSERT (chp == array + sizeof_array);
  /* now enter it */
  /* now enter it */
  hw_add_property (me, property, string_array_property,
  hw_add_property (me, property, string_array_property,
                   array, sizeof_array,
                   array, sizeof_array,
                   array, sizeof_array,
                   array, sizeof_array,
                   NULL, permenant_object);
                   NULL, permenant_object);
}
}
 
 
int
int
hw_find_string_array_property (struct hw *me,
hw_find_string_array_property (struct hw *me,
                               const char *property,
                               const char *property,
                               unsigned index,
                               unsigned index,
                               string_property_spec *string)
                               string_property_spec *string)
{
{
  const struct hw_property *node;
  const struct hw_property *node;
  node = hw_find_property (me, property);
  node = hw_find_property (me, property);
  if (node == NULL)
  if (node == NULL)
    hw_abort (me, "property \"%s\" not found", property);
    hw_abort (me, "property \"%s\" not found", property);
  switch (node->type)
  switch (node->type)
    {
    {
    default:
    default:
      hw_abort (me, "property \"%s\" of wrong type", property);
      hw_abort (me, "property \"%s\" of wrong type", property);
      break;
      break;
    case string_property:
    case string_property:
      if (index == 0)
      if (index == 0)
        {
        {
          *string = node->array;
          *string = node->array;
          ASSERT (strlen(*string) + 1 == node->sizeof_array);
          ASSERT (strlen(*string) + 1 == node->sizeof_array);
          return 1;
          return 1;
        }
        }
      break;
      break;
    case array_property:
    case array_property:
      if (node->sizeof_array == 0
      if (node->sizeof_array == 0
          || ((char*)node->array)[node->sizeof_array - 1] != '\0')
          || ((char*)node->array)[node->sizeof_array - 1] != '\0')
        hw_abort (me, "property \"%s\" invalid for string array", property);
        hw_abort (me, "property \"%s\" invalid for string array", property);
      /* FALL THROUGH */
      /* FALL THROUGH */
    case string_array_property:
    case string_array_property:
      ASSERT (node->sizeof_array > 0);
      ASSERT (node->sizeof_array > 0);
      ASSERT (((char*)node->array)[node->sizeof_array - 1] == '\0');
      ASSERT (((char*)node->array)[node->sizeof_array - 1] == '\0');
      {
      {
        const char *chp = node->array;
        const char *chp = node->array;
        int nr_entries = 0;
        int nr_entries = 0;
        /* count the number of strings, keeping an eye out for the one
        /* count the number of strings, keeping an eye out for the one
           we're looking for */
           we're looking for */
        *string = chp;
        *string = chp;
        do
        do
          {
          {
            if (*chp == '\0')
            if (*chp == '\0')
              {
              {
                /* next string */
                /* next string */
                nr_entries++;
                nr_entries++;
                chp++;
                chp++;
                if (nr_entries == index)
                if (nr_entries == index)
                  *string = chp;
                  *string = chp;
              }
              }
            else
            else
              {
              {
                chp++;
                chp++;
              }
              }
          } while (chp < (char*)node->array + node->sizeof_array);
          } while (chp < (char*)node->array + node->sizeof_array);
        if (index < nr_entries)
        if (index < nr_entries)
          return nr_entries;
          return nr_entries;
        else
        else
          {
          {
            *string = NULL;
            *string = NULL;
            return 0;
            return 0;
          }
          }
      }
      }
      break;
      break;
    }
    }
  return 0;
  return 0;
}
}
 
 
void
void
hw_add_duplicate_property (struct hw *me,
hw_add_duplicate_property (struct hw *me,
                           const char *property,
                           const char *property,
                           const struct hw_property *original)
                           const struct hw_property *original)
{
{
  struct hw_property_data *master;
  struct hw_property_data *master;
  TRACE (trace_devices,
  TRACE (trace_devices,
         ("hw_add_duplicate_property(me=0x%lx, property=%s, ...)\n",
         ("hw_add_duplicate_property(me=0x%lx, property=%s, ...)\n",
          (long)me, property));
          (long)me, property));
  if (original->disposition != permenant_object)
  if (original->disposition != permenant_object)
    hw_abort (me, "Can only duplicate permenant objects");
    hw_abort (me, "Can only duplicate permenant objects");
  /* find the original's master */
  /* find the original's master */
  master = original->owner->properties_of_hw;
  master = original->owner->properties_of_hw;
  while (master->property != original)
  while (master->property != original)
    {
    {
      master = master->next;
      master = master->next;
      ASSERT(master != NULL);
      ASSERT(master != NULL);
    }
    }
  /* now duplicate it */
  /* now duplicate it */
  hw_add_property (me, property,
  hw_add_property (me, property,
                   original->type,
                   original->type,
                   master->init_array, master->sizeof_init_array,
                   master->init_array, master->sizeof_init_array,
                   original->array, original->sizeof_array,
                   original->array, original->sizeof_array,
                   original, permenant_object);
                   original, permenant_object);
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.