pcie: Add a helper to declare the PRI capability for a pcie device

Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
Message-Id: <20250520071823.764266-5-clement.mathieu--drif@eviden.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
CLEMENT MATHIEU--DRIF 2025-05-20 07:18:54 +00:00 committed by Michael S. Tsirkin
parent 6a3ae6a244
commit dcad6cb2ab
3 changed files with 33 additions and 1 deletions

View file

@ -1240,6 +1240,32 @@ void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width,
dev->exp.pasid_cap = offset; dev->exp.pasid_cap = offset;
} }
/* PRI */
void pcie_pri_init(PCIDevice *dev, uint16_t offset, uint32_t outstanding_pr_cap,
bool prg_response_pasid_req)
{
static const uint16_t control_reg_rw_mask = 0x3;
static const uint16_t status_reg_rw1_mask = 0x3;
static const uint32_t pr_alloc_reg_rw_mask = 0xffffffff;
uint16_t status_reg;
status_reg = prg_response_pasid_req ? PCI_PRI_STATUS_PASID : 0;
status_reg |= PCI_PRI_STATUS_STOPPED; /* Stopped by default */
pcie_add_capability(dev, PCI_EXT_CAP_ID_PRI, PCI_PRI_VER, offset,
PCI_EXT_CAP_PRI_SIZEOF);
/* Disabled by default */
pci_set_word(dev->config + offset + PCI_PRI_STATUS, status_reg);
pci_set_long(dev->config + offset + PCI_PRI_MAX_REQ, outstanding_pr_cap);
pci_set_word(dev->wmask + offset + PCI_PRI_CTRL, control_reg_rw_mask);
pci_set_word(dev->w1cmask + offset + PCI_PRI_STATUS, status_reg_rw1_mask);
pci_set_long(dev->wmask + offset + PCI_PRI_ALLOC_REQ, pr_alloc_reg_rw_mask);
dev->exp.pri_cap = offset;
}
bool pcie_pasid_enabled(const PCIDevice *dev) bool pcie_pasid_enabled(const PCIDevice *dev)
{ {
if (!pci_is_express(dev) || !dev->exp.pasid_cap) { if (!pci_is_express(dev) || !dev->exp.pasid_cap) {

View file

@ -70,9 +70,10 @@ struct PCIExpressDevice {
uint16_t aer_cap; uint16_t aer_cap;
PCIEAERLog aer_log; PCIEAERLog aer_log;
/* Offset of ATS and PASID capabilities in config space */ /* Offset of ATS, PRI and PASID capabilities in config space */
uint16_t ats_cap; uint16_t ats_cap;
uint16_t pasid_cap; uint16_t pasid_cap;
uint16_t pri_cap;
/* ACS */ /* ACS */
uint16_t acs_cap; uint16_t acs_cap;
@ -154,6 +155,8 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width, void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width,
bool exec_perm, bool priv_mod); bool exec_perm, bool priv_mod);
void pcie_pri_init(PCIDevice *dev, uint16_t offset, uint32_t outstanding_pr_cap,
bool prg_response_pasid_req);
bool pcie_pasid_enabled(const PCIDevice *dev); bool pcie_pasid_enabled(const PCIDevice *dev);
bool pcie_ats_enabled(const PCIDevice *dev); bool pcie_ats_enabled(const PCIDevice *dev);

View file

@ -91,6 +91,9 @@ typedef enum PCIExpLinkWidth {
#define PCI_EXT_CAP_PASID_MAX_WIDTH 20 #define PCI_EXT_CAP_PASID_MAX_WIDTH 20
#define PCI_PASID_CAP_WIDTH_SHIFT 8 #define PCI_PASID_CAP_WIDTH_SHIFT 8
/* PRI */
#define PCI_PRI_VER 1
/* AER */ /* AER */
#define PCI_ERR_VER 2 #define PCI_ERR_VER 2
#define PCI_ERR_SIZEOF 0x48 #define PCI_ERR_SIZEOF 0x48