All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v1 0/3] PCIe Root complex event collector
@ 2021-09-09 11:02 Mayuresh Chitale
  2021-09-09 11:02 ` [RFC PATCH v1 1/3] hw/pci/pcie.c: modify PCIe Express capability for RCiEP and RCEC Mayuresh Chitale
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Mayuresh Chitale @ 2021-09-09 11:02 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: Mayuresh Chitale

Hi All,

This is a first attempt to add PCIe Root Complex Event Collector emulation
support to Qemu. This patch is created on Qemu commit:88afdc92b6 and tested
using Qemu Risc V virt machine and the PCIe aer error injection module in the
Linux kernel(v 5.14).

Thanks,
Mayuresh.

Mayuresh Chitale (3):
  hw/pci/pcie.c: modify PCIe Express capability for RCiEP and RCEC
  hw/pci: Add PCIe RCEC support
  docs: pcie: RCEC

 docs/pcie.txt              |  16 +++--
 hw/pci/meson.build         |   2 +-
 hw/pci/pcie.c              |  40 ++++++++++---
 hw/pci/pcie_aer.c          |   9 +++
 hw/pci/pcie_rcec.c         | 119 +++++++++++++++++++++++++++++++++++++
 include/hw/pci/pci.h       |   1 +
 include/hw/pci/pci_ids.h   |   1 +
 include/hw/pci/pcie.h      |   3 +
 include/hw/pci/pcie_regs.h |   3 +
 9 files changed, 180 insertions(+), 14 deletions(-)
 create mode 100644 hw/pci/pcie_rcec.c

-- 
2.17.1



^ permalink raw reply	[flat|nested] 4+ messages in thread

* [RFC PATCH v1 1/3] hw/pci/pcie.c: modify PCIe Express capability for RCiEP and RCEC
  2021-09-09 11:02 [RFC PATCH v1 0/3] PCIe Root complex event collector Mayuresh Chitale
@ 2021-09-09 11:02 ` Mayuresh Chitale
  2021-09-09 11:02 ` [RFC PATCH v1 2/3] hw/pci: Add PCIe RCEC support Mayuresh Chitale
  2021-09-09 11:02 ` [RFC PATCH v1 3/3] docs: pcie: RCEC Mayuresh Chitale
  2 siblings, 0 replies; 4+ messages in thread
From: Mayuresh Chitale @ 2021-09-09 11:02 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: Mayuresh Chitale

Skip the link and slot capabilities' configuration for PCIe RCiEP
and PCIe RCEC.

Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
---
 hw/pci/pcie.c         | 22 ++++++++++++++--------
 include/hw/pci/pcie.h |  2 ++
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 6e95d82903..017d5075ae 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -64,6 +64,8 @@ pcie_cap_v1_fill(PCIDevice *dev, uint8_t port, uint8_t type, uint8_t version)
      * Specification revisions.
      */
     pci_set_long(exp_cap + PCI_EXP_DEVCAP, PCI_EXP_DEVCAP_RBER);
