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