]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/arm/wrapper.c
* osabi.h (gdb_osabi): Add GDB_OSABI_GO32 and GDB_OSABI_NETWARE.
[thirdparty/binutils-gdb.git] / sim / arm / wrapper.c
CommitLineData
c906108c 1/* run front end support for arm
86c735a5
NC
2 Copyright (C) 1995, 1996, 1997, 2000, 2001, 2002
3 Free Software Foundation, Inc.
c906108c 4
86c735a5 5 This file is part of ARM SIM.
c906108c 6
86c735a5
NC
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 2, or (at your
10 option) any later version.
c906108c 11
86c735a5
NC
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 the GNU General Public License for more details.
c906108c 16
86c735a5
NC
17 You should have received a copy of the GNU General Public
18 License along with this program; if not, write to the Free
19 Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
c906108c 21
86c735a5
NC
22/* This file provides the interface between the simulator and
23 run.c and gdb (when the simulator is linked with gdb).
c906108c
SS
24 All simulator interaction should go through this file. */
25
26#include <stdio.h>
27#include <stdarg.h>
6d358e86 28#include <string.h>
c906108c
SS
29#include <bfd.h>
30#include <signal.h>
31#include "callback.h"
32#include "remote-sim.h"
33#include "armdefs.h"
34#include "armemu.h"
35#include "dbg_rdi.h"
6d358e86 36#include "ansidecl.h"
86c735a5 37#include "sim-utils.h"
de4112fa 38#include "run-sim.h"
c906108c
SS
39
40host_callback *sim_callback;
41
42static struct ARMul_State *state;
43
44/* Who is using the simulator. */
45static SIM_OPEN_KIND sim_kind;
46
47/* argv[0] */
48static char *myname;
49
50/* Memory size in bytes. */
ae60d3dd 51static int mem_size = (1 << 23);
c906108c
SS
52
53/* Non-zero to display start up banner, and maybe other things. */
54static int verbosity;
55
56/* Non-zero to set big endian mode. */
57static int big_endian;
58
7a292a7a
SS
59int stop_simulator;
60
dfcd3bfb 61static void
c906108c
SS
62init ()
63{
64 static int done;
65
66 if (!done)
67 {
dfcd3bfb 68 ARMul_EmulateInit ();
c906108c
SS
69 state = ARMul_NewState ();
70 state->bigendSig = (big_endian ? HIGH : LOW);
dfcd3bfb
JM
71 ARMul_MemoryInit (state, mem_size);
72 ARMul_OSInit (state);
73 ARMul_CoProInit (state);
c906108c
SS
74 state->verbose = verbosity;
75 done = 1;
76 }
77}
78
79/* Set verbosity level of simulator.
80 This is not intended to produce detailed tracing or debugging information.
81 Just summaries. */
82/* FIXME: common/run.c doesn't do this yet. */
83
84void
85sim_set_verbose (v)
86 int v;
87{
88 verbosity = v;
89}
90
91/* Set the memory size to SIZE bytes.
dfcd3bfb 92 Must be called before initializing simulator. */
c906108c
SS
93/* FIXME: Rename to sim_set_mem_size. */
94
dfcd3bfb 95void
c906108c
SS
96sim_size (size)
97 int size;
98{
99 mem_size = size;
100}
101
dfcd3bfb 102void
86c735a5
NC
103ARMul_ConsolePrint VPARAMS ((ARMul_State * state,
104 const char * format,
105 ...))
c906108c
SS
106{
107 va_list ap;
108
109 if (state->verbose)
110 {
111 va_start (ap, format);
112 vprintf (format, ap);
113 va_end (ap);
114 }
115}
116
6d358e86 117ARMword
86c735a5
NC
118ARMul_Debug (state, pc, instr)
119 ARMul_State * state ATTRIBUTE_UNUSED;
120 ARMword pc ATTRIBUTE_UNUSED;
121 ARMword instr ATTRIBUTE_UNUSED;
c906108c 122{
6d358e86 123 return 0;
c906108c
SS
124}
125
126int
127sim_write (sd, addr, buffer, size)
6d358e86 128 SIM_DESC sd ATTRIBUTE_UNUSED;
c906108c 129 SIM_ADDR addr;
86c735a5 130 unsigned char * buffer;
c906108c
SS
131 int size;
132{
133 int i;
3943c96b 134
c906108c 135 init ();
3943c96b 136
c906108c 137 for (i = 0; i < size; i++)
917bca4f 138 ARMul_SafeWriteByte (state, addr + i, buffer[i]);
3943c96b 139
c906108c
SS
140 return size;
141}
142
143int
144sim_read (sd, addr, buffer, size)
6d358e86 145 SIM_DESC sd ATTRIBUTE_UNUSED;
c906108c 146 SIM_ADDR addr;
86c735a5 147 unsigned char * buffer;
c906108c
SS
148 int size;
149{
150 int i;
917bca4f 151
c906108c 152 init ();
86c735a5 153
c906108c 154 for (i = 0; i < size; i++)
917bca4f
NC
155 buffer[i] = ARMul_SafeReadByte (state, addr + i);
156
c906108c
SS
157 return size;
158}
159
160int
161sim_trace (sd)
6d358e86 162 SIM_DESC sd ATTRIBUTE_UNUSED;
dfcd3bfb 163{
86c735a5
NC
164 (*sim_callback->printf_filtered)
165 (sim_callback,
166 "This simulator does not support tracing\n");
c906108c
SS
167 return 1;
168}
169
170int
171sim_stop (sd)
6d358e86 172 SIM_DESC sd ATTRIBUTE_UNUSED;
c906108c 173{
7a292a7a
SS
174 state->Emulate = STOP;
175 stop_simulator = 1;
176 return 1;
c906108c
SS
177}
178
179void
180sim_resume (sd, step, siggnal)
6d358e86
NC
181 SIM_DESC sd ATTRIBUTE_UNUSED;
182 int step;
183 int siggnal ATTRIBUTE_UNUSED;
c906108c
SS
184{
185 state->EndCondition = 0;
7a292a7a 186 stop_simulator = 0;
c906108c
SS
187
188 if (step)
189 {
190 state->Reg[15] = ARMul_DoInstr (state);
191 if (state->EndCondition == 0)
192 state->EndCondition = RDIError_BreakpointReached;
193 }
194 else
195 {
dfcd3bfb 196 state->NextInstr = RESUME; /* treat as PC change */
c906108c
SS
197 state->Reg[15] = ARMul_DoProg (state);
198 }
199
200 FLUSHPIPE;
201}
202
203SIM_RC
204sim_create_inferior (sd, abfd, argv, env)
6d358e86 205 SIM_DESC sd ATTRIBUTE_UNUSED;
86c735a5
NC
206 struct _bfd * abfd;
207 char ** argv;
208 char ** env;
c906108c 209{
dfcd3bfb 210 int argvlen = 0;
1e6b544a 211 int mach;
c906108c
SS
212 char **arg;
213
214 if (abfd != NULL)
215 ARMul_SetPC (state, bfd_get_start_address (abfd));
216 else
dfcd3bfb 217 ARMul_SetPC (state, 0); /* ??? */
c906108c 218
1e6b544a
AO
219 mach = bfd_get_mach (abfd);
220
3943c96b
NC
221 switch (mach)
222 {
223 default:
86c735a5
NC
224 (*sim_callback->printf_filtered)
225 (sim_callback,
10b57fcb
NC
226 "Unknown machine type '%d'; please update sim_create_inferior.\n",
227 mach);
3943c96b
NC
228 /* fall through */
229
f1129fb8 230 case 0:
3943c96b 231 /* We wouldn't set the machine type with earlier toolchains, so we
f1129fb8
NC
232 explicitly select a processor capable of supporting all ARMs in
233 32bit mode. */
272fcdcd
NC
234 case bfd_mach_arm_XScale:
235 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop);
236 break;
237
f1129fb8 238 case bfd_mach_arm_5:
c17aa318
NC
239 if (bfd_family_coff (abfd))
240 {
241 /* This is a special case in order to support COFF based ARM toolchains.
242 The COFF header does not have enough room to store all the different
243 kinds of ARM cpu, so the XScale, v5T and v5TE architectures all default
244 to v5. (See coff_set_flags() in bdf/coffcode.h). So if we see a v5
245 machine type here, we assume it could be any of the above architectures
246 and so select the most feature-full. */
247 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop);
248 break;
249 }
250 /* Otherwise drop through. */
25180f8a 251
f1129fb8
NC
252 case bfd_mach_arm_5T:
253 ARMul_SelectProcessor (state, ARM_v5_Prop);
254 break;
3943c96b 255
f1129fb8
NC
256 case bfd_mach_arm_5TE:
257 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop);
258 break;
259
f1129fb8
NC
260 case bfd_mach_arm_4:
261 case bfd_mach_arm_4T:
262 ARMul_SelectProcessor (state, ARM_v4_Prop);
263 break;
264
265 case bfd_mach_arm_3:
266 case bfd_mach_arm_3M:
3943c96b
NC
267 ARMul_SelectProcessor (state, ARM_Lock_Prop);
268 break;
269
f1129fb8
NC
270 case bfd_mach_arm_2:
271 case bfd_mach_arm_2a:
3943c96b
NC
272 ARMul_SelectProcessor (state, ARM_Fix26_Prop);
273 break;
274 }
275
5f7d0a33
NC
276 if ( mach != bfd_mach_arm_3
277 && mach != bfd_mach_arm_3M
278 && mach != bfd_mach_arm_2
279 && mach != bfd_mach_arm_2a)
f1129fb8
NC
280 {
281 /* Reset mode to ARM. A gdb user may rerun a program that had entered
282 THUMB mode from the start and cause the ARM-mode startup code to be
5f7d0a33
NC
283 executed in THUMB mode. */
284 ARMul_SetCPSR (state, SVC32MODE);
f1129fb8
NC
285 }
286
c906108c
SS
287 if (argv != NULL)
288 {
5f7d0a33
NC
289 /* Set up the command line by laboriously stringing together
290 the environment carefully picked apart by our caller. */
291
292 /* Free any old stuff. */
c906108c
SS
293 if (state->CommandLine != NULL)
294 {
dfcd3bfb 295 free (state->CommandLine);
c906108c
SS
296 state->CommandLine = NULL;
297 }
dfcd3bfb 298
5f7d0a33 299 /* See how much we need. */
c906108c 300 for (arg = argv; *arg != NULL; arg++)
dfcd3bfb
JM
301 argvlen += strlen (*arg) + 1;
302
5f7d0a33 303 /* Allocate it. */
dfcd3bfb 304 state->CommandLine = malloc (argvlen + 1);
c906108c
SS
305 if (state->CommandLine != NULL)
306 {
307 arg = argv;
dfcd3bfb 308 state->CommandLine[0] = '\0';
5f7d0a33 309
c906108c
SS
310 for (arg = argv; *arg != NULL; arg++)
311 {
dfcd3bfb
JM
312 strcat (state->CommandLine, *arg);
313 strcat (state->CommandLine, " ");
c906108c
SS
314 }
315 }
316 }
317
318 if (env != NULL)
319 {
5f7d0a33 320 /* Now see if there's a MEMSIZE spec in the environment. */
c906108c
SS
321 while (*env)
322 {
dfcd3bfb 323 if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
c906108c 324 {
c906108c 325 char *end_of_num;
dfcd3bfb 326
5f7d0a33 327 /* Set up memory limit. */
dfcd3bfb
JM
328 state->MemSize =
329 strtoul (*env + sizeof ("MEMSIZE=") - 1, &end_of_num, 0);
c906108c
SS
330 }
331 env++;
332 }
333 }
334
335 return SIM_RC_OK;
336}
337
338void
339sim_info (sd, verbose)
6d358e86
NC
340 SIM_DESC sd ATTRIBUTE_UNUSED;
341 int verbose ATTRIBUTE_UNUSED;
c906108c
SS
342{
343}
344
dfcd3bfb 345static int
c906108c
SS
346frommem (state, memory)
347 struct ARMul_State *state;
348 unsigned char *memory;
349{
350 if (state->bigendSig == HIGH)
86c735a5
NC
351 return (memory[0] << 24) | (memory[1] << 16)
352 | (memory[2] << 8) | (memory[3] << 0);
c906108c 353 else
86c735a5
NC
354 return (memory[3] << 24) | (memory[2] << 16)
355 | (memory[1] << 8) | (memory[0] << 0);
c906108c
SS
356}
357
c906108c 358static void
dfcd3bfb 359tomem (state, memory, val)
c906108c
SS
360 struct ARMul_State *state;
361 unsigned char *memory;
362 int val;
363{
364 if (state->bigendSig == HIGH)
365 {
366 memory[0] = val >> 24;
367 memory[1] = val >> 16;
368 memory[2] = val >> 8;
369 memory[3] = val >> 0;
370 }
371 else
372 {
373 memory[3] = val >> 24;
374 memory[2] = val >> 16;
375 memory[1] = val >> 8;
376 memory[0] = val >> 0;
377 }
378}
379
380int
381sim_store_register (sd, rn, memory, length)
6d358e86 382 SIM_DESC sd ATTRIBUTE_UNUSED;
c906108c
SS
383 int rn;
384 unsigned char *memory;
6d358e86 385 int length ATTRIBUTE_UNUSED;
c906108c
SS
386{
387 init ();
f1129fb8 388
3463c3fb
NC
389 if (rn == 25)
390 {
391 state->Cpsr = frommem (state, memory);
10b57fcb 392 ARMul_CPSRAltered (state);
3463c3fb
NC
393 }
394 else
395 ARMul_SetReg (state, state->Mode, rn, frommem (state, memory));
c906108c
SS
396 return -1;
397}
398
399int
400sim_fetch_register (sd, rn, memory, length)
6d358e86 401 SIM_DESC sd ATTRIBUTE_UNUSED;
c906108c
SS
402 int rn;
403 unsigned char *memory;
6d358e86 404 int length ATTRIBUTE_UNUSED;
c906108c
SS
405{
406 ARMword regval;
407
408 init ();
f1129fb8 409
c906108c 410 if (rn < 16)
dfcd3bfb 411 regval = ARMul_GetReg (state, state->Mode, rn);
86c735a5
NC
412 else if (rn == 25)
413 /* FIXME: use PS_REGNUM from gdb/config/arm/tm-arm.h. */
dfcd3bfb 414 regval = ARMul_GetCPSR (state);
c906108c 415 else
86c735a5
NC
416 /* FIXME: should report an error. */
417 regval = 0;
272fcdcd
NC
418
419 while (length)
420 {
421 tomem (state, memory, regval);
422
423 length -= 4;
424 memory += 4;
425 regval = 0;
426 }
427
c906108c
SS
428 return -1;
429}
430
de4112fa
NC
431#ifdef SIM_TARGET_SWITCHES
432
433static void sim_target_parse_arg_array PARAMS ((char **));
434
435typedef struct
436{
437 char * swi_option;
438 unsigned int swi_mask;
439} swi_options;
440
441#define SWI_SWITCH "--swi-support"
442
443static swi_options options[] =
444 {
445 { "none", 0 },
446 { "demon", SWI_MASK_DEMON },
447 { "angel", SWI_MASK_ANGEL },
448 { "redboot", SWI_MASK_REDBOOT },
449 { "all", -1 },
450 { "NONE", 0 },
451 { "DEMON", SWI_MASK_DEMON },
452 { "ANGEL", SWI_MASK_ANGEL },
453 { "REDBOOT", SWI_MASK_REDBOOT },
454 { "ALL", -1 }
455 };
456
457
458int
459sim_target_parse_command_line (argc, argv)
460 int argc;
461 char ** argv;
462{
463 int i;
464
465 for (i = 1; i < argc; i++)
466 {
467 char * ptr = argv[i];
468 int arg;
469
470 if ((ptr == NULL) || (* ptr != '-'))
471 break;
472
473 if (strncmp (ptr, SWI_SWITCH, sizeof SWI_SWITCH - 1) != 0)
474 continue;
475
476 if (ptr[sizeof SWI_SWITCH - 1] == 0)
477 {
478 /* Remove this option from the argv array. */
479 for (arg = i; arg < argc; arg ++)
480 argv[arg] = argv[arg + 1];
481 argc --;
482
483 ptr = argv[i];
484 }
485 else
486 ptr += sizeof SWI_SWITCH;
487
488 swi_mask = 0;
489
490 while (* ptr)
491 {
492 int i;
493
494 for (i = sizeof options / sizeof options[0]; i--;)
495 if (strncmp (ptr, options[i].swi_option,
496 strlen (options[i].swi_option)) == 0)
497 {
498 swi_mask |= options[i].swi_mask;
499 ptr += strlen (options[i].swi_option);
500
501 if (* ptr == ',')
502 ++ ptr;
503
504 break;
505 }
506
507 if (i < 0)
508 break;
509 }
510
511 if (* ptr != 0)
512 fprintf (stderr, "Ignoring swi options: %s\n", ptr);
513
514 /* Remove this option from the argv array. */
515 for (arg = i; arg < argc; arg ++)
516 argv[arg] = argv[arg + 1];
517 argc --;
518 i --;
519 }
520 return argc;
521}
522
523static void
524sim_target_parse_arg_array (argv)
525 char ** argv;
526{
527 int i;
528
529 for (i = 0; argv[i]; i++)
530 ;
531
532 return (void) sim_target_parse_command_line (i, argv);
533}
534
535void
536sim_target_display_usage ()
537{
538 fprintf (stderr, "%s=<list> Comma seperated list of SWI protocols to supoport.\n\
539 This list can contain: NONE, DEMON, ANGEL, REDBOOT and/or ALL.\n",
540 SWI_SWITCH);
541}
542#endif
543
c906108c
SS
544SIM_DESC
545sim_open (kind, ptr, abfd, argv)
546 SIM_OPEN_KIND kind;
547 host_callback *ptr;
548 struct _bfd *abfd;
549 char **argv;
550{
551 sim_kind = kind;
6c9e0292 552 if (myname) free (myname);
c1a72ffd 553 myname = (char *) xstrdup (argv[0]);
c906108c 554 sim_callback = ptr;
dfcd3bfb 555
de4112fa
NC
556#ifdef SIM_TARGET_SWITCHES
557 sim_target_parse_arg_array (argv);
558#endif
559
c906108c
SS
560 /* Decide upon the endian-ness of the processor.
561 If we can, get the information from the bfd itself.
562 Otherwise look to see if we have been given a command
563 line switch that tells us. Otherwise default to little endian. */
564 if (abfd != NULL)
565 big_endian = bfd_big_endian (abfd);
566 else if (argv[1] != NULL)
567 {
568 int i;
dfcd3bfb 569
c906108c
SS
570 /* Scan for endian-ness switch. */
571 for (i = 0; (argv[i] != NULL) && (argv[i][0] != 0); i++)
dfcd3bfb
JM
572 if (argv[i][0] == '-' && argv[i][1] == 'E')
573 {
574 char c;
575
576 if ((c = argv[i][2]) == 0)
577 {
578 ++i;
579 c = argv[i][0];
580 }
581
582 switch (c)
583 {
584 case 0:
585 sim_callback->printf_filtered
586 (sim_callback, "No argument to -E option provided\n");
587 break;
588
589 case 'b':
590 case 'B':
591 big_endian = 1;
592 break;
593
594 case 'l':
595 case 'L':
596 big_endian = 0;
597 break;
598
599 default:
600 sim_callback->printf_filtered
601 (sim_callback, "Unrecognised argument to -E option\n");
602 break;
603 }
604 }
c906108c
SS
605 }
606
607 return (SIM_DESC) 1;
608}
609
610void
611sim_close (sd, quitting)
6d358e86
NC
612 SIM_DESC sd ATTRIBUTE_UNUSED;
613 int quitting ATTRIBUTE_UNUSED;
c906108c 614{
86c735a5
NC
615 if (myname)
616 free (myname);
6c9e0292 617 myname = NULL;
c906108c
SS
618}
619
620SIM_RC
621sim_load (sd, prog, abfd, from_tty)
622 SIM_DESC sd;
623 char *prog;
624 bfd *abfd;
6d358e86 625 int from_tty ATTRIBUTE_UNUSED;
c906108c 626{
c906108c
SS
627 bfd *prog_bfd;
628
629 prog_bfd = sim_load_file (sd, myname, sim_callback, prog, abfd,
dfcd3bfb 630 sim_kind == SIM_OPEN_DEBUG, 0, sim_write);
c906108c
SS
631 if (prog_bfd == NULL)
632 return SIM_RC_FAIL;
633 ARMul_SetPC (state, bfd_get_start_address (prog_bfd));
634 if (abfd == NULL)
635 bfd_close (prog_bfd);
636 return SIM_RC_OK;
637}
638
639void
640sim_stop_reason (sd, reason, sigrc)
6d358e86 641 SIM_DESC sd ATTRIBUTE_UNUSED;
c906108c
SS
642 enum sim_stop *reason;
643 int *sigrc;
644{
7a292a7a
SS
645 if (stop_simulator)
646 {
647 *reason = sim_stopped;
648 *sigrc = SIGINT;
649 }
650 else if (state->EndCondition == 0)
c906108c
SS
651 {
652 *reason = sim_exited;
653 *sigrc = state->Reg[0] & 255;
654 }
655 else
656 {
657 *reason = sim_stopped;
658 if (state->EndCondition == RDIError_BreakpointReached)
659 *sigrc = SIGTRAP;
660 else
661 *sigrc = 0;
662 }
663}
664
665void
666sim_do_command (sd, cmd)
6d358e86
NC
667 SIM_DESC sd ATTRIBUTE_UNUSED;
668 char *cmd ATTRIBUTE_UNUSED;
dfcd3bfb 669{
86c735a5
NC
670 (*sim_callback->printf_filtered)
671 (sim_callback,
672 "This simulator does not accept any commands.\n");
c906108c
SS
673}
674
c906108c
SS
675void
676sim_set_callbacks (ptr)
677 host_callback *ptr;
678{
679 sim_callback = ptr;
680}