+    if (type == PCI_EXP_TYPE_RC_EC || type == PCI_EXP_TYPE_RC_END)
+	    return;
 
     pci_set_long(exp_cap + PCI_EXP_LNKCAP,
                  (port << PCI_EXP_LNKCAP_PN_SHIFT) |
@@ -172,8 +174,9 @@ int pcie_cap_init(PCIDevice *dev, uint8_t offset,
     /* Filling values common with v1 */
     pcie_cap_v1_fill(dev, port, type, PCI_EXP_FLAGS_VER2);
 
-    /* Fill link speed and width options */
-    pcie_cap_fill_slot_lnk(dev);
+    if (type != PCI_EXP_TYPE_RC_EC && type != PCI_EXP_TYPE_RC_END)
+        /* Fill link speed and width options */
+        pcie_cap_fill_slot_lnk(dev);
 
     /* Filling v2 specific values */
     pci_set_long(exp_cap + PCI_EXP_DEVCAP2,
@@ -211,10 +214,10 @@ int pcie_cap_v1_init(PCIDevice *dev, uint8_t offset, uint8_t type,
     return pos;
 }
 
-static int
-pcie_endpoint_cap_common_init(PCIDevice *dev, uint8_t offset, uint8_t cap_size)
+int
+pcie_endpoint_cap_common_init(PCIDevice *dev, uint8_t offset, uint8_t cap_size,
+		uint8_t type)
 {
-    uint8_t type = PCI_EXP_TYPE_ENDPOINT;
     Error *local_err = NULL;
     int ret;
 
@@ -224,7 +227,8 @@ pcie_endpoint_cap_common_init(PCIDevice *dev, uint8_t offset, uint8_t cap_size)
      * should instead be Root Complex Integrated Endpoints.
      */
     if (pci_bus_is_express(pci_get_bus(dev))
-        && pci_bus_is_root(pci_get_bus(dev))) {
+        && pci_bus_is_root(pci_get_bus(dev))
+        && type != PCI_EXP_TYPE_RC_EC) {
         type = PCI_EXP_TYPE_RC_END;
     }
 
@@ -243,12 +247,14 @@ pcie_endpoint_cap_common_init(PCIDevice *dev, uint8_t offset, uint8_t cap_size)
 
 int pcie_endpoint_cap_init(PCIDevice *dev, uint8_t offset)
 {
-    return pcie_endpoint_cap_common_init(dev, offset, PCI_EXP_VER2_SIZEOF);
+    return pcie_endpoint_cap_common_init(dev, offset,
+            PCI_EXP_VER2_SIZEOF, PCI_EXP_TYPE_ENDPOINT);
 }
 
 int pcie_endpoint_cap_v1_init(PCIDevice *dev, uint8_t offset)
 {
-    return pcie_endpoint_cap_common_init(dev, offset, PCI_EXP_VER1_SIZEOF);
+    return pcie_endpoint_cap_common_init(dev, offset,
+            PCI_EXP_VER1_SIZEOF, PCI_EXP_TYPE_ENDPOINT);
 }
 
 void pcie_cap_exit(PCIDevice *dev)
diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
index 6063bee0ec..b40b088604 100644
--- a/include/hw/pci/pcie.h
+++ b/include/hw/pci/pcie.h
@@ -147,4 +147,6 @@ void pcie_cap_slot_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
                              Error **errp);
 void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
                                      DeviceState *dev, Error **errp);
+int pcie_endpoint_cap_common_init(PCIDevice *dev, uint8_t offset,
+                                         uint8_t cap_size, uint8_t type);
 #endif /* QEMU_PCIE_H */
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [RFC PATCH v1 2/3] hw/pci: Add PCIe RCEC support
  2021-09-09 11:02 [RFC PATCH v1 0/3] PCIe Root complex event collector Mayuresh Chitale
  2021-09-09 11:02 ` [RFC PATCH v1 1/3] hw/pci/pcie.c: modify PCIe Express capability for RCiEP and RCEC Mayuresh Chitale
@ 2021-09-09 11:02 ` Mayuresh Chitale
  2021-09-09 11:02 ` [RFC PATCH v1 3/3] docs: pcie: RCEC Mayuresh Chitale
  2 siblings, 0 replies; 4+ messages in thread
From: Mayuresh Chitale @ 2021-09-09 11:02 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: Mayuresh Chitale

This patch adds support for PCIe Root Complex Event Collector
(RCEC) emulation. Further, if a RCiEP supports AER capability
then a mapping is created for that RCiEP in the RCEC's
endpoint association capability.

Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
---
 hw/pci/meson.build         |   2 +-
 hw/pci/pcie.c              |  18 ++++++
 hw/pci/pcie_aer.c          |   9 +++
 hw/pci/pcie_rcec.c         | 119 +++++++++++++++++++++++++++++++++++++
 include/hw/pci/pci.h       |   1 +
 include/hw/pci/pci_ids.h   |   1 +
 include/hw/pci/pcie.h      |   1 +
 include/hw/pci/pcie_regs.h |   3 +
 8 files changed, 153 insertions(+), 1 deletion(-)
 create mode 100644 hw/pci/pcie_rcec.c

diff --git a/hw/pci/meson.build b/hw/pci/meson.build
index 5c4bbac817..34ae7d4a44 100644
--- a/hw/pci/meson.build
+++ b/hw/pci/meson.build
@@ -11,7 +11,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'))
+pci_ss.add(files('pcie.c', 'pcie_aer.c', 'pcie_rcec.c'))
 softmmu_ss.add(when: 'CONFIG_PCI_EXPRESS', if_true: files('pcie_port.c', 'pcie_host.c'))
 softmmu_ss.add_all(when: 'CONFIG_PCI', if_true: pci_ss)
 
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 017d5075ae..55938a1798 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -747,6 +747,24 @@ void pcie_cap_slot_push_attention_button(PCIDevice *dev)
     pcie_cap_slot_event(dev, PCI_EXP_HP_EV_ABP);
 }
 
+void pcie_rcec_ep_map(PCIDevice *dev)
+{
+    int devnum = PCI_SLOT(dev->devfn);
+    uint32_t ep_bitmap;
+    PCIDevice *rcec;
+    uint16_t cap;
+
+    /* RCEC is always expected to be at 00:01.0 */
+    rcec = pci_find_device(pci_get_bus(dev), 0, PCI_DEVFN(1,0));
+    if (!rcec)
+        return;
+
+    pcie_cap_deverr_init(dev);
+    cap = pcie_find_capability(rcec, PCI_EXT_CAP_ID_RCEC);
+    ep_bitmap = pci_get_long(rcec->config + cap + 0x4);
+    pci_set_long(rcec->config + cap + 0x4, ep_bitmap | 1 << devnum);
+}
+
 /* root control/capabilities/status. PME isn't emulated for now */
 void pcie_cap_root_init(PCIDevice *dev)
 {
diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c
index 27f9cc56af..ba4a1e6d78 100644
--- a/hw/pci/pcie_aer.c
+++ b/hw/pci/pcie_aer.c
@@ -166,6 +166,15 @@ int pcie_aer_init(PCIDevice *dev, uint8_t cap_ver, uint16_t offset,
         /* nothing */
         break;
     }
+
+    /*
+     * If this is a RCiEP, map it into the RCEC's endpoint association bitmap
+     * capability
+     */
+    if (pci_bus_is_express(pci_get_bus(dev))
+        && pci_bus_is_root(pci_get_bus(dev)))
+	    pcie_rcec_ep_map(dev);
+
     return 0;
 }
 
diff --git a/hw/pci/pcie_rcec.c b/hw/pci/pcie_rcec.c
new file mode 100644
index 0000000000..9a51d7b9b4
--- /dev/null
+++ b/hw/pci/pcie_rcec.c
@@ -0,0 +1,119 @@
+/*
+ * pcie_rcec.c
+ * PCIe Root Complex Event Collector emulation
+ *
+ * Copyright (c) 2021 Mayuresh Chitale <mchitale@ventanamicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qemu/module.h"
+#include "qemu/range.h"
+#include "sysemu/sysemu.h"
+#include "hw/hw.h"
+#include "hw/pci/pci.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+
+#define TYPE_RCEC_DEVICE "pcie-rcec"
+#define PCIE_RCEC_EXP_CAP_OFF 0x40
+#define PCIE_RCEC_EP_ECAP_OFF 0x100
+#define PCIE_RCEC_AER_ECAP_OFF 0x120
+
+struct RcecState {
+    /*< private >*/
+    PCIDevice parent_obj;
+    /*< public >*/
+};
+
+
+static int pcie_rcec_cap_init(PCIDevice *dev, uint8_t offset)
+{
+    int rc;
+
+    dev->config[PCI_INTERRUPT_PIN] = 1;
+    rc = pcie_endpoint_cap_common_init(dev, offset,
+            PCI_EXP_VER2_SIZEOF, PCI_EXP_TYPE_RC_EC);
+    pcie_cap_root_init(dev);
+    pcie_cap_deverr_init(dev);
+
+    return rc;
+}
+
+static void pcie_rcec_ep_cap_init(PCIDevice *dev, uint8_t cap_ver, uint16_t offset,
+                  uint16_t size, Error **errp)
+{
+    pcie_add_capability(dev, PCI_EXT_CAP_ID_RCEC, cap_ver, offset, size);
+    /* Map device (bit) 1 which is RCEC by default */
+    pci_set_long(dev->config + offset + 0x4, 0x2);
+}
+
+static void pcie_rcec_realize(PCIDevice *pci_dev, Error **errp)
+{
+    if (pcie_rcec_cap_init(pci_dev, PCIE_RCEC_EXP_CAP_OFF) < 0)
+        hw_error("Failed to initialize RCEC express capability");
+
+    pcie_rcec_ep_cap_init(pci_dev, PCI_RCEC_EP_VER, PCIE_RCEC_EP_ECAP_OFF,
+        PCI_RCEC_EP_SIZEOF, errp);
+
+    if (pcie_aer_init(pci_dev, PCI_ERR_VER, PCIE_RCEC_AER_ECAP_OFF,
+        PCI_ERR_SIZEOF, errp) < 0)
+        hw_error("Failed to initialize RCEC AER capability");
+}
+
+static const VMStateDescription vmstate_rcec = {
+    .name = "rcec",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_PCI_DEVICE(parent_obj, struct RcecState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void rcec_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+    dc->desc = "QEMU generic RCEC";
+    dc->vmsd = &vmstate_rcec;
+    k->vendor_id = PCI_VENDOR_ID_REDHAT;
+    k->device_id = PCI_DEVICE_ID_REDHAT_RCEC;
+    k->revision = 0;
+    k->class_id = PCI_CLASS_SYSTEM_RCEC;
+    k->realize = pcie_rcec_realize;
+}
+
+static const TypeInfo pcie_rcec_info = {
+    .name = TYPE_RCEC_DEVICE,
+    .parent = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(struct RcecState),
+    .class_init = rcec_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { INTERFACE_PCIE_DEVICE },
+        { },
+    },
+};
+
+
+static void pcie_rcec_register_types(void)
+{
+    type_register_static(&pcie_rcec_info);
+}
+
+type_init(pcie_rcec_register_types)
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index d0f4266e37..d580c9e6cf 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -109,6 +109,7 @@ extern bool pci_available;
 #define PCI_DEVICE_ID_REDHAT_NVME        0x0010
 #define PCI_DEVICE_ID_REDHAT_PVPANIC     0x0011
 #define PCI_DEVICE_ID_REDHAT_QXL         0x0100
+#define PCI_DEVICE_ID_REDHAT_RCEC        0x0101
 
 #define FMT_PCIBUS                      PRIx64
 
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index 11abe22d46..d5214d2764 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -88,6 +88,7 @@
 #define PCI_CLASS_SYSTEM_RTC             0x0803
 #define PCI_CLASS_SYSTEM_PCI_HOTPLUG     0x0804
 #define PCI_CLASS_SYSTEM_SDHCI           0x0805
+#define PCI_CLASS_SYSTEM_RCEC            0x0807
 #define PCI_CLASS_SYSTEM_OTHER           0x0880
 
 #define PCI_BASE_CLASS_INPUT             0x09
diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
index b40b088604..482fefe704 100644
--- a/include/hw/pci/pcie.h
+++ b/include/hw/pci/pcie.h
@@ -149,4 +149,5 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
                                      DeviceState *dev, Error **errp);
 int pcie_endpoint_cap_common_init(PCIDevice *dev, uint8_t offset,
                                          uint8_t cap_size, uint8_t type);
+void pcie_rcec_ep_map(PCIDevice *dev);
 #endif /* QEMU_PCIE_H */
diff --git a/include/hw/pci/pcie_regs.h b/include/hw/pci/pcie_regs.h
index 1db86b0ec4..7b8f2616e9 100644
--- a/include/hw/pci/pcie_regs.h
+++ b/include/hw/pci/pcie_regs.h
@@ -179,4 +179,7 @@ typedef enum PCIExpLinkWidth {
 #define PCI_ACS_VER                     0x1
 #define PCI_ACS_SIZEOF                  8
 
+#define PCI_RCEC_EP_VER        1
+#define PCI_RCEC_EP_SIZEOF     0x8
+
 #endif /* QEMU_PCIE_REGS_H */
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [RFC PATCH v1 3/3] docs: pcie: RCEC
  2021-09-09 11:02 [RFC PATCH v1 0/3] PCIe Root complex event collector Mayuresh Chitale
  2021-09-09 11:02 ` [RFC PATCH v1 1/3] hw/pci/pcie.c: modify PCIe Express capability for RCiEP and RCEC Mayuresh Chitale
  2021-09-09 11:02 ` [RFC PATCH v1 2/3] hw/pci: Add PCIe RCEC support Mayuresh Chitale
@ 2021-09-09 11:02 ` Mayuresh Chitale
  2 siblings, 0 replies; 4+ messages in thread
From: Mayuresh Chitale @ 2021-09-09 11:02 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: Mayuresh Chitale

Update root bus section to include information on how to
enable PCIe RCEC for any given machine.

Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
---
 docs/pcie.txt | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/docs/pcie.txt b/docs/pcie.txt
index 89e3502075..da5d7b676b 100644
--- a/docs/pcie.txt
+++ b/docs/pcie.txt
@@ -57,12 +57,14 @@ Place only the following kinds of devices directly on the Root Complex:
     (4) Extra Root Complexes (pxb-pcie), if multiple PCI Express Root Buses
         are needed.
 
+    (5) Root complex event collector (pcie-rcec).
+
    pcie.0 bus
-   ----------------------------------------------------------------------------
-        |                |                    |                  |
-   -----------   ------------------   -------------------   --------------
-   | PCI Dev |   | PCIe Root Port |   | PCIe-PCI Bridge |   |  pxb-pcie  |
-   -----------   ------------------   -------------------   --------------
+   ------------------------------------------------------------------------------------
+        |                |                    |                  |                |
+   -----------   ------------------   -------------------   --------------   -------------
+   | PCI Dev |   | PCIe Root Port |   | PCIe-PCI Bridge |   |  pxb-pcie  |   | PCIe RCEC |
+   -----------   ------------------   -------------------   --------------   -------------
 
 2.1.1 To plug a device into pcie.0 as a Root Complex Integrated Endpoint use:
           -device <dev>[,bus=pcie.0]
@@ -72,6 +74,10 @@ Place only the following kinds of devices directly on the Root Complex:
       connected to the pcie.1 bus:
           -device ioh3420,id=root_port1[,bus=pcie.1][,chassis=x][,slot=y][,addr=z]                                     \
           -device pcie-pci-bridge,id=pcie_pci_bridge1,bus=pcie.1
+2.1.3 To plug a PCIe RCEC into pcie.0 use:
+          -device pcie-rcec
+      PCIe RCEC must always be the first device on the root bus, pcie.0. So any RCiEP
+      devices plugged into pcie.0 must appear after the rcec in the command line.
 
 
 2.2 PCI Express only hierarchy
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-09-09 11:05 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-09 11:02 [RFC PATCH v1 0/3] PCIe Root complex event collector Mayuresh Chitale
2021-09-09 11:02 ` [RFC PATCH v1 1/3] hw/pci/pcie.c: modify PCIe Express capability for RCiEP and RCEC Mayuresh Chitale
2021-09-09 11:02 ` [RFC PATCH v1 2/3] hw/pci: Add PCIe RCEC support Mayuresh Chitale
2021-09-09 11:02 ` [RFC PATCH v1 3/3] docs: pcie: RCEC Mayuresh Chitale

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.