diff options
author | Cédric Le Goater | 2022-03-02 06:51:39 +0100 |
---|---|---|
committer | Cédric Le Goater | 2022-03-02 06:51:39 +0100 |
commit | 623575e16cd55082ca36b57114a774f146b2c95b (patch) | |
tree | d75205ae6db121b3518f6937eac1722145f044ce /hw/ppc | |
parent | ppc/pnv: Add POWER10 quads (diff) | |
download | qemu-623575e16cd55082ca36b57114a774f146b2c95b.tar.gz qemu-623575e16cd55082ca36b57114a774f146b2c95b.tar.xz qemu-623575e16cd55082ca36b57114a774f146b2c95b.zip |
ppc/pnv: Add model for POWER10 PHB5 PCIe Host bridge
PHB4 and PHB5 are very similar. Use the PHB4 models with some minor
adjustements in a subclass for P10.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Diffstat (limited to 'hw/ppc')
-rw-r--r-- | hw/ppc/pnv.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 77f250b86d..34659087e8 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -727,6 +727,9 @@ static void pnv_chip_power10_pic_print_info(PnvChip *chip, Monitor *mon) pnv_xive2_pic_print_info(&chip10->xive, mon); pnv_psi_pic_print_info(&chip10->psi, mon); + + object_child_foreach_recursive(OBJECT(chip), + pnv_chip_power9_pic_print_info_child, mon); } /* Always give the first 1GB to chip 0 else we won't boot */ @@ -1581,7 +1584,10 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data) static void pnv_chip_power10_instance_init(Object *obj) { + PnvChip *chip = PNV_CHIP(obj); Pnv10Chip *chip10 = PNV10_CHIP(obj); + PnvChipClass *pcc = PNV_CHIP_GET_CLASS(obj); + int i; object_initialize_child(obj, "xive", &chip10->xive, TYPE_PNV_XIVE2); object_property_add_alias(obj, "xive-fabric", OBJECT(&chip10->xive), @@ -1589,6 +1595,15 @@ static void pnv_chip_power10_instance_init(Object *obj) object_initialize_child(obj, "psi", &chip10->psi, TYPE_PNV10_PSI); object_initialize_child(obj, "lpc", &chip10->lpc, TYPE_PNV10_LPC); object_initialize_child(obj, "occ", &chip10->occ, TYPE_PNV10_OCC); + + if (defaults_enabled()) { + chip->num_pecs = pcc->num_pecs; + } + + for (i = 0; i < chip->num_pecs; i++) { + object_initialize_child(obj, "pec[*]", &chip10->pecs[i], + TYPE_PNV_PHB5_PEC); + } } static void pnv_chip_power10_quad_realize(Pnv10Chip *chip10, Error **errp) @@ -1609,6 +1624,34 @@ static void pnv_chip_power10_quad_realize(Pnv10Chip *chip10, Error **errp) } } +static void pnv_chip_power10_phb_realize(PnvChip *chip, Error **errp) +{ + Pnv10Chip *chip10 = PNV10_CHIP(chip); + int i; + + for (i = 0; i < chip->num_pecs; i++) { + PnvPhb4PecState *pec = &chip10->pecs[i]; + PnvPhb4PecClass *pecc = PNV_PHB4_PEC_GET_CLASS(pec); + uint32_t pec_nest_base; + uint32_t pec_pci_base; + + object_property_set_int(OBJECT(pec), "index", i, &error_fatal); + object_property_set_int(OBJECT(pec), "chip-id", chip->chip_id, + &error_fatal); + object_property_set_link(OBJECT(pec), "chip", OBJECT(chip), + &error_fatal); + if (!qdev_realize(DEVICE(pec), NULL, errp)) { + return; + } + + pec_nest_base = pecc->xscom_nest_base(pec); + pec_pci_base = pecc->xscom_pci_base(pec); + + pnv_xscom_add_subregion(chip, pec_nest_base, &pec->nest_regs_mr); + pnv_xscom_add_subregion(chip, pec_pci_base, &pec->pci_regs_mr); + } +} + static void pnv_chip_power10_realize(DeviceState *dev, Error **errp) { PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev); @@ -1687,6 +1730,13 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp) } pnv_xscom_add_subregion(chip, PNV10_XSCOM_OCC_BASE, &chip10->occ.xscom_regs); + + /* PHBs */ + pnv_chip_power10_phb_realize(chip, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } } static uint32_t pnv_chip_power10_xscom_pcba(PnvChip *chip, uint64_t addr) @@ -1713,6 +1763,7 @@ static void pnv_chip_power10_class_init(ObjectClass *klass, void *data) k->xscom_core_base = pnv_chip_power10_xscom_core_base; k->xscom_pcba = pnv_chip_power10_xscom_pcba; dc->desc = "PowerNV Chip POWER10"; + k->num_pecs = PNV10_CHIP_MAX_PEC; device_class_set_parent_realize(dc, pnv_chip_power10_realize, &k->parent_realize); |