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