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