aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCédric Le Goater <clg@kaod.org>2022-01-12 11:28:27 +0100
committerCédric Le Goater <clg@kaod.org>2022-01-12 11:28:27 +0100
commitc29dd0034deafc9772eb256f7b4cea16c5bffd65 (patch)
tree7d4b6e368629d2c3c352b1d03c3042546b9b6e1e
parent1f6a88fffc7533a9fd64c74c298d82590277cb3b (diff)
ppc/pnv: Reparent user created PHB3 devices to the PnvChip
The powernv machine uses the object hierarchy to populate the device tree and each device should be parented to the chip it belongs to. This is not the case for user created devices which are parented to the container "/unattached". Make sure a PHB3 device is parented to its chip by reparenting the object if necessary. Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> Reviewed-by: Frederic Barrat <fbarrat@linux.ibm.com> Signed-off-by: Cédric Le Goater <clg@kaod.org> Message-Id: <20220105212338.49899-8-danielhb413@gmail.com> Signed-off-by: Cédric Le Goater <clg@kaod.org>
-rw-r--r--hw/pci-host/pnv_phb3.c6
-rw-r--r--hw/ppc/pnv.c17
-rw-r--r--include/hw/ppc/pnv.h1
3 files changed, 24 insertions, 0 deletions
diff --git a/hw/pci-host/pnv_phb3.c b/hw/pci-host/pnv_phb3.c
index 1ebe43df5d..a52aedcad3 100644
--- a/hw/pci-host/pnv_phb3.c
+++ b/hw/pci-host/pnv_phb3.c
@@ -998,6 +998,12 @@ static void pnv_phb3_realize(DeviceState *dev, Error **errp)
error_setg(errp, "invalid chip id: %d", phb->chip_id);
return;
}
+
+ /*
+ * Reparent user created devices to the chip to build
+ * correctly the device tree.
+ */
+ pnv_chip_parent_fixup(phb->chip, OBJECT(phb), phb->phb_id);
}
if (phb->phb_id >= PNV_CHIP_GET_CLASS(phb->chip)->num_phbs) {
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index ad02d56aa7..fa5e7bc751 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1814,6 +1814,23 @@ static ICSState *pnv_ics_get(XICSFabric *xi, int irq)
return NULL;
}
+void pnv_chip_parent_fixup(PnvChip *chip, Object *obj, int index)
+{
+ Object *parent = OBJECT(chip);
+ g_autofree char *default_id =
+ g_strdup_printf("%s[%d]", object_get_typename(obj), index);
+
+ if (obj->parent == parent) {
+ return;
+ }
+
+ object_ref(obj);
+ object_unparent(obj);
+ object_property_add_child(
+ parent, DEVICE(obj)->id ? DEVICE(obj)->id : default_id, obj);
+ object_unref(obj);
+}
+
PnvChip *pnv_get_chip(PnvMachineState *pnv, uint32_t chip_id)
{
int i;
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 64bab7112b..f4219da7c5 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -178,6 +178,7 @@ DECLARE_INSTANCE_CHECKER(PnvChip, PNV_CHIP_POWER10,
PowerPCCPU *pnv_chip_find_cpu(PnvChip *chip, uint32_t pir);
void pnv_phb_attach_root_port(PCIHostState *pci, const char *name);
+void pnv_chip_parent_fixup(PnvChip *chip, Object *obj, int index);
#define TYPE_PNV_MACHINE MACHINE_TYPE_NAME("powernv")
typedef struct PnvMachineClass PnvMachineClass;