aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>2025-05-20 07:18:54 +0000
committerMichael S. Tsirkin <mst@redhat.com>2025-06-01 06:38:53 -0400
commitdcad6cb2abf4ffc4f911041d0547c4b54c2f92e2 (patch)
tree7e9efbc9afccb4503edcd5188eb68a1819eeabaf
parent6a3ae6a2440dead9dd8e3f84152dc53a5214c48d (diff)
downloadqemu-dcad6cb2abf4ffc4f911041d0547c4b54c2f92e2.zip
qemu-dcad6cb2abf4ffc4f911041d0547c4b54c2f92e2.tar.gz
qemu-dcad6cb2abf4ffc4f911041d0547c4b54c2f92e2.tar.bz2
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>
-rw-r--r--hw/pci/pcie.c26
-rw-r--r--include/hw/pci/pcie.h5
-rw-r--r--include/hw/pci/pcie_regs.h3
3 files changed, 33 insertions, 1 deletions
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 36de709..542172b 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -1240,6 +1240,32 @@ void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width,
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)
{
if (!pci_is_express(dev) || !dev->exp.pasid_cap) {
diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
index 497d0bc..17f06cd 100644
--- a/include/hw/pci/pcie.h
+++ b/include/hw/pci/pcie.h
@@ -70,9 +70,10 @@ struct PCIExpressDevice {
uint16_t aer_cap;
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 pasid_cap;
+ uint16_t pri_cap;
/* ACS */
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,
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_ats_enabled(const PCIDevice *dev);
diff --git a/include/hw/pci/pcie_regs.h b/include/hw/pci/pcie_regs.h
index 4d9cf4a..33a2222 100644
--- a/include/hw/pci/pcie_regs.h
+++ b/include/hw/pci/pcie_regs.h
@@ -91,6 +91,9 @@ typedef enum PCIExpLinkWidth {
#define PCI_EXT_CAP_PASID_MAX_WIDTH 20
#define PCI_PASID_CAP_WIDTH_SHIFT 8
+/* PRI */
+#define PCI_PRI_VER 1
+
/* AER */
#define PCI_ERR_VER 2
#define PCI_ERR_SIZEOF 0x48