Home | History | Annotate | Line # | Download | only in common
      1 /* The common simulator framework for GDB, the GNU Debugger.
      2 
      3    Copyright 2002-2024 Free Software Foundation, Inc.
      4 
      5    Contributed by Andrew Cagney and Red Hat.
      6 
      7    This file is part of GDB.
      8 
      9    This program is free software; you can redistribute it and/or modify
     10    it under the terms of the GNU General Public License as published by
     11    the Free Software Foundation; either version 3 of the License, or
     12    (at your option) any later version.
     13 
     14    This program is distributed in the hope that it will be useful,
     15    but WITHOUT ANY WARRANTY; without even the implied warranty of
     16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17    GNU General Public License for more details.
     18 
     19    You should have received a copy of the GNU General Public License
     20    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     21 
     22 /* This must come before any other includes.  */
     23 #include "defs.h"
     24 
     25 #include "hw-main.h"
     26 #include "hw-base.h"
     27 
     28 #include "sim-io.h"
     29 #include "sim-assert.h"
     30 
     31 struct hw_instance_data
     32 {
     33   hw_finish_instance_method *to_finish;
     34   struct hw_instance *instances;
     35 };
     36 
     37 static hw_finish_instance_method abort_hw_finish_instance;
     38 
     39 void
     40 create_hw_instance_data (struct hw *me)
     41 {
     42   me->instances_of_hw = HW_ZALLOC (me, struct hw_instance_data);
     43   set_hw_finish_instance (me, abort_hw_finish_instance);
     44 }
     45 
     46 void
     47 delete_hw_instance_data (struct hw *me)
     48 {
     49   /* NOP */
     50 }
     51 
     52 
     53 static void
     54 abort_hw_finish_instance (struct hw *hw,
     55 			  struct hw_instance *instance)
     56 {
     57   hw_abort (hw, "no instance finish method");
     58 }
     59 
     60 void
     61 set_hw_finish_instance (struct hw *me,
     62 			hw_finish_instance_method *finish)
     63 {
     64   me->instances_of_hw->to_finish = finish;
     65 }
     66 
     67 
     68 #if 0
     69 void
     70 clean_hw_instances (struct hw *me)
     71 {
     72   struct hw_instance **instance = &me->instances;
     73   while (*instance != NULL)
     74     {
     75       struct hw_instance *old_instance = *instance;
     76       hw_instance_delete (old_instance);
     77       instance = &me->instances;
     78     }
     79 }
     80 #endif
     81 
     82 
     83 void
     84 hw_instance_delete (struct hw_instance *instance)
     85 {
     86 #if 1
     87   hw_abort (hw_instance_hw (instance), "not implemented");
     88 #else
     89   struct hw *me = hw_instance_hw (instance);
     90   if (instance->to_instance_delete == NULL)
     91     hw_abort (me, "no delete method");
     92   instance->method->delete (instance);
     93   if (instance->args != NULL)
     94     free (instance->args);
     95   if (instance->path != NULL)
     96     free (instance->path);
     97   if (instance->child == NULL)
     98     {
     99       /* only remove leaf nodes */
    100       struct hw_instance **curr = &me->instances;
    101       while (*curr != instance)
    102 	{
    103 	  ASSERT (*curr != NULL);
    104 	  curr = &(*curr)->next;
    105 	}
    106       *curr = instance->next;
    107     }
    108   else
    109     {
    110       /* check it isn't in the instance list */
    111       struct hw_instance *curr = me->instances;
    112       while (curr != NULL)
    113 	{
    114 	  ASSERT (curr != instance);
    115 	  curr = curr->next;
    116 	}
    117       /* unlink the child */
    118       ASSERT (instance->child->parent == instance);
    119       instance->child->parent = NULL;
    120     }
    121   cap_remove (me->ihandles, instance);
    122   free (instance);
    123 #endif
    124 }
    125 
    126 
    127 static int
    128 panic_hw_instance_read (struct hw_instance *instance,
    129 			void *addr,
    130 			unsigned_word len)
    131 {
    132   hw_abort (hw_instance_hw (instance), "no read method");
    133   return -1;
    134 }
    135 
    136 
    137 
    138 static int
    139 panic_hw_instance_write (struct hw_instance *instance,
    140 			 const void *addr,
    141 			 unsigned_word len)
    142 {
    143   hw_abort (hw_instance_hw (instance), "no write method");
    144   return -1;
    145 }
    146 
    147 
    148 static int
    149 panic_hw_instance_seek (struct hw_instance *instance,
    150 			unsigned_word pos_hi,
    151 			unsigned_word pos_lo)
    152 {
    153   hw_abort (hw_instance_hw (instance), "no seek method");
    154   return -1;
    155 }
    156 
    157 
    158 int
    159 hw_instance_call_method (struct hw_instance *instance,
    160 			 const char *method_name,
    161 			 int n_stack_args,
    162 			 unsigned_cell stack_args[/*n_stack_args*/],
    163 			 int n_stack_returns,
    164 			 unsigned_cell stack_returns[/*n_stack_args*/])
    165 {
    166 #if 1
    167   hw_abort (hw_instance_hw (instance), "not implemented");
    168   return -1;
    169 #else
    170   struct hw *me = instance->owner;
    171   const hw_instance_methods *method = instance->method->methods;
    172   if (method == NULL)
    173     {
    174       hw_abort (me, "no methods (want %s)", method_name);
    175     }
    176   while (method->name != NULL)
    177     {
    178       if (strcmp (method->name, method_name) == 0)
    179 	{
    180 	  return method->method (instance,
    181 				 n_stack_args, stack_args,
    182 				 n_stack_returns, stack_returns);
    183 	}
    184       method++;
    185     }
    186   hw_abort (me, "no %s method", method_name);
    187   return 0;
    188 #endif
    189 }
    190 
    191 
    192 #define set_hw_instance_read(instance, method)\
    193 ((instance)->to_instance_read = (method))
    194 
    195 #define set_hw_instance_write(instance, method)\
    196 ((instance)->to_instance_write = (method))
    197 
    198 #define set_hw_instance_seek(instance, method)\
    199 ((instance)->to_instance_seek = (method))
    200 
    201 
    202 #if 0
    203 static void
    204 set_hw_instance_finish (struct hw *me,
    205 			hw_instance_finish_method *method)
    206 {
    207   if (me->instances_of_hw == NULL)
    208     me->instances_of_hw = HW_ZALLOC (me, struct hw_instance_data);
    209   me->instances_of_hw->to_finish = method;
    210 }
    211 #endif
    212 
    213 
    214 struct hw_instance *
    215 hw_instance_create (struct hw *me,
    216 		    struct hw_instance *parent,
    217 		    const char *path,
    218 		    const char *args)
    219 {
    220   struct hw_instance *instance = ZALLOC (struct hw_instance);
    221   /*instance->unit*/
    222   /* link this instance into the devices list */
    223   instance->hw_of_instance = me;
    224   instance->parent_of_instance = NULL;
    225   /* link this instance into the front of the devices instance list */
    226   instance->sibling_of_instance = me->instances_of_hw->instances;
    227   me->instances_of_hw->instances = instance;
    228   if (parent != NULL)
    229     {
    230       ASSERT (parent->child_of_instance == NULL);
    231       parent->child_of_instance = instance;
    232       instance->parent_of_instance = parent;
    233     }
    234   instance->args_of_instance = hw_strdup (me, args);
    235   instance->path_of_instance = hw_strdup (me, path);
    236   set_hw_instance_read (instance, panic_hw_instance_read);
    237   set_hw_instance_write (instance, panic_hw_instance_write);
    238   set_hw_instance_seek (instance, panic_hw_instance_seek);
    239   hw_handle_add_ihandle (me, instance);
    240   me->instances_of_hw->to_finish (me, instance);
    241   return instance;
    242 }
    243 
    244 
    245 struct hw_instance *
    246 hw_instance_interceed (struct hw_instance *parent,
    247 		       const char *path,
    248 		       const char *args)
    249 {
    250 #if 1
    251   return NULL;
    252 #else
    253   struct hw_instance *instance = ZALLOC (struct hw_instance);
    254   /*instance->unit*/
    255   /* link this instance into the devices list */
    256   if (me != NULL)
    257     {
    258       ASSERT (parent == NULL);
    259       instance->hw_of_instance = me;
    260       instance->parent_of_instance = NULL;
    261       /* link this instance into the front of the devices instance list */
    262       instance->sibling_of_instance = me->instances_of_hw->instances;
    263       me->instances_of_hw->instances = instance;
    264     }
    265   if (parent != NULL)
    266     {
    267       struct hw_instance **previous;
    268       ASSERT (parent->child_of_instance == NULL);
    269       parent->child_of_instance = instance;
    270       instance->owner = parent->owner;
    271       instance->parent_of_instance = parent;
    272       /* in the devices instance list replace the parent instance with
    273 	 this one */
    274       instance->next = parent->next;
    275       /* replace parent with this new node */
    276       previous = &instance->owner->instances;
    277       while (*previous != parent)
    278 	{
    279 	  ASSERT (*previous != NULL);
    280 	  previous = &(*previous)->next;
    281 	}
    282       *previous = instance;
    283     }
    284   instance->data = data;
    285   instance->args = (args == NULL ? NULL : (char *) strdup (args));
    286   instance->path = (path == NULL ? NULL : (char *) strdup (path));
    287   cap_add (instance->owner->ihandles, instance);
    288   return instance;
    289 #endif
    290 }
    291