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