* [Qemu-devel] [PATCH RFC] Generic PCIE-to-PCI Bridge
@ 2017-06-25 17:10 Aleksandr Bezzubikov
2017-06-25 17:11 ` [Qemu-devel] [PATCH RFC] hw/pci-bridge: implement pcie-pci-bridge device Aleksandr Bezzubikov
0 siblings, 1 reply; 2+ messages in thread
From: Aleksandr Bezzubikov @ 2017-06-25 17:10 UTC (permalink / raw)
To: qemu-devel; +Cc: mst, marcel, imammedo, Aleksandr Bezzubikov
This patch introduces a new device - generic PCI Express to PCI bridge.
Now only x86-specific DMI-to-PCI bridge can be used to enable
usage of legacy PCI devices on Q35 machine. But this bridge isn't cross-platform
and doesn't support hotplugging.
That's why we need a new generic cross-platform bridge device, which supports hotplugging.
This patch creates device only for static CLI usage,
the next goal is to add ACPI hotplug support. It will utilize
in some way past Marcel's RFC series for Q35 ACPI PCI hotplug support
https://lists.gnu.org/archive/html/qemu-devel/2016-05/msg05681.html,
but will require dynamic ACPI code emission in case when the bridge was hotplugged itself.
Aleksandr Bezzubikov (1):
hw/pci-bridge: implement pcie-pci-bridge device
hw/pci-bridge/Makefile.objs | 2 +-
hw/pci-bridge/pcie_pci_bridge.c | 152 ++++++++++++++++++++++++++++++++++++++++
include/hw/pci/pci.h | 1 +
3 files changed, 154 insertions(+), 1 deletion(-)
create mode 100644 hw/pci-bridge/pcie_pci_bridge.c
--
2.7.4
^ permalink raw reply [flat|nested] 2+ messages in thread
* [Qemu-devel] [PATCH RFC] hw/pci-bridge: implement pcie-pci-bridge device
2017-06-25 17:10 [Qemu-devel] [PATCH RFC] Generic PCIE-to-PCI Bridge Aleksandr Bezzubikov
@ 2017-06-25 17:11 ` Aleksandr Bezzubikov
0 siblings, 0 replies; 2+ messages in thread
From: Aleksandr Bezzubikov @ 2017-06-25 17:11 UTC (permalink / raw)
To: qemu-devel; +Cc: mst, marcel, imammedo, Aleksandr Bezzubikov
Signed-off-by: Aleksandr Bezzubikov <zuban32s@gmail.com>
---
hw/pci-bridge/Makefile.objs | 2 +-
hw/pci-bridge/pcie_pci_bridge.c | 152 ++++++++++++++++++++++++++++++++++++++++
include/hw/pci/pci.h | 1 +
3 files changed, 154 insertions(+), 1 deletion(-)
create mode 100644 hw/pci-bridge/pcie_pci_bridge.c
diff --git a/hw/pci-bridge/Makefile.objs b/hw/pci-bridge/Makefile.objs
index c4683cf..666db37 100644
--- a/hw/pci-bridge/Makefile.objs
+++ b/hw/pci-bridge/Makefile.objs
@@ -1,4 +1,4 @@
-common-obj-y += pci_bridge_dev.o
+common-obj-y += pci_bridge_dev.o pcie_pci_bridge.o
common-obj-$(CONFIG_PCIE_PORT) += pcie_root_port.o gen_pcie_root_port.o
common-obj-$(CONFIG_PXB) += pci_expander_bridge.o
common-obj-$(CONFIG_XIO3130) += xio3130_upstream.o xio3130_downstream.o
diff --git a/hw/pci-bridge/pcie_pci_bridge.c b/hw/pci-bridge/pcie_pci_bridge.c
new file mode 100644
index 0000000..06b19d6
--- /dev/null
+++ b/hw/pci-bridge/pcie_pci_bridge.c
@@ -0,0 +1,152 @@
+/*
+ * QEMU Generic PCIE-PCI Bridge
+ *
+ * Copyright (c) 2017 Aleksandr Bezzubikov
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
+#include "hw/pci/pci_bridge.h"
+#include "hw/pci/msi.h"
+#include "hw/pci/slotid_cap.h"
+
+typedef struct PCIEPCIBridge {
+ /*< private >*/
+ PCIBridge parent_obj;
+
+#define PCI_BRIDGE_DEV_F_SHPC_REQ 0
+ uint32_t flags;
+ /*< public >*/
+} PCIEPCIBridge;
+
+#define TYPE_PCIE_PCI_BRIDGE_DEV "pcie-pci-bridge"
+#define PCIE_PCI_BRIDGE_DEV(obj) \
+ OBJECT_CHECK(PCIEPCIBridge, (obj), TYPE_PCIE_PCI_BRIDGE_DEV)
+
+static void pciepci_bridge_realize(PCIDevice *d, Error **errp)
+{
+ int rc, pos;
+ Error *local_err = NULL;
+
+ pci_bridge_initfn(d, TYPE_PCI_BUS);
+
+ rc = pci_bridge_ssvid_init(d, 0, 0, 0x32);
+ if (rc < 0) {
+ error_setg(errp, "Can't add SSVID, error %d", rc);
+ goto error;
+ }
+
+ rc = pcie_cap_init(d, 0, PCI_EXP_TYPE_PCI_BRIDGE, 0);
+ if (rc < 0) {
+ error_setg(errp, "Can't add PCIE-PCI bridge capability, error %d", rc);
+ goto error;
+ }
+
+ pos = pci_add_capability(d, PCI_CAP_ID_PM, 0, PCI_PM_SIZEOF);
+ assert(pos > 0);
+ d->exp.pm_cap = pos;
+ pci_set_word(d->config + pos + PCI_PM_PMC, 0x3);
+
+ pcie_cap_arifwd_init(d);
+ pcie_cap_deverr_init(d);
+
+ rc = pcie_aer_init(d, PCI_ERR_VER, 0x100, PCI_ERR_SIZEOF, &local_err);
+ if (rc < 0) {
+ error_propagate(errp, local_err);
+ goto error;
+ }
+
+ rc = msi_init(d, 0, 1, 1, 1, &local_err);
+ if (rc < 0) {
+ error_propagate(errp, local_err);
+ }
+
+ return;
+
+ error:
+ pci_bridge_exitfn(d);
+}
+
+static void pciepci_bridge_exit(PCIDevice *d)
+{
+ pcie_cap_exit(d);
+ pci_bridge_exitfn(d);
+}
+
+static void pciepci_bridge_reset(DeviceState *qdev)
+{
+ pci_bridge_reset(qdev);
+}
+
+static void pcie_pci_bridge_write_config(PCIDevice *d,
+ uint32_t address, uint32_t val, int len)
+{
+ pci_bridge_write_config(d, address, val, len);
+ msi_write_config(d, address, val, len);
+}
+
+
+static Property pcie_pci_bridge_dev_properties[] = {
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static const VMStateDescription pciepci_bridge_dev_vmstate = {
+ .name = TYPE_PCIE_PCI_BRIDGE_DEV,
+ .fields = (VMStateField[]) {
+ VMSTATE_PCI_DEVICE(parent_obj, PCIBridge),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void pciepci_bridge_class_init(ObjectClass *klass, void *data)
+{
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ k->is_express = 1;
+ k->is_bridge = 1;
+ k->vendor_id = PCI_VENDOR_ID_REDHAT;
+ k->device_id = PCI_DEVICE_ID_REDHAT_PCIE_BRIDGE;
+ k->realize = pciepci_bridge_realize;
+ k->exit = pciepci_bridge_exit;
+ k->config_write = pcie_pci_bridge_write_config;
+ dc->vmsd = &pciepci_bridge_dev_vmstate;
+ dc->props = pcie_pci_bridge_dev_properties;
+ dc->vmsd = &pciepci_bridge_dev_vmstate;
+ dc->reset = &pciepci_bridge_reset;
+ set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+}
+
+static const TypeInfo pciepci_bridge_info = {
+ .name = TYPE_PCIE_PCI_BRIDGE_DEV,
+ .parent = TYPE_PCI_BRIDGE,
+ .instance_size = sizeof(PCIEPCIBridge),
+ .class_init = pciepci_bridge_class_init
+};
+
+static void pciepci_register(void)
+{
+ type_register_static(&pciepci_bridge_info);
+}
+
+type_init(pciepci_register);
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index a37a2d5..47bf8da 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -98,6 +98,7 @@
#define PCI_DEVICE_ID_REDHAT_PXB_PCIE 0x000b
#define PCI_DEVICE_ID_REDHAT_PCIE_RP 0x000c
#define PCI_DEVICE_ID_REDHAT_XHCI 0x000d
+#define PCI_DEVICE_ID_REDHAT_PCIE_BRIDGE 0x000e
#define PCI_DEVICE_ID_REDHAT_QXL 0x0100
#define FMT_PCIBUS PRIx64
--
2.7.4
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2017-06-25 17:11 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-06-25 17:10 [Qemu-devel] [PATCH RFC] Generic PCIE-to-PCI Bridge Aleksandr Bezzubikov
2017-06-25 17:11 ` [Qemu-devel] [PATCH RFC] hw/pci-bridge: implement pcie-pci-bridge device Aleksandr Bezzubikov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).