diff mbox series

[4/5] ppc/pnv: add a PSI bridge model for POWER10

Message ID 20191205184454.10722-5-clg@kaod.org
State New
Headers show
Series ppc/pnv: add a POWER10 PnvChip and a powernv10 machine | expand

Commit Message

Cédric Le Goater Dec. 5, 2019, 6:44 p.m. UTC
The POWER10 PSIHB controller is very similar to the one on POWER9. We
should probably introduce a common PnvPsiXive object.

The ESB page size should be changed to 64k when P10 support is ready.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/pnv.h       |  9 +++++++++
 include/hw/ppc/pnv_psi.h   |  2 ++
 include/hw/ppc/pnv_xscom.h |  3 +++
 hw/ppc/pnv.c               | 27 ++++++++++++++++++++-------
 hw/ppc/pnv_psi.c           | 25 ++++++++++++++++++++++++-
 5 files changed, 58 insertions(+), 8 deletions(-)
diff mbox series

Patch

diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index bfa61edfbabd..47b7370b27d8 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -112,6 +112,9 @@  typedef struct Pnv9Chip {
 typedef struct Pnv10Chip {
     /*< private >*/
     PnvChip      parent_obj;
+
+    /*< public >*/
+    Pnv9Psi      psi;
 } Pnv10Chip;
 
 typedef struct PnvChipClass {
@@ -326,4 +329,10 @@  IPMIBmc *pnv_bmc_create(void);
 #define PNV10_XSCOM_SIZE             0x0000000400000000ull
 #define PNV10_XSCOM_BASE(chip)       PNV10_CHIP_BASE(chip, 0x00603fc00000000ull)
 
+#define PNV10_PSIHB_ESB_SIZE        0x0000000000100000ull
+#define PNV10_PSIHB_ESB_BASE(chip)  PNV10_CHIP_BASE(chip, 0x0006030202000000ull)
+
+#define PNV10_PSIHB_SIZE            0x0000000000100000ull
+#define PNV10_PSIHB_BASE(chip)      PNV10_CHIP_BASE(chip, 0x0006030203000000ull)
+
 #endif /* PPC_PNV_H */
diff --git a/include/hw/ppc/pnv_psi.h b/include/hw/ppc/pnv_psi.h
index e82df9709fb8..a044aab304ae 100644
--- a/include/hw/ppc/pnv_psi.h
+++ b/include/hw/ppc/pnv_psi.h
@@ -69,6 +69,8 @@  typedef struct Pnv9Psi {
     XiveSource source;
 } Pnv9Psi;
 
+#define TYPE_PNV10_PSI TYPE_PNV_PSI "-POWER10"
+
 #define PNV_PSI_CLASS(klass) \
      OBJECT_CLASS_CHECK(PnvPsiClass, (klass), TYPE_PNV_PSI)
 #define PNV_PSI_GET_CLASS(obj) \
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index 790eb3d8f3b0..a40d2a2a2a98 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -106,6 +106,9 @@  typedef struct PnvXScomInterfaceClass {
     ((uint64_t) PNV10_XSCOM_EQ_BASE(core) | PNV10_XSCOM_EC(core & 0x3))
 #define PNV10_XSCOM_EC_SIZE        0x100000
 
+#define PNV10_XSCOM_PSIHB_BASE     0x3011D00
+#define PNV10_XSCOM_PSIHB_SIZE     0x100
+
 extern void pnv_xscom_realize(PnvChip *chip, uint64_t size, Error **errp);
 extern int pnv_dt_xscom(PnvChip *chip, void *fdt, int offset);
 
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index d99cd72840be..09263ab747d8 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -647,9 +647,9 @@  static void pnv_ipmi_bt_init(ISABus *bus, IPMIBmc *bmc, uint32_t irq)
 
 static void pnv_chip_power10_pic_print_info(PnvChip *chip, Monitor *mon)
 {
-    /*
-     * No interrupt controller yet
-     */;
+    Pnv10Chip *chip10 = PNV10_CHIP(chip);
+
+    pnv_psi_pic_print_info(&chip10->psi, mon);
 }
 
 static void pnv_init(MachineState *machine)
@@ -1311,16 +1311,17 @@  static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
 
 static void pnv_chip_power10_instance_init(Object *obj)
 {
-    /*
-     * No controllers yet
-     */
-    ;
+    Pnv10Chip *chip10 = PNV10_CHIP(obj);
+
+    object_initialize_child(obj, "psi",  &chip10->psi, sizeof(chip10->psi),
+                            TYPE_PNV10_PSI, &error_abort, NULL);
 }
 
 static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
 {
     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
     PnvChip *chip = PNV_CHIP(dev);
+    Pnv10Chip *chip10 = PNV10_CHIP(dev);
     Error *local_err = NULL;
 
     /* XSCOM bridge is first */
@@ -1336,6 +1337,18 @@  static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
         error_propagate(errp, local_err);
         return;
     }
+
+    /* Processor Service Interface (PSI) Host Bridge */
+    object_property_set_int(OBJECT(&chip10->psi), PNV10_PSIHB_BASE(chip),
+                            "bar", &error_fatal);
+    object_property_set_bool(OBJECT(&chip10->psi), true, "realized",
+                             &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    pnv_xscom_add_subregion(chip, PNV10_XSCOM_PSIHB_BASE,
+                            &PNV_PSI(&chip10->psi)->xscom_regs);
 }
 
 static void pnv_chip_power10_class_init(ObjectClass *klass, void *data)
diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
index f15aaa5c9cc0..32e4cbdb09bb 100644
--- a/hw/ppc/pnv_psi.c
+++ b/hw/ppc/pnv_psi.c
@@ -539,6 +539,7 @@  static void pnv_psi_power8_realize(DeviceState *dev, Error **errp)
 
 static const char compat_p8[] = "ibm,power8-psihb-x\0ibm,psihb-x";
 static const char compat_p9[] = "ibm,power9-psihb-x\0ibm,psihb-x";
+static const char compat_p10[] = "ibm,power10-psihb-x\0ibm,psihb-x";
 
 static int pnv_psi_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
 {
@@ -558,7 +559,10 @@  static int pnv_psi_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
     _FDT(fdt_setprop(fdt, offset, "reg", reg, sizeof(reg)));
     _FDT(fdt_setprop_cell(fdt, offset, "#address-cells", 2));
     _FDT(fdt_setprop_cell(fdt, offset, "#size-cells", 1));
-    if (ppc->chip_type == PNV_CHIP_POWER9) {
+    if (ppc->chip_type == PNV_CHIP_POWER10) {
+        _FDT(fdt_setprop(fdt, offset, "compatible", compat_p10,
+                         sizeof(compat_p10)));
+    } else if (ppc->chip_type == PNV_CHIP_POWER9) {
         _FDT(fdt_setprop(fdt, offset, "compatible", compat_p9,
                          sizeof(compat_p9)));
     } else {
@@ -910,6 +914,24 @@  static const TypeInfo pnv_psi_power9_info = {
     },
 };
 
+static void pnv_psi_power10_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PnvPsiClass *ppc = PNV_PSI_CLASS(klass);
+
+    dc->desc    = "PowerNV PSI Controller POWER10";
+
+    ppc->chip_type  = PNV_CHIP_POWER10;
+    ppc->xscom_pcba = PNV10_XSCOM_PSIHB_BASE;
+    ppc->xscom_size = PNV10_XSCOM_PSIHB_SIZE;
+}
+
+static const TypeInfo pnv_psi_power10_info = {
+    .name          = TYPE_PNV10_PSI,
+    .parent        = TYPE_PNV9_PSI,
+    .class_init    = pnv_psi_power10_class_init,
+};
+
 static void pnv_psi_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -939,6 +961,7 @@  static void pnv_psi_register_types(void)
     type_register_static(&pnv_psi_info);
     type_register_static(&pnv_psi_power8_info);
     type_register_static(&pnv_psi_power9_info);
+    type_register_static(&pnv_psi_power10_info);
 }
 
 type_init(pnv_psi_register_types);