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