--- trunk/src/cpu.c 2007/10/08 16:19:43 23 +++ trunk/src/cpu.c 2007/10/08 16:19:56 24 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: cpu.c,v 1.329 2006/01/16 04:48:08 debug Exp $ + * $Id: cpu.c,v 1.342 2006/06/22 13:27:03 debug Exp $ * * Common routines for CPU emulation. (Not specific to any CPU type.) */ @@ -43,8 +43,6 @@ extern int quiet_mode; -extern int show_opcode_statistics; -extern int dyntrans_backend_enable; static struct cpu_family *first_cpu_family = NULL; @@ -106,22 +104,7 @@ } fatal("\ncpu_new(): unknown cpu type '%s'\n", cpu_type_name); - exit(1); -} - - -/* - * cpu_show_full_statistics(): - * - * Show detailed statistics on opcode usage on each cpu. - */ -void cpu_show_full_statistics(struct machine *m) -{ - if (m->cpu_family == NULL || - m->cpu_family->show_full_statistics == NULL) - fatal("cpu_show_full_statistics(): NULL\n"); - else - m->cpu_family->show_full_statistics(m); + return NULL; } @@ -166,14 +149,14 @@ * tracing. */ int cpu_disassemble_instr(struct machine *m, struct cpu *cpu, - unsigned char *instr, int running, uint64_t addr, int bintrans) + unsigned char *instr, int running, uint64_t addr) { if (m->cpu_family == NULL || m->cpu_family->disassemble_instr == NULL) { fatal("cpu_disassemble_instr(): NULL\n"); return 0; } else return m->cpu_family->disassemble_instr(cpu, instr, - running, addr, bintrans); + running, addr); } @@ -196,6 +179,24 @@ /* + * cpu_gdb_stub(): + * + * Execute a "remote GDB" command. Return value is a pointer to a newly + * allocated response string, if the command was successfully executed. If + * there was an error, NULL is returned. + */ +char *cpu_gdb_stub(struct cpu *cpu, char *cmd) +{ + if (cpu->machine->cpu_family == NULL || + cpu->machine->cpu_family->gdb_stub == NULL) { + fatal("cpu_gdb_stub(): NULL\n"); + return NULL; + } else + return cpu->machine->cpu_family->gdb_stub(cpu, cmd); +} + + +/* * cpu_interrupt(): * * Assert an interrupt. @@ -257,9 +258,9 @@ fatal("%s", symbol); else { if (cpu->is_32bit) - fatal("0x%08x", (int)f); + fatal("0x%"PRIx32, (uint32_t) f); else - fatal("0x%llx", (long long)f); + fatal("0x%"PRIx64, (uint64_t) f); } fatal("("); @@ -267,6 +268,11 @@ cpu->machine->cpu_family->functioncall_trace(cpu, f, n_args); fatal(")>\n"); + +#ifdef PRINT_MEMORY_CHECKSUM + /* Temporary hack for finding bugs: */ + fatal("call chksum=%016"PRIx64"\n", memory_checksum(cpu->mem)); +#endif } @@ -297,22 +303,8 @@ { size_t s = DYNTRANS_CACHE_SIZE + DYNTRANS_CACHE_MARGIN; - if (cpu->translation_cache == NULL) { -#ifdef DYNTRANS_BACKEND - if (dyntrans_backend_enable) { - cpu->translation_cache = (unsigned char *) mmap(NULL, - s, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | - MAP_PRIVATE, -1, 0); - if (cpu->translation_cache == NULL) { - dyntrans_backend_enable = 0; - fatal("%\n% WARNING! Dyntrans backend disabled" - ", because mmap() failed.\n%\n"); - } - } -#endif - if (cpu->translation_cache == NULL) - cpu->translation_cache = zeroed_alloc(s); - } + if (cpu->translation_cache == NULL) + cpu->translation_cache = zeroed_alloc(s); /* Create an empty table at the beginning of the translation cache: */ memset(cpu->translation_cache, 0, sizeof(uint32_t) @@ -425,9 +417,6 @@ if (machine->show_nr_of_instructions || !quiet_mode) cpu_show_cycles(machine, 1); - if (show_opcode_statistics) - cpu_show_full_statistics(machine); - fflush(stdout); } @@ -446,18 +435,11 @@ char *symbol; int64_t mseconds, ninstrs, is, avg; struct timeval tv; - int h, m, s, ms, d, instrs_per_cycle = 1; + int h, m, s, ms, d; static int64_t mseconds_last = 0; static int64_t ninstrs_last = -1; - switch (machine->arch) { - case ARCH_MIPS: - instrs_per_cycle = machine->cpus[machine->bootstrap_cpu]-> - cd.mips.cpu_type.instrs_per_cycle; - break; - } - pc = machine->cpus[machine->bootstrap_cpu]->pc; gettimeofday(&tv, NULL); @@ -470,15 +452,17 @@ if (mseconds - mseconds_last == 0) mseconds ++; - ninstrs = machine->ncycles_since_gettimeofday * instrs_per_cycle; + ninstrs = machine->ncycles_since_gettimeofday; if (machine->automatic_clock_adjustment) { static int first_adjustment = 1; /* Current nr of cycles per second: */ int64_t cur_cycles_per_second = 1000 * - (ninstrs-ninstrs_last) / (mseconds-mseconds_last) - / instrs_per_cycle; + (ninstrs-ninstrs_last) / (mseconds-mseconds_last); + + /* fatal("[ CYCLES PER SECOND = %"PRIi64" ]\n", + cur_cycles_per_second); */ if (cur_cycles_per_second < 1000000) cur_cycles_per_second = 1000000; @@ -491,8 +475,8 @@ cur_cycles_per_second) / 16; } - /* debug("[ updating emulated_hz to %lli Hz ]\n", - (long long)machine->emulated_hz); */ + /* fatal("[ updating emulated_hz to %"PRIi64" Hz ]\n", + machine->emulated_hz); */ } @@ -500,8 +484,7 @@ if (!machine->show_nr_of_instructions && !forced) goto do_return; - printf("[ %lli instrs", - (long long)(machine->ncycles * instrs_per_cycle)); + printf("[ %"PRIi64" instrs", (int64_t)machine->ncycles); if (!machine->automatic_clock_adjustment) { d = machine->emulated_hz / 1000; @@ -525,15 +508,15 @@ is = 0; if (avg < 0) avg = 0; - printf("; i/s=%lli avg=%lli", (long long)is, (long long)avg); + printf("; i/s=%"PRIi64" avg=%"PRIi64, is, avg); symbol = get_symbol_name(&machine->symbol_context, pc, &offset); if (machine->ncpus == 1) { if (machine->cpus[machine->bootstrap_cpu]->is_32bit) - printf("; pc=0x%08x", (int)pc); + printf("; pc=0x%08"PRIx32, (uint32_t) pc); else - printf("; pc=0x%016llx", (long long)pc); + printf("; pc=0x%016"PRIx64, (uint64_t) pc); } if (symbol != NULL) @@ -577,7 +560,7 @@ if (machine->a_few_cycles < 1) machine->a_few_cycles = 1; - if (ncpus > 1 && machine->max_random_cycles_per_chunk == 0) + if (ncpus > 1) machine->a_few_cycles = 1; /* debug("cpu_run_init(): a_few_cycles = %i\n", @@ -654,95 +637,6 @@ } -#ifdef DYNTRANS_BACKEND -/* - * cpu_dtb_add_fixup(): - * - * Add a fixup entry to a currently ongoing dyntrans backend translation. - */ -void cpu_dtb_add_fixup(struct cpu *cpu, int type, void *addr, size_t data) -{ - struct dtb_fixup *fixup = malloc(sizeof (struct dtb_fixup)); - if (fixup == NULL) { - fprintf(stderr, "out of memory\n"), - exit(1); - } - - /* memset(fixup, 0, sizeof(struct dtb_fixup)); */ - - fixup->next = cpu->translation_context.fixups; - cpu->translation_context.fixups = fixup; - - fixup->type = type; - fixup->addr = addr; - fixup->data = data; - - /* printf("{ fixup added: host addr %p, data=%p }\n", addr, - (void *)data); */ -} - - -/* - * cpu_dtb_do_fixups(): - * - * This function should be called when a chunk of code has been translated, - * and post-fixup is to be applied (i.e. add data which for some reason was - * not included in the generated code). - * - * If no fixup is necessary for a specific host platform, then it still needs - * an empty do_fixups routine here (just set done = 1). - */ -void cpu_dtb_do_fixups(struct cpu *cpu) -{ - for (;;) { - int done = 0; - size_t omit_addr; - - struct dtb_fixup *fixup = cpu->translation_context.fixups; - if (fixup == NULL) - break; - - cpu->translation_context.fixups = fixup->next; - -#ifdef DYNTRANS_BACKEND_ALPHA - /* Add the data at the end of the new translation: */ -/*printf("%p %p\n", fixup->addr, fixup->data);*/ - omit_addr = (size_t)cpu->translation_context.p - - (size_t)cpu->translation_context.translation_buffer; -/*printf("omit_addr = %016llx\n", (long long)omit_addr);*/ - omit_addr = ((omit_addr - 1) | (sizeof(uint64_t) - 1)) + 1; -/*printf("omit_addr = %016llx\n", (long long)omit_addr);*/ - { - uint64_t *x = (void *)(omit_addr + (size_t)cpu-> - translation_context.translation_buffer); - uint32_t *fixup_instr = (void *)fixup->addr; - size_t ofs = omit_addr; - if (ofs > 0x7fff) { - fatal("Alpha fixup > 0x7fff!\n"); - exit(1); - } - *x = fixup->data; -/*printf("orig instr = 0x%08x\n", *fixup_instr);*/ - (*fixup_instr) &= ~0xffff; - (*fixup_instr) |= ofs; -/*printf("new instr = 0x%08x\n", *fixup_instr);*/ - } - omit_addr += sizeof(uint64_t); - cpu->translation_context.p = (void *) - ((size_t)cpu->translation_context.translation_buffer - + omit_addr); - done = 1; -#endif /* DYNTRANS_BACKEND_ALPHA */ - - if (!done) - fatal("!!! cpu_dtb_do_fixups() not implemented yet" - " for this host architecture!\n"); - } -} - -#endif /* DYNTRANS_BACKEND */ - - /* * cpu_init(): *