qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC PATCH 5/7] pci-bridge: CCIX capable PCIE/CCIX switch d


From: Jonathan Cameron
Subject: [Qemu-devel] [RFC PATCH 5/7] pci-bridge: CCIX capable PCIE/CCIX switch downstream port
Date: Tue, 25 Jun 2019 19:27:50 +0800

Note that this is simply emulation of the configuration space.

Has the same issue with cut and paste code as the upstream port
driver.  Solution likely to be the same.

Signed-off-by: Jonathan Cameron <address@hidden>
---
 hw/pci-bridge/Makefile.objs     |   2 +-
 hw/pci-bridge/ccix_downstream.c | 222 ++++++++++++++++++++++++++++++++
 2 files changed, 223 insertions(+), 1 deletion(-)

diff --git a/hw/pci-bridge/Makefile.objs b/hw/pci-bridge/Makefile.objs
index e266e39fed..78a49fb90b 100644
--- a/hw/pci-bridge/Makefile.objs
+++ b/hw/pci-bridge/Makefile.objs
@@ -8,4 +8,4 @@ common-obj-$(CONFIG_I82801B11) += i82801b11.o
 common-obj-$(CONFIG_DEC_PCI) += dec.o
 # Sun4u
 common-obj-$(CONFIG_SIMBA) += simba.o
