1/* Main simulator entry points specific to the M32R. 2 Copyright (C) 1996, 1997, 1998, 1999, 2003, 2007 3 Free Software Foundation, Inc. 4 Contributed by Cygnus Support. 5 6 This file is part of GDB, the GNU debugger. 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#include "sim-main.h" 22#include "sim-options.h" 23#include "libiberty.h" 24#include "bfd.h" 25 26#ifdef HAVE_STRING_H 27#include <string.h> 28#else 29#ifdef HAVE_STRINGS_H 30#include <strings.h> 31#endif 32#endif 33#ifdef HAVE_STDLIB_H 34#include <stdlib.h> 35#endif 36 37static void free_state (SIM_DESC); 38static void print_m32r_misc_cpu (SIM_CPU *cpu, int verbose); 39 40/* Records simulator descriptor so utilities like m32r_dump_regs can be 41 called from gdb. */ 42SIM_DESC current_state; 43 44/* Cover function of sim_state_free to free the cpu buffers as well. */ 45 46static void 47free_state (SIM_DESC sd) 48{ 49 if (STATE_MODULES (sd) != NULL) 50 sim_module_uninstall (sd); 51 sim_cpu_free_all (sd); 52 sim_state_free (sd); 53} 54 55/* Create an instance of the simulator. */ 56 57SIM_DESC 58sim_open (kind, callback, abfd, argv) 59 SIM_OPEN_KIND kind; 60 host_callback *callback; 61 struct bfd *abfd; 62 char **argv; 63{ 64 SIM_DESC sd = sim_state_alloc (kind, callback); 65 char c; 66 int i; 67 68 /* The cpu data is kept in a separately allocated chunk of memory. */ 69 if (sim_cpu_alloc_all (sd, 1, cgen_cpu_max_extra_bytes ()) != SIM_RC_OK) 70 { 71 free_state (sd); 72 return 0; 73 } 74 75#if 0 /* FIXME: pc is in mach-specific struct */ 76 /* FIXME: watchpoints code shouldn't need this */ 77 { 78 SIM_CPU *current_cpu = STATE_CPU (sd, 0); 79 STATE_WATCHPOINTS (sd)->pc = &(PC); 80 STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC); 81 } 82#endif 83 84 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) 85 { 86 free_state (sd); 87 return 0; 88 } 89 90#ifdef HAVE_DV_SOCKSER /* FIXME: was done differently before */ 91 if (dv_sockser_install (sd) != SIM_RC_OK) 92 { 93 free_state (sd); 94 return 0; 95 } 96#endif 97 98#if 0 /* FIXME: 'twould be nice if we could do this */ 99 /* These options override any module options. 100 Obviously ambiguity should be avoided, however the caller may wish to 101 augment the meaning of an option. */ 102 if (extra_options != NULL) 103 sim_add_option_table (sd, extra_options); 104#endif 105 106 /* getopt will print the error message so we just have to exit if this fails. 107 FIXME: Hmmm... in the case of gdb we need getopt to call 108 print_filtered. */ 109 if (sim_parse_args (sd, argv) != SIM_RC_OK) 110 { 111 free_state (sd); 112 return 0; 113 } 114 115 /* Allocate a handler for the control registers and other devices 116 if no memory for that range has been allocated by the user. 117 All are allocated in one chunk to keep things from being 118 unnecessarily complicated. */ 119 if (sim_core_read_buffer (sd, NULL, read_map, &c, M32R_DEVICE_ADDR, 1) == 0) 120 sim_core_attach (sd, NULL, 121 0 /*level*/, 122 access_read_write, 123 0 /*space ???*/, 124 M32R_DEVICE_ADDR, M32R_DEVICE_LEN /*nr_bytes*/, 125 0 /*modulo*/, 126 &m32r_devices, 127 NULL /*buffer*/); 128 129 /* Allocate core managed memory if none specified by user. 130 Use address 4 here in case the user wanted address 0 unmapped. */ 131 if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0) 132 sim_do_commandf (sd, "memory region 0,0x%x", M32R_DEFAULT_MEM_SIZE); 133 134 /* check for/establish the reference program image */ 135 if (sim_analyze_program (sd, 136 (STATE_PROG_ARGV (sd) != NULL 137 ? *STATE_PROG_ARGV (sd) 138 : NULL), 139 abfd) != SIM_RC_OK) 140 { 141 free_state (sd); 142 return 0; 143 } 144 145 /* Establish any remaining configuration options. */ 146 if (sim_config (sd) != SIM_RC_OK) 147 { 148 free_state (sd); 149 return 0; 150 } 151 152 if (sim_post_argv_init (sd) != SIM_RC_OK) 153 { 154 free_state (sd); 155 return 0; 156 } 157 158 /* Open a copy of the cpu descriptor table. */ 159 { 160 CGEN_CPU_DESC cd = m32r_cgen_cpu_open_1 (STATE_ARCHITECTURE (sd)->printable_name, 161 CGEN_ENDIAN_BIG); 162 for (i = 0; i < MAX_NR_PROCESSORS; ++i) 163 { 164 SIM_CPU *cpu = STATE_CPU (sd, i); 165 CPU_CPU_DESC (cpu) = cd; 166 CPU_DISASSEMBLER (cpu) = sim_cgen_disassemble_insn; 167 } 168 m32r_cgen_init_dis (cd); 169 } 170 171 /* Initialize various cgen things not done by common framework. 172 Must be done after m32r_cgen_cpu_open. */ 173 cgen_init (sd); 174 175 for (c = 0; c < MAX_NR_PROCESSORS; ++c) 176 { 177 /* Only needed for profiling, but the structure member is small. */ 178 memset (CPU_M32R_MISC_PROFILE (STATE_CPU (sd, i)), 0, 179 sizeof (* CPU_M32R_MISC_PROFILE (STATE_CPU (sd, i)))); 180 /* Hook in callback for reporting these stats */ 181 PROFILE_INFO_CPU_CALLBACK (CPU_PROFILE_DATA (STATE_CPU (sd, i))) 182 = print_m32r_misc_cpu; 183 } 184 185 /* Store in a global so things like sparc32_dump_regs can be invoked 186 from the gdb command line. */ 187 current_state = sd; 188 189 return sd; 190} 191 192void 193sim_close (sd, quitting) 194 SIM_DESC sd; 195 int quitting; 196{ 197 m32r_cgen_cpu_close (CPU_CPU_DESC (STATE_CPU (sd, 0))); 198 sim_module_uninstall (sd); 199} 200 201SIM_RC 202sim_create_inferior (sd, abfd, argv, envp) 203 SIM_DESC sd; 204 struct bfd *abfd; 205 char **argv; 206 char **envp; 207{ 208 SIM_CPU *current_cpu = STATE_CPU (sd, 0); 209 SIM_ADDR addr; 210 211 if (abfd != NULL) 212 addr = bfd_get_start_address (abfd); 213 else 214 addr = 0; 215 sim_pc_set (current_cpu, addr); 216 217#ifdef M32R_LINUX 218 m32rbf_h_cr_set (current_cpu, 219 m32r_decode_gdb_ctrl_regnum(SPI_REGNUM), 0x1f00000); 220 m32rbf_h_cr_set (current_cpu, 221 m32r_decode_gdb_ctrl_regnum(SPU_REGNUM), 0x1f00000); 222#endif 223 224#if 0 225 STATE_ARGV (sd) = sim_copy_argv (argv); 226 STATE_ENVP (sd) = sim_copy_argv (envp); 227#endif 228 229 return SIM_RC_OK; 230} 231 232/* PROFILE_CPU_CALLBACK */ 233 234static void 235print_m32r_misc_cpu (SIM_CPU *cpu, int verbose) 236{ 237 SIM_DESC sd = CPU_STATE (cpu); 238 char buf[20]; 239 240 if (CPU_PROFILE_FLAGS (cpu) [PROFILE_INSN_IDX]) 241 { 242 sim_io_printf (sd, "Miscellaneous Statistics\n\n"); 243 sim_io_printf (sd, " %-*s %s\n\n", 244 PROFILE_LABEL_WIDTH, "Fill nops:", 245 sim_add_commas (buf, sizeof (buf), 246 CPU_M32R_MISC_PROFILE (cpu)->fillnop_count)); 247 if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_m32rx) 248 sim_io_printf (sd, " %-*s %s\n\n", 249 PROFILE_LABEL_WIDTH, "Parallel insns:", 250 sim_add_commas (buf, sizeof (buf), 251 CPU_M32R_MISC_PROFILE (cpu)->parallel_count)); 252 if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_m32r2) 253 sim_io_printf (sd, " %-*s %s\n\n", 254 PROFILE_LABEL_WIDTH, "Parallel insns:", 255 sim_add_commas (buf, sizeof (buf), 256 CPU_M32R_MISC_PROFILE (cpu)->parallel_count)); 257 } 258} 259 260void 261sim_do_command (sd, cmd) 262 SIM_DESC sd; 263 char *cmd; 264{ 265 char **argv; 266 267 if (cmd == NULL) 268 return; 269 270 argv = buildargv (cmd); 271 272 if (argv[0] != NULL 273 && strcasecmp (argv[0], "info") == 0 274 && argv[1] != NULL 275 && strncasecmp (argv[1], "reg", 3) == 0) 276 { 277 SI val; 278 279 /* We only support printing bbpsw,bbpc here as there is no equivalent 280 functionality in gdb. */ 281 if (argv[2] == NULL) 282 sim_io_eprintf (sd, "Missing register in `%s'\n", cmd); 283 else if (argv[3] != NULL) 284 sim_io_eprintf (sd, "Too many arguments in `%s'\n", cmd); 285 else if (strcasecmp (argv[2], "bbpsw") == 0) 286 { 287 val = m32rbf_h_cr_get (STATE_CPU (sd, 0), H_CR_BBPSW); 288 sim_io_printf (sd, "bbpsw 0x%x %d\n", val, val); 289 } 290 else if (strcasecmp (argv[2], "bbpc") == 0) 291 { 292 val = m32rbf_h_cr_get (STATE_CPU (sd, 0), H_CR_BBPC); 293 sim_io_printf (sd, "bbpc 0x%x %d\n", val, val); 294 } 295 else 296 sim_io_eprintf (sd, "Printing of register `%s' not supported with `sim info'\n", 297 argv[2]); 298 } 299 else 300 { 301 if (sim_args_command (sd, cmd) != SIM_RC_OK) 302 sim_io_eprintf (sd, "Unknown sim command `%s'\n", cmd); 303 } 304 305 freeargv (argv); 306} 307