21 enum interrupt_cond_type
28 struct interrupt_generator
30 enum interrupt_type type;
31 enum interrupt_cond_type cond_type;
36 struct interrupt_generator *next;
39 char *interrupt_names[] = {
52 struct interrupt_generator *intgen_list;
54 /* True if a non-maskable (such as NMI or reset) interrupt generator
57 static int have_nm_generator;
67 /* These default values correspond to expected usage for the chip. */
69 SIM_ADDR rom_size = 0x8000;
70 SIM_ADDR low_end = 0x200000;
71 SIM_ADDR high_start = 0xffe000;
75 host_callback *v850_callback;
79 static SIM_OPEN_KIND sim_kind;
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));
100 struct hash_entry *next;
106 struct hash_entry hash_table[MAX_HASH+1];
113 if ((insn & 0x0600) == 0
114 || (insn & 0x0700) == 0x0200
115 || (insn & 0x0700) == 0x0600
116 || (insn & 0x0780) == 0x0700)
117 return (insn & 0x07e0) >> 5;
119 if ((insn & 0x0700) == 0x0300
120 || (insn & 0x0700) == 0x0400
121 || (insn & 0x0700) == 0x0500)
122 return (insn & 0x0780) >> 7;
124 if ((insn & 0x07c0) == 0x0780)
125 return (insn & 0x07c0) >> 6;
127 return (insn & 0x07e0) >> 5;
130 static struct hash_entry *
134 struct hash_entry *h;
136 h = &hash_table[hash(ins)];
138 while ((ins & h->mask) != h->opcode)
142 (*v850_callback->printf_filtered) (v850_callback, "ERROR looking up hash for 0x%x, PC=0x%x\n", ins, PC);
150 /* FIXME These would more efficient to use than load_mem/store_mem,
151 but need to be changed to use the memory map. */
165 return (a[1] << 8) + (a[0]);
173 return (a[3]<<24) + (a[2]<<16) + (a[1]<<8) + (a[0]);
177 put_byte (addr, data)
186 put_half (addr, data)
192 a[1] = (data >> 8) & 0xff;
196 put_word (addr, data)
202 a[1] = (data >> 8) & 0xff;
203 a[2] = (data >> 16) & 0xff;
204 a[3] = (data >> 24) & 0xff;
213 /* Mask down to 24 bits. */
218 /* "Mirror" the addresses below 1MB. */
220 addr &= (rom_size - 1);
222 addr += (rom_size - 0x100000);
223 return (uint8 *) (addr + State.mem);
225 else if (addr >= high_start)
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)
231 else if (addr >= 0xffe000)
233 return (uint8 *) (addr - high_start + high_base + State.mem);
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);
250 uint8 *p = map (addr);
257 return p[1] << 8 | p[0];
259 return p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0];
266 store_mem (addr, len, data)
271 uint8 *p = map (addr);
297 struct hash_entry *h;
299 h = lookup_hash (insn);
301 OP[1] = (insn >> 11) & 0x1f;
309 struct hash_entry *h;
311 h = lookup_hash (insn);
312 OP[0] = (((insn & 0x70) >> 4) | ((insn & 0xf800) >> 8)) << 1;
320 struct hash_entry *h;
322 h = lookup_hash (insn);
323 OP[0] = (insn >> 11) & 0x1f;
324 OP[1] = (insn & 0x7f);
332 struct hash_entry *h;
334 h = lookup_hash (insn);
335 OP[0] = (((insn & 0x3f) << 15) | ((insn >> 17) & 0x7fff)) << 1;
336 OP[1] = (insn >> 11) & 0x1f;
344 struct hash_entry *h;
346 h = lookup_hash (insn);
347 OP[0] = (insn >> 16) & 0xffff;
349 OP[2] = (insn >> 11) & 0x1f;
357 struct hash_entry *h;
359 h = lookup_hash (insn);
361 OP[1] = (insn >> 11) & 0x1f;
362 OP[2] = (insn >> 16) & 0xffff;
370 struct hash_entry *h;
372 h = lookup_hash (insn);
374 OP[1] = (insn >> 11) & 0x7;
375 OP[2] = (insn >> 16) & 0xffff;
380 do_format_9_10 (insn)
383 struct hash_entry *h;
385 h = lookup_hash (insn);
387 OP[1] = (insn >> 11) & 0x1f;
401 totsize = rom_size + (low_end - 0x100000) + (0x1000000 - high_start);
403 high_base = rom_size + (low_end - 0x100000);
405 State.mem = (uint8 *) calloc (1, totsize);
408 (*v850_callback->printf_filtered) (v850_callback, "Allocation of main memory failed.\n");
414 sim_set_memory_map (spec)
417 char *reststr, *nreststr;
418 SIM_ADDR new_low_end, new_high_start;
420 new_low_end = low_end;
421 new_high_start = high_start;
422 if (! strncmp (spec, "hole=", 5))
424 new_low_end = sim_parse_number (spec + 5, &reststr);
425 if (new_low_end < 0x100000)
427 (*v850_callback->printf_filtered) (v850_callback,
428 "Low end must be at least 0x100000\n");
434 new_high_start = sim_parse_number (reststr, &nreststr);
435 /* FIXME Check high_start also */
437 (*v850_callback->printf_filtered) (v850_callback,
438 "Hole goes from 0x%x to 0x%x\n",
439 new_low_end, new_high_start);
443 (*v850_callback->printf_filtered) (v850_callback, "Invalid specification for memory map, must be `hole=<m>[,<n>]'\n");
446 if (new_low_end != low_end || new_high_start != high_start)
448 low_end = new_low_end;
449 high_start = new_high_start;
452 (*v850_callback->printf_filtered) (v850_callback, "Reconfiguring memory (old contents will be lost)\n");
458 /* Parse a number in hex, octal, or decimal form. */
461 sim_parse_number (str, rest)
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);
469 return strtol (str, rest, 10);
480 sim_write (sd, addr, buffer, size)
483 unsigned char *buffer;
490 for (i = 0; i < size; i++)
491 store_mem (addr + i, 1, buffer[i]);
502 struct hash_entry *h;
508 for (p = argv + 1; *p; ++p)
510 if (strcmp (*p, "-E") == 0)
511 ++p; /* ignore endian spec */
514 if (strcmp (*p, "-t") == 0)
518 (*v850_callback->printf_filtered) (v850_callback, "ERROR: unsupported option(s): %s\n",*p);
521 /* put all the opcodes in the hash table */
522 for (s = Simops; s->func; s++)
524 h = &hash_table[hash(s->opcode)];
526 /* go to the last entry in the chain */
532 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
537 h->opcode = s->opcode;
540 /* fudge our descriptor for now */
546 sim_close (sd, quitting)
557 (*v850_callback->printf_filtered) (v850_callback, "sim_set_profile %d\n", n);
561 sim_set_profile_size (n)
564 (*v850_callback->printf_filtered) (v850_callback, "sim_set_profile_size %d\n", n);
569 static void do_interrupt PARAMS ((enum interrupt_type));
579 sim_resume (sd, step, siggnal)
585 struct interrupt_generator *intgen;
589 State.exception = SIGTRAP;
597 /* Fetch the current instruction. */
600 opcode = (inst & 0x07e0) >> 5;
602 /* Decode the opcode field. */
603 if ((opcode & 0x30) == 0
604 || (opcode & 0x38) == 0x10)
606 do_format_1_2 (inst & 0xffff);
609 else if ((opcode & 0x3C) == 0x18
610 || (opcode & 0x3C) == 0x1C
611 || (opcode & 0x3C) == 0x20
612 || (opcode & 0x3C) == 0x24
613 || (opcode & 0x3C) == 0x28)
615 do_format_4 (inst & 0xffff);
618 else if ((opcode & 0x3C) == 0x2C)
620 do_format_3 (inst & 0xffff);
621 /* No PC update, it's done in the instruction. */
623 else if ((opcode & 0x38) == 0x30)
628 else if ((opcode & 0x3C) == 0x38)
633 else if ((opcode & 0x3E) == 0x3C)
636 /* No PC update, it's done in the instruction. */
638 else if ((opcode & 0x3F) == 0x3E)
645 do_format_9_10 (inst);
649 /* Check for and handle pending interrupts. */
650 if (intgen_list && (have_nm_generator || !(PSW & PSW_ID)))
653 for (intgen = intgen_list; intgen != NULL; intgen = intgen->next)
655 if (intgen->cond_type == int_cond_pc
656 && oldpc == intgen->address
661 else if (intgen->cond_type == int_cond_time
665 if (((long) now - (long) start_time) > intgen->time)
673 do_interrupt (intgen->type);
675 else if (State.pending_nmi)
677 State.pending_nmi = 0;
678 do_interrupt (int_nmi);
681 while (!State.exception);
685 do_interrupt (inttype)
686 enum interrupt_type inttype;
688 /* Disable further interrupts. */
690 /* Indicate that we're doing interrupt not exception processing. */
692 if (inttype == int_reset)
697 /* (Might be useful to init other regs with random values.) */
699 else if (inttype == int_nmi)
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;
712 /* Set the FECC part of the ECR. */
723 /* Clear the EICC part of the ECR, will set below. */
752 /* Should never be possible. */
766 sim_resume (sd, 0, 0);
771 sim_info (sd, verbose)
775 (*v850_callback->printf_filtered) (v850_callback, "sim_info\n");
779 sim_create_inferior (sd, argv, env)
795 sim_set_callbacks (sd, p)
802 /* All the code for exiting, signals, etc needs to be revamped.
804 This is enough to get c-torture limping though. */
807 sim_stop_reason (sd, reason, sigrc)
809 enum sim_stop *reason;
812 if (State.exception == SIG_V850_EXIT)
814 *reason = sim_exited;
815 *sigrc = State.regs[7];
819 *reason = sim_stopped;
820 *sigrc = State.exception;
825 sim_fetch_register (sd, rn, memory)
828 unsigned char *memory;
830 put_word (memory, State.regs[rn]);
834 sim_store_register (sd, rn, memory)
837 unsigned char *memory;
839 State.regs[rn] = get_word (memory);
843 sim_read (sd, addr, buffer, size)
846 unsigned char *buffer;
850 for (i = 0; i < size; i++)
851 buffer[i] = load_mem (addr + i, 1);
856 int current_intgen_number = 1;
859 sim_set_interrupt (spec)
864 struct interrupt_generator *intgen, *tmpgen;
865 extern char **buildargv ();
867 argv = buildargv (spec);
869 if (*argv && ! strcmp (*argv, "add"))
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;
880 /* Match on interrupt type name. */
881 for (i = 0; i < num_int_types; ++i)
883 if (*argv && ! strcmp (*argv, interrupt_names[i]))
889 if (intgen->type == int_none)
891 (*v850_callback->printf_filtered) (v850_callback, "Interrupt type unknown; known types are\n");
892 for (i = 0; i < num_int_types; ++i)
894 (*v850_callback->printf_filtered) (v850_callback, " %s", interrupt_names[i]);
896 (*v850_callback->printf_filtered) (v850_callback, "\n");
903 if (*argv && ! strcmp (*argv, "pc"))
905 intgen->cond_type = int_cond_pc;
907 intgen->address = sim_parse_number (*argv, NULL);
909 else if (*argv && ! strcmp (*argv, "time"))
911 intgen->cond_type = int_cond_time;
913 intgen->time = sim_parse_number (*argv, NULL);
917 (*v850_callback->printf_filtered) (v850_callback, "Condition type must be `pc' or `time'.\n");
921 /* We now have a valid interrupt generator. Number it and add
922 to the list of generators. */
923 intgen->number = current_intgen_number++;
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);
929 else if (*argv && !strcmp (*argv, "remove"))
932 num = sim_parse_number (*argv, NULL);
936 if (intgen_list->number == num)
938 tmpgen = intgen_list;
939 intgen_list = intgen_list->next;
943 for (intgen = intgen_list; intgen != NULL; intgen = intgen->next)
945 if (intgen->next != NULL && intgen->next->number == num)
947 tmpgen = intgen->next;
948 intgen->next = intgen->next->next;
956 (*v850_callback->printf_filtered) (v850_callback,
957 "No interrupt generator numbered %d, ignoring.\n", num);
960 else if (*argv && !strcmp (*argv, "info"))
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",
968 interrupt_names[intgen->type],
971 (intgen->enabled ? "" : " (disabled)"));
975 (*v850_callback->printf_filtered) (v850_callback, "No interrupt generators defined.\n");
981 (*v850_callback->printf_filtered) (v850_callback,
982 "Invalid interrupt command, must be one of `add', `remove', or `info'.\n");
984 /* Cache the presence of a non-maskable generator. */
985 have_nm_generator = 0;
986 for (intgen = intgen_list; intgen != NULL; intgen = intgen->next)
988 if (intgen->type == int_nmi || intgen->type == int_reset)
990 have_nm_generator = 1;
997 sim_do_command (sd, cmd)
1001 char *mm_cmd = "memory-map";
1002 char *int_cmd = "interrupt";
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);
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);
1012 else if (! strcmp (cmd, "help"))
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");
1022 (*v850_callback->printf_filtered) (v850_callback, "\"%s\" is not a valid V850 simulator command.\n",
1027 sim_load (sd, prog, abfd, from_tty)
1033 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
1036 prog_bfd = sim_load_file (sd, myname, v850_callback, prog, abfd,
1037 sim_kind == SIM_OPEN_DEBUG);
1038 if (prog_bfd == NULL)
1040 PC = bfd_get_start_address (prog_bfd);
1042 bfd_close (prog_bfd);