예제 #1
0
파일: sun4u.c 프로젝트: Marshalzxy/qemu
/* EBUS (Eight bit bus) bridge */
static void ebus_realize(PCIDevice *pci_dev, Error **errp)
{
    EbusState *s = EBUS(pci_dev);
    SysBusDevice *sbd;
    DeviceState *dev;
    qemu_irq *isa_irq;
    DriveInfo *fd[MAX_FD];
    int i;

    s->isa_bus = isa_bus_new(DEVICE(pci_dev), get_system_memory(),
                             pci_address_space_io(pci_dev), errp);
    if (!s->isa_bus) {
        error_setg(errp, "unable to instantiate EBUS ISA bus");
        return;
    }

    /* ISA bus */
    isa_irq = qemu_allocate_irqs(ebus_isa_irq_handler, s, ISA_NUM_IRQS);
    isa_bus_irqs(s->isa_bus, isa_irq);
    qdev_init_gpio_out_named(DEVICE(s), s->isa_bus_irqs, "isa-irq",
                             ISA_NUM_IRQS);

    /* Serial ports */
    i = 0;
    if (s->console_serial_base) {
        serial_mm_init(pci_address_space(pci_dev), s->console_serial_base,
                       0, NULL, 115200, serial_hds[i], DEVICE_BIG_ENDIAN);
        i++;
    }
    serial_hds_isa_init(s->isa_bus, i, MAX_SERIAL_PORTS);

    /* Parallel ports */
    parallel_hds_isa_init(s->isa_bus, MAX_PARALLEL_PORTS);

    /* Keyboard */
    isa_create_simple(s->isa_bus, "i8042");

    /* Floppy */
    for (i = 0; i < MAX_FD; i++) {
        fd[i] = drive_get(IF_FLOPPY, 0, i);
    }
    dev = DEVICE(isa_create(s->isa_bus, TYPE_ISA_FDC));
    if (fd[0]) {
        qdev_prop_set_drive(dev, "driveA", blk_by_legacy_dinfo(fd[0]),
                            &error_abort);
    }
    if (fd[1]) {
        qdev_prop_set_drive(dev, "driveB", blk_by_legacy_dinfo(fd[1]),
                            &error_abort);
    }
    qdev_prop_set_uint32(dev, "dma", -1);
    qdev_init_nofail(dev);

    /* Power */
    dev = qdev_create(NULL, TYPE_SUN4U_POWER);
    qdev_init_nofail(dev);
    sbd = SYS_BUS_DEVICE(dev);
    memory_region_add_subregion(pci_address_space_io(pci_dev), 0x7240,
                                sysbus_mmio_get_region(sbd, 0));

    /* PCI */
    pci_dev->config[0x04] = 0x06; // command = bus master, pci mem
    pci_dev->config[0x05] = 0x00;
    pci_dev->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
    pci_dev->config[0x07] = 0x03; // status = medium devsel
    pci_dev->config[0x09] = 0x00; // programming i/f
    pci_dev->config[0x0D] = 0x0a; // latency_timer

    memory_region_init_alias(&s->bar0, OBJECT(s), "bar0", get_system_io(),
                             0, 0x1000000);
    pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar0);
    memory_region_init_alias(&s->bar1, OBJECT(s), "bar1", get_system_io(),
                             0, 0x8000);
    pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->bar1);
}
예제 #2
0
파일: sun4u.c 프로젝트: dota1923/qemu
static void sun4uv_init(MemoryRegion *address_space_mem,
                        MachineState *machine,
                        const struct hwdef *hwdef)
{
    SPARCCPU *cpu;
    Nvram *nvram;
    unsigned int i;
    uint64_t initrd_addr, initrd_size, kernel_addr, kernel_size, kernel_entry;
    PCIBus *pci_bus, *pci_bus2, *pci_bus3;
    ISABus *isa_bus;
    SysBusDevice *s;
    qemu_irq *ivec_irqs, *pbm_irqs;
    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
    DriveInfo *fd[MAX_FD];
    FWCfgState *fw_cfg;

    /* init CPUs */
    cpu = cpu_devinit(machine->cpu_model, hwdef);

    /* set up devices */
    ram_init(0, machine->ram_size);

    prom_init(hwdef->prom_addr, bios_name);

    ivec_irqs = qemu_allocate_irqs(cpu_set_ivec_irq, cpu, IVEC_MAX);
    pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, ivec_irqs, &pci_bus2,
                           &pci_bus3, &pbm_irqs);
    pci_vga_init(pci_bus);

    // XXX Should be pci_bus3
    isa_bus = pci_ebus_init(pci_bus, -1, pbm_irqs);

    i = 0;
    if (hwdef->console_serial_base) {
        serial_mm_init(address_space_mem, hwdef->console_serial_base, 0,
                       NULL, 115200, serial_hds[i], DEVICE_BIG_ENDIAN);
        i++;
    }

    serial_hds_isa_init(isa_bus, MAX_SERIAL_PORTS);
    parallel_hds_isa_init(isa_bus, MAX_PARALLEL_PORTS);

    for(i = 0; i < nb_nics; i++)
        pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL);

    ide_drive_get(hd, ARRAY_SIZE(hd));

    pci_cmd646_ide_init(pci_bus, hd, 1);

    isa_create_simple(isa_bus, "i8042");
    for(i = 0; i < MAX_FD; i++) {
        fd[i] = drive_get(IF_FLOPPY, 0, i);
    }
    fdctrl_init_isa(isa_bus, fd);

    /* Map NVRAM into I/O (ebus) space */
    nvram = m48t59_init(NULL, 0, 0, NVRAM_SIZE, 1968, 59);
    s = SYS_BUS_DEVICE(nvram);
    memory_region_add_subregion(get_system_io(), 0x2000,
                                sysbus_mmio_get_region(s, 0));
 
    initrd_size = 0;
    initrd_addr = 0;
    kernel_size = sun4u_load_kernel(machine->kernel_filename,
                                    machine->initrd_filename,
                                    ram_size, &initrd_size, &initrd_addr,
                                    &kernel_addr, &kernel_entry);

    sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", machine->ram_size,
                           machine->boot_order,
                           kernel_addr, kernel_size,
                           machine->kernel_cmdline,
                           initrd_addr, initrd_size,
                           /* XXX: need an option to load a NVRAM image */
                           0,
                           graphic_width, graphic_height, graphic_depth,
                           (uint8_t *)&nd_table[0].macaddr);

    fw_cfg = fw_cfg_init_io(BIOS_CFG_IOPORT);
    fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
    fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
    fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_entry);
    fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
    if (machine->kernel_cmdline) {
        fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
                       strlen(machine->kernel_cmdline) + 1);
        fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, machine->kernel_cmdline);
    } else {
        fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, 0);
    }
    fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr);
    fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, machine->boot_order[0]);

    fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_WIDTH, graphic_width);
    fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_HEIGHT, graphic_height);
    fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_DEPTH, graphic_depth);

    qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
}