--- trunk/src/emul.c 2007/10/08 16:20:40 30 +++ trunk/src/emul.c 2007/10/08 16:20:58 32 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: emul.c,v 1.260 2006/07/26 23:21:47 debug Exp $ + * $Id: emul.c,v 1.272 2006/10/31 08:26:56 debug Exp $ * * Emulation startup and misc. routines. */ @@ -51,7 +51,9 @@ #include "mips_cpu_types.h" #include "misc.h" #include "net.h" +#include "settings.h" #include "sgi_arcbios.h" +#include "timer.h" #include "x11.h" @@ -144,7 +146,7 @@ */ static void fix_console(void) { - console_deinit(); + console_deinit_main(); } @@ -563,9 +565,18 @@ /* Convert loadaddr to uncached: */ if ((bootblock_loadaddr & 0xf0000000ULL) != 0x80000000 && - (bootblock_loadaddr & 0xf0000000ULL) != 0xa0000000) - fatal("\nWARNING! Weird load address 0x%08x.\n\n", - (int)bootblock_loadaddr); + (bootblock_loadaddr & 0xf0000000ULL) != 0xa0000000) { + fatal("\nWARNING! Weird load address 0x%08"PRIx32 + " for SCSI id %i.\n\n", + (uint32_t)bootblock_loadaddr, boot_disk_id); + if (bootblock_loadaddr == 0) { + fatal("I'm assuming that this is _not_ a " + "DEC bootblock.\nAre you sure you are" + " booting from the correct disk?\n"); + exit(1); + } + } + bootblock_loadaddr &= 0x0fffffffULL; bootblock_loadaddr |= 0xffffffffa0000000ULL; @@ -690,8 +701,10 @@ iso_type = 3; if (iso_type != 0) { - /* We can't load a kernel if the name - isn't specified. */ + /* + * If the user specified a kernel name, then load it from + * disk. + */ if (cpu->machine->boot_kernel_filename == NULL || cpu->machine->boot_kernel_filename[0] == '\0') fatal("\nISO9660 filesystem, but no kernel " @@ -714,8 +727,6 @@ } if (bootblock_buf[0x000] == 'E' && bootblock_buf[0x001] == 'R' && bootblock_buf[0x200] == 'P' && bootblock_buf[0x201] == 'M') { - /* We can't load a kernel if the name - isn't specified. */ if (cpu->machine->boot_kernel_filename == NULL || cpu->machine->boot_kernel_filename[0] == '\0') fatal("\nApple partition table, but no kernel " @@ -747,6 +758,14 @@ memset(e, 0, sizeof(struct emul)); + e->settings = settings_new(); + + settings_add(e->settings, "n_machines", 0, + SETTINGS_TYPE_INT, SETTINGS_FORMAT_DECIMAL, + (void *) &e->n_machines); + + /* TODO: More settings? */ + /* Sane default values: */ e->n_machines = 0; e->next_serial_nr = 1; @@ -757,6 +776,10 @@ fprintf(stderr, "out of memory in emul_new()\n"); exit(1); } + + settings_add(e->settings, "name", 0, + SETTINGS_TYPE_STRING, SETTINGS_FORMAT_STRING, + (void *) &e->name); } return e; @@ -764,6 +787,34 @@ /* + * emul_destroy(): + * + * Destroys a previously created emul object. + */ +void emul_destroy(struct emul *emul) +{ + int i; + + if (emul->name != NULL) { + settings_remove(emul->settings, "name"); + free(emul->name); + } + + for (i=0; in_machines; i++) + machine_destroy(emul->machines[i]); + + if (emul->machines != NULL) + free(emul->machines); + + /* Remove any remaining level-1 settings: */ + settings_remove_all(emul->settings); + settings_destroy(emul->settings); + + free(emul); +} + + +/* * emul_add_machine(): * * Calls machine_new(), adds the new machine into the emul struct, and @@ -774,10 +825,14 @@ struct machine *emul_add_machine(struct emul *e, char *name) { struct machine *m; + char tmpstr[20]; + int i; m = machine_new(name, e); m->serial_nr = (e->next_serial_nr ++); + i = e->n_machines; + e->n_machines ++; e->machines = realloc(e->machines, sizeof(struct machine *) * e->n_machines); @@ -786,7 +841,12 @@ exit(1); } - e->machines[e->n_machines - 1] = m; + e->machines[i] = m; + + snprintf(tmpstr, sizeof(tmpstr), "machine[%i]", i); + settings_add(e->settings, tmpstr, 1, SETTINGS_TYPE_SUBSETTINGS, 0, + e->machines[i]->settings); + return m; } @@ -1237,6 +1297,18 @@ } break; + case ARCH_AVR32: + cpu->pc = (uint32_t) cpu->pc; + if (cpu->pc & 1) { + fatal("AVR32: lowest bit of pc set: TODO\n"); + exit(1); + } + break; + + case ARCH_RCA180X: + cpu->pc &= 0xffff; + break; + case ARCH_HPPA: break; @@ -1466,7 +1538,9 @@ /* Create a simple network: */ emul->net = net_init(emul, NET_INIT_FLAG_GATEWAY, - "10.0.0.0", 8, NULL, 0, 0); + NET_DEFAULT_IPV4_MASK, + NET_DEFAULT_IPV4_LEN, + NULL, 0, 0, NULL); } else { /* Userland pseudo-machine: */ debug("Syscall emulation (userland-only) setup...\n"); @@ -1575,6 +1649,9 @@ cpu_functioncall_trace(emuls[0]->machines[0]->cpus[0], emuls[0]->machines[0]->cpus[0]->pc); + /* Start emulated clocks: */ + timer_start(); + /* * MAIN LOOP: * @@ -1619,18 +1696,24 @@ if (single_step == SINGLE_STEPPING) debugger(); - e = emuls[0]; /* Note: Only 1 emul supported now. */ + for (i=0; in_machines; j++) { - if (e->machines[j]->gdb.port > 0) - debugger_gdb_check_incoming(e->machines[j]); - - anything = machine_run(e->machines[j]); - if (anything) - go = 1; + for (j=0; jn_machines; j++) { + if (e->machines[j]->gdb.port > 0) + debugger_gdb_check_incoming( + e->machines[j]); + + anything = machine_run(e->machines[j]); + if (anything) + go = 1; + } } } + /* Stop any running timers: */ + timer_stop(); + /* Deinitialize all CPUs in all machines in all emulations: */ for (i=0; in_machines; j++) @@ -1657,11 +1740,11 @@ printf("Press enter to quit.\n"); while (!console_charavail(MAIN_CONSOLE)) { x11_check_event(emuls, n_emuls); - usleep(1); + usleep(10000); } console_readchar(MAIN_CONSOLE); } - console_deinit(); + console_deinit_main(); }