static void pci_tnetw1130_uninit(PCIDevice *pci_dev) { TNETW1130State *s = DO_UPCAST(TNETW1130State, dev, pci_dev); memory_region_destroy(&s->mmio_bar0); memory_region_destroy(&s->mmio_bar1); qemu_del_nic(s->tnetw1130.nic); }
static void pci_bridge_region_cleanup(PCIBridge *br, PCIBridgeWindows *w) { memory_region_destroy(&w->alias_io); memory_region_destroy(&w->alias_mem); memory_region_destroy(&w->alias_pref_mem); g_free(w); }
static int pci_pcnet_uninit(PCIDevice *dev) { PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, dev); memory_region_destroy(&d->state.mmio); memory_region_destroy(&d->io_bar); qemu_del_timer(d->state.poll_timer); qemu_free_timer(d->state.poll_timer); qemu_del_vlan_client(&d->state.nic->nc); return 0; }
/* default qdev clean up function for PCI-to-PCI bridge */ int pci_bridge_exitfn(PCIDevice *pci_dev) { PCIBridge *s = DO_UPCAST(PCIBridge, dev, pci_dev); assert(QLIST_EMPTY(&s->sec_bus.child)); QLIST_REMOVE(&s->sec_bus, sibling); pci_bridge_region_cleanup(s); memory_region_destroy(&s->address_space_mem); memory_region_destroy(&s->address_space_io); /* qbus_free() is called automatically by qdev_free() */ return 0; }
static int pci_ivshmem_uninit(PCIDevice *dev) { IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev); memory_region_destroy(&s->ivshmem_mmio); memory_region_del_subregion(&s->bar, &s->ivshmem); memory_region_destroy(&s->ivshmem); memory_region_destroy(&s->bar); unregister_savevm(&dev->qdev, "ivshmem", s); return 0; }
static void pci_piix_ide_exitfn(PCIDevice *dev) { PCIIDEState *d = PCI_IDE(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); }
static void multi_serial_pci_exit(PCIDevice *dev) { PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev); SerialState *s; int i; for (i = 0; i < pci->ports; i++) { s = pci->state + i; serial_exit_core(s); memory_region_destroy(&s->io); g_free(pci->name[i]); } memory_region_destroy(&pci->iobar); qemu_free_irqs(pci->irqs); }
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; }
static void pci_cmd646_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->cmd646_bar[i].cmd); memory_region_destroy(&d->cmd646_bar[i].data); } memory_region_destroy(&d->bmdma_bar); }
static void tpm_tis_uninitfn(Object *obj) { TPMState *s = TPM(obj); memory_region_del_subregion(get_system_memory(), &s->mmio); memory_region_destroy(&s->mmio); }
static int f2xx_flash_init(SysBusDevice *dev) { f2xx_flash_t *flash = FROM_SYSBUS(typeof(*flash), dev); // memory_region_init_rom_device(&flash->mem, &f2xx_flash_ops, flash, "name", // size); memory_region_init_ram(&flash->mem, NULL, "f2xx.flash", flash->size); vmstate_register_ram(&flash->mem, DEVICE(flash)); //vmstate_register_ram_global(&flash->mem); memory_region_set_readonly(&flash->mem, true); memory_region_add_subregion(get_system_memory(), flash->base_address, &flash->mem); // sysbus_init_mmio(dev, &flash->mem); flash->data = memory_region_get_ram_ptr(&flash->mem); memset(flash->data, 0xff, flash->size); if (flash->bdrv) { int r; r = bdrv_read(flash->bdrv, 0, flash->data, bdrv_getlength(flash->bdrv)/BDRV_SECTOR_SIZE); if (r < 0) { vmstate_unregister_ram(&flash->mem, DEVICE(flash)); memory_region_destroy(&flash->mem); return 1; } } return 0; }
void msix_uninit_exclusive_bar(PCIDevice *dev) { if (msix_present(dev)) { msix_uninit(dev, &dev->msix_exclusive_bar, &dev->msix_exclusive_bar); memory_region_destroy(&dev->msix_exclusive_bar); } }
static void pci_ivshmem_uninit(PCIDevice *dev) { IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev); if (s->migration_blocker) { migrate_del_blocker(s->migration_blocker); error_free(s->migration_blocker); } memory_region_destroy(&s->ivshmem_mmio); memory_region_del_subregion(&s->bar, &s->ivshmem); vmstate_unregister_ram(&s->ivshmem, &s->dev.qdev); memory_region_destroy(&s->ivshmem); memory_region_destroy(&s->bar); unregister_savevm(&dev->qdev, "ivshmem", s); }
static void serial_pci_exit(PCIDevice *dev) { PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev); SerialState *s = &pci->state; serial_exit_core(s); memory_region_destroy(&s->io); }
static void pci_testdev_uninit(PCIDevice *dev) { PCITestDevState *d = DO_UPCAST(PCITestDevState, dev, dev); int i; pci_testdev_reset(d); for (i = 0; i < IOTEST_MAX; ++i) { if (d->tests[i].hasnotifier) { event_notifier_cleanup(&d->tests[i].notifier); } g_free(d->tests[i].hdr); } g_free(d->tests); memory_region_destroy(&d->mmio); memory_region_destroy(&d->portio); }
void pcie_host_mmcfg_unmap(PCIExpressHost *e) { if (e->base_addr != PCIE_BASE_ADDR_UNMAPPED) { memory_region_del_subregion(get_system_memory(), &e->mmio); memory_region_destroy(&e->mmio); e->base_addr = PCIE_BASE_ADDR_UNMAPPED; } }
static void vigs_device_exit(PCIDevice *dev) { VIGSState *s = DO_UPCAST(VIGSState, dev.pci_dev, dev); vigs_server_destroy(s->server); qemu_bh_delete(s->fence_ack_bh); vigs_fenceman_destroy(s->fenceman); memory_region_destroy(&s->io_bar); memory_region_destroy(&s->ram_bar); memory_region_destroy(&s->vram_bar); VIGS_LOG_INFO("VIGS deinitialized"); vigs_log_cleanup(); }
void portio_list_del(PortioList *piolist) { MemoryRegion *mr, *alias; unsigned i; for (i = 0; i < piolist->nr; ++i) { mr = piolist->regions[i]; alias = piolist->aliases[i]; memory_region_del_subregion(piolist->address_space, alias); memory_region_destroy(alias); memory_region_destroy(mr); g_free((MemoryRegionOps *)mr->ops); g_free(mr); g_free(alias); piolist->regions[i] = NULL; piolist->aliases[i] = NULL; } }
static int pci_fake_uninit(PCIDevice *dev) { PCIFakeState *d = DO_UPCAST(PCIFakeState, dev, dev); for (int i=0; i<d->fake_pci.num_resources; ++i) { memory_region_destroy(&d->io[i]); } return 0; }
static void pci_bridge_dev_exitfn(PCIDevice *dev) { PCIBridgeDev *bridge_dev = PCI_BRIDGE_DEV(dev); if (msi_present(dev)) { msi_uninit(dev); } slotid_cap_cleanup(dev); shpc_cleanup(dev, &bridge_dev->bar); memory_region_destroy(&bridge_dev->bar); pci_bridge_exitfn(dev); }
static void nic_cleanup(VLANClientState *nc) { dp8393xState *s = DO_UPCAST(NICState, nc, nc)->opaque; memory_region_del_subregion(s->address_space, &s->mmio); memory_region_destroy(&s->mmio); qemu_del_timer(s->watchdog); qemu_free_timer(s->watchdog); g_free(s); }
static void pci_bridge_dev_exitfn(PCIDevice *dev) { PCIBridge *br = DO_UPCAST(PCIBridge, dev, dev); PCIBridgeDev *bridge_dev = DO_UPCAST(PCIBridgeDev, bridge, br); if (msi_present(dev)) { msi_uninit(dev); } slotid_cap_cleanup(dev); shpc_cleanup(dev, &bridge_dev->bar); memory_region_destroy(&bridge_dev->bar); pci_bridge_exitfn(dev); }
/* Clean up resources for the device. */ void msix_uninit(PCIDevice *dev, MemoryRegion *table_bar, MemoryRegion *pba_bar) { if (!msix_present(dev)) { return; } pci_del_capability(dev, PCI_CAP_ID_MSIX, MSIX_CAP_LENGTH); dev->msix_cap = 0; msix_free_irq_entries(dev); dev->msix_entries_nr = 0; memory_region_del_subregion(pba_bar, &dev->msix_pba_mmio); memory_region_destroy(&dev->msix_pba_mmio); g_free(dev->msix_pba); dev->msix_pba = NULL; memory_region_del_subregion(table_bar, &dev->msix_table_mmio); memory_region_destroy(&dev->msix_table_mmio); g_free(dev->msix_table); dev->msix_table = NULL; g_free(dev->msix_entry_used); dev->msix_entry_used = NULL; dev->cap_present &= ~QEMU_PCI_CAP_MSIX; }
static int pci_bridge_dev_exitfn(PCIDevice *dev) { PCIBridge *br = DO_UPCAST(PCIBridge, dev, dev); PCIBridgeDev *bridge_dev = DO_UPCAST(PCIBridgeDev, bridge, br); int ret; if (msi_present(dev)) { msi_uninit(dev); } slotid_cap_cleanup(dev); shpc_cleanup(dev, &bridge_dev->bar); memory_region_destroy(&bridge_dev->bar); ret = pci_bridge_exitfn(dev); assert(!ret); return 0; }
static void pci_bridge_region_cleanup(PCIBridge *br, PCIBridgeWindows *w) { memory_region_destroy(&w->alias_io); memory_region_destroy(&w->alias_mem); memory_region_destroy(&w->alias_pref_mem); memory_region_destroy(&w->alias_vga[QEMU_PCI_VGA_IO_LO]); memory_region_destroy(&w->alias_vga[QEMU_PCI_VGA_IO_HI]); memory_region_destroy(&w->alias_vga[QEMU_PCI_VGA_MEM]); g_free(w); }
/* Initialize the MSI-X structures. Note: if MSI-X is supported, BAR size is * modified, it should be retrieved with msix_bar_size. */ int msix_init(struct PCIDevice *dev, unsigned short nentries, MemoryRegion *bar, unsigned bar_nr, unsigned bar_size) { int ret; /* Nothing to do if MSI is not supported by interrupt controller */ if (!msix_supported || (kvm_enabled() && kvm_irqchip_in_kernel() && !kvm_has_gsi_routing())) { return -ENOTSUP; } if (nentries > MSIX_MAX_ENTRIES) return -EINVAL; dev->msix_mask_notifier = NULL; dev->msix_entry_used = g_malloc0(MSIX_MAX_ENTRIES * sizeof *dev->msix_entry_used); dev->msix_table_page = g_malloc0(MSIX_PAGE_SIZE); msix_mask_all(dev, nentries); memory_region_init_io(&dev->msix_mmio, &msix_mmio_ops, dev, "msix", MSIX_PAGE_SIZE); dev->msix_entries_nr = nentries; ret = msix_add_config(dev, nentries, bar_nr, bar_size); if (ret) goto err_config; if (kvm_enabled() && kvm_irqchip_in_kernel()) { dev->msix_irq_entries = g_malloc(nentries * sizeof *dev->msix_irq_entries); } dev->cap_present |= QEMU_PCI_CAP_MSIX; msix_mmio_setup(dev, bar); return 0; err_config: dev->msix_entries_nr = 0; memory_region_destroy(&dev->msix_mmio); g_free(dev->msix_table_page); dev->msix_table_page = NULL; g_free(dev->msix_entry_used); dev->msix_entry_used = NULL; return ret; }
/* Clean up resources for the device. */ int msix_uninit(PCIDevice *dev, MemoryRegion *bar) { if (!(dev->cap_present & QEMU_PCI_CAP_MSIX)) return 0; pci_del_capability(dev, PCI_CAP_ID_MSIX, MSIX_CAP_LENGTH); dev->msix_cap = 0; msix_free_irq_entries(dev); dev->msix_entries_nr = 0; memory_region_del_subregion(bar, &dev->msix_mmio); memory_region_destroy(&dev->msix_mmio); qemu_free(dev->msix_table_page); dev->msix_table_page = NULL; qemu_free(dev->msix_entry_used); dev->msix_entry_used = NULL; dev->cap_present &= ~QEMU_PCI_CAP_MSIX; return 0; }
static int pci_bridge_dev_initfn(PCIDevice *dev) { PCIBridge *br = DO_UPCAST(PCIBridge, dev, dev); PCIBridgeDev *bridge_dev = DO_UPCAST(PCIBridgeDev, bridge, br); int err, ret; pci_bridge_map_irq(br, NULL, pci_bridge_dev_map_irq_fn); err = pci_bridge_initfn(dev); if (err) { goto bridge_error; } memory_region_init(&bridge_dev->bar, "shpc-bar", shpc_bar_size(dev)); err = shpc_init(dev, &br->sec_bus, &bridge_dev->bar, 0); if (err) { goto shpc_error; } err = slotid_cap_init(dev, 0, bridge_dev->chassis_nr, 0); if (err) { goto slotid_error; } if ((bridge_dev->flags & (1 << PCI_BRIDGE_DEV_F_MSI_REQ)) && msi_supported) { err = msi_init(dev, 0, 1, true, true); if (err < 0) { goto msi_error; } } /* TODO: spec recommends using 64 bit prefetcheable BAR. * Check whether that works well. */ pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64, &bridge_dev->bar); dev->config[PCI_INTERRUPT_PIN] = 0x1; return 0; msi_error: slotid_cap_cleanup(dev); slotid_error: shpc_cleanup(dev, &bridge_dev->bar); shpc_error: memory_region_destroy(&bridge_dev->bar); ret = pci_bridge_exitfn(dev); assert(!ret); bridge_error: return err; }
/* Initialize the MSI-X structures. Note: if MSI-X is supported, BAR size is * modified, it should be retrieved with msix_bar_size. */ int msix_init(struct PCIDevice *dev, unsigned short nentries, MemoryRegion *bar, unsigned bar_nr, unsigned bar_size) { int ret; /* Nothing to do if MSI is not supported by interrupt controller */ if (!msix_supported) return -ENOTSUP; if (nentries > MSIX_MAX_ENTRIES) return -EINVAL; dev->msix_entry_used = qemu_mallocz(MSIX_MAX_ENTRIES * sizeof *dev->msix_entry_used); dev->msix_table_page = qemu_mallocz(MSIX_PAGE_SIZE); msix_mask_all(dev, nentries); memory_region_init_io(&dev->msix_mmio, &msix_mmio_ops, dev, "msix", MSIX_PAGE_SIZE); dev->msix_entries_nr = nentries; ret = msix_add_config(dev, nentries, bar_nr, bar_size); if (ret) goto err_config; dev->cap_present |= QEMU_PCI_CAP_MSIX; msix_mmio_setup(dev, bar); return 0; err_config: dev->msix_entries_nr = 0; memory_region_destroy(&dev->msix_mmio); qemu_free(dev->msix_table_page); dev->msix_table_page = NULL; qemu_free(dev->msix_entry_used); dev->msix_entry_used = NULL; return ret; }
int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries, uint8_t bar_nr) { int ret; char *name; /* * Migration compatibility dictates that this remains a 4k * BAR with the vector table in the lower half and PBA in * the upper half. Do not use these elsewhere! */ #define MSIX_EXCLUSIVE_BAR_SIZE 4096 #define MSIX_EXCLUSIVE_BAR_TABLE_OFFSET 0 #define MSIX_EXCLUSIVE_BAR_PBA_OFFSET (MSIX_EXCLUSIVE_BAR_SIZE / 2) #define MSIX_EXCLUSIVE_CAP_OFFSET 0 if (nentries * PCI_MSIX_ENTRY_SIZE > MSIX_EXCLUSIVE_BAR_PBA_OFFSET) { return -EINVAL; } name = g_strdup_printf("%s-msix", dev->name); memory_region_init(&dev->msix_exclusive_bar, OBJECT(dev), name, MSIX_EXCLUSIVE_BAR_SIZE); g_free(name); ret = msix_init(dev, nentries, &dev->msix_exclusive_bar, bar_nr, MSIX_EXCLUSIVE_BAR_TABLE_OFFSET, &dev->msix_exclusive_bar, bar_nr, MSIX_EXCLUSIVE_BAR_PBA_OFFSET, MSIX_EXCLUSIVE_CAP_OFFSET); if (ret) { memory_region_destroy(&dev->msix_exclusive_bar); return ret; } pci_register_bar(dev, bar_nr, PCI_BASE_ADDRESS_SPACE_MEMORY, &dev->msix_exclusive_bar); return 0; }