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