/* default qdev initialization function for PCI-to-PCI bridge */ int pci_bridge_initfn(PCIDevice *dev) { PCIBus *parent = dev->bus; PCIBridge *br = DO_UPCAST(PCIBridge, dev, dev); PCIBus *sec_bus = &br->sec_bus; pci_set_word(dev->config + PCI_STATUS, PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK); pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_PCI); dev->config[PCI_HEADER_TYPE] = (dev->config[PCI_HEADER_TYPE] & PCI_HEADER_TYPE_MULTI_FUNCTION) | PCI_HEADER_TYPE_BRIDGE; pci_set_word(dev->config + PCI_SEC_STATUS, PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK); qbus_create_inplace(&sec_bus->qbus, &pci_bus_info, &dev->qdev, br->bus_name); sec_bus->parent_dev = dev; sec_bus->map_irq = br->map_irq; sec_bus->address_space_mem = &br->address_space_mem; memory_region_init(&br->address_space_mem, "pci_bridge_pci", INT64_MAX); sec_bus->address_space_io = &br->address_space_io; memory_region_init(&br->address_space_io, "pci_bridge_io", 65536); pci_bridge_region_init(br); QLIST_INIT(&sec_bus->child); QLIST_INSERT_HEAD(&parent->child, sec_bus, sibling); return 0; }
static int i6300esb_init(PCIDevice *dev) { I6300State *d = DO_UPCAST(I6300State, dev, dev); uint8_t *pci_conf; int io_mem; static CPUReadMemoryFunc * const mem_read[3] = { i6300esb_mem_readb, i6300esb_mem_readw, i6300esb_mem_readl, }; static CPUWriteMemoryFunc * const mem_write[3] = { i6300esb_mem_writeb, i6300esb_mem_writew, i6300esb_mem_writel, }; i6300esb_debug("I6300State = %p\n", d); d->timer = qemu_new_timer_ns(vm_clock, i6300esb_timer_expired, d); d->previous_reboot_flag = 0; pci_conf = d->dev.config; pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_ESB_9); pci_config_set_class(pci_conf, PCI_CLASS_SYSTEM_OTHER); io_mem = cpu_register_io_memory(mem_read, mem_write, d, DEVICE_NATIVE_ENDIAN); pci_register_bar_simple(&d->dev, 0, 0x10, 0, io_mem); /* qemu_register_coalesced_mmio (addr, 0x10); ? */ return 0; }
/* via ide func */ static int vt82c686b_ide_initfn(PCIDevice *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); 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); return 0; }
PCIBus *pci_prep_init(qemu_irq *pic) { PREPPCIState *s; PCIDevice *d; int PPC_io_memory; s = qemu_mallocz(sizeof(PREPPCIState)); s->bus = pci_register_bus(NULL, "pci", prep_set_irq, prep_map_irq, pic, 0, 4); pci_host_conf_register_ioport(0xcf8, s); pci_host_data_register_ioport(0xcfc, s); PPC_io_memory = cpu_register_io_memory(PPC_PCIIO_read, PPC_PCIIO_write, s); cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory); /* PCI host bridge */ d = pci_register_device(s->bus, "PREP Host Bridge - Motorola Raven", sizeof(PCIDevice), 0, NULL, NULL); pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_MOTOROLA); pci_config_set_device_id(d->config, PCI_DEVICE_ID_MOTOROLA_RAVEN); d->config[0x08] = 0x00; // revision pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST); d->config[0x0C] = 0x08; // cache_line_size d->config[0x0D] = 0x10; // latency_timer d->config[0x34] = 0x00; // capabilities_pointer return s->bus; }
/* XXX Interrupt acknowledge cycles not supported. */ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4], target_phys_addr_t config_space, target_phys_addr_t int_ack, target_phys_addr_t special_cycle, target_phys_addr_t registers) { PPC4xxPCIState *controller; int index; static int ppc4xx_pci_id; uint8_t *pci_conf; controller = qemu_mallocz(sizeof(PPC4xxPCIState)); controller->pci_state.bus = pci_register_bus(ppc4xx_pci_set_irq, ppc4xx_pci_map_irq, pci_irqs, 0, 4); controller->pci_dev = pci_register_device(controller->pci_state.bus, "host bridge", sizeof(PCIDevice), 0, NULL, NULL); pci_conf = controller->pci_dev->config; pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_IBM); pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_IBM_440GX); pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_OTHER); /* CFGADDR */ index = cpu_register_io_memory(0, pci4xx_cfgaddr_read, pci4xx_cfgaddr_write, controller); if (index < 0) goto free; cpu_register_physical_memory(config_space + PCIC0_CFGADDR, 4, index); /* CFGDATA */ index = cpu_register_io_memory(0, pci4xx_cfgdata_read, pci4xx_cfgdata_write, &controller->pci_state); if (index < 0) goto free; cpu_register_physical_memory(config_space + PCIC0_CFGDATA, 4, index); /* Internal registers */ index = cpu_register_io_memory(0, pci_reg_read, pci_reg_write, controller); if (index < 0) goto free; cpu_register_physical_memory(registers, PCI_REG_SIZE, index); qemu_register_reset(ppc4xx_pci_reset, controller); /* XXX load/save code not tested. */ register_savevm("ppc4xx_pci", ppc4xx_pci_id++, 1, ppc4xx_pci_save, ppc4xx_pci_load, controller); return controller->pci_state.bus; free: printf("%s error\n", __func__); qemu_free(controller); return NULL; }
static int dec_21154_pci_host_init(PCIDevice *d) { /* PCI2PCI bridge same values as PearPC - check this */ pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_DEC); pci_config_set_device_id(d->config, PCI_DEVICE_ID_DEC_21154); pci_set_byte(d->config + PCI_REVISION_ID, 0x02); pci_config_set_class(d->config, PCI_CLASS_BRIDGE_PCI); return 0; }
static int versatile_pci_host_init(PCIDevice *d) { pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_XILINX); /* Both boards have the same device ID. Oh well. */ pci_config_set_device_id(d->config, PCI_DEVICE_ID_XILINX_XC2VP30); pci_set_word(d->config + PCI_STATUS, PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_MEDIUM); pci_config_set_class(d->config, PCI_CLASS_PROCESSOR_CO); pci_set_byte(d->config + PCI_LATENCY_TIMER, 0x10); return 0; }
static int pci_pcnet_init(PCIDevice *pci_dev) { PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, pci_dev); PCNetState *s = &d->state; uint8_t *pci_conf; #if 0 printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n", sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD)); #endif pci_conf = pci_dev->config; pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_AMD); pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_AMD_LANCE); pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM); pci_conf[PCI_REVISION_ID] = 0x10; pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET); pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, 0x0); pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, 0x0); pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0 pci_conf[PCI_MIN_GNT] = 0x06; pci_conf[PCI_MAX_LAT] = 0xff; /* Handler for memory-mapped I/O */ s->mmio_index = cpu_register_io_memory(pcnet_mmio_read, pcnet_mmio_write, &d->state, DEVICE_NATIVE_ENDIAN); pci_register_bar(pci_dev, 0, PCNET_IOPORT_SIZE, PCI_BASE_ADDRESS_SPACE_IO, pcnet_ioport_map); pci_register_bar_simple(pci_dev, 1, PCNET_PNPMMIO_SIZE, 0, s->mmio_index); s->irq = pci_dev->irq[0]; s->phys_mem_read = pci_physical_memory_read; s->phys_mem_write = pci_physical_memory_write; if (!pci_dev->qdev.hotplugged) { static int loaded = 0; if (!loaded) { rom_add_option("pxe-pcnet.rom", -1); loaded = 1; } } return pcnet_common_init(&pci_dev->qdev, s, &net_pci_pcnet_info); }
static int pci_piix_ide_initfn(PCIIDEState *d) { 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); vmstate_register(&d->dev.qdev, 0, &vmstate_ide_pci, d); pci_piix_init_ports(d); return 0; }
static void pci_ebus_init1(PCIDevice *s) { pci_config_set_vendor_id(s->config, PCI_VENDOR_ID_SUN); pci_config_set_device_id(s->config, PCI_DEVICE_ID_SUN_EBUS); s->config[0x04] = 0x06; // command = bus master, pci mem s->config[0x05] = 0x00; s->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error s->config[0x07] = 0x03; // status = medium devsel s->config[0x08] = 0x01; // revision s->config[0x09] = 0x00; // programming i/f pci_config_set_class(s->config, PCI_CLASS_BRIDGE_OTHER); s->config[0x0D] = 0x0a; // latency_timer s->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type pci_register_bar(s, 0, 0x1000000, PCI_ADDRESS_SPACE_MEM, ebus_mmio_mapfunc); pci_register_bar(s, 1, 0x800000, PCI_ADDRESS_SPACE_MEM, ebus_mmio_mapfunc); }
static int pci_ebus_init1(PCIDevice *s) { isa_bus_new(&s->qdev); pci_config_set_vendor_id(s->config, PCI_VENDOR_ID_SUN); pci_config_set_device_id(s->config, PCI_DEVICE_ID_SUN_EBUS); s->config[0x04] = 0x06; // command = bus master, pci mem s->config[0x05] = 0x00; s->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error s->config[0x07] = 0x03; // status = medium devsel s->config[0x08] = 0x01; // revision s->config[0x09] = 0x00; // programming i/f pci_config_set_class(s->config, PCI_CLASS_BRIDGE_OTHER); s->config[0x0D] = 0x0a; // latency_timer pci_register_bar(s, 0, 0x1000000, PCI_BASE_ADDRESS_SPACE_MEMORY, ebus_mmio_mapfunc); pci_register_bar(s, 1, 0x800000, PCI_BASE_ADDRESS_SPACE_MEMORY, ebus_mmio_mapfunc); return 0; }
void macio_init (PCIBus *bus, int device_id, int is_oldworld, MemoryRegion *pic_mem, MemoryRegion *dbdma_mem, MemoryRegion *cuda_mem, void *nvram, int nb_ide, MemoryRegion **ide_mem, MemoryRegion *escc_mem) { PCIDevice *d; macio_state_t *macio_state; int i; d = pci_register_device(bus, "macio", sizeof(PCIDevice) + sizeof(macio_state_t), -1, NULL, NULL); macio_state = (macio_state_t *)(d + 1); macio_state->is_oldworld = is_oldworld; macio_state->pic_mem = pic_mem; macio_state->dbdma_mem = dbdma_mem; macio_state->cuda_mem = cuda_mem; macio_state->escc_mem = escc_mem; macio_state->nvram = nvram; if (nb_ide > 4) nb_ide = 4; macio_state->nb_ide = nb_ide; for (i = 0; i < nb_ide; i++) macio_state->ide_mem[i] = ide_mem[i]; for (; i < 4; i++) macio_state->ide_mem[i] = NULL; /* Note: this code is strongly inspirated from the corresponding code in PearPC */ pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE); pci_config_set_device_id(d->config, device_id); pci_config_set_class(d->config, PCI_CLASS_OTHERS << 8); d->config[0x3d] = 0x01; // interrupt on pin 1 macio_bar_setup(macio_state); pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &macio_state->bar); }
/* default qdev initialization function for PCI-to-PCI bridge */ int pci_bridge_initfn(PCIDevice *dev) { PCIBus *parent = dev->bus; PCIBridge *br = DO_UPCAST(PCIBridge, dev, dev); PCIBus *sec_bus = &br->sec_bus; pci_word_test_and_set_mask(dev->config + PCI_STATUS, PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK); pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_PCI); dev->config[PCI_HEADER_TYPE] = (dev->config[PCI_HEADER_TYPE] & PCI_HEADER_TYPE_MULTI_FUNCTION) | PCI_HEADER_TYPE_BRIDGE; pci_set_word(dev->config + PCI_SEC_STATUS, PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK); /* * If we don't specify the name, the bus will be addressed as <id>.0, where * id is the device id. * Since PCI Bridge devices have a single bus each, we don't need the index: * let users address the bus using the device name. */ if (!br->bus_name && dev->qdev.id && *dev->qdev.id) { br->bus_name = dev->qdev.id; } qbus_create_inplace(&sec_bus->qbus, TYPE_PCI_BUS, &dev->qdev, br->bus_name); sec_bus->parent_dev = dev; sec_bus->map_irq = br->map_irq; sec_bus->address_space_mem = &br->address_space_mem; memory_region_init(&br->address_space_mem, "pci_bridge_pci", INT64_MAX); sec_bus->address_space_io = &br->address_space_io; memory_region_init(&br->address_space_io, "pci_bridge_io", 65536); pci_bridge_region_init(br); QLIST_INIT(&sec_bus->child); QLIST_INSERT_HEAD(&parent->child, sec_bus, sibling); return 0; }
/* EBUS (Eight bit bus) bridge */ static void pci_ebus_init(PCIBus *bus, int devfn) { PCIDevice *s; s = pci_register_device(bus, "EBUS", sizeof(*s), devfn, NULL, NULL); pci_config_set_vendor_id(s->config, PCI_VENDOR_ID_SUN); pci_config_set_device_id(s->config, PCI_DEVICE_ID_SUN_EBUS); s->config[0x04] = 0x06; // command = bus master, pci mem s->config[0x05] = 0x00; s->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error s->config[0x07] = 0x03; // status = medium devsel s->config[0x08] = 0x01; // revision s->config[0x09] = 0x00; // programming i/f pci_config_set_class(s->config, PCI_CLASS_BRIDGE_OTHER); s->config[0x0D] = 0x0a; // latency_timer s->config[0x0E] = 0x00; // header_type pci_register_io_region(s, 0, 0x1000000, PCI_ADDRESS_SPACE_MEM, ebus_mmio_mapfunc); pci_register_io_region(s, 1, 0x800000, PCI_ADDRESS_SPACE_MEM, ebus_mmio_mapfunc); }
PCIBus *pci_pmac_init(qemu_irq *pic) { UNINState *s; PCIDevice *d; int pci_mem_config, pci_mem_data; /* Use values found on a real PowerMac */ /* Uninorth main bus */ s = qemu_mallocz(sizeof(UNINState)); s->bus = pci_register_bus(NULL, "pci", pci_unin_set_irq, pci_unin_map_irq, pic, 11 << 3, 4); pci_mem_config = cpu_register_io_memory(pci_unin_main_config_read, pci_unin_main_config_write, s); pci_mem_data = cpu_register_io_memory(pci_unin_main_read, pci_unin_main_write, s); cpu_register_physical_memory(0xf2800000, 0x1000, pci_mem_config); cpu_register_physical_memory(0xf2c00000, 0x1000, pci_mem_data); d = pci_register_device(s->bus, "Uni-north main", sizeof(PCIDevice), 11 << 3, NULL, NULL); pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE); pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_UNI_N_PCI); d->config[0x08] = 0x00; // revision pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST); d->config[0x0C] = 0x08; // cache_line_size d->config[0x0D] = 0x10; // latency_timer d->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type d->config[0x34] = 0x00; // capabilities_pointer #if 0 // XXX: not activated as PPC BIOS doesn't handle multiple buses properly /* pci-to-pci bridge */ d = pci_register_device("Uni-north bridge", sizeof(PCIDevice), 0, 13 << 3, NULL, NULL); pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_DEC); pci_config_set_device_id(d->config, PCI_DEVICE_ID_DEC_21154); d->config[0x08] = 0x05; // revision pci_config_set_class(d->config, PCI_CLASS_BRIDGE_PCI); d->config[0x0C] = 0x08; // cache_line_size d->config[0x0D] = 0x20; // latency_timer d->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_BRIDGE; // header_type d->config[0x18] = 0x01; // primary_bus d->config[0x19] = 0x02; // secondary_bus d->config[0x1A] = 0x02; // subordinate_bus d->config[0x1B] = 0x20; // secondary_latency_timer d->config[0x1C] = 0x11; // io_base d->config[0x1D] = 0x01; // io_limit d->config[0x20] = 0x00; // memory_base d->config[0x21] = 0x80; d->config[0x22] = 0x00; // memory_limit d->config[0x23] = 0x80; d->config[0x24] = 0x01; // prefetchable_memory_base d->config[0x25] = 0x80; d->config[0x26] = 0xF1; // prefectchable_memory_limit d->config[0x27] = 0x7F; // d->config[0x34] = 0xdc // capabilities_pointer #endif /* Uninorth AGP bus */ pci_mem_config = cpu_register_io_memory(pci_unin_config_read, pci_unin_config_write, s); pci_mem_data = cpu_register_io_memory(pci_unin_main_read, pci_unin_main_write, s); cpu_register_physical_memory(0xf0800000, 0x1000, pci_mem_config); cpu_register_physical_memory(0xf0c00000, 0x1000, pci_mem_data); d = pci_register_device(s->bus, "Uni-north AGP", sizeof(PCIDevice), 11 << 3, NULL, NULL); pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE); pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_UNI_N_AGP); d->config[0x08] = 0x00; // revision pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST); d->config[0x0C] = 0x08; // cache_line_size d->config[0x0D] = 0x10; // latency_timer d->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type // d->config[0x34] = 0x80; // capabilities_pointer #if 0 // XXX: not needed for now /* Uninorth internal bus */ s = &pci_bridge[2]; pci_mem_config = cpu_register_io_memory(pci_unin_config_read, pci_unin_config_write, s); pci_mem_data = cpu_register_io_memory(pci_unin_read, pci_unin_write, s); cpu_register_physical_memory(0xf4800000, 0x1000, pci_mem_config); cpu_register_physical_memory(0xf4c00000, 0x1000, pci_mem_data); d = pci_register_device("Uni-north internal", sizeof(PCIDevice), 3, 11 << 3, NULL, NULL); pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE); pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_UNI_N_I_PCI); d->config[0x08] = 0x00; // revision pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST); d->config[0x0C] = 0x08; // cache_line_size d->config[0x0D] = 0x10; // latency_timer d->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type d->config[0x34] = 0x00; // capabilities_pointer #endif register_savevm("uninorth", 0, 1, pci_unin_save, pci_unin_load, d); qemu_register_reset(pci_unin_reset, d); pci_unin_reset(d); return s->bus; }
static int pci_ivshmem_init(PCIDevice *dev) { IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev); uint8_t *pci_conf; if (s->sizearg == NULL) s->ivshmem_size = 4 << 20; /* 4 MB default */ else { s->ivshmem_size = ivshmem_get_size(s); } register_savevm(&s->dev.qdev, "ivshmem", 0, 0, ivshmem_save, ivshmem_load, dev); /* IRQFD requires MSI */ if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD) && !ivshmem_has_feature(s, IVSHMEM_MSI)) { fprintf(stderr, "ivshmem: ioeventfd/irqfd requires MSI\n"); exit(1); } /* check that role is reasonable */ if (s->role) { if (strncmp(s->role, "peer", 5) == 0) { s->role_val = IVSHMEM_PEER; } else if (strncmp(s->role, "master", 7) == 0) { s->role_val = IVSHMEM_MASTER; } else { fprintf(stderr, "ivshmem: 'role' must be 'peer' or 'master'\n"); exit(1); } } else { s->role_val = IVSHMEM_MASTER; /* default */ } if (s->role_val == IVSHMEM_PEER) { register_device_unmigratable(&s->dev.qdev, "ivshmem", s); } pci_conf = s->dev.config; pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REDHAT_QUMRANET); pci_conf[0x02] = 0x10; pci_conf[0x03] = 0x11; pci_conf[PCI_COMMAND] = PCI_COMMAND_IO | PCI_COMMAND_MEMORY; pci_config_set_class(pci_conf, PCI_CLASS_MEMORY_RAM); pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; pci_config_set_interrupt_pin(pci_conf, 1); s->shm_pci_addr = 0; s->ivshmem_offset = 0; s->shm_fd = 0; s->ivshmem_mmio_io_addr = cpu_register_io_memory(ivshmem_mmio_read, ivshmem_mmio_write, s); /* region for registers*/ pci_register_bar(&s->dev, 0, IVSHMEM_REG_BAR_SIZE, PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_mmio_map); if ((s->server_chr != NULL) && (strncmp(s->server_chr->filename, "unix:", 5) == 0)) { /* if we get a UNIX socket as the parameter we will talk * to the ivshmem server to receive the memory region */ if (s->shmobj != NULL) { fprintf(stderr, "WARNING: do not specify both 'chardev' " "and 'shm' with ivshmem\n"); } IVSHMEM_DPRINTF("using shared memory server (socket = %s)\n", s->server_chr->filename); if (ivshmem_has_feature(s, IVSHMEM_MSI)) { ivshmem_setup_msi(s); } /* we allocate enough space for 16 guests and grow as needed */ s->nb_peers = 16; s->vm_id = -1; /* allocate/initialize space for interrupt handling */ s->peers = qemu_mallocz(s->nb_peers * sizeof(Peer)); pci_register_bar(&s->dev, 2, s->ivshmem_size, PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_map); s->eventfd_chr = qemu_mallocz(s->vectors * sizeof(CharDriverState *)); qemu_chr_add_handlers(s->server_chr, ivshmem_can_receive, ivshmem_read, ivshmem_event, s); } else { /* just map the file immediately, we're not using a server */ int fd; if (s->shmobj == NULL) { fprintf(stderr, "Must specify 'chardev' or 'shm' to ivshmem\n"); } IVSHMEM_DPRINTF("using shm_open (shm object = %s)\n", s->shmobj); /* try opening with O_EXCL and if it succeeds zero the memory * by truncating to 0 */ if ((fd = shm_open(s->shmobj, O_CREAT|O_RDWR|O_EXCL, S_IRWXU|S_IRWXG|S_IRWXO)) > 0) { /* truncate file to length PCI device's memory */ if (ftruncate(fd, s->ivshmem_size) != 0) { fprintf(stderr, "ivshmem: could not truncate shared file\n"); } } else if ((fd = shm_open(s->shmobj, O_CREAT|O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO)) < 0) { fprintf(stderr, "ivshmem: could not open shared file\n"); exit(-1); } if (check_shm_size(s, fd) == -1) { exit(-1); } create_shared_memory_BAR(s, fd); } return 0; }