1 /* Main simulator entry points specific to the FRV. 2 Copyright (C) 1998, 1999, 2000, 2007, 2008, 2009, 2010, 2011 3 Free Software Foundation, Inc. 4 Contributed by Red Hat. 5 6 This file is part of the GNU simulators. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20 21 #define WANT_CPU 22 #define WANT_CPU_FRVBF 23 #include "sim-main.h" 24 #ifdef HAVE_STDLIB_H 25 #include <stdlib.h> 26 #endif 27 #include "sim-options.h" 28 #include "libiberty.h" 29 #include "bfd.h" 30 #include "elf-bfd.h" 31 32 static void free_state (SIM_DESC); 33 static void print_frv_misc_cpu (SIM_CPU *cpu, int verbose); 34 35 /* Records simulator descriptor so utilities like frv_dump_regs can be 36 called from gdb. */ 37 SIM_DESC current_state; 38 39 /* Cover function of sim_state_free to free the cpu buffers as well. */ 40 41 static void 42 free_state (SIM_DESC sd) 43 { 44 if (STATE_MODULES (sd) != NULL) 45 sim_module_uninstall (sd); 46 sim_cpu_free_all (sd); 47 sim_state_free (sd); 48 } 49 50 /* Create an instance of the simulator. */ 51 52 SIM_DESC 53 sim_open (kind, callback, abfd, argv) 54 SIM_OPEN_KIND kind; 55 host_callback *callback; 56 bfd *abfd; 57 char **argv; 58 { 59 char c; 60 int i; 61 unsigned long elf_flags = 0; 62 SIM_DESC sd = sim_state_alloc (kind, callback); 63 64 /* The cpu data is kept in a separately allocated chunk of memory. */ 65 if (sim_cpu_alloc_all (sd, 1, cgen_cpu_max_extra_bytes ()) != SIM_RC_OK) 66 { 67 free_state (sd); 68 return 0; 69 } 70 71 #if 0 /* FIXME: pc is in mach-specific struct */ 72 /* FIXME: watchpoints code shouldn't need this */ 73 { 74 SIM_CPU *current_cpu = STATE_CPU (sd, 0); 75 STATE_WATCHPOINTS (sd)->pc = &(PC); 76 STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC); 77 } 78 #endif 79 80 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) 81 { 82 free_state (sd); 83 return 0; 84 } 85 86 /* These options override any module options. 87 Obviously ambiguity should be avoided, however the caller may wish to 88 augment the meaning of an option. */ 89 sim_add_option_table (sd, NULL, frv_options); 90 91 /* getopt will print the error message so we just have to exit if this fails. 92 FIXME: Hmmm... in the case of gdb we need getopt to call 93 print_filtered. */ 94 if (sim_parse_args (sd, argv) != SIM_RC_OK) 95 { 96 free_state (sd); 97 return 0; 98 } 99 100 #if 0 101 /* Allocate a handler for the control registers and other devices 102 if no memory for that range has been allocated by the user. 103 All are allocated in one chunk to keep things from being 104 unnecessarily complicated. */ 105 if (sim_core_read_buffer (sd, NULL, read_map, &c, FRV_DEVICE_ADDR, 1) == 0) 106 sim_core_attach (sd, NULL, 107 0 /*level*/, 108 access_read_write, 109 0 /*space ???*/, 110 FRV_DEVICE_ADDR, FRV_DEVICE_LEN /*nr_bytes*/, 111 0 /*modulo*/, 112 &frv_devices, 113 NULL /*buffer*/); 114 #endif 115 116 /* Allocate core managed memory if none specified by user. 117 Use address 4 here in case the user wanted address 0 unmapped. */ 118 if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0) 119 sim_do_commandf (sd, "memory region 0,0x%lx", FRV_DEFAULT_MEM_SIZE); 120 121 /* check for/establish the reference program image */ 122 if (sim_analyze_program (sd, 123 (STATE_PROG_ARGV (sd) != NULL 124 ? *STATE_PROG_ARGV (sd) 125 : NULL), 126 abfd) != SIM_RC_OK) 127 { 128 free_state (sd); 129 return 0; 130 } 131 132 /* set machine and architecture correctly instead of defaulting to frv */ 133 { 134 bfd *prog_bfd = STATE_PROG_BFD (sd); 135 if (prog_bfd != NULL) 136 { 137 struct elf_backend_data *backend_data; 138 139 if (bfd_get_arch (prog_bfd) != bfd_arch_frv) 140 { 141 sim_io_eprintf (sd, "%s: \"%s\" is not a FRV object file\n", 142 STATE_MY_NAME (sd), 143 bfd_get_filename (prog_bfd)); 144 free_state (sd); 145 return 0; 146 } 147 148 backend_data = get_elf_backend_data (prog_bfd); 149 150 if (backend_data != NULL) 151 backend_data->elf_backend_object_p (prog_bfd); 152 153 elf_flags = elf_elfheader (prog_bfd)->e_flags; 154 } 155 } 156 157 /* Establish any remaining configuration options. */ 158 if (sim_config (sd) != SIM_RC_OK) 159 { 160 free_state (sd); 161 return 0; 162 } 163 164 if (sim_post_argv_init (sd) != SIM_RC_OK) 165 { 166 free_state (sd); 167 return 0; 168 } 169 170 /* Open a copy of the cpu descriptor table. */ 171 { 172 CGEN_CPU_DESC cd = frv_cgen_cpu_open_1 (STATE_ARCHITECTURE (sd)->printable_name, 173 CGEN_ENDIAN_BIG); 174 for (i = 0; i < MAX_NR_PROCESSORS; ++i) 175 { 176 SIM_CPU *cpu = STATE_CPU (sd, i); 177 CPU_CPU_DESC (cpu) = cd; 178 CPU_DISASSEMBLER (cpu) = sim_cgen_disassemble_insn; 179 CPU_ELF_FLAGS (cpu) = elf_flags; 180 } 181 frv_cgen_init_dis (cd); 182 } 183 184 /* Initialize various cgen things not done by common framework. 185 Must be done after frv_cgen_cpu_open. */ 186 cgen_init (sd); 187 188 /* CPU specific initialization. */ 189 for (i = 0; i < MAX_NR_PROCESSORS; ++i) 190 { 191 SIM_CPU* cpu = STATE_CPU (sd, i); 192 frv_initialize (cpu, sd); 193 } 194 195 /* Store in a global so things like sparc32_dump_regs can be invoked 196 from the gdb command line. */ 197 current_state = sd; 198 199 return sd; 200 } 201 202 void 203 sim_close (sd, quitting) 204 SIM_DESC sd; 205 int quitting; 206 { 207 int i; 208 /* Terminate cache support. */ 209 for (i = 0; i < MAX_NR_PROCESSORS; ++i) 210 { 211 SIM_CPU* cpu = STATE_CPU (sd, i); 212 frv_cache_term (CPU_INSN_CACHE (cpu)); 213 frv_cache_term (CPU_DATA_CACHE (cpu)); 214 } 215 216 frv_cgen_cpu_close (CPU_CPU_DESC (STATE_CPU (sd, 0))); 217 sim_module_uninstall (sd); 218 } 219 220 SIM_RC 221 sim_create_inferior (sd, abfd, argv, envp) 222 SIM_DESC sd; 223 bfd *abfd; 224 char **argv; 225 char **envp; 226 { 227 SIM_CPU *current_cpu = STATE_CPU (sd, 0); 228 SIM_ADDR addr; 229 230 if (abfd != NULL) 231 addr = bfd_get_start_address (abfd); 232 else 233 addr = 0; 234 sim_pc_set (current_cpu, addr); 235 236 #if 0 237 STATE_ARGV (sd) = sim_copy_argv (argv); 238 STATE_ENVP (sd) = sim_copy_argv (envp); 239 #endif 240 241 return SIM_RC_OK; 242 } 243 244 void 245 sim_do_command (sd, cmd) 246 SIM_DESC sd; 247 char *cmd; 248 { 249 if (sim_args_command (sd, cmd) != SIM_RC_OK) 250 sim_io_eprintf (sd, "Unknown command `%s'\n", cmd); 251 } 252