mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-19 12:12:16 +00:00
dm: PTM: Add virtual root port to vm
If PTM can be enabled on passthru device, a virtual root port is added to vm to act as ptm root. And the passthru device is connected to the virtual root port instead of the virtual host bridge. Tracked-On: #5915 Signed-off-by: Rong Liu <rong.l.liu@intel.com> Acked-by: Yu Wang <yu1.wang@intel.com>
This commit is contained in:
parent
d5d792aa96
commit
7e93f31e2c
@ -18,6 +18,10 @@
|
|||||||
#include "passthru.h"
|
#include "passthru.h"
|
||||||
#include "pci_util.h"
|
#include "pci_util.h"
|
||||||
#include "vmmapi.h"
|
#include "vmmapi.h"
|
||||||
|
#include "acrn_common.h"
|
||||||
|
|
||||||
|
#define PTM_ROOT_PORT_VENDOR 0x8086U
|
||||||
|
#define PTM_ROOT_PORT_DEVICE 0x9d14U
|
||||||
|
|
||||||
/* PTM capability register ID*/
|
/* PTM capability register ID*/
|
||||||
#define PCIZ_PTM 0x1fU
|
#define PCIZ_PTM 0x1fU
|
||||||
@ -33,6 +37,9 @@
|
|||||||
#define PCIM_PTM_CTRL_ENABLE 0x1U /* PTM enable */
|
#define PCIM_PTM_CTRL_ENABLE 0x1U /* PTM enable */
|
||||||
#define PCIM_PTM_CTRL_ROOT_SELECT 0x2U /* Root select */
|
#define PCIM_PTM_CTRL_ROOT_SELECT 0x2U /* Root select */
|
||||||
|
|
||||||
|
/* virtual root port secondary bus */
|
||||||
|
static int ptm_root_port_secondary_bus;
|
||||||
|
|
||||||
/* get ptm capability register value */
|
/* get ptm capability register value */
|
||||||
static int
|
static int
|
||||||
get_ptm_cap(struct pci_device *pdev, int *offset)
|
get_ptm_cap(struct pci_device *pdev, int *offset)
|
||||||
@ -56,13 +63,61 @@ get_ptm_cap(struct pci_device *pdev, int *offset)
|
|||||||
return cap;
|
return cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Probe whether device and its root port support PTM */
|
/* add virtual root port to hv */
|
||||||
int ptm_probe(struct vmctx *ctx, struct passthru_dev *ptdev)
|
static int
|
||||||
|
add_vroot_port(struct vmctx *ctx, struct passthru_dev *ptdev, struct pci_device *root_port, int ptm_cap_offset)
|
||||||
{
|
{
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
|
struct acrn_emul_dev rp_vdev = {};
|
||||||
|
struct vrp_config *rp_priv = (struct vrp_config *)&rp_vdev.args;
|
||||||
|
|
||||||
|
rp_vdev.dev_id.fields.vendor_id = PTM_ROOT_PORT_VENDOR;
|
||||||
|
rp_vdev.dev_id.fields.device_id = PTM_ROOT_PORT_DEVICE;
|
||||||
|
|
||||||
|
// virtual root port takes bdf from its downstream device
|
||||||
|
rp_vdev.slot = PCI_BDF(ptdev->dev->bus, ptdev->dev->slot, ptdev->dev->func);
|
||||||
|
|
||||||
|
rp_priv->phy_bdf = PCI_BDF(root_port->bus, root_port->dev, root_port->func);
|
||||||
|
|
||||||
|
rp_priv->primary_bus = ptdev->dev->bus;
|
||||||
|
|
||||||
|
rp_priv->secondary_bus = ++ptm_root_port_secondary_bus;
|
||||||
|
|
||||||
|
// only passthru device is connected to virtual root port
|
||||||
|
rp_priv->subordinate_bus = rp_priv->secondary_bus;
|
||||||
|
|
||||||
|
rp_priv->ptm_capable = 1;
|
||||||
|
|
||||||
|
rp_priv->ptm_cap_offset = ptm_cap_offset;
|
||||||
|
|
||||||
|
pr_info("%s: virtual root port info: vbdf=0x%x, phy_bdf=0x%x, prim_bus=%x, sec_bus=%x, sub_bus=%x, ptm_cpa_offset=0x%x.\n", __func__,
|
||||||
|
rp_vdev.slot, rp_priv->phy_bdf, rp_priv->primary_bus, rp_priv->secondary_bus, rp_priv->subordinate_bus, rp_priv->ptm_cap_offset);
|
||||||
|
|
||||||
|
error = vm_add_hv_vdev(ctx, &rp_vdev);
|
||||||
|
if (error) {
|
||||||
|
pr_err("failed to add virtual root.\n");
|
||||||
|
return -1;
|
||||||
|
} else
|
||||||
|
return rp_priv->secondary_bus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Probe whether device and its root port support PTM */
|
||||||
|
int ptm_probe(struct vmctx *ctx, struct passthru_dev *ptdev, int *vrp_sec_bus)
|
||||||
|
{
|
||||||
|
int error = 0;
|
||||||
int pos, pcie_type, cap, rootport_ptm_offset, device_ptm_offset;
|
int pos, pcie_type, cap, rootport_ptm_offset, device_ptm_offset;
|
||||||
struct pci_device *phys_dev = ptdev->phys_dev;
|
struct pci_device *phys_dev = ptdev->phys_dev;
|
||||||
|
//struct pci_bridge_info bridge_info = {};
|
||||||
struct pci_device *root_port;
|
struct pci_device *root_port;
|
||||||
|
|
||||||
|
*vrp_sec_bus = 0;
|
||||||
|
|
||||||
|
/* build pci hierarch */
|
||||||
|
error = scan_pci();
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
|
||||||
if (!ptdev->pcie_cap) {
|
if (!ptdev->pcie_cap) {
|
||||||
pr_err("%s Error: %x:%x.%x is not a pci-e device.\n", __func__,
|
pr_err("%s Error: %x:%x.%x is not a pci-e device.\n", __func__,
|
||||||
phys_dev->bus, phys_dev->dev, phys_dev->func);
|
phys_dev->bus, phys_dev->dev, phys_dev->func);
|
||||||
@ -105,6 +160,10 @@ int ptm_probe(struct vmctx *ctx, struct passthru_dev *ptdev)
|
|||||||
root_port->func, phys_dev->bus, phys_dev->dev, phys_dev->func);
|
root_port->func, phys_dev->bus, phys_dev->dev, phys_dev->func);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add virtual root port
|
||||||
|
*vrp_sec_bus = add_vroot_port(ctx, ptdev, root_port, rootport_ptm_offset);
|
||||||
|
|
||||||
} else if (pcie_type == PCIEM_TYPE_ROOT_INT_EP) {
|
} else if (pcie_type == PCIEM_TYPE_ROOT_INT_EP) {
|
||||||
// No need to emulate root port if ptm requestor is RCIE
|
// No need to emulate root port if ptm requestor is RCIE
|
||||||
pr_notice("%s: ptm requestor is root complex integrated device.\n",
|
pr_notice("%s: ptm requestor is root complex integrated device.\n",
|
||||||
|
@ -10,6 +10,6 @@
|
|||||||
|
|
||||||
#include "passthru.h"
|
#include "passthru.h"
|
||||||
|
|
||||||
int ptm_probe(struct vmctx *ctx, struct passthru_dev *pdev);
|
int ptm_probe(struct vmctx *ctx, struct passthru_dev *pdev, int *vrp_sec_bus);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -663,6 +663,22 @@ struct acrn_intr_monitor {
|
|||||||
#define INTR_CMD_GET_DATA 0U
|
#define INTR_CMD_GET_DATA 0U
|
||||||
#define INTR_CMD_DELAY_INT 1U
|
#define INTR_CMD_DELAY_INT 1U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Info to configure virtual root port
|
||||||
|
*
|
||||||
|
* Configuration passed to hv when adding a virtual root port which
|
||||||
|
* is used as PTM root
|
||||||
|
*/
|
||||||
|
struct vrp_config
|
||||||
|
{
|
||||||
|
uint16_t phy_bdf;
|
||||||
|
uint8_t primary_bus;
|
||||||
|
uint8_t secondary_bus;
|
||||||
|
uint8_t subordinate_bus;
|
||||||
|
uint8_t ptm_capable;
|
||||||
|
uint32_t ptm_cap_offset;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user