--- trunk/src/cpu.c 2007/10/08 16:18:31 11 +++ trunk/src/cpu.c 2007/10/08 16:18:38 12 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: cpu.c,v 1.298 2005/06/27 10:43:16 debug Exp $ + * $Id: cpu.c,v 1.316 2005/08/16 05:37:09 debug Exp $ * * Common routines for CPU emulation. (Not specific to any CPU type.) */ @@ -37,6 +37,7 @@ #include "cpu.h" #include "machine.h" +#include "memory.h" #include "misc.h" @@ -71,13 +72,8 @@ exit(1); } - cpu = malloc(sizeof(struct cpu)); - if (cpu == NULL) { - fprintf(stderr, "out of memory\n"); - exit(1); - } + cpu = zeroed_alloc(sizeof(struct cpu)); - memset(cpu, 0, sizeof(struct cpu)); cpu->memory_rw = NULL; cpu->name = cpu_type_name; cpu->mem = mem; @@ -87,6 +83,8 @@ cpu->bootstrap_cpu_flag = 0; cpu->running = 0; + cpu_create_or_reset_tc(cpu); + fp = first_cpu_family; while (fp != NULL) { @@ -231,6 +229,90 @@ /* + * cpu_functioncall_trace(): + * + * This function should be called if machine->show_trace_tree is enabled, and + * a function call is being made. f contains the address of the function. + */ +void cpu_functioncall_trace(struct cpu *cpu, uint64_t f) +{ + int i, n_args = -1; + char *symbol; + uint64_t offset; + + if (cpu->machine->ncpus > 1) + fatal("cpu%i:\t", cpu->cpu_id); + + cpu->trace_tree_depth ++; + for (i=0; itrace_tree_depth; i++) + fatal(" "); + + fatal("<"); + symbol = get_symbol_name_and_n_args(&cpu->machine->symbol_context, + f, &offset, &n_args); + if (symbol != NULL) + fatal("%s", symbol); + else { + if (cpu->is_32bit) + fatal("0x%08x", (int)f); + else + fatal("0x%llx", (long long)f); + } + fatal("("); + + if (cpu->machine->cpu_family->functioncall_trace != NULL) + cpu->machine->cpu_family->functioncall_trace(cpu, f, n_args); + + fatal(")>\n"); +} + + +/* + * cpu_functioncall_trace_return(): + * + * This function should be called if machine->show_trace_tree is enabled, and + * a function is being returned from. + * + * TODO: Print return value? This could be implemented similar to the + * cpu->functioncall_trace function call above. + */ +void cpu_functioncall_trace_return(struct cpu *cpu) +{ + cpu->trace_tree_depth --; + if (cpu->trace_tree_depth < 0) + cpu->trace_tree_depth = 0; +} + + +/* + * cpu_create_or_reset_tc(): + * + * Create the translation cache in memory (ie allocate memory for it), if + * necessary, and then reset it to an initial state. + */ +void cpu_create_or_reset_tc(struct cpu *cpu) +{ + if (cpu->translation_cache == NULL) + cpu->translation_cache = zeroed_alloc(DYNTRANS_CACHE_SIZE + + DYNTRANS_CACHE_MARGIN); + + /* Create an empty table at the beginning of the translation cache: */ + memset(cpu->translation_cache, 0, sizeof(uint32_t) + * N_BASE_TABLE_ENTRIES); + + cpu->translation_cache_cur_ofs = + N_BASE_TABLE_ENTRIES * sizeof(uint32_t); + + /* + * There might be other translation pointers that still point to + * within the translation_cache region. Let's invalidate those too: + */ + if (cpu->invalidate_code_translation_caches != NULL) + cpu->invalidate_code_translation_caches(cpu); +} + + +/* * cpu_run(): * * Run instructions on all CPUs in this machine, for a "medium duration" @@ -304,7 +386,7 @@ * Shuts down all CPUs in a machine when ending a simulation. (This function * should only need to be called once for each machine.) */ -void cpu_run_deinit(struct emul *emul, struct machine *machine) +void cpu_run_deinit(struct machine *machine) { int te; @@ -343,27 +425,19 @@ void cpu_show_cycles(struct machine *machine, int forced) { uint64_t offset, pc; - int is_32bit = 0, instrs_per_cycle = 1; char *symbol; - int64_t mseconds, ninstrs; + int64_t mseconds, ninstrs, is, avg; struct timeval tv; - int h, m, s, ms, d; + int h, m, s, ms, d, instrs_per_cycle = 1; static int64_t mseconds_last = 0; static int64_t ninstrs_last = -1; switch (machine->arch) { case ARCH_MIPS: - if (machine->cpus[machine->bootstrap_cpu]->cd.mips. - cpu_type.isa_level < 3 || machine->cpus[machine-> - bootstrap_cpu]->cd.mips.cpu_type.isa_level == 32) - is_32bit = 1; instrs_per_cycle = machine->cpus[machine->bootstrap_cpu]-> cd.mips.cpu_type.instrs_per_cycle; break; - case ARCH_ARM: - is_32bit = 1; - break; } pc = machine->cpus[machine->bootstrap_cpu]->pc; @@ -399,8 +473,8 @@ cur_cycles_per_second) / 16; } - debug("[ updating emulated_hz to %lli Hz ]\n", - (long long)machine->emulated_hz); + /* debug("[ updating emulated_hz to %lli Hz ]\n", + (long long)machine->emulated_hz); */ } @@ -427,17 +501,22 @@ } /* Instructions per second, and average so far: */ - printf("; i/s=%lli avg=%lli; ", - (long long) ((long long)1000 * (ninstrs-ninstrs_last) - / (mseconds-mseconds_last)), - (long long) ((long long)1000 * ninstrs / mseconds)); + is = 1000 * (ninstrs-ninstrs_last) / (mseconds-mseconds_last); + avg = (long long)1000 * ninstrs / mseconds; + if (is < 0) + is = 0; + if (avg < 0) + avg = 0; + printf("; i/s=%lli avg=%lli", (long long)is, (long long)avg); symbol = get_symbol_name(&machine->symbol_context, pc, &offset); - if (is_32bit) - printf("pc=0x%08x", (int)pc); - else - printf("pc=0x%016llx", (long long)pc); + if (machine->ncpus == 1) { + if (machine->cpus[machine->bootstrap_cpu]->is_32bit) + printf("; pc=0x%08x", (int)pc); + else + printf("; pc=0x%016llx", (long long)pc); + } if (symbol != NULL) printf(" <%s>", symbol); @@ -455,7 +534,7 @@ * Prepare to run instructions on all CPUs in this machine. (This function * should only need to be called once for each machine.) */ -void cpu_run_init(struct emul *emul, struct machine *machine) +void cpu_run_init(struct machine *machine) { int ncpus = machine->ncpus; int te; @@ -565,10 +644,37 @@ void cpu_init(void) { /* Note: These are registered in alphabetic order. */ + +#ifdef ENABLE_ALPHA + add_cpu_family(alpha_cpu_family_init, ARCH_ALPHA); +#endif + +#ifdef ENABLE_ARM add_cpu_family(arm_cpu_family_init, ARCH_ARM); +#endif + +#ifdef ENABLE_IA64 + add_cpu_family(ia64_cpu_family_init, ARCH_IA64); +#endif + +#ifdef ENABLE_M68K + add_cpu_family(m68k_cpu_family_init, ARCH_M68K); +#endif + +#ifdef ENABLE_MIPS add_cpu_family(mips_cpu_family_init, ARCH_MIPS); +#endif + +#ifdef ENABLE_PPC add_cpu_family(ppc_cpu_family_init, ARCH_PPC); - add_cpu_family(urisc_cpu_family_init, ARCH_URISC); +#endif + +#ifdef ENABLE_SPARC + add_cpu_family(sparc_cpu_family_init, ARCH_SPARC); +#endif + +#ifdef ENABLE_X86 add_cpu_family(x86_cpu_family_init, ARCH_X86); +#endif }