📄 interp.c
字号:
sim_hw_parse (sd, "/tx3904tmr@0xfffff100/reg 0xfffff100 0x100"); sim_hw_parse (sd, "/tx3904tmr@0xfffff200/reg 0xfffff200 0x100"); sim_hw_parse (sd, "/tx3904sio@0xfffff300/reg 0xfffff300 0x100"); { /* FIXME: poking at dv-sockser internals, use tcp backend if --sockser_addr option was given.*/ extern char* sockser_addr; if(sockser_addr == NULL) sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend stdio"); else sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend tcp"); } sim_hw_parse (sd, "/tx3904sio@0xfffff400/reg 0xfffff400 0x100"); sim_hw_parse (sd, "/tx3904sio@0xfffff400/backend stdio"); /* -- device connections --- */ sim_hw_parse (sd, "/tx3904irc > ip level /tx3904cpu"); sim_hw_parse (sd, "/tx3904tmr@0xfffff000 > int tmr0 /tx3904irc"); sim_hw_parse (sd, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc"); sim_hw_parse (sd, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc"); sim_hw_parse (sd, "/tx3904sio@0xfffff300 > int sio0 /tx3904irc"); sim_hw_parse (sd, "/tx3904sio@0xfffff400 > int sio1 /tx3904irc"); /* add PAL timer & I/O module */ if(! strcmp(board, BOARD_JMR3904_PAL)) { /* the device */ sim_hw_parse (sd, "/pal@0xffff0000"); sim_hw_parse (sd, "/pal@0xffff0000/reg 0xffff0000 64"); /* wire up interrupt ports to irc */ sim_hw_parse (sd, "/pal@0x31000000 > countdown tmr0 /tx3904irc"); sim_hw_parse (sd, "/pal@0x31000000 > timer tmr1 /tx3904irc"); sim_hw_parse (sd, "/pal@0x31000000 > int int0 /tx3904irc"); } if(! strcmp(board, BOARD_JMR3904_DEBUG)) { /* -- DEBUG: glue interrupt generators --- */ sim_hw_parse (sd, "/glue@0xffff0000/reg 0xffff0000 0x50"); sim_hw_parse (sd, "/glue@0xffff0000 > int0 int0 /tx3904irc"); sim_hw_parse (sd, "/glue@0xffff0000 > int1 int1 /tx3904irc"); sim_hw_parse (sd, "/glue@0xffff0000 > int2 int2 /tx3904irc"); sim_hw_parse (sd, "/glue@0xffff0000 > int3 int3 /tx3904irc"); sim_hw_parse (sd, "/glue@0xffff0000 > int4 int4 /tx3904irc"); sim_hw_parse (sd, "/glue@0xffff0000 > int5 int5 /tx3904irc"); sim_hw_parse (sd, "/glue@0xffff0000 > int6 int6 /tx3904irc"); sim_hw_parse (sd, "/glue@0xffff0000 > int7 int7 /tx3904irc"); sim_hw_parse (sd, "/glue@0xffff0000 > int8 dmac0 /tx3904irc"); sim_hw_parse (sd, "/glue@0xffff0000 > int9 dmac1 /tx3904irc"); sim_hw_parse (sd, "/glue@0xffff0000 > int10 dmac2 /tx3904irc"); sim_hw_parse (sd, "/glue@0xffff0000 > int11 dmac3 /tx3904irc"); sim_hw_parse (sd, "/glue@0xffff0000 > int12 sio0 /tx3904irc"); sim_hw_parse (sd, "/glue@0xffff0000 > int13 sio1 /tx3904irc"); sim_hw_parse (sd, "/glue@0xffff0000 > int14 tmr0 /tx3904irc"); sim_hw_parse (sd, "/glue@0xffff0000 > int15 tmr1 /tx3904irc"); sim_hw_parse (sd, "/glue@0xffff0000 > int16 tmr2 /tx3904irc"); sim_hw_parse (sd, "/glue@0xffff0000 > int17 nmi /tx3904cpu"); } device_init(sd); }#endif /* check for/establish the a reference program image */ if (sim_analyze_program (sd, (STATE_PROG_ARGV (sd) != NULL ? *STATE_PROG_ARGV (sd) : NULL), abfd) != SIM_RC_OK) { sim_module_uninstall (sd); return 0; } /* Configure/verify the target byte order and other runtime configuration options */ if (sim_config (sd) != SIM_RC_OK) { sim_module_uninstall (sd); return 0; } if (sim_post_argv_init (sd) != SIM_RC_OK) { /* Uninstall the modules to avoid memory leaks, file descriptor leaks, etc. */ sim_module_uninstall (sd); return 0; } /* verify assumptions the simulator made about the host type system. This macro does not return if there is a problem */ SIM_ASSERT (sizeof(int) == (4 * sizeof(char))); SIM_ASSERT (sizeof(word64) == (8 * sizeof(char))); /* This is NASTY, in that we are assuming the size of specific registers: */ { int rn; for (rn = 0; (rn < (LAST_EMBED_REGNUM + 1)); rn++) { if (rn < 32) cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE; else if ((rn >= FGR_BASE) && (rn < (FGR_BASE + NR_FGR))) cpu->register_widths[rn] = WITH_TARGET_FLOATING_POINT_BITSIZE; else if ((rn >= 33) && (rn <= 37)) cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE; else if ((rn == SRIDX) || (rn == FCR0IDX) || (rn == FCR31IDX) || ((rn >= 72) && (rn <= 89))) cpu->register_widths[rn] = 32; else cpu->register_widths[rn] = 0; } }#if defined(TRACE) if (STATE & simTRACE) open_trace(sd);#endif /* TRACE */ /* sim_io_eprintf (sd, "idt@%x pmon@%x lsipmon@%x\n", idt_monitor_base, pmon_monitor_base, lsipmon_monitor_base); */ /* Write the monitor trap address handlers into the monitor (eeprom) address space. This can only be done once the target endianness has been determined. */ if (idt_monitor_base != 0) { unsigned loop; unsigned idt_monitor_size = 1 << 11; /* the default monitor region */ sim_do_commandf (sd, "memory region 0x%x,0x%x", idt_monitor_base, idt_monitor_size); /* Entry into the IDT monitor is via fixed address vectors, and not using machine instructions. To avoid clashing with use of the MIPS TRAP system, we place our own (simulator specific) "undefined" instructions into the relevant vector slots. */ for (loop = 0; (loop < idt_monitor_size); loop += 4) { address_word vaddr = (idt_monitor_base + loop); unsigned32 insn = (RSVD_INSTRUCTION | (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK) << RSVD_INSTRUCTION_ARG_SHIFT)); H2T (insn); sim_write (sd, vaddr, (char *)&insn, sizeof (insn)); } } if ((pmon_monitor_base != 0) || (lsipmon_monitor_base != 0)) { /* The PMON monitor uses the same address space, but rather than branching into it the address of a routine is loaded. We can cheat for the moment, and direct the PMON routine to IDT style instructions within the monitor space. This relies on the IDT monitor not using the locations from 0xBFC00500 onwards as its entry points.*/ unsigned loop; for (loop = 0; (loop < 24); loop++) { unsigned32 value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */ switch (loop) { case 0: /* read */ value = 7; break; case 1: /* write */ value = 8; break; case 2: /* open */ value = 6; break; case 3: /* close */ value = 10; break; case 5: /* printf */ value = ((0x500 - 16) / 8); /* not an IDT reason code */ break; case 8: /* cliexit */ value = 17; break; case 11: /* flush_cache */ value = 28; break; } SIM_ASSERT (idt_monitor_base != 0); value = ((unsigned int) idt_monitor_base + (value * 8)); H2T (value); if (pmon_monitor_base != 0) { address_word vaddr = (pmon_monitor_base + (loop * 4)); sim_write (sd, vaddr, (char *)&value, sizeof (value)); } if (lsipmon_monitor_base != 0) { address_word vaddr = (lsipmon_monitor_base + (loop * 4)); sim_write (sd, vaddr, (char *)&value, sizeof (value)); } } /* Write an abort sequence into the TRAP (common) exception vector addresses. This is to catch code executing a TRAP (et.al.) instruction without installing a trap handler. */ if ((idt_monitor_base != 0) || (pmon_monitor_base != 0) || (lsipmon_monitor_base != 0)) { unsigned32 halt[2] = { 0x2404002f /* addiu r4, r0, 47 */, HALT_INSTRUCTION /* BREAK */ }; H2T (halt[0]); H2T (halt[1]); sim_write (sd, 0x80000000, (char *) halt, sizeof (halt)); sim_write (sd, 0x80000180, (char *) halt, sizeof (halt)); sim_write (sd, 0x80000200, (char *) halt, sizeof (halt)); /* XXX: Write here unconditionally? */ sim_write (sd, 0xBFC00200, (char *) halt, sizeof (halt)); sim_write (sd, 0xBFC00380, (char *) halt, sizeof (halt)); sim_write (sd, 0xBFC00400, (char *) halt, sizeof (halt)); } } return sd;}#if defined(TRACE)static voidopen_trace(sd) SIM_DESC sd;{ tracefh = fopen(tracefile,"wb+"); if (tracefh == NULL) { sim_io_eprintf(sd,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile); tracefh = stderr; }}#endif /* TRACE *//* Return name of an insn, used by insn profiling. */static const char *get_insn_name (sim_cpu *cpu, int i){ return itable[i].name;}voidsim_close (sd, quitting) SIM_DESC sd; int quitting;{#ifdef DEBUG printf("DBG: sim_close: entered (quitting = %d)\n",quitting);#endif /* "quitting" is non-zero if we cannot hang on errors */ /* shut down modules */ sim_module_uninstall (sd); /* Ensure that any resources allocated through the callback mechanism are released: */ sim_io_shutdown (sd);#if defined(TRACE) if (tracefh != NULL && tracefh != stderr) fclose(tracefh); tracefh = NULL;#endif /* TRACE */ /* FIXME - free SD */ return;}intsim_write (sd,addr,buffer,size) SIM_DESC sd; SIM_ADDR addr; unsigned char *buffer; int size;{ int index; sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */ /* Return the number of bytes written, or zero if error. */#ifdef DEBUG sim_io_printf(sd,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr),size);#endif /* We use raw read and write routines, since we do not want to count the GDB memory accesses in our statistics gathering. */ for (index = 0; index < size; index++) { address_word vaddr = (address_word)addr + index; address_word paddr; int cca; if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isSTORE, &paddr, &cca, isRAW)) break; if (sim_core_write_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1) break; } return(index);}intsim_read (sd,addr,buffer,size) SIM_DESC sd; SIM_ADDR addr; unsigned char *buffer; int size;{ int index; sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */ /* Return the number of bytes read, or zero if error. */#ifdef DEBUG sim_io_printf(sd,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr),size);#endif /* DEBUG */ for (index = 0; (index < size); index++) { address_word vaddr = (address_word)addr + index; address_word paddr; int cca; if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isLOAD, &paddr, &cca, isRAW)) break; if (sim_core_read_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1) break; } return(index);}intsim_store_register (sd,rn,memory,length) SIM_DESC sd; int rn; unsigned char *memory; int length;{ sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */ /* NOTE: gdb (the client) stores registers in target byte order while the simulator uses host byte order */#ifdef DEBUG sim_io_printf(sd,"sim_store_register(%d,*memory=0x%s);\n",rn,pr_addr(*((SIM_ADDR *)memory)));#endif /* DEBUG */ /* Unfortunately this suffers from the same problem as the register numbering one. We need to know what the width of each logical register number is for the architecture being simulated. */ if (cpu->register_widths[rn] == 0) { sim_io_eprintf(sd,"Invalid register width for %d (register store ignored)\n",rn); return 0; } if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR) { cpu->fpr_state[rn - FGR_BASE] = fmt_uninterpreted; if (cpu->register_widths[rn] == 32) { if (length == 8) { cpu->fgr[rn - FGR_BASE] = (unsigned32) T2H_8 (*(unsigned64*)memory); return 8; } else { cpu->fgr[rn - FGR_BASE] = T2H_4 (*(unsigned32*)memory); return 4; } } else { cpu->fgr[rn - FGR_BASE] = T2H_8 (*(unsigned64*)memory); return 8; } } if (cpu->register_widths[rn] == 32) { if (length == 8) { cpu->registers[rn] = (unsigned32) T2H_8 (*(unsigned64*)memory); return 8; } else { cpu->registers[rn] = T2H_4 (*(unsigned32*)memory); return 4; } } else { cpu->registers[rn] = T2H_8 (*(unsigned64*)memory); return 8; } return 0;}intsim_fetch_register (sd,rn,memory,length) SIM_DESC sd; int rn; unsigned char *memory; int length;{ sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */ /* NOTE: gdb (the client) stores registers in target byte order while the simulator uses host byte order */#ifdef DEBUG#if 0 /* FIXME: doesn't compile */ sim_io_printf(sd,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn,pr_addr(registers[rn]));#endif#endif /* DEBUG */ if (cpu->register_widths[rn] == 0) { sim_io_eprintf (sd, "Invalid register width for %d (register fetch ignored)\n",rn); return 0; } /* Any floating point register */ if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR) { if (cpu->register_widths[rn] == 32) { if (length == 8) { *(unsigned64*)memory = H2T_8 ((unsigned32) (cpu->fgr[rn - FGR_BASE])); return 8; } else { *(unsigned32*)memory = H2T_4 (cpu->fgr[rn - FGR_BASE]); return 4; } } else { *(unsigned64*)memory = H2T_8 (cpu->fgr[rn - FGR_BASE]); return 8; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -