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