Home | History | Annotate | Line # | Download | only in common
      1   1.1  christos /* Model support.
      2  1.11  christos    Copyright (C) 1996-2024 Free Software Foundation, Inc.
      3   1.1  christos    Contributed by Cygnus Support.
      4   1.1  christos 
      5   1.1  christos This file is part of GDB, the GNU debugger.
      6   1.1  christos 
      7   1.1  christos This program is free software; you can redistribute it and/or modify
      8   1.1  christos it under the terms of the GNU General Public License as published by
      9   1.1  christos the Free Software Foundation; either version 3 of the License, or
     10   1.1  christos (at your option) any later version.
     11   1.1  christos 
     12   1.1  christos This program is distributed in the hope that it will be useful,
     13   1.1  christos but WITHOUT ANY WARRANTY; without even the implied warranty of
     14   1.1  christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15   1.1  christos GNU General Public License for more details.
     16   1.1  christos 
     17   1.1  christos You should have received a copy of the GNU General Public License
     18   1.1  christos along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19   1.1  christos 
     20  1.10  christos /* This must come before any other includes.  */
     21  1.10  christos #include "defs.h"
     22  1.10  christos 
     23  1.10  christos #include "bfd.h"
     24  1.10  christos #include "libiberty.h"
     25  1.10  christos 
     26   1.1  christos #include "sim-main.h"
     27   1.1  christos #include "sim-model.h"
     28   1.1  christos #include "sim-options.h"
     29   1.1  christos #include "sim-io.h"
     30   1.1  christos #include "sim-assert.h"
     31   1.1  christos 
     32   1.6  christos static void model_set (sim_cpu *, const SIM_MODEL *);
     33   1.1  christos 
     34   1.1  christos static DECLARE_OPTION_HANDLER (model_option_handler);
     35   1.1  christos 
     36   1.1  christos static MODULE_INIT_FN sim_model_init;
     37   1.1  christos 
     38   1.1  christos enum {
     39   1.1  christos   OPTION_MODEL = OPTION_START,
     40   1.1  christos   OPTION_MODEL_INFO,
     41   1.1  christos };
     42   1.1  christos 
     43   1.1  christos static const OPTION model_options[] = {
     44   1.1  christos   { {"model", required_argument, NULL, OPTION_MODEL},
     45   1.1  christos       '\0', "MODEL", "Specify model to simulate",
     46   1.1  christos       model_option_handler, NULL },
     47   1.1  christos 
     48   1.1  christos   { {"model-info", no_argument, NULL, OPTION_MODEL_INFO},
     49   1.1  christos       '\0', NULL, "List selectable models",
     50   1.1  christos       model_option_handler, NULL },
     51   1.1  christos   { {"info-model", no_argument, NULL, OPTION_MODEL_INFO},
     52   1.1  christos       '\0', NULL, NULL,
     53   1.1  christos       model_option_handler, NULL },
     54   1.1  christos 
     55   1.1  christos   { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
     56   1.1  christos };
     57   1.1  christos 
     58   1.1  christos static SIM_RC
     59   1.1  christos model_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
     60   1.1  christos 		      char *arg, int is_command)
     61   1.1  christos {
     62   1.1  christos   switch (opt)
     63   1.1  christos     {
     64   1.1  christos     case OPTION_MODEL :
     65   1.1  christos       {
     66  1.10  christos 	const SIM_MODEL *model = sim_model_lookup (sd, arg);
     67   1.1  christos 	if (! model)
     68   1.1  christos 	  {
     69   1.1  christos 	    sim_io_eprintf (sd, "unknown model `%s'\n", arg);
     70   1.1  christos 	    return SIM_RC_FAIL;
     71   1.1  christos 	  }
     72  1.10  christos 	STATE_MODEL_NAME (sd) = arg;
     73   1.1  christos 	sim_model_set (sd, cpu, model);
     74   1.1  christos 	break;
     75   1.1  christos       }
     76   1.1  christos 
     77   1.1  christos     case OPTION_MODEL_INFO :
     78   1.1  christos       {
     79  1.10  christos 	const SIM_MACH * const *machp;
     80   1.6  christos 	const SIM_MODEL *model;
     81  1.10  christos 
     82  1.10  christos 	if (STATE_MACHS (sd) == NULL)
     83  1.10  christos 	  {
     84  1.10  christos 	    sim_io_printf (sd, "This target does not support any models\n");
     85  1.10  christos 	    return SIM_RC_FAIL;
     86  1.10  christos 	  }
     87  1.10  christos 
     88  1.10  christos 	for (machp = STATE_MACHS(sd); *machp != NULL; ++machp)
     89   1.1  christos 	  {
     90   1.1  christos 	    sim_io_printf (sd, "Models for architecture `%s':\n",
     91   1.1  christos 			   MACH_NAME (*machp));
     92   1.1  christos 	    for (model = MACH_MODELS (*machp); MODEL_NAME (model) != NULL;
     93   1.1  christos 		 ++model)
     94   1.1  christos 	      sim_io_printf (sd, " %s", MODEL_NAME (model));
     95   1.1  christos 	    sim_io_printf (sd, "\n");
     96   1.1  christos 	  }
     97   1.1  christos 	break;
     98   1.1  christos       }
     99   1.1  christos     }
    100   1.1  christos 
    101   1.1  christos   return SIM_RC_OK;
    102   1.1  christos }
    103   1.1  christos 
    104   1.1  christos SIM_RC
    105   1.1  christos sim_model_install (SIM_DESC sd)
    106   1.1  christos {
    107   1.1  christos   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
    108   1.1  christos 
    109   1.1  christos   sim_add_option_table (sd, NULL, model_options);
    110   1.1  christos   sim_module_add_init_fn (sd, sim_model_init);
    111   1.1  christos 
    112   1.1  christos   return SIM_RC_OK;
    113   1.1  christos }
    114   1.1  christos 
    115   1.1  christos /* Subroutine of sim_model_set to set the model for one cpu.  */
    116   1.1  christos 
    117   1.1  christos static void
    118   1.6  christos model_set (sim_cpu *cpu, const SIM_MODEL *model)
    119   1.1  christos {
    120   1.1  christos   CPU_MACH (cpu) = MODEL_MACH (model);
    121   1.1  christos   CPU_MODEL (cpu) = model;
    122   1.1  christos   (* MACH_INIT_CPU (MODEL_MACH (model))) (cpu);
    123   1.1  christos   (* MODEL_INIT (model)) (cpu);
    124   1.1  christos }
    125   1.1  christos 
    126   1.1  christos /* Set the current model of CPU to MODEL.
    127   1.1  christos    If CPU is NULL, all cpus are set to MODEL.  */
    128   1.1  christos 
    129   1.1  christos void
    130   1.6  christos sim_model_set (SIM_DESC sd, sim_cpu *cpu, const SIM_MODEL *model)
    131   1.1  christos {
    132   1.1  christos   if (! cpu)
    133   1.1  christos     {
    134   1.1  christos       int c;
    135   1.1  christos 
    136   1.1  christos       for (c = 0; c < MAX_NR_PROCESSORS; ++c)
    137   1.1  christos 	if (STATE_CPU (sd, c))
    138   1.1  christos 	  model_set (STATE_CPU (sd, c), model);
    139   1.1  christos     }
    140   1.1  christos   else
    141   1.1  christos     {
    142   1.1  christos       model_set (cpu, model);
    143   1.1  christos     }
    144   1.1  christos }
    145   1.1  christos 
    146   1.1  christos /* Look up model named NAME.
    147   1.1  christos    Result is pointer to MODEL entry or NULL if not found.  */
    148   1.1  christos 
    149   1.6  christos const SIM_MODEL *
    150  1.10  christos sim_model_lookup (SIM_DESC sd, const char *name)
    151   1.1  christos {
    152  1.10  christos   const SIM_MACH * const *machp;
    153   1.6  christos   const SIM_MODEL *model;
    154   1.1  christos 
    155  1.10  christos   if (STATE_MACHS (sd) == NULL)
    156  1.10  christos     return NULL;
    157  1.10  christos 
    158  1.10  christos   for (machp = STATE_MACHS (sd); *machp != NULL; ++machp)
    159   1.1  christos     {
    160   1.1  christos       for (model = MACH_MODELS (*machp); MODEL_NAME (model) != NULL; ++model)
    161   1.1  christos 	{
    162   1.1  christos 	  if (strcmp (MODEL_NAME (model), name) == 0)
    163   1.1  christos 	    return model;
    164   1.1  christos 	}
    165   1.1  christos     }
    166   1.1  christos   return NULL;
    167   1.1  christos }
    168   1.1  christos 
    169   1.1  christos /* Look up machine named NAME.
    170   1.1  christos    Result is pointer to MACH entry or NULL if not found.  */
    171   1.1  christos 
    172   1.6  christos const SIM_MACH *
    173  1.10  christos sim_mach_lookup (SIM_DESC sd, const char *name)
    174   1.1  christos {
    175  1.10  christos   const SIM_MACH * const *machp;
    176   1.1  christos 
    177  1.10  christos   if (STATE_MACHS (sd) == NULL)
    178  1.10  christos     return NULL;
    179  1.10  christos 
    180  1.10  christos   for (machp = STATE_MACHS (sd); *machp != NULL; ++machp)
    181   1.1  christos     {
    182   1.1  christos       if (strcmp (MACH_NAME (*machp), name) == 0)
    183   1.1  christos 	return *machp;
    184   1.1  christos     }
    185   1.1  christos   return NULL;
    186   1.1  christos }
    187   1.1  christos 
    188   1.1  christos /* Look up a machine via its bfd name.
    189   1.1  christos    Result is pointer to MACH entry or NULL if not found.  */
    190   1.1  christos 
    191   1.6  christos const SIM_MACH *
    192  1.10  christos sim_mach_lookup_bfd_name (SIM_DESC sd, const char *name)
    193   1.1  christos {
    194  1.10  christos   const SIM_MACH * const *machp;
    195  1.10  christos 
    196  1.10  christos   if (STATE_MACHS (sd) == NULL)
    197  1.10  christos     return NULL;
    198   1.1  christos 
    199  1.10  christos   for (machp = STATE_MACHS (sd); *machp != NULL; ++machp)
    200   1.1  christos     {
    201   1.1  christos       if (strcmp (MACH_BFD_NAME (*machp), name) == 0)
    202   1.1  christos 	return *machp;
    203   1.1  christos     }
    204   1.1  christos   return NULL;
    205   1.1  christos }
    206   1.1  christos 
    207   1.1  christos /* Initialize model support.  */
    208   1.1  christos 
    209   1.1  christos static SIM_RC
    210   1.1  christos sim_model_init (SIM_DESC sd)
    211   1.1  christos {
    212   1.1  christos   SIM_CPU *cpu;
    213   1.1  christos 
    214   1.1  christos   /* If both cpu model and state architecture are set, ensure they're
    215   1.1  christos      compatible.  If only one is set, set the other.  If neither are set,
    216   1.1  christos      use the default model.  STATE_ARCHITECTURE is the bfd_arch_info data
    217   1.1  christos      for the selected "mach" (bfd terminology).  */
    218   1.1  christos 
    219   1.1  christos   /* Only check cpu 0.  STATE_ARCHITECTURE is for that one only.  */
    220   1.1  christos   /* ??? At present this only supports homogeneous multiprocessors.  */
    221   1.1  christos   cpu = STATE_CPU (sd, 0);
    222   1.1  christos 
    223   1.1  christos   if (! STATE_ARCHITECTURE (sd)
    224  1.10  christos       && ! CPU_MACH (cpu)
    225  1.10  christos       && STATE_MODEL_NAME (sd))
    226   1.1  christos     {
    227   1.1  christos       /* Set the default model.  */
    228  1.10  christos       const SIM_MODEL *model = sim_model_lookup (sd, STATE_MODEL_NAME (sd));
    229   1.5  christos       SIM_ASSERT (model != NULL);
    230   1.1  christos       sim_model_set (sd, NULL, model);
    231   1.1  christos     }
    232   1.1  christos 
    233   1.1  christos   if (STATE_ARCHITECTURE (sd)
    234   1.1  christos       && CPU_MACH (cpu))
    235   1.1  christos     {
    236   1.1  christos       if (strcmp (STATE_ARCHITECTURE (sd)->printable_name,
    237   1.1  christos 		  MACH_BFD_NAME (CPU_MACH (cpu))) != 0)
    238   1.1  christos 	{
    239   1.1  christos 	  sim_io_eprintf (sd, "invalid model `%s' for `%s'\n",
    240   1.1  christos 			  MODEL_NAME (CPU_MODEL (cpu)),
    241   1.1  christos 			  STATE_ARCHITECTURE (sd)->printable_name);
    242   1.1  christos 	  return SIM_RC_FAIL;
    243   1.1  christos 	}
    244   1.1  christos     }
    245  1.10  christos   else if (STATE_ARCHITECTURE (sd) && STATE_MACHS (sd))
    246   1.1  christos     {
    247   1.1  christos       /* Use the default model for the selected machine.
    248   1.1  christos 	 The default model is the first one in the list.  */
    249  1.10  christos       const SIM_MACH *mach =
    250  1.10  christos 	sim_mach_lookup_bfd_name (sd, STATE_ARCHITECTURE (sd)->printable_name);
    251   1.1  christos 
    252   1.1  christos       if (mach == NULL)
    253   1.1  christos 	{
    254   1.1  christos 	  sim_io_eprintf (sd, "unsupported machine `%s'\n",
    255   1.1  christos 			  STATE_ARCHITECTURE (sd)->printable_name);
    256   1.1  christos 	  return SIM_RC_FAIL;
    257   1.1  christos 	}
    258   1.1  christos       sim_model_set (sd, NULL, MACH_MODELS (mach));
    259   1.1  christos     }
    260  1.10  christos   else if (CPU_MACH (cpu))
    261   1.1  christos     {
    262   1.1  christos       STATE_ARCHITECTURE (sd) = bfd_scan_arch (MACH_BFD_NAME (CPU_MACH (cpu)));
    263   1.1  christos     }
    264   1.1  christos 
    265   1.1  christos   return SIM_RC_OK;
    266   1.1  christos }
    267