diff --git a/hypervisor/dm/vpci/vpci_bridge.c b/hypervisor/dm/vpci/vpci_bridge.c index ab40ac006..854c79c84 100644 --- a/hypervisor/dm/vpci/vpci_bridge.c +++ b/hypervisor/dm/vpci/vpci_bridge.c @@ -37,8 +37,6 @@ * * for this emulation of vpci bridge, limitations set as following: * 1. all configure registers are readonly - * 2. BIST not support; by default is 0H - * 3. not support interrupt, including INTx and MSI. * * TODO: * 1. configure tool can select whether a PCI bridge is emulated or pass through @@ -55,7 +53,7 @@ static void init_vpci_bridge(struct pci_vdev *vdev) { - uint32_t offset, val, capoff, msgctrl; + uint32_t offset, val; /* read PCI config space to virtual space */ for (offset = 0x00U; offset < 0x100U; offset += 4U) { @@ -72,21 +70,6 @@ static void init_vpci_bridge(struct pci_vdev *vdev) pci_vdev_write_cfg_u8(vdev, PCIR_HDRTYPE, (uint8_t)(PCIM_HDRTYPE_BRIDGE | PCIM_MFDEV)); pci_vdev_write_cfg_u8(vdev, PCIR_CLASS, (uint8_t)PCIC_BRIDGE); pci_vdev_write_cfg_u8(vdev, PCIR_SUBCLASS, (uint8_t)PCIS_BRIDGE_PCI); - - /* for command regsiters, disable INTx */ - val = pci_pdev_read_cfg(vdev->pdev->bdf, PCIR_COMMAND, 2U); - pci_vdev_write_cfg_u16(vdev, PCIR_COMMAND, (uint16_t)val | PCIM_CMD_INTxDIS); - pci_pdev_write_cfg(vdev->pdev->bdf, PCIR_COMMAND, 2U, (uint16_t)val | PCIM_CMD_INTxDIS); - - /* disale MSI */ - if (vdev->pdev->msi_capoff != 0x00UL) { - capoff = vdev->pdev->msi_capoff; - msgctrl = pci_vdev_read_cfg(vdev, capoff + PCIR_MSI_CTRL, 2U); - - msgctrl &= ~PCIM_MSICTRL_MSI_ENABLE; - pci_pdev_write_cfg(vdev->pdev->bdf, capoff + PCIR_MSI_CTRL, 2U, msgctrl); - pci_vdev_write_cfg(vdev, capoff + PCIR_MSI_CTRL, 2U, msgctrl); - } } static void deinit_vpci_bridge(__unused struct pci_vdev *vdev) diff --git a/hypervisor/hw/pci.c b/hypervisor/hw/pci.c index da2b5d43a..83871f523 100644 --- a/hypervisor/hw/pci.c +++ b/hypervisor/hw/pci.c @@ -450,17 +450,37 @@ static void pci_parse_iommu_devscopes(struct pci_bdf_set *const bdfs_from_drhds, } } -/* do enabling or limitation to pci bridge */ -static void config_pci_bridge(struct pci_pdev *pdev) +/* + * There are some rules to config PCI bridge: try to avoid interference between SOS and RTVM or + * pre-launched VM; and to support some features like SRIOV by default, so as following: + * 1. disable interrupt, including INTx and MSI. + * 2. enable ARI if it's a PCIe bridge and all its sub devices support ARI (need check further). + * 3. enable ACS. (now assume BIOS does it), could check and do it in HV in the future. + * + */ +static void config_pci_bridge(const struct pci_pdev *pdev) { - uint32_t offset, val; + uint32_t offset, val, msgctrl; + + /* for command regsiters, disable INTx */ + val = pci_pdev_read_cfg(pdev->bdf, PCIR_COMMAND, 2U); + pci_pdev_write_cfg(pdev->bdf, PCIR_COMMAND, 2U, (uint16_t)val | PCIM_CMD_INTxDIS); + + /* disale MSI */ + if (pdev->msi_capoff != 0x00UL) { + offset = pdev->msi_capoff + PCIR_MSI_CTRL; + + msgctrl = pci_pdev_read_cfg(pdev->bdf, offset, 2U); + msgctrl &= ~PCIM_MSICTRL_MSI_ENABLE; + pci_pdev_write_cfg(pdev->bdf, offset, 2U, msgctrl); + } /* Enable ARI if PCIe bridge could support it for SRIOV needs it */ if (pdev->pcie_capoff != 0x00UL) { offset = pdev->pcie_capoff + PCIR_PCIE_DEVCAP2; val = pci_pdev_read_cfg(pdev->bdf, offset, 2U); - if (val & PCIM_PCIE_DEVCAP2_ARI) { + if ((val & PCIM_PCIE_DEVCAP2_ARI) != 0U) { offset = pdev->pcie_capoff + PCIR_PCIE_DEVCTL2; val = pci_pdev_read_cfg(pdev->bdf, offset, 2U);