From: Shrihari E S <shrihari.s@samsung.com>
To: jic23@kernel.org, junjie.cao@linux.dev,
linux-cxl@vger.kernel.org, linux-pci@vger.kernel.org,
qemu-devel@nongnu.org, anisa.su887@gmail.com, mst@redhat.com,
marcel.apfelbaum@gmail.com
Cc: shrihari.s@samsung.com, arun.george@samsung.com,
cpgs@samsung.com, dave@stgolabs.net, dongjoo.seo1@samsung.com,
gost.dev@samsung.com, s.neeraj@samsung.com,
vikash.k5@samsung.com, anisa.su@samsung.com,
junjie.cao@intel.com
Subject: [PATCH qemu v1 6/8] hw/pci: Add PCIe Device3 capability support
Date: Wed, 4 Nov 2026 17:22:40 +0530 [thread overview]
Message-ID: <932285561.201793792284372.JavaMail.epsvc@epcpadp2new> (raw)
In-Reply-To: <20261104115242.2035807-1-shrihari.s@samsung.com>
Add the PCIe Device 3 Extended Capability (PCIe 6.4 section 7.7.9),
with which an endpoint exposes its UIO requester and completer
support and the related control bits.
The capability tracks the link's flit state: the requester-enable
bits stay clear while the link is not in flit mode, and the Segment
Captured status bit follows the flit state.
Signed-off-by: Shrihari E S <shrihari.s@samsung.com>
Signed-off-by: Dongjoo Seo <dongjoo.seo1@samsung.com>
---
hw/pci/meson.build | 2 +-
hw/pci/pci.c | 2 +
hw/pci/pcie.c | 29 ++++++++++
hw/pci/pcie_dev3.c | 111 +++++++++++++++++++++++++++++++++++++
include/hw/pci/pcie.h | 5 ++
include/hw/pci/pcie_dev3.h | 26 +++++++++
include/hw/pci/pcie_regs.h | 26 +++++++++
7 files changed, 200 insertions(+), 1 deletion(-)
create mode 100644 hw/pci/pcie_dev3.c
create mode 100644 include/hw/pci/pcie_dev3.h
diff --git a/hw/pci/meson.build b/hw/pci/meson.build
index d55882a0c9..0a7f3b162a 100644
--- a/hw/pci/meson.build
+++ b/hw/pci/meson.build
@@ -14,7 +14,7 @@ pci_ss.add(files(
# The functions in these modules can be used by devices too. Since we
# allow plugging PCIe devices into PCI buses, include them even if
# CONFIG_PCI_EXPRESS=n.
-pci_ss.add(files('pcie.c', 'pcie_aer.c', 'pcie_svc.c'))
+pci_ss.add(files('pcie.c', 'pcie_aer.c', 'pcie_svc.c', 'pcie_dev3.c'))
pci_ss.add(files('pcie_doe.c'))
system_ss.add(when: 'CONFIG_PCI_EXPRESS', if_true: files('pcie_port.c', 'pcie_host.c'))
system_ss.add_all(when: 'CONFIG_PCI', if_true: pci_ss)
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 50472cab88..cc5e40ac5c 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -571,6 +571,7 @@ static void pci_do_device_reset(PCIDevice *dev)
pcie_sriov_pf_reset(dev);
pcie_cap_flit_reset(dev);
pcie_svc_cap_reset(dev);
+ pcie_dev3_cap_reset(dev);
}
/*
@@ -1819,6 +1820,7 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val_in, int
pcie_sriov_config_write(d, addr, val_in, l);
pcie_cap_flit_write_config(d, addr, l);
pcie_svc_cap_write_config(d, addr, val_in, l);
+ pcie_dev3_cap_write_config(d, addr, val_in, l);
}
/***********************************************************/
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index b05f70022a..9f16cc8d1b 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -190,6 +190,32 @@ void pcie_cap_fill_link_ep_usp(PCIDevice *dev, PCIExpLinkWidth width,
pcie_cap_fill_lnk(dev, exp_cap, width, speed, flitmode);
}
+bool pcie_link_flit_active(PCIDevice *dev)
+{
+ uint8_t *exp_cap;
+ uint16_t lnksta2;
+ uint16_t lnkctl;
+ uint16_t flags;
+
+ if (!pci_is_express(dev) || !dev->exp.exp_cap) {
+ return false;
+ }
+
+ exp_cap = dev->config + dev->exp.exp_cap;
+ flags = pci_get_word(exp_cap + PCI_EXP_FLAGS);
+ if (!(flags & PCI_EXP_FLAGS_FLIT)) {
+ return false;
+ }
+ lnkctl = pci_get_word(exp_cap + PCI_EXP_LNKCTL);
+ lnksta2 = pci_get_word(exp_cap + PCI_EXP_LNKSTA2);
+
+ if (lnkctl & PCI_EXP_LNKCTL_FLIT_DIS) {
+ return false;
+ }
+
+ return lnksta2 & PCI_EXP_LNKSTA2_FLIT;
+}
+
/*
* Derive the read-only Flit Status bit of the Link Status 2
* register from the Flit Disable bit of the Link Control register.
@@ -226,6 +252,9 @@ void pcie_cap_flit_write_config(PCIDevice *dev, uint32_t addr, int len)
}
pcie_cap_flit_update_sta(dev);
+ if (dev->exp.dev3_cap) {
+ pcie_dev3_cap_flit_update(dev);
+ }
}
/*
diff --git a/hw/pci/pcie_dev3.c b/hw/pci/pcie_dev3.c
new file mode 100644
index 0000000000..8ca7c74b8c
--- /dev/null
+++ b/hw/pci/pcie_dev3.c
@@ -0,0 +1,111 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * PCIe Device3 Extended Capability
+ *
+ * Copyright (c) 2026 Samsung Electronics Co., Ltd.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/pci/pci_device.h"
+#include "hw/pci/pcie.h"
+#include "hw/pci/pcie_port.h"
+#include "hw/pci/pcie_dev3.h"
+
+int pcie_dev3_cap_init(PCIDevice *dev, uint32_t offset,
+ bool uio_req, bool uio_comp, Error **errp)
+{
+ uint32_t devcap3 = 0;
+ uint32_t wmask = 0;
+
+ if (!pci_is_express(dev)) {
+ error_setg(errp, "Device 3 ECAP requires PCIe");
+ return -EINVAL;
+ }
+
+ pcie_add_capability(dev, PCI_EXT_CAP_ID_DEV3, 1, offset, PCI_DEV3_SIZEOF);
+ dev->exp.dev3_cap = offset;
+ dev->exp.dev3.uio_req = uio_req;
+ dev->exp.dev3.uio_comp = uio_comp;
+
+ /*
+ * In this implementation, 14-bit tag support is only advertised
+ * when UIO is enabled. A real device may support 14-bit tags
+ * independently of UIO.
+ */
+ if (uio_comp) {
+ devcap3 |= PCI_DEV3_CAP_TAG_COMP | PCI_DEV3_CAP_UIO_COMP;
+ }
+ if (uio_req) {
+ devcap3 |= PCI_DEV3_CAP_TAG_REQ | PCI_DEV3_CAP_UIO_REQ;
+ wmask |= PCI_DEV3_CTL_TAG_REQ_EN |
+ PCI_DEV3_CTL_UIO_REQ_EN |
+ PCI_DEV3_CTL_UIO_256B_DIS;
+ }
+
+ pci_set_long(dev->config + offset + PCI_DEV3_CAP_OFFSET, devcap3);
+ pci_set_long(dev->wmask + offset + PCI_DEV3_CTL_OFFSET, wmask);
+
+ return 0;
+}
+
+/*
+ * Track the link's flit state in the Device 3 capability: the
+ * requester-enable bits of the Device Control 3 register are cleared
+ * while the link is not in flit mode, and the Segment Captured
+ * status bit follows the link's flit state.
+ */
+void pcie_dev3_cap_flit_update(PCIDevice *dev)
+{
+ uint32_t off = dev->exp.dev3_cap;
+ uint32_t devctl3;
+ uint32_t devsta3;
+ bool flit;
+
+ if (!off) {
+ return;
+ }
+
+ flit = pcie_link_flit_active(dev);
+ if (!dev->exp.dev3.uio_req || !flit) {
+ devctl3 = pci_get_long(dev->config + off + PCI_DEV3_CTL_OFFSET);
+ devctl3 &= ~(PCI_DEV3_CTL_TAG_REQ_EN |
+ PCI_DEV3_CTL_UIO_REQ_EN |
+ PCI_DEV3_CTL_UIO_256B_DIS);
+ pci_set_long(dev->config + off + PCI_DEV3_CTL_OFFSET, devctl3);
+ }
+
+ devsta3 = pci_get_long(dev->config + off + PCI_DEV3_STA_OFFSET);
+ if (flit) {
+ devsta3 |= PCI_DEV3_STA_SEGMENT_CAP;
+ } else {
+ devsta3 &= ~PCI_DEV3_STA_SEGMENT_CAP;
+ }
+ pci_set_long(dev->config + off + PCI_DEV3_STA_OFFSET, devsta3);
+}
+
+void pcie_dev3_cap_reset(PCIDevice *dev)
+{
+ uint32_t off = dev->exp.dev3_cap;
+
+ if (!off) {
+ return;
+ }
+
+ pci_set_long(dev->config + off + PCI_DEV3_CTL_OFFSET, 0);
+ pci_set_long(dev->config + off + PCI_DEV3_STA_OFFSET, 0);
+ pcie_dev3_cap_flit_update(dev);
+}
+
+void pcie_dev3_cap_write_config(PCIDevice *dev,
+ uint32_t addr, uint32_t val, int len)
+{
+ if (!dev->exp.dev3_cap) {
+ return;
+ }
+
+ if (ranges_overlap(addr, len,
+ dev->exp.dev3_cap + PCI_DEV3_CTL_OFFSET, 4)) {
+ pcie_dev3_cap_flit_update(dev);
+ }
+}
diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
index 3d092e8871..95f670c830 100644
--- a/include/hw/pci/pcie.h
+++ b/include/hw/pci/pcie.h
@@ -26,6 +26,7 @@
#include "hw/pci/pcie_aer.h"
#include "hw/pci/pcie_sriov.h"
#include "hw/pci/pcie_svc.h"
+#include "hw/pci/pcie_dev3.h"
#include "hw/core/hotplug.h"
typedef struct PCIEPort PCIEPort;
@@ -86,6 +87,9 @@ struct PCIExpressDevice {
/* Streamlined Virtual Channel (SVC) introduced from PCIe 6.1 */
uint32_t svc_cap;
+ /* PCIe Device 3 Capability */
+ uint32_t dev3_cap;
+ struct PCIEDev3Cap dev3;
};
#define COMPAT_PROP_PCP "power_controller_present"
@@ -149,6 +153,7 @@ void pcie_cap_fill_link_ep_usp(PCIDevice *dev, PCIExpLinkWidth width,
PCIExpLinkSpeed speed, bool flitmode);
void pcie_cap_flit_write_config(PCIDevice *dev, uint32_t addr, int len);
void pcie_cap_flit_reset(PCIDevice *dev);
+bool pcie_link_flit_active(PCIDevice *dev);
void pcie_cap_slot_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp);
diff --git a/include/hw/pci/pcie_dev3.h b/include/hw/pci/pcie_dev3.h
new file mode 100644
index 0000000000..4cfa07fe32
--- /dev/null
+++ b/include/hw/pci/pcie_dev3.h
@@ -0,0 +1,26 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * PCIe Device3 Extended Capability
+ *
+ * Copyright (c) 2026 Samsung Electronics Co., Ltd.
+ */
+
+#ifndef HW_PCIE_DEV3_H
+#define HW_PCIE_DEV3_H
+
+#include "hw/pci/pci.h"
+
+typedef struct PCIEDev3Cap {
+ bool uio_req;
+ bool uio_comp;
+} PCIEDev3Cap;
+
+int pcie_dev3_cap_init(PCIDevice *dev, uint32_t offset,
+ bool uio_req, bool uio_comp, Error **errp);
+void pcie_dev3_cap_reset(PCIDevice *dev);
+void pcie_dev3_cap_write_config(PCIDevice *dev,
+ uint32_t addr, uint32_t val, int len);
+void pcie_dev3_cap_flit_update(PCIDevice *dev);
+
+#endif /* HW_PCIE_DEV3_H */
diff --git a/include/hw/pci/pcie_regs.h b/include/hw/pci/pcie_regs.h
index 044b3caae4..484178adb3 100644
--- a/include/hw/pci/pcie_regs.h
+++ b/include/hw/pci/pcie_regs.h
@@ -256,4 +256,30 @@ typedef enum PCIExpLinkWidth {
#define PCI_SVC_RES_STATUS(n) (PCI_SVC_RES_STATUS_BASE + ((n) * 0x0c))
#define PCI_SVC_VC_NEGO BIT(1)
+/* PCIe Device 3 capability structure. PCIe 6.4 Specification Section 7.7.9 */
+#ifndef PCI_EXT_CAP_ID_DEV3
+#define PCI_EXT_CAP_ID_DEV3 0x2f
+#endif
+
+#define PCI_DEV3_CAP_OFFSET 0x04
+#define PCI_DEV3_CTL_OFFSET 0x08
+#define PCI_DEV3_STA_OFFSET 0x0c
+#define PCI_DEV3_SIZEOF 0x10
+
+/* Section 7.7.9.2 Device Capabilities 3 Register */
+#define PCI_DMWR_REQ_SUPPORTED BIT(0)
+#define PCI_DEV3_CAP_TAG_COMP BIT(1)
+#define PCI_DEV3_CAP_TAG_REQ BIT(2)
+#define PCI_L0P_SUPPORTED BIT(3)
+#define PCI_DEV3_CAP_UIO_COMP BIT(10)
+#define PCI_DEV3_CAP_UIO_REQ BIT(11)
+
+/* Section 7.7.9.3 Device Control 3 Register */
+#define PCI_DEV3_CTL_TAG_REQ_EN BIT(2)
+#define PCI_DEV3_CTL_UIO_REQ_EN BIT(7)
+#define PCI_DEV3_CTL_UIO_256B_DIS BIT(8)
+
+/* Section 7.7.9.4 Device Status 3 Register */
+#define PCI_DEV3_STA_SEGMENT_CAP BIT(3)
+
#endif /* QEMU_PCIE_REGS_H */
--
2.34.1
next prev parent reply other threads:[~2026-11-04 11:39 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20261104113014epcas5p1dbf4b09e2849d28b46eb39db7990a54f@epcas5p1.samsung.com>
[not found] ` <20261104115242.2035807-1-shrihari.s@samsung.com>
2026-11-04 11:52 ` [PATCH qemu v1 1/8] hw/pci: Refactor flitmode from PCIESlot to PCIEPort Shrihari E S
2026-11-04 11:52 ` [PATCH qemu v1 2/8] hw/pci: Move 'x-256b-flit' property from cxl_root_port to pcie_root_port Shrihari E S
2026-11-04 11:52 ` [PATCH qemu v1 3/8] hw/cxl: Wire UIO capability into HDM decoder and DVSEC registers Shrihari E S
2026-11-04 17:25 ` Junjie Cao
2026-11-04 11:52 ` [PATCH qemu v1 4/8] hw/pci: Add PCIe Streamlined Virtual Channel (SVC) capability Shrihari E S
2026-11-04 17:25 ` Junjie Cao
2026-11-04 11:52 ` [PATCH qemu v1 5/8] hw/pci: Wire SVC initialization into port realize functions Shrihari E S
2026-11-04 17:25 ` Junjie Cao
2026-11-04 11:52 ` Shrihari E S [this message]
2026-11-04 11:52 ` [PATCH qemu v1 7/8] hw/cxl: Wire SVC and Dev3 capabilities to CXL Type 3 device Shrihari E S
2026-11-04 17:25 ` Junjie Cao
2026-11-04 11:52 ` [PATCH qemu v1 8/8] cxl: Add documentation for CXL UIO support Shrihari E S
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=932285561.201793792284372.JavaMail.epsvc@epcpadp2new \
--to=shrihari.s@samsung.com \
--cc=anisa.su887@gmail.com \
--cc=anisa.su@samsung.com \
--cc=arun.george@samsung.com \
--cc=cpgs@samsung.com \
--cc=dave@stgolabs.net \
--cc=dongjoo.seo1@samsung.com \
--cc=gost.dev@samsung.com \
--cc=jic23@kernel.org \
--cc=junjie.cao@intel.com \
--cc=junjie.cao@linux.dev \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=marcel.apfelbaum@gmail.com \
--cc=mst@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=s.neeraj@samsung.com \
--cc=vikash.k5@samsung.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.