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