PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
PCI_STATUS_DEVSEL_MEDIUM);
pci_set_byte(dev->config + PCI_REVISION_ID, 0x11);
- pci_set_byte(dev->config + PCI_HEADER_TYPE,
- pci_get_byte(dev->config + PCI_HEADER_TYPE) |
- PCI_HEADER_TYPE_MULTI_FUNCTION);
}
PCIBus *pci_apb_init(target_phys_addr_t special_base,
pci_set_word(d->wmask + PCI_BRIDGE_CONTROL, 0xffff);
}
+static int pci_init_multifunction(PCIBus *bus, PCIDevice *dev)
+{
+ uint8_t slot = PCI_SLOT(dev->devfn);
+ uint8_t func;
+
+ if (dev->cap_present & QEMU_PCI_CAP_MULTIFUNCTION) {
+ dev->config[PCI_HEADER_TYPE] |= PCI_HEADER_TYPE_MULTI_FUNCTION;
+ }
+
+ /*
+ * multifuction bit is interpreted in two ways as follows.
+ * - all functions must set the bit to 1.
+ * Example: Intel X53
+ * - function 0 must set the bit, but the rest function (> 0)
+ * is allowed to leave the bit to 0.
+ * Example: PIIX3(also in qemu), PIIX4(also in qemu), ICH10,
+ *
+ * So OS (at least Linux) checks the bit of only function 0,
+ * and doesn't see the bit of function > 0.
+ *
+ * The below check allows both interpretation.
+ */
+ if (PCI_FUNC(dev->devfn)) {
+ PCIDevice *f0 = bus->devices[PCI_DEVFN(slot, 0)];
+ if (f0 && !(f0->cap_present & QEMU_PCI_CAP_MULTIFUNCTION)) {
+ /* function 0 should set multifunction bit */
+ error_report("PCI: single function device can't be populated "
+ "in function %x.%x", slot, PCI_FUNC(dev->devfn));
+ return -1;
+ }
+ return 0;
+ }
+
+ if (dev->cap_present & QEMU_PCI_CAP_MULTIFUNCTION) {
+ return 0;
+ }
+ /* function 0 indicates single function, so function > 0 must be NULL */
+ for (func = 1; func < PCI_FUNC_MAX; ++func) {
+ if (bus->devices[PCI_DEVFN(slot, func)]) {
+ error_report("PCI: %x.0 indicates single function, "
+ "but %x.%x is already populated.",
+ slot, slot, func);
+ return -1;
+ }
+ }
+ return 0;
+}
+
static void pci_config_alloc(PCIDevice *pci_dev)
{
int config_size = pci_config_size(pci_dev);
if (is_bridge) {
pci_init_wmask_bridge(pci_dev);
}
+ if (pci_init_multifunction(bus, pci_dev)) {
+ pci_config_free(pci_dev);
+ return NULL;
+ }
if (!config_read)
config_read = pci_default_read_config;
pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_0); // 82371AB/EB/MB PIIX4 PCI-to-ISA bridge
pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA);
- pci_conf[PCI_HEADER_TYPE] =
- PCI_HEADER_TYPE_NORMAL | PCI_HEADER_TYPE_MULTI_FUNCTION; // header_type = PCI_multifunction, generic
piix4_dev = d;
qemu_register_reset(piix4_reset, d);
pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371SB_0); // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA);
- pci_conf[PCI_HEADER_TYPE] =
- PCI_HEADER_TYPE_NORMAL | PCI_HEADER_TYPE_MULTI_FUNCTION; // header_type = PCI_multifunction, generic
qemu_register_reset(piix3_reset, d);
return 0;