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
;
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
);
158 /* FIXME These would more efficient to use than load_mem/store_mem,
159 but need to be changed to use the memory map. */
173 return (a
[1] << 8) + (a
[0]);
181 return (a
[3]<<24) + (a
[2]<<16) + (a
[1]<<8) + (a
[0]);
185 put_byte (addr
, data
)
194 put_half (addr
, data
)
200 a
[1] = (data
>> 8) & 0xff;
204 put_word (addr
, data
)
210 a
[1] = (data
>> 8) & 0xff;
211 a
[2] = (data
>> 16) & 0xff;
212 a
[3] = (data
>> 24) & 0xff;
219 /* Mask down to 24 bits. */
224 /* "Mirror" the addresses below 1MB. */
225 addr
= addr
& (simulator
->rom_size
- 1);
226 return (uint8
*) (addr
+ STATE_MEMORY (simulator
));
228 else if (addr
< simulator
->low_end
)
230 /* chunk is just after the rom */
231 addr
= addr
- 0x100000 + simulator
->rom_size
;
232 return (uint8
*) (addr
+ STATE_MEMORY (simulator
));
234 else if (addr
>= simulator
->high_start
)
236 /* If in the peripheral I/O region, mirror 1K region across 4K,
237 and similarly if in the internal RAM region. */
238 if (addr
>= 0xfff000)
240 else if (addr
>= 0xffe000)
242 addr
= addr
- simulator
->high_start
+ simulator
->high_base
;
243 return (uint8
*) (STATE_MEMORY (simulator
));
247 sim_io_eprintf (simulator
, "segmentation fault: access address: %lx not below %lx or above %lx [ep = %lx]\n",
249 (long) simulator
->low_end
,
250 (long) simulator
->high_start
,
253 /* Signal a memory error. */
254 State
.exception
= SIGSEGV
;
255 /* Point to a location not in main memory - renders invalid
256 addresses harmless until we get back to main insn loop. */
257 return (uint8
*) &(State
.dummy_mem
);
266 uint8
*p
= map (addr
);
273 return p
[1] << 8 | p
[0];
275 return p
[3] << 24 | p
[2] << 16 | p
[1] << 8 | p
[0];
282 store_mem (addr
, len
, data
)
287 uint8
*p
= map (addr
);
310 sim_memory_init (SIM_DESC sd
)
314 if (STATE_MEMORY (sd
))
315 zfree (STATE_MEMORY (sd
));
317 totsize
= (simulator
->rom_size
318 + (sd
->low_end
- 0x100000)
319 + (0x1000000 - sd
->high_start
));
321 sd
->high_base
= sd
->rom_size
+ (sd
->low_end
- 0x100000);
323 STATE_MEMORY (sd
) = zalloc (totsize
);
324 if (!STATE_MEMORY (sd
))
326 sim_io_error (sd
, "Allocation of main memory failed.");
331 sim_parse_number (str
, rest
)
334 if (str
[0] == '0' && str
[1] == 'x')
335 return strtoul (str
, rest
, 16);
336 else if (str
[0] == '0')
337 return strtoul (str
, rest
, 16);
339 return strtoul (str
, rest
, 10);
343 sim_set_memory_map (sd
, spec
)
347 char *reststr
, *nreststr
;
348 SIM_ADDR new_low_end
, new_high_start
;
350 new_low_end
= sd
->low_end
;
351 new_high_start
= sd
->high_start
;
352 if (! strncmp (spec
, "hole=", 5))
354 new_low_end
= sim_parse_number (spec
+ 5, &reststr
);
355 if (new_low_end
< 0x100000)
357 sim_io_printf (sd
, "Low end must be at least 0x100000\n");
363 new_high_start
= sim_parse_number (reststr
, &nreststr
);
364 /* FIXME Check high_start also */
366 sim_io_printf (sd
, "Hole goes from 0x%x to 0x%x\n",
367 new_low_end
, new_high_start
);
371 sim_io_printf (sd
, "Invalid specification for memory map, must be `hole=<m>[,<n>]'\n");
374 if (new_low_end
!= sd
->low_end
|| new_high_start
!= sd
->high_start
)
376 sd
->low_end
= new_low_end
;
377 sd
->high_start
= new_high_start
;
378 sim_io_printf (sd
, "Reconfiguring memory (old contents will be lost)\n");
379 sim_memory_init (sd
);
383 /* Parse a number in hex, octal, or decimal form. */
386 sim_write (sd
, addr
, buffer
, size
)
389 unsigned char *buffer
;
394 for (i
= 0; i
< size
; i
++)
395 store_mem (addr
+ i
, 1, buffer
[i
]);
402 sim_open (kind
, cb
, abfd
, argv
)
408 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
410 struct hash_entry
*h
;
412 /* for compatibility */
415 sd
->rom_size
= V850_ROM_SIZE
;
416 sd
->low_end
= V850_LOW_END
;
417 sd
->high_start
= V850_HIGH_START
;
419 /* Allocate memory */
420 sim_memory_init (sd
);
422 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
425 /* getopt will print the error message so we just have to exit if this fails.
426 FIXME: Hmmm... in the case of gdb we need getopt to call
428 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
430 /* Uninstall the modules to avoid memory leaks,
431 file descriptor leaks, etc. */
432 sim_module_uninstall (sd
);
436 /* check for/establish the a reference program image */
437 if (sim_analyze_program (sd
,
438 (STATE_PROG_ARGV (sd
) != NULL
439 ? *STATE_PROG_ARGV (sd
)
443 sim_module_uninstall (sd
);
447 /* establish any remaining configuration options */
448 if (sim_config (sd
) != SIM_RC_OK
)
450 sim_module_uninstall (sd
);
454 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
456 /* Uninstall the modules to avoid memory leaks,
457 file descriptor leaks, etc. */
458 sim_module_uninstall (sd
);
462 /* put all the opcodes in the hash table */
463 for (s
= Simops
; s
->func
; s
++)
465 h
= &hash_table
[hash(s
->opcode
)];
467 /* go to the last entry in the chain */
473 h
->next
= (struct hash_entry
*) calloc(1,sizeof(struct hash_entry
));
478 h
->opcode
= s
->opcode
;
486 sim_close (sd
, quitting
)
490 sim_module_uninstall (sd
);
493 static void do_interrupt
PARAMS ((SIM_DESC sd
, enum interrupt_type
));
503 sim_resume (sd
, step
, siggnal
)
507 SIM_ELAPSED_TIME start_time
;
510 struct interrupt_generator
*intgen
;
513 State
.exception
= SIGTRAP
;
518 start_time
= sim_elapsed_time_get ();
522 struct hash_entry
* h
;
523 /* Fetch the current instruction. */
527 h
= lookup_hash (sd
, inst
);
529 OP
[1] = (inst
>> 11) & 0x1f;
530 OP
[2] = (inst
>> 16) & 0xffff;
533 /* fprintf (stderr, "PC = %x, SP = %x\n", PC, SP ); */
537 fprintf (stderr
, "NOP encountered!\n");
541 PC
+= h
->ops
->func ();
545 sim_io_eprintf (sd
, "simulator loop at %lx\n", (long) PC
);
549 /* Check for and handle pending interrupts. */
550 if (intgen_list
&& (have_nm_generator
|| !(PSW
& PSW_ID
)))
553 for (intgen
= intgen_list
; intgen
!= NULL
; intgen
= intgen
->next
)
555 if (intgen
->cond_type
== int_cond_pc
556 && oldpc
== intgen
->address
561 else if (intgen
->cond_type
== int_cond_time
564 SIM_ELAPSED_TIME delta
;
565 delta
= sim_elapsed_time_since (start_time
);
566 if (delta
> intgen
->time
)
574 do_interrupt (sd
, intgen
->type
);
576 else if (State
.pending_nmi
)
578 State
.pending_nmi
= 0;
579 do_interrupt (sd
, int_nmi
);
582 while (!State
.exception
);
586 do_interrupt (sd
, inttype
)
588 enum interrupt_type inttype
;
590 /* Disable further interrupts. */
592 /* Indicate that we're doing interrupt not exception processing. */
594 if (inttype
== int_reset
)
599 /* (Might be useful to init other regs with random values.) */
601 else if (inttype
== int_nmi
)
605 /* We're already working on an NMI, so this one must wait
606 around until the previous one is done. The processor
607 ignores subsequent NMIs, so we don't need to count them. */
608 State
.pending_nmi
= 1;
614 /* Set the FECC part of the ECR. */
625 /* Clear the EICC part of the ECR, will set below. */
654 /* Should never be possible. */
668 sim_resume (sd
, 0, 0);
673 sim_info (sd
, verbose
)
677 sim_io_printf (sd
, "sim_info\n");
681 sim_create_inferior (sd
, prog_bfd
, argv
, env
)
683 struct _bfd
*prog_bfd
;
687 memset (&State
, 0, sizeof (State
));
688 if (prog_bfd
!= NULL
)
689 PC
= bfd_get_start_address (prog_bfd
);
693 /* All the code for exiting, signals, etc needs to be revamped.
695 This is enough to get c-torture limping though. */
698 sim_stop_reason (sd
, reason
, sigrc
)
700 enum sim_stop
*reason
;
703 if (State
.exception
== SIG_V850_EXIT
)
705 *reason
= sim_exited
;
706 *sigrc
= State
.regs
[7];
710 *reason
= sim_stopped
;
711 *sigrc
= State
.exception
;
716 sim_fetch_register (sd
, rn
, memory
)
719 unsigned char *memory
;
721 put_word (memory
, State
.regs
[rn
]);
725 sim_store_register (sd
, rn
, memory
)
728 unsigned char *memory
;
730 State
.regs
[rn
] = get_word (memory
);
734 sim_read (sd
, addr
, buffer
, size
)
737 unsigned char *buffer
;
741 for (i
= 0; i
< size
; i
++)
742 buffer
[i
] = load_mem (addr
+ i
, 1);
747 int current_intgen_number
= 1;
750 sim_set_interrupt (sd
, spec
)
756 struct interrupt_generator
*intgen
, *tmpgen
;
757 extern char **buildargv ();
759 argv
= buildargv (spec
);
761 if (*argv
&& ! strcmp (*argv
, "add"))
763 /* Create a new interrupt generator object. */
764 intgen
= (struct interrupt_generator
*)
765 malloc (sizeof(struct interrupt_generator
));
766 intgen
->type
= int_none
;
767 intgen
->cond_type
= int_cond_none
;
772 /* Match on interrupt type name. */
773 for (i
= 0; i
< num_int_types
; ++i
)
775 if (*argv
&& ! strcmp (*argv
, interrupt_names
[i
]))
781 if (intgen
->type
== int_none
)
783 sim_io_printf (sd
, "Interrupt type unknown; known types are\n");
784 for (i
= 0; i
< num_int_types
; ++i
)
786 sim_io_printf (sd
, " %s", interrupt_names
[i
]);
788 sim_io_printf (sd
, "\n");
795 if (*argv
&& ! strcmp (*argv
, "pc"))
797 intgen
->cond_type
= int_cond_pc
;
799 intgen
->address
= sim_parse_number (*argv
, NULL
);
801 else if (*argv
&& ! strcmp (*argv
, "time"))
803 intgen
->cond_type
= int_cond_time
;
805 intgen
->time
= sim_parse_number (*argv
, NULL
);
809 sim_io_printf (sd
, "Condition type must be `pc' or `time'.\n");
813 /* We now have a valid interrupt generator. Number it and add
814 to the list of generators. */
815 intgen
->number
= current_intgen_number
++;
817 intgen
->next
= intgen_list
;
818 intgen_list
= intgen
;
819 sim_io_printf (sd
, "Interrupt generator %d (NMI) at pc=0x%x, time=%d.\n", intgen_list
->number
, intgen_list
->address
, intgen_list
->time
);
821 else if (*argv
&& !strcmp (*argv
, "remove"))
824 num
= sim_parse_number (*argv
, NULL
);
828 if (intgen_list
->number
== num
)
830 tmpgen
= intgen_list
;
831 intgen_list
= intgen_list
->next
;
835 for (intgen
= intgen_list
; intgen
!= NULL
; intgen
= intgen
->next
)
837 if (intgen
->next
!= NULL
&& intgen
->next
->number
== num
)
839 tmpgen
= intgen
->next
;
840 intgen
->next
= intgen
->next
->next
;
848 sim_io_printf (sd
, "No interrupt generator numbered %d, ignoring.\n", num
);
851 else if (*argv
&& !strcmp (*argv
, "info"))
855 for (intgen
= intgen_list
; intgen
!= NULL
; intgen
= intgen
->next
)
856 sim_io_printf (sd
, "Interrupt generator %d (%s) at pc=0x%x/time=%d%s.\n",
858 interrupt_names
[intgen
->type
],
861 (intgen
->enabled
? "" : " (disabled)"));
865 sim_io_printf (sd
, "No interrupt generators defined.\n");
871 sim_io_printf (sd
, "Invalid interrupt command, must be one of `add', `remove', or `info'.\n");
873 /* Cache the presence of a non-maskable generator. */
874 have_nm_generator
= 0;
875 for (intgen
= intgen_list
; intgen
!= NULL
; intgen
= intgen
->next
)
877 if (intgen
->type
== int_nmi
|| intgen
->type
== int_reset
)
879 have_nm_generator
= 1;
886 sim_do_command (sd
, cmd
)
890 char *mm_cmd
= "memory-map";
891 char *int_cmd
= "interrupt";
893 if (! strncmp (cmd
, mm_cmd
, strlen (mm_cmd
))
894 && strchr (" ", cmd
[strlen(mm_cmd
)]))
895 sim_set_memory_map (sd
, cmd
+ strlen(mm_cmd
) + 1);
897 else if (! strncmp (cmd
, int_cmd
, strlen (int_cmd
))
898 && strchr (" ", cmd
[strlen(int_cmd
)]))
899 sim_set_interrupt (sd
, cmd
+ strlen(int_cmd
) + 1);
901 else if (! strcmp (cmd
, "help"))
903 sim_io_printf (sd
, "V850 simulator commands:\n\n");
904 sim_io_printf (sd
, "interrupt add <inttype> { pc | time } <value> -- Set up an interrupt generator\n");
905 sim_io_printf (sd
, "interrupt remove <n> -- Remove an existing interrupt generator\n");
906 sim_io_printf (sd
, "interrupt info -- List all the interrupt generators\n");
907 sim_io_printf (sd
, "memory-map hole=<m>,<n> -- Set the memory map to have a hole between <m> and <n>\n");
908 sim_io_printf (sd
, "\n");
911 sim_io_printf (sd
, "\"%s\" is not a valid V850 simulator command.\n",