1 /* Main simulator entry points specific to the M32R.
2    Copyright (C) 1996, 1997, 1998, 1999, 2003, 2007, 2008, 2009, 2010, 2011
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 
37 static void free_state (SIM_DESC);
38 static 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.  */
42 SIM_DESC current_state;
43 
44 /* Cover function of sim_state_free to free the cpu buffers as well.  */
45 
46 static void
free_state(SIM_DESC sd)47 free_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 
57 SIM_DESC
sim_open(kind,callback,abfd,argv)58 sim_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 
192 void
sim_close(sd,quitting)193 sim_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 
201 SIM_RC
sim_create_inferior(sd,abfd,argv,envp)202 sim_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 
234 static void
print_m32r_misc_cpu(SIM_CPU * cpu,int verbose)235 print_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 
260 void
sim_do_command(sd,cmd)261 sim_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