diff mbox series

[05/17] ppc/pnv: add pnv-phb device

Message ID 20220507190624.507419-6-danielhb413@gmail.com (mailing list archive)
State New, archived
Headers show
Series powernv: introduce pnv-phb unified devices | expand

Commit Message

Daniel Henrique Barboza May 7, 2022, 7:06 p.m. UTC
This device works as a generic pnv-phb that redirects the control flow
to one of the implemented PHB versions (PHB3 and PHB4 at this moment).

The control redirection happens in the instance_init() and realize()
callbacks, where we check which powernv machine we're running and
execute the PnvPHB3 callbacks if running powernv8 or PnvPHB4 if running
powernv9/10.  This will allow us to keep the existing PHB3 and PHB4 code
as is, just changing their device type to PnvPHB3/PnvPHB4 to PnvPHB when
we're ready.

For now we're putting logic to handle the PHB3 version. We'll add PHB4
later on.

Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
---
 hw/pci-host/meson.build        |   3 +-
 hw/pci-host/pnv_phb.c          | 116 +++++++++++++++++++++++++++++++++
 hw/pci-host/pnv_phb3.c         |   4 +-
 include/hw/pci-host/pnv_phb3.h |   3 +
 4 files changed, 123 insertions(+), 3 deletions(-)
 create mode 100644 hw/pci-host/pnv_phb.c
diff mbox series

Patch

diff --git a/hw/pci-host/meson.build b/hw/pci-host/meson.build
index 4c4f39c15c..b4107b7a2a 100644
--- a/hw/pci-host/meson.build
+++ b/hw/pci-host/meson.build
@@ -32,5 +32,6 @@  specific_ss.add(when: 'CONFIG_PCI_POWERNV', if_true: files(
   'pnv_phb3_msi.c',
   'pnv_phb3_pbcq.c',
   'pnv_phb4.c',
-  'pnv_phb4_pec.c'
+  'pnv_phb4_pec.c',
+  'pnv_phb.c',
 ))
