--- qemu/hw/ide/piix.c 2018/04/24 18:48:07 1.1.1.5 +++ qemu/hw/ide/piix.c 2018/04/24 19:30:26 1.1.1.7 @@ -27,17 +27,20 @@ #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; @@ -55,36 +58,46 @@ 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; } } -static void bmdma_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static MemoryRegionOps piix_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, "piix-bmdma-container", 16); for(i = 0;i < 2; i++) { BMDMAState *bm = &d->bmdma[i]; - 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); - - iorange_init(&bm->addr_ioport, &bmdma_addr_ioport_ops, addr + 4, 4); - ioport_register(&bm->addr_ioport); - addr += 8; + memory_region_init_io(&bm->extra_io, &piix_bmdma_ops, bm, + "piix-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); } } @@ -109,8 +122,7 @@ static void piix3_reset(void *opaque) } static void pci_piix_init_ports(PCIIDEState *d) { - int i; - struct { + static const struct { int iobase; int iobase2; int isairq; @@ -118,29 +130,32 @@ static void pci_piix_init_ports(PCIIDESt {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], port_info[i].iobase, port_info[i].iobase2); + ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase, + port_info[i].iobase2); ide_init2(&d->bus[i], isa_get_irq(port_info[i].isairq)); - bmdma_init(&d->bus[i], &d->bmdma[i]); + 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); } } -static int pci_piix_ide_initfn(PCIIDEState *d) +static int pci_piix_ide_initfn(PCIDevice *dev) { + PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev); uint8_t *pci_conf = d->dev.config; pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode - pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE); qemu_register_reset(piix3_reset, d); - pci_register_bar(&d->dev, 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(&d->dev.qdev, 0, &vmstate_ide_pci, d); @@ -149,22 +164,56 @@ static int pci_piix_ide_initfn(PCIIDESta return 0; } -static int pci_piix3_ide_initfn(PCIDevice *dev) +static int pci_piix3_xen_ide_unplug(DeviceState *dev) { - PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev); + PCIDevice *pci_dev; + PCIIDEState *pci_ide; + DriveInfo *di; + int i = 0; + + pci_dev = DO_UPCAST(PCIDevice, qdev, dev); + pci_ide = DO_UPCAST(PCIIDEState, dev, pci_dev); + + for (; i < 3; i++) { + di = drive_get_by_index(IF_IDE, i); + if (di != NULL && !di->media_cd) { + DeviceState *ds = bdrv_get_attached_dev(di->bdrv); + if (ds) { + bdrv_detach_dev(di->bdrv, ds); + } + bdrv_close(di->bdrv); + pci_ide->bus[di->bus].ifs[di->unit].bs = NULL; + drive_put_ref(di); + } + } + qdev_reset_all(&(pci_ide->dev.qdev)); + return 0; +} - pci_config_set_vendor_id(d->dev.config, PCI_VENDOR_ID_INTEL); - pci_config_set_device_id(d->dev.config, PCI_DEVICE_ID_INTEL_82371SB_1); - return pci_piix_ide_initfn(d); +PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn) +{ + PCIDevice *dev; + + dev = pci_create_simple(bus, devfn, "piix3-ide-xen"); + dev->qdev.info->unplug = pci_piix3_xen_ide_unplug; + pci_ide_create_devs(dev, hd_table); + return dev; } -static int pci_piix4_ide_initfn(PCIDevice *dev) +static int pci_piix_ide_exitfn(PCIDevice *dev) { PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev); + unsigned i; - pci_config_set_vendor_id(d->dev.config, PCI_VENDOR_ID_INTEL); - pci_config_set_device_id(d->dev.config, PCI_DEVICE_ID_INTEL_82371AB); - return pci_piix_ide_initfn(d); + 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; } /* hd_table must contain 4 block drivers */ @@ -195,13 +244,29 @@ static PCIDeviceInfo piix_ide_info[] = { .qdev.size = sizeof(PCIIDEState), .qdev.no_user = 1, .no_hotplug = 1, - .init = pci_piix3_ide_initfn, + .init = pci_piix_ide_initfn, + .exit = pci_piix_ide_exitfn, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_82371SB_1, + .class_id = PCI_CLASS_STORAGE_IDE, + },{ + .qdev.name = "piix3-ide-xen", + .qdev.size = sizeof(PCIIDEState), + .qdev.no_user = 1, + .init = pci_piix_ide_initfn, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_82371SB_1, + .class_id = PCI_CLASS_STORAGE_IDE, },{ .qdev.name = "piix4-ide", .qdev.size = sizeof(PCIIDEState), .qdev.no_user = 1, .no_hotplug = 1, - .init = pci_piix4_ide_initfn, + .init = pci_piix_ide_initfn, + .exit = pci_piix_ide_exitfn, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_82371AB, + .class_id = PCI_CLASS_STORAGE_IDE, },{ /* end of list */ }