* [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.