diff --git a/hw/pci-host/pnv_phb.c b/hw/pci-host/pnv_phb.c
new file mode 100644
index 0000000000..3dd08f768f
--- /dev/null
+++ b/hw/pci-host/pnv_phb.c
@@ -0,0 +1,116 @@ 
+/*
+ * QEMU PowerPC PowerNV Unified PHB model
+ *
+ * Copyright (c) 2022, IBM Corporation.
+ *
+ * This code is licensed under the GPL version 2 or later. See the
+ * COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/visitor.h"
+#include "qapi/error.h"
+#include "hw/pci-host/pnv_phb.h"
+#include "hw/pci/pcie_host.h"
+#include "hw/pci/pcie_port.h"
+#include "hw/ppc/pnv.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "qom/object.h"
+#include "sysemu/sysemu.h"
+
+
+static char *pnv_phb_get_chip_typename(void)
+{
+    Object *qdev_machine = qdev_get_machine();
+    PnvMachineState *pnv = PNV_MACHINE(qdev_machine);
+    MachineState *machine = MACHINE(pnv);
+    g_autofree char *chip_typename = NULL;
+    int i;
+
+    if (!machine->cpu_type) {
+        return NULL;
+    }
+
+    i = strlen(machine->cpu_type) - strlen(POWERPC_CPU_TYPE_SUFFIX);
+    chip_typename = g_strdup_printf(PNV_CHIP_TYPE_NAME("%.*s"),
+                                    i, machine->cpu_type);
+
+    return g_steal_pointer(&chip_typename);
+}
+
+static void pnv_phb_instance_init(Object *obj)
+{
+    g_autofree char *chip_typename = pnv_phb_get_chip_typename();
+
+    /*
+     * When doing command line instrospection we won't have
+     * a valid machine->cpu_type value.
+     */
+    if (!chip_typename) {
+        return;
+    }
+
+    if (!strcmp(chip_typename, TYPE_PNV_CHIP_POWER8) ||
+        !strcmp(chip_typename, TYPE_PNV_CHIP_POWER8E) ||
+        !strcmp(chip_typename, TYPE_PNV_CHIP_POWER8NVL)) {
+        pnv_phb3_instance_init(obj);
+    }
+}
+
+static void pnv_phb_realize(DeviceState *dev, Error **errp)
+{
+    g_autofree char *chip_typename = pnv_phb_get_chip_typename();
+
+    g_assert(chip_typename != NULL);
+
+    if (!strcmp(chip_typename, TYPE_PNV_CHIP_POWER8) ||
+        !strcmp(chip_typename, TYPE_PNV_CHIP_POWER8E) ||
+        !strcmp(chip_typename, TYPE_PNV_CHIP_POWER8NVL)) {
+        /* PnvPHB3 */
+        pnv_phb3_realize(dev, errp);
+    }
+}
+
+static const char *pnv_phb_root_bus_path(PCIHostState *host_bridge,
+                                          PCIBus *rootbus)
+{
+    PnvPHB *phb = PNV_PHB(host_bridge);
+
+    snprintf(phb->bus_path, sizeof(phb->bus_path), "00%02x:%02x",
+             phb->chip_id, phb->phb_id);
+    return phb->bus_path;
+}
+
+static Property pnv_phb_properties[] = {
+    DEFINE_PROP_UINT32("index", PnvPHB, phb_id, 0),
+    DEFINE_PROP_UINT32("chip-id", PnvPHB, chip_id, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void pnv_phb_class_init(ObjectClass *klass, void *data)
+{
+    PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    hc->root_bus_path = pnv_phb_root_bus_path;
+    dc->realize = pnv_phb_realize;
+    device_class_set_props(dc, pnv_phb_properties);
+    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+    dc->user_creatable = true;
+}
+
+static const TypeInfo pnv_phb_type_info = {
+    .name          = TYPE_PNV_PHB,
+    .parent        = TYPE_PCIE_HOST_BRIDGE,
+    .instance_size = sizeof(PnvPHB),
+    .class_init    = pnv_phb_class_init,
+    .instance_init = pnv_phb_instance_init,
+};
+
+static void pnv_phb_register_types(void)
+{
+    type_register_static(&pnv_phb_type_info);
+}
+
+type_init(pnv_phb_register_types)
diff --git a/hw/pci-host/pnv_phb3.c b/hw/pci-host/pnv_phb3.c
index 70d92edd94..8e31a69083 100644
--- a/hw/pci-host/pnv_phb3.c
+++ b/hw/pci-host/pnv_phb3.c
@@ -966,7 +966,7 @@  static AddressSpace *pnv_phb3_dma_iommu(PCIBus *bus, void *opaque, int devfn)
     return &ds->dma_as;
 }
 
-static void pnv_phb3_instance_init(Object *obj)
+void pnv_phb3_instance_init(Object *obj)
 {
     PnvPHB3 *phb = PNV_PHB3(obj);
 
@@ -986,7 +986,7 @@  static void pnv_phb3_instance_init(Object *obj)
 
 }
 
-static void pnv_phb3_realize(DeviceState *dev, Error **errp)
+void pnv_phb3_realize(DeviceState *dev, Error **errp)
 {
     PnvPHB3 *phb = PNV_PHB3(dev);
     PCIHostState *pci = PCI_HOST_BRIDGE(dev);
diff --git a/include/hw/pci-host/pnv_phb3.h b/include/hw/pci-host/pnv_phb3.h
index b6b5f91684..aba26f4f7c 100644
--- a/include/hw/pci-host/pnv_phb3.h
+++ b/include/hw/pci-host/pnv_phb3.h
@@ -102,4 +102,7 @@  void pnv_phb3_reg_write(void *opaque, hwaddr off, uint64_t val, unsigned size);
 void pnv_phb3_update_regions(PnvPHB3 *phb);
 void pnv_phb3_remap_irqs(PnvPHB3 *phb);
 
+void pnv_phb3_instance_init(Object *obj);
+void pnv_phb3_realize(DeviceState *dev, Error **errp);
+
 #endif /* PCI_HOST_PNV_PHB3_H */