-common-obj-$(CONFIG_CCIX_SWITCH) += ccix_upstream.o
+common-obj-$(CONFIG_CCIX_SWITCH) += ccix_upstream.o ccix_downstream.o
diff --git a/hw/pci-bridge/ccix_downstream.c b/hw/pci-bridge/ccix_downstream.c
new file mode 100644
index 0000000000..92c66431e2
--- /dev/null
+++ b/hw/pci-bridge/ccix_downstream.c
@@ -0,0 +1,222 @@
+/*
+ * ccix_downstream.c
+ * A PCIe downstream switch port with CCIX support.
+ * 
+ * Copyright (c) 2019 Jonathan Cameron <address@hidden>
+ *                    Huawei
+ * Based on: xio3130_downstream.c
+ * Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * 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 "hw/pci/pci_ids.h"
+#include "hw/pci/msi.h"
+#include "hw/pci/pcie.h"
+#include "hw/pci/pcie_port.h"
+#include "qapi/error.h"
+#include "hw/misc/ccix.h"
+#include "qemu/module.h"
+
+/*
+ * No public spec is available for a CCIX downstream port so for
+ * now use the values from teh xio3130 pcie downstream port
+ */
+#define XIO3130_MSI_OFFSET              0x70
+#define XIO3130_MSI_SUPPORTED_FLAGS     PCI_MSI_FLAGS_64BIT
+#define XIO3130_MSI_NR_VECTOR           1
+#define XIO3130_SSVID_OFFSET            0x80
+#define XIO3130_SSVID_SVID              0
+#define XIO3130_SSVID_SSID              0
+#define XIO3130_EXP_OFFSET              0x90
+#define XIO3130_AER_OFFSET              0x100
+
+#define TYPE_CCIX_DOWN_PORT "ccix-downstream-port"
+
+#define CCIX_DOWN_DEV(obj) OBJECT_CHECK(CCIXDownPortState, (obj), 
TYPE_CCIX_DOWN_PORT)
+
+typedef struct CCIXDownPortState {
+    PCIESlot parent_obj;
+    struct CCIXState s;
+} CCIXDownPortState;
+
+static void ccix_downstream_write_config(PCIDevice *d, uint32_t address,
+                                  uint32_t val, int len)
+{
+    CCIXDownPortState *s = CCIX_DOWN_DEV(d);
+
+    pci_bridge_write_config(d, address, val, len);
+    pcie_cap_flr_write_config(d, address, val, len);
+    pcie_cap_slot_write_config(d, address, val, len);
+    pcie_aer_write_config(d, address, val, len);
+    ccix_write_config(d, &s->s, address, val, len);
+}
+
+static void ccix_downstream_reset(DeviceState *qdev)
+{
+    PCIDevice *d = PCI_DEVICE(qdev);
+
+    pcie_cap_deverr_reset(d);
+    pcie_cap_slot_reset(d);
+    pcie_cap_arifwd_reset(d);
+    pci_bridge_reset(qdev);
+}
+
+static void ccix_downstream_realize(PCIDevice *d, Error **errp)
+{
+    PCIEPort *p = PCIE_PORT(d);
+    PCIESlot *s = PCIE_SLOT(d);
+    CCIXDownPortState *cs = CCIX_DOWN_DEV(d);
+    /* Allow space for existing extended capabilities from xio3130 */
+    uint32_t offset = 0x180;
+    int rc;
+
+    pci_bridge_initfn(d, TYPE_PCIE_BUS);
+    pcie_port_init_reg(d);
+
+    rc = msi_init(d, XIO3130_MSI_OFFSET, XIO3130_MSI_NR_VECTOR,
+                  XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT,
+                  XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT,
+                  errp);
+    if (rc < 0) {
+        assert(rc == -ENOTSUP);
+        goto err_bridge;
+    }
+
+    rc = pci_bridge_ssvid_init(d, XIO3130_SSVID_OFFSET,
+                               XIO3130_SSVID_SVID, XIO3130_SSVID_SSID,
+                               errp);
+    if (rc < 0) {
+        goto err_bridge;
+    }
+
+    rc = pcie_cap_init(d, XIO3130_EXP_OFFSET, PCI_EXP_TYPE_DOWNSTREAM,
+                       p->port, errp);
+    if (rc < 0) {
+        goto err_msi;
+    }
+    pcie_cap_flr_init(d);
+    pcie_cap_deverr_init(d);
+    pcie_cap_slot_init(d, s->slot);
+    pcie_cap_arifwd_init(d);
+
+    pcie_chassis_create(s->chassis);
+    rc = pcie_chassis_add_slot(s);
+    if (rc < 0) {
+        error_setg(errp, "Can't add chassis slot, error %d", rc);
+        goto err_pcie_cap;
+    }
+
+    rc = pcie_aer_init(d, PCI_ERR_VER, XIO3130_AER_OFFSET,
+                       PCI_ERR_SIZEOF, errp);
+    if (rc < 0) {
+        goto err;
+    }
+    initialize_ccixstate(&cs->s, d);
+    ccix_set_port(&cs->s);
+    offset = ccix_add_prldvsec(d, &cs->s, offset);
+    ccix_add_tdldvsec(d, offset);
+    ccix_register(&cs->s);
+
+    return;
+
+err:
+    pcie_chassis_del_slot(s);
+err_pcie_cap:
+    pcie_cap_exit(d);
+err_msi:
+    msi_uninit(d);
+err_bridge:
+    pci_bridge_exitfn(d);
+}
+
+static void ccix_downstream_exitfn(PCIDevice *d)
+{
+    PCIESlot *s = PCIE_SLOT(d);
+
+    pcie_aer_exit(d);
+    pcie_chassis_del_slot(s);
+    pcie_cap_exit(d);
+    msi_uninit(d);
+    pci_bridge_exitfn(d);
+}
+
+static Property ccix_props[] = {
+    DEFINE_PROP_STRING("ccix_device", CCIXDownPortState, s.ccix_dev_name),
+    DEFINE_PROP_BIT("primaryport", CCIXDownPortState, s.flags, 
PRIMARY_PORT_BIT, false),
+    DEFINE_PROP_UINT8("port_id", CCIXDownPortState, s.port_id, 0),
+    DEFINE_PROP_UINT8("num_links", CCIXDownPortState, s.num_links, 1),
+    DEFINE_PROP_UINT8("psam_entries", CCIXDownPortState, s.psam_entries, 0),
+    DEFINE_PROP_UINT8("request_agents", CCIXDownPortState, s.num_ras, 0),
+    DEFINE_PROP_UINT8("home_agents", CCIXDownPortState, s.num_has, 0),
+    DEFINE_PROP_UINT8("hsam_entries", CCIXDownPortState, s.hsam_entries, 0),
+    DEFINE_PROP_UINT8("rsam_entries", CCIXDownPortState, s.rsam_entries, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static const VMStateDescription vmstate_ccix_downstream = {
+    .name = "ccix-downstream-port",
+    .priority = MIG_PRI_PCI_BUS,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .post_load = pcie_cap_slot_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_PCI_DEVICE(parent_obj.parent_obj.parent_obj, PCIESlot),
+        VMSTATE_STRUCT(parent_obj.parent_obj.parent_obj.exp.aer_log,
+                       PCIESlot, 0, vmstate_pcie_aer_log, PCIEAERLog),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+
+static void ccix_downstream_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->is_bridge = true;
+    k->config_write = ccix_downstream_write_config;
+    k->realize = ccix_downstream_realize;
+    k->exit = ccix_downstream_exitfn;
+    /* Temp values for the RFC */
+    k->vendor_id = PCI_VENDOR_ID_HUAWEI;
+    k->device_id = PCI_DEVICE_ID_HUAWEI_CCIX_DOWN;;
+    k->revision = 1;
+    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+    dc->desc = "CCIX / PCIE switch downstream port";
+    dc->reset = ccix_downstream_reset;
+    dc->vmsd = &vmstate_ccix_downstream;
+    dc->props = ccix_props;
+}
+
+static const TypeInfo ccix_downstream_info = {
+    .name = TYPE_CCIX_DOWN_PORT,
+    .parent = TYPE_PCIE_SLOT,
+    .class_init = ccix_downstream_class_init,
+    .instance_size = sizeof(CCIXDownPortState),
+    .interfaces = (InterfaceInfo[]) {
+        { INTERFACE_PCIE_DEVICE },
+        { }
+    },
+};
+
+static void ccix_downstream_register_types(void)
+{
+    type_register_static(&ccix_downstream_info);
+}
+
+type_init(ccix_downstream_register_types)
+    
-- 
2.20.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]