--- trunk/src/cpu.c 2007/10/08 16:22:20 41 +++ trunk/src/cpu.c 2007/10/08 16:22:32 42 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: cpu.c,v 1.376 2007/04/19 15:18:15 debug Exp $ + * $Id: cpu.c,v 1.389 2007/06/15 17:02:37 debug Exp $ * * Common routines for CPU emulation. (Not specific to any CPU type.) */ @@ -39,8 +39,8 @@ #include "cpu.h" #include "machine.h" #include "memory.h" -#include "misc.h" #include "settings.h" +#include "timer.h" extern size_t dyntrans_cache_size; @@ -71,19 +71,11 @@ exit(1); } - cpu_type_name = strdup(name); - if (cpu_type_name == NULL) { - fprintf(stderr, "cpu_new(): out of memory\n"); - exit(1); - } + CHECK_ALLOCATION(cpu_type_name = strdup(name)); cpu = zeroed_alloc(sizeof(struct cpu)); - cpu->path = malloc(strlen(machine->path) + 15); - if (cpu->path == NULL) { - fprintf(stderr, "cpu_new(): out of memory\n"); - exit(1); - } + CHECK_ALLOCATION(cpu->path = malloc(strlen(machine->path) + 15)); snprintf(cpu->path, strlen(machine->path) + 15, "%s.cpu[%i]", machine->path, cpu_id); @@ -95,6 +87,8 @@ cpu->byte_order = EMUL_UNDEFINED_ENDIAN; cpu->running = 0; + cpu->sampling_paddr = zeroed_alloc(N_PADDR_SAMPLES * sizeof(uint64_t)); + /* Create settings, and attach to the machine: */ cpu->settings = settings_new(); snprintf(tmpstr, sizeof(tmpstr), "cpu[%i]", cpu_id); @@ -103,7 +97,7 @@ settings_add(cpu->settings, "name", 0, SETTINGS_TYPE_STRING, SETTINGS_FORMAT_STRING, (void *) &cpu->name); - settings_add(cpu->settings, "running", 0, SETTINGS_TYPE_INT, + settings_add(cpu->settings, "running", 0, SETTINGS_TYPE_UINT8, SETTINGS_FORMAT_YESNO, (void *) &cpu->running); cpu_create_or_reset_tc(cpu); @@ -150,6 +144,9 @@ */ void cpu_destroy(struct cpu *cpu) { + if (cpu->sampling_timer != NULL) + timer_remove(cpu->sampling_timer); + settings_remove(cpu->settings, "name"); settings_remove(cpu->settings, "running"); @@ -229,23 +226,30 @@ */ void cpu_functioncall_trace(struct cpu *cpu, uint64_t f) { + int show_symbolic_function_name = 1; int i, n_args = -1; char *symbol; uint64_t offset; + /* Special hack for M88K userspace: */ + if (cpu->machine->arch == ARCH_M88K && + !(cpu->cd.m88k.cr[M88K_CR_PSR] & M88K_PSR_MODE)) + show_symbolic_function_name = 0; + if (cpu->machine->ncpus > 1) fatal("cpu%i:\t", cpu->cpu_id); - cpu->trace_tree_depth ++; if (cpu->trace_tree_depth > 100) cpu->trace_tree_depth = 100; for (i=0; itrace_tree_depth; i++) fatal(" "); + cpu->trace_tree_depth ++; + fatal("<"); symbol = get_symbol_name_and_n_args(&cpu->machine->symbol_context, f, &offset, &n_args); - if (symbol != NULL) + if (symbol != NULL && show_symbolic_function_name) fatal("%s", symbol); else { if (cpu->is_32bit) @@ -297,22 +301,12 @@ if (cpu->translation_cache == NULL) { cpu->translation_cache = zeroed_alloc(s); -#ifdef NATIVE_CODE_GENERATION if (native_code_translation_enabled) { mprotect(cpu->translation_cache, s, PROT_READ | PROT_WRITE | PROT_EXEC); } -#endif } -#ifdef NATIVE_CODE_GENERATION - if (native_code_translation_enabled && cpu->inr.inr_entries == NULL) - cpu->inr.inr_entries = zeroed_alloc( - sizeof(struct inr_entry) * INR_MAX_ENTRIES); - - cpu->inr.nr_inr_entries_used = 0; -#endif - /* Create an empty table at the beginning of the translation cache: */ memset(cpu->translation_cache, 0, sizeof(uint32_t) * N_BASE_TABLE_ENTRIES); @@ -396,11 +390,11 @@ * TODO: This should be refactored when redesigning the mainbus * concepts! */ - for (te=0; ten_tick_entries; te++) { - machine->tick_func[te](machine->cpus[0], - machine->tick_extra[te]); - machine->tick_func[te](machine->cpus[0], - machine->tick_extra[te]); + for (te=0; tetick_functions.n_entries; te++) { + machine->tick_functions.f[te](machine->cpus[0], + machine->tick_functions.extra[te]); + machine->tick_functions.f[te](machine->cpus[0], + machine->tick_functions.extra[te]); } if (machine->show_nr_of_instructions) @@ -430,8 +424,8 @@ pc = cpu->pc; gettimeofday(&tv, NULL); - mseconds = (tv.tv_sec - machine->starttime.tv_sec) * 1000 - + (tv.tv_usec - machine->starttime.tv_usec) / 1000; + mseconds = (tv.tv_sec - cpu->starttime.tv_sec) * 1000 + + (tv.tv_usec - cpu->starttime.tv_usec) / 1000; if (mseconds == 0) mseconds = 1; @@ -439,13 +433,13 @@ if (mseconds - mseconds_last == 0) mseconds ++; - ninstrs = machine->ninstrs_since_gettimeofday; + ninstrs = cpu->ninstrs_since_gettimeofday; /* RETURN here, unless show_nr_of_instructions (-N) is turned on: */ if (!machine->show_nr_of_instructions && !forced) goto do_return; - printf("[ %"PRIi64" instrs", (int64_t)machine->ninstrs); + printf("[ %"PRIi64" instrs", (int64_t) cpu->ninstrs); /* Instructions per second, and average so far: */ is = 1000 * (ninstrs-ninstrs_last) / (mseconds-mseconds_last); @@ -470,6 +464,11 @@ printf("; pc=0x%016"PRIx64, (uint64_t) pc); } + /* Special hack for M88K userland: (Don't show symbols.) */ + if (cpu->machine->arch == ARCH_M88K && + !(cpu->cd.m88k.cr[M88K_CR_PSR] & M88K_PSR_MODE)) + symbol = NULL; + if (symbol != NULL) printf(" <%s>", symbol); printf(" ]\n"); @@ -488,13 +487,18 @@ */ void cpu_run_init(struct machine *machine) { - machine->ninstrs_flush = 0; - machine->ninstrs = 0; - machine->ninstrs_show = 0; - - /* For performance measurement: */ - gettimeofday(&machine->starttime, NULL); - machine->ninstrs_since_gettimeofday = 0; + int i; + for (i=0; incpus; i++) { + struct cpu *cpu = machine->cpus[i]; + + cpu->ninstrs_flush = 0; + cpu->ninstrs = 0; + cpu->ninstrs_show = 0; + + /* For performance measurement: */ + gettimeofday(&cpu->starttime, NULL); + cpu->ninstrs_since_gettimeofday = 0; + } } @@ -509,11 +513,7 @@ struct cpu_family *fp, *tmp; int res; - fp = malloc(sizeof(struct cpu_family)); - if (fp == NULL) { - fprintf(stderr, "add_cpu_family(): out of memory\n"); - exit(1); - } + CHECK_ALLOCATION(fp = malloc(sizeof(struct cpu_family))); memset(fp, 0, sizeof(struct cpu_family)); /* @@ -568,43 +568,12 @@ * * Should be called before any other cpu_*() function. * - * TODO: Make this nicer by moving out the conditional stuff to - * an automagically generated file? Or a define in config.h? + * This function calls add_cpu_family() for each processor architecture. + * ADD_ALL_CPU_FAMILIES is defined in the config.h file generated by the + * configure script. */ 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_AVR - add_cpu_family(avr_cpu_family_init, ARCH_AVR); -#endif - -#ifdef ENABLE_M88K - add_cpu_family(m88k_cpu_family_init, ARCH_M88K); -#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); -#endif - -#ifdef ENABLE_SH - add_cpu_family(sh_cpu_family_init, ARCH_SH); -#endif - -#ifdef ENABLE_SPARC - add_cpu_family(sparc_cpu_family_init, ARCH_SPARC); -#endif + ADD_ALL_CPU_FAMILIES; }