3 #include "sim-options.h"
21 /* For compatibility */
38 enum interrupt_cond_type
45 struct interrupt_generator
47 enum interrupt_type type
;
48 enum interrupt_cond_type cond_type
;
53 struct interrupt_generator
*next
;
56 char *interrupt_names
[] = {
69 struct interrupt_generator
*intgen_list
;
71 /* True if a non-maskable (such as NMI or reset) interrupt generator
74 static int have_nm_generator
;
84 /* These default values correspond to expected usage for the chip. */
90 static struct hash_entry
*lookup_hash
PARAMS ((SIM_DESC sd
, uint32 ins
));
91 static long hash
PARAMS ((long));
93 static void do_format_1_2
PARAMS ((uint32
));
94 static void do_format_3
PARAMS ((uint32
));
95 static void do_format_4
PARAMS ((uint32
));
96 static void do_format_5
PARAMS ((uint32
));
97 static void do_format_6
PARAMS ((uint32
));
98 static void do_format_7
PARAMS ((uint32
));
99 static void do_format_8
PARAMS ((uint32
));
100 static void do_format_9_10
PARAMS ((uint32
));
107 struct hash_entry
*next
;
108 unsigned long opcode
;
113 struct hash_entry hash_table
[MAX_HASH
+1];
120 if ( (insn
& 0x0600) == 0
121 || (insn
& 0x0700) == 0x0200
122 || (insn
& 0x0700) == 0x0600
123 || (insn
& 0x0780) == 0x0700)
124 return (insn
& 0x07e0) >> 5;
126 if ((insn
& 0x0700) == 0x0300
127 || (insn
& 0x0700) == 0x0400
128 || (insn
& 0x0700) == 0x0500)
129 return (insn
& 0x0780) >> 7;
131 if ((insn
& 0x07c0) == 0x0780)
132 return (insn
& 0x07c0) >> 6;
134 return (insn
& 0x07e0) >> 5;
137 static struct hash_entry
*
138 lookup_hash (sd
, ins
)
142 struct hash_entry
*h
;
144 h
= &hash_table
[hash(ins
)];
146 while ((ins
& h
->mask
) != h
->opcode
)
150 sim_io_error (sd
, "ERROR looking up hash for 0x%lx, PC=0x%lx",
151 (long) ins
, (long) PC
);
159 sim_open (kind
, cb
, abfd
, argv
)
166 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
168 struct hash_entry
*h
;
170 /* for compatibility */
173 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
176 /* Allocate core managed memory */
177 /* "Mirror" the ROM addresses below 1MB. */
178 asprintf (&buf
, "memory region 0,0x100000,0x%lx", V850_ROM_SIZE
);
179 sim_do_command (sd
, buf
);
181 /* Chunk of ram adjacent to rom */
182 asprintf (&buf
, "memory region 0x100000,0x%lx", V850_LOW_END
- 0x100000);
183 sim_do_command (sd
, buf
);
185 /* peripheral I/O region - mirror 1K across 4k (0x1000) */
186 sim_do_command (sd
, "memory region 0xfff000,0x1000,1024");
187 /* similarly if in the internal RAM region */
188 sim_do_command (sd
, "memory region 0xffe000,0x1000,1024");
190 /* getopt will print the error message so we just have to exit if this fails.
191 FIXME: Hmmm... in the case of gdb we need getopt to call
193 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
195 /* Uninstall the modules to avoid memory leaks,
196 file descriptor leaks, etc. */
197 sim_module_uninstall (sd
);
201 /* check for/establish the a reference program image */
202 if (sim_analyze_program (sd
,
203 (STATE_PROG_ARGV (sd
) != NULL
204 ? *STATE_PROG_ARGV (sd
)
208 sim_module_uninstall (sd
);
212 /* establish any remaining configuration options */
213 if (sim_config (sd
) != SIM_RC_OK
)
215 sim_module_uninstall (sd
);
219 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
221 /* Uninstall the modules to avoid memory leaks,
222 file descriptor leaks, etc. */
223 sim_module_uninstall (sd
);
227 /* put all the opcodes in the hash table */
228 for (s
= Simops
; s
->func
; s
++)
230 h
= &hash_table
[hash(s
->opcode
)];
232 /* go to the last entry in the chain */
238 h
->next
= (struct hash_entry
*) calloc(1,sizeof(struct hash_entry
));
243 h
->opcode
= s
->opcode
;
251 sim_close (sd
, quitting
)
255 sim_module_uninstall (sd
);
258 static void do_interrupt
PARAMS ((SIM_DESC sd
, enum interrupt_type
));
268 sim_resume (sd
, step
, siggnal
)
272 SIM_ELAPSED_TIME start_time
;
275 struct interrupt_generator
*intgen
;
278 State
.exception
= SIGTRAP
;
283 start_time
= sim_elapsed_time_get ();
287 struct hash_entry
* h
;
288 /* Fetch the current instruction. */
292 h
= lookup_hash (sd
, inst
);
294 OP
[1] = (inst
>> 11) & 0x1f;
295 OP
[2] = (inst
>> 16) & 0xffff;
298 /* fprintf (stderr, "PC = %x, SP = %x\n", PC, SP ); */
302 fprintf (stderr
, "NOP encountered!\n");
306 PC
+= h
->ops
->func ();
310 sim_io_eprintf (sd
, "simulator loop at %lx\n", (long) PC
);
314 /* Check for and handle pending interrupts. */
315 if (intgen_list
&& (have_nm_generator
|| !(PSW
& PSW_ID
)))
318 for (intgen
= intgen_list
; intgen
!= NULL
; intgen
= intgen
->next
)
320 if (intgen
->cond_type
== int_cond_pc
321 && oldpc
== intgen
->address
326 else if (intgen
->cond_type
== int_cond_time
329 SIM_ELAPSED_TIME delta
;
330 delta
= sim_elapsed_time_since (start_time
);
331 if (delta
> intgen
->time
)
339 do_interrupt (sd
, intgen
->type
);
341 else if (State
.pending_nmi
)
343 State
.pending_nmi
= 0;
344 do_interrupt (sd
, int_nmi
);
347 while (!State
.exception
);
351 do_interrupt (sd
, inttype
)
353 enum interrupt_type inttype
;
355 /* Disable further interrupts. */
357 /* Indicate that we're doing interrupt not exception processing. */
359 if (inttype
== int_reset
)
364 /* (Might be useful to init other regs with random values.) */
366 else if (inttype
== int_nmi
)
370 /* We're already working on an NMI, so this one must wait
371 around until the previous one is done. The processor
372 ignores subsequent NMIs, so we don't need to count them. */
373 State
.pending_nmi
= 1;
379 /* Set the FECC part of the ECR. */
390 /* Clear the EICC part of the ECR, will set below. */
419 /* Should never be possible. */
433 sim_resume (sd
, 0, 0);
438 sim_info (sd
, verbose
)
442 sim_io_printf (sd
, "sim_info\n");
446 sim_create_inferior (sd
, prog_bfd
, argv
, env
)
448 struct _bfd
*prog_bfd
;
452 memset (&State
, 0, sizeof (State
));
453 if (prog_bfd
!= NULL
)
454 PC
= bfd_get_start_address (prog_bfd
);
458 /* All the code for exiting, signals, etc needs to be revamped.
460 This is enough to get c-torture limping though. */
463 sim_stop_reason (sd
, reason
, sigrc
)
465 enum sim_stop
*reason
;
468 if (State
.exception
== SIG_V850_EXIT
)
470 *reason
= sim_exited
;
471 *sigrc
= State
.regs
[7];
475 *reason
= sim_stopped
;
476 *sigrc
= State
.exception
;
481 sim_fetch_register (sd
, rn
, memory
)
484 unsigned char *memory
;
486 *(unsigned32
*)memory
= H2T_4 (State
.regs
[rn
]);
490 sim_store_register (sd
, rn
, memory
)
493 unsigned char *memory
;
495 State
.regs
[rn
] = T2H_4 (*(unsigned32
*)memory
);
499 sim_parse_number (str
, rest
)
502 if (str
[0] == '0' && str
[1] == 'x')
503 return strtoul (str
, rest
, 16);
504 else if (str
[0] == '0')
505 return strtoul (str
, rest
, 16);
507 return strtoul (str
, rest
, 10);
510 int current_intgen_number
= 1;
513 sim_set_interrupt (sd
, spec
)
519 struct interrupt_generator
*intgen
, *tmpgen
;
520 extern char **buildargv ();
522 argv
= buildargv (spec
);
524 if (*argv
&& ! strcmp (*argv
, "add"))
526 /* Create a new interrupt generator object. */
527 intgen
= (struct interrupt_generator
*)
528 malloc (sizeof(struct interrupt_generator
));
529 intgen
->type
= int_none
;
530 intgen
->cond_type
= int_cond_none
;
535 /* Match on interrupt type name. */
536 for (i
= 0; i
< num_int_types
; ++i
)
538 if (*argv
&& ! strcmp (*argv
, interrupt_names
[i
]))
544 if (intgen
->type
== int_none
)
546 sim_io_printf (sd
, "Interrupt type unknown; known types are\n");
547 for (i
= 0; i
< num_int_types
; ++i
)
549 sim_io_printf (sd
, " %s", interrupt_names
[i
]);
551 sim_io_printf (sd
, "\n");
558 if (*argv
&& ! strcmp (*argv
, "pc"))
560 intgen
->cond_type
= int_cond_pc
;
562 intgen
->address
= sim_parse_number (*argv
, NULL
);
564 else if (*argv
&& ! strcmp (*argv
, "time"))
566 intgen
->cond_type
= int_cond_time
;
568 intgen
->time
= sim_parse_number (*argv
, NULL
);
572 sim_io_printf (sd
, "Condition type must be `pc' or `time'.\n");
576 /* We now have a valid interrupt generator. Number it and add
577 to the list of generators. */
578 intgen
->number
= current_intgen_number
++;
580 intgen
->next
= intgen_list
;
581 intgen_list
= intgen
;
582 sim_io_printf (sd
, "Interrupt generator %d (NMI) at pc=0x%x, time=%ld.\n", intgen_list
->number
, intgen_list
->address
, intgen_list
->time
);
584 else if (*argv
&& !strcmp (*argv
, "remove"))
587 num
= sim_parse_number (*argv
, NULL
);
591 if (intgen_list
->number
== num
)
593 tmpgen
= intgen_list
;
594 intgen_list
= intgen_list
->next
;
598 for (intgen
= intgen_list
; intgen
!= NULL
; intgen
= intgen
->next
)
600 if (intgen
->next
!= NULL
&& intgen
->next
->number
== num
)
602 tmpgen
= intgen
->next
;
603 intgen
->next
= intgen
->next
->next
;
611 sim_io_printf (sd
, "No interrupt generator numbered %d, ignoring.\n", num
);
614 else if (*argv
&& !strcmp (*argv
, "info"))
618 for (intgen
= intgen_list
; intgen
!= NULL
; intgen
= intgen
->next
)
619 sim_io_printf (sd
, "Interrupt generator %d (%s) at pc=0x%lx/time=%ld%s.\n",
621 interrupt_names
[intgen
->type
],
622 (long) intgen
->address
,
624 (intgen
->enabled
? "" : " (disabled)"));
628 sim_io_printf (sd
, "No interrupt generators defined.\n");
634 sim_io_printf (sd
, "Invalid interrupt command, must be one of `add', `remove', or `info'.\n");
636 /* Cache the presence of a non-maskable generator. */
637 have_nm_generator
= 0;
638 for (intgen
= intgen_list
; intgen
!= NULL
; intgen
= intgen
->next
)
640 if (intgen
->type
== int_nmi
|| intgen
->type
== int_reset
)
642 have_nm_generator
= 1;
649 sim_do_command (sd
, cmd
)
653 char *mm_cmd
= "memory-map";
654 char *int_cmd
= "interrupt";
656 if (strncmp (cmd
, mm_cmd
, strlen (mm_cmd
) == 0))
657 sim_io_eprintf (sd
, "`memory-map' command replaced by `sim memory'\n");
659 else if (! strncmp (cmd
, int_cmd
, strlen (int_cmd
))
660 && strchr (" ", cmd
[strlen(int_cmd
)]))
661 sim_set_interrupt (sd
, cmd
+ strlen(int_cmd
) + 1);
663 else if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
664 sim_io_eprintf (sd
, "Unknown command `%s'\n", cmd
);