From: Dongjoo Seo <[email protected]> Implement the Streamlined Virtual Channel (SVC) extended capability for PCIe ports (Root, Upstream, and Downstream). This capability is mandatory for enabling Unordered IO (UIO) traffic as per PCIe 6.4 specification [1].
UIO functionality depends on two key prerequisites: 1. SVC support (SVC3 mandatory, SVC4 optional) 2. 256-byte Flit mode support This patch adds the following experimental properties to PCIe ports: - x-uio-svc: Enable UIO traffic via SVC3 (mandatory path) - x-uio-svc-opt: Enable UIO traffic via SVC4 (optional path) - x-256b-flit: Enable 256B flit mode required for UIO Helper functions are included to manage UIO traffic gating and SVC configuration. This change lays the groundwork for UIO emulation in QEMU. [1]: PCIe 6.4 Specification, Table 2-46 (Streamlined Virtual Channel) Signed-off-by: Dongjoo Seo <[email protected]> Signed-off-by: Shrihari E S <[email protected]> --- hw/pci-bridge/pcie_root_port.c | 2 ++ hw/pci-bridge/xio3130_downstream.c | 3 +++ hw/pci-bridge/xio3130_upstream.c | 8 ++++++++ include/hw/pci/pcie_port.h | 21 +++++++++++++++++++++ 4 files changed, 34 insertions(+) diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c index eeee24e042..20554bd854 100644 --- a/hw/pci-bridge/pcie_root_port.c +++ b/hw/pci-bridge/pcie_root_port.c @@ -153,6 +153,8 @@ static const Property rp_props[] = { QEMU_PCIE_SLTCAP_PCP_BITNR, true), DEFINE_PROP_BOOL("disable-acs", PCIESlot, disable_acs, false), DEFINE_PROP_BOOL("x-256b-flit", PCIEPort, flitmode, true), + DEFINE_PROP_BIT("x-uio-svc", PCIEPort, svc, UIO_MANDATORY_SVC, false), + DEFINE_PROP_BIT("x-uio-svc-opt", PCIEPort, svc, UIO_OPTIONAL_SVC, false), }; static void rp_instance_post_init(Object *obj) diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c index 0c3fed3053..b0b297bb53 100644 --- a/hw/pci-bridge/xio3130_downstream.c +++ b/hw/pci-bridge/xio3130_downstream.c @@ -137,6 +137,9 @@ static void xio3130_downstream_exitfn(PCIDevice *d) static const Property xio3130_downstream_props[] = { DEFINE_PROP_BIT(COMPAT_PROP_PCP, PCIDevice, cap_present, QEMU_PCIE_SLTCAP_PCP_BITNR, true), + DEFINE_PROP_BIT("x-uio-svc", PCIEPort, svc, UIO_MANDATORY_SVC, false), + DEFINE_PROP_BIT("x-uio-svc-opt", PCIEPort, svc, UIO_OPTIONAL_SVC, false), + DEFINE_PROP_BOOL("x-256b-flit", PCIEPort, flitmode, false), }; static const VMStateDescription vmstate_xio3130_downstream = { diff --git a/hw/pci-bridge/xio3130_upstream.c b/hw/pci-bridge/xio3130_upstream.c index 40057b749b..925df5add3 100644 --- a/hw/pci-bridge/xio3130_upstream.c +++ b/hw/pci-bridge/xio3130_upstream.c @@ -24,6 +24,7 @@ #include "hw/pci/msi.h" #include "hw/pci/pcie.h" #include "hw/pci/pcie_port.h" +#include "hw/core/qdev-properties.h" #include "migration/vmstate.h" #include "qemu/module.h" @@ -123,6 +124,12 @@ static const VMStateDescription vmstate_xio3130_upstream = { } }; +static const Property xio3130_upstream_props[] = { + DEFINE_PROP_BIT("x-uio-svc", PCIEPort, svc, UIO_MANDATORY_SVC, false), + DEFINE_PROP_BIT("x-uio-svc-opt", PCIEPort, svc, UIO_OPTIONAL_SVC, false), + DEFINE_PROP_BOOL("x-256b-flit", PCIEPort, flitmode, false), +}; + static void xio3130_upstream_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -138,6 +145,7 @@ static void xio3130_upstream_class_init(ObjectClass *klass, const void *data) dc->desc = "TI X3130 Upstream Port of PCI Express Switch"; device_class_set_legacy_reset(dc, xio3130_upstream_reset); dc->vmsd = &vmstate_xio3130_upstream; + device_class_set_props(dc, xio3130_upstream_props); } static const TypeInfo xio3130_upstream_info = { diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h index 1bcc734649..a6b1b8a6cf 100644 --- a/include/hw/pci/pcie_port.h +++ b/include/hw/pci/pcie_port.h @@ -37,8 +37,29 @@ struct PCIEPort { /* pci express switch port */ uint8_t port; + + /* + * This field declares Streamlined Virtual Channel (SVC) capability. + * Per PCIe 6.4 specification section 7.9.29, a pcie port supports + * upto 8 SVCs, in that SVC0 is a default one, SVC3 is for UIO traffic + * and SVC 4 is shared by both UIO and non-UIO traffic. + */ + uint32_t svc; }; +#define UIO_MANDATORY_SVC 3 +#define UIO_OPTIONAL_SVC 4 + +static inline bool get_uio_mandatory_svc(PCIEPort *port) +{ + return (port->svc >> UIO_MANDATORY_SVC) & 1; +} + +static inline bool get_uio_optional_svc(PCIEPort *port) +{ + return (port->svc >> UIO_OPTIONAL_SVC) & 1; +} + void pcie_port_init_reg(PCIDevice *d); PCIDevice *pcie_find_port_by_pn(PCIBus *bus, uint8_t pn); -- 2.34.1
