/* PCIe MMCFG */ static void mch_update_pciexbar(MCHPCIState *mch) { PCIDevice *pci_dev = PCI_DEVICE(mch); BusState *bus = qdev_get_parent_bus(DEVICE(mch)); PCIExpressHost *pehb = PCIE_HOST_BRIDGE(bus->parent); uint64_t pciexbar; int enable; uint64_t addr; uint64_t addr_mask; uint32_t length; pciexbar = pci_get_quad(pci_dev->config + MCH_HOST_BRIDGE_PCIEXBAR); enable = pciexbar & MCH_HOST_BRIDGE_PCIEXBAREN; addr_mask = MCH_HOST_BRIDGE_PCIEXBAR_ADMSK; switch (pciexbar & MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_MASK) { case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_256M: length = 256 * 1024 * 1024; break; case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_128M: length = 128 * 1024 * 1024; addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK | MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK; break; case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_64M: length = 64 * 1024 * 1024; addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK; break; case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_RVD: default: enable = 0; length = 0; abort(); break; } addr = pciexbar & addr_mask; pcie_host_mmcfg_update(pehb, enable, addr, length); /* Leave enough space for the MCFG BAR */ /* * TODO: this matches current bios behaviour, but it's not a power of two, * which means an MTRR can't cover it exactly. */ if (enable) { mch->pci_info.w32.begin = addr + length; } else { mch->pci_info.w32.begin = MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT; } }
static void q35_host_realize(DeviceState *dev, Error **errp) { PCIHostState *pci = PCI_HOST_BRIDGE(dev); Q35PCIHost *s = Q35_HOST_DEVICE(dev); SysBusDevice *sbd = SYS_BUS_DEVICE(dev); sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_ADDR, &pci->conf_mem); sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_ADDR, 4); sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, &pci->data_mem); sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, 4); if (pcie_host_init(PCIE_HOST_BRIDGE(s)) < 0) { error_setg(errp, "failed to initialize pcie host"); return; } pci->bus = pci_bus_new(DEVICE(s), "pcie.0", s->mch.pci_address_space, s->mch.address_space_io, 0, TYPE_PCIE_BUS); qdev_set_parent_bus(DEVICE(&s->mch), BUS(pci->bus)); qdev_init_nofail(DEVICE(&s->mch)); }
/* PCIe MMCFG */ static void mch_update_pciexbar(MCHPCIState *mch) { PCIDevice *pci_dev = PCI_DEVICE(mch); BusState *bus = qdev_get_parent_bus(DEVICE(mch)); PCIExpressHost *pehb = PCIE_HOST_BRIDGE(bus->parent); uint64_t pciexbar; int enable; uint64_t addr; uint64_t addr_mask; uint32_t length; pciexbar = pci_get_quad(pci_dev->config + MCH_HOST_BRIDGE_PCIEXBAR); enable = pciexbar & MCH_HOST_BRIDGE_PCIEXBAREN; addr_mask = MCH_HOST_BRIDGE_PCIEXBAR_ADMSK; switch (pciexbar & MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_MASK) { case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_256M: length = 256 * 1024 * 1024; break; case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_128M: length = 128 * 1024 * 1024; addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK | MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK; break; case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_64M: length = 64 * 1024 * 1024; addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK; break; case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_RVD: default: enable = 0; length = 0; abort(); break; } addr = pciexbar & addr_mask; pcie_host_mmcfg_update(pehb, enable, addr, length); }
static void pcie_host_init(Object *obj) { PCIExpressHost *e = PCIE_HOST_BRIDGE(obj); e->base_addr = PCIE_BASE_ADDR_UNMAPPED; }