15298722eSAleksandar Markovic /* 25298722eSAleksandar Markovic * QEMU MIPS Jazz support 35298722eSAleksandar Markovic * 45298722eSAleksandar Markovic * Copyright (c) 2007-2008 Hervé Poussineau 55298722eSAleksandar Markovic * 65298722eSAleksandar Markovic * Permission is hereby granted, free of charge, to any person obtaining a copy 75298722eSAleksandar Markovic * of this software and associated documentation files (the "Software"), to deal 85298722eSAleksandar Markovic * in the Software without restriction, including without limitation the rights 95298722eSAleksandar Markovic * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 105298722eSAleksandar Markovic * copies of the Software, and to permit persons to whom the Software is 115298722eSAleksandar Markovic * furnished to do so, subject to the following conditions: 125298722eSAleksandar Markovic * 135298722eSAleksandar Markovic * The above copyright notice and this permission notice shall be included in 145298722eSAleksandar Markovic * all copies or substantial portions of the Software. 155298722eSAleksandar Markovic * 165298722eSAleksandar Markovic * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 175298722eSAleksandar Markovic * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 185298722eSAleksandar Markovic * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 195298722eSAleksandar Markovic * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 205298722eSAleksandar Markovic * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 215298722eSAleksandar Markovic * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 225298722eSAleksandar Markovic * THE SOFTWARE. 235298722eSAleksandar Markovic */ 245298722eSAleksandar Markovic 255298722eSAleksandar Markovic #include "qemu/osdep.h" 262c65db5eSPaolo Bonzini #include "qemu/datadir.h" 2779b99fe3SPhilippe Mathieu-Daudé #include "hw/clock.h" 285298722eSAleksandar Markovic #include "hw/mips/mips.h" 295298722eSAleksandar Markovic #include "hw/mips/cpudevs.h" 305298722eSAleksandar Markovic #include "hw/intc/i8259.h" 315298722eSAleksandar Markovic #include "hw/dma/i8257.h" 325298722eSAleksandar Markovic #include "hw/char/serial.h" 335298722eSAleksandar Markovic #include "hw/char/parallel.h" 345298722eSAleksandar Markovic #include "hw/isa/isa.h" 355298722eSAleksandar Markovic #include "hw/block/fdc.h" 365298722eSAleksandar Markovic #include "sysemu/sysemu.h" 375298722eSAleksandar Markovic #include "hw/boards.h" 385298722eSAleksandar Markovic #include "net/net.h" 395298722eSAleksandar Markovic #include "hw/scsi/esp.h" 405298722eSAleksandar Markovic #include "hw/mips/bios.h" 415298722eSAleksandar Markovic #include "hw/loader.h" 425298722eSAleksandar Markovic #include "hw/rtc/mc146818rtc.h" 435298722eSAleksandar Markovic #include "hw/timer/i8254.h" 445298722eSAleksandar Markovic #include "hw/display/vga.h" 457336c944SPhilippe Mathieu-Daudé #include "hw/display/bochs-vbe.h" 465298722eSAleksandar Markovic #include "hw/audio/pcspk.h" 475298722eSAleksandar Markovic #include "hw/input/i8042.h" 485298722eSAleksandar Markovic #include "hw/sysbus.h" 495298722eSAleksandar Markovic #include "sysemu/qtest.h" 505298722eSAleksandar Markovic #include "sysemu/reset.h" 515298722eSAleksandar Markovic #include "qapi/error.h" 525298722eSAleksandar Markovic #include "qemu/error-report.h" 535298722eSAleksandar Markovic #include "qemu/help_option.h" 5478271684SClaudio Fontana #ifdef CONFIG_TCG 5578271684SClaudio Fontana #include "hw/core/tcg-cpu-ops.h" 5678271684SClaudio Fontana #endif /* CONFIG_TCG */ 575298722eSAleksandar Markovic 585298722eSAleksandar Markovic enum jazz_model_e { 595298722eSAleksandar Markovic JAZZ_MAGNUM, 605298722eSAleksandar Markovic JAZZ_PICA61, 615298722eSAleksandar Markovic }; 625298722eSAleksandar Markovic 635298722eSAleksandar Markovic static void main_cpu_reset(void *opaque) 645298722eSAleksandar Markovic { 655298722eSAleksandar Markovic MIPSCPU *cpu = opaque; 665298722eSAleksandar Markovic 675298722eSAleksandar Markovic cpu_reset(CPU(cpu)); 685298722eSAleksandar Markovic } 695298722eSAleksandar Markovic 705298722eSAleksandar Markovic static uint64_t rtc_read(void *opaque, hwaddr addr, unsigned size) 715298722eSAleksandar Markovic { 725298722eSAleksandar Markovic uint8_t val; 735298722eSAleksandar Markovic address_space_read(&address_space_memory, 0x90000071, 745298722eSAleksandar Markovic MEMTXATTRS_UNSPECIFIED, &val, 1); 755298722eSAleksandar Markovic return val; 765298722eSAleksandar Markovic } 775298722eSAleksandar Markovic 785298722eSAleksandar Markovic static void rtc_write(void *opaque, hwaddr addr, 795298722eSAleksandar Markovic uint64_t val, unsigned size) 805298722eSAleksandar Markovic { 815298722eSAleksandar Markovic uint8_t buf = val & 0xff; 825298722eSAleksandar Markovic address_space_write(&address_space_memory, 0x90000071, 835298722eSAleksandar Markovic MEMTXATTRS_UNSPECIFIED, &buf, 1); 845298722eSAleksandar Markovic } 855298722eSAleksandar Markovic 865298722eSAleksandar Markovic static const MemoryRegionOps rtc_ops = { 875298722eSAleksandar Markovic .read = rtc_read, 885298722eSAleksandar Markovic .write = rtc_write, 895298722eSAleksandar Markovic .endianness = DEVICE_NATIVE_ENDIAN, 905298722eSAleksandar Markovic }; 915298722eSAleksandar Markovic 925298722eSAleksandar Markovic static uint64_t dma_dummy_read(void *opaque, hwaddr addr, 935298722eSAleksandar Markovic unsigned size) 945298722eSAleksandar Markovic { 955298722eSAleksandar Markovic /* 965298722eSAleksandar Markovic * Nothing to do. That is only to ensure that 975298722eSAleksandar Markovic * the current DMA acknowledge cycle is completed. 985298722eSAleksandar Markovic */ 995298722eSAleksandar Markovic return 0xff; 1005298722eSAleksandar Markovic } 1015298722eSAleksandar Markovic 1025298722eSAleksandar Markovic static void dma_dummy_write(void *opaque, hwaddr addr, 1035298722eSAleksandar Markovic uint64_t val, unsigned size) 1045298722eSAleksandar Markovic { 1055298722eSAleksandar Markovic /* 1065298722eSAleksandar Markovic * Nothing to do. That is only to ensure that 1075298722eSAleksandar Markovic * the current DMA acknowledge cycle is completed. 1085298722eSAleksandar Markovic */ 1095298722eSAleksandar Markovic } 1105298722eSAleksandar Markovic 1115298722eSAleksandar Markovic static const MemoryRegionOps dma_dummy_ops = { 1125298722eSAleksandar Markovic .read = dma_dummy_read, 1135298722eSAleksandar Markovic .write = dma_dummy_write, 1145298722eSAleksandar Markovic .endianness = DEVICE_NATIVE_ENDIAN, 1155298722eSAleksandar Markovic }; 1165298722eSAleksandar Markovic 1174032f04cSThomas Huth static void mips_jazz_init_net(NICInfo *nd, IOMMUMemoryRegion *rc4030_dma_mr, 1184032f04cSThomas Huth DeviceState *rc4030, MemoryRegion *dp8393x_prom) 1194032f04cSThomas Huth { 1204032f04cSThomas Huth DeviceState *dev; 1214032f04cSThomas Huth SysBusDevice *sysbus; 1224032f04cSThomas Huth int checksum, i; 1234032f04cSThomas Huth uint8_t *prom; 1244032f04cSThomas Huth 1254032f04cSThomas Huth qemu_check_nic_model(nd, "dp83932"); 1264032f04cSThomas Huth 1274032f04cSThomas Huth dev = qdev_new("dp8393x"); 1284032f04cSThomas Huth qdev_set_nic_properties(dev, nd); 1294032f04cSThomas Huth qdev_prop_set_uint8(dev, "it_shift", 2); 1304032f04cSThomas Huth qdev_prop_set_bit(dev, "big_endian", TARGET_BIG_ENDIAN); 1314032f04cSThomas Huth object_property_set_link(OBJECT(dev), "dma_mr", 1324032f04cSThomas Huth OBJECT(rc4030_dma_mr), &error_abort); 1334032f04cSThomas Huth sysbus = SYS_BUS_DEVICE(dev); 1344032f04cSThomas Huth sysbus_realize_and_unref(sysbus, &error_fatal); 1354032f04cSThomas Huth sysbus_mmio_map(sysbus, 0, 0x80001000); 1364032f04cSThomas Huth sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(rc4030, 4)); 1374032f04cSThomas Huth 1384032f04cSThomas Huth /* Add MAC address with valid checksum to PROM */ 1394032f04cSThomas Huth prom = memory_region_get_ram_ptr(dp8393x_prom); 1404032f04cSThomas Huth checksum = 0; 1414032f04cSThomas Huth for (i = 0; i < 6; i++) { 1424032f04cSThomas Huth prom[i] = nd->macaddr.a[i]; 1434032f04cSThomas Huth checksum += prom[i]; 1444032f04cSThomas Huth if (checksum > 0xff) { 1454032f04cSThomas Huth checksum = (checksum + 1) & 0xff; 1464032f04cSThomas Huth } 1474032f04cSThomas Huth } 1484032f04cSThomas Huth prom[7] = 0xff - checksum; 1494032f04cSThomas Huth } 1504032f04cSThomas Huth 1515298722eSAleksandar Markovic #define MAGNUM_BIOS_SIZE_MAX 0x7e000 1525298722eSAleksandar Markovic #define MAGNUM_BIOS_SIZE \ 1535298722eSAleksandar Markovic (BIOS_SIZE < MAGNUM_BIOS_SIZE_MAX ? BIOS_SIZE : MAGNUM_BIOS_SIZE_MAX) 154cbc183d2SClaudio Fontana 1555d53baf3SMark Cave-Ayland #define SONIC_PROM_SIZE 0x1000 1565d53baf3SMark Cave-Ayland 1575298722eSAleksandar Markovic static void mips_jazz_init(MachineState *machine, 1585298722eSAleksandar Markovic enum jazz_model_e jazz_model) 1595298722eSAleksandar Markovic { 1605298722eSAleksandar Markovic MemoryRegion *address_space = get_system_memory(); 1615298722eSAleksandar Markovic char *filename; 162ded625e7SThomas Huth int bios_size, n; 16379b99fe3SPhilippe Mathieu-Daudé Clock *cpuclk; 1645298722eSAleksandar Markovic MIPSCPU *cpu; 1653803b6b4SRichard Henderson MIPSCPUClass *mcc; 1665298722eSAleksandar Markovic CPUMIPSState *env; 1675298722eSAleksandar Markovic qemu_irq *i8259; 1685298722eSAleksandar Markovic rc4030_dma *dmas; 1695298722eSAleksandar Markovic IOMMUMemoryRegion *rc4030_dma_mr; 1705298722eSAleksandar Markovic MemoryRegion *isa_mem = g_new(MemoryRegion, 1); 1715298722eSAleksandar Markovic MemoryRegion *isa_io = g_new(MemoryRegion, 1); 1725298722eSAleksandar Markovic MemoryRegion *rtc = g_new(MemoryRegion, 1); 1735298722eSAleksandar Markovic MemoryRegion *dma_dummy = g_new(MemoryRegion, 1); 1745d53baf3SMark Cave-Ayland MemoryRegion *dp8393x_prom = g_new(MemoryRegion, 1); 1755298722eSAleksandar Markovic NICInfo *nd; 1765298722eSAleksandar Markovic DeviceState *dev, *rc4030; 17701d924dcSMark Cave-Ayland MMIOKBDState *i8042; 1785298722eSAleksandar Markovic SysBusDevice *sysbus; 1795298722eSAleksandar Markovic ISABus *isa_bus; 1805298722eSAleksandar Markovic ISADevice *pit; 1815298722eSAleksandar Markovic DriveInfo *fds[MAX_FD]; 1825298722eSAleksandar Markovic MemoryRegion *bios = g_new(MemoryRegion, 1); 1835298722eSAleksandar Markovic MemoryRegion *bios2 = g_new(MemoryRegion, 1); 1845298722eSAleksandar Markovic SysBusESPState *sysbus_esp; 1855298722eSAleksandar Markovic ESPState *esp; 18679b99fe3SPhilippe Mathieu-Daudé static const struct { 18779b99fe3SPhilippe Mathieu-Daudé unsigned freq_hz; 18879b99fe3SPhilippe Mathieu-Daudé unsigned pll_mult; 18979b99fe3SPhilippe Mathieu-Daudé } ext_clk[] = { 19079b99fe3SPhilippe Mathieu-Daudé [JAZZ_MAGNUM] = {50000000, 2}, 19179b99fe3SPhilippe Mathieu-Daudé [JAZZ_PICA61] = {33333333, 4}, 19279b99fe3SPhilippe Mathieu-Daudé }; 1935298722eSAleksandar Markovic 1945298722eSAleksandar Markovic if (machine->ram_size > 256 * MiB) { 1955298722eSAleksandar Markovic error_report("RAM size more than 256Mb is not supported"); 1965298722eSAleksandar Markovic exit(EXIT_FAILURE); 1975298722eSAleksandar Markovic } 1985298722eSAleksandar Markovic 19979b99fe3SPhilippe Mathieu-Daudé cpuclk = clock_new(OBJECT(machine), "cpu-refclk"); 20079b99fe3SPhilippe Mathieu-Daudé clock_set_hz(cpuclk, ext_clk[jazz_model].freq_hz 20179b99fe3SPhilippe Mathieu-Daudé * ext_clk[jazz_model].pll_mult); 20279b99fe3SPhilippe Mathieu-Daudé 2035298722eSAleksandar Markovic /* init CPUs */ 20479b99fe3SPhilippe Mathieu-Daudé cpu = mips_cpu_create_with_clock(machine->cpu_type, cpuclk); 2055298722eSAleksandar Markovic env = &cpu->env; 2065298722eSAleksandar Markovic qemu_register_reset(main_cpu_reset, cpu); 2075298722eSAleksandar Markovic 2085298722eSAleksandar Markovic /* 2095298722eSAleksandar Markovic * Chipset returns 0 in invalid reads and do not raise data exceptions. 2105298722eSAleksandar Markovic * However, we can't simply add a global memory region to catch 2115298722eSAleksandar Markovic * everything, as this would make all accesses including instruction 2125298722eSAleksandar Markovic * accesses be ignored and not raise exceptions. 2135298722eSAleksandar Markovic * 2145298722eSAleksandar Markovic * NOTE: this behaviour of raising exceptions for bad instruction 2155298722eSAleksandar Markovic * fetches but not bad data accesses was added in commit 54e755588cf1e9 2165298722eSAleksandar Markovic * to restore behaviour broken by c658b94f6e8c206, but it is not clear 2175298722eSAleksandar Markovic * whether the real hardware behaves this way. It is possible that 2185298722eSAleksandar Markovic * real hardware ignores bad instruction fetches as well -- if so then 2195298722eSAleksandar Markovic * we could replace this hijacking of CPU methods with a simple global 2205298722eSAleksandar Markovic * memory region that catches all memory accesses, as we do on Malta. 2215298722eSAleksandar Markovic */ 2223803b6b4SRichard Henderson mcc = MIPS_CPU_GET_CLASS(cpu); 2233803b6b4SRichard Henderson mcc->no_data_aborts = true; 2245298722eSAleksandar Markovic 2255298722eSAleksandar Markovic /* allocate RAM */ 2265298722eSAleksandar Markovic memory_region_add_subregion(address_space, 0, machine->ram); 2275298722eSAleksandar Markovic 2285298722eSAleksandar Markovic memory_region_init_rom(bios, NULL, "mips_jazz.bios", MAGNUM_BIOS_SIZE, 2295298722eSAleksandar Markovic &error_fatal); 2305298722eSAleksandar Markovic memory_region_init_alias(bios2, NULL, "mips_jazz.bios", bios, 2315298722eSAleksandar Markovic 0, MAGNUM_BIOS_SIZE); 2325298722eSAleksandar Markovic memory_region_add_subregion(address_space, 0x1fc00000LL, bios); 2335298722eSAleksandar Markovic memory_region_add_subregion(address_space, 0xfff00000LL, bios2); 2345298722eSAleksandar Markovic 2355298722eSAleksandar Markovic /* load the BIOS image. */ 23659588beaSPaolo Bonzini filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, machine->firmware ?: BIOS_FILENAME); 2375298722eSAleksandar Markovic if (filename) { 2385298722eSAleksandar Markovic bios_size = load_image_targphys(filename, 0xfff00000LL, 2395298722eSAleksandar Markovic MAGNUM_BIOS_SIZE); 2405298722eSAleksandar Markovic g_free(filename); 2415298722eSAleksandar Markovic } else { 2425298722eSAleksandar Markovic bios_size = -1; 2435298722eSAleksandar Markovic } 244a4374f86SPavel Dovgalyuk if ((bios_size < 0 || bios_size > MAGNUM_BIOS_SIZE) 24559588beaSPaolo Bonzini && machine->firmware && !qtest_enabled()) { 24659588beaSPaolo Bonzini error_report("Could not load MIPS bios '%s'", machine->firmware); 2475298722eSAleksandar Markovic exit(1); 2485298722eSAleksandar Markovic } 2495298722eSAleksandar Markovic 2505298722eSAleksandar Markovic /* Init CPU internal devices */ 2515298722eSAleksandar Markovic cpu_mips_irq_init_cpu(cpu); 2525298722eSAleksandar Markovic cpu_mips_clock_init(cpu); 2535298722eSAleksandar Markovic 2545298722eSAleksandar Markovic /* Chipset */ 2555298722eSAleksandar Markovic rc4030 = rc4030_init(&dmas, &rc4030_dma_mr); 2565298722eSAleksandar Markovic sysbus = SYS_BUS_DEVICE(rc4030); 2575298722eSAleksandar Markovic sysbus_connect_irq(sysbus, 0, env->irq[6]); 2585298722eSAleksandar Markovic sysbus_connect_irq(sysbus, 1, env->irq[3]); 2595298722eSAleksandar Markovic memory_region_add_subregion(address_space, 0x80000000, 2605298722eSAleksandar Markovic sysbus_mmio_get_region(sysbus, 0)); 2615298722eSAleksandar Markovic memory_region_add_subregion(address_space, 0xf0000000, 2625298722eSAleksandar Markovic sysbus_mmio_get_region(sysbus, 1)); 2635298722eSAleksandar Markovic memory_region_init_io(dma_dummy, NULL, &dma_dummy_ops, 2645298722eSAleksandar Markovic NULL, "dummy_dma", 0x1000); 2655298722eSAleksandar Markovic memory_region_add_subregion(address_space, 0x8000d000, dma_dummy); 2665298722eSAleksandar Markovic 2675d53baf3SMark Cave-Ayland memory_region_init_rom(dp8393x_prom, NULL, "dp8393x-jazz.prom", 2685d53baf3SMark Cave-Ayland SONIC_PROM_SIZE, &error_fatal); 2695d53baf3SMark Cave-Ayland memory_region_add_subregion(address_space, 0x8000b000, dp8393x_prom); 2705d53baf3SMark Cave-Ayland 2715298722eSAleksandar Markovic /* ISA bus: IO space at 0x90000000, mem space at 0x91000000 */ 2725298722eSAleksandar Markovic memory_region_init(isa_io, NULL, "isa-io", 0x00010000); 2735298722eSAleksandar Markovic memory_region_init(isa_mem, NULL, "isa-mem", 0x01000000); 2745298722eSAleksandar Markovic memory_region_add_subregion(address_space, 0x90000000, isa_io); 2755298722eSAleksandar Markovic memory_region_add_subregion(address_space, 0x91000000, isa_mem); 2765298722eSAleksandar Markovic isa_bus = isa_bus_new(NULL, isa_mem, isa_io, &error_abort); 2775298722eSAleksandar Markovic 2785298722eSAleksandar Markovic /* ISA devices */ 2795298722eSAleksandar Markovic i8259 = i8259_init(isa_bus, env->irq[4]); 2807067887eSPhilippe Mathieu-Daudé isa_bus_register_input_irqs(isa_bus, i8259); 2815298722eSAleksandar Markovic i8257_dma_init(isa_bus, 0); 2825298722eSAleksandar Markovic pit = i8254_pit_init(isa_bus, 0x40, 0, NULL); 283525d654dSGerd Hoffmann pcspk_init(isa_new(TYPE_PC_SPEAKER), isa_bus, pit); 2845298722eSAleksandar Markovic 2855298722eSAleksandar Markovic /* Video card */ 2865298722eSAleksandar Markovic switch (jazz_model) { 2875298722eSAleksandar Markovic case JAZZ_MAGNUM: 2883e80f690SMarkus Armbruster dev = qdev_new("sysbus-g364"); 2895298722eSAleksandar Markovic sysbus = SYS_BUS_DEVICE(dev); 2903c6ef471SMarkus Armbruster sysbus_realize_and_unref(sysbus, &error_fatal); 2915298722eSAleksandar Markovic sysbus_mmio_map(sysbus, 0, 0x60080000); 2925298722eSAleksandar Markovic sysbus_mmio_map(sysbus, 1, 0x40000000); 2935298722eSAleksandar Markovic sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(rc4030, 3)); 2945298722eSAleksandar Markovic { 2955298722eSAleksandar Markovic /* Simple ROM, so user doesn't have to provide one */ 2965298722eSAleksandar Markovic MemoryRegion *rom_mr = g_new(MemoryRegion, 1); 2975298722eSAleksandar Markovic memory_region_init_rom(rom_mr, NULL, "g364fb.rom", 0x80000, 2985298722eSAleksandar Markovic &error_fatal); 2995298722eSAleksandar Markovic uint8_t *rom = memory_region_get_ram_ptr(rom_mr); 3005298722eSAleksandar Markovic memory_region_add_subregion(address_space, 0x60000000, rom_mr); 3015298722eSAleksandar Markovic rom[0] = 0x10; /* Mips G364 */ 3025298722eSAleksandar Markovic } 3035298722eSAleksandar Markovic break; 3045298722eSAleksandar Markovic case JAZZ_PICA61: 3057336c944SPhilippe Mathieu-Daudé dev = qdev_new(TYPE_VGA_MMIO); 3067336c944SPhilippe Mathieu-Daudé qdev_prop_set_uint8(dev, "it_shift", 0); 3077336c944SPhilippe Mathieu-Daudé sysbus = SYS_BUS_DEVICE(dev); 3087336c944SPhilippe Mathieu-Daudé sysbus_realize_and_unref(sysbus, &error_fatal); 3097336c944SPhilippe Mathieu-Daudé sysbus_mmio_map(sysbus, 0, 0x60000000); 3107336c944SPhilippe Mathieu-Daudé sysbus_mmio_map(sysbus, 1, 0x400a0000); 3117336c944SPhilippe Mathieu-Daudé sysbus_mmio_map(sysbus, 2, VBE_DISPI_LFB_PHYSICAL_ADDRESS); 3125298722eSAleksandar Markovic break; 3135298722eSAleksandar Markovic default: 3145298722eSAleksandar Markovic break; 3155298722eSAleksandar Markovic } 3165298722eSAleksandar Markovic 3175298722eSAleksandar Markovic /* Network controller */ 3185298722eSAleksandar Markovic for (n = 0; n < nb_nics; n++) { 3195298722eSAleksandar Markovic nd = &nd_table[n]; 3205298722eSAleksandar Markovic if (!nd->model) { 3215298722eSAleksandar Markovic nd->model = g_strdup("dp83932"); 3225298722eSAleksandar Markovic } 3235298722eSAleksandar Markovic if (strcmp(nd->model, "dp83932") == 0) { 3244032f04cSThomas Huth mips_jazz_init_net(nd, rc4030_dma_mr, rc4030, dp8393x_prom); 3255298722eSAleksandar Markovic break; 3265298722eSAleksandar Markovic } else if (is_help_option(nd->model)) { 3275298722eSAleksandar Markovic error_report("Supported NICs: dp83932"); 3285298722eSAleksandar Markovic exit(1); 3295298722eSAleksandar Markovic } else { 3305298722eSAleksandar Markovic error_report("Unsupported NIC: %s", nd->model); 3315298722eSAleksandar Markovic exit(1); 3325298722eSAleksandar Markovic } 3335298722eSAleksandar Markovic } 3345298722eSAleksandar Markovic 3355298722eSAleksandar Markovic /* SCSI adapter */ 33684fbefedSMark Cave-Ayland dev = qdev_new(TYPE_SYSBUS_ESP); 33784fbefedSMark Cave-Ayland sysbus_esp = SYSBUS_ESP(dev); 3385298722eSAleksandar Markovic esp = &sysbus_esp->esp; 3395298722eSAleksandar Markovic esp->dma_memory_read = rc4030_dma_read; 3405298722eSAleksandar Markovic esp->dma_memory_write = rc4030_dma_write; 3415298722eSAleksandar Markovic esp->dma_opaque = dmas[0]; 3425298722eSAleksandar Markovic sysbus_esp->it_shift = 0; 3435298722eSAleksandar Markovic /* XXX for now until rc4030 has been changed to use DMA enable signal */ 3445298722eSAleksandar Markovic esp->dma_enabled = 1; 3455298722eSAleksandar Markovic 3465298722eSAleksandar Markovic sysbus = SYS_BUS_DEVICE(dev); 3473c6ef471SMarkus Armbruster sysbus_realize_and_unref(sysbus, &error_fatal); 3485298722eSAleksandar Markovic sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(rc4030, 5)); 3495298722eSAleksandar Markovic sysbus_mmio_map(sysbus, 0, 0x80002000); 3505298722eSAleksandar Markovic 3515298722eSAleksandar Markovic scsi_bus_legacy_handle_cmdline(&esp->bus); 3525298722eSAleksandar Markovic 3535298722eSAleksandar Markovic /* Floppy */ 3545298722eSAleksandar Markovic for (n = 0; n < MAX_FD; n++) { 3555298722eSAleksandar Markovic fds[n] = drive_get(IF_FLOPPY, 0, n); 3565298722eSAleksandar Markovic } 3575298722eSAleksandar Markovic /* FIXME: we should enable DMA with a custom IsaDma device */ 3580c285e01SPeter Maydell fdctrl_init_sysbus(qdev_get_gpio_in(rc4030, 1), 0x80003000, fds); 3595298722eSAleksandar Markovic 3605298722eSAleksandar Markovic /* Real time clock */ 3615298722eSAleksandar Markovic mc146818_rtc_init(isa_bus, 1980, NULL); 3625298722eSAleksandar Markovic memory_region_init_io(rtc, NULL, &rtc_ops, NULL, "rtc", 0x1000); 3635298722eSAleksandar Markovic memory_region_add_subregion(address_space, 0x80004000, rtc); 3645298722eSAleksandar Markovic 3655298722eSAleksandar Markovic /* Keyboard (i8042) */ 366b704d63dSMark Cave-Ayland i8042 = I8042_MMIO(qdev_new(TYPE_I8042_MMIO)); 367b704d63dSMark Cave-Ayland qdev_prop_set_uint64(DEVICE(i8042), "mask", 1); 368b704d63dSMark Cave-Ayland qdev_prop_set_uint32(DEVICE(i8042), "size", 0x1000); 369b704d63dSMark Cave-Ayland sysbus_realize_and_unref(SYS_BUS_DEVICE(i8042), &error_fatal); 370b704d63dSMark Cave-Ayland 371b704d63dSMark Cave-Ayland qdev_connect_gpio_out(DEVICE(i8042), I8042_KBD_IRQ, 372b704d63dSMark Cave-Ayland qdev_get_gpio_in(rc4030, 6)); 373b704d63dSMark Cave-Ayland qdev_connect_gpio_out(DEVICE(i8042), I8042_MOUSE_IRQ, 374b704d63dSMark Cave-Ayland qdev_get_gpio_in(rc4030, 7)); 375b704d63dSMark Cave-Ayland 37601d924dcSMark Cave-Ayland memory_region_add_subregion(address_space, 0x80005000, 37701d924dcSMark Cave-Ayland sysbus_mmio_get_region(SYS_BUS_DEVICE(i8042), 37801d924dcSMark Cave-Ayland 0)); 3795298722eSAleksandar Markovic 3805298722eSAleksandar Markovic /* Serial ports */ 3815298722eSAleksandar Markovic serial_mm_init(address_space, 0x80006000, 0, 3825298722eSAleksandar Markovic qdev_get_gpio_in(rc4030, 8), 8000000 / 16, 3835298722eSAleksandar Markovic serial_hd(0), DEVICE_NATIVE_ENDIAN); 3845298722eSAleksandar Markovic serial_mm_init(address_space, 0x80007000, 0, 3855298722eSAleksandar Markovic qdev_get_gpio_in(rc4030, 9), 8000000 / 16, 3865298722eSAleksandar Markovic serial_hd(1), DEVICE_NATIVE_ENDIAN); 3875298722eSAleksandar Markovic 3885298722eSAleksandar Markovic /* Parallel port */ 3895298722eSAleksandar Markovic if (parallel_hds[0]) 3905298722eSAleksandar Markovic parallel_mm_init(address_space, 0x80008000, 0, 3915298722eSAleksandar Markovic qdev_get_gpio_in(rc4030, 0), parallel_hds[0]); 3925298722eSAleksandar Markovic 3935298722eSAleksandar Markovic /* FIXME: missing Jazz sound at 0x8000c000, rc4030[2] */ 3945298722eSAleksandar Markovic 3955298722eSAleksandar Markovic /* NVRAM */ 3963e80f690SMarkus Armbruster dev = qdev_new("ds1225y"); 3975298722eSAleksandar Markovic sysbus = SYS_BUS_DEVICE(dev); 3983c6ef471SMarkus Armbruster sysbus_realize_and_unref(sysbus, &error_fatal); 3995298722eSAleksandar Markovic sysbus_mmio_map(sysbus, 0, 0x80009000); 4005298722eSAleksandar Markovic 4015298722eSAleksandar Markovic /* LED indicator */ 4025298722eSAleksandar Markovic sysbus_create_simple("jazz-led", 0x8000f000, NULL); 4035298722eSAleksandar Markovic 4045298722eSAleksandar Markovic g_free(dmas); 4055298722eSAleksandar Markovic } 4065298722eSAleksandar Markovic 4075298722eSAleksandar Markovic static 4085298722eSAleksandar Markovic void mips_magnum_init(MachineState *machine) 4095298722eSAleksandar Markovic { 4105298722eSAleksandar Markovic mips_jazz_init(machine, JAZZ_MAGNUM); 4115298722eSAleksandar Markovic } 4125298722eSAleksandar Markovic 4135298722eSAleksandar Markovic static 4145298722eSAleksandar Markovic void mips_pica61_init(MachineState *machine) 4155298722eSAleksandar Markovic { 4165298722eSAleksandar Markovic mips_jazz_init(machine, JAZZ_PICA61); 4175298722eSAleksandar Markovic } 4185298722eSAleksandar Markovic 4195298722eSAleksandar Markovic static void mips_magnum_class_init(ObjectClass *oc, void *data) 4205298722eSAleksandar Markovic { 4215298722eSAleksandar Markovic MachineClass *mc = MACHINE_CLASS(oc); 4225298722eSAleksandar Markovic 4235298722eSAleksandar Markovic mc->desc = "MIPS Magnum"; 4245298722eSAleksandar Markovic mc->init = mips_magnum_init; 4255298722eSAleksandar Markovic mc->block_default_type = IF_SCSI; 4265298722eSAleksandar Markovic mc->default_cpu_type = MIPS_CPU_TYPE_NAME("R4000"); 4275298722eSAleksandar Markovic mc->default_ram_id = "mips_jazz.ram"; 4285298722eSAleksandar Markovic } 4295298722eSAleksandar Markovic 4305298722eSAleksandar Markovic static const TypeInfo mips_magnum_type = { 4315298722eSAleksandar Markovic .name = MACHINE_TYPE_NAME("magnum"), 4325298722eSAleksandar Markovic .parent = TYPE_MACHINE, 4335298722eSAleksandar Markovic .class_init = mips_magnum_class_init, 4345298722eSAleksandar Markovic }; 4355298722eSAleksandar Markovic 4365298722eSAleksandar Markovic static void mips_pica61_class_init(ObjectClass *oc, void *data) 4375298722eSAleksandar Markovic { 4385298722eSAleksandar Markovic MachineClass *mc = MACHINE_CLASS(oc); 4395298722eSAleksandar Markovic 4405298722eSAleksandar Markovic mc->desc = "Acer Pica 61"; 4415298722eSAleksandar Markovic mc->init = mips_pica61_init; 4425298722eSAleksandar Markovic mc->block_default_type = IF_SCSI; 4435298722eSAleksandar Markovic mc->default_cpu_type = MIPS_CPU_TYPE_NAME("R4000"); 4445298722eSAleksandar Markovic mc->default_ram_id = "mips_jazz.ram"; 4455298722eSAleksandar Markovic } 4465298722eSAleksandar Markovic 4475298722eSAleksandar Markovic static const TypeInfo mips_pica61_type = { 4485298722eSAleksandar Markovic .name = MACHINE_TYPE_NAME("pica61"), 4495298722eSAleksandar Markovic .parent = TYPE_MACHINE, 4505298722eSAleksandar Markovic .class_init = mips_pica61_class_init, 4515298722eSAleksandar Markovic }; 4525298722eSAleksandar Markovic 4535298722eSAleksandar Markovic static void mips_jazz_machine_init(void) 4545298722eSAleksandar Markovic { 4555298722eSAleksandar Markovic type_register_static(&mips_magnum_type); 4565298722eSAleksandar Markovic type_register_static(&mips_pica61_type); 4575298722eSAleksandar Markovic } 4585298722eSAleksandar Markovic 4595298722eSAleksandar Markovic type_init(mips_jazz_machine_init) 460