--- trunk/src/machine.c 2007/10/08 16:18:22 9 +++ trunk/src/machine.c 2007/10/08 16:18:27 10 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: machine.c,v 1.453 2005/06/12 12:31:54 debug Exp $ + * $Id: machine.c,v 1.470 2005/06/26 11:36:28 debug Exp $ * * Emulation of specific machines. * @@ -83,6 +83,9 @@ #include "hpc_bootinfo.h" #include "vripreg.h" +#define BOOTSTR_BUFLEN 1000 +#define BOOTARG_BUFLEN 2000 +#define ETHERNET_STRING_MAXLEN 40 struct machine_entry_subtype { int machine_subtype;/* Old-style subtype */ @@ -137,10 +140,13 @@ m->name = strdup(name); /* Sane default values: */ - m->serial_nr = 0; + m->serial_nr = 1; m->machine_type = MACHINE_NONE; m->machine_subtype = MACHINE_NONE; +#ifdef BINTRANS m->bintrans_enable = 1; + m->old_bintrans_enable = 1; +#endif m->prom_emulation = 1; m->speed_tricks = 1; m->byte_order_override = NO_BYTE_ORDER_OVERRIDE; @@ -1053,16 +1059,33 @@ * interrupt 2 should be asserted. * * TODO: how should all this be done nicely? - * - * TODO: mace interrupt mask */ uint64_t crime_addr = CRIME_INTSTAT; - uint64_t mace_addr = 0x14; - uint64_t crime_interrupts, crime_interrupts_mask, mace_interrupts; + uint64_t mace_addr = 0x10; + uint64_t crime_interrupts, crime_interrupts_mask; + uint64_t mace_interrupts, mace_interrupt_mask; unsigned int i; unsigned char x[8]; + /* Read current MACE interrupt assertions: */ + memcpy(x, m->md_int.ip32.mace_data->reg + mace_addr, + sizeof(uint64_t)); + mace_interrupts = 0; + for (i=0; imd_int.ip32.mace_data->reg + mace_addr + 8, + sizeof(uint64_t)); + mace_interrupt_mask = 0; + for (i=0; imd_int.ip32.mace_data->reg + mace_addr, sizeof(uint32_t)); - mace_interrupts = 0; - for (i=0; i> (i*8); - memcpy(m->md_int.ip32.mace_data->reg + mace_addr, x, sizeof(uint32_t)); - irq_nr = MACE_PERIPH_SERIAL; - if (mace_interrupts == 0) + if ((mace_interrupts & mace_interrupt_mask) == 0) assrt = 0; else assrt = 1; @@ -1102,37 +1111,28 @@ /* Hopefully _MISC and _SERIAL will not be both on at the same time. */ if (irq_nr & MACE_PERIPH_MISC) { - /* Read current MACE interrupt bits: */ - memcpy(x, m->md_int.ip32.mace_data->reg + mace_addr, sizeof(uint32_t)); - mace_interrupts = 0; - for (i=0; i> (i*8); - memcpy(m->md_int.ip32.mace_data->reg + mace_addr, x, sizeof(uint32_t)); - irq_nr = MACE_PERIPH_MISC; - if (mace_interrupts == 0) + if ((mace_interrupts & mace_interrupt_mask) == 0) assrt = 0; else assrt = 1; } + /* Write back MACE interrupt assertions: */ + for (i=0; i> (i*8); + memcpy(m->md_int.ip32.mace_data->reg + mace_addr, x, sizeof(uint64_t)); + /* Read CRIME_INTSTAT: */ - memcpy(x, m->md_int.ip32.crime_data->reg + crime_addr, sizeof(uint64_t)); + memcpy(x, m->md_int.ip32.crime_data->reg + crime_addr, + sizeof(uint64_t)); crime_interrupts = 0; - for (i=0; i<8; i++) { - /* SGI is big-endian... */ + for (i=0; i> (i*8); - memcpy(m->md_int.ip32.crime_data->reg + crime_addr, x, sizeof(uint64_t)); + memcpy(m->md_int.ip32.crime_data->reg + crime_addr, x, + sizeof(uint64_t)); /* Read CRIME_INTMASK: */ - memcpy(x, m->md_int.ip32.crime_data->reg + CRIME_INTMASK, sizeof(uint64_t)); + memcpy(x, m->md_int.ip32.crime_data->reg + CRIME_INTMASK, + sizeof(uint64_t)); crime_interrupts_mask = 0; - for (i=0; i<8; i++) { + for (i=0; imd_int.malta_data->assert_lo |= mask; + else + m->md_int.malta_data->assert_lo &= ~mask; + } else if (irq_nr < 16) { + if (assrt) + m->md_int.malta_data->assert_hi |= mask; + else + m->md_int.malta_data->assert_hi &= ~mask; + } + + /* Any interrupt assertions on PIC2 go to irq 2 on PIC1 */ + if (m->md_int.malta_data->assert_hi & + ~m->md_int.malta_data->disable_hi) + m->md_int.malta_data->assert_lo |= 0x04; + else + m->md_int.malta_data->assert_lo &= ~0x04; + + /* Now, PIC1: */ + if (m->md_int.malta_data->assert_lo & + ~m->md_int.malta_data->disable_lo) + cpu_interrupt(cpu, 2); + else + cpu_interrupt_ack(cpu, 2); +} + + +/* * x86 (PC) interrupts: * * (irq_nr = 16 can be used to just reassert/deassert interrupts.) @@ -1358,8 +1403,8 @@ case MACHINE_TESTMIPS: /* - * A MIPS test machine (which happens to work with my - * thesis work). + * A MIPS test machine (which happens to work with the + * code in my master's thesis). :-) */ cpu->byte_order = EMUL_BIG_ENDIAN; machine->machine_name = "MIPS test machine"; @@ -1927,14 +1972,14 @@ #if 0 if (machine->machine_subtype == MACHINE_DEC_PMAX_3100) - strcpy(bootpath, "rz(0,0,0)"); + strlcpy(bootpath, "rz(0,0,0)", sizeof(bootpath)); else #endif - strcpy(bootpath, "5/rz1/"); + strlcpy(bootpath, "5/rz1/", sizeof(bootpath)); if (bootdev_id < 0 || machine->force_netboot) { /* tftp boot: */ - strcpy(bootpath, "5/tftp/"); + strlcpy(bootpath, "5/tftp/", sizeof(bootpath)); bootpath[0] = '0' + boot_net_boardnumber; } else { /* disk boot: */ @@ -1948,11 +1993,17 @@ init_bootpath = bootpath; } - bootarg = malloc(strlen(init_bootpath) + - strlen(machine->boot_kernel_filename) + 1 + - strlen(machine->boot_string_argument) + 1); - strcpy(bootarg, init_bootpath); - strcat(bootarg, machine->boot_kernel_filename); + bootarg = malloc(BOOTARG_BUFLEN); + if (bootarg == NULL) { + fprintf(stderr, "out of memory\n"); + exit(1); + } + strlcpy(bootarg, init_bootpath, BOOTARG_BUFLEN); + if (strlcat(bootarg, machine->boot_kernel_filename, + BOOTARG_BUFLEN) > BOOTARG_BUFLEN) { + fprintf(stderr, "bootarg truncated?\n"); + exit(1); + } bootstr = "boot"; @@ -1967,8 +2018,12 @@ cpu->cd.mips.gpr[MIPS_GPR_A0] --; if (machine->boot_string_argument[0] != '\0') { - strcat(bootarg, " "); - strcat(bootarg, machine->boot_string_argument); + strlcat(bootarg, " ", BOOTARG_BUFLEN); + if (strlcat(bootarg, machine->boot_string_argument, + BOOTARG_BUFLEN) >= BOOTARG_BUFLEN) { + fprintf(stderr, "bootstr truncated?\n"); + exit(1); + } } xx.a.common.next = (char *)&xx.b - (char *)&xx; @@ -1977,7 +2032,7 @@ xx.b.common.next = (char *)&xx.c - (char *)&xx.b; xx.b.common.type = BTINFO_BOOTPATH; - strcpy(xx.b.bootpath, bootstr); + strlcpy(xx.b.bootpath, bootstr, sizeof(xx.b.bootpath)); xx.c.common.next = 0; xx.c.common.type = BTINFO_SYMTAB; @@ -2018,25 +2073,28 @@ */ { char tmps[300]; - sprintf(tmps, "cca=%x", + snprintf(tmps, sizeof(tmps), "cca=%x", (int)(DEC_DECCCA_BASEADDR + 0xa0000000ULL)); add_environment_string(cpu, tmps, &addr); } /* These are needed for Sprite to boot: */ { - char tmps[300]; + char tmps[500]; - sprintf(tmps, "boot=%s", bootarg); + snprintf(tmps, sizeof(tmps), "boot=%s", bootarg); + tmps[sizeof(tmps)-1] = '\0'; add_environment_string(cpu, tmps, &addr); - sprintf(tmps, "bitmap=0x%x", (uint32_t)(( + snprintf(tmps, sizeof(tmps), "bitmap=0x%x", (uint32_t)(( DEC_MEMMAP_ADDR + sizeof(memmap.pagesize)) & 0xffffffffULL)); + tmps[sizeof(tmps)-1] = '\0'; add_environment_string(cpu, tmps, &addr); - sprintf(tmps, "bitmaplen=0x%x", + snprintf(tmps, sizeof(tmps), "bitmaplen=0x%x", machine->physical_ram_in_mb * 1048576 / 4096 / 8); + tmps[sizeof(tmps)-1] = '\0'; add_environment_string(cpu, tmps, &addr); } @@ -2095,7 +2153,7 @@ * pciide0 at pci0 dev 9 function 1: VIA Technologies VT82C586 (Apollo VP) ATA33 cr * tlp1 at pci0 dev 12 function 0: DECchip 21143 Ethernet, pass 4.1 */ - pci_data = dev_gt_init(machine, mem, 0x14000000, 2, 6); /* 7 for PCI, not 6? */ + pci_data = dev_gt_init(machine, mem, 0x14000000, 2, 6, 11); /* 7 for PCI, not 6? */ /* bus_pci_add(machine, pci_data, mem, 0, 7, 0, pci_dec21143_init, pci_dec21143_rr); */ bus_pci_add(machine, pci_data, mem, 0, 8, 0, NULL, NULL); /* PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_860 */ bus_pci_add(machine, pci_data, mem, 0, 9, 0, pci_vt82c586_isa_init, pci_vt82c586_isa_rr); @@ -2519,7 +2577,7 @@ exit(1); } - strcpy(tmp, "root=/dev/hda1 crtmode=vesa0,60"); + strlcpy(tmp, "root=/dev/hda1 crtmode=vesa0,60", tmplen); if (machine->boot_string_argument[0]) snprintf(tmp+strlen(tmp), tmplen-strlen(tmp), @@ -2562,7 +2620,7 @@ * detailed list of IP ("Inhouse Processor") model numbers. * (Or http://hardware.majix.org/computers/sgi/iptable.shtml) */ - machine->machine_name = malloc(500); + machine->machine_name = malloc(MACHINE_NAME_MAXBUF); if (machine->machine_name == NULL) { fprintf(stderr, "out of memory\n"); exit(1); @@ -2570,7 +2628,8 @@ if (machine->machine_type == MACHINE_SGI) { cpu->byte_order = EMUL_BIG_ENDIAN; - sprintf(machine->machine_name, "SGI-IP%i", machine->machine_subtype); + snprintf(machine->machine_name, MACHINE_NAME_MAXBUF, + "SGI-IP%i", machine->machine_subtype); sgi_ram_offset = 1048576 * machine->memory_offset_in_mb; @@ -2588,14 +2647,16 @@ } } else { cpu->byte_order = EMUL_LITTLE_ENDIAN; - sprintf(machine->machine_name, "ARC"); + snprintf(machine->machine_name, + MACHINE_NAME_MAXBUF, "ARC"); } if (machine->machine_type == MACHINE_SGI) { /* TODO: Other SGI machine types? */ switch (machine->machine_subtype) { case 12: - strcat(machine->machine_name, " (Iris Indigo IP12)"); + strlcat(machine->machine_name, + " (Iris Indigo IP12)", MACHINE_NAME_MAXBUF); /* TODO */ /* 33 MHz R3000, according to http://www.irisindigo.com/ */ @@ -2603,7 +2664,8 @@ break; case 19: - strcat(machine->machine_name, " (Everest IP19)"); + strlcat(machine->machine_name, + " (Everest IP19)", MACHINE_NAME_MAXBUF); machine->main_console_handle = dev_zs_init(machine, mem, 0x1fbd9830, 0, 1, "serial zs"); /* serial? netbsd? */ dev_scc_init(machine, mem, 0x10086000, 0, machine->use_x11, 0, 8); /* serial? irix? */ @@ -2623,7 +2685,8 @@ break; case 20: - strcat(machine->machine_name, " (Indigo)"); + strlcat(machine->machine_name, + " (Indigo)", MACHINE_NAME_MAXBUF); /* * Guesses based on NetBSD 2.0 beta, 20040606. @@ -2668,7 +2731,8 @@ break; case 21: - strcat(machine->machine_name, " (uknown SGI-IP21 ?)"); /* TODO */ + strlcat(machine->machine_name, /* TODO */ + " (uknown SGI-IP21 ?)", MACHINE_NAME_MAXBUF); /* NOTE: Special case for arc_wordlen: */ arc_wordlen = sizeof(uint64_t); @@ -2678,10 +2742,14 @@ case 22: case 24: if (machine->machine_subtype == 22) { - strcat(machine->machine_name, " (Indy, Indigo2, Challenge S; Full-house)"); + strlcat(machine->machine_name, + " (Indy, Indigo2, Challenge S; Full-house)", + MACHINE_NAME_MAXBUF); machine->md_int.sgi_ip22_data = dev_sgi_ip22_init(machine, mem, 0x1fbd9000, 0); } else { - strcat(machine->machine_name, " (Indy, Indigo2, Challenge S; Guiness)"); + strlcat(machine->machine_name, + " (Indy, Indigo2, Challenge S; Guiness)", + MACHINE_NAME_MAXBUF); machine->md_int.sgi_ip22_data = dev_sgi_ip22_init(machine, mem, 0x1fbd9880, 1); } @@ -2754,7 +2822,8 @@ case 25: /* NOTE: Special case for arc_wordlen: */ arc_wordlen = sizeof(uint64_t); - strcat(machine->machine_name, " (Everest IP25)"); + strlcat(machine->machine_name, + " (Everest IP25)", MACHINE_NAME_MAXBUF); /* serial? irix? */ dev_scc_init(machine, mem, @@ -2775,15 +2844,17 @@ case 26: /* NOTE: Special case for arc_wordlen: */ arc_wordlen = sizeof(uint64_t); - strcat(machine->machine_name, - " (uknown SGI-IP26 ?)"); /* TODO */ + strlcat(machine->machine_name, + " (uknown SGI-IP26 ?)", + MACHINE_NAME_MAXBUF); /* TODO */ machine->main_console_handle = dev_zs_init(machine, mem, 0x1fbd9830, 0, 1, "zs console"); break; case 27: - strcat(machine->machine_name, - " (Origin 200/2000, Onyx2)"); + strlcat(machine->machine_name, + " (Origin 200/2000, Onyx2)", + MACHINE_NAME_MAXBUF); arc_wordlen = sizeof(uint64_t); /* 2 cpus per node */ @@ -2794,7 +2865,8 @@ case 28: /* NOTE: Special case for arc_wordlen: */ arc_wordlen = sizeof(uint64_t); - strcat(machine->machine_name, " (Impact Indigo2 ?)"); + strlcat(machine->machine_name, + " (Impact Indigo2 ?)", MACHINE_NAME_MAXBUF); device_add(machine, "random addr=0x1fbe0000, len=1"); @@ -2804,7 +2876,8 @@ case 30: /* NOTE: Special case for arc_wordlen: */ arc_wordlen = sizeof(uint64_t); - strcat(machine->machine_name, " (Octane)"); + strlcat(machine->machine_name, + " (Octane)", MACHINE_NAME_MAXBUF); machine->md_int.sgi_ip30_data = dev_sgi_ip30_init(machine, mem, 0x0ff00000); machine->md_interrupt = sgi_ip30_interrupt; @@ -2838,7 +2911,8 @@ break; case 32: - strcat(machine->machine_name, " (O2)"); + strlcat(machine->machine_name, + " (O2)", MACHINE_NAME_MAXBUF); /* TODO: Find out where the physical ram is actually located. */ dev_ram_init(mem, 0x07ffff00ULL, 256, DEV_RAM_MIRROR, 0x03ffff00); @@ -2893,22 +2967,25 @@ * intr 7 = MACE_PCI_BRIDGE */ +#if 0 i = dev_pckbc_init(machine, mem, 0x1f320000, PCKBC_8242, 0x200 + MACE_PERIPH_MISC, 0x800 + MACE_PERIPH_MISC, machine->use_x11, 0); /* keyb+mouse (mace irq numbers) */ +#endif net_generate_unique_mac(machine, macaddr); - eaddr_string = malloc(30); + eaddr_string = malloc(ETHERNET_STRING_MAXLEN); if (eaddr_string == NULL) { fprintf(stderr, "out of memory\n"); exit(1); } - sprintf(eaddr_string, "eaddr=%02x:%02x:" - "%02x:%02x:%02x:%02x", + snprintf(eaddr_string, ETHERNET_STRING_MAXLEN, + "eaddr=%02x:%02x:%02x:%02x:%02x:%02x", macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]); - dev_sgi_mec_init(machine, mem, 0x1f280000, MACE_ETHERNET, macaddr); + dev_sgi_mec_init(machine, mem, 0x1f280000, + MACE_ETHERNET, macaddr); dev_sgi_ust_init(mem, 0x1f340000); /* ust? */ @@ -2919,9 +2996,11 @@ (1<<26) + MACE_PERIPH_SERIAL, 0x100, 0, "serial 1"); /* com1 */ +#if 0 if (machine->use_x11) machine->main_console_handle = i; else +#endif machine->main_console_handle = j; dev_mc146818_init(machine, mem, 0x1f3a0000, (1<<8) + MACE_PERIPH_MISC, MC146818_SGI, 0x40); /* mcclock0 */ @@ -2954,7 +3033,8 @@ break; case 35: - strcat(machine->machine_name, " (Origin 3000)"); + strlcat(machine->machine_name, + " (Origin 3000)", MACHINE_NAME_MAXBUF); /* 4 cpus per node */ machine->main_console_handle = @@ -2962,7 +3042,8 @@ 0, 1, "zs console"); break; case 53: - strcat(machine->machine_name, " (Origin 350)"); + strlcat(machine->machine_name, + " (Origin 350)", MACHINE_NAME_MAXBUF); /* * According to http://kumba.drachentekh.net/xml/myguide.html * Origin 350, Tezro IP53 R16000 @@ -2989,13 +3070,17 @@ switch (machine->machine_subtype) { case MACHINE_ARC_NEC_RD94: - strcat(machine->machine_name, " (NEC-RD94, NEC RISCstation 2250)"); + strlcat(machine->machine_name, + " (NEC-RD94, NEC RISCstation 2250)", + MACHINE_NAME_MAXBUF); break; case MACHINE_ARC_NEC_R94: - strcat(machine->machine_name, " (NEC-R94; NEC RISCstation 2200)"); + strlcat(machine->machine_name, " (NEC-R94; NEC RISCstation 2200)", + MACHINE_NAME_MAXBUF); break; case MACHINE_ARC_NEC_R96: - strcat(machine->machine_name, " (NEC-R96; NEC Express RISCserver)"); + strlcat(machine->machine_name, " (NEC-R96; NEC Express RISCserver)", + MACHINE_NAME_MAXBUF); break; } @@ -3049,7 +3134,9 @@ * Parallel at "start: 0x 0 18c10278, length: 0x1000, level: 5, vector: 5" */ - strcat(machine->machine_name, " (NEC-R98; NEC RISCserver 4200)"); + strlcat(machine->machine_name, + " (NEC-R98; NEC RISCserver 4200)", + MACHINE_NAME_MAXBUF); /* * Windows NT access stuff at these addresses: @@ -3105,10 +3192,12 @@ switch (machine->machine_subtype) { case MACHINE_ARC_JAZZ_PICA: - strcat(machine->machine_name, " (Microsoft Jazz, Acer PICA-61)"); + strlcat(machine->machine_name, " (Microsoft Jazz, Acer PICA-61)", + MACHINE_NAME_MAXBUF); break; case MACHINE_ARC_JAZZ_MAGNUM: - strcat(machine->machine_name, " (Microsoft Jazz, MIPS Magnum)"); + strlcat(machine->machine_name, " (Microsoft Jazz, MIPS Magnum)", + MACHINE_NAME_MAXBUF); break; default: fatal("error in machine.c. jazz\n"); @@ -3186,7 +3275,8 @@ * See http://mail-index.netbsd.org/port-arc/2000/10/18/0001.html. */ - strcat(machine->machine_name, " (Microsoft Jazz, Olivetti M700)"); + strlcat(machine->machine_name, " (Microsoft Jazz, Olivetti M700)", + MACHINE_NAME_MAXBUF); machine->md_int.jazz_data = device_add(machine, "jazz addr=0x80000000"); @@ -3224,7 +3314,8 @@ * http://mail-index.netbsd.org/port-arc/2000/10/14/0000.html */ - strcat(machine->machine_name, " (Deskstation Tyne)"); + strlcat(machine->machine_name, " (Deskstation Tyne)", + MACHINE_NAME_MAXBUF); i = dev_ns16550_init(machine, mem, 0x9000003f8ULL, 0, 1, machine->use_x11? 0 : 1, "serial 0"); dev_ns16550_init(machine, mem, 0x9000002f8ULL, 0, 1, 0, "serial 1"); @@ -3300,9 +3391,11 @@ /* TODO: Make this nicer. */ if (machine->machine_type == MACHINE_SGI) { if (machine->machine_subtype == 30) - strcat(init_bootpath, "xio(0)pci(15)"); + strlcat(init_bootpath, "xio(0)pci(15)", + MACHINE_NAME_MAXBUF); if (machine->machine_subtype == 32) - strcat(init_bootpath, "pci(0)"); + strlcat(init_bootpath, "pci(0)", + MACHINE_NAME_MAXBUF); } if (diskimage_is_a_cdrom(machine, bootdev_id, @@ -3316,12 +3409,19 @@ } if (machine->machine_type == MACHINE_ARC) - strcat(init_bootpath, "\\"); + strlcat(init_bootpath, "\\", MACHINE_NAME_MAXBUF); - bootstr = malloc(strlen(init_bootpath) + - strlen(machine->boot_kernel_filename) + 1); - strcpy(bootstr, init_bootpath); - strcat(bootstr, machine->boot_kernel_filename); + bootstr = malloc(BOOTSTR_BUFLEN); + if (bootstr == NULL) { + fprintf(stderr, "out of memory\n"); + exit(1); + } + strlcpy(bootstr, init_bootpath, BOOTSTR_BUFLEN); + if (strlcat(bootstr, machine->boot_kernel_filename, + BOOTSTR_BUFLEN) >= BOOTSTR_BUFLEN) { + fprintf(stderr, "boot string too long?\n"); + exit(1); + } /* Boot args., eg "-a" */ bootarg = machine->boot_string_argument; @@ -3449,8 +3549,9 @@ add_environment_string(cpu, "kernname=unix", &addr); } else { char *tmp; - tmp = malloc(strlen(bootarg) + strlen("OSLOADOPTIONS=") + 2); - sprintf(tmp, "OSLOADOPTIONS=%s", bootarg); + size_t mlen = strlen(bootarg) + strlen("OSLOADOPTIONS=") + 2; + tmp = malloc(mlen); + snprintf(tmp, mlen, "OSLOADOPTIONS=%s", bootarg); store_pointer_and_advance(cpu, &addr2, addr, arc_wordlen==sizeof(uint64_t)); add_environment_string(cpu, tmp, &addr); @@ -3570,15 +3671,40 @@ break; case MACHINE_EVBMIPS: - /* - * http://www.netbsd.org/Ports/evbmips/ - */ + /* http://www.netbsd.org/Ports/evbmips/ */ + cpu->byte_order = EMUL_LITTLE_ENDIAN; + switch (machine->machine_subtype) { case MACHINE_EVBMIPS_MALTA: machine->machine_name = "MALTA (evbmips)"; + + machine->md_int.malta_data = + device_add(machine, "malta addr=0x18000020"); + machine->md_interrupt = malta_interrupt; + + dev_mc146818_init(machine, mem, 0x18000070, + 8 + 8, MC146818_PC_CMOS, 1); + machine->main_console_handle = dev_ns16550_init(machine, mem, + 0x180003f8, 8 + 4, 1, 1, "serial console"); + + /* TODO: Irqs */ + pci_data = dev_gt_init(machine, mem, 0x1be00000, + 8+16, 8+16, 120); + + /* TODO: Haha, this is bogus. Just a cut&paste + from the Cobalt emulation above. */ + bus_pci_add(machine, pci_data, mem, 0, 9, 0, + pci_vt82c586_isa_init, pci_vt82c586_isa_rr); + bus_pci_add(machine, pci_data, mem, 0, 9, 1, + pci_vt82c586_ide_init, pci_vt82c586_ide_rr); + + device_add(machine, "malta_lcd addr=0x1f000400"); break; case MACHINE_EVBMIPS_PB1000: machine->machine_name = "PB1000 (evbmips)"; + machine->md_interrupt = au1x00_interrupt; + machine->md_int.au1x00_ic_data = + dev_au1x00_init(machine, mem); break; default: fatal("Unimplemented EVBMIPS model.\n"); @@ -3586,14 +3712,78 @@ } /* This is just a test. TODO */ - { - int i; - for (i=0; i<32; i++) - cpu->cd.mips.gpr[i] = - 0x01230000 + (i << 8) + 0x55; - } + for (i=0; i<32; i++) + cpu->cd.mips.gpr[i] = + 0x01230000 + (i << 8) + 0x55; - /* TODO: Yamon emulation. 0x9fc00504 = putchar? etc. */ + /* NetBSD/evbmips wants these: (at least for Malta) */ + + /* a0 = argc */ + cpu->cd.mips.gpr[MIPS_GPR_A0] = 2; + + /* a1 = argv */ + cpu->cd.mips.gpr[MIPS_GPR_A1] = (int32_t)0x9fc01000; + store_32bit_word(cpu, (int32_t)0x9fc01000, 0x9fc01040); + store_32bit_word(cpu, (int32_t)0x9fc01004, 0x9fc01200); + + bootstr = strdup(machine->boot_kernel_filename); + bootarg = strdup(machine->boot_string_argument); + store_string(cpu, (int32_t)0x9fc01040, bootstr); + store_string(cpu, (int32_t)0x9fc01200, bootarg); + + /* a2 = (yamon_env_var *)envp */ + cpu->cd.mips.gpr[MIPS_GPR_A2] = 0; + + /* a3 = memsize */ + cpu->cd.mips.gpr[MIPS_GPR_A3] = + machine->physical_ram_in_mb * 1048576; + + /* Yamon emulation vectors at 0x9fc005xx: */ + for (i=0; i<0x100; i+=4) + store_32bit_word(cpu, (int64_t)(int32_t)0x9fc00500 + i, + (int64_t)(int32_t)0x9fc00800 + i); + break; + + case MACHINE_PSP: + /* + * The Playstation Portable seems to be a strange beast. + * + * http://yun.cup.com/psppg004.html (in Japanese) seems to + * suggest that virtual addresses are not displaced by + * 0x80000000 as on normal CPUs, but by 0x40000000? + */ + machine->machine_name = "Playstation Portable"; + cpu->byte_order = EMUL_LITTLE_ENDIAN; + + if (!machine->use_x11 && !quiet_mode) + fprintf(stderr, "-------------------------------------" + "------------------------------------------\n" + "\n WARNING! You are emulating a PSP without -X. " + "You will miss graphical output!\n\n" + "-------------------------------------" + "------------------------------------------\n"); + + /* 480 x 272 pixels framebuffer (512 bytes per line) */ + fb = dev_fb_init(machine, mem, 0x04000000, VFB_HPCMIPS, + 480,272, 512,1088, -15, "Playstation Portable", 0); + + /* + * TODO/NOTE: This is ugly, but necessary since GXemul doesn't + * emulate any MIPS CPU without MMU right now. + */ + mips_coproc_tlb_set_entry(cpu, 0, 1048576*16, + 0x44000000 /*vaddr*/, 0x4000000, 0x4000000 + 1048576*16, + 1,1,1,1,1, 0, 2, 2); + mips_coproc_tlb_set_entry(cpu, 1, 1048576*16, + 0x8000000 /*vaddr*/, 0x0, 0x0 + 1048576*16, + 1,1,1,1,1, 0, 2, 2); + mips_coproc_tlb_set_entry(cpu, 2, 1048576*16, + 0x9000000 /*vaddr*/, 0x01000000, 0x01000000 + 1048576*16, + 1,1,1,1,1, 0, 2, 2); + mips_coproc_tlb_set_entry(cpu, 3, 1048576*16, + 0x0 /*vaddr*/, 0, 0 + 1048576*16, 1,1,1,1,1, 0, 2, 2); + + cpu->cd.mips.gpr[MIPS_GPR_SP] = 0xfff0; break; @@ -3823,7 +4013,11 @@ case MACHINE_TESTARM: machine->machine_name = "ARM test machine"; - /* TODO */ + machine->main_console_handle = dev_cons_init( + machine, mem, DEV_CONS_ADDRESS, "console", 2); + + fb = dev_fb_init(machine, mem, 0x12000000, VFB_GENERIC, + 640,480, 640,480, 24, "generic", 1); break; case MACHINE_BAREX86: @@ -3965,6 +4159,18 @@ case MACHINE_NETGEAR: m->physical_ram_in_mb = 16; break; + case MACHINE_EVBMIPS: + m->physical_ram_in_mb = 64; + break; + case MACHINE_PSP: + /* + * According to + * http://wiki.ps2dev.org/psp:memory_map: + * 0×08000000 = 8 MB kernel memory + * 0×08800000 = 24 MB user memory + */ + m->physical_ram_in_mb = 8 + 24; + break; case MACHINE_ARC: switch (m->machine_subtype) { case MACHINE_ARC_JAZZ_PICA: @@ -4061,18 +4267,6 @@ case MACHINE_SONYNEWS: m->cpu_name = strdup("R3000"); break; - case MACHINE_EVBMIPS: - switch (m->machine_subtype) { - case MACHINE_EVBMIPS_MALTA: - m->cpu_name = strdup("5Kc"); - break; - case MACHINE_EVBMIPS_PB1000: - m->cpu_name = strdup("AU1000"); - break; - default:fatal("Unimpl. evbmips.\n"); - exit(1); - } - break; case MACHINE_HPCMIPS: switch (m->machine_subtype) { case MACHINE_HPCMIPS_CASIO_BE300: @@ -4140,6 +4334,21 @@ if (m->cpu_name == NULL) m->cpu_name = strdup("R4400"); break; + case MACHINE_EVBMIPS: + switch (m->machine_subtype) { + case MACHINE_EVBMIPS_MALTA: + m->cpu_name = strdup("5Kc"); + break; + case MACHINE_EVBMIPS_PB1000: + m->cpu_name = strdup("AU1000"); + break; + default:fatal("Unimpl. evbmips.\n"); + exit(1); + } + break; + case MACHINE_PSP: + m->cpu_name = strdup("Allegrex"); + break; /* PowerPC: */ case MACHINE_BAREPPC: @@ -4608,6 +4817,14 @@ me->next = first_machine_entry; first_machine_entry = me; } + /* Playstation Portable: */ + me = machine_entry_new("Playstation Portable", ARCH_MIPS, + MACHINE_PSP, 1, 0); + me->aliases[0] = "psp"; + if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) { + me->next = first_machine_entry; first_machine_entry = me; + } + /* NetGear: */ me = machine_entry_new("NetGear WG602", ARCH_MIPS, MACHINE_NETGEAR, 2, 0);