[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-arm] [RFC PATCH 5/7] pci-bridge: CCIX capable PCIE/CCIX switch dow
From: |
Jonathan Cameron |
Subject: |
[Qemu-arm] [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
- [Qemu-arm] [RFC PATCH 0/7] qemu: CCIX pcie config space emulation, Jonathan Cameron, 2019/06/25
- [Qemu-arm] [RFC PATCH 2/7] pci: Add Huawei vendor ID and Huawei Emulated CCIX Device IDs., Jonathan Cameron, 2019/06/25
- [Qemu-arm] [RFC PATCH 1/7] Temp: Add the PCI_EXT_ID_DVSEC definition to the qemu pci_regs.h copy., Jonathan Cameron, 2019/06/25
- [Qemu-arm] [RFC PATCH 4/7] pci-bridge: CCIX capable PCIE/CCIX switch upstream port., Jonathan Cameron, 2019/06/25
- [Qemu-arm] [RFC PATCH 7/7] Temp: Add to ARM64 makefiles for testing, Jonathan Cameron, 2019/06/25
- [Qemu-arm] [RFC PATCH 5/7] pci-bridge: CCIX capable PCIE/CCIX switch downstream port,
Jonathan Cameron <=
- [Qemu-arm] [RFC PATCH 6/7] misc: CCIX endpoint function, Jonathan Cameron, 2019/06/25
- [Qemu-arm] [RFC PATCH 3/7] pci: CCIX config space emulation library., Jonathan Cameron, 2019/06/25