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