Ref gdb/11763 - can't stop a running simulator:
[binutils-gdb.git] / sim / v850 / interp.c
1 #include <signal.h>
2 #include "sysdep.h"
3 #include "bfd.h"
4
5 #include "v850_sim.h"
6
7 enum interrupt_type
8 {
9 int_none,
10 int_reset,
11 int_nmi,
12 int_intov1,
13 int_intp10,
14 int_intp11,
15 int_intp12,
16 int_intp13,
17 int_intcm4,
18 num_int_types
19 };
20
21 enum interrupt_cond_type
22 {
23 int_cond_none,
24 int_cond_pc,
25 int_cond_time
26 };
27
28 struct interrupt_generator
29 {
30 enum interrupt_type type;
31 enum interrupt_cond_type cond_type;
32 int number;
33 int address;
34 int time;
35 int enabled;
36 struct interrupt_generator *next;
37 };
38
39 char *interrupt_names[] = {
40 "",
41 "reset",
42 "nmi",
43 "intov1",
44 "intp10",
45 "intp11",
46 "intp12",
47 "intp13",
48 "intcm4",
49 NULL
50 };
51
52 struct interrupt_generator *intgen_list;
53
54 /* True if a non-maskable (such as NMI or reset) interrupt generator
55 is present. */
56
57 static int have_nm_generator;
58
59 #ifndef INLINE
60 #ifdef __GNUC__
61 #define INLINE inline
62 #else
63 #define INLINE
64 #endif
65 #endif
66
67 /* These default values correspond to expected usage for the chip. */
68
69 SIM_ADDR rom_size = 0x8000;
70 SIM_ADDR low_end = 0x200000;
71 SIM_ADDR high_start = 0xffe000;
72
73 SIM_ADDR high_base;
74
75 host_callback *v850_callback;
76
77 int v850_debug;
78
79 static SIM_OPEN_KIND sim_kind;
80 static char *myname;
81
82 uint32 OP[4];
83
84 static struct hash_entry *lookup_hash PARAMS ((uint32 ins));
85 static long hash PARAMS ((long));
86 static void do_format_1_2 PARAMS ((uint32));
87 static void do_format_3 PARAMS ((uint32));
88 static void do_format_4 PARAMS ((uint32));
89 static void do_format_5 PARAMS ((uint32));
90 static void do_format_6 PARAMS ((uint32));
91 static void do_format_7 PARAMS ((uint32));
92 static void do_format_8 PARAMS ((uint32));
93 static void do_format_9_10 PARAMS ((uint32));
94 static void init_system PARAMS ((void));
95
96 #define MAX_HASH 63
97
98 struct hash_entry
99 {
100 struct hash_entry *next;
101 long opcode;
102 long mask;
103 struct simops *ops;
104 };
105
106 struct hash_entry hash_table[MAX_HASH+1];
107
108
109 static INLINE long
110 hash(insn)
111 long insn;
112 {
113 if ((insn & 0x0600) == 0
114 || (insn & 0x0700) == 0x0200
115 || (insn & 0x0700) == 0x0600
116 || (insn & 0x0780) == 0x0700)
117 return (insn & 0x07e0) >> 5;
118
119 if ((insn & 0x0700) == 0x0300
120 || (insn & 0x0700) == 0x0400
121 || (insn & 0x0700) == 0x0500)
122 return (insn & 0x0780) >> 7;
123
124 if ((insn & 0x07c0) == 0x0780)
125 return (insn & 0x07c0) >> 6;
126
127 return (insn & 0x07e0) >> 5;
128 }
129
130 static struct hash_entry *
131 lookup_hash (ins)
132 uint32 ins;
133 {
134 struct hash_entry *h;
135
136 h = &hash_table[hash(ins)];
137
138 while ((ins & h->mask) != h->opcode)
139 {
140 if (h->next == NULL)
141 {
142 (*v850_callback->printf_filtered) (v850_callback, "ERROR looking up hash for 0x%x, PC=0x%x\n", ins, PC);
143 exit(1);
144 }
145 h = h->next;
146 }
147 return (h);
148 }
149
150 /* FIXME These would more efficient to use than load_mem/store_mem,
151 but need to be changed to use the memory map. */
152
153 uint8
154 get_byte (x)
155 uint8 *x;
156 {
157 return *x;
158 }
159
160 uint16
161 get_half (x)
162 uint8 *x;
163 {
164 uint8 *a = x;
165 return (a[1] << 8) + (a[0]);
166 }
167
168 uint32
169 get_word (x)
170 uint8 *x;
171 {
172 uint8 *a = x;
173 return (a[3]<<24) + (a[2]<<16) + (a[1]<<8) + (a[0]);
174 }
175
176 void
177 put_byte (addr, data)
178 uint8 *addr;
179 uint8 data;
180 {
181 uint8 *a = addr;
182 a[0] = data;
183 }
184
185 void
186 put_half (addr, data)
187 uint8 *addr;
188 uint16 data;
189 {
190 uint8 *a = addr;
191 a[0] = data & 0xff;
192 a[1] = (data >> 8) & 0xff;
193 }
194
195 void
196 put_word (addr, data)
197 uint8 *addr;
198 uint32 data;
199 {
200 uint8 *a = addr;
201 a[0] = data & 0xff;
202 a[1] = (data >> 8) & 0xff;
203 a[2] = (data >> 16) & 0xff;
204 a[3] = (data >> 24) & 0xff;
205 }
206
207 uint8 *
208 map (addr)
209 SIM_ADDR addr;
210 {
211 uint8 *p;
212
213 /* Mask down to 24 bits. */
214 addr &= 0xffffff;
215
216 if (addr < low_end)
217 {
218 /* "Mirror" the addresses below 1MB. */
219 if (addr < 0x100000)
220 addr &= (rom_size - 1);
221 else
222 addr += (rom_size - 0x100000);
223 return (uint8 *) (addr + State.mem);
224 }
225 else if (addr >= high_start)
226 {
227 /* If in the peripheral I/O region, mirror 1K region across 4K,
228 and similarly if in the internal RAM region. */
229 if (addr >= 0xfff000)
230 addr &= 0xfff3ff;
231 else if (addr >= 0xffe000)
232 addr &= 0xffe3ff;
233 return (uint8 *) (addr - high_start + high_base + State.mem);
234 }
235 else
236 {
237 /* Signal a memory error. */
238 State.exception = SIGSEGV;
239 /* Point to a location not in main memory - renders invalid
240 addresses harmless until we get back to main insn loop. */
241 return (uint8 *) &(State.dummy_mem);
242 }
243 }
244
245 uint32
246 load_mem (addr, len)
247 SIM_ADDR addr;
248 int len;
249 {
250 uint8 *p = map (addr);
251
252 switch (len)
253 {
254 case 1:
255 return p[0];
256 case 2:
257 return p[1] << 8 | p[0];
258 case 4:
259 return p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0];
260 default:
261 abort ();
262 }
263 }
264
265 void
266 store_mem (addr, len, data)
267 SIM_ADDR addr;
268 int len;
269 uint32 data;
270 {
271 uint8 *p = map (addr);
272
273 switch (len)
274 {
275 case 1:
276 p[0] = data;
277 return;
278 case 2:
279 p[0] = data;
280 p[1] = data >> 8;
281 return;
282 case 4:
283 p[0] = data;
284 p[1] = data >> 8;
285 p[2] = data >> 16;
286 p[3] = data >> 24;
287 return;
288 default:
289 abort ();
290 }
291 }
292
293 static void
294 do_format_1_2 (insn)
295 uint32 insn;
296 {
297 struct hash_entry *h;
298
299 h = lookup_hash (insn);
300 OP[0] = insn & 0x1f;
301 OP[1] = (insn >> 11) & 0x1f;
302 (h->ops->func) ();
303 }
304
305 static void
306 do_format_3 (insn)
307 uint32 insn;
308 {
309 struct hash_entry *h;
310
311 h = lookup_hash (insn);
312 OP[0] = (((insn & 0x70) >> 4) | ((insn & 0xf800) >> 8)) << 1;
313 (h->ops->func) ();
314 }
315
316 static void
317 do_format_4 (insn)
318 uint32 insn;
319 {
320 struct hash_entry *h;
321
322 h = lookup_hash (insn);
323 OP[0] = (insn >> 11) & 0x1f;
324 OP[1] = (insn & 0x7f);
325 (h->ops->func) ();
326 }
327
328 static void
329 do_format_5 (insn)
330 uint32 insn;
331 {
332 struct hash_entry *h;
333
334 h = lookup_hash (insn);
335 OP[0] = (((insn & 0x3f) << 15) | ((insn >> 17) & 0x7fff)) << 1;
336 OP[1] = (insn >> 11) & 0x1f;
337 (h->ops->func) ();
338 }
339
340 static void
341 do_format_6 (insn)
342 uint32 insn;
343 {
344 struct hash_entry *h;
345
346 h = lookup_hash (insn);
347 OP[0] = (insn >> 16) & 0xffff;
348 OP[1] = insn & 0x1f;
349 OP[2] = (insn >> 11) & 0x1f;
350 (h->ops->func) ();
351 }
352
353 static void
354 do_format_7 (insn)
355 uint32 insn;
356 {
357 struct hash_entry *h;
358
359 h = lookup_hash (insn);
360 OP[0] = insn & 0x1f;
361 OP[1] = (insn >> 11) & 0x1f;
362 OP[2] = (insn >> 16) & 0xffff;
363 (h->ops->func) ();
364 }
365
366 static void
367 do_format_8 (insn)
368 uint32 insn;
369 {
370 struct hash_entry *h;
371
372 h = lookup_hash (insn);
373 OP[0] = insn & 0x1f;
374 OP[1] = (insn >> 11) & 0x7;
375 OP[2] = (insn >> 16) & 0xffff;
376 (h->ops->func) ();
377 }
378
379 static void
380 do_format_9_10 (insn)
381 uint32 insn;
382 {
383 struct hash_entry *h;
384
385 h = lookup_hash (insn);
386 OP[0] = insn & 0x1f;
387 OP[1] = (insn >> 11) & 0x1f;
388 (h->ops->func) ();
389 }
390
391 void
392 sim_size (power)
393 int power;
394
395 {
396 int totsize;
397
398 if (State.mem)
399 free (State.mem);
400
401 totsize = rom_size + (low_end - 0x100000) + (0x1000000 - high_start);
402
403 high_base = rom_size + (low_end - 0x100000);
404
405 State.mem = (uint8 *) calloc (1, totsize);
406 if (!State.mem)
407 {
408 (*v850_callback->printf_filtered) (v850_callback, "Allocation of main memory failed.\n");
409 exit (1);
410 }
411 }
412
413 void
414 sim_set_memory_map (spec)
415 char *spec;
416 {
417 char *reststr, *nreststr;
418 SIM_ADDR new_low_end, new_high_start;
419
420 new_low_end = low_end;
421 new_high_start = high_start;
422 if (! strncmp (spec, "hole=", 5))
423 {
424 new_low_end = sim_parse_number (spec + 5, &reststr);
425 if (new_low_end < 0x100000)
426 {
427 (*v850_callback->printf_filtered) (v850_callback,
428 "Low end must be at least 0x100000\n");
429 return;
430 }
431 if (*reststr == ',')
432 {
433 ++reststr;
434 new_high_start = sim_parse_number (reststr, &nreststr);
435 /* FIXME Check high_start also */
436 }
437 (*v850_callback->printf_filtered) (v850_callback,
438 "Hole goes from 0x%x to 0x%x\n",
439 new_low_end, new_high_start);
440 }
441 else
442 {
443 (*v850_callback->printf_filtered) (v850_callback, "Invalid specification for memory map, must be `hole=<m>[,<n>]'\n");
444 }
445
446 if (new_low_end != low_end || new_high_start != high_start)
447 {
448 low_end = new_low_end;
449 high_start = new_high_start;
450 if (State.mem)
451 {
452 (*v850_callback->printf_filtered) (v850_callback, "Reconfiguring memory (old contents will be lost)\n");
453 sim_size (1);
454 }
455 }
456 }
457
458 /* Parse a number in hex, octal, or decimal form. */
459
460 int
461 sim_parse_number (str, rest)
462 char *str, **rest;
463 {
464 if (str[0] == '0' && str[1] == 'x')
465 return strtol (str, rest, 16);
466 else if (str[0] == '0')
467 return strtol (str, rest, 16);
468 else
469 return strtol (str, rest, 10);
470 }
471
472 static void
473 init_system ()
474 {
475 if (!State.mem)
476 sim_size(1);
477 }
478
479 int
480 sim_write (sd, addr, buffer, size)
481 SIM_DESC sd;
482 SIM_ADDR addr;
483 unsigned char *buffer;
484 int size;
485 {
486 int i;
487
488 init_system ();
489
490 for (i = 0; i < size; i++)
491 store_mem (addr + i, 1, buffer[i]);
492
493 return size;
494 }
495
496 SIM_DESC
497 sim_open (kind,argv)
498 SIM_OPEN_KIND kind;
499 char **argv;
500 {
501 struct simops *s;
502 struct hash_entry *h;
503 char **p;
504
505 sim_kind = kind;
506 myname = argv[0];
507
508 for (p = argv + 1; *p; ++p)
509 {
510 if (strcmp (*p, "-E") == 0)
511 ++p; /* ignore endian spec */
512 else
513 #ifdef DEBUG
514 if (strcmp (*p, "-t") == 0)
515 v850_debug = DEBUG;
516 else
517 #endif
518 (*v850_callback->printf_filtered) (v850_callback, "ERROR: unsupported option(s): %s\n",*p);
519 }
520
521 /* put all the opcodes in the hash table */
522 for (s = Simops; s->func; s++)
523 {
524 h = &hash_table[hash(s->opcode)];
525
526 /* go to the last entry in the chain */
527 while (h->next)
528 h = h->next;
529
530 if (h->ops)
531 {
532 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
533 h = h->next;
534 }
535 h->ops = s;
536 h->mask = s->mask;
537 h->opcode = s->opcode;
538 }
539
540 /* fudge our descriptor for now */
541 return (SIM_DESC) 1;
542 }
543
544
545 void
546 sim_close (sd, quitting)
547 SIM_DESC sd;
548 int quitting;
549 {
550 /* nothing to do */
551 }
552
553 void
554 sim_set_profile (n)
555 int n;
556 {
557 (*v850_callback->printf_filtered) (v850_callback, "sim_set_profile %d\n", n);
558 }
559
560 void
561 sim_set_profile_size (n)
562 int n;
563 {
564 (*v850_callback->printf_filtered) (v850_callback, "sim_set_profile_size %d\n", n);
565 }
566
567 time_t start_time;
568
569 static void do_interrupt PARAMS ((enum interrupt_type));
570
571 int
572 sim_stop (sd)
573 SIM_DESC sd;
574 {
575 return 0;
576 }
577
578 void
579 sim_resume (sd, step, siggnal)
580 SIM_DESC sd;
581 int step, siggnal;
582 {
583 uint32 inst, opcode;
584 reg_t oldpc;
585 struct interrupt_generator *intgen;
586 time_t now;
587
588 if (step)
589 State.exception = SIGTRAP;
590 else
591 State.exception = 0;
592
593 time (&start_time);
594
595 do
596 {
597 /* Fetch the current instruction. */
598 inst = RLW (PC);
599 oldpc = PC;
600 opcode = (inst & 0x07e0) >> 5;
601
602 /* Decode the opcode field. */
603 if ((opcode & 0x30) == 0
604 || (opcode & 0x38) == 0x10)
605 {
606 do_format_1_2 (inst & 0xffff);
607 PC += 2;
608 }
609 else if ((opcode & 0x3C) == 0x18
610 || (opcode & 0x3C) == 0x1C
611 || (opcode & 0x3C) == 0x20
612 || (opcode & 0x3C) == 0x24
613 || (opcode & 0x3C) == 0x28)
614 {
615 do_format_4 (inst & 0xffff);
616 PC += 2;
617 }
618 else if ((opcode & 0x3C) == 0x2C)
619 {
620 do_format_3 (inst & 0xffff);
621 /* No PC update, it's done in the instruction. */
622 }
623 else if ((opcode & 0x38) == 0x30)
624 {
625 do_format_6 (inst);
626 PC += 4;
627 }
628 else if ((opcode & 0x3C) == 0x38)
629 {
630 do_format_7 (inst);
631 PC += 4;
632 }
633 else if ((opcode & 0x3E) == 0x3C)
634 {
635 do_format_5 (inst);
636 /* No PC update, it's done in the instruction. */
637 }
638 else if ((opcode & 0x3F) == 0x3E)
639 {
640 do_format_8 (inst);
641 PC += 4;
642 }
643 else
644 {
645 do_format_9_10 (inst);
646 PC += 4;
647 }
648
649 /* Check for and handle pending interrupts. */
650 if (intgen_list && (have_nm_generator || !(PSW & PSW_ID)))
651 {
652 intgen = NULL;
653 for (intgen = intgen_list; intgen != NULL; intgen = intgen->next)
654 {
655 if (intgen->cond_type == int_cond_pc
656 && oldpc == intgen->address
657 && intgen->enabled)
658 {
659 break;
660 }
661 else if (intgen->cond_type == int_cond_time
662 && intgen->enabled)
663 {
664 time (&now);
665 if (((long) now - (long) start_time) > intgen->time)
666 {
667 intgen->enabled = 0;
668 break;
669 }
670 }
671 }
672 if (intgen)
673 do_interrupt (intgen->type);
674 }
675 else if (State.pending_nmi)
676 {
677 State.pending_nmi = 0;
678 do_interrupt (int_nmi);
679 }
680 }
681 while (!State.exception);
682 }
683
684 static void
685 do_interrupt (inttype)
686 enum interrupt_type inttype;
687 {
688 /* Disable further interrupts. */
689 PSW |= PSW_ID;
690 /* Indicate that we're doing interrupt not exception processing. */
691 PSW &= ~PSW_EP;
692 if (inttype == int_reset)
693 {
694 PC = 0;
695 PSW = 0x20;
696 ECR = 0;
697 /* (Might be useful to init other regs with random values.) */
698 }
699 else if (inttype == int_nmi)
700 {
701 if (PSW & PSW_NP)
702 {
703 /* We're already working on an NMI, so this one must wait
704 around until the previous one is done. The processor
705 ignores subsequent NMIs, so we don't need to count them. */
706 State.pending_nmi = 1;
707 }
708 else
709 {
710 FEPC = PC;
711 FEPSW = PSW;
712 /* Set the FECC part of the ECR. */
713 ECR &= 0x0000ffff;
714 ECR |= 0x10;
715 PSW |= PSW_NP;
716 PC = 0x10;
717 }
718 }
719 else
720 {
721 EIPC = PC;
722 EIPSW = PSW;
723 /* Clear the EICC part of the ECR, will set below. */
724 ECR &= 0xffff0000;
725 switch (inttype)
726 {
727 case int_intov1:
728 PC = 0x80;
729 ECR |= 0x80;
730 break;
731 case int_intp10:
732 PC = 0x90;
733 ECR |= 0x90;
734 break;
735 case int_intp11:
736 PC = 0xa0;
737 ECR |= 0xa0;
738 break;
739 case int_intp12:
740 PC = 0xb0;
741 ECR |= 0xb0;
742 break;
743 case int_intp13:
744 PC = 0xc0;
745 ECR |= 0xc0;
746 break;
747 case int_intcm4:
748 PC = 0xd0;
749 ECR |= 0xd0;
750 break;
751 default:
752 /* Should never be possible. */
753 abort ();
754 break;
755 }
756 }
757 }
758
759 int
760 sim_trace (sd)
761 SIM_DESC sd;
762 {
763 #ifdef DEBUG
764 v850_debug = DEBUG;
765 #endif
766 sim_resume (sd, 0, 0);
767 return 1;
768 }
769
770 void
771 sim_info (sd, verbose)
772 SIM_DESC sd;
773 int verbose;
774 {
775 (*v850_callback->printf_filtered) (v850_callback, "sim_info\n");
776 }
777
778 SIM_RC
779 sim_create_inferior (sd, argv, env)
780 SIM_DESC sd;
781 char **argv;
782 char **env;
783 {
784 return SIM_RC_OK;
785 }
786
787 void
788 sim_kill (sd)
789 SIM_DESC sd;
790 {
791 /* nothing to do */
792 }
793
794 void
795 sim_set_callbacks (sd, p)
796 SIM_DESC sd;
797 host_callback *p;
798 {
799 v850_callback = p;
800 }
801
802 /* All the code for exiting, signals, etc needs to be revamped.
803
804 This is enough to get c-torture limping though. */
805
806 void
807 sim_stop_reason (sd, reason, sigrc)
808 SIM_DESC sd;
809 enum sim_stop *reason;
810 int *sigrc;
811 {
812 if (State.exception == SIG_V850_EXIT)
813 {
814 *reason = sim_exited;
815 *sigrc = State.regs[7];
816 }
817 else
818 {
819 *reason = sim_stopped;
820 *sigrc = State.exception;
821 }
822 }
823
824 void
825 sim_fetch_register (sd, rn, memory)
826 SIM_DESC sd;
827 int rn;
828 unsigned char *memory;
829 {
830 put_word (memory, State.regs[rn]);
831 }
832
833 void
834 sim_store_register (sd, rn, memory)
835 SIM_DESC sd;
836 int rn;
837 unsigned char *memory;
838 {
839 State.regs[rn] = get_word (memory);
840 }
841
842 int
843 sim_read (sd, addr, buffer, size)
844 SIM_DESC sd;
845 SIM_ADDR addr;
846 unsigned char *buffer;
847 int size;
848 {
849 int i;
850 for (i = 0; i < size; i++)
851 buffer[i] = load_mem (addr + i, 1);
852
853 return size;
854 }
855
856 int current_intgen_number = 1;
857
858 void
859 sim_set_interrupt (spec)
860 char *spec;
861 {
862 int i, num;
863 char **argv;
864 struct interrupt_generator *intgen, *tmpgen;
865 extern char **buildargv ();
866
867 argv = buildargv (spec);
868
869 if (*argv && ! strcmp (*argv, "add"))
870 {
871 /* Create a new interrupt generator object. */
872 intgen = (struct interrupt_generator *)
873 malloc (sizeof(struct interrupt_generator));
874 intgen->type = int_none;
875 intgen->cond_type = int_cond_none;
876 intgen->address = 0;
877 intgen->time = 0;
878 intgen->enabled = 0;
879 ++argv;
880 /* Match on interrupt type name. */
881 for (i = 0; i < num_int_types; ++i)
882 {
883 if (*argv && ! strcmp (*argv, interrupt_names[i]))
884 {
885 intgen->type = i;
886 break;
887 }
888 }
889 if (intgen->type == int_none)
890 {
891 (*v850_callback->printf_filtered) (v850_callback, "Interrupt type unknown; known types are\n");
892 for (i = 0; i < num_int_types; ++i)
893 {
894 (*v850_callback->printf_filtered) (v850_callback, " %s", interrupt_names[i]);
895 }
896 (*v850_callback->printf_filtered) (v850_callback, "\n");
897 free (intgen);
898 return;
899 }
900 ++argv;
901 intgen->address = 0;
902 intgen->time = 0;
903 if (*argv && ! strcmp (*argv, "pc"))
904 {
905 intgen->cond_type = int_cond_pc;
906 ++argv;
907 intgen->address = sim_parse_number (*argv, NULL);
908 }
909 else if (*argv && ! strcmp (*argv, "time"))
910 {
911 intgen->cond_type = int_cond_time;
912 ++argv;
913 intgen->time = sim_parse_number (*argv, NULL);
914 }
915 else
916 {
917 (*v850_callback->printf_filtered) (v850_callback, "Condition type must be `pc' or `time'.\n");
918 free (intgen);
919 return;
920 }
921 /* We now have a valid interrupt generator. Number it and add
922 to the list of generators. */
923 intgen->number = current_intgen_number++;
924 intgen->enabled = 1;
925 intgen->next = intgen_list;
926 intgen_list = intgen;
927 (*v850_callback->printf_filtered) (v850_callback, "Interrupt generator %d (NMI) at pc=0x%x, time=%d.\n", intgen_list->number, intgen_list->address, intgen_list->time);
928 }
929 else if (*argv && !strcmp (*argv, "remove"))
930 {
931 ++argv;
932 num = sim_parse_number (*argv, NULL);
933 tmpgen = NULL;
934 if (intgen_list)
935 {
936 if (intgen_list->number == num)
937 {
938 tmpgen = intgen_list;
939 intgen_list = intgen_list->next;
940 }
941 else
942 {
943 for (intgen = intgen_list; intgen != NULL; intgen = intgen->next)
944 {
945 if (intgen->next != NULL && intgen->next->number == num)
946 {
947 tmpgen = intgen->next;
948 intgen->next = intgen->next->next;
949 break;
950 }
951 }
952 }
953 if (tmpgen)
954 free (tmpgen);
955 else
956 (*v850_callback->printf_filtered) (v850_callback,
957 "No interrupt generator numbered %d, ignoring.\n", num);
958 }
959 }
960 else if (*argv && !strcmp (*argv, "info"))
961 {
962 if (intgen_list)
963 {
964 for (intgen = intgen_list; intgen != NULL; intgen = intgen->next)
965 (*v850_callback->printf_filtered) (v850_callback,
966 "Interrupt generator %d (%s) at pc=0x%x/time=%d%s.\n",
967 intgen->number,
968 interrupt_names[intgen->type],
969 intgen->address,
970 intgen->time,
971 (intgen->enabled ? "" : " (disabled)"));
972 }
973 else
974 {
975 (*v850_callback->printf_filtered) (v850_callback, "No interrupt generators defined.\n");
976 }
977
978 }
979 else
980 {
981 (*v850_callback->printf_filtered) (v850_callback,
982 "Invalid interrupt command, must be one of `add', `remove', or `info'.\n");
983 }
984 /* Cache the presence of a non-maskable generator. */
985 have_nm_generator = 0;
986 for (intgen = intgen_list; intgen != NULL; intgen = intgen->next)
987 {
988 if (intgen->type == int_nmi || intgen->type == int_reset)
989 {
990 have_nm_generator = 1;
991 break;
992 }
993 }
994 }
995
996 void
997 sim_do_command (sd, cmd)
998 SIM_DESC sd;
999 char *cmd;
1000 {
1001 char *mm_cmd = "memory-map";
1002 char *int_cmd = "interrupt";
1003
1004 if (! strncmp (cmd, mm_cmd, strlen (mm_cmd))
1005 && strchr (" ", cmd[strlen(mm_cmd)]))
1006 sim_set_memory_map (cmd + strlen(mm_cmd) + 1);
1007
1008 else if (! strncmp (cmd, int_cmd, strlen (int_cmd))
1009 && strchr (" ", cmd[strlen(int_cmd)]))
1010 sim_set_interrupt (cmd + strlen(int_cmd) + 1);
1011
1012 else if (! strcmp (cmd, "help"))
1013 {
1014 (*v850_callback->printf_filtered) (v850_callback, "V850 simulator commands:\n\n");
1015 (*v850_callback->printf_filtered) (v850_callback, "interrupt add <inttype> { pc | time } <value> -- Set up an interrupt generator\n");
1016 (*v850_callback->printf_filtered) (v850_callback, "interrupt remove <n> -- Remove an existing interrupt generator\n");
1017 (*v850_callback->printf_filtered) (v850_callback, "interrupt info -- List all the interrupt generators\n");
1018 (*v850_callback->printf_filtered) (v850_callback, "memory-map hole=<m>,<n> -- Set the memory map to have a hole between <m> and <n>\n");
1019 (*v850_callback->printf_filtered) (v850_callback, "\n");
1020 }
1021 else
1022 (*v850_callback->printf_filtered) (v850_callback, "\"%s\" is not a valid V850 simulator command.\n",
1023 cmd);
1024 }
1025
1026 SIM_RC
1027 sim_load (sd, prog, abfd, from_tty)
1028 SIM_DESC sd;
1029 char *prog;
1030 bfd *abfd;
1031 int from_tty;
1032 {
1033 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
1034 bfd *prog_bfd;
1035
1036 prog_bfd = sim_load_file (sd, myname, v850_callback, prog, abfd,
1037 sim_kind == SIM_OPEN_DEBUG);
1038 if (prog_bfd == NULL)
1039 return SIM_RC_FAIL;
1040 PC = bfd_get_start_address (prog_bfd);
1041 if (abfd == NULL)
1042 bfd_close (prog_bfd);
1043 return SIM_RC_OK;
1044 }