sim: start a unified sim_do_command
[external/binutils.git] / sim / lm32 / sim-if.c
1 /* Main simulator entry points specific to Lattice Mico32.
2    Contributed by Jon Beniston <jon@beniston.com>
3    
4    Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
5
6    This file is part of GDB.
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_STDLIB_H
27 #include <stdlib.h>
28 #endif
29
30 static void free_state (SIM_DESC);
31 static void print_lm32_misc_cpu (SIM_CPU * cpu, int verbose);
32 static DECLARE_OPTION_HANDLER (lm32_option_handler);
33
34 enum
35 {
36   OPTION_ENDIAN = OPTION_START,
37 };
38
39 /* GDB passes -E, even though it's fixed, so we have to handle it here. common code only handles it if SIM_HAVE_BIENDIAN is defined, which it isn't for lm32.  */
40 static const OPTION lm32_options[] = {
41   {{"endian", required_argument, NULL, OPTION_ENDIAN},
42    'E', "big", "Set endianness",
43    lm32_option_handler},
44   {{NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL}
45 };
46
47 /* Records simulator descriptor so utilities like lm32_dump_regs can be
48    called from gdb.  */
49 SIM_DESC current_state;
50 \f
51 /* Cover function of sim_state_free to free the cpu buffers as well.  */
52
53 static void
54 free_state (SIM_DESC sd)
55 {
56   if (STATE_MODULES (sd) != NULL)
57     sim_module_uninstall (sd);
58   sim_cpu_free_all (sd);
59   sim_state_free (sd);
60 }
61
62 /* Find memory range used by program.  */
63
64 static unsigned long
65 find_base (bfd *prog_bfd)
66 {
67   int found;
68   unsigned long base = ~(0UL);
69   asection *s;
70
71   found = 0;
72   for (s = prog_bfd->sections; s; s = s->next)
73     {
74       if ((strcmp (bfd_get_section_name (prog_bfd, s), ".boot") == 0)
75           || (strcmp (bfd_get_section_name (prog_bfd, s), ".text") == 0)
76           || (strcmp (bfd_get_section_name (prog_bfd, s), ".data") == 0)
77           || (strcmp (bfd_get_section_name (prog_bfd, s), ".bss") == 0))
78         {
79           if (!found)
80             {
81               base = bfd_get_section_vma (prog_bfd, s);
82               found = 1;
83             }
84           else
85             base =
86               bfd_get_section_vma (prog_bfd,
87                                    s) < base ? bfd_get_section_vma (prog_bfd,
88                                                                     s) : base;
89         }
90     }
91   return base & ~(0xffffUL);
92 }
93
94 static unsigned long
95 find_limit (bfd *prog_bfd)
96 {
97   struct bfd_symbol **asymbols;
98   long symsize;
99   long symbol_count;
100   long s;
101
102   symsize = bfd_get_symtab_upper_bound (prog_bfd);
103   if (symsize < 0)
104     return 0;
105   asymbols = (asymbol **) xmalloc (symsize);
106   symbol_count = bfd_canonicalize_symtab (prog_bfd, asymbols);
107   if (symbol_count < 0)
108     return 0;
109
110   for (s = 0; s < symbol_count; s++)
111     {
112       if (!strcmp (asymbols[s]->name, "_fstack"))
113         return (asymbols[s]->value + 65536) & ~(0xffffUL);
114     }
115   return 0;
116 }
117
118 /* Handle lm32 specific options.  */
119
120 static SIM_RC
121 lm32_option_handler (sd, cpu, opt, arg, is_command)
122      SIM_DESC sd;
123      sim_cpu *cpu;
124      int opt;
125      char *arg;
126      int is_command;
127 {
128   return SIM_RC_OK;
129 }
130
131 /* Create an instance of the simulator.  */
132
133 SIM_DESC
134 sim_open (kind, callback, abfd, argv)
135      SIM_OPEN_KIND kind;
136      host_callback *callback;
137      struct bfd *abfd;
138      char **argv;
139 {
140   SIM_DESC sd = sim_state_alloc (kind, callback);
141   char c;
142   int i;
143   unsigned long base, limit;
144
145   /* The cpu data is kept in a separately allocated chunk of memory.  */
146   if (sim_cpu_alloc_all (sd, 1, cgen_cpu_max_extra_bytes ()) != SIM_RC_OK)
147     {
148       free_state (sd);
149       return 0;
150     }
151
152   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
153     {
154       free_state (sd);
155       return 0;
156     }
157   sim_add_option_table (sd, NULL, lm32_options);
158
159   /* getopt will print the error message so we just have to exit if this fails.
160      FIXME: Hmmm...  in the case of gdb we need getopt to call
161      print_filtered.  */
162   if (sim_parse_args (sd, argv) != SIM_RC_OK)
163     {
164       free_state (sd);
165       return 0;
166     }
167
168 #if 0
169   /* Allocate a handler for I/O devices
170      if no memory for that range has been allocated by the user.
171      All are allocated in one chunk to keep things from being
172      unnecessarily complicated.  */
173   if (sim_core_read_buffer (sd, NULL, read_map, &c, LM32_DEVICE_ADDR, 1) == 0)
174     sim_core_attach (sd, NULL, 0 /*level */ ,
175                      access_read_write, 0 /*space ??? */ ,
176                      LM32_DEVICE_ADDR, LM32_DEVICE_LEN /*nr_bytes */ ,
177                      0 /*modulo */ ,
178                      &lm32_devices, NULL /*buffer */ );
179 #endif
180
181   /* check for/establish the reference program image.  */
182   if (sim_analyze_program (sd,
183                            (STATE_PROG_ARGV (sd) != NULL
184                             ? *STATE_PROG_ARGV (sd)
185                             : NULL), abfd) != SIM_RC_OK)
186     {
187       free_state (sd);
188       return 0;
189     }
190
191   /* Check to see if memory exists at programs start address.  */
192   if (sim_core_read_buffer (sd, NULL, read_map, &c, STATE_START_ADDR (sd), 1)
193       == 0)
194     {
195       if (STATE_PROG_BFD (sd) != NULL)
196         {
197           /* It doesn't, so we should try to allocate enough memory to hold program.  */
198           base = find_base (STATE_PROG_BFD (sd));
199           limit = find_limit (STATE_PROG_BFD (sd));
200           if (limit == 0)
201             {
202               sim_io_eprintf (sd,
203                               "Failed to find symbol _fstack in program. You must specify memory regions with --memory-region.\n");
204               free_state (sd);
205               return 0;
206             }
207           /*sim_io_printf (sd, "Allocating memory at 0x%x size 0x%x\n", base, limit); */
208           sim_do_commandf (sd, "memory region 0x%x,0x%x", base, limit);
209         }
210     }
211
212   /* Establish any remaining configuration options.  */
213   if (sim_config (sd) != SIM_RC_OK)
214     {
215       free_state (sd);
216       return 0;
217     }
218
219   if (sim_post_argv_init (sd) != SIM_RC_OK)
220     {
221       free_state (sd);
222       return 0;
223     }
224
225   /* Open a copy of the cpu descriptor table.  */
226   {
227     CGEN_CPU_DESC cd =
228       lm32_cgen_cpu_open_1 (STATE_ARCHITECTURE (sd)->printable_name,
229                             CGEN_ENDIAN_BIG);
230     for (i = 0; i < MAX_NR_PROCESSORS; ++i)
231       {
232         SIM_CPU *cpu = STATE_CPU (sd, i);
233         CPU_CPU_DESC (cpu) = cd;
234         CPU_DISASSEMBLER (cpu) = sim_cgen_disassemble_insn;
235       }
236     lm32_cgen_init_dis (cd);
237   }
238
239   /* Initialize various cgen things not done by common framework.
240      Must be done after lm32_cgen_cpu_open.  */
241   cgen_init (sd);
242
243   /* Store in a global so things like lm32_dump_regs can be invoked
244      from the gdb command line.  */
245   current_state = sd;
246
247   return sd;
248 }
249
250 void
251 sim_close (sd, quitting)
252      SIM_DESC sd;
253      int quitting;
254 {
255   lm32_cgen_cpu_close (CPU_CPU_DESC (STATE_CPU (sd, 0)));
256   sim_module_uninstall (sd);
257 }
258 \f
259 SIM_RC
260 sim_create_inferior (sd, abfd, argv, envp)
261      SIM_DESC sd;
262      struct bfd *abfd;
263      char **argv;
264      char **envp;
265 {
266   SIM_CPU *current_cpu = STATE_CPU (sd, 0);
267   SIM_ADDR addr;
268
269   if (abfd != NULL)
270     addr = bfd_get_start_address (abfd);
271   else
272     addr = 0;
273   sim_pc_set (current_cpu, addr);
274
275 #if 0
276   STATE_ARGV (sd) = sim_copy_argv (argv);
277   STATE_ENVP (sd) = sim_copy_argv (envp);
278 #endif
279
280   return SIM_RC_OK;
281 }