Add ABFD argument to sim_open call. Pass through to sim_config so
[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
DE
665SIM_RC
666sim_create_inferior (sd, argv, env)
667 SIM_DESC sd;
22c1c7dd
JL
668 char **argv;
669 char **env;
670{
1ad886c9 671 return SIM_RC_OK;
22c1c7dd
JL
672}
673
22c1c7dd 674void
1ad886c9
DE
675sim_kill (sd)
676 SIM_DESC sd;
22c1c7dd
JL
677{
678 /* nothing to do */
679}
680
681void
247fccde 682sim_set_callbacks (p)
22c1c7dd
JL
683 host_callback *p;
684{
d81352b8 685 v850_callback = p;
22c1c7dd
JL
686}
687
2b6b2c6d 688/* All the code for exiting, signals, etc needs to be revamped.
d81352b8
JL
689
690 This is enough to get c-torture limping though. */
1ad886c9 691
22c1c7dd 692void
1ad886c9
DE
693sim_stop_reason (sd, reason, sigrc)
694 SIM_DESC sd;
22c1c7dd
JL
695 enum sim_stop *reason;
696 int *sigrc;
697{
1ad886c9
DE
698 if (State.exception == SIG_V850_EXIT)
699 {
700 *reason = sim_exited;
701 *sigrc = State.regs[7];
702 }
22c1c7dd 703 else
1ad886c9
DE
704 {
705 *reason = sim_stopped;
706 *sigrc = State.exception;
707 }
22c1c7dd
JL
708}
709
710void
1ad886c9
DE
711sim_fetch_register (sd, rn, memory)
712 SIM_DESC sd;
22c1c7dd
JL
713 int rn;
714 unsigned char *memory;
715{
88777ce2 716 put_word (memory, State.regs[rn]);
22c1c7dd
JL
717}
718
719void
1ad886c9
DE
720sim_store_register (sd, rn, memory)
721 SIM_DESC sd;
22c1c7dd
JL
722 int rn;
723 unsigned char *memory;
724{
88777ce2 725 State.regs[rn] = get_word (memory);
22c1c7dd
JL
726}
727
9909e232 728int
1ad886c9
DE
729sim_read (sd, addr, buffer, size)
730 SIM_DESC sd;
22c1c7dd
JL
731 SIM_ADDR addr;
732 unsigned char *buffer;
733 int size;
734{
735 int i;
736 for (i = 0; i < size; i++)
1ad886c9
DE
737 buffer[i] = load_mem (addr + i, 1);
738
22c1c7dd
JL
739 return size;
740}
741
1ad886c9
DE
742int current_intgen_number = 1;
743
22c1c7dd 744void
1ad886c9
DE
745sim_set_interrupt (spec)
746 char *spec;
747{
748 int i, num;
749 char **argv;
750 struct interrupt_generator *intgen, *tmpgen;
751 extern char **buildargv ();
752
753 argv = buildargv (spec);
754
755 if (*argv && ! strcmp (*argv, "add"))
756 {
757 /* Create a new interrupt generator object. */
758 intgen = (struct interrupt_generator *)
759 malloc (sizeof(struct interrupt_generator));
760 intgen->type = int_none;
761 intgen->cond_type = int_cond_none;
762 intgen->address = 0;
763 intgen->time = 0;
764 intgen->enabled = 0;
765 ++argv;
766 /* Match on interrupt type name. */
767 for (i = 0; i < num_int_types; ++i)
768 {
769 if (*argv && ! strcmp (*argv, interrupt_names[i]))
770 {
771 intgen->type = i;
772 break;
773 }
774 }
775 if (intgen->type == int_none)
776 {
777 (*v850_callback->printf_filtered) (v850_callback, "Interrupt type unknown; known types are\n");
778 for (i = 0; i < num_int_types; ++i)
779 {
780 (*v850_callback->printf_filtered) (v850_callback, " %s", interrupt_names[i]);
781 }
782 (*v850_callback->printf_filtered) (v850_callback, "\n");
783 free (intgen);
784 return;
785 }
786 ++argv;
787 intgen->address = 0;
788 intgen->time = 0;
789 if (*argv && ! strcmp (*argv, "pc"))
790 {
791 intgen->cond_type = int_cond_pc;
792 ++argv;
793 intgen->address = sim_parse_number (*argv, NULL);
794 }
795 else if (*argv && ! strcmp (*argv, "time"))
796 {
797 intgen->cond_type = int_cond_time;
798 ++argv;
799 intgen->time = sim_parse_number (*argv, NULL);
800 }
801 else
802 {
803 (*v850_callback->printf_filtered) (v850_callback, "Condition type must be `pc' or `time'.\n");
804 free (intgen);
805 return;
806 }
807 /* We now have a valid interrupt generator. Number it and add
808 to the list of generators. */
809 intgen->number = current_intgen_number++;
810 intgen->enabled = 1;
811 intgen->next = intgen_list;
812 intgen_list = intgen;
813 (*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);
814 }
815 else if (*argv && !strcmp (*argv, "remove"))
816 {
817 ++argv;
818 num = sim_parse_number (*argv, NULL);
819 tmpgen = NULL;
820 if (intgen_list)
821 {
822 if (intgen_list->number == num)
823 {
824 tmpgen = intgen_list;
825 intgen_list = intgen_list->next;
826 }
827 else
828 {
829 for (intgen = intgen_list; intgen != NULL; intgen = intgen->next)
830 {
831 if (intgen->next != NULL && intgen->next->number == num)
832 {
833 tmpgen = intgen->next;
834 intgen->next = intgen->next->next;
835 break;
836 }
837 }
838 }
839 if (tmpgen)
840 free (tmpgen);
841 else
842 (*v850_callback->printf_filtered) (v850_callback,
843 "No interrupt generator numbered %d, ignoring.\n", num);
844 }
845 }
846 else if (*argv && !strcmp (*argv, "info"))
847 {
848 if (intgen_list)
849 {
850 for (intgen = intgen_list; intgen != NULL; intgen = intgen->next)
851 (*v850_callback->printf_filtered) (v850_callback,
852 "Interrupt generator %d (%s) at pc=0x%x/time=%d%s.\n",
853 intgen->number,
854 interrupt_names[intgen->type],
855 intgen->address,
856 intgen->time,
857 (intgen->enabled ? "" : " (disabled)"));
858 }
859 else
860 {
861 (*v850_callback->printf_filtered) (v850_callback, "No interrupt generators defined.\n");
862 }
863
864 }
865 else
866 {
867 (*v850_callback->printf_filtered) (v850_callback,
868 "Invalid interrupt command, must be one of `add', `remove', or `info'.\n");
869 }
870 /* Cache the presence of a non-maskable generator. */
871 have_nm_generator = 0;
872 for (intgen = intgen_list; intgen != NULL; intgen = intgen->next)
873 {
874 if (intgen->type == int_nmi || intgen->type == int_reset)
875 {
876 have_nm_generator = 1;
877 break;
878 }
879 }
880}
881
882void
883sim_do_command (sd, cmd)
884 SIM_DESC sd;
22c1c7dd 885 char *cmd;
1ad886c9
DE
886{
887 char *mm_cmd = "memory-map";
888 char *int_cmd = "interrupt";
889
890 if (! strncmp (cmd, mm_cmd, strlen (mm_cmd))
891 && strchr (" ", cmd[strlen(mm_cmd)]))
892 sim_set_memory_map (cmd + strlen(mm_cmd) + 1);
893
894 else if (! strncmp (cmd, int_cmd, strlen (int_cmd))
895 && strchr (" ", cmd[strlen(int_cmd)]))
896 sim_set_interrupt (cmd + strlen(int_cmd) + 1);
897
898 else if (! strcmp (cmd, "help"))
899 {
900 (*v850_callback->printf_filtered) (v850_callback, "V850 simulator commands:\n\n");
901 (*v850_callback->printf_filtered) (v850_callback, "interrupt add <inttype> { pc | time } <value> -- Set up an interrupt generator\n");
902 (*v850_callback->printf_filtered) (v850_callback, "interrupt remove <n> -- Remove an existing interrupt generator\n");
903 (*v850_callback->printf_filtered) (v850_callback, "interrupt info -- List all the interrupt generators\n");
904 (*v850_callback->printf_filtered) (v850_callback, "memory-map hole=<m>,<n> -- Set the memory map to have a hole between <m> and <n>\n");
905 (*v850_callback->printf_filtered) (v850_callback, "\n");
906 }
907 else
908 (*v850_callback->printf_filtered) (v850_callback, "\"%s\" is not a valid V850 simulator command.\n",
909 cmd);
22c1c7dd
JL
910}
911
1ad886c9
DE
912SIM_RC
913sim_load (sd, prog, abfd, from_tty)
914 SIM_DESC sd;
22c1c7dd 915 char *prog;
1ad886c9 916 bfd *abfd;
22c1c7dd
JL
917 int from_tty;
918{
1ad886c9 919 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
1ad886c9 920
247fccde
AC
921 if (prog_bfd != NULL && prog_bfd_was_opened_p)
922 bfd_close (prog_bfd);
1ad886c9
DE
923 prog_bfd = sim_load_file (sd, myname, v850_callback, prog, abfd,
924 sim_kind == SIM_OPEN_DEBUG);
925 if (prog_bfd == NULL)
926 return SIM_RC_FAIL;
927 PC = bfd_get_start_address (prog_bfd);
247fccde 928 prog_bfd_was_opened_p = abfd == NULL;
1ad886c9 929 return SIM_RC_OK;
22c1c7dd 930}
This page took 0.090747 seconds and 4 git commands to generate.