QEMU-Devel Archive on lore.kernel.org
 help / color / Atom feed
From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
To: QEMU Developers <qemu-devel@nongnu.org>
Cc: Peter Maydell <peter.maydell@linaro.org>,
	jcm@redhat.com, linuxarm@huawei.com,
	Auger Eric <eric.auger@redhat.com>,
	qemu-arm <qemu-arm@nongnu.org>,
	Jonathan Cameron <Jonathan.Cameron@huawei.com>
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
Message-ID: <20190625112752.83188-6-Jonathan.Cameron@huawei.com> (raw)
In-Reply-To: <20190625112752.83188-1-Jonathan.Cameron@huawei.com>

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 <Jonathan.Cameron@huawei.com>
---
 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 <Jonathan.Cameron@huawei.com>
+ *                    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



  parent reply index

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-25 11:27 [Qemu-devel] [RFC PATCH 0/7] qemu: CCIX pcie config space emulation Jonathan Cameron
2019-06-25 11:27 ` [Qemu-devel] [RFC PATCH 1/7] Temp: Add the PCI_EXT_ID_DVSEC definition to the qemu pci_regs.h copy Jonathan Cameron
2019-06-25 11:27 ` [Qemu-devel] [RFC PATCH 2/7] pci: Add Huawei vendor ID and Huawei Emulated CCIX Device IDs Jonathan Cameron
2019-06-25 11:27 ` [Qemu-devel] [RFC PATCH 3/7] pci: CCIX config space emulation library Jonathan Cameron
2019-06-25 11:27 ` [Qemu-devel] [RFC PATCH 4/7] pci-bridge: CCIX capable PCIE/CCIX switch upstream port Jonathan Cameron
2019-06-25 11:27 ` Jonathan Cameron [this message]
2019-06-25 11:27 ` [Qemu-devel] [RFC PATCH 6/7] misc: CCIX endpoint function Jonathan Cameron
2019-06-25 11:27 ` [Qemu-devel] [RFC PATCH 7/7] Temp: Add to ARM64 makefiles for testing Jonathan Cameron
2019-08-06 11:19 ` [Qemu-devel] [RFC PATCH 0/7] qemu: CCIX pcie config space emulation Jonathan Cameron
2019-08-16 12:59 ` Peter Maydell
2019-08-19  9:47   ` Jonathan Cameron

Reply instructions:

You may reply publically to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190625112752.83188-6-Jonathan.Cameron@huawei.com \
    --to=jonathan.cameron@huawei.com \
    --cc=eric.auger@redhat.com \
    --cc=jcm@redhat.com \
    --cc=linuxarm@huawei.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

QEMU-Devel Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/qemu-devel/0 qemu-devel/git/0.git
	git clone --mirror https://lore.kernel.org/qemu-devel/1 qemu-devel/git/1.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 qemu-devel qemu-devel/ https://lore.kernel.org/qemu-devel \
		qemu-devel@nongnu.org
	public-inbox-index qemu-devel

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.nongnu.qemu-devel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git