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