📄 interp.c
字号:
} if (cpu->register_widths[rn] == 32) { if (length == 8) { *(unsigned64*)memory = H2T_8 ((unsigned32) (cpu->registers[rn])); return 8; } else { *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn])); return 4; } } else { *(unsigned64*)memory = H2T_8 ((unsigned64)(cpu->registers[rn])); return 8; } return 0;}SIM_RCsim_create_inferior (sd, abfd, argv,env) SIM_DESC sd; struct bfd *abfd; char **argv; char **env;{#ifdef DEBUG#if 0 /* FIXME: doesn't compile */ printf("DBG: sim_create_inferior entered: start_address = 0x%s\n", pr_addr(PC));#endif#endif /* DEBUG */ ColdReset(sd); if (abfd != NULL) { /* override PC value set by ColdReset () */ int cpu_nr; for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++) { sim_cpu *cpu = STATE_CPU (sd, cpu_nr); CIA_SET (cpu, (unsigned64) bfd_get_start_address (abfd)); } }#if 0 /* def DEBUG */ if (argv || env) { /* We should really place the argv slot values into the argument registers, and onto the stack as required. However, this assumes that we have a stack defined, which is not necessarily true at the moment. */ char **cptr; sim_io_printf(sd,"sim_create_inferior() : passed arguments ignored\n"); for (cptr = argv; (cptr && *cptr); cptr++) printf("DBG: arg \"%s\"\n",*cptr); }#endif /* DEBUG */ return SIM_RC_OK;}voidsim_do_command (sd,cmd) SIM_DESC sd; char *cmd;{ if (sim_args_command (sd, cmd) != SIM_RC_OK) sim_io_printf (sd, "Error: \"%s\" is not a valid MIPS simulator command.\n", cmd);}/*---------------------------------------------------------------------------*//*-- Private simulator support interface ------------------------------------*//*---------------------------------------------------------------------------*//* Read a null terminated string from memory, return in a buffer */static char *fetch_str (SIM_DESC sd, address_word addr){ char *buf; int nr = 0; char null; while (sim_read (sd, addr + nr, &null, 1) == 1 && null != 0) nr++; buf = NZALLOC (char, nr + 1); sim_read (sd, addr, buf, nr); return buf;}/* Implements the "sim firmware" command: sim firmware NAME[@ADDRESS] --- emulate ROM monitor named NAME. NAME can be idt, pmon, or lsipmon. If omitted, ADDRESS defaults to the normal address for that monitor. sim firmware none --- don't emulate any ROM monitor. Useful if you need a clean address space. */static SIM_RCsim_firmware_command (SIM_DESC sd, char *arg){ int address_present = 0; SIM_ADDR address; /* Signal occurrence of this option. */ firmware_option_p = 1; /* Parse out the address, if present. */ { char *p = strchr (arg, '@'); if (p) { char *q; address_present = 1; p ++; /* skip over @ */ address = strtoul (p, &q, 0); if (*q != '\0') { sim_io_printf (sd, "Invalid address given to the" "`sim firmware NAME@ADDRESS' command: %s\n", p); return SIM_RC_FAIL; } } else { address_present = 0; address = -1; /* Dummy value. */ } } if (! strncmp (arg, "idt", 3)) { idt_monitor_base = address_present ? address : 0xBFC00000; pmon_monitor_base = 0; lsipmon_monitor_base = 0; } else if (! strncmp (arg, "pmon", 4)) { /* pmon uses indirect calls. Hook into implied idt. */ pmon_monitor_base = address_present ? address : 0xBFC00500; idt_monitor_base = pmon_monitor_base - 0x500; lsipmon_monitor_base = 0; } else if (! strncmp (arg, "lsipmon", 7)) { /* lsipmon uses indirect calls. Hook into implied idt. */ pmon_monitor_base = 0; lsipmon_monitor_base = address_present ? address : 0xBFC00200; idt_monitor_base = lsipmon_monitor_base - 0x200; } else if (! strncmp (arg, "none", 4)) { if (address_present) { sim_io_printf (sd, "The `sim firmware none' command does " "not take an `ADDRESS' argument.\n"); return SIM_RC_FAIL; } idt_monitor_base = 0; pmon_monitor_base = 0; lsipmon_monitor_base = 0; } else { sim_io_printf (sd, "\Unrecognized name given to the `sim firmware NAME' command: %s\n\Recognized firmware names are: `idt', `pmon', `lsipmon', and `none'.\n", arg); return SIM_RC_FAIL; } return SIM_RC_OK;}/* Simple monitor interface (currently setup for the IDT and PMON monitors) */intsim_monitor (SIM_DESC sd, sim_cpu *cpu, address_word cia, unsigned int reason){#ifdef DEBUG printf("DBG: sim_monitor: entered (reason = %d)\n",reason);#endif /* DEBUG */ /* The IDT monitor actually allows two instructions per vector slot. However, the simulator currently causes a trap on each individual instruction. We cheat, and lose the bottom bit. */ reason >>= 1; /* The following callback functions are available, however the monitor we are simulating does not make use of them: get_errno, isatty, lseek, rename, system, time and unlink */ switch (reason) { case 6: /* int open(char *path,int flags) */ { char *path = fetch_str (sd, A0); V0 = sim_io_open (sd, path, (int)A1); zfree (path); break; } case 7: /* int read(int file,char *ptr,int len) */ { int fd = A0; int nr = A2; char *buf = zalloc (nr); V0 = sim_io_read (sd, fd, buf, nr); sim_write (sd, A1, buf, nr); zfree (buf); } break; case 8: /* int write(int file,char *ptr,int len) */ { int fd = A0; int nr = A2; char *buf = zalloc (nr); sim_read (sd, A1, buf, nr); V0 = sim_io_write (sd, fd, buf, nr); zfree (buf); break; } case 10: /* int close(int file) */ { V0 = sim_io_close (sd, (int)A0); break; } case 2: /* Densan monitor: char inbyte(int waitflag) */ { if (A0 == 0) /* waitflag == NOWAIT */ V0 = (unsigned_word)-1; } /* Drop through to case 11 */ case 11: /* char inbyte(void) */ { char tmp; /* ensure that all output has gone... */ sim_io_flush_stdout (sd); if (sim_io_read_stdin (sd, &tmp, sizeof(char)) != sizeof(char)) { sim_io_error(sd,"Invalid return from character read"); V0 = (unsigned_word)-1; } else V0 = (unsigned_word)tmp; break; } case 3: /* Densan monitor: void co(char chr) */ case 12: /* void outbyte(char chr) : write a byte to "stdout" */ { char tmp = (char)(A0 & 0xFF); sim_io_write_stdout (sd, &tmp, sizeof(char)); break; } case 17: /* void _exit() */ { sim_io_eprintf (sd, "sim_monitor(17): _exit(int reason) to be coded\n"); sim_engine_halt (SD, CPU, NULL, NULL_CIA, sim_exited, (unsigned int)(A0 & 0xFFFFFFFF)); break; } case 28: /* PMON flush_cache */ break; case 55: /* void get_mem_info(unsigned int *ptr) */ /* in: A0 = pointer to three word memory location */ /* out: [A0 + 0] = size */ /* [A0 + 4] = instruction cache size */ /* [A0 + 8] = data cache size */ { unsigned_4 value = MEM_SIZE /* FIXME STATE_MEM_SIZE (sd) */; unsigned_4 zero = 0; H2T (value); sim_write (sd, A0 + 0, (char *)&value, 4); sim_write (sd, A0 + 4, (char *)&zero, 4); sim_write (sd, A0 + 8, (char *)&zero, 4); /* sim_io_eprintf (sd, "sim: get_mem_info() deprecated\n"); */ break; } case 158: /* PMON printf */ /* in: A0 = pointer to format string */ /* A1 = optional argument 1 */ /* A2 = optional argument 2 */ /* A3 = optional argument 3 */ /* out: void */ /* The following is based on the PMON printf source */ { address_word s = A0; char c; signed_word *ap = &A1; /* 1st argument */ /* This isn't the quickest way, since we call the host print routine for every character almost. But it does avoid having to allocate and manage a temporary string buffer. */ /* TODO: Include check that we only use three arguments (A1, A2 and A3) */ while (sim_read (sd, s++, &c, 1) && c != '\0') { if (c == '%') { char tmp[40]; enum {FMT_RJUST, FMT_LJUST, FMT_RJUST0, FMT_CENTER} fmt = FMT_RJUST; int width = 0, trunc = 0, haddot = 0, longlong = 0; while (sim_read (sd, s++, &c, 1) && c != '\0') { if (strchr ("dobxXulscefg%", c)) break; else if (c == '-') fmt = FMT_LJUST; else if (c == '0') fmt = FMT_RJUST0; else if (c == '~') fmt = FMT_CENTER; else if (c == '*') { if (haddot) trunc = (int)*ap++; else width = (int)*ap++; } else if (c >= '1' && c <= '9') { address_word t = s; unsigned int n; while (sim_read (sd, s++, &c, 1) == 1 && isdigit (c)) tmp[s - t] = c; tmp[s - t] = '\0'; n = (unsigned int)strtol(tmp,NULL,10); if (haddot) trunc = n; else width = n; s--; } else if (c == '.') haddot = 1; } switch (c) { case '%': sim_io_printf (sd, "%%"); break; case 's': if ((int)*ap != 0) { address_word p = *ap++; char ch; while (sim_read (sd, p++, &ch, 1) == 1 && ch != '\0') sim_io_printf(sd, "%c", ch); } else sim_io_printf(sd,"(null)"); break; case 'c': sim_io_printf (sd, "%c", (int)*ap++); break; default: if (c == 'l') { sim_read (sd, s++, &c, 1); if (c == 'l') { longlong = 1; sim_read (sd, s++, &c, 1); } } if (strchr ("dobxXu", c)) { word64 lv = (word64) *ap++; if (c == 'b') sim_io_printf(sd,"<binary not supported>"); else { sprintf (tmp, "%%%s%c", longlong ? "ll" : "", c); if (longlong) sim_io_printf(sd, tmp, lv); else sim_io_printf(sd, tmp, (int)lv); } } else if (strchr ("eEfgG", c)) { double dbl = *(double*)(ap++); sprintf (tmp, "%%%d.%d%c", width, trunc, c); sim_io_printf (sd, tmp, dbl); trunc = 0; } } } else sim_io_printf(sd, "%c", c); } break; } default: /* Unknown reason. */ return 0; } return 1;}/* Store a word into memory. */static voidstore_word (SIM_DESC sd, sim_cpu *cpu, address_word cia, uword64 vaddr, signed_word val){ address_word paddr; int uncached; if ((vaddr & 3) != 0) SignalExceptionAddressStore (); else { if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL)) { const uword64 mask = 7; uword64 memval; unsigned int byte; paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)); byte = (vaddr & mask) ^ (BigEndianCPU << 2); memval = ((uword64) val) << (8 * byte); StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr, isREAL); } }}/* Load a word from memory. */static signed_wordload_word (SIM_DESC sd, sim_cpu *cpu, address_word cia, uword64 vaddr){ if ((vaddr & 3) != 0) { SIM_CORE_SIGNAL (SD, cpu, cia, read_map, AccessLength_WORD+1, vaddr, read_transfer, sim_core_unaligned_signal); } else { address_word paddr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -