]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/arm/wrapper.c
sim: sim-close: unify sim_close logic
[thirdparty/binutils-gdb.git] / sim / arm / wrapper.c
CommitLineData
c906108c 1/* run front end support for arm
32d0add0 2 Copyright (C) 1995-2015 Free Software Foundation, Inc.
c906108c 3
86c735a5 4 This file is part of ARM SIM.
c906108c 5
4744ac1b
JB
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
c906108c 10
4744ac1b
JB
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
c906108c 15
4744ac1b
JB
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c 18
86c735a5
NC
19/* This file provides the interface between the simulator and
20 run.c and gdb (when the simulator is linked with gdb).
c906108c
SS
21 All simulator interaction should go through this file. */
22
a6ff997c 23#include "config.h"
c906108c
SS
24#include <stdio.h>
25#include <stdarg.h>
6d358e86 26#include <string.h>
c906108c
SS
27#include <bfd.h>
28#include <signal.h>
3c25f8c7
AC
29#include "gdb/callback.h"
30#include "gdb/remote-sim.h"
49d62f89
MF
31#include "sim-main.h"
32#include "sim-options.h"
c906108c
SS
33#include "armemu.h"
34#include "dbg_rdi.h"
6d358e86 35#include "ansidecl.h"
26216b98 36#include "gdb/sim-arm.h"
aba6488e 37#include "gdb/signals.h"
9256caa6 38#include "libiberty.h"
8d052926 39#include "iwmmxt.h"
74ec5579 40
49d62f89 41/* TODO: This should get pulled from the SIM_DESC. */
c906108c
SS
42host_callback *sim_callback;
43
49d62f89
MF
44/* TODO: This should get merged into sim_cpu. */
45struct ARMul_State *state;
c906108c
SS
46
47/* Memory size in bytes. */
49d62f89 48/* TODO: Memory should be converted to the common memory module. */
058f270d 49static int mem_size = (1 << 21);
c906108c 50
7a292a7a
SS
51int stop_simulator;
52
8d052926
NC
53#include "dis-asm.h"
54
49d62f89 55/* TODO: Tracing should be converted to common tracing module. */
8d052926
NC
56int trace = 0;
57int disas = 0;
58int trace_funcs = 0;
59
60static struct disassemble_info info;
61static char opbuf[1000];
62
63static int
64op_printf (char *buf, char *fmt, ...)
65{
66 int ret;
67 va_list ap;
68
69 va_start (ap, fmt);
70 ret = vsprintf (opbuf + strlen (opbuf), fmt, ap);
71 va_end (ap);
72 return ret;
73}
74
75static int
76sim_dis_read (bfd_vma memaddr ATTRIBUTE_UNUSED,
77 bfd_byte * ptr,
78 unsigned int length,
79 struct disassemble_info * info)
80{
81 ARMword val = (ARMword) *((ARMword *) info->application_data);
82
83 while (length--)
84 {
85 * ptr ++ = val & 0xFF;
86 val >>= 8;
87 }
88 return 0;
89}
90
91void
92print_insn (ARMword instr)
93{
94 int size;
95
96 opbuf[0] = 0;
97 info.application_data = & instr;
98 size = print_insn_little_arm (0, & info);
99 fprintf (stderr, " %*s\n", size, opbuf);
100}
101
f603c8fe
NC
102/* Cirrus DSP registers.
103
104 We need to define these registers outside of maverick.c because
105 maverick.c might not be linked in unless --target=arm9e-* in which
106 case wrapper.c will not compile because it tries to access Cirrus
107 registers. This should all go away once we get the Cirrus and ARM
108 Coprocessor to coexist in armcopro.c-- aldyh. */
109
110struct maverick_regs
111{
112 union
113 {
114 int i;
115 float f;
116 } upper;
454de2ee 117
f603c8fe
NC
118 union
119 {
120 int i;
121 float f;
122 } lower;
123};
124
125union maverick_acc_regs
126{
127 long double ld; /* Acc registers are 72-bits. */
128};
129
130struct maverick_regs DSPregs[16];
131union maverick_acc_regs DSPacc[4];
132ARMword DSPsc;
133
dfcd3bfb 134static void
d68d7e6b 135init (void)
c906108c
SS
136{
137 static int done;
138
139 if (!done)
140 {
dfcd3bfb 141 ARMul_EmulateInit ();
c906108c 142 state = ARMul_NewState ();
49d62f89 143 state->bigendSig = (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN ? HIGH : LOW);
dfcd3bfb
JM
144 ARMul_MemoryInit (state, mem_size);
145 ARMul_OSInit (state);
58b991b1 146 state->verbose = 0;
c906108c
SS
147 done = 1;
148 }
149}
150
dfcd3bfb 151void
bdca5ee4
TT
152ARMul_ConsolePrint (ARMul_State * state,
153 const char * format,
154 ...)
c906108c
SS
155{
156 va_list ap;
157
158 if (state->verbose)
159 {
160 va_start (ap, format);
161 vprintf (format, ap);
162 va_end (ap);
163 }
164}
165
6d358e86 166ARMword
d68d7e6b
NC
167ARMul_Debug (ARMul_State * state ATTRIBUTE_UNUSED,
168 ARMword pc ATTRIBUTE_UNUSED,
169 ARMword instr ATTRIBUTE_UNUSED)
c906108c 170{
6d358e86 171 return 0;
c906108c
SS
172}
173
174int
d68d7e6b
NC
175sim_write (SIM_DESC sd ATTRIBUTE_UNUSED,
176 SIM_ADDR addr,
177 const unsigned char * buffer,
178 int size)
c906108c
SS
179{
180 int i;
3943c96b 181
c906108c 182 init ();
3943c96b 183
c906108c 184 for (i = 0; i < size; i++)
917bca4f 185 ARMul_SafeWriteByte (state, addr + i, buffer[i]);
3943c96b 186
c906108c
SS
187 return size;
188}
189
190int
d68d7e6b
NC
191sim_read (SIM_DESC sd ATTRIBUTE_UNUSED,
192 SIM_ADDR addr,
193 unsigned char * buffer,
194 int size)
c906108c
SS
195{
196 int i;
917bca4f 197
c906108c 198 init ();
86c735a5 199
c906108c 200 for (i = 0; i < size; i++)
917bca4f
NC
201 buffer[i] = ARMul_SafeReadByte (state, addr + i);
202
c906108c
SS
203 return size;
204}
205
c906108c 206int
d68d7e6b 207sim_stop (SIM_DESC sd ATTRIBUTE_UNUSED)
c906108c 208{
7a292a7a
SS
209 state->Emulate = STOP;
210 stop_simulator = 1;
211 return 1;
c906108c
SS
212}
213
214void
d68d7e6b
NC
215sim_resume (SIM_DESC sd ATTRIBUTE_UNUSED,
216 int step,
217 int siggnal ATTRIBUTE_UNUSED)
c906108c
SS
218{
219 state->EndCondition = 0;
7a292a7a 220 stop_simulator = 0;
c906108c
SS
221
222 if (step)
223 {
224 state->Reg[15] = ARMul_DoInstr (state);
225 if (state->EndCondition == 0)
226 state->EndCondition = RDIError_BreakpointReached;
227 }
228 else
229 {
dfcd3bfb 230 state->NextInstr = RESUME; /* treat as PC change */
c906108c
SS
231 state->Reg[15] = ARMul_DoProg (state);
232 }
233
234 FLUSHPIPE;
235}
236
237SIM_RC
d68d7e6b
NC
238sim_create_inferior (SIM_DESC sd ATTRIBUTE_UNUSED,
239 struct bfd * abfd,
240 char ** argv,
241 char ** env)
c906108c 242{
dfcd3bfb 243 int argvlen = 0;
1e6b544a 244 int mach;
c906108c
SS
245 char **arg;
246
1ed6c797
WN
247 init ();
248
c906108c 249 if (abfd != NULL)
8782aa32
WN
250 {
251 ARMul_SetPC (state, bfd_get_start_address (abfd));
252 mach = bfd_get_mach (abfd);
253 }
c906108c 254 else
8782aa32
WN
255 {
256 ARMul_SetPC (state, 0); /* ??? */
257 mach = 0;
258 }
1e6b544a 259
73cb0348
NC
260#ifdef MODET
261 if (abfd != NULL && (bfd_get_start_address (abfd) & 1))
262 SETT;
263#endif
264
3943c96b
NC
265 switch (mach)
266 {
267 default:
86c735a5
NC
268 (*sim_callback->printf_filtered)
269 (sim_callback,
10b57fcb
NC
270 "Unknown machine type '%d'; please update sim_create_inferior.\n",
271 mach);
3943c96b
NC
272 /* fall through */
273
f1129fb8 274 case 0:
3943c96b 275 /* We wouldn't set the machine type with earlier toolchains, so we
f1129fb8
NC
276 explicitly select a processor capable of supporting all ARMs in
277 32bit mode. */
8d052926
NC
278 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_v6_Prop);
279 break;
280
272fcdcd 281 case bfd_mach_arm_XScale:
8207e0f2 282 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_v6_Prop);
272fcdcd
NC
283 break;
284
b0f05691 285 case bfd_mach_arm_iWMMXt2:
0f026fd0
NC
286 case bfd_mach_arm_iWMMXt:
287 {
288 extern int SWI_vector_installed;
289 ARMword i;
290
291 if (! SWI_vector_installed)
292 {
293 /* Intialise the hardware vectors to zero. */
294 if (! SWI_vector_installed)
295 for (i = ARMul_ResetV; i <= ARMFIQV; i += 4)
296 ARMul_WriteWord (state, i, 0);
297
298 /* ARM_WriteWord will have detected the write to the SWI vector,
299 but we want SWI_vector_installed to remain at 0 so that thumb
300 mode breakpoints will work. */
301 SWI_vector_installed = 0;
302 }
303 }
304 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_iWMMXt_Prop);
305 break;
306
f603c8fe
NC
307 case bfd_mach_arm_ep9312:
308 ARMul_SelectProcessor (state, ARM_v4_Prop | ARM_ep9312_Prop);
309 break;
310
f1129fb8 311 case bfd_mach_arm_5:
c17aa318
NC
312 if (bfd_family_coff (abfd))
313 {
314 /* This is a special case in order to support COFF based ARM toolchains.
315 The COFF header does not have enough room to store all the different
316 kinds of ARM cpu, so the XScale, v5T and v5TE architectures all default
317 to v5. (See coff_set_flags() in bdf/coffcode.h). So if we see a v5
318 machine type here, we assume it could be any of the above architectures
319 and so select the most feature-full. */
320 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop);
321 break;
322 }
323 /* Otherwise drop through. */
25180f8a 324
f1129fb8
NC
325 case bfd_mach_arm_5T:
326 ARMul_SelectProcessor (state, ARM_v5_Prop);
327 break;
3943c96b 328
f1129fb8
NC
329 case bfd_mach_arm_5TE:
330 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop);
331 break;
332
f1129fb8
NC
333 case bfd_mach_arm_4:
334 case bfd_mach_arm_4T:
335 ARMul_SelectProcessor (state, ARM_v4_Prop);
336 break;
337
338 case bfd_mach_arm_3:
339 case bfd_mach_arm_3M:
3943c96b
NC
340 ARMul_SelectProcessor (state, ARM_Lock_Prop);
341 break;
342
f1129fb8
NC
343 case bfd_mach_arm_2:
344 case bfd_mach_arm_2a:
3943c96b
NC
345 ARMul_SelectProcessor (state, ARM_Fix26_Prop);
346 break;
347 }
348
8d052926
NC
349 memset (& info, 0, sizeof (info));
350 INIT_DISASSEMBLE_INFO (info, stdout, op_printf);
351 info.read_memory_func = sim_dis_read;
352 info.arch = bfd_get_arch (abfd);
353 info.mach = bfd_get_mach (abfd);
354 info.endian_code = BFD_ENDIAN_LITTLE;
355 if (info.mach == 0)
356 info.arch = bfd_arch_arm;
357 disassemble_init_for_target (& info);
358
c906108c
SS
359 if (argv != NULL)
360 {
5f7d0a33
NC
361 /* Set up the command line by laboriously stringing together
362 the environment carefully picked apart by our caller. */
363
364 /* Free any old stuff. */
c906108c
SS
365 if (state->CommandLine != NULL)
366 {
dfcd3bfb 367 free (state->CommandLine);
c906108c
SS
368 state->CommandLine = NULL;
369 }
dfcd3bfb 370
5f7d0a33 371 /* See how much we need. */
c906108c 372 for (arg = argv; *arg != NULL; arg++)
dfcd3bfb
JM
373 argvlen += strlen (*arg) + 1;
374
5f7d0a33 375 /* Allocate it. */
dfcd3bfb 376 state->CommandLine = malloc (argvlen + 1);
c906108c
SS
377 if (state->CommandLine != NULL)
378 {
379 arg = argv;
dfcd3bfb 380 state->CommandLine[0] = '\0';
5f7d0a33 381
c906108c
SS
382 for (arg = argv; *arg != NULL; arg++)
383 {
dfcd3bfb
JM
384 strcat (state->CommandLine, *arg);
385 strcat (state->CommandLine, " ");
c906108c
SS
386 }
387 }
388 }
389
390 if (env != NULL)
391 {
5f7d0a33 392 /* Now see if there's a MEMSIZE spec in the environment. */
c906108c
SS
393 while (*env)
394 {
dfcd3bfb 395 if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
c906108c 396 {
c906108c 397 char *end_of_num;
dfcd3bfb 398
5f7d0a33 399 /* Set up memory limit. */
dfcd3bfb
JM
400 state->MemSize =
401 strtoul (*env + sizeof ("MEMSIZE=") - 1, &end_of_num, 0);
c906108c
SS
402 }
403 env++;
404 }
405 }
406
407 return SIM_RC_OK;
408}
409
dfcd3bfb 410static int
d68d7e6b 411frommem (struct ARMul_State *state, unsigned char *memory)
c906108c
SS
412{
413 if (state->bigendSig == HIGH)
86c735a5
NC
414 return (memory[0] << 24) | (memory[1] << 16)
415 | (memory[2] << 8) | (memory[3] << 0);
c906108c 416 else
86c735a5
NC
417 return (memory[3] << 24) | (memory[2] << 16)
418 | (memory[1] << 8) | (memory[0] << 0);
c906108c
SS
419}
420
c906108c 421static void
d68d7e6b
NC
422tomem (struct ARMul_State *state,
423 unsigned char *memory,
424 int val)
c906108c
SS
425{
426 if (state->bigendSig == HIGH)
427 {
428 memory[0] = val >> 24;
429 memory[1] = val >> 16;
430 memory[2] = val >> 8;
431 memory[3] = val >> 0;
432 }
433 else
434 {
435 memory[3] = val >> 24;
436 memory[2] = val >> 16;
437 memory[1] = val >> 8;
438 memory[0] = val >> 0;
439 }
440}
441
442int
d68d7e6b
NC
443sim_store_register (SIM_DESC sd ATTRIBUTE_UNUSED,
444 int rn,
445 unsigned char *memory,
446 int length)
c906108c
SS
447{
448 init ();
f1129fb8 449
26216b98 450 switch ((enum sim_arm_regs) rn)
3463c3fb 451 {
26216b98
AC
452 case SIM_ARM_R0_REGNUM:
453 case SIM_ARM_R1_REGNUM:
454 case SIM_ARM_R2_REGNUM:
455 case SIM_ARM_R3_REGNUM:
456 case SIM_ARM_R4_REGNUM:
457 case SIM_ARM_R5_REGNUM:
458 case SIM_ARM_R6_REGNUM:
459 case SIM_ARM_R7_REGNUM:
460 case SIM_ARM_R8_REGNUM:
461 case SIM_ARM_R9_REGNUM:
462 case SIM_ARM_R10_REGNUM:
463 case SIM_ARM_R11_REGNUM:
464 case SIM_ARM_R12_REGNUM:
465 case SIM_ARM_R13_REGNUM:
466 case SIM_ARM_R14_REGNUM:
467 case SIM_ARM_R15_REGNUM: /* PC */
468 case SIM_ARM_FP0_REGNUM:
469 case SIM_ARM_FP1_REGNUM:
470 case SIM_ARM_FP2_REGNUM:
471 case SIM_ARM_FP3_REGNUM:
472 case SIM_ARM_FP4_REGNUM:
473 case SIM_ARM_FP5_REGNUM:
474 case SIM_ARM_FP6_REGNUM:
475 case SIM_ARM_FP7_REGNUM:
476 case SIM_ARM_FPS_REGNUM:
477 ARMul_SetReg (state, state->Mode, rn, frommem (state, memory));
478 break;
479
480 case SIM_ARM_PS_REGNUM:
3463c3fb 481 state->Cpsr = frommem (state, memory);
10b57fcb 482 ARMul_CPSRAltered (state);
26216b98
AC
483 break;
484
f603c8fe
NC
485 case SIM_ARM_MAVERIC_COP0R0_REGNUM:
486 case SIM_ARM_MAVERIC_COP0R1_REGNUM:
487 case SIM_ARM_MAVERIC_COP0R2_REGNUM:
488 case SIM_ARM_MAVERIC_COP0R3_REGNUM:
489 case SIM_ARM_MAVERIC_COP0R4_REGNUM:
490 case SIM_ARM_MAVERIC_COP0R5_REGNUM:
491 case SIM_ARM_MAVERIC_COP0R6_REGNUM:
492 case SIM_ARM_MAVERIC_COP0R7_REGNUM:
493 case SIM_ARM_MAVERIC_COP0R8_REGNUM:
494 case SIM_ARM_MAVERIC_COP0R9_REGNUM:
495 case SIM_ARM_MAVERIC_COP0R10_REGNUM:
496 case SIM_ARM_MAVERIC_COP0R11_REGNUM:
497 case SIM_ARM_MAVERIC_COP0R12_REGNUM:
498 case SIM_ARM_MAVERIC_COP0R13_REGNUM:
499 case SIM_ARM_MAVERIC_COP0R14_REGNUM:
500 case SIM_ARM_MAVERIC_COP0R15_REGNUM:
501 memcpy (& DSPregs [rn - SIM_ARM_MAVERIC_COP0R0_REGNUM],
502 memory, sizeof (struct maverick_regs));
503 return sizeof (struct maverick_regs);
504
505 case SIM_ARM_MAVERIC_DSPSC_REGNUM:
506 memcpy (&DSPsc, memory, sizeof DSPsc);
507 return sizeof DSPsc;
508
0f026fd0
NC
509 case SIM_ARM_IWMMXT_COP0R0_REGNUM:
510 case SIM_ARM_IWMMXT_COP0R1_REGNUM:
511 case SIM_ARM_IWMMXT_COP0R2_REGNUM:
512 case SIM_ARM_IWMMXT_COP0R3_REGNUM:
513 case SIM_ARM_IWMMXT_COP0R4_REGNUM:
514 case SIM_ARM_IWMMXT_COP0R5_REGNUM:
515 case SIM_ARM_IWMMXT_COP0R6_REGNUM:
516 case SIM_ARM_IWMMXT_COP0R7_REGNUM:
517 case SIM_ARM_IWMMXT_COP0R8_REGNUM:
518 case SIM_ARM_IWMMXT_COP0R9_REGNUM:
519 case SIM_ARM_IWMMXT_COP0R10_REGNUM:
520 case SIM_ARM_IWMMXT_COP0R11_REGNUM:
521 case SIM_ARM_IWMMXT_COP0R12_REGNUM:
522 case SIM_ARM_IWMMXT_COP0R13_REGNUM:
523 case SIM_ARM_IWMMXT_COP0R14_REGNUM:
524 case SIM_ARM_IWMMXT_COP0R15_REGNUM:
525 case SIM_ARM_IWMMXT_COP1R0_REGNUM:
526 case SIM_ARM_IWMMXT_COP1R1_REGNUM:
527 case SIM_ARM_IWMMXT_COP1R2_REGNUM:
528 case SIM_ARM_IWMMXT_COP1R3_REGNUM:
529 case SIM_ARM_IWMMXT_COP1R4_REGNUM:
530 case SIM_ARM_IWMMXT_COP1R5_REGNUM:
531 case SIM_ARM_IWMMXT_COP1R6_REGNUM:
532 case SIM_ARM_IWMMXT_COP1R7_REGNUM:
533 case SIM_ARM_IWMMXT_COP1R8_REGNUM:
534 case SIM_ARM_IWMMXT_COP1R9_REGNUM:
535 case SIM_ARM_IWMMXT_COP1R10_REGNUM:
536 case SIM_ARM_IWMMXT_COP1R11_REGNUM:
537 case SIM_ARM_IWMMXT_COP1R12_REGNUM:
538 case SIM_ARM_IWMMXT_COP1R13_REGNUM:
539 case SIM_ARM_IWMMXT_COP1R14_REGNUM:
540 case SIM_ARM_IWMMXT_COP1R15_REGNUM:
541 return Store_Iwmmxt_Register (rn - SIM_ARM_IWMMXT_COP0R0_REGNUM, memory);
3a3d6f65 542
26216b98
AC
543 default:
544 return 0;
3463c3fb 545 }
26216b98 546
9256caa6 547 return length;
c906108c
SS
548}
549
550int
d68d7e6b
NC
551sim_fetch_register (SIM_DESC sd ATTRIBUTE_UNUSED,
552 int rn,
553 unsigned char *memory,
554 int length)
c906108c
SS
555{
556 ARMword regval;
9256caa6 557 int len = length;
c906108c
SS
558
559 init ();
f1129fb8 560
26216b98
AC
561 switch ((enum sim_arm_regs) rn)
562 {
563 case SIM_ARM_R0_REGNUM:
564 case SIM_ARM_R1_REGNUM:
565 case SIM_ARM_R2_REGNUM:
566 case SIM_ARM_R3_REGNUM:
567 case SIM_ARM_R4_REGNUM:
568 case SIM_ARM_R5_REGNUM:
569 case SIM_ARM_R6_REGNUM:
570 case SIM_ARM_R7_REGNUM:
571 case SIM_ARM_R8_REGNUM:
572 case SIM_ARM_R9_REGNUM:
573 case SIM_ARM_R10_REGNUM:
574 case SIM_ARM_R11_REGNUM:
575 case SIM_ARM_R12_REGNUM:
576 case SIM_ARM_R13_REGNUM:
577 case SIM_ARM_R14_REGNUM:
578 case SIM_ARM_R15_REGNUM: /* PC */
579 regval = ARMul_GetReg (state, state->Mode, rn);
580 break;
581
582 case SIM_ARM_FP0_REGNUM:
583 case SIM_ARM_FP1_REGNUM:
584 case SIM_ARM_FP2_REGNUM:
585 case SIM_ARM_FP3_REGNUM:
586 case SIM_ARM_FP4_REGNUM:
587 case SIM_ARM_FP5_REGNUM:
588 case SIM_ARM_FP6_REGNUM:
589 case SIM_ARM_FP7_REGNUM:
590 case SIM_ARM_FPS_REGNUM:
591 memset (memory, 0, length);
592 return 0;
593
594 case SIM_ARM_PS_REGNUM:
595 regval = ARMul_GetCPSR (state);
596 break;
597
f603c8fe
NC
598 case SIM_ARM_MAVERIC_COP0R0_REGNUM:
599 case SIM_ARM_MAVERIC_COP0R1_REGNUM:
600 case SIM_ARM_MAVERIC_COP0R2_REGNUM:
601 case SIM_ARM_MAVERIC_COP0R3_REGNUM:
602 case SIM_ARM_MAVERIC_COP0R4_REGNUM:
603 case SIM_ARM_MAVERIC_COP0R5_REGNUM:
604 case SIM_ARM_MAVERIC_COP0R6_REGNUM:
605 case SIM_ARM_MAVERIC_COP0R7_REGNUM:
606 case SIM_ARM_MAVERIC_COP0R8_REGNUM:
607 case SIM_ARM_MAVERIC_COP0R9_REGNUM:
608 case SIM_ARM_MAVERIC_COP0R10_REGNUM:
609 case SIM_ARM_MAVERIC_COP0R11_REGNUM:
610 case SIM_ARM_MAVERIC_COP0R12_REGNUM:
611 case SIM_ARM_MAVERIC_COP0R13_REGNUM:
612 case SIM_ARM_MAVERIC_COP0R14_REGNUM:
613 case SIM_ARM_MAVERIC_COP0R15_REGNUM:
614 memcpy (memory, & DSPregs [rn - SIM_ARM_MAVERIC_COP0R0_REGNUM],
615 sizeof (struct maverick_regs));
616 return sizeof (struct maverick_regs);
617
618 case SIM_ARM_MAVERIC_DSPSC_REGNUM:
619 memcpy (memory, & DSPsc, sizeof DSPsc);
620 return sizeof DSPsc;
621
0f026fd0
NC
622 case SIM_ARM_IWMMXT_COP0R0_REGNUM:
623 case SIM_ARM_IWMMXT_COP0R1_REGNUM:
624 case SIM_ARM_IWMMXT_COP0R2_REGNUM:
625 case SIM_ARM_IWMMXT_COP0R3_REGNUM:
626 case SIM_ARM_IWMMXT_COP0R4_REGNUM:
627 case SIM_ARM_IWMMXT_COP0R5_REGNUM:
628 case SIM_ARM_IWMMXT_COP0R6_REGNUM:
629 case SIM_ARM_IWMMXT_COP0R7_REGNUM:
630 case SIM_ARM_IWMMXT_COP0R8_REGNUM:
631 case SIM_ARM_IWMMXT_COP0R9_REGNUM:
632 case SIM_ARM_IWMMXT_COP0R10_REGNUM:
633 case SIM_ARM_IWMMXT_COP0R11_REGNUM:
634 case SIM_ARM_IWMMXT_COP0R12_REGNUM:
635 case SIM_ARM_IWMMXT_COP0R13_REGNUM:
636 case SIM_ARM_IWMMXT_COP0R14_REGNUM:
637 case SIM_ARM_IWMMXT_COP0R15_REGNUM:
638 case SIM_ARM_IWMMXT_COP1R0_REGNUM:
639 case SIM_ARM_IWMMXT_COP1R1_REGNUM:
640 case SIM_ARM_IWMMXT_COP1R2_REGNUM:
641 case SIM_ARM_IWMMXT_COP1R3_REGNUM:
642 case SIM_ARM_IWMMXT_COP1R4_REGNUM:
643 case SIM_ARM_IWMMXT_COP1R5_REGNUM:
644 case SIM_ARM_IWMMXT_COP1R6_REGNUM:
645 case SIM_ARM_IWMMXT_COP1R7_REGNUM:
646 case SIM_ARM_IWMMXT_COP1R8_REGNUM:
647 case SIM_ARM_IWMMXT_COP1R9_REGNUM:
648 case SIM_ARM_IWMMXT_COP1R10_REGNUM:
649 case SIM_ARM_IWMMXT_COP1R11_REGNUM:
650 case SIM_ARM_IWMMXT_COP1R12_REGNUM:
651 case SIM_ARM_IWMMXT_COP1R13_REGNUM:
652 case SIM_ARM_IWMMXT_COP1R14_REGNUM:
653 case SIM_ARM_IWMMXT_COP1R15_REGNUM:
654 return Fetch_Iwmmxt_Register (rn - SIM_ARM_IWMMXT_COP0R0_REGNUM, memory);
3a3d6f65 655
26216b98
AC
656 default:
657 return 0;
658 }
272fcdcd 659
9256caa6 660 while (len)
272fcdcd
NC
661 {
662 tomem (state, memory, regval);
663
9256caa6 664 len -= 4;
272fcdcd
NC
665 memory += 4;
666 regval = 0;
454de2ee 667 }
272fcdcd 668
9256caa6 669 return length;
c906108c
SS
670}
671
de4112fa
NC
672typedef struct
673{
674 char * swi_option;
675 unsigned int swi_mask;
676} swi_options;
677
678#define SWI_SWITCH "--swi-support"
679
680static swi_options options[] =
681 {
682 { "none", 0 },
683 { "demon", SWI_MASK_DEMON },
684 { "angel", SWI_MASK_ANGEL },
685 { "redboot", SWI_MASK_REDBOOT },
686 { "all", -1 },
687 { "NONE", 0 },
688 { "DEMON", SWI_MASK_DEMON },
689 { "ANGEL", SWI_MASK_ANGEL },
690 { "REDBOOT", SWI_MASK_REDBOOT },
691 { "ALL", -1 }
692 };
693
694
49d62f89 695static int
d68d7e6b 696sim_target_parse_command_line (int argc, char ** argv)
de4112fa
NC
697{
698 int i;
699
700 for (i = 1; i < argc; i++)
701 {
702 char * ptr = argv[i];
703 int arg;
704
705 if ((ptr == NULL) || (* ptr != '-'))
706 break;
707
8d052926
NC
708 if (strcmp (ptr, "-t") == 0)
709 {
710 trace = 1;
711 continue;
712 }
454de2ee 713
8d052926
NC
714 if (strcmp (ptr, "-z") == 0)
715 {
716 /* Remove this option from the argv array. */
717 for (arg = i; arg < argc; arg ++)
718 argv[arg] = argv[arg + 1];
719 argc --;
720 i --;
721 trace_funcs = 1;
722 continue;
723 }
454de2ee 724
8d052926
NC
725 if (strcmp (ptr, "-d") == 0)
726 {
727 /* Remove this option from the argv array. */
728 for (arg = i; arg < argc; arg ++)
729 argv[arg] = argv[arg + 1];
730 argc --;
731 i --;
732 disas = 1;
733 continue;
734 }
735
de4112fa
NC
736 if (strncmp (ptr, SWI_SWITCH, sizeof SWI_SWITCH - 1) != 0)
737 continue;
738
739 if (ptr[sizeof SWI_SWITCH - 1] == 0)
740 {
741 /* Remove this option from the argv array. */
742 for (arg = i; arg < argc; arg ++)
743 argv[arg] = argv[arg + 1];
744 argc --;
454de2ee 745
de4112fa
NC
746 ptr = argv[i];
747 }
748 else
749 ptr += sizeof SWI_SWITCH;
750
751 swi_mask = 0;
454de2ee 752
de4112fa
NC
753 while (* ptr)
754 {
755 int i;
756
757 for (i = sizeof options / sizeof options[0]; i--;)
758 if (strncmp (ptr, options[i].swi_option,
759 strlen (options[i].swi_option)) == 0)
760 {
761 swi_mask |= options[i].swi_mask;
762 ptr += strlen (options[i].swi_option);
763
764 if (* ptr == ',')
765 ++ ptr;
766
767 break;
768 }
769
770 if (i < 0)
771 break;
772 }
773
774 if (* ptr != 0)
775 fprintf (stderr, "Ignoring swi options: %s\n", ptr);
454de2ee 776
de4112fa
NC
777 /* Remove this option from the argv array. */
778 for (arg = i; arg < argc; arg ++)
779 argv[arg] = argv[arg + 1];
780 argc --;
781 i --;
782 }
783 return argc;
784}
785
786static void
d68d7e6b 787sim_target_parse_arg_array (char ** argv)
de4112fa
NC
788{
789 int i;
790
791 for (i = 0; argv[i]; i++)
792 ;
793
8944021f 794 sim_target_parse_command_line (i, argv);
de4112fa
NC
795}
796
27b97b40
MF
797static sim_cia
798arm_pc_get (sim_cpu *cpu)
799{
800 return PC;
801}
802
803static void
804arm_pc_set (sim_cpu *cpu, sim_cia pc)
805{
806 ARMul_SetPC (state, pc);
807}
808
49d62f89
MF
809static void
810free_state (SIM_DESC sd)
de4112fa 811{
49d62f89
MF
812 if (STATE_MODULES (sd) != NULL)
813 sim_module_uninstall (sd);
814 sim_cpu_free_all (sd);
815 sim_state_free (sd);
de4112fa 816}
de4112fa 817
c906108c 818SIM_DESC
49d62f89
MF
819sim_open (SIM_OPEN_KIND kind,
820 host_callback *cb,
821 struct bfd *abfd,
822 char **argv)
c906108c 823{
27b97b40 824 int i;
49d62f89
MF
825 SIM_DESC sd = sim_state_alloc (kind, cb);
826 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
d68d7e6b 827
49d62f89
MF
828 /* The cpu data is kept in a separately allocated chunk of memory. */
829 if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
830 {
831 free_state (sd);
832 return 0;
833 }
d68d7e6b 834
49d62f89
MF
835 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
836 {
837 free_state (sd);
838 return 0;
839 }
dfcd3bfb 840
49d62f89
MF
841 /* getopt will print the error message so we just have to exit if this fails.
842 FIXME: Hmmm... in the case of gdb we need getopt to call
843 print_filtered. */
844 if (sim_parse_args (sd, argv) != SIM_RC_OK)
c906108c 845 {
49d62f89
MF
846 free_state (sd);
847 return 0;
848 }
dfcd3bfb 849
49d62f89
MF
850 /* Check for/establish the a reference program image. */
851 if (sim_analyze_program (sd,
852 (STATE_PROG_ARGV (sd) != NULL
853 ? *STATE_PROG_ARGV (sd)
854 : NULL), abfd) != SIM_RC_OK)
855 {
856 free_state (sd);
857 return 0;
858 }
dfcd3bfb 859
49d62f89
MF
860 /* Configure/verify the target byte order and other runtime
861 configuration options. */
862 if (sim_config (sd) != SIM_RC_OK)
863 {
864 sim_module_uninstall (sd);
865 return 0;
866 }
dfcd3bfb 867
49d62f89
MF
868 if (sim_post_argv_init (sd) != SIM_RC_OK)
869 {
870 /* Uninstall the modules to avoid memory leaks,
871 file descriptor leaks, etc. */
872 sim_module_uninstall (sd);
873 return 0;
874 }
dfcd3bfb 875
27b97b40
MF
876 /* CPU specific initialization. */
877 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
878 {
879 SIM_CPU *cpu = STATE_CPU (sd, i);
880
881 CPU_PC_FETCH (cpu) = arm_pc_get;
882 CPU_PC_STORE (cpu) = arm_pc_set;
883 }
884
49d62f89 885 sim_callback = cb;
dfcd3bfb 886
49d62f89 887 sim_target_parse_arg_array (argv);
dfcd3bfb 888
49d62f89
MF
889 if (argv[1] != NULL)
890 {
891 int i;
892
893 /* Scan for memory-size switches. */
894 for (i = 0; (argv[i] != NULL) && (argv[i][0] != 0); i++)
895 if (argv[i][0] == '-' && argv[i][1] == 'm')
058f270d
AC
896 {
897 if (argv[i][2] != '\0')
49d62f89 898 mem_size = atoi (&argv[i][2]);
058f270d
AC
899 else if (argv[i + 1] != NULL)
900 {
49d62f89 901 mem_size = atoi (argv[i + 1]);
058f270d
AC
902 i++;
903 }
904 else
905 {
906 sim_callback->printf_filtered (sim_callback,
907 "Missing argument to -m option\n");
908 return NULL;
909 }
058f270d 910 }
c906108c
SS
911 }
912
49d62f89 913 return sd;
c906108c
SS
914}
915
c906108c 916void
d68d7e6b
NC
917sim_stop_reason (SIM_DESC sd ATTRIBUTE_UNUSED,
918 enum sim_stop *reason,
919 int *sigrc)
c906108c 920{
7a292a7a
SS
921 if (stop_simulator)
922 {
923 *reason = sim_stopped;
a493e3e2 924 *sigrc = GDB_SIGNAL_INT;
7a292a7a
SS
925 }
926 else if (state->EndCondition == 0)
c906108c
SS
927 {
928 *reason = sim_exited;
929 *sigrc = state->Reg[0] & 255;
930 }
931 else
932 {
933 *reason = sim_stopped;
934 if (state->EndCondition == RDIError_BreakpointReached)
a493e3e2 935 *sigrc = GDB_SIGNAL_TRAP;
0f026fd0
NC
936 else if ( state->EndCondition == RDIError_DataAbort
937 || state->EndCondition == RDIError_AddressException)
a493e3e2 938 *sigrc = GDB_SIGNAL_BUS;
c906108c
SS
939 else
940 *sigrc = 0;
941 }
942}