--- trunk/src/emul.c 2007/10/08 16:22:11 40 +++ trunk/src/emul.c 2007/10/08 16:22:32 42 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: emul.c,v 1.284 2007/04/19 15:18:15 debug Exp $ + * $Id: emul.c,v 1.297 2007/06/15 17:02:37 debug Exp $ * * Emulation startup and misc. routines. */ @@ -52,8 +52,8 @@ #include "misc.h" #include "net.h" #include "settings.h" -#include "sgi_arcbios.h" #include "timer.h" +#include "useremul.h" #include "x11.h" @@ -68,37 +68,26 @@ extern int old_instruction_trace; extern int old_quiet_mode; extern int quiet_mode; - -extern struct emul *debugger_emul; -extern struct diskimage *diskimages[]; - - -static void print_separator(void) -{ - int i = 79; - while (i-- > 0) - debug("-"); - debug("\n"); -} +extern int native_code_translation_enabled; /* - * add_dump_points(): + * add_breakpoints(): * * Take the strings breakpoint_string[] and convert to addresses * (and store them in breakpoint_addr[]). * * TODO: This function should be moved elsewhere. */ -static void add_dump_points(struct machine *m) +static void add_breakpoints(struct machine *m) { int i; int string_flag; uint64_t dp; - for (i=0; in_breakpoints; i++) { + for (i=0; ibreakpoints.n; i++) { string_flag = 0; - dp = strtoull(m->breakpoint_string[i], NULL, 0); + dp = strtoull(m->breakpoints.string[i], NULL, 0); /* * If conversion resulted in 0, then perhaps it is a @@ -107,12 +96,13 @@ if (dp == 0) { uint64_t addr; int res = get_symbol_addr(&m->symbol_context, - m->breakpoint_string[i], &addr); + m->breakpoints.string[i], &addr); if (!res) { fprintf(stderr, "ERROR! Breakpoint '%s' could not be" " parsed\n", - m->breakpoint_string[i]); + m->breakpoints.string[i]); + exit(1); } else { dp = addr; string_flag = 1; @@ -129,11 +119,11 @@ dp |= 0xffffffff00000000ULL; } - m->breakpoint_addr[i] = dp; + m->breakpoints.addr[i] = dp; debug("breakpoint %i: 0x%llx", i, (long long)dp); if (string_flag) - debug(" (%s)", m->breakpoint_string[i]); + debug(" (%s)", m->breakpoints.string[i]); debug("\n"); } } @@ -156,19 +146,11 @@ struct emul *emul_new(char *name, int id) { struct emul *e; - e = malloc(sizeof(struct emul)); - if (e == NULL) { - fprintf(stderr, "out of memory in emul_new()\n"); - exit(1); - } + CHECK_ALLOCATION(e = malloc(sizeof(struct emul))); memset(e, 0, sizeof(struct emul)); - e->path = malloc(15); - if (e->path == NULL) { - fprintf(stderr, "out of memory\n"); - exit(1); - } + CHECK_ALLOCATION(e->path = malloc(15)); snprintf(e->path, 15, "emul[%i]", id); e->settings = settings_new(); @@ -184,12 +166,7 @@ e->next_serial_nr = 1; if (name != NULL) { - e->name = strdup(name); - if (e->name == NULL) { - fprintf(stderr, "out of memory in emul_new()\n"); - exit(1); - } - + CHECK_ALLOCATION(e->name = strdup(name)); settings_add(e->settings, "name", 0, SETTINGS_TYPE_STRING, SETTINGS_FORMAT_STRING, (void *) &e->name); @@ -244,15 +221,10 @@ m = machine_new(name, e, e->n_machines); m->serial_nr = (e->next_serial_nr ++); - i = e->n_machines; + i = e->n_machines ++; - e->n_machines ++; - e->machines = realloc(e->machines, - sizeof(struct machine *) * e->n_machines); - if (e->machines == NULL) { - fprintf(stderr, "emul_add_machine(): out of memory\n"); - exit(1); - } + CHECK_ALLOCATION(e->machines = realloc(e->machines, + sizeof(struct machine *) * e->n_machines)); e->machines[i] = m; @@ -447,20 +419,11 @@ /* TODO: This should be moved elsewhere... */ if (m->machine_type == MACHINE_BEBOX) m->ncpus = 2; - else if (m->machine_type == MACHINE_ARC && - m->machine_subtype == MACHINE_ARC_NEC_R96) - m->ncpus = 2; - else if (m->machine_type == MACHINE_ARC && - m->machine_subtype == MACHINE_ARC_NEC_R98) - m->ncpus = 4; else m->ncpus = 1; } - m->cpus = malloc(sizeof(struct cpu *) * m->ncpus); - if (m->cpus == NULL) { - fprintf(stderr, "out of memory\n"); - exit(1); - } + + CHECK_ALLOCATION(m->cpus = malloc(sizeof(struct cpu *) * m->ncpus)); memset(m->cpus, 0, sizeof(struct cpu *) * m->ncpus); debug("cpu0"); @@ -477,18 +440,6 @@ } debug("\n"); -#if 0 - /* Special case: The Playstation Portable has an additional CPU: */ - if (m->machine_type == MACHINE_PSP) { - debug("cpu%i: ", m->ncpus); - m->cpus[m->ncpus] = cpu_new(m->memory, m, - 0 /* use 0 here to show info with debug() */, - "Allegrex" /* TODO */); - debug("\n"); - m->ncpus ++; - } -#endif - if (m->use_random_bootstrap_cpu) m->bootstrap_cpu = random() % m->ncpus; else @@ -502,16 +453,17 @@ m->userland_emul, NULL, NULL, NULL); switch (m->arch) { -#ifdef ENABLE_ALPHA + case ARCH_ALPHA: cpu->memory_rw = alpha_userland_memory_rw; break; -#endif - default:cpu->memory_rw = userland_memory_rw; + + default: + cpu->memory_rw = userland_memory_rw; } } - if (m->use_x11) + if (m->x11_md.in_use) x11_init(m); /* Fill memory with random bytes: */ @@ -580,8 +532,11 @@ fread(buf, 1, sizeof(buf), tmp_f); if (buf[0]==0x1f && buf[1]==0x8b) { size_t zzlen = strlen(name_to_load)*2 + 100; - char *zz = malloc(zzlen); + char *zz; + + CHECK_ALLOCATION(zz = malloc(zzlen)); debug("gunziping %s\n", name_to_load); + /* * gzip header found. If this was a file * extracted from, say, a CDROM image, then it @@ -598,8 +553,9 @@ } else { /* gunzip into new temp file: */ int tmpfile_handle; - char *new_temp_name = - strdup("/tmp/gxemul.XXXXXXXXXXXX"); + char *new_temp_name; + CHECK_ALLOCATION(new_temp_name = + strdup("/tmp/gxemul.XXXXXXXXXXXX")); tmpfile_handle = mkstemp(new_temp_name); close(tmpfile_handle); snprintf(zz, zzlen, "gunzip -c '%s' > " @@ -613,48 +569,6 @@ fclose(tmp_f); } - /* - * Ugly (but usable) hack for Playstation Portable: If the - * filename ends with ".pbp" and the file contains an ELF - * header, then extract the ELF file into a temporary file. - */ - if (strlen(name_to_load) > 4 && strcasecmp(name_to_load + - strlen(name_to_load) - 4, ".pbp") == 0 && - (tmp_f = fopen(name_to_load, "r")) != NULL) { - off_t filesize, j, found=0; - unsigned char *buf; - fseek(tmp_f, 0, SEEK_END); - filesize = ftello(tmp_f); - fseek(tmp_f, 0, SEEK_SET); - buf = malloc(filesize); - if (buf == NULL) { - fprintf(stderr, "out of memory while trying" - " to read %s\n", name_to_load); - exit(1); - } - fread(buf, 1, filesize, tmp_f); - fclose(tmp_f); - /* Search for the ELF header, from offset 1 (!): */ - for (j=1; jpc &= 0xfffffffc; break; - case ARCH_AVR: - cpu->pc &= 0xfffff; - if (cpu->pc & 1) { - fatal("AVR: lowest bit of pc set: TODO\n"); + case ARCH_M88K: + if (cpu->pc & 3) { + fatal("M88K: lowest bits of pc set: TODO\n"); exit(1); } - break; - - case ARCH_M88K: + cpu->pc &= 0xfffffffc; break; case ARCH_MIPS: @@ -772,8 +683,8 @@ m->cpus[i]->running = 0; } - /* Add PC dump points: */ - add_dump_points(m); + /* Parse and add breakpoints: */ + add_breakpoints(m); /* TODO: This is MIPS-specific! */ if (m->machine_type == MACHINE_PMAX && @@ -796,11 +707,6 @@ debug("0x%08"PRIx32, (uint32_t) entrypoint); break; - case ARCH_AVR: - /* Atmel AVR uses a 16-bit or 22-bit program counter: */ - debug("0x%04x", (int) entrypoint); - break; - case ARCH_MIPS: if (cpu->is_32bit) { debug("0x%08"PRIx32, (uint32_t) @@ -955,7 +861,7 @@ if (emul->n_debugger_cmds > 0) { int j; if (i == 0) - print_separator(); + print_separator_line(); for (j = 0; j < emul->n_debugger_cmds; j ++) { debug("> %s\n", emul->debugger_cmds[j]); debugger_execute_cmd(emul->debugger_cmds[j], @@ -964,7 +870,7 @@ } } - print_separator(); + print_separator_line(); debug("\n"); @@ -1006,29 +912,27 @@ /* * MAIN LOOP: * - * Run all emulations in parallel, running each machine in - * each emulation. + * Run all emulations in parallel, running instructions from each + * cpu in each machine in each emulation. */ while (go) { + struct cpu *bootcpu = emuls[0]->machines[0]->cpus[ + emuls[0]->machines[0]->bootstrap_cpu]; + go = 0; /* Flush X11 and serial console output every now and then: */ - if (emuls[0]->machines[0]->ninstrs > - emuls[0]->machines[0]->ninstrs_flush + (1<<19)) { + if (bootcpu->ninstrs > bootcpu->ninstrs_flush + (1<<19)) { x11_check_event(emuls, n_emuls); console_flush(); - emuls[0]->machines[0]->ninstrs_flush = - emuls[0]->machines[0]->ninstrs; + bootcpu->ninstrs_flush = bootcpu->ninstrs; } - if (emuls[0]->machines[0]->ninstrs > - emuls[0]->machines[0]->ninstrs_show + (1<<25)) { - emuls[0]->machines[0]->ninstrs_since_gettimeofday += - (emuls[0]->machines[0]->ninstrs - - emuls[0]->machines[0]->ninstrs_show); + if (bootcpu->ninstrs > bootcpu->ninstrs_show + (1<<25)) { + bootcpu->ninstrs_since_gettimeofday += + (bootcpu->ninstrs - bootcpu->ninstrs_show); cpu_show_cycles(emuls[0]->machines[0], 0); - emuls[0]->machines[0]->ninstrs_show = - emuls[0]->machines[0]->ninstrs; + bootcpu->ninstrs_show = bootcpu->ninstrs; } if (single_step == ENTER_SINGLE_STEPPING) { @@ -1081,7 +985,7 @@ n = 0; for (i=0; in_machines; j++) - if (emuls[i]->machines[j]->use_x11) + if (emuls[i]->machines[j]->x11_md.in_use) n++; if (n > 0) { printf("Press enter to quit.\n");