]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - sim/common/hw-base.c
Updated copyright notices for most files.
[thirdparty/binutils-gdb.git] / sim / common / hw-base.c
index 495f96d4f8b5e55536237b9486d5d8afee6d3e19..1bbc424405149ac6c1e5084c64f52adba9b5ce79 100644 (file)
@@ -1,36 +1,28 @@
-/*  This file is part of the program psim.
+/* The common simulator framework for GDB, the GNU Debugger.
 
-    Copyright (C) 1994-1996, 1998, Andrew Cagney <cagney@highland.com.au>
+   Copyright 2002, 2007, 2008 Free Software Foundation, Inc.
 
-    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 2 of the License, or
-    (at your option) any later version.
+   Contributed by Andrew Cagney and Red Hat.
 
-    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, write to the Free Software
-    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-    */
+   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.
 
-#include "sim-main.h"
-#include "hw-base.h"
+   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"
 
-/* LATER: #include "hwconfig.h" */
-extern const struct hw_device_descriptor dv_core_descriptor[];
-extern const struct hw_device_descriptor dv_pal_descriptor[];
-const struct hw_device_descriptor *hw_descriptors[] = {
-  dv_core_descriptor,
-  dv_pal_descriptor,
-  NULL,
-};
 
 #ifdef HAVE_STRING_H
 #include <string.h>
@@ -46,9 +38,11 @@ const struct hw_device_descriptor *hw_descriptors[] = {
 
 #include <ctype.h>
 
+#include "hw-config.h"
+
 struct hw_base_data {
   int finished_p;
-  const struct hw_device_descriptor *descriptor;
+  const struct hw_descriptor *descriptor;
   hw_delete_callback *to_delete;
 };
 
@@ -222,9 +216,7 @@ panic_hw_io_read_buffer (struct hw *me,
                         void *dest,
                         int space,
                         unsigned_word addr,
-                        unsigned nr_bytes,
-                        sim_cpu *processor,
-                        sim_cia cia)
+                        unsigned nr_bytes)
 {
   hw_abort (me, "no io-read method");
   return 0;
@@ -235,9 +227,7 @@ panic_hw_io_write_buffer (struct hw *me,
                          const void *source,
                          int space,
                          unsigned_word addr,
-                         unsigned nr_bytes,
-                         sim_cpu *processor,
-                         sim_cia cia)
+                         unsigned nr_bytes)
 {
   hw_abort (me, "no io-write method");
   return 0;
@@ -272,22 +262,6 @@ passthrough_hw_dma_write_buffer (struct hw *me,
                              violate_read_only_section);
 }
 
