summary refs log tree commit diff stats
path: root/hw/pci
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 /hw/pci
parent6a3ae6a2440dead9dd8e3f84152dc53a5214c48d (diff)
downloadfocaccia-qemu-dcad6cb2abf4ffc4f911041d0547c4b54c2f92e2.tar.gz
focaccia-qemu-dcad6cb2abf4ffc4f911041d0547c4b54c2f92e2.zip
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>
Diffstat (limited to 'hw/pci')
-rw-r--r--hw/pci/pcie.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 36de709801..542172b3fa 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) {