--- trunk/src/machine.c 2007/10/08 16:19:16 19 +++ trunk/src/machine.c 2007/10/08 16:19:23 20 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: machine.c,v 1.577 2005/10/27 14:01:12 debug Exp $ + * $Id: machine.c,v 1.611 2005/11/23 23:31:34 debug Exp $ * * Emulation of specific machines. * @@ -51,6 +51,7 @@ #include #include "arcbios.h" +#include "bus_isa.h" #include "bus_pci.h" #include "cpu.h" #include "device.h" @@ -165,6 +166,7 @@ m->boot_string_argument = NULL; m->automatic_clock_adjustment = 1; m->x11_scaledown = 1; + m->x11_scaleup = 1; m->n_gfx_cards = 1; m->dbe_on_nonexistant_memaccess = 1; m->show_symbolic_register_names = 1; @@ -1293,62 +1295,39 @@ /* - * Malta (evbmips) interrupts: + * CPC700 interrupt routine: * - * ISA interrupts. - * (irq_nr = 16+8 can be used to just reassert/deassert interrupts.) + * irq_nr should be 0..31. (32 means reassertion.) */ -void malta_interrupt(struct machine *m, struct cpu *cpu, int irq_nr, - int assrt) +void cpc700_interrupt(struct machine *m, struct cpu *cpu, + int irq_nr, int assrt) { - int mask; - - irq_nr -= 8; - mask = 1 << (irq_nr & 7); - - if (irq_nr < 8) { - if (assrt) - m->isa_pic_data.pic1->irr |= mask; - else - m->isa_pic_data.pic1->irr &= ~mask; - } else if (irq_nr < 16) { + if (irq_nr < 32) { + uint32_t mask = 1 << (irq_nr & 31); if (assrt) - m->isa_pic_data.pic2->irr |= mask; + m->md_int.cpc700_data->sr |= mask; else - m->isa_pic_data.pic2->irr &= ~mask; + m->md_int.cpc700_data->sr &= ~mask; } - /* Any interrupt assertions on PIC2 go to irq 2 on PIC1 */ - /* (TODO: don't hardcode this here) */ - if (m->isa_pic_data.pic2->irr & - ~m->isa_pic_data.pic2->ier) - m->isa_pic_data.pic1->irr |= 0x04; - else - m->isa_pic_data.pic1->irr &= ~0x04; - - /* Now, PIC1: */ - if (m->isa_pic_data.pic1->irr & - ~m->isa_pic_data.pic1->ier) - cpu_interrupt(cpu, 2); + if ((m->md_int.cpc700_data->sr & m->md_int.cpc700_data->er) != 0) + cpu_interrupt(cpu, 65); else - cpu_interrupt_ack(cpu, 2); - - /* printf("MALTA: pic1.irr=0x%02x ier=0x%02x pic2.irr=0x%02x " - "ier=0x%02x\n", m->isa_pic_data.pic1->irr, - m->isa_pic_data.pic1->ier, - m->isa_pic_data.pic2->irr, - m->isa_pic_data.pic2->ier); */ + cpu_interrupt_ack(cpu, 65); } /* - * Cobalt interrupts: + * Interrupt function for Cobalt, evbmips (Malta), and Algor. * * (irq_nr = 8 + 16 can be used to just reassert/deassert interrupts.) */ -void cobalt_interrupt(struct machine *m, struct cpu *cpu, int irq_nr, int assrt) +void isa8_interrupt(struct machine *m, struct cpu *cpu, int irq_nr, int assrt) { - int mask; + int mask, x; + int old_isa_assert, new_isa_assert; + + old_isa_assert = m->isa_pic_data.pic1->irr & ~m->isa_pic_data.pic1->ier; irq_nr -= 8; mask = 1 << (irq_nr & 7); @@ -1367,24 +1346,31 @@ /* Any interrupt assertions on PIC2 go to irq 2 on PIC1 */ /* (TODO: don't hardcode this here) */ - if (m->isa_pic_data.pic2->irr & - ~m->isa_pic_data.pic2->ier) + if (m->isa_pic_data.pic2->irr & ~m->isa_pic_data.pic2->ier) m->isa_pic_data.pic1->irr |= 0x04; else m->isa_pic_data.pic1->irr &= ~0x04; /* Now, PIC1: */ - if (m->isa_pic_data.pic1->irr & - ~m->isa_pic_data.pic1->ier) - cpu_interrupt(cpu, 6); - else - cpu_interrupt_ack(cpu, 6); + new_isa_assert = m->isa_pic_data.pic1->irr & ~m->isa_pic_data.pic1->ier; + if (old_isa_assert != new_isa_assert) { + for (x=0; x<16; x++) { + if (x == 2) + continue; + if (x < 8 && (m->isa_pic_data.pic1->irr & + ~m->isa_pic_data.pic1->ier & (1 << x))) + break; + if (x >= 8 && (m->isa_pic_data.pic2->irr & + ~m->isa_pic_data.pic2->ier & (1 << (x&7)))) + break; + } + m->isa_pic_data.last_int = x; + } - /* printf("COBALT: pic1.irr=0x%02x ier=0x%02x pic2.irr=0x%02x " - "ier=0x%02x\n", m->isa_pic_data.pic1->irr, - m->isa_pic_data.pic1->ier, - m->isa_pic_data.pic2->irr, - m->isa_pic_data.pic2->ier); */ + if (m->isa_pic_data.pic1->irr & ~m->isa_pic_data.pic1->ier) + cpu_interrupt(cpu, m->isa_pic_data.native_irq); + else + cpu_interrupt_ack(cpu, m->isa_pic_data.native_irq); } @@ -1432,18 +1418,19 @@ /* - * Footbridge interrupts: + * "Generic" ISA interrupt management, 32 native interrupts, 16 ISA + * interrupts. So far: Footbridge (CATS, NetWinder), BeBox, and PReP. * * 0..31 = footbridge interrupt - * 32..47 = ISA (connected to IRQ_IN_L2 on CATS, L3 on NetWinder) - * 64 = reassert + * 32..47 = ISA interrupts + * 48 = ISA reassert + * 64 = reassert (non-ISA) */ -void footbridge_interrupt(struct machine *m, struct cpu *cpu, int irq_nr, +void isa32_interrupt(struct machine *m, struct cpu *cpu, int irq_nr, int assrt) { uint32_t mask = 1 << (irq_nr & 31); int old_isa_assert, new_isa_assert; - int isa_int = m->machine_type == MACHINE_CATS? 10 : 11; old_isa_assert = m->isa_pic_data.pic1->irr & ~m->isa_pic_data.pic1->ier; @@ -1470,26 +1457,73 @@ /* Now, PIC1: */ new_isa_assert = m->isa_pic_data.pic1->irr & ~m->isa_pic_data.pic1->ier; - if (old_isa_assert != new_isa_assert) { - if (new_isa_assert) - cpu_interrupt(cpu, isa_int); - else - cpu_interrupt_ack(cpu, isa_int); + if (old_isa_assert != new_isa_assert || irq_nr == 48) { + if (new_isa_assert) { + int x; + for (x=0; x<16; x++) { + if (x == 2) + continue; + if (x < 8 && (m->isa_pic_data.pic1->irr & + ~m->isa_pic_data.pic1->ier & (1 << x))) + break; + if (x >= 8 && (m->isa_pic_data.pic2->irr & + ~m->isa_pic_data.pic2->ier & (1 << (x&7)))) + break; + } + m->isa_pic_data.last_int = x; + cpu_interrupt(cpu, m->isa_pic_data.native_irq); + } else + cpu_interrupt_ack(cpu, m->isa_pic_data.native_irq); return; } - if (irq_nr < 32) { - if (assrt) - m->md_int.footbridge_data->irq_status |= mask; + switch (m->machine_type) { + case MACHINE_CATS: + case MACHINE_NETWINDER: + if (irq_nr < 32) { + if (assrt) + m->md_int.footbridge_data->irq_status |= mask; + else + m->md_int.footbridge_data->irq_status &= ~mask; + } + if (m->md_int.footbridge_data->irq_status & + m->md_int.footbridge_data->irq_enable) + cpu_interrupt(cpu, 65); + else + cpu_interrupt_ack(cpu, 65); + break; + case MACHINE_BEBOX: + if (irq_nr < 32) { + if (assrt) + m->md_int.bebox_data->int_status |= mask; + else + m->md_int.bebox_data->int_status &= ~mask; + } + if (m->md_int.bebox_data->int_status & + m->md_int.bebox_data->cpu0_int_mask) + cpu_interrupt(m->cpus[0], 65); + else + cpu_interrupt_ack(m->cpus[0], 65); + if (m->ncpus > 1 && + m->md_int.bebox_data->int_status & + m->md_int.bebox_data->cpu1_int_mask) + cpu_interrupt(m->cpus[1], 65); else - m->md_int.footbridge_data->irq_status &= ~mask; + cpu_interrupt_ack(m->cpus[1], 65); + break; + case MACHINE_PREP: + if (irq_nr < 32) { + if (assrt) + m->md_int.prep_data->int_status |= mask; + else + m->md_int.prep_data->int_status &= ~mask; + } + if (m->md_int.prep_data->int_status & 2) + cpu_interrupt(cpu, 65); + else + cpu_interrupt_ack(cpu, 65); + break; } - - if (m->md_int.footbridge_data->irq_status & - m->md_int.footbridge_data->irq_enable) - cpu_interrupt(cpu, 65); - else - cpu_interrupt_ack(cpu, 65); } @@ -2363,13 +2397,16 @@ machine->isa_pic_data.pic1 = device_add(machine, tmpstr); snprintf(tmpstr, sizeof(tmpstr), "8259 irq=24 addr=0x100000a0"); machine->isa_pic_data.pic2 = device_add(machine, tmpstr); - machine->md_interrupt = cobalt_interrupt; + machine->md_interrupt = isa8_interrupt; + machine->isa_pic_data.native_irq = 6; dev_mc146818_init(machine, mem, 0x10000070, 0, MC146818_PC_CMOS, 4); machine->main_console_handle = (size_t) device_add(machine, "ns16550 irq=5 addr=0x1c800000 name2=tty0 in_use=1"); + /* TODO: bus_isa() ? */ + #if 0 device_add(machine, "ns16550 irq=0 addr=0x1f000010 name2=tty1 in_use=0"); #endif @@ -2387,11 +2424,11 @@ * The PCI controller interrupts at ISA interrupt 9. */ pci_data = dev_gt_init(machine, mem, 0x14000000, 2, 8 + 9, 11); - /* 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); - bus_pci_add(machine, pci_data, mem, 0, 9, 1, pci_vt82c586_ide_init, pci_vt82c586_ide_rr); - /* bus_pci_add(machine, pci_data, mem, 0, 12, 0, pci_dec21143_init, pci_dec21143_rr); */ + bus_pci_add(machine, pci_data, mem, 0, 7, 0, "dec21143"); + /* bus_pci_add(machine, pci_data, mem, 0, 8, 0, "symbios_860"); PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_860 */ + bus_pci_add(machine, pci_data, mem, 0, 9, 0, "vt82c586_isa"); + bus_pci_add(machine, pci_data, mem, 0, 9, 1, "vt82c586_ide"); + /* bus_pci_add(machine, pci_data, mem, 0, 12, 0, "dec21143"); */ if (machine->prom_emulation) { /* @@ -3223,7 +3260,7 @@ */ pci_data = dev_macepci_init(mem, 0x1f080000, MACE_PCI_BRIDGE); /* macepci0 */ - /* bus_pci_add(machine, pci_data, mem, 0, 0, 0, pci_ne2000_init, pci_ne2000_rr); TODO */ + /* bus_pci_add(machine, pci_data, mem, 0, 0, 0, "ne2000"); TODO */ /* TODO: make this nicer */ if (diskimage_exist(machine, 0, DISKIMAGE_SCSI) || @@ -3234,10 +3271,10 @@ diskimage_exist(machine, 5, DISKIMAGE_SCSI) || diskimage_exist(machine, 6, DISKIMAGE_SCSI) || diskimage_exist(machine, 7, DISKIMAGE_SCSI)) - bus_pci_add(machine, pci_data, mem, 0, 1, 0, pci_ahc_init, pci_ahc_rr); + bus_pci_add(machine, pci_data, mem, 0, 1, 0, "ahc"); /* TODO: second ahc */ - /* bus_pci_add(machine, pci_data, mem, 0, 2, 0, pci_ahc_init, pci_ahc_rr); */ + /* bus_pci_add(machine, pci_data, mem, 0, 2, 0, "ahc"); */ break; case 35: @@ -3319,7 +3356,7 @@ case MACHINE_ARC_NEC_RD94: case MACHINE_ARC_NEC_R94: /* PCI devices: (NOTE: bus must be 0, device must be 3, 4, or 5, for NetBSD to accept interrupts) */ - bus_pci_add(machine, pci_data, mem, 0, 3, 0, pci_dec21030_init, pci_dec21030_rr); /* tga graphics */ + bus_pci_add(machine, pci_data, mem, 0, 3, 0, "dec21030"); /* tga graphics */ break; case MACHINE_ARC_NEC_R96: dev_fb_init(machine, mem, 0x100e00000ULL, @@ -3893,28 +3930,25 @@ cpu->byte_order = EMUL_BIG_ENDIAN; } - /* ISA interrupt controllers: */ - snprintf(tmpstr, sizeof(tmpstr), "8259 irq=24 addr=0x18000020"); - machine->isa_pic_data.pic1 = device_add(machine, tmpstr); - snprintf(tmpstr, sizeof(tmpstr), "8259 irq=24 addr=0x180000a0"); - machine->isa_pic_data.pic2 = device_add(machine, tmpstr); - machine->md_interrupt = malta_interrupt; - - dev_mc146818_init(machine, mem, 0x18000070, 8 + 8, MC146818_PC_CMOS, 1); - - machine->main_console_handle = (size_t) - device_add(machine, "ns16550 irq=12 addr=0x180003f8 name2=tty0"); - device_add(machine, "ns16550 irq=11 addr=0x180002f8 name2=tty1"); + machine->md_interrupt = isa8_interrupt; + machine->isa_pic_data.native_irq = 2; + + bus_isa(machine, 0, 0x18000000, 0x10000000, 8, 24); snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=4 addr=0x%x name2=tty2", MALTA_CBUSUART); device_add(machine, tmpstr); - /* TODO: Irqs */ + pci_data = dev_gt_init(machine, mem, 0x1be00000, 8+9, 8+9, 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); + if (machine->use_x11) { + if (strlen(machine->boot_string_argument) < 3) + fatal("WARNING: remember to use -o 'console=tty0' " + "if you are emulating Linux. (Not needed for NetBSD.)\n"); + bus_pci_add(machine, pci_data, mem, 0xc0, 8, 0, "s3_virge"); + } + + bus_pci_add(machine, pci_data, mem, 0, 9, 0, "i82371ab_isa"); + bus_pci_add(machine, pci_data, mem, 0, 9, 1, "i82371ab_ide"); device_add(machine, "malta_lcd addr=0x1f000400"); break; @@ -3932,11 +3966,6 @@ } if (machine->prom_emulation) { - /* This is just a test. TODO */ - for (i=0; i<32; i++) - cpu->cd.mips.gpr[i] = - 0x01230000 + (i << 8) + 0x55; - /* NetBSD/evbmips wants these: (at least for Malta) */ /* a0 = argc */ @@ -4037,6 +4066,59 @@ cpu->cd.mips.gpr[MIPS_GPR_SP] = 0xfff0; break; + + case MACHINE_ALGOR: + switch (machine->machine_subtype) { + case MACHINE_ALGOR_P4032: + machine->machine_name = "\"Algor\" P4032"; + break; + case MACHINE_ALGOR_P5064: + machine->machine_name = "\"Algor\" P5064"; + break; + default:fatal("Unimplemented Algor machine.\n"); + exit(1); + } + + machine->md_interrupt = isa8_interrupt; + machine->isa_pic_data.native_irq = 6; + + /* TODO: correct isa irq? 6 is just a bogus guess */ + + bus_isa(machine, 0, 0x1d000000, 0xc0000000, 8, 24); + + if (machine->prom_emulation) { + /* NetBSD/algor wants these: */ + + /* 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); + store_32bit_word(cpu, (int32_t)0x9fc01008, 0); + + 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] = (int32_t)0x9fc01800; + { + char tmps[50]; + + store_32bit_word(cpu, (int32_t)0x9fc01800, 0x9fc01900); + store_32bit_word(cpu, (int32_t)0x9fc01804, 0x9fc01a00); + store_32bit_word(cpu, (int32_t)0x9fc01808, 0); + + snprintf(tmps, sizeof(tmps), "memsize=0x%08x", + machine->physical_ram_in_mb * 1048576); + store_string(cpu, (int)0x9fc01900, tmps); + store_string(cpu, (int)0x9fc01a00, "ethaddr=10:20:30:30:20:10"); + } + } + break; #endif /* ENABLE_MIPS */ #ifdef ENABLE_PPC @@ -4084,6 +4166,11 @@ */ machine->machine_name = "Walnut evaluation board"; + /* "OpenBIOS" entrypoint (?): */ + dev_ram_init(machine, 0xfffe0b50, 8, DEV_RAM_RAM, 0); + store_32bit_word(cpu, 0xfffe0b50, 0xfffe0b54); + store_32bit_word(cpu, 0xfffe0b54, 0x4e800020); /* blr */ + break; case MACHINE_PMPPC: @@ -4091,13 +4178,19 @@ * NetBSD/pmppc (http://www.netbsd.org/Ports/pmppc/) */ machine->machine_name = "Artesyn's PM/PPC board"; + machine->emulated_hz = 10000000; dev_pmppc_init(mem); - /* com0 = 0xff600300, com1 = 0xff600400 */ + machine->md_int.cpc700_data = dev_cpc700_init(machine, mem); + machine->md_interrupt = cpc700_interrupt; - machine->main_console_handle = (size_t)device_add(machine, "ns16550 irq=0 addr=0xff600300 name2=tty0"); - device_add(machine, "ns16550 irq=0 addr=0xff600400 in_use=0 name2=tty1"); + /* RTC at "ext int 5" = "int 25" in IBM jargon, int + 31-25 = 6 for the rest of us. */ + dev_mc146818_init(machine, mem, 0x7ff00000, 31-25, MC146818_PMPPC, 1); + + bus_pci_add(machine, machine->md_int.cpc700_data->pci_data, + mem, 0, 8, 0, "dec21143"); break; @@ -4107,12 +4200,8 @@ */ machine->machine_name = "Motorola Sandpoint"; - { - int i; - for (i=0; i<32; i++) - cpu->cd.ppc.gpr[i] = - 0x12340000 + (i << 8) + 0x55; - } + /* r4 should point to first free byte after the loaded kernel: */ + cpu->cd.ppc.gpr[4] = 6 * 1048576; break; @@ -4122,22 +4211,23 @@ */ machine->machine_name = "BeBox"; - device_add(machine, "bebox"); + machine->md_int.bebox_data = device_add(machine, "bebox"); + machine->isa_pic_data.native_irq = 5; + machine->md_interrupt = isa32_interrupt; - machine->main_console_handle = (size_t) - device_add(machine, "ns16550 irq=0 addr=0x800003f8 name2=tty0"); - device_add(machine, "ns16550 irq=0 addr=0x800002f8 name2=tty1 in_use=0"); + pci_data = dev_eagle_init(machine, mem, + 32 /* isa irq base */, 0 /* pci irq: TODO */); - dev_pckbc_init(machine, mem, 0x80000060, PCKBC_8042, - 1, 12, machine->use_x11, 1); - - if (machine->use_x11) - dev_vga_init(machine, mem, 0xc00a0000ULL, 0x800003c0ULL, - machine->machine_name); + bus_isa(machine, BUS_ISA_IDE0 | BUS_ISA_VGA, + 0x80000000, 0xc0000000, 32, 48); if (machine->prom_emulation) { + /* According to the docs, and also used by NetBSD: */ store_32bit_word(cpu, 0x3010, machine->physical_ram_in_mb * 1048576); + /* Used by Linux: */ + store_32bit_word(cpu, 0x32f8, machine->physical_ram_in_mb * 1048576); + /* TODO: List of stuff, see http://www.beatjapan.org/ mirror/www.be.com/aboutbe/benewsletter/ Issue27.html#Cookbook for the details. */ @@ -4146,7 +4236,7 @@ /* NetBSD/bebox: r3 = startkernel, r4 = endkernel, r5 = args, r6 = ptr to bootinfo? */ cpu->cd.ppc.gpr[3] = 0x3100; - cpu->cd.ppc.gpr[4] = 0x200000; + cpu->cd.ppc.gpr[4] = 0x400000; cpu->cd.ppc.gpr[5] = 0x2000; store_string(cpu, cpu->cd.ppc.gpr[5], "-a"); cpu->cd.ppc.gpr[6] = machine->physical_ram_in_mb * 1048576 - 0x100; @@ -4175,14 +4265,58 @@ * NetBSD/prep (http://www.netbsd.org/Ports/prep/) */ machine->machine_name = "PowerPC Reference Platform"; + machine->emulated_hz = 20000000; + + machine->md_int.bebox_data = device_add(machine, "prep"); + machine->isa_pic_data.native_irq = 1; /* Semi-bogus */ + machine->md_interrupt = isa32_interrupt; + + pci_data = dev_eagle_init(machine, mem, + 32 /* isa irq base */, 0 /* pci irq: TODO */); + + bus_isa(machine, BUS_ISA_IDE0 | BUS_ISA_IDE1, + 0x80000000, 0xc0000000, 32, 48); + + bus_pci_add(machine, pci_data, mem, 0, 13, 0, "dec21143"); + + if (machine->use_x11) + bus_pci_add(machine, pci_data, mem, 0, 14, 0, "s3_virge"); if (machine->prom_emulation) { /* Linux on PReP has 0xdeadc0de at address 0? (See http://joshua.raleigh.nc.us/docs/linux-2.4.10_html/113568.html) */ store_32bit_word(cpu, 0, 0xdeadc0de); - /* r6 should point to "residual data"? */ - cpu->cd.ppc.gpr[6] = machine->physical_ram_in_mb * 1048576 - 0x1000; + /* r4 should point to first free byte after the loaded kernel: */ + cpu->cd.ppc.gpr[4] = 6 * 1048576; + + /* + * r6 should point to bootinfo. + * (See NetBSD's prep/include/bootinfo.h for details.) + */ + cpu->cd.ppc.gpr[6] = machine->physical_ram_in_mb * 1048576 - 0x8000; + + store_32bit_word(cpu, cpu->cd.ppc.gpr[6]+ 0, 12); /* next */ + store_32bit_word(cpu, cpu->cd.ppc.gpr[6]+ 4, 2); /* type: clock */ + store_32bit_word(cpu, cpu->cd.ppc.gpr[6]+ 8, machine->emulated_hz); + + store_32bit_word(cpu, cpu->cd.ppc.gpr[6]+12, 20); /* next */ + store_32bit_word(cpu, cpu->cd.ppc.gpr[6]+16, 1); /* type: console */ + store_buf(cpu, cpu->cd.ppc.gpr[6] + 20, + machine->use_x11? "vga" : "com", 4); + store_32bit_word(cpu, cpu->cd.ppc.gpr[6]+24, 0x3f8); /* addr */ + store_32bit_word(cpu, cpu->cd.ppc.gpr[6]+28, 9600); /* speed */ + + store_32bit_word(cpu, cpu->cd.ppc.gpr[6]+32, 0); /* next */ + store_32bit_word(cpu, cpu->cd.ppc.gpr[6]+36, 0); /* type: residual */ + store_32bit_word(cpu, cpu->cd.ppc.gpr[6]+40, /* addr of data */ + cpu->cd.ppc.gpr[6] + 0x100); + + store_32bit_word(cpu, cpu->cd.ppc.gpr[6]+0x100, 0x200); /* TODO: residual */ + /* store_string(cpu, cpu->cd.ppc.gpr[6]+0x100+0x8, "IBM PPS Model 7248 (E)"); */ + store_string(cpu, cpu->cd.ppc.gpr[6]+0x100+0x8, "IBM PPS Model 6050/6070 (E)"); + + store_32bit_word(cpu, cpu->cd.ppc.gpr[6]+0x100+0x1f8, machine->physical_ram_in_mb * 1048576); /* memsize */ } break; @@ -4560,7 +4694,19 @@ machine->md_int.footbridge_data = device_add(machine, "footbridge addr=0x42000000"); - machine->md_interrupt = footbridge_interrupt; + machine->md_interrupt = isa32_interrupt; + machine->isa_pic_data.native_irq = 10; + + /* + * DC21285_ROM_BASE (0x41000000): "reboot" code. Works + * with NetBSD. + */ + dev_ram_init(machine, 0x41000000, 12, DEV_RAM_RAM, 0); + store_32bit_word(cpu, 0x41000008ULL, 0xef8c64ebUL); + + /* OpenBSD reboot needs 0xf??????? to be mapped to phys.: */ + dev_ram_init(machine, 0xf0000000, 0x1000000, + DEV_RAM_MIRROR, 0x0); /* NetBSD and OpenBSD clean their caches here: */ dev_ram_init(machine, 0x50000000, 0x4000, DEV_RAM_RAM, 0); @@ -4568,26 +4714,11 @@ /* Interrupt ack space? */ dev_ram_init(machine, 0x80000000, 0x1000, DEV_RAM_RAM, 0); - snprintf(tmpstr, sizeof(tmpstr), "8259 irq=64 addr=0x7c000020"); - machine->isa_pic_data.pic1 = device_add(machine, tmpstr); - snprintf(tmpstr, sizeof(tmpstr), "8259 irq=64 addr=0x7c0000a0"); - machine->isa_pic_data.pic2 = device_add(machine, tmpstr); - - device_add(machine, "pccmos addr=0x7c000070"); + bus_isa(machine, BUS_ISA_PCKBC_FORCE_USE | BUS_ISA_PCKBC_NONPCSTYLE, + 0x7c000000, 0x80000000, 32, 48); - if (machine->use_x11) { - bus_pci_add(machine, machine->md_int.footbridge_data->pcibus, - mem, 0xc0, 8, 0, pci_s3_virge_init, pci_s3_virge_rr); - dev_vga_init(machine, mem, 0x800a0000ULL, 0x7c0003c0, machine->machine_name); - j = dev_pckbc_init(machine, mem, 0x7c000060, PCKBC_8042, - 32 + 1, 32 + 12, machine->use_x11, 0); - machine->main_console_handle = j; - } - - device_add(machine, "ns16550 irq=36 addr=0x7c0003f8 name2=com0 in_use=0"); - device_add(machine, "ns16550 irq=35 addr=0x7c0002f8 name2=com1 in_use=0"); - - device_add(machine, "lpt irq=39 addr=0x7c000378 name2=lpt in_use=0"); + bus_pci_add(machine, machine->md_int.footbridge_data->pcibus, + mem, 0xc0, 8, 0, "s3_virge"); if (machine->prom_emulation) { struct ebsaboot ebsaboot; @@ -4626,8 +4757,8 @@ store_buf(cpu, cpu->cd.arm.r[0], (char *)&ebsaboot, sizeof(struct ebsaboot)); - snprintf(bs, sizeof(bs), "(hd%i)%s%s%s", - boot_id, machine->boot_kernel_filename, + snprintf(bs, sizeof(bs), "(hd%i)%s root=/dev/wd%i%s%s", + boot_id, machine->boot_kernel_filename, boot_id, (machine->boot_string_argument[0])? " " : "", machine->boot_string_argument); @@ -4758,7 +4889,15 @@ machine->machine_name = "Zaurus"; dev_ram_init(machine, 0xa0000000, 0x20000000, DEV_RAM_MIRROR, 0x0); + dev_ram_init(machine, 0xc0000000, 0x20000000, + DEV_RAM_MIRROR, 0x0); + + /* TODO: replace this with the correct device */ + dev_ram_init(machine, 0x40d00000, 0x1000, DEV_RAM_RAM, 0); + device_add(machine, "ns16550 irq=0 addr=0x40100000 addr_mult=4"); + device_add(machine, "ns16550 irq=0 addr=0xfd400000 addr_mult=4"); + /* TODO */ if (machine->prom_emulation) { arm_setup_initial_translation_table(cpu, 0x4000); @@ -4774,8 +4913,11 @@ machine->md_int.footbridge_data = device_add(machine, "footbridge addr=0x42000000"); - machine->md_interrupt = footbridge_interrupt; + machine->md_interrupt = isa32_interrupt; + machine->isa_pic_data.native_irq = 11; + bus_isa(machine, 0, 0x7c000000, 0x80000000, 32, 48); +#if 0 snprintf(tmpstr, sizeof(tmpstr), "8259 irq=64 addr=0x7c000020"); machine->isa_pic_data.pic1 = device_add(machine, tmpstr); snprintf(tmpstr, sizeof(tmpstr), "8259 irq=64 addr=0x7c0000a0"); @@ -4784,13 +4926,14 @@ device_add(machine, "ns16550 irq=36 addr=0x7c0003f8 name2=com0"); device_add(machine, "ns16550 irq=35 addr=0x7c0002f8 name2=com1"); - if (machine->use_x11) { - bus_pci_add(machine, machine->md_int.footbridge_data->pcibus, - mem, 0xc0, 8, 0, pci_igsfb_init, pci_igsfb_rr); dev_vga_init(machine, mem, 0x800a0000ULL, 0x7c0003c0, machine->machine_name); j = dev_pckbc_init(machine, mem, 0x7c000060, PCKBC_8042, 32 + 1, 32 + 12, machine->use_x11, 0); machine->main_console_handle = j; +#endif + if (machine->use_x11) { + bus_pci_add(machine, machine->md_int.footbridge_data->pcibus, + mem, 0xc0, 8, 0, "igsfb"); } if (machine->prom_emulation) { @@ -4822,6 +4965,12 @@ cpu->cd.arm.coproc[14] = arm_coproc_i80321_14; device_add(machine, "ns16550 irq=0 addr=0xfe800000"); + /* Used by "Redboot": */ + dev_ram_init(machine, 0xa800024, 4, DEV_RAM_RAM, 0); + store_32bit_word(cpu, 0xa800024, 0x7fff); + device_add(machine, "ns16550 irq=0 addr=0x0d800000 addr_mult=4"); + device_add(machine, "ns16550 irq=0 addr=0x0d800020 addr_mult=4"); + /* 0xa0000000 = physical ram, 0xc0000000 = uncached */ dev_ram_init(machine, 0xa0000000, 0x20000000, DEV_RAM_MIRROR, 0x0); @@ -4849,12 +4998,16 @@ cpu->cd.arm.coproc[14] = arm_coproc_i80321_14; device_add(machine, "ns16550 irq=0 addr=0xfe800000"); + device_add(machine, "ns16550 irq=0 addr=0x900003f8"); + device_add(machine, "ns16550 irq=0 addr=0x900002f8"); /* 0xa0000000 = physical ram, 0xc0000000 = uncached */ dev_ram_init(machine, 0xa0000000, 0x20000000, DEV_RAM_MIRROR, 0x0); dev_ram_init(machine, 0xc0000000, 0x20000000, DEV_RAM_MIRROR, 0x0); + dev_ram_init(machine, 0xf0000000, 0x08000000, + DEV_RAM_MIRROR, 0x0); device_add(machine, "i80321 addr=0xffffe000"); @@ -4948,66 +5101,13 @@ else machine->machine_name = "Generic x86 PC"; - /* Interrupt controllers: */ - snprintf(tmpstr, sizeof(tmpstr), "8259 irq=16 addr=0x%llx", - (long long)(X86_IO_BASE + 0x20)); - machine->isa_pic_data.pic1 = device_add(machine, tmpstr); - if (machine->machine_subtype != MACHINE_X86_XT) { - snprintf(tmpstr, sizeof(tmpstr), "8259 irq=16 addr=0x%llx irq=2", - (long long)(X86_IO_BASE + 0xa0)); - machine->isa_pic_data.pic2 = device_add(machine, tmpstr); - } - machine->md_interrupt = x86_pc_interrupt; - /* Timer: */ - snprintf(tmpstr, sizeof(tmpstr), "8253 addr=0x%llx irq=0", - (long long)(X86_IO_BASE + 0x40)); - device_add(machine, tmpstr); - - snprintf(tmpstr, sizeof(tmpstr), "pccmos addr=0x%llx", - (long long)(X86_IO_BASE + 0x70)); - device_add(machine, tmpstr); - - /* TODO: IRQ when emulating a PC XT? */ - - /* IDE controllers: */ - if (diskimage_exist(machine, 0, DISKIMAGE_IDE) || - diskimage_exist(machine, 1, DISKIMAGE_IDE)) { - snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i", - X86_IO_BASE + 0x1f0, 14); - device_add(machine, tmpstr); - } - if (diskimage_exist(machine, 2, DISKIMAGE_IDE) || - diskimage_exist(machine, 3, DISKIMAGE_IDE)) { - snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0x%llx irq=%i", - X86_IO_BASE + 0x170, 15); - device_add(machine, tmpstr); - } - - /* Floppy controller at irq 6 */ - snprintf(tmpstr, sizeof(tmpstr), "fdc addr=0x%llx irq=6", - (long long)(X86_IO_BASE + 0x3f0)); - device_add(machine, tmpstr); - - /* TODO: sound blaster (eventually) at irq 7? */ - - /* TODO: parallel port */ - - /* Serial ports: (TODO: 8250 for PC XT?) */ - - snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=4 addr=0x%llx name2=com1 in_use=0", - (long long)X86_IO_BASE + 0x3f8); - device_add(machine, tmpstr); - snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=3 addr=0x%llx name2=com2 in_use=0", - (long long)X86_IO_BASE + 0x2f8); - device_add(machine, tmpstr); - - /* VGA + keyboard: */ - dev_vga_init(machine, mem, 0xa0000ULL, X86_IO_BASE + 0x3c0, - "Generic x86 PC"); - machine->main_console_handle = dev_pckbc_init(machine, - mem, X86_IO_BASE + 0x60, PCKBC_8042, 1, 12, 1, 1); + bus_isa(machine, BUS_ISA_IDE0 | BUS_ISA_IDE1 | BUS_ISA_VGA | + BUS_ISA_PCKBC_FORCE_USE | + (machine->machine_subtype == MACHINE_X86_XT? + BUS_ISA_NO_SECOND_PIC : 0) | BUS_ISA_FDC, + X86_IO_BASE, 0x00000000, 0, 16); if (machine->prom_emulation) pc_bios_init(cpu); @@ -5034,8 +5134,9 @@ debug(" (%.2f MHz)", (float)machine->emulated_hz / 1000000); debug("\n"); + /* Default fake speed: 5 MHz */ if (machine->emulated_hz < 1) - machine->emulated_hz = 1000000; + machine->emulated_hz = 5000000; if (bootstr != NULL) { debug("bootstring%s: %s", (bootarg!=NULL && @@ -5123,14 +5224,9 @@ } break; case MACHINE_ALPHA: - m->physical_ram_in_mb = 64; - break; case MACHINE_BEBOX: - m->physical_ram_in_mb = 64; - break; + case MACHINE_PREP: case MACHINE_CATS: - m->physical_ram_in_mb = 64; - break; case MACHINE_ZAURUS: m->physical_ram_in_mb = 64; break; @@ -5291,6 +5387,9 @@ case MACHINE_PSP: m->cpu_name = strdup("Allegrex"); break; + case MACHINE_ALGOR: + m->cpu_name = strdup("RM5200"); + break; /* PowerPC: */ case MACHINE_BAREPPC: @@ -5319,8 +5418,8 @@ m->cpu_name = strdup("PPC603e"); break; case MACHINE_PREP: - /* For NetBSD/prep. TODO */ - m->cpu_name = strdup("PPC603e"); + /* For NetBSD/prep. TODO: Differs between models! */ + m->cpu_name = strdup("PPC604"); break; case MACHINE_MACPPC: switch (m->machine_subtype) { @@ -5483,6 +5582,8 @@ debug("Using X11"); if (m->x11_scaledown > 1) debug(", scaledown %i", m->x11_scaledown); + if (m->x11_scaleup > 1) + debug(", scaleup %i", m->x11_scaleup); if (m->x11_n_display_names > 0) { for (i=0; ix11_n_display_names; i++) { debug(i? ", " : " ("); @@ -5638,9 +5739,9 @@ debug_indentation(-iadd); debug("\nMost of the machine types are bogus too. Please read the " - "GXemul\ndocumentation for information about which machine" - " types that actually\nwork. Use the alias when selecting a " - "machine type or subtype, not the\nreal name.\n"); + "GXemul documentation\nfor information about which machine types " + "that actually work. Use the alias\nwhen selecting a machine type " + "or subtype, not the real name.\n"); debug("\n"); @@ -5679,8 +5780,9 @@ me->aliases[0] = "pc"; me->aliases[1] = "x86"; me->subtype[0] = machine_entry_subtype_new("Generic PC", - MACHINE_X86_GENERIC, 1); - me->subtype[0]->aliases[0] = "generic"; + MACHINE_X86_GENERIC, 2); + me->subtype[0]->aliases[0] = "pc"; + me->subtype[0]->aliases[1] = "generic"; me->subtype[1] = machine_entry_subtype_new("PC XT", MACHINE_X86_XT, 1); me->subtype[1]->aliases[0] = "xt"; if (cpu_family_ptr_by_number(ARCH_X86) != NULL) { @@ -6249,5 +6351,18 @@ if (cpu_family_ptr_by_number(ARCH_ALPHA) != NULL) { me->next = first_machine_entry; first_machine_entry = me; } + + /* Algor evaluation board: */ + me = machine_entry_new("Algor", ARCH_MIPS, MACHINE_ALGOR, 1, 2); + me->aliases[0] = "algor"; + me->subtype[0] = machine_entry_subtype_new("P4032", + MACHINE_ALGOR_P4032, 1); + me->subtype[0]->aliases[0] = "p4032"; + me->subtype[1] = machine_entry_subtype_new("P5064", + MACHINE_ALGOR_P5064, 1); + me->subtype[1]->aliases[0] = "p5064"; + if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) { + me->next = first_machine_entry; first_machine_entry = me; + } }