* cris/dv-cris.c, cris/dv-rv.c, cris/rvdummy.c: New files.
[deliverable/binutils-gdb.git] / sim / cris / sim-if.c
CommitLineData
f6bcefef 1/* Main simulator entry points specific to the CRIS.
aad3b3cb 2 Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
f6bcefef
HPN
3 Contributed by Axis Communications.
4
5This file is part of the GNU simulators.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License along
18with this program; if not, write to the Free Software Foundation, Inc.,
1959 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21/* Based on the fr30 file, mixing in bits from the i960 and pruning of
22 dead code. */
23
24#include "libiberty.h"
25#include "bfd.h"
26
27#include "sim-main.h"
28#ifdef HAVE_STDLIB_H
29#include <stdlib.h>
30#endif
31#include "sim-options.h"
32#include "dis-asm.h"
33
34/* Apparently the autoconf bits are missing (though HAVE_ENVIRON is used
35 in other dirs; also lacking there). Patch around it for major systems. */
36#if defined (HAVE_ENVIRON) || defined (__GLIBC__)
37extern char **environ;
38#define GET_ENVIRON() environ
39#else
40char *missing_environ[] = { "SHELL=/bin/sh", "PATH=/bin:/usr/bin", NULL };
41#define GET_ENVIRON() missing_environ
42#endif
43
44/* AUX vector entries. */
45#define TARGET_AT_NULL 0
46#define TARGET_AT_PHDR 3
47#define TARGET_AT_PHENT 4
48#define TARGET_AT_PHNUM 5
49#define TARGET_AT_PAGESZ 6
50#define TARGET_AT_BASE 7
51#define TARGET_AT_FLAGS 8
52#define TARGET_AT_ENTRY 9
53#define TARGET_AT_UID 11
54#define TARGET_AT_EUID 12
55#define TARGET_AT_GID 13
56#define TARGET_AT_EGID 14
57#define TARGET_AT_HWCAP 16
58#define TARGET_AT_CLKTCK 17
59
60/* Used with get_progbounds to find out how much memory is needed for the
61 program. We don't want to allocate more, since that could mask
62 invalid memory accesses program bugs. */
63struct progbounds {
64 USI startmem;
65 USI endmem;
66};
67
68static void free_state (SIM_DESC);
69static void get_progbounds (bfd *, asection *, void *);
70static SIM_RC cris_option_handler (SIM_DESC, sim_cpu *, int, char *, int);
71
72/* Since we don't build the cgen-opcode table, we use the old
73 disassembler. */
74static CGEN_DISASSEMBLER cris_disassemble_insn;
75
76/* By default, we set up stack and environment variables like the Linux
77 kernel. */
78static char cris_bare_iron = 0;
79
80/* Whether 0x9000000xx have simulator-specific meanings. */
aad3b3cb 81char cris_have_900000xxif = 0;
f6bcefef
HPN
82
83/* Records simulator descriptor so utilities like cris_dump_regs can be
84 called from gdb. */
85SIM_DESC current_state;
86
87/* CRIS-specific options. */
88typedef enum {
89 OPTION_CRIS_STATS = OPTION_START,
90 OPTION_CRIS_TRACE,
91 OPTION_CRIS_NAKED,
92 OPTION_CRIS_900000XXIF,
93} CRIS_OPTIONS;
94
95static const OPTION cris_options[] =
96{
97 { {"cris-cycles", required_argument, NULL, OPTION_CRIS_STATS},
98 '\0', "basic|unaligned|schedulable|all",
99 "Dump execution statistics",
100 cris_option_handler, NULL },
101 { {"cris-trace", required_argument, NULL, OPTION_CRIS_TRACE},
102 '\0', "basic",
103 "Emit trace information while running",
104 cris_option_handler, NULL },
105 { {"cris-naked", no_argument, NULL, OPTION_CRIS_NAKED},
106 '\0', NULL, "Don't set up stack and environment",
107 cris_option_handler, NULL },
108 { {"cris-900000xx", no_argument, NULL, OPTION_CRIS_900000XXIF},
109 '\0', NULL, "Define addresses at 0x900000xx with simulator semantics",
110 cris_option_handler, NULL },
111 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
112};
113\f
114/* Add the CRIS-specific option list to the simulator. */
115
116SIM_RC
117cris_option_install (SIM_DESC sd)
118{
119 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
120 if (sim_add_option_table (sd, NULL, cris_options) != SIM_RC_OK)
121 return SIM_RC_FAIL;
122 return SIM_RC_OK;
123}
124
125/* Handle CRIS-specific options. */
126
127static SIM_RC
128cris_option_handler (SIM_DESC sd, sim_cpu *cpu ATTRIBUTE_UNUSED, int opt,
129 char *arg, int is_command ATTRIBUTE_UNUSED)
130{
131 /* The options are CRIS-specific, but cpu-specific option-handling is
132 broken; required to being with "--cpu0-". We store the flags in an
133 unused field in the global state structure and move the flags over
134 to the module-specific CPU data when we store things in the
135 cpu-specific structure. */
136 char *tracefp = STATE_TRACE_FLAGS (sd);
137
138 switch ((CRIS_OPTIONS) opt)
139 {
140 case OPTION_CRIS_STATS:
141 if (strcmp (arg, "basic") == 0)
142 *tracefp = FLAG_CRIS_MISC_PROFILE_SIMPLE;
143 else if (strcmp (arg, "unaligned") == 0)
144 *tracefp
145 = (FLAG_CRIS_MISC_PROFILE_UNALIGNED
146 | FLAG_CRIS_MISC_PROFILE_SIMPLE);
147 else if (strcmp (arg, "schedulable") == 0)
148 *tracefp
149 = (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE
150 | FLAG_CRIS_MISC_PROFILE_SIMPLE);
151 else if (strcmp (arg, "all") == 0)
152 *tracefp = FLAG_CRIS_MISC_PROFILE_ALL;
153 else
154 {
155 /* We'll actually never get here; the caller handles the
156 error case. */
157 sim_io_eprintf (sd, "Unknown option `--cris-stats=%s'\n", arg);
158 return SIM_RC_FAIL;
159 }
160 break;
161
162 case OPTION_CRIS_TRACE:
163 if (strcmp (arg, "basic") == 0)
164 *tracefp |= FLAG_CRIS_MISC_PROFILE_XSIM_TRACE;
165 else
166 {
167 sim_io_eprintf (sd, "Unknown option `--cris-trace=%s'\n", arg);
168 return SIM_RC_FAIL;
169 }
170 break;
171
172 case OPTION_CRIS_NAKED:
173 cris_bare_iron = 1;
174 break;
175
176 case OPTION_CRIS_900000XXIF:
177 cris_have_900000xxif = 1;
178 break;
179
180 default:
181 /* We'll actually never get here; the caller handles the error
182 case. */
183 sim_io_eprintf (sd, "Unknown option `%s'\n", arg);
184 return SIM_RC_FAIL;
185 }
186
187 /* Imply --profile-model=on. */
188 return sim_profile_set_option (sd, "-model", PROFILE_MODEL_IDX, "on");
189}
190
191/* Cover function of sim_state_free to free the cpu buffers as well. */
192
193static void
194free_state (SIM_DESC sd)
195{
196 if (STATE_MODULES (sd) != NULL)
197 sim_module_uninstall (sd);
198 sim_cpu_free_all (sd);
199 sim_state_free (sd);
200}
201
202/* BFD section iterator to find the highest allocated section address
203 (plus one). If we could, we should use the program header table
204 instead, but we can't get to that using bfd. */
205
206void
207get_progbounds (bfd *abfd ATTRIBUTE_UNUSED, asection *s, void *vp)
208{
209 struct progbounds *pbp = (struct progbounds *) vp;
210
211 if ((bfd_get_section_flags (abfd, s) & SEC_ALLOC))
212 {
213 bfd_size_type sec_size = bfd_get_section_size (s);
214 bfd_size_type sec_start = bfd_get_section_vma (abfd, s);
215 bfd_size_type sec_end = sec_start + sec_size;
216
217 if (sec_end > pbp->endmem)
218 pbp->endmem = sec_end;
219
220 if (sec_start < pbp->startmem)
221 pbp->startmem = sec_start;
222 }
223}
224
225/* Create an instance of the simulator. */
226
227SIM_DESC
228sim_open (SIM_OPEN_KIND kind, host_callback *callback, struct bfd *abfd,
229 char **argv)
230{
231 char c;
232 int i;
233 USI startmem = 0;
234 USI endmem = CRIS_DEFAULT_MEM_SIZE;
235 USI endbrk = endmem;
236 USI stack_low = 0;
237 SIM_DESC sd = sim_state_alloc (kind, callback);
238
239 /* Can't initialize to "" below. It's either a GCC bug in old
240 releases (up to and including 2.95.3 (.4 in debian) or a bug in the
241 standard ;-) that the rest of the elements won't be initialized. */
242 bfd_byte sp_init[4] = {0, 0, 0, 0};
243
244 /* The cpu data is kept in a separately allocated chunk of memory. */
245 if (sim_cpu_alloc_all (sd, 1, cgen_cpu_max_extra_bytes ()) != SIM_RC_OK)
246 {
247 free_state (sd);
248 return 0;
249 }
250
251 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
252 {
253 free_state (sd);
254 return 0;
255 }
256
257 /* getopt will print the error message so we just have to exit if this fails.
258 FIXME: Hmmm... in the case of gdb we need getopt to call
259 print_filtered. */
260 if (sim_parse_args (sd, argv) != SIM_RC_OK)
261 {
262 free_state (sd);
263 return 0;
264 }
265
266 /* If we have a binary program, endianness-setting would not be taken
267 from elsewhere unfortunately, so set it here. At the time of this
268 writing, it isn't used until sim_config, but that might change so
269 set it here before memory is defined or touched. */
270 current_target_byte_order = LITTLE_ENDIAN;
271
272 /* check for/establish the reference program image */
273 if (sim_analyze_program (sd,
274 (STATE_PROG_ARGV (sd) != NULL
275 ? *STATE_PROG_ARGV (sd)
276 : NULL),
277 abfd) != SIM_RC_OK)
278 {
279 free_state (sd);
280 return 0;
281 }
282
283 /* For CRIS simulator-specific use, we need to find out the bounds of
284 the program as well, which is not done by sim_analyze_program
285 above. */
286 if (STATE_PROG_BFD (sd))
287 {
288 struct progbounds pb;
289
290 /* The sections should now be accessible using bfd functions. */
291 pb.startmem = 0x7fffffff;
292 pb.endmem = 0;
293 bfd_map_over_sections (STATE_PROG_BFD (sd), get_progbounds, &pb);
294
295 /* We align the area that the program uses to page boundaries. */
296 startmem = pb.startmem & ~8191;
297 endbrk = pb.endmem;
298 endmem = (endbrk + 8191) & ~8191;
299 }
300
301 /* Find out how much room is needed for the environment and argv, create
302 that memory and fill it. Only do this when there's a program
303 specified. */
304 if (STATE_PROG_BFD (sd) && !cris_bare_iron)
305 {
306 char *name = bfd_get_filename (STATE_PROG_BFD (sd));
307 char **my_environ = GET_ENVIRON ();
308 /* We use these maps to give the same behavior as the old xsim
309 simulator. */
310 USI envtop = 0x40000000;
311 USI stacktop = 0x3e000000;
312 USI envstart;
313 int envc;
314 int len = strlen (name) + 1;
315 USI epp, epp0;
316 USI stacklen;
317 int i;
318 char **prog_argv = STATE_PROG_ARGV (sd);
319 int my_argc = 0;
320 /* All CPU:s have the same memory map, apparently. */
321 SIM_CPU *cpu = STATE_CPU (sd, 0);
322 USI csp;
323 bfd_byte buf[4];
324
325 /* Count in the environment as well. */
326 for (envc = 0; my_environ[envc] != NULL; envc++)
327 len += strlen (my_environ[envc]) + 1;
328
329 for (i = 0; prog_argv[i] != NULL; my_argc++, i++)
330 len += strlen (prog_argv[i]) + 1;
331
332 envstart = (envtop - len) & ~8191;
333
334 /* Create read-only block for the environment strings. */
335 sim_core_attach (sd, NULL, 0, access_read, 0,
336 envstart, (len + 8191) & ~8191,
337 0, NULL, NULL);
338
339 /* This shouldn't happen. */
340 if (envstart < stacktop)
341 stacktop = envstart - 64 * 8192;
342
343 csp = stacktop;
344
345 /* Note that the linux kernel does not correctly compute the storage
346 needs for the static-exe AUX vector. */
347 csp -= 4 * 4 * 2;
348
349 csp -= (envc + 1) * 4;
350 csp -= (my_argc + 1) * 4;
351 csp -= 4;
352
353 /* Write the target representation of the start-up-value for the
354 stack-pointer suitable for register initialization below. */
355 bfd_putl32 (csp, sp_init);
356
357 /* If we make this 1M higher; say 8192*1024, we have to take
358 special precautions for pthreads, because pthreads assumes that
359 the memory that low isn't mmapped, and that it can mmap it
360 without fallback in case of failure (and we fail ungracefully
361 long before *that*: the memory isn't accounted for in our mmap
362 list). */
363 stack_low = (csp - (7168*1024)) & ~8191;
364
365 stacklen = stacktop - stack_low;
366
367 /* Tee hee, we have an executable stack. Well, it's necessary to
368 test GCC trampolines... */
369 sim_core_attach (sd, NULL, 0, access_read_write_exec, 0,
370 stack_low, stacklen,
371 0, NULL, NULL);
372
373 epp = epp0 = envstart;
374
375 /* Can't use sim_core_write_unaligned_4 without everything
376 initialized when tracing, and then these writes would get into
377 the trace. */
378#define write_dword(addr, data) \
379 do \
380 { \
381 USI data_ = data; \
382 USI addr_ = addr; \
383 bfd_putl32 (data_, buf); \
384 if (sim_core_write_buffer (sd, cpu, 0, buf, addr_, 4) != 4) \
385 goto abandon_chip; \
386 } \
387 while (0)
388
389 write_dword (csp, my_argc);
390 csp += 4;
391
392 for (i = 0; i < my_argc; i++, csp += 4)
393 {
394 size_t strln = strlen (prog_argv[i]) + 1;
395
396 if (sim_core_write_buffer (sd, cpu, 0, prog_argv[i], epp, strln)
397 != strln)
398 goto abandon_chip;
399
400 write_dword (csp, envstart + epp - epp0);
401 epp += strln;
402 }
403
404 write_dword (csp, 0);
405 csp += 4;
406
407 for (i = 0; i < envc; i++, csp += 4)
408 {
409 unsigned int strln = strlen (my_environ[i]) + 1;
410
411 if (sim_core_write_buffer (sd, cpu, 0, my_environ[i], epp, strln)
412 != strln)
413 goto abandon_chip;
414
415 write_dword (csp, envstart + epp - epp0);
416 epp += strln;
417 }
418
419 write_dword (csp, 0);
420 csp += 4;
421
422#define NEW_AUX_ENT(nr, id, val) \
423 do \
424 { \
425 write_dword (csp + (nr) * 4 * 2, (id)); \
426 write_dword (csp + (nr) * 4 * 2 + 4, (val)); \
427 } \
428 while (0)
429
430 /* Note that there are some extra AUX entries for a dynlinked
431 program loaded image. */
432
433 /* AUX entries always present. */
434 NEW_AUX_ENT (0, TARGET_AT_HWCAP, 0);
435 NEW_AUX_ENT (1, TARGET_AT_PAGESZ, 8192);
436 NEW_AUX_ENT (2, TARGET_AT_CLKTCK, 100);
437
438 csp += 4 * 2 * 3;
439 NEW_AUX_ENT (0, TARGET_AT_NULL, 0);
440#undef NEW_AUX_ENT
441
442 /* Register R10 should hold 0 at static start (no initfunc), but
443 that's the default, so don't bother. */
444 }
445
446 /* Allocate core managed memory if none specified by user. */
447 if (sim_core_read_buffer (sd, NULL, read_map, &c, startmem, 1) == 0)
448 sim_do_commandf (sd, "memory region 0x%lx,0x%lx", startmem,
449 endmem - startmem);
450
451 /* Allocate simulator I/O managed memory if none specified by user. */
452 if (cris_have_900000xxif)
453 {
454 if (sim_core_read_buffer (sd, NULL, read_map, &c, 0x90000000, 1) == 0)
455 sim_core_attach (sd, NULL, 0, access_write, 0, 0x90000000, 0x100,
456 0, &cris_devices, NULL);
457 else
458 {
459 (*callback->
460 printf_filtered) (callback,
461 "Seeing --cris-900000xx with memory defined there\n");
462 goto abandon_chip;
463 }
464 }
465
466 /* Establish any remaining configuration options. */
467 if (sim_config (sd) != SIM_RC_OK)
468 {
469 abandon_chip:
470 free_state (sd);
471 return 0;
472 }
473
474 if (sim_post_argv_init (sd) != SIM_RC_OK)
475 {
476 free_state (sd);
477 return 0;
478 }
479
480 /* Open a copy of the cpu descriptor table. */
481 {
482 CGEN_CPU_DESC cd = cris_cgen_cpu_open_1 (STATE_ARCHITECTURE (sd)->printable_name,
483 CGEN_ENDIAN_LITTLE);
484 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
485 {
486 SIM_CPU *cpu = STATE_CPU (sd, i);
487 CPU_CPU_DESC (cpu) = cd;
488 CPU_DISASSEMBLER (cpu) = cris_disassemble_insn;
489
490 /* See cris_option_handler for the reason why this is needed. */
491 CPU_CRIS_MISC_PROFILE (cpu)->flags = STATE_TRACE_FLAGS (sd)[0];
492
493 /* Set SP to the stack we allocated above. */
494 (* CPU_REG_STORE (cpu)) (cpu, H_GR_SP, (char *) sp_init, 4);
495
496 /* Set the simulator environment data. */
497 cpu->highest_mmapped_page = NULL;
498 cpu->endmem = endmem;
499 cpu->endbrk = endbrk;
500 cpu->stack_low = stack_low;
501 cpu->syscalls = 0;
502 cpu->m1threads = 0;
503 cpu->threadno = 0;
504 cpu->max_threadid = 0;
505 cpu->thread_data = NULL;
506 memset (cpu->sighandler, 0, sizeof (cpu->sighandler));
507 cpu->make_thread_cpu_data = NULL;
508 cpu->thread_cpu_data_size = 0;
aad3b3cb
HPN
509#if WITH_HW
510 cpu->deliver_interrupt = NULL;
511#endif
f6bcefef 512 }
aad3b3cb
HPN
513#if WITH_HW
514 /* Always be cycle-accurate and call before/after functions if
515 with-hardware. */
516 sim_profile_set_option (sd, "-model", PROFILE_MODEL_IDX, "on");
517#endif
f6bcefef
HPN
518 }
519
520 /* Initialize various cgen things not done by common framework.
521 Must be done after cris_cgen_cpu_open. */
522 cgen_init (sd);
523
524 /* Store in a global so things like cris_dump_regs can be invoked
525 from the gdb command line. */
526 current_state = sd;
527
528 cris_set_callbacks (callback);
529
530 return sd;
531}
532
533void
534sim_close (SIM_DESC sd, int quitting ATTRIBUTE_UNUSED)
535{
536 cris_cgen_cpu_close (CPU_CPU_DESC (STATE_CPU (sd, 0)));
537 sim_module_uninstall (sd);
538}
539\f
540SIM_RC
541sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
542 char **argv ATTRIBUTE_UNUSED,
543 char **envp ATTRIBUTE_UNUSED)
544{
545 SIM_CPU *current_cpu = STATE_CPU (sd, 0);
546 SIM_ADDR addr;
547
548 if (abfd != NULL)
549 addr = bfd_get_start_address (abfd);
550 else
551 addr = 0;
552 sim_pc_set (current_cpu, addr);
553
554 /* Other simulators have #if 0:d code that says
555 STATE_ARGV (sd) = sim_copy_argv (argv);
556 STATE_ENVP (sd) = sim_copy_argv (envp);
557 Enabling that gives you not-found link-errors for sim_copy_argv.
558 FIXME: Do archaeology to find out more. */
559
560 return SIM_RC_OK;
561}
562
563void
564sim_do_command (SIM_DESC sd, char *cmd)
565{
566 if (sim_args_command (sd, cmd) != SIM_RC_OK)
567 sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
568}
569\f
570/* Disassemble an instruction. */
571
572static void
573cris_disassemble_insn (SIM_CPU *cpu,
574 const CGEN_INSN *insn ATTRIBUTE_UNUSED,
575 const ARGBUF *abuf ATTRIBUTE_UNUSED,
576 IADDR pc, char *buf)
577{
578 disassembler_ftype pinsn;
579 struct disassemble_info disasm_info;
580 SFILE sfile;
581 SIM_DESC sd = CPU_STATE (cpu);
582
583 sfile.buffer = sfile.current = buf;
584 INIT_DISASSEMBLE_INFO (disasm_info, (FILE *) &sfile,
585 (fprintf_ftype) sim_disasm_sprintf);
586 disasm_info.endian =
587 (bfd_big_endian (STATE_PROG_BFD (sd)) ? BFD_ENDIAN_BIG
588 : bfd_little_endian (STATE_PROG_BFD (sd)) ? BFD_ENDIAN_LITTLE
589 : BFD_ENDIAN_UNKNOWN);
590 /* We live with the cast until the prototype is fixed, or else we get a
591 warning because the functions differ in the signedness of one parameter. */
592 disasm_info.read_memory_func =
593 sim_disasm_read_memory;
594 disasm_info.memory_error_func = sim_disasm_perror_memory;
595 disasm_info.application_data = (PTR) cpu;
596 pinsn = cris_get_disassembler (STATE_PROG_BFD (sd));
597 (*pinsn) (pc, &disasm_info);
598}
This page took 0.081661 seconds and 4 git commands to generate.