--- qemu/hw/ide/via.c 2018/04/24 18:30:53 1.1.1.1 +++ qemu/hw/ide/via.c 2018/04/24 19:51:03 1.1.1.6 @@ -28,17 +28,21 @@ #include #include #include "block.h" -#include "block_int.h" #include "sysemu.h" #include "dma.h" #include -static uint32_t bmdma_readb(void *opaque, uint32_t addr) +static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, + unsigned size) { BMDMAState *bm = opaque; uint32_t val; + if (size != 1) { + return ((uint64_t)1 << (size * 8)) - 1; + } + switch (addr & 3) { case 0: val = bm->cmd; @@ -56,13 +60,21 @@ static uint32_t bmdma_readb(void *opaque return val; } -static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val) +static void bmdma_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { BMDMAState *bm = opaque; + + if (size != 1) { + return; + } + #ifdef DEBUG_IDE printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val); #endif switch (addr & 3) { + case 0: + return bmdma_cmd_writeb(bm, val); case 2: bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06); break; @@ -70,30 +82,25 @@ static void bmdma_writeb(void *opaque, u } } -static void bmdma_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static const MemoryRegionOps via_bmdma_ops = { + .read = bmdma_read, + .write = bmdma_write, +}; + +static void bmdma_setup_bar(PCIIDEState *d) { - PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev); int i; + memory_region_init(&d->bmdma_bar, "via-bmdma-container", 16); for(i = 0;i < 2; i++) { BMDMAState *bm = &d->bmdma[i]; - d->bus[i].bmdma = bm; - bm->bus = d->bus+i; - qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm); - - register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm); - - register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm); - register_ioport_read(addr, 4, 1, bmdma_readb, bm); - - register_ioport_write(addr + 4, 4, 1, bmdma_addr_writeb, bm); - register_ioport_read(addr + 4, 4, 1, bmdma_addr_readb, bm); - register_ioport_write(addr + 4, 4, 2, bmdma_addr_writew, bm); - register_ioport_read(addr + 4, 4, 2, bmdma_addr_readw, bm); - register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm); - register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm); - addr += 8; + + memory_region_init_io(&bm->extra_io, &via_bmdma_ops, bm, + "via-bmdma", 4); + memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io); + memory_region_init_io(&bm->addr_ioport, &bmdma_addr_ioport_ops, bm, + "bmdma", 4); + memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport); } } @@ -105,7 +112,6 @@ static void via_reset(void *opaque) for (i = 0; i < 2; i++) { ide_bus_reset(&d->bus[i]); - ide_dma_reset(&d->bmdma[i]); } pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_WAIT); @@ -139,31 +145,62 @@ static void via_reset(void *opaque) pci_set_long(pci_conf + 0xc0, 0x00020001); } +static void vt82c686b_init_ports(PCIIDEState *d) { + static const struct { + int iobase; + int iobase2; + int isairq; + } port_info[] = { + {0x1f0, 0x3f6, 14}, + {0x170, 0x376, 15}, + }; + int i; + + for (i = 0; i < 2; i++) { + ide_bus_new(&d->bus[i], &d->dev.qdev, i); + ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase, + port_info[i].iobase2); + ide_init2(&d->bus[i], isa_get_irq(NULL, port_info[i].isairq)); + + bmdma_init(&d->bus[i], &d->bmdma[i], d); + d->bmdma[i].bus = &d->bus[i]; + qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb, + &d->bmdma[i].dma); + } +} + /* via ide func */ static int vt82c686b_ide_initfn(PCIDevice *dev) { - PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);; + PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev); uint8_t *pci_conf = d->dev.config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_IDE); - pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE); pci_config_set_prog_interface(pci_conf, 0x8a); /* legacy ATA mode */ - pci_config_set_revision(pci_conf,0x06); /* Revision 0.6 */ pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); qemu_register_reset(via_reset, d); - pci_register_bar((PCIDevice *)d, 4, 0x10, - PCI_BASE_ADDRESS_SPACE_IO, bmdma_map); + bmdma_setup_bar(d); + pci_register_bar(&d->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar); vmstate_register(&dev->qdev, 0, &vmstate_ide_pci, d); - ide_bus_new(&d->bus[0], &d->dev.qdev); - ide_bus_new(&d->bus[1], &d->dev.qdev); - ide_init2(&d->bus[0], isa_reserve_irq(14)); - ide_init2(&d->bus[1], isa_reserve_irq(15)); - ide_init_ioport(&d->bus[0], 0x1f0, 0x3f6); - ide_init_ioport(&d->bus[1], 0x170, 0x376); + vt82c686b_init_ports(d); + + return 0; +} + +static int vt82c686b_ide_exitfn(PCIDevice *dev) +{ + PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev); + unsigned i; + + for (i = 0; i < 2; ++i) { + memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io); + memory_region_destroy(&d->bmdma[i].extra_io); + memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport); + memory_region_destroy(&d->bmdma[i].addr_ioport); + } + memory_region_destroy(&d->bmdma_bar); return 0; } @@ -176,15 +213,30 @@ void vt82c686b_ide_init(PCIBus *bus, Dri pci_ide_create_devs(dev, hd_table); } -static PCIDeviceInfo via_ide_info = { - .qdev.name = "via-ide", - .qdev.size = sizeof(PCIIDEState), - .qdev.no_user = 1, - .init = vt82c686b_ide_initfn, +static void via_ide_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + + k->init = vt82c686b_ide_initfn; + k->exit = vt82c686b_ide_exitfn; + k->vendor_id = PCI_VENDOR_ID_VIA; + k->device_id = PCI_DEVICE_ID_VIA_IDE; + k->revision = 0x06; + k->class_id = PCI_CLASS_STORAGE_IDE; + dc->no_user = 1; +} + +static TypeInfo via_ide_info = { + .name = "via-ide", + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(PCIIDEState), + .class_init = via_ide_class_init, }; -static void via_ide_register(void) +static void via_ide_register_types(void) { - pci_qdev_register(&via_ide_info); + type_register_static(&via_ide_info); } -device_init(via_ide_register); + +type_init(via_ide_register_types)