-const struct hw_port_descriptor empty_hw_ports[] = {
-  { NULL, },
-};
-
-static void
-panic_hw_port_event (struct hw *me,
-                    int my_port,
-                    struct hw *source,
-                    int source_port,
-                    int level,
-                    sim_cpu *processor,
-                    sim_cia cia)
-{
-  hw_abort (me, "no port method");
-}
-
 static void
 ignore_hw_delete (struct hw *me)
 {
@@ -342,12 +316,12 @@ full_name_of_hw (struct hw *leaf,
   
   /* return it usefully */
   if (buf == full_name)
-    buf = (char *) strdup (full_name);
+    buf = hw_strdup (leaf, full_name);
   return buf;
 }
 
 struct hw *
-hw_create (SIM_DESC sd,
+hw_create (struct sim_state *sd,
           struct hw *parent,
           const char *family,
           const char *name,
@@ -358,9 +332,9 @@ hw_create (SIM_DESC sd,
   struct hw *hw = ZALLOC (struct hw);
 
   /* our identity */
-  hw->family_of_hw = family;
-  hw->name_of_hw = name;
-  hw->args_of_hw = args;
+  hw->family_of_hw = hw_strdup (hw, family);
+  hw->name_of_hw = hw_strdup (hw, name);
+  hw->args_of_hw = hw_strdup (hw, args);
 
   /* a hook into the system */
   if (sd != NULL)
@@ -420,12 +394,12 @@ hw_create (SIM_DESC sd,
 
   /* locate a descriptor */
   {
-    const struct hw_device_descriptor **table;
+    const struct hw_descriptor **table;
     for (table = hw_descriptors;
         *table != NULL;
         table++)
       {
-       const struct hw_device_descriptor *entry;
+       const struct hw_descriptor *entry;
        for (entry = *table;
             entry->family != NULL;
             entry++)
@@ -433,6 +407,7 @@ hw_create (SIM_DESC sd,
            if (strcmp (family, entry->family) == 0)
              {
                hw->base_of_hw->descriptor = entry;
+               break;
              }
          }
       }
@@ -443,8 +418,12 @@ hw_create (SIM_DESC sd,
   }
 
   /* Attach dummy ports */
-  set_hw_ports (hw, empty_hw_ports);
-  set_hw_port_event (hw, panic_hw_port_event);
+  create_hw_alloc_data (hw);
+  create_hw_property_data (hw);
+  create_hw_port_data (hw);
+  create_hw_event_data (hw);
+  create_hw_handle_data (hw);
+  create_hw_instance_data (hw);
   
   return hw;
 }
@@ -474,6 +453,16 @@ hw_finish (struct hw *me)
   else
     me->nr_size_cells_of_hw_unit = 1;
 
+  /* Fill in the (hopefully) defined trace variable */
+  if (hw_find_property (me, "trace?") != NULL)
+    me->trace_of_hw_p = hw_find_boolean_property (me, "trace?");
+  /* allow global variable to define default tracing */
+  else if (! hw_trace_p (me)
+          && hw_find_property (hw_root (me), "global-trace?") != NULL
+          && hw_find_boolean_property (hw_root (me), "global-trace?"))
+    me->trace_of_hw_p = 1;
+    
+
   /* Allow the real device to override any methods */
   me->base_of_hw->descriptor->to_finish (me);
   me->base_of_hw->finished_p = 1;
@@ -486,6 +475,12 @@ hw_delete (struct hw *me)
   /* give the object a chance to tidy up */
   me->base_of_hw->to_delete (me);
 
+  delete_hw_instance_data (me);
+  delete_hw_handle_data (me);
+  delete_hw_event_data (me);
+  delete_hw_port_data (me);
+  delete_hw_property_data (me);
+
   /* now unlink us from the tree */
   if (hw_parent (me))
     {
@@ -513,9 +508,70 @@ hw_delete (struct hw *me)
     }
 
   /* blow away all memory belonging to the device */
-  hw_free_all (me);
+  delete_hw_alloc_data (me);
 
   /* finally */
-  zfree (me->base_of_hw);
   zfree (me);
 }
+
+void
+set_hw_delete (struct hw *hw, hw_delete_callback method)
+{
+  hw->base_of_hw->to_delete = method;
+}
+
+
+/* Go through the devices various reg properties for those that
+   specify attach addresses */
+
+
+void
+do_hw_attach_regs (struct hw *hw)
+{
+  static const char *(reg_property_names[]) = {
+    "attach-addresses",
+    "assigned-addresses",
+    "reg",
+    "alternate-reg" ,
+    NULL
+  };
+  const char **reg_property_name;
+  int nr_valid_reg_properties = 0;
+  for (reg_property_name = reg_property_names;
+       *reg_property_name != NULL;
+       reg_property_name++)
+    {
+      if (hw_find_property (hw, *reg_property_name) != NULL)
+       {
+         reg_property_spec reg;
+         int reg_entry;
+         for (reg_entry = 0;
+              hw_find_reg_array_property (hw, *reg_property_name, reg_entry,
+                                          &reg);
+              reg_entry++)
+           {
+             unsigned_word attach_address;
+             int attach_space;
+             unsigned attach_size;
+             if (!hw_unit_address_to_attach_address (hw_parent (hw),
+                                                     &reg.address,
+                                                     &attach_space,
+                                                     &attach_address,
+                                                     hw))
+               continue;
+             if (!hw_unit_size_to_attach_size (hw_parent (hw),
+                                               &reg.size,
+                                               &attach_size, hw))
+               continue;
+             hw_attach_address (hw_parent (hw),
+                                0,
+                                attach_space, attach_address, attach_size,
+                                hw);
+             nr_valid_reg_properties++;
+           }
+         /* if first option matches don't try for any others */
+         if (reg_property_name == reg_property_names)
+           break;
+       }
+    }
+}