All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/6] ppc/pnv: new Pnv8Chip and Pnv9Chip models
@ 2018-06-14 14:00 Cédric Le Goater
  2018-06-14 14:00 ` [Qemu-devel] [PATCH 1/6] ppc/pnv: introduce a 'primary' field under the LPC model Cédric Le Goater
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Cédric Le Goater @ 2018-06-14 14:00 UTC (permalink / raw)
  To: qemu-ppc; +Cc: qemu-devel, David Gibson, Cédric Le Goater

Hello,

First are some cleanups around the ISA bus of the machine. Then
additions of new chip models for the different processor the PowerNV
machine supports, which come with their respective "powernv8" and
"powernv9" machines.


For some obscure reasons, this patchset breaks 'make check' :

  TEST: tests/spapr-phb-test... (pid=8196)
  qemu-system-ppc64: -device spapr-pci-host-bridge,index=30: spapr-pci-host-bridge needs a pseries machine
  Broken pipe
 FAIL: tests/spapr-phb-test

Any idea ? I guess this is because of the new machines. 

Thanks,

C. 

Cédric Le Goater (6):
  ppc/pnv: introduce a 'primary' field under the LPC model
  ppc/pnv: move the details of the ISA bus creation under the LPC model
  ppc/pnv: introduce an 'isa_bus_name' field under the LPC model
  ppc/pnv: introduce a pnv_chip_core_realize() routine
  ppc/pnv: introduce a new intc_create() operation to the chip model
  ppc/pnv: introduce Pnv8Chip and Pnv9Chip models

 include/hw/ppc/pnv.h     |  29 +++-
 include/hw/ppc/pnv_lpc.h |   6 +-
 hw/ppc/pnv.c             | 380 +++++++++++++++++++++++++++++------------------
 hw/ppc/pnv_core.c        |  18 +--
 hw/ppc/pnv_lpc.c         |  55 +++++--
 5 files changed, 322 insertions(+), 166 deletions(-)

-- 
2.13.6

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 1/6] ppc/pnv: introduce a 'primary' field under the LPC model
  2018-06-14 14:00 [Qemu-devel] [PATCH 0/6] ppc/pnv: new Pnv8Chip and Pnv9Chip models Cédric Le Goater
@ 2018-06-14 14:00 ` Cédric Le Goater
  2018-06-15  2:38   ` David Gibson
  2018-06-14 14:00 ` [Qemu-devel] [PATCH 2/6] ppc/pnv: move the details of the ISA bus creation " Cédric Le Goater
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Cédric Le Goater @ 2018-06-14 14:00 UTC (permalink / raw)
  To: qemu-ppc; +Cc: qemu-devel, David Gibson, Cédric Le Goater

When a PowerNV system is started, the firmware (skiboot) looks for a
"primary" property to determine which LPC bus is the default on a
multichip system. This property is currently populated in the main
routine creating the device tree of a chip, which is the not the right
place to do so.

Check the chip id to flag the LPC controller as "primary", or not, and
use that to add the property in the LPC device tree routine.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/pnv_lpc.h |  2 ++
 hw/ppc/pnv.c             | 19 ++++++-------------
 hw/ppc/pnv_lpc.c         | 29 ++++++++++++++++++++---------
 3 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/include/hw/ppc/pnv_lpc.h b/include/hw/ppc/pnv_lpc.h
index 53fdd5bb6450..fddcb1c054b3 100644
--- a/include/hw/ppc/pnv_lpc.h
+++ b/include/hw/ppc/pnv_lpc.h
@@ -68,6 +68,8 @@ typedef struct PnvLpcController {
 
     /* PSI to generate interrupts */
     PnvPsi *psi;
+
+    bool   primary;
 } PnvLpcController;
 
 qemu_irq *pnv_lpc_isa_irq_create(PnvLpcController *lpc, int chip_type,
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 031488131629..b419d3323100 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -285,16 +285,6 @@ static void pnv_dt_chip(PnvChip *chip, void *fdt)
 
     pnv_dt_xscom(chip, fdt, 0);
 
-    /* The default LPC bus of a multichip system is on chip 0. It's
-     * recognized by the firmware (skiboot) using a "primary"
-     * property.
-     */
-    if (chip->chip_id == 0x0) {
-        int lpc_offset = pnv_chip_lpc_offset(chip, fdt);
-
-        _FDT((fdt_setprop(fdt, lpc_offset, "primary", NULL, 0)));
-    }
-
     for (i = 0; i < chip->nr_cores; i++) {
         PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
 
@@ -814,9 +804,12 @@ static void pnv_chip_init(Object *obj)
     object_property_add_const_link(OBJECT(&chip->occ), "psi",
                                    OBJECT(&chip->psi), &error_abort);
 
-    /* The LPC controller needs PSI to generate interrupts */
-    object_property_add_const_link(OBJECT(&chip->lpc), "psi",
-                                   OBJECT(&chip->psi), &error_abort);
+    /*
+     * The LPC controller needs a few things from the chip : to know
+     * if it's primary and PSI to generate interrupts
+     */
+    object_property_add_const_link(OBJECT(&chip->lpc), "chip",
+                                   OBJECT(chip), &error_abort);
 }
 
 static void pnv_chip_icp_realize(PnvChip *chip, Error **errp)
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index 402c4fefa886..1e70c8c19d52 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -113,6 +113,14 @@ static int pnv_lpc_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
     _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 2)));
     _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 1)));
     _FDT((fdt_setprop(fdt, offset, "compatible", compat, sizeof(compat))));
+
+    /*
+     * The default LPC bus of a multichip system is on chip 0. It's
+     * recognized by the firmware (skiboot) using a "primary" property.
+     */
+    if (PNV_LPC(dev)->primary) {
+        _FDT((fdt_setprop(fdt, offset, "primary", NULL, 0)));
+    }
     return 0;
 }
 
@@ -416,6 +424,18 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
     PnvLpcController *lpc = PNV_LPC(dev);
     Object *obj;
     Error *error = NULL;
+    PnvChip *chip;
+
+    /* get PSI object from chip */
+    obj = object_property_get_link(OBJECT(dev), "chip", &error);
+    if (!obj) {
+        error_propagate(errp, error);
+        error_prepend(errp, "required link 'chip' not found: ");
+        return;
+    }
+    chip = PNV_CHIP(obj);
+    lpc->psi = &chip->psi;
+    lpc->primary = chip->chip_id == 0;
 
     /* Reg inits */
     lpc->lpc_hc_fw_rd_acc_size = LPC_HC_FW_RD_4B;
@@ -460,15 +480,6 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
     pnv_xscom_region_init(&lpc->xscom_regs, OBJECT(dev),
                           &pnv_lpc_xscom_ops, lpc, "xscom-lpc",
                           PNV_XSCOM_LPC_SIZE);
-
-    /* get PSI object from chip */
-    obj = object_property_get_link(OBJECT(dev), "psi", &error);
-    if (!obj) {
-        error_setg(errp, "%s: required link 'psi' not found: %s",
-                   __func__, error_get_pretty(error));
-        return;
-    }
-    lpc->psi = PNV_PSI(obj);
 }
 
 static void pnv_lpc_class_init(ObjectClass *klass, void *data)
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 2/6] ppc/pnv: move the details of the ISA bus creation under the LPC model
  2018-06-14 14:00 [Qemu-devel] [PATCH 0/6] ppc/pnv: new Pnv8Chip and Pnv9Chip models Cédric Le Goater
  2018-06-14 14:00 ` [Qemu-devel] [PATCH 1/6] ppc/pnv: introduce a 'primary' field under the LPC model Cédric Le Goater
@ 2018-06-14 14:00 ` Cédric Le Goater
  2018-06-15  2:41   ` David Gibson
  2018-06-14 14:00 ` [Qemu-devel] [PATCH 3/6] ppc/pnv: introduce an 'isa_bus_name' field " Cédric Le Goater
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Cédric Le Goater @ 2018-06-14 14:00 UTC (permalink / raw)
  To: qemu-ppc; +Cc: qemu-devel, David Gibson, Cédric Le Goater

This is a small cleanup to hide to the machine the gory details of the
creation of the ISA bus. When time comes, the 'qemu_irq_handler' should
become a LPC controller class attribute.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/pnv_lpc.h |  3 +--
 hw/ppc/pnv.c             | 15 +--------------
 hw/ppc/pnv_lpc.c         | 24 ++++++++++++++++++++----
 3 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/include/hw/ppc/pnv_lpc.h b/include/hw/ppc/pnv_lpc.h
index fddcb1c054b3..fb4b7b83d798 100644
--- a/include/hw/ppc/pnv_lpc.h
+++ b/include/hw/ppc/pnv_lpc.h
@@ -72,7 +72,6 @@ typedef struct PnvLpcController {
     bool   primary;
 } PnvLpcController;
 
-qemu_irq *pnv_lpc_isa_irq_create(PnvLpcController *lpc, int chip_type,
-                                 int nirqs);
+ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, int chip_type);
 
 #endif /* _PPC_PNV_LPC_H */
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index b419d3323100..d2126ee4affc 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -521,22 +521,9 @@ static void pnv_reset(void)
 
 static ISABus *pnv_isa_create(PnvChip *chip)
 {
-    PnvLpcController *lpc = &chip->lpc;
-    ISABus *isa_bus;
-    qemu_irq *irqs;
     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
 
-    /* let isa_bus_new() create its own bridge on SysBus otherwise
-     * devices speficied on the command line won't find the bus and
-     * will fail to create.
-     */
-    isa_bus = isa_bus_new(NULL, &lpc->isa_mem, &lpc->isa_io,
-                          &error_fatal);
-
-    irqs = pnv_lpc_isa_irq_create(lpc, pcc->chip_type, ISA_NUM_IRQS);
-
-    isa_bus_irqs(isa_bus, irqs);
-    return isa_bus;
+    return pnv_lpc_isa_create(&chip->lpc, pcc->chip_type);
 }
 
 static void pnv_init(MachineState *machine)
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index 1e70c8c19d52..7c6c012d5176 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -22,6 +22,7 @@
 #include "target/ppc/cpu.h"
 #include "qapi/error.h"
 #include "qemu/log.h"
+#include "hw/isa/isa.h"
 
 #include "hw/ppc/pnv.h"
 #include "hw/ppc/pnv_lpc.h"
@@ -546,16 +547,31 @@ static void pnv_lpc_isa_irq_handler(void *opaque, int n, int level)
     }
 }
 
-qemu_irq *pnv_lpc_isa_irq_create(PnvLpcController *lpc, int chip_type,
-                                 int nirqs)
+ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, int chip_type)
 {
+    ISABus *isa_bus;
+    qemu_irq *irqs;
+    qemu_irq_handler handler;
+
+    /* let isa_bus_new() create its own bridge on SysBus otherwise
+     * devices speficied on the command line won't find the bus and
+     * will fail to create.
+     */
+    isa_bus = isa_bus_new(NULL, &lpc->isa_mem, &lpc->isa_io,
+                          &error_fatal);
+
     /* Not all variants have a working serial irq decoder. If not,
      * handling of LPC interrupts becomes a platform issue (some
      * platforms have a CPLD to do it).
      */
     if (chip_type == PNV_CHIP_POWER8NVL) {
-        return qemu_allocate_irqs(pnv_lpc_isa_irq_handler, lpc, nirqs);
+        handler = pnv_lpc_isa_irq_handler;
     } else {
-        return qemu_allocate_irqs(pnv_lpc_isa_irq_handler_cpld, lpc, nirqs);
+        handler = pnv_lpc_isa_irq_handler_cpld;
     }
+
+    irqs = qemu_allocate_irqs(handler, lpc, ISA_NUM_IRQS);
+
+    isa_bus_irqs(isa_bus, irqs);
+    return isa_bus;
 }
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 3/6] ppc/pnv: introduce an 'isa_bus_name' field under the LPC model
  2018-06-14 14:00 [Qemu-devel] [PATCH 0/6] ppc/pnv: new Pnv8Chip and Pnv9Chip models Cédric Le Goater
  2018-06-14 14:00 ` [Qemu-devel] [PATCH 1/6] ppc/pnv: introduce a 'primary' field under the LPC model Cédric Le Goater
  2018-06-14 14:00 ` [Qemu-devel] [PATCH 2/6] ppc/pnv: move the details of the ISA bus creation " Cédric Le Goater
@ 2018-06-14 14:00 ` Cédric Le Goater
  2018-06-15  2:47   ` David Gibson
  2018-06-14 14:00 ` [Qemu-devel] [PATCH 4/6] ppc/pnv: introduce a pnv_chip_core_realize() routine Cédric Le Goater
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Cédric Le Goater @ 2018-06-14 14:00 UTC (permalink / raw)
  To: qemu-ppc; +Cc: qemu-devel, David Gibson, Cédric Le Goater

This is again a small cleanup to hide to the machine the details of
the ISA bus. The ISA bus device tree nodename will be different on
Power9.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/pnv_lpc.h | 1 +
 hw/ppc/pnv.c             | 9 +--------
 hw/ppc/pnv_lpc.c         | 4 ++++
 3 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/include/hw/ppc/pnv_lpc.h b/include/hw/ppc/pnv_lpc.h
index fb4b7b83d798..e8f7dcb9bfe9 100644
--- a/include/hw/ppc/pnv_lpc.h
+++ b/include/hw/ppc/pnv_lpc.h
@@ -70,6 +70,7 @@ typedef struct PnvLpcController {
     PnvPsi *psi;
 
     bool   primary;
+    char   *isa_bus_name;
 } PnvLpcController;
 
 ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, int chip_type);
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index d2126ee4affc..72cfe4c2627c 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -267,14 +267,7 @@ static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t pir,
 
 static int pnv_chip_lpc_offset(PnvChip *chip, void *fdt)
 {
-    char *name;
-    int offset;
-
-    name = g_strdup_printf("/xscom@%" PRIx64 "/isa@%x",
-                           (uint64_t) PNV_XSCOM_BASE(chip), PNV_XSCOM_LPC_BASE);
-    offset = fdt_path_offset(fdt, name);
-    g_free(name);
-    return offset;
+    return fdt_path_offset(fdt, chip->lpc.isa_bus_name);
 }
 
 static void pnv_dt_chip(PnvChip *chip, void *fdt)
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index 7c6c012d5176..7f13c4bcf52c 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -481,6 +481,10 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
     pnv_xscom_region_init(&lpc->xscom_regs, OBJECT(dev),
                           &pnv_lpc_xscom_ops, lpc, "xscom-lpc",
                           PNV_XSCOM_LPC_SIZE);
+
+    lpc->isa_bus_name = g_strdup_printf("/xscom@%" PRIx64 "/isa@%x",
+                                        (uint64_t) PNV_XSCOM_BASE(chip),
+                                        PNV_XSCOM_LPC_BASE);
 }
 
 static void pnv_lpc_class_init(ObjectClass *klass, void *data)
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 4/6] ppc/pnv: introduce a pnv_chip_core_realize() routine
  2018-06-14 14:00 [Qemu-devel] [PATCH 0/6] ppc/pnv: new Pnv8Chip and Pnv9Chip models Cédric Le Goater
                   ` (2 preceding siblings ...)
  2018-06-14 14:00 ` [Qemu-devel] [PATCH 3/6] ppc/pnv: introduce an 'isa_bus_name' field " Cédric Le Goater
@ 2018-06-14 14:00 ` Cédric Le Goater
  2018-06-15  2:52   ` David Gibson
  2018-06-14 14:00 ` [Qemu-devel] [PATCH 5/6] ppc/pnv: introduce a new intc_create() operation to the chip model Cédric Le Goater
  2018-06-14 14:00 ` [Qemu-devel] [PATCH 6/6] ppc/pnv: introduce Pnv8Chip and Pnv9Chip models Cédric Le Goater
  5 siblings, 1 reply; 14+ messages in thread
From: Cédric Le Goater @ 2018-06-14 14:00 UTC (permalink / raw)
  To: qemu-ppc; +Cc: qemu-devel, David Gibson, Cédric Le Goater

This extracts from the PvChip realize routine the part creating the
cores. On Power9, we will need to create the cores after the Xive
interrupt controller is created.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/pnv.c | 32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 72cfe4c2627c..b3b0dd44582f 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -822,9 +822,8 @@ static void pnv_chip_icp_realize(PnvChip *chip, Error **errp)
     }
 }
 
-static void pnv_chip_realize(DeviceState *dev, Error **errp)
+static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
 {
-    PnvChip *chip = PNV_CHIP(dev);
     Error *error = NULL;
     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
     const char *typename = pnv_chip_core_typename(chip);
@@ -836,14 +835,6 @@ static void pnv_chip_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-    /* XSCOM bridge */
-    pnv_xscom_realize(chip, &error);
-    if (error) {
-        error_propagate(errp, error);
-        return;
-    }
-    sysbus_mmio_map(SYS_BUS_DEVICE(chip), 0, PNV_XSCOM_BASE(chip));
-
     /* Cores */
     pnv_chip_core_sanitize(chip, &error);
     if (error) {
@@ -891,6 +882,27 @@ static void pnv_chip_realize(DeviceState *dev, Error **errp)
                                 &PNV_CORE(pnv_core)->xscom_regs);
         i++;
     }
+}
+
+static void pnv_chip_realize(DeviceState *dev, Error **errp)
+{
+    PnvChip *chip = PNV_CHIP(dev);
+    Error *error = NULL;
+
+    /* XSCOM bridge */
+    pnv_xscom_realize(chip, &error);
+    if (error) {
+        error_propagate(errp, error);
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(chip), 0, PNV_XSCOM_BASE(chip));
+
+    /* Cores */
+    pnv_chip_core_realize(chip, &error);
+    if (error) {
+        error_propagate(errp, error);
+        return;
+    }
 
     /* Create LPC controller */
     object_property_set_bool(OBJECT(&chip->lpc), true, "realized",
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 5/6] ppc/pnv: introduce a new intc_create() operation to the chip model
  2018-06-14 14:00 [Qemu-devel] [PATCH 0/6] ppc/pnv: new Pnv8Chip and Pnv9Chip models Cédric Le Goater
                   ` (3 preceding siblings ...)
  2018-06-14 14:00 ` [Qemu-devel] [PATCH 4/6] ppc/pnv: introduce a pnv_chip_core_realize() routine Cédric Le Goater
@ 2018-06-14 14:00 ` Cédric Le Goater
  2018-06-15  2:55   ` David Gibson
  2018-06-14 14:00 ` [Qemu-devel] [PATCH 6/6] ppc/pnv: introduce Pnv8Chip and Pnv9Chip models Cédric Le Goater
  5 siblings, 1 reply; 14+ messages in thread
From: Cédric Le Goater @ 2018-06-14 14:00 UTC (permalink / raw)
  To: qemu-ppc; +Cc: qemu-devel, David Gibson, Cédric Le Goater

On Power9, the thread interrupt presenter has a different type and is
linked to the chip owning the cores.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/pnv.h |  1 +
 hw/ppc/pnv.c         | 21 +++++++++++++++++++--
 hw/ppc/pnv_core.c    | 18 +++++++++---------
 3 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 90759240a7b1..e934e84f555e 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -76,6 +76,7 @@ typedef struct PnvChipClass {
     hwaddr       xscom_base;
 
     uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id);
+    Object *(*intc_create)(PnvChip *chip, Object *child, Error **errp);
 } PnvChipClass;
 
 #define PNV_CHIP_TYPE_SUFFIX "-" TYPE_PNV_CHIP
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index b3b0dd44582f..7d99366daf90 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -641,6 +641,13 @@ static uint32_t pnv_chip_core_pir_p8(PnvChip *chip, uint32_t core_id)
     return (chip->chip_id << 7) | (core_id << 3);
 }
 
+static Object *pnv_chip_power8_intc_create(PnvChip *chip, Object *child,
+                                           Error **errp)
+{
+    return icp_create(child, TYPE_PNV_ICP, XICS_FABRIC(qdev_get_machine()),
+                      errp);
+}
+
 /*
  *    0:48  Reserved - Read as zeroes
  *   49:52  Node ID
@@ -656,6 +663,12 @@ static uint32_t pnv_chip_core_pir_p9(PnvChip *chip, uint32_t core_id)
     return (chip->chip_id << 8) | (core_id << 2);
 }
 
+static Object *pnv_chip_power9_intc_create(PnvChip *chip, Object *child,
+                                           Error **errp)
+{
+    return NULL;
+}
+
 /* Allowed core identifiers on a POWER8 Processor Chip :
  *
  * <EX0 reserved>
@@ -691,6 +704,7 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
     k->chip_cfam_id = 0x221ef04980000000ull;  /* P8 Murano DD2.1 */
     k->cores_mask = POWER8E_CORE_MASK;
     k->core_pir = pnv_chip_core_pir_p8;
+    k->intc_create = pnv_chip_power8_intc_create;
     k->xscom_base = 0x003fc0000000000ull;
     dc->desc = "PowerNV Chip POWER8E";
 }
@@ -704,6 +718,7 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data)
     k->chip_cfam_id = 0x220ea04980000000ull; /* P8 Venice DD2.0 */
     k->cores_mask = POWER8_CORE_MASK;
     k->core_pir = pnv_chip_core_pir_p8;
+    k->intc_create = pnv_chip_power8_intc_create;
     k->xscom_base = 0x003fc0000000000ull;
     dc->desc = "PowerNV Chip POWER8";
 }
@@ -717,6 +732,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data)
     k->chip_cfam_id = 0x120d304980000000ull;  /* P8 Naples DD1.0 */
     k->cores_mask = POWER8_CORE_MASK;
     k->core_pir = pnv_chip_core_pir_p8;
+    k->intc_create = pnv_chip_power8_intc_create;
     k->xscom_base = 0x003fc0000000000ull;
     dc->desc = "PowerNV Chip POWER8NVL";
 }
@@ -730,6 +746,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
     k->chip_cfam_id = 0x220d104900008000ull; /* P9 Nimbus DD2.0 */
     k->cores_mask = POWER9_CORE_MASK;
     k->core_pir = pnv_chip_core_pir_p9;
+    k->intc_create = pnv_chip_power9_intc_create;
     k->xscom_base = 0x00603fc00000000ull;
     dc->desc = "PowerNV Chip POWER9";
 }
@@ -865,8 +882,8 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
         object_property_set_int(OBJECT(pnv_core),
                                 pcc->core_pir(chip, core_hwid),
                                 "pir", &error_fatal);
-        object_property_add_const_link(OBJECT(pnv_core), "xics",
-                                       qdev_get_machine(), &error_fatal);
+        object_property_add_const_link(OBJECT(pnv_core), "chip",
+                                       OBJECT(chip), &error_fatal);
         object_property_set_bool(OBJECT(pnv_core), true, "realized",
                                  &error_fatal);
         object_unref(OBJECT(pnv_core));
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 13ad7d9e0470..5805bcd10abf 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -121,11 +121,12 @@ static const MemoryRegionOps pnv_core_xscom_ops = {
     .endianness = DEVICE_BIG_ENDIAN,
 };
 
-static void pnv_core_realize_child(Object *child, XICSFabric *xi, Error **errp)
+static void pnv_core_realize_child(Object *child, PnvChip *chip, Error **errp)
 {
     Error *local_err = NULL;
     CPUState *cs = CPU(child);
     PowerPCCPU *cpu = POWERPC_CPU(cs);
+    PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
 
     object_property_set_bool(child, true, "realized", &local_err);
     if (local_err) {
@@ -133,7 +134,7 @@ static void pnv_core_realize_child(Object *child, XICSFabric *xi, Error **errp)
         return;
     }
 
-    cpu->intc = icp_create(child, TYPE_PNV_ICP, xi, &local_err);
+    cpu->intc = pcc->intc_create(chip, child, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         return;
@@ -156,13 +157,12 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
     void *obj;
     int i, j;
     char name[32];
-    Object *xi;
+    Object *chip;
 
-    xi = object_property_get_link(OBJECT(dev), "xics", &local_err);
-    if (!xi) {
-        error_setg(errp, "%s: required link 'xics' not found: %s",
-                   __func__, error_get_pretty(local_err));
-        return;
+    chip = object_property_get_link(OBJECT(dev), "chip", &local_err);
+    if (!chip) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "required link 'chip' not found: ");
     }
 
     pc->threads = g_malloc0(size * cc->nr_threads);
@@ -184,7 +184,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
     for (j = 0; j < cc->nr_threads; j++) {
         obj = pc->threads + j * size;
 
-        pnv_core_realize_child(obj, XICS_FABRIC(xi), &local_err);
+        pnv_core_realize_child(obj, PNV_CHIP(chip), &local_err);
         if (local_err) {
             goto err;
         }
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 6/6] ppc/pnv: introduce Pnv8Chip and Pnv9Chip models
  2018-06-14 14:00 [Qemu-devel] [PATCH 0/6] ppc/pnv: new Pnv8Chip and Pnv9Chip models Cédric Le Goater
                   ` (4 preceding siblings ...)
  2018-06-14 14:00 ` [Qemu-devel] [PATCH 5/6] ppc/pnv: introduce a new intc_create() operation to the chip model Cédric Le Goater
@ 2018-06-14 14:00 ` Cédric Le Goater
  2018-06-15  3:16   ` David Gibson
  5 siblings, 1 reply; 14+ messages in thread
From: Cédric Le Goater @ 2018-06-14 14:00 UTC (permalink / raw)
  To: qemu-ppc; +Cc: qemu-devel, David Gibson, Cédric Le Goater

This is a major reshuffle of the PowerNV machine and chip models to
introduce a machine type per processor. It is quite noisy but it
doesn't change much the code flow.

It introduces a base PnvChip class from which the specific processor
chip classes, Pnv8Chip and Pnv9Chip, inherit. Each of them needs to
define an init and a realize routine which will create the controllers
of the target processor.

For the moment, the base PnvChip class handles the XSCOM bus and the
cores but the core creation will surely move to the specific processor
chip classes because of the new XIVE interrupt controller in Power9.
The base class also has pointers on the main controllers of the chip
which are common to all processors : PSI, LPC, OCC. These controllers
have some subtil differences in each processor version, but, globally,
they are very similar and provide the same feature. This is how we
have a console for instance.

>From there, we introduce two different machines : "powernv8" and
"powernv9" but, a part from the XICSFabric interface, this is not
strictly needed as it is the cpu type which determines the PnvChip
class. Something to discuss.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/pnv.h |  28 ++++-
 hw/ppc/pnv.c         | 322 +++++++++++++++++++++++++++++++++------------------
 hw/ppc/pnv_lpc.c     |   2 +-
 3 files changed, 236 insertions(+), 116 deletions(-)

diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index e934e84f555e..4942add9458a 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -57,12 +57,37 @@ typedef struct PnvChip {
     MemoryRegion xscom_mmio;
     MemoryRegion xscom;
     AddressSpace xscom_as;
+
+    /* Base class controllers */
+    PnvLpcController *lpc;
+    PnvPsi       *psi;
+    PnvOCC       *occ;
+} PnvChip;
+
+#define TYPE_PNV8_CHIP "pnv8-chip"
+#define PNV8_CHIP(obj) OBJECT_CHECK(Pnv8Chip, (obj), TYPE_PNV8_CHIP)
+
+typedef struct Pnv8Chip {
+    /*< private >*/
+    PnvChip      parent_obj;
+
+    /*< public >*/
     MemoryRegion icp_mmio;
 
     PnvLpcController lpc;
     PnvPsi       psi;
     PnvOCC       occ;
-} PnvChip;
+} Pnv8Chip;
+
+#define TYPE_PNV9_CHIP "pnv9-chip"
+#define PNV9_CHIP(obj) OBJECT_CHECK(Pnv9Chip, (obj), TYPE_PNV9_CHIP)
+
+typedef struct Pnv9Chip {
+    /*< private >*/
+    PnvChip      parent_obj;
+
+    /*< public >*/
+} Pnv9Chip;
 
 typedef struct PnvChipClass {
     /*< private >*/
@@ -75,6 +100,7 @@ typedef struct PnvChipClass {
 
     hwaddr       xscom_base;
 
+    void (*realize)(PnvChip *chip, Error **errp);
     uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id);
     Object *(*intc_create)(PnvChip *chip, Object *child, Error **errp);
 } PnvChipClass;
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 7d99366daf90..60b56c7fe07b 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -267,7 +267,7 @@ static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t pir,
 
 static int pnv_chip_lpc_offset(PnvChip *chip, void *fdt)
 {
-    return fdt_path_offset(fdt, chip->lpc.isa_bus_name);
+    return fdt_path_offset(fdt, chip->lpc->isa_bus_name);
 }
 
 static void pnv_dt_chip(PnvChip *chip, void *fdt)
@@ -516,7 +516,7 @@ static ISABus *pnv_isa_create(PnvChip *chip)
 {
     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
 
-    return pnv_lpc_isa_create(&chip->lpc, pcc->chip_type);
+    return pnv_lpc_isa_create(chip->lpc, pcc->chip_type);
 }
 
 static void pnv_init(MachineState *machine)
@@ -695,6 +695,106 @@ static Object *pnv_chip_power9_intc_create(PnvChip *chip, Object *child,
  */
 #define POWER9_CORE_MASK   (0xffffffffffffffull)
 
+static void pnv_chip_power8_initfn(Object *obj)
+{
+    Pnv8Chip *chip8 = PNV8_CHIP(obj);
+    PnvChip *chip = PNV_CHIP(obj);
+
+    object_initialize(&chip8->lpc, sizeof(chip8->lpc), TYPE_PNV_LPC);
+    object_property_add_child(obj, "lpc", OBJECT(&chip8->lpc), NULL);
+
+    object_initialize(&chip8->psi, sizeof(chip8->psi), TYPE_PNV_PSI);
+    object_property_add_child(obj, "psi", OBJECT(&chip8->psi), NULL);
+    object_property_add_const_link(OBJECT(&chip8->psi), "xics",
+                                   OBJECT(qdev_get_machine()), &error_abort);
+
+    object_initialize(&chip8->occ, sizeof(chip8->occ), TYPE_PNV_OCC);
+    object_property_add_child(obj, "occ", OBJECT(&chip8->occ), NULL);
+    object_property_add_const_link(OBJECT(&chip8->occ), "psi",
+                                   OBJECT(&chip8->psi), &error_abort);
+
+    /*
+     * The LPC controller needs a few things from the chip : to know
+     * if it's primary and PSI to generate interrupts
+     */
+    object_property_add_const_link(OBJECT(&chip8->lpc), "chip",
+                                   OBJECT(chip8), &error_abort);
+
+    /* Intialize the controllers in the base class also */
+    chip->lpc = &chip8->lpc;
+    chip->psi = &chip8->psi;
+    chip->occ = &chip8->occ;
+}
+
+static void pnv_chip_icp_realize(Pnv8Chip *chip8, Error **errp)
+ {
+    PnvChip *chip = PNV_CHIP(chip8);
+    PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
+    const char *typename = pnv_chip_core_typename(chip);
+    size_t typesize = object_type_get_instance_size(typename);
+    int i, j;
+    char *name;
+    XICSFabric *xi = XICS_FABRIC(qdev_get_machine());
+
+    name = g_strdup_printf("icp-%x", chip->chip_id);
+    memory_region_init(&chip8->icp_mmio, OBJECT(chip), name, PNV_ICP_SIZE);
+    sysbus_init_mmio(SYS_BUS_DEVICE(chip), &chip8->icp_mmio);
+    g_free(name);
+
+    sysbus_mmio_map(SYS_BUS_DEVICE(chip), 1, PNV_ICP_BASE(chip));
+
+    /* Map the ICP registers for each thread */
+    for (i = 0; i < chip->nr_cores; i++) {
+        PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
+        int core_hwid = CPU_CORE(pnv_core)->core_id;
+
+        for (j = 0; j < CPU_CORE(pnv_core)->nr_threads; j++) {
+            uint32_t pir = pcc->core_pir(chip, core_hwid) + j;
+            PnvICPState *icp = PNV_ICP(xics_icp_get(xi, pir));
+
+            memory_region_add_subregion(&chip8->icp_mmio, pir << 12,
+                                        &icp->mmio);
+        }
+    }
+}
+
+static void pnv_chip_power8_realize(PnvChip *chip, Error **errp)
+ {
+    Pnv8Chip *chip8 = PNV8_CHIP(chip);
+    Error *error = NULL;
+
+    /* Create LPC controller */
+    object_property_set_bool(OBJECT(&chip8->lpc), true, "realized",
+                             &error_fatal);
+    pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip8->lpc.xscom_regs);
+
+    /* Interrupt Management Area. This is the memory region holding
+     * all the Interrupt Control Presenter (ICP) registers */
+    pnv_chip_icp_realize(chip8, &error);
+    if (error) {
+        error_propagate(errp, error);
+        return;
+    }
+
+    /* Processor Service Interface (PSI) Host Bridge */
+    object_property_set_int(OBJECT(&chip8->psi), PNV_PSIHB_BASE(chip),
+                            "bar", &error_fatal);
+    object_property_set_bool(OBJECT(&chip8->psi), true, "realized", &error);
+    if (error) {
+        error_propagate(errp, error);
+        return;
+    }
+    pnv_xscom_add_subregion(chip, PNV_XSCOM_PSIHB_BASE, &chip8->psi.xscom_regs);
+
+    /* Create the simplified OCC model */
+    object_property_set_bool(OBJECT(&chip8->occ), true, "realized", &error);
+    if (error) {
+        error_propagate(errp, error);
+        return;
+    }
+    pnv_xscom_add_subregion(chip, PNV_XSCOM_OCC_BASE, &chip8->occ.xscom_regs);
+}
+
 static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -719,6 +819,7 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data)
     k->cores_mask = POWER8_CORE_MASK;
     k->core_pir = pnv_chip_core_pir_p8;
     k->intc_create = pnv_chip_power8_intc_create;
+    k->realize  = pnv_chip_power8_realize;
     k->xscom_base = 0x003fc0000000000ull;
     dc->desc = "PowerNV Chip POWER8";
 }
@@ -733,10 +834,20 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data)
     k->cores_mask = POWER8_CORE_MASK;
     k->core_pir = pnv_chip_core_pir_p8;
     k->intc_create = pnv_chip_power8_intc_create;
+    k->realize  = pnv_chip_power8_realize;
     k->xscom_base = 0x003fc0000000000ull;
     dc->desc = "PowerNV Chip POWER8NVL";
 }
 
+static void pnv_chip_power9_initfn(Object *obj)
+{
+}
+
+static void pnv_chip_power9_realize(PnvChip *chip, Error **errp)
+{
+
+}
+
 static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -747,6 +858,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
     k->cores_mask = POWER9_CORE_MASK;
     k->core_pir = pnv_chip_core_pir_p9;
     k->intc_create = pnv_chip_power9_intc_create;
+    k->realize  = pnv_chip_power9_realize;
     k->xscom_base = 0x00603fc00000000ull;
     dc->desc = "PowerNV Chip POWER9";
 }
@@ -781,62 +893,9 @@ static void pnv_chip_core_sanitize(PnvChip *chip, Error **errp)
     }
 }
 
-static void pnv_chip_init(Object *obj)
+static void pnv_chip_initfn(Object *obj)
 {
-    PnvChip *chip = PNV_CHIP(obj);
-    PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
-
-    chip->xscom_base = pcc->xscom_base;
-
-    object_initialize(&chip->lpc, sizeof(chip->lpc), TYPE_PNV_LPC);
-    object_property_add_child(obj, "lpc", OBJECT(&chip->lpc), NULL);
-
-    object_initialize(&chip->psi, sizeof(chip->psi), TYPE_PNV_PSI);
-    object_property_add_child(obj, "psi", OBJECT(&chip->psi), NULL);
-    object_property_add_const_link(OBJECT(&chip->psi), "xics",
-                                   OBJECT(qdev_get_machine()), &error_abort);
-
-    object_initialize(&chip->occ, sizeof(chip->occ), TYPE_PNV_OCC);
-    object_property_add_child(obj, "occ", OBJECT(&chip->occ), NULL);
-    object_property_add_const_link(OBJECT(&chip->occ), "psi",
-                                   OBJECT(&chip->psi), &error_abort);
-
-    /*
-     * The LPC controller needs a few things from the chip : to know
-     * if it's primary and PSI to generate interrupts
-     */
-    object_property_add_const_link(OBJECT(&chip->lpc), "chip",
-                                   OBJECT(chip), &error_abort);
-}
-
-static void pnv_chip_icp_realize(PnvChip *chip, Error **errp)
-{
-    PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
-    const char *typename = pnv_chip_core_typename(chip);
-    size_t typesize = object_type_get_instance_size(typename);
-    int i, j;
-    char *name;
-    XICSFabric *xi = XICS_FABRIC(qdev_get_machine());
-
-    name = g_strdup_printf("icp-%x", chip->chip_id);
-    memory_region_init(&chip->icp_mmio, OBJECT(chip), name, PNV_ICP_SIZE);
-    sysbus_init_mmio(SYS_BUS_DEVICE(chip), &chip->icp_mmio);
-    g_free(name);
-
-    sysbus_mmio_map(SYS_BUS_DEVICE(chip), 1, PNV_ICP_BASE(chip));
-
-    /* Map the ICP registers for each thread */
-    for (i = 0; i < chip->nr_cores; i++) {
-        PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
-        int core_hwid = CPU_CORE(pnv_core)->core_id;
-
-        for (j = 0; j < CPU_CORE(pnv_core)->nr_threads; j++) {
-            uint32_t pir = pcc->core_pir(chip, core_hwid) + j;
-            PnvICPState *icp = PNV_ICP(xics_icp_get(xi, pir));
-
-            memory_region_add_subregion(&chip->icp_mmio, pir << 12, &icp->mmio);
-        }
-    }
+    PNV_CHIP(obj)->xscom_base = PNV_CHIP_GET_CLASS(obj)->xscom_base;
 }
 
 static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
@@ -904,6 +963,7 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
 static void pnv_chip_realize(DeviceState *dev, Error **errp)
 {
     PnvChip *chip = PNV_CHIP(dev);
+    PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
     Error *error = NULL;
 
     /* XSCOM bridge */
@@ -921,36 +981,7 @@ static void pnv_chip_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-    /* Create LPC controller */
-    object_property_set_bool(OBJECT(&chip->lpc), true, "realized",
-                             &error_fatal);
-    pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip->lpc.xscom_regs);
-
-    /* Interrupt Management Area. This is the memory region holding
-     * all the Interrupt Control Presenter (ICP) registers */
-    pnv_chip_icp_realize(chip, &error);
-    if (error) {
-        error_propagate(errp, error);
-        return;
-    }
-
-    /* Processor Service Interface (PSI) Host Bridge */
-    object_property_set_int(OBJECT(&chip->psi), PNV_PSIHB_BASE(chip),
-                            "bar", &error_fatal);
-    object_property_set_bool(OBJECT(&chip->psi), true, "realized", &error);
-    if (error) {
-        error_propagate(errp, error);
-        return;
-    }
-    pnv_xscom_add_subregion(chip, PNV_XSCOM_PSIHB_BASE, &chip->psi.xscom_regs);
-
-    /* Create the simplified OCC model */
-    object_property_set_bool(OBJECT(&chip->occ), true, "realized", &error);
-    if (error) {
-        error_propagate(errp, error);
-        return;
-    }
-    pnv_xscom_add_subregion(chip, PNV_XSCOM_OCC_BASE, &chip->occ.xscom_regs);
+    pcc->realize(chip, errp);
 }
 
 static Property pnv_chip_properties[] = {
@@ -972,26 +1003,29 @@ static void pnv_chip_class_init(ObjectClass *klass, void *data)
     dc->desc = "PowerNV Chip";
 }
 
-static ICSState *pnv_ics_get(XICSFabric *xi, int irq)
+static ICSState *pnv8_ics_get(XICSFabric *xi, int irq)
 {
     PnvMachineState *pnv = PNV_MACHINE(xi);
     int i;
 
     for (i = 0; i < pnv->num_chips; i++) {
-        if (ics_valid_irq(&pnv->chips[i]->psi.ics, irq)) {
-            return &pnv->chips[i]->psi.ics;
+        Pnv8Chip *chip = PNV8_CHIP(pnv->chips[i]);
+
+        if (ics_valid_irq(&chip->psi.ics, irq)) {
+            return &chip->psi.ics;
         }
     }
     return NULL;
 }
 
-static void pnv_ics_resend(XICSFabric *xi)
+static void pnv8_ics_resend(XICSFabric *xi)
 {
     PnvMachineState *pnv = PNV_MACHINE(xi);
     int i;
 
     for (i = 0; i < pnv->num_chips; i++) {
-        ics_resend(&pnv->chips[i]->psi.ics);
+        Pnv8Chip *chip = PNV8_CHIP(pnv->chips[i]);
+        ics_resend(&chip->psi.ics);
     }
 }
 
@@ -1011,15 +1045,14 @@ static PowerPCCPU *ppc_get_vcpu_by_pir(int pir)
     return NULL;
 }
 
-static ICPState *pnv_icp_get(XICSFabric *xi, int pir)
+static ICPState *pnv8_icp_get(XICSFabric *xi, int pir)
 {
     PowerPCCPU *cpu = ppc_get_vcpu_by_pir(pir);
 
     return cpu ? ICP(cpu->intc) : NULL;
 }
 
-static void pnv_pic_print_info(InterruptStatsProvider *obj,
-                               Monitor *mon)
+static void pnv8_pic_print_info(InterruptStatsProvider *obj, Monitor *mon)
 {
     PnvMachineState *pnv = PNV_MACHINE(obj);
     int i;
@@ -1032,7 +1065,8 @@ static void pnv_pic_print_info(InterruptStatsProvider *obj,
     }
 
     for (i = 0; i < pnv->num_chips; i++) {
-        ics_pic_print_info(&pnv->chips[i]->psi.ics, mon);
+        Pnv8Chip *chip = PNV8_CHIP(pnv->chips[i]);
+        ics_pic_print_info(&chip->psi.ics, mon);
     }
 }
 
@@ -1086,8 +1120,6 @@ static void pnv_machine_class_props_init(ObjectClass *oc)
 static void pnv_machine_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
-    XICSFabricClass *xic = XICS_FABRIC_CLASS(oc);
-    InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc);
 
     mc->desc = "IBM PowerNV (Non-Virtualized)";
     mc->init = pnv_init;
@@ -1099,48 +1131,110 @@ static void pnv_machine_class_init(ObjectClass *oc, void *data)
     mc->no_parallel = 1;
     mc->default_boot_order = NULL;
     mc->default_ram_size = 1 * G_BYTE;
-    xic->icp_get = pnv_icp_get;
-    xic->ics_get = pnv_ics_get;
-    xic->ics_resend = pnv_ics_resend;
-    ispc->print_info = pnv_pic_print_info;
 
     pnv_machine_class_props_init(oc);
 }
 
-#define DEFINE_PNV_CHIP_TYPE(type, class_initfn) \
-    {                                            \
-        .name          = type,                   \
-        .class_init    = class_initfn,           \
-        .parent        = TYPE_PNV_CHIP,          \
+static void pnv8_machine_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    XICSFabricClass *xic = XICS_FABRIC_CLASS(oc);
+    InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc);
+
+    /* Power8 is the default */
+    mc->alias = "powernv";
+    mc->is_default = 1;
+
+    xic->icp_get = pnv8_icp_get;
+    xic->ics_get = pnv8_ics_get;
+    xic->ics_resend = pnv8_ics_resend;
+    ispc->print_info = pnv8_pic_print_info;
+}
+
+static void pnv9_machine_class_init(ObjectClass *oc, void *data)
+{
+}
+
+#define DEFINE_PNV8_CHIP_TYPE(type, class_initfn) \
+    {                                             \
+        .name          = type,                    \
+        .class_init    = class_initfn,            \
+        .parent        = TYPE_PNV8_CHIP,          \
+    }
+
+#define DEFINE_PNV9_CHIP_TYPE(type, class_initfn) \
+    {                                             \
+        .name          = type,                    \
+        .class_init    = class_initfn,            \
+        .parent        = TYPE_PNV9_CHIP,          \
     }
 
 static const TypeInfo types[] = {
+    /*
+     * PowerNV machines and variants
+     */
     {
         .name          = TYPE_PNV_MACHINE,
         .parent        = TYPE_MACHINE,
+        .abstract      = true,
         .instance_size = sizeof(PnvMachineState),
         .instance_init = pnv_machine_initfn,
         .class_init    = pnv_machine_class_init,
         .interfaces = (InterfaceInfo[]) {
-            { TYPE_XICS_FABRIC },
             { TYPE_INTERRUPT_STATS_PROVIDER },
             { },
         },
     },
     {
+        .name          = MACHINE_TYPE_NAME("powernv9"),
+        .parent        = TYPE_PNV_MACHINE,
+        .class_init    = pnv9_machine_class_init,
+    },
+    {
+        .name          = MACHINE_TYPE_NAME("powernv8"),
+        .parent        = TYPE_PNV_MACHINE,
+        .class_init    = pnv8_machine_class_init,
+        .interfaces    = (InterfaceInfo[]) {
+            { TYPE_XICS_FABRIC },
+            { },
+        },
+    },
+
+    /* Power Chip */
+    {
         .name          = TYPE_PNV_CHIP,
         .parent        = TYPE_SYS_BUS_DEVICE,
         .class_init    = pnv_chip_class_init,
-        .instance_init = pnv_chip_init,
+        .instance_init = pnv_chip_initfn,
         .instance_size = sizeof(PnvChip),
         .class_size    = sizeof(PnvChipClass),
         .abstract      = true,
     },
-    DEFINE_PNV_CHIP_TYPE(TYPE_PNV_CHIP_POWER9, pnv_chip_power9_class_init),
-    DEFINE_PNV_CHIP_TYPE(TYPE_PNV_CHIP_POWER8, pnv_chip_power8_class_init),
-    DEFINE_PNV_CHIP_TYPE(TYPE_PNV_CHIP_POWER8E, pnv_chip_power8e_class_init),
-    DEFINE_PNV_CHIP_TYPE(TYPE_PNV_CHIP_POWER8NVL,
-                         pnv_chip_power8nvl_class_init),
+
+    /*
+     * P9 chips and variants
+     */
+    {
+        .name          = TYPE_PNV9_CHIP,
+        .parent        = TYPE_PNV_CHIP,
+        .instance_init = pnv_chip_power9_initfn,
+        .instance_size = sizeof(Pnv9Chip),
+    },
+    DEFINE_PNV9_CHIP_TYPE(TYPE_PNV_CHIP_POWER9, pnv_chip_power9_class_init),
+
+    /*
+     * P8 chips and variants
+     */
+    {
+        .name          = TYPE_PNV8_CHIP,
+        .parent        = TYPE_PNV_CHIP,
+        .instance_init = pnv_chip_power8_initfn,
+        .instance_size = sizeof(Pnv8Chip),
+    },
+    DEFINE_PNV8_CHIP_TYPE(TYPE_PNV_CHIP_POWER8, pnv_chip_power8_class_init),
+    DEFINE_PNV8_CHIP_TYPE(TYPE_PNV_CHIP_POWER8E, pnv_chip_power8e_class_init),
+    DEFINE_PNV8_CHIP_TYPE(TYPE_PNV_CHIP_POWER8NVL,
+                          pnv_chip_power8nvl_class_init),
 };
 
 DEFINE_TYPES(types)
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index 7f13c4bcf52c..265d94c3240d 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -435,7 +435,7 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
         return;
     }
     chip = PNV_CHIP(obj);
-    lpc->psi = &chip->psi;
+    lpc->psi = chip->psi;
     lpc->primary = chip->chip_id == 0;
 
     /* Reg inits */
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 1/6] ppc/pnv: introduce a 'primary' field under the LPC model
  2018-06-14 14:00 ` [Qemu-devel] [PATCH 1/6] ppc/pnv: introduce a 'primary' field under the LPC model Cédric Le Goater
@ 2018-06-15  2:38   ` David Gibson
  2018-06-15 13:40     ` Cédric Le Goater
  0 siblings, 1 reply; 14+ messages in thread
From: David Gibson @ 2018-06-15  2:38 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 5323 bytes --]

On Thu, Jun 14, 2018 at 04:00:38PM +0200, Cédric Le Goater wrote:
> When a PowerNV system is started, the firmware (skiboot) looks for a
> "primary" property to determine which LPC bus is the default on a
> multichip system. This property is currently populated in the main
> routine creating the device tree of a chip, which is the not the right
> place to do so.
> 
> Check the chip id to flag the LPC controller as "primary", or not, and
> use that to add the property in the LPC device tree routine.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

This doesn't seem particularly useful to me.  Is there ever likely to
be a case where we want the primary LPC to be something other than the
one on chip 0?

If not, we seem to be just creating properties and states and a bunch
of stuff just to cache a (chip# == 0) test.

> ---
>  include/hw/ppc/pnv_lpc.h |  2 ++
>  hw/ppc/pnv.c             | 19 ++++++-------------
>  hw/ppc/pnv_lpc.c         | 29 ++++++++++++++++++++---------
>  3 files changed, 28 insertions(+), 22 deletions(-)
> 
> diff --git a/include/hw/ppc/pnv_lpc.h b/include/hw/ppc/pnv_lpc.h
> index 53fdd5bb6450..fddcb1c054b3 100644
> --- a/include/hw/ppc/pnv_lpc.h
> +++ b/include/hw/ppc/pnv_lpc.h
> @@ -68,6 +68,8 @@ typedef struct PnvLpcController {
>  
>      /* PSI to generate interrupts */
>      PnvPsi *psi;
> +
> +    bool   primary;
>  } PnvLpcController;
>  
>  qemu_irq *pnv_lpc_isa_irq_create(PnvLpcController *lpc, int chip_type,
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index 031488131629..b419d3323100 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -285,16 +285,6 @@ static void pnv_dt_chip(PnvChip *chip, void *fdt)
>  
>      pnv_dt_xscom(chip, fdt, 0);
>  
> -    /* The default LPC bus of a multichip system is on chip 0. It's
> -     * recognized by the firmware (skiboot) using a "primary"
> -     * property.
> -     */
> -    if (chip->chip_id == 0x0) {
> -        int lpc_offset = pnv_chip_lpc_offset(chip, fdt);
> -
> -        _FDT((fdt_setprop(fdt, lpc_offset, "primary", NULL, 0)));
> -    }
> -
>      for (i = 0; i < chip->nr_cores; i++) {
>          PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
>  
> @@ -814,9 +804,12 @@ static void pnv_chip_init(Object *obj)
>      object_property_add_const_link(OBJECT(&chip->occ), "psi",
>                                     OBJECT(&chip->psi), &error_abort);
>  
> -    /* The LPC controller needs PSI to generate interrupts */
> -    object_property_add_const_link(OBJECT(&chip->lpc), "psi",
> -                                   OBJECT(&chip->psi), &error_abort);
> +    /*
> +     * The LPC controller needs a few things from the chip : to know
> +     * if it's primary and PSI to generate interrupts
> +     */
> +    object_property_add_const_link(OBJECT(&chip->lpc), "chip",
> +                                   OBJECT(chip), &error_abort);
>  }
>  
>  static void pnv_chip_icp_realize(PnvChip *chip, Error **errp)
> diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
> index 402c4fefa886..1e70c8c19d52 100644
> --- a/hw/ppc/pnv_lpc.c
> +++ b/hw/ppc/pnv_lpc.c
> @@ -113,6 +113,14 @@ static int pnv_lpc_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
>      _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 2)));
>      _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 1)));
>      _FDT((fdt_setprop(fdt, offset, "compatible", compat, sizeof(compat))));
> +
> +    /*
> +     * The default LPC bus of a multichip system is on chip 0. It's
> +     * recognized by the firmware (skiboot) using a "primary" property.
> +     */
> +    if (PNV_LPC(dev)->primary) {
> +        _FDT((fdt_setprop(fdt, offset, "primary", NULL, 0)));
> +    }
>      return 0;
>  }
>  
> @@ -416,6 +424,18 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
>      PnvLpcController *lpc = PNV_LPC(dev);
>      Object *obj;
>      Error *error = NULL;
> +    PnvChip *chip;
> +
> +    /* get PSI object from chip */
> +    obj = object_property_get_link(OBJECT(dev), "chip", &error);
> +    if (!obj) {
> +        error_propagate(errp, error);
> +        error_prepend(errp, "required link 'chip' not found: ");
> +        return;
> +    }
> +    chip = PNV_CHIP(obj);
> +    lpc->psi = &chip->psi;
> +    lpc->primary = chip->chip_id == 0;
>  
>      /* Reg inits */
>      lpc->lpc_hc_fw_rd_acc_size = LPC_HC_FW_RD_4B;
> @@ -460,15 +480,6 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
>      pnv_xscom_region_init(&lpc->xscom_regs, OBJECT(dev),
>                            &pnv_lpc_xscom_ops, lpc, "xscom-lpc",
>                            PNV_XSCOM_LPC_SIZE);
> -
> -    /* get PSI object from chip */
> -    obj = object_property_get_link(OBJECT(dev), "psi", &error);
> -    if (!obj) {
> -        error_setg(errp, "%s: required link 'psi' not found: %s",
> -                   __func__, error_get_pretty(error));
> -        return;
> -    }
> -    lpc->psi = PNV_PSI(obj);
>  }
>  
>  static void pnv_lpc_class_init(ObjectClass *klass, void *data)

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 2/6] ppc/pnv: move the details of the ISA bus creation under the LPC model
  2018-06-14 14:00 ` [Qemu-devel] [PATCH 2/6] ppc/pnv: move the details of the ISA bus creation " Cédric Le Goater
@ 2018-06-15  2:41   ` David Gibson
  0 siblings, 0 replies; 14+ messages in thread
From: David Gibson @ 2018-06-15  2:41 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 4028 bytes --]

On Thu, Jun 14, 2018 at 04:00:39PM +0200, Cédric Le Goater wrote:
> This is a small cleanup to hide to the machine the gory details of the
> creation of the ISA bus. When time comes, the 'qemu_irq_handler' should
> become a LPC controller class attribute.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  include/hw/ppc/pnv_lpc.h |  3 +--
>  hw/ppc/pnv.c             | 15 +--------------
>  hw/ppc/pnv_lpc.c         | 24 ++++++++++++++++++++----
>  3 files changed, 22 insertions(+), 20 deletions(-)
> 
> diff --git a/include/hw/ppc/pnv_lpc.h b/include/hw/ppc/pnv_lpc.h
> index fddcb1c054b3..fb4b7b83d798 100644
> --- a/include/hw/ppc/pnv_lpc.h
> +++ b/include/hw/ppc/pnv_lpc.h
> @@ -72,7 +72,6 @@ typedef struct PnvLpcController {
>      bool   primary;
>  } PnvLpcController;
>  
> -qemu_irq *pnv_lpc_isa_irq_create(PnvLpcController *lpc, int chip_type,
> -                                 int nirqs);
> +ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, int chip_type);
>  
>  #endif /* _PPC_PNV_LPC_H */
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index b419d3323100..d2126ee4affc 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -521,22 +521,9 @@ static void pnv_reset(void)
>  
>  static ISABus *pnv_isa_create(PnvChip *chip)
>  {
> -    PnvLpcController *lpc = &chip->lpc;
> -    ISABus *isa_bus;
> -    qemu_irq *irqs;
>      PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
>  
> -    /* let isa_bus_new() create its own bridge on SysBus otherwise
> -     * devices speficied on the command line won't find the bus and
> -     * will fail to create.
> -     */
> -    isa_bus = isa_bus_new(NULL, &lpc->isa_mem, &lpc->isa_io,
> -                          &error_fatal);
> -
> -    irqs = pnv_lpc_isa_irq_create(lpc, pcc->chip_type, ISA_NUM_IRQS);
> -
> -    isa_bus_irqs(isa_bus, irqs);
> -    return isa_bus;
> +    return pnv_lpc_isa_create(&chip->lpc, pcc->chip_type);
>  }

This 1-line wrapper doesn't look useful.  Why not just call
pnv_lpc_isa_create() from this thing's caller?

>  
>  static void pnv_init(MachineState *machine)
> diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
> index 1e70c8c19d52..7c6c012d5176 100644
> --- a/hw/ppc/pnv_lpc.c
> +++ b/hw/ppc/pnv_lpc.c
> @@ -22,6 +22,7 @@
>  #include "target/ppc/cpu.h"
>  #include "qapi/error.h"
>  #include "qemu/log.h"
> +#include "hw/isa/isa.h"
>  
>  #include "hw/ppc/pnv.h"
>  #include "hw/ppc/pnv_lpc.h"
> @@ -546,16 +547,31 @@ static void pnv_lpc_isa_irq_handler(void *opaque, int n, int level)
>      }
>  }
>  
> -qemu_irq *pnv_lpc_isa_irq_create(PnvLpcController *lpc, int chip_type,
> -                                 int nirqs)
> +ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, int chip_type)
>  {
> +    ISABus *isa_bus;
> +    qemu_irq *irqs;
> +    qemu_irq_handler handler;
> +
> +    /* let isa_bus_new() create its own bridge on SysBus otherwise
> +     * devices speficied on the command line won't find the bus and
> +     * will fail to create.
> +     */
> +    isa_bus = isa_bus_new(NULL, &lpc->isa_mem, &lpc->isa_io,
> +                          &error_fatal);
> +
>      /* Not all variants have a working serial irq decoder. If not,
>       * handling of LPC interrupts becomes a platform issue (some
>       * platforms have a CPLD to do it).
>       */
>      if (chip_type == PNV_CHIP_POWER8NVL) {
> -        return qemu_allocate_irqs(pnv_lpc_isa_irq_handler, lpc, nirqs);
> +        handler = pnv_lpc_isa_irq_handler;
>      } else {
> -        return qemu_allocate_irqs(pnv_lpc_isa_irq_handler_cpld, lpc, nirqs);
> +        handler = pnv_lpc_isa_irq_handler_cpld;
>      }
> +
> +    irqs = qemu_allocate_irqs(handler, lpc, ISA_NUM_IRQS);
> +
> +    isa_bus_irqs(isa_bus, irqs);
> +    return isa_bus;
>  }

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 3/6] ppc/pnv: introduce an 'isa_bus_name' field under the LPC model
  2018-06-14 14:00 ` [Qemu-devel] [PATCH 3/6] ppc/pnv: introduce an 'isa_bus_name' field " Cédric Le Goater
@ 2018-06-15  2:47   ` David Gibson
  0 siblings, 0 replies; 14+ messages in thread
From: David Gibson @ 2018-06-15  2:47 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 2741 bytes --]

On Thu, Jun 14, 2018 at 04:00:40PM +0200, Cédric Le Goater wrote:
> This is again a small cleanup to hide to the machine the details of
> the ISA bus. The ISA bus device tree nodename will be different on
> Power9.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>



> ---
>  include/hw/ppc/pnv_lpc.h | 1 +
>  hw/ppc/pnv.c             | 9 +--------
>  hw/ppc/pnv_lpc.c         | 4 ++++
>  3 files changed, 6 insertions(+), 8 deletions(-)
> 
> diff --git a/include/hw/ppc/pnv_lpc.h b/include/hw/ppc/pnv_lpc.h
> index fb4b7b83d798..e8f7dcb9bfe9 100644
> --- a/include/hw/ppc/pnv_lpc.h
> +++ b/include/hw/ppc/pnv_lpc.h
> @@ -70,6 +70,7 @@ typedef struct PnvLpcController {
>      PnvPsi *psi;
>  
>      bool   primary;
> +    char   *isa_bus_name;

I'd suggest putting 'dt' somewhere in the field to make it more
obvious that this is about the bus's path in the device tree, rather
than say the bus's QOM path name.

>  } PnvLpcController;
>  
>  ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, int chip_type);
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index d2126ee4affc..72cfe4c2627c 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -267,14 +267,7 @@ static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t pir,
>  
>  static int pnv_chip_lpc_offset(PnvChip *chip, void *fdt)
>  {
> -    char *name;
> -    int offset;
> -
> -    name = g_strdup_printf("/xscom@%" PRIx64 "/isa@%x",
> -                           (uint64_t) PNV_XSCOM_BASE(chip), PNV_XSCOM_LPC_BASE);
> -    offset = fdt_path_offset(fdt, name);
> -    g_free(name);
> -    return offset;
> +    return fdt_path_offset(fdt, chip->lpc.isa_bus_name);
>  }

Having reduced this wrapper to 1 line, I'm not sure there is any
remaining point to it.

>  
>  static void pnv_dt_chip(PnvChip *chip, void *fdt)
> diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
> index 7c6c012d5176..7f13c4bcf52c 100644
> --- a/hw/ppc/pnv_lpc.c
> +++ b/hw/ppc/pnv_lpc.c
> @@ -481,6 +481,10 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
>      pnv_xscom_region_init(&lpc->xscom_regs, OBJECT(dev),
>                            &pnv_lpc_xscom_ops, lpc, "xscom-lpc",
>                            PNV_XSCOM_LPC_SIZE);
> +
> +    lpc->isa_bus_name = g_strdup_printf("/xscom@%" PRIx64 "/isa@%x",
> +                                        (uint64_t) PNV_XSCOM_BASE(chip),
> +                                        PNV_XSCOM_LPC_BASE);
>  }
>  
>  static void pnv_lpc_class_init(ObjectClass *klass, void *data)

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 4/6] ppc/pnv: introduce a pnv_chip_core_realize() routine
  2018-06-14 14:00 ` [Qemu-devel] [PATCH 4/6] ppc/pnv: introduce a pnv_chip_core_realize() routine Cédric Le Goater
@ 2018-06-15  2:52   ` David Gibson
  0 siblings, 0 replies; 14+ messages in thread
From: David Gibson @ 2018-06-15  2:52 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 2498 bytes --]

On Thu, Jun 14, 2018 at 04:00:41PM +0200, Cédric Le Goater wrote:
> This extracts from the PvChip realize routine the part creating the
> cores. On Power9, we will need to create the cores after the Xive
> interrupt controller is created.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Applied to ppc-for-3.0, thanks.

> ---
>  hw/ppc/pnv.c | 32 ++++++++++++++++++++++----------
>  1 file changed, 22 insertions(+), 10 deletions(-)
> 
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index 72cfe4c2627c..b3b0dd44582f 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -822,9 +822,8 @@ static void pnv_chip_icp_realize(PnvChip *chip, Error **errp)
>      }
>  }
>  
> -static void pnv_chip_realize(DeviceState *dev, Error **errp)
> +static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
>  {
> -    PnvChip *chip = PNV_CHIP(dev);
>      Error *error = NULL;
>      PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
>      const char *typename = pnv_chip_core_typename(chip);
> @@ -836,14 +835,6 @@ static void pnv_chip_realize(DeviceState *dev, Error **errp)
>          return;
>      }
>  
> -    /* XSCOM bridge */
> -    pnv_xscom_realize(chip, &error);
> -    if (error) {
> -        error_propagate(errp, error);
> -        return;
> -    }
> -    sysbus_mmio_map(SYS_BUS_DEVICE(chip), 0, PNV_XSCOM_BASE(chip));
> -
>      /* Cores */
>      pnv_chip_core_sanitize(chip, &error);
>      if (error) {
> @@ -891,6 +882,27 @@ static void pnv_chip_realize(DeviceState *dev, Error **errp)
>                                  &PNV_CORE(pnv_core)->xscom_regs);
>          i++;
>      }
> +}
> +
> +static void pnv_chip_realize(DeviceState *dev, Error **errp)
> +{
> +    PnvChip *chip = PNV_CHIP(dev);
> +    Error *error = NULL;
> +
> +    /* XSCOM bridge */
> +    pnv_xscom_realize(chip, &error);
> +    if (error) {
> +        error_propagate(errp, error);
> +        return;
> +    }
> +    sysbus_mmio_map(SYS_BUS_DEVICE(chip), 0, PNV_XSCOM_BASE(chip));
> +
> +    /* Cores */
> +    pnv_chip_core_realize(chip, &error);
> +    if (error) {
> +        error_propagate(errp, error);
> +        return;
> +    }
>  
>      /* Create LPC controller */
>      object_property_set_bool(OBJECT(&chip->lpc), true, "realized",

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 5/6] ppc/pnv: introduce a new intc_create() operation to the chip model
  2018-06-14 14:00 ` [Qemu-devel] [PATCH 5/6] ppc/pnv: introduce a new intc_create() operation to the chip model Cédric Le Goater
@ 2018-06-15  2:55   ` David Gibson
  0 siblings, 0 replies; 14+ messages in thread
From: David Gibson @ 2018-06-15  2:55 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 6814 bytes --]

On Thu, Jun 14, 2018 at 04:00:42PM +0200, Cédric Le Goater wrote:
> On Power9, the thread interrupt presenter has a different type and is
> linked to the chip owning the cores.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

(but not applied for now, since it depends on earlier patches I had
comments on)

> ---
>  include/hw/ppc/pnv.h |  1 +
>  hw/ppc/pnv.c         | 21 +++++++++++++++++++--
>  hw/ppc/pnv_core.c    | 18 +++++++++---------
>  3 files changed, 29 insertions(+), 11 deletions(-)
> 
> diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
> index 90759240a7b1..e934e84f555e 100644
> --- a/include/hw/ppc/pnv.h
> +++ b/include/hw/ppc/pnv.h
> @@ -76,6 +76,7 @@ typedef struct PnvChipClass {
>      hwaddr       xscom_base;
>  
>      uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id);
> +    Object *(*intc_create)(PnvChip *chip, Object *child, Error **errp);
>  } PnvChipClass;
>  
>  #define PNV_CHIP_TYPE_SUFFIX "-" TYPE_PNV_CHIP
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index b3b0dd44582f..7d99366daf90 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -641,6 +641,13 @@ static uint32_t pnv_chip_core_pir_p8(PnvChip *chip, uint32_t core_id)
>      return (chip->chip_id << 7) | (core_id << 3);
>  }
>  
> +static Object *pnv_chip_power8_intc_create(PnvChip *chip, Object *child,
> +                                           Error **errp)
> +{
> +    return icp_create(child, TYPE_PNV_ICP, XICS_FABRIC(qdev_get_machine()),
> +                      errp);
> +}
> +
>  /*
>   *    0:48  Reserved - Read as zeroes
>   *   49:52  Node ID
> @@ -656,6 +663,12 @@ static uint32_t pnv_chip_core_pir_p9(PnvChip *chip, uint32_t core_id)
>      return (chip->chip_id << 8) | (core_id << 2);
>  }
>  
> +static Object *pnv_chip_power9_intc_create(PnvChip *chip, Object *child,
> +                                           Error **errp)
> +{
> +    return NULL;
> +}
> +
>  /* Allowed core identifiers on a POWER8 Processor Chip :
>   *
>   * <EX0 reserved>
> @@ -691,6 +704,7 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
>      k->chip_cfam_id = 0x221ef04980000000ull;  /* P8 Murano DD2.1 */
>      k->cores_mask = POWER8E_CORE_MASK;
>      k->core_pir = pnv_chip_core_pir_p8;
> +    k->intc_create = pnv_chip_power8_intc_create;
>      k->xscom_base = 0x003fc0000000000ull;
>      dc->desc = "PowerNV Chip POWER8E";
>  }
> @@ -704,6 +718,7 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data)
>      k->chip_cfam_id = 0x220ea04980000000ull; /* P8 Venice DD2.0 */
>      k->cores_mask = POWER8_CORE_MASK;
>      k->core_pir = pnv_chip_core_pir_p8;
> +    k->intc_create = pnv_chip_power8_intc_create;
>      k->xscom_base = 0x003fc0000000000ull;
>      dc->desc = "PowerNV Chip POWER8";
>  }
> @@ -717,6 +732,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data)
>      k->chip_cfam_id = 0x120d304980000000ull;  /* P8 Naples DD1.0 */
>      k->cores_mask = POWER8_CORE_MASK;
>      k->core_pir = pnv_chip_core_pir_p8;
> +    k->intc_create = pnv_chip_power8_intc_create;
>      k->xscom_base = 0x003fc0000000000ull;
>      dc->desc = "PowerNV Chip POWER8NVL";
>  }
> @@ -730,6 +746,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
>      k->chip_cfam_id = 0x220d104900008000ull; /* P9 Nimbus DD2.0 */
>      k->cores_mask = POWER9_CORE_MASK;
>      k->core_pir = pnv_chip_core_pir_p9;
> +    k->intc_create = pnv_chip_power9_intc_create;
>      k->xscom_base = 0x00603fc00000000ull;
>      dc->desc = "PowerNV Chip POWER9";
>  }
> @@ -865,8 +882,8 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
>          object_property_set_int(OBJECT(pnv_core),
>                                  pcc->core_pir(chip, core_hwid),
>                                  "pir", &error_fatal);
> -        object_property_add_const_link(OBJECT(pnv_core), "xics",
> -                                       qdev_get_machine(), &error_fatal);
> +        object_property_add_const_link(OBJECT(pnv_core), "chip",
> +                                       OBJECT(chip), &error_fatal);
>          object_property_set_bool(OBJECT(pnv_core), true, "realized",
>                                   &error_fatal);
>          object_unref(OBJECT(pnv_core));
> diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
> index 13ad7d9e0470..5805bcd10abf 100644
> --- a/hw/ppc/pnv_core.c
> +++ b/hw/ppc/pnv_core.c
> @@ -121,11 +121,12 @@ static const MemoryRegionOps pnv_core_xscom_ops = {
>      .endianness = DEVICE_BIG_ENDIAN,
>  };
>  
> -static void pnv_core_realize_child(Object *child, XICSFabric *xi, Error **errp)
> +static void pnv_core_realize_child(Object *child, PnvChip *chip, Error **errp)
>  {
>      Error *local_err = NULL;
>      CPUState *cs = CPU(child);
>      PowerPCCPU *cpu = POWERPC_CPU(cs);
> +    PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
>  
>      object_property_set_bool(child, true, "realized", &local_err);
>      if (local_err) {
> @@ -133,7 +134,7 @@ static void pnv_core_realize_child(Object *child, XICSFabric *xi, Error **errp)
>          return;
>      }
>  
> -    cpu->intc = icp_create(child, TYPE_PNV_ICP, xi, &local_err);
> +    cpu->intc = pcc->intc_create(chip, child, &local_err);
>      if (local_err) {
>          error_propagate(errp, local_err);
>          return;
> @@ -156,13 +157,12 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
>      void *obj;
>      int i, j;
>      char name[32];
> -    Object *xi;
> +    Object *chip;
>  
> -    xi = object_property_get_link(OBJECT(dev), "xics", &local_err);
> -    if (!xi) {
> -        error_setg(errp, "%s: required link 'xics' not found: %s",
> -                   __func__, error_get_pretty(local_err));
> -        return;
> +    chip = object_property_get_link(OBJECT(dev), "chip", &local_err);
> +    if (!chip) {
> +        error_propagate(errp, local_err);
> +        error_prepend(errp, "required link 'chip' not found: ");
>      }
>  
>      pc->threads = g_malloc0(size * cc->nr_threads);
> @@ -184,7 +184,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
>      for (j = 0; j < cc->nr_threads; j++) {
>          obj = pc->threads + j * size;
>  
> -        pnv_core_realize_child(obj, XICS_FABRIC(xi), &local_err);
> +        pnv_core_realize_child(obj, PNV_CHIP(chip), &local_err);
>          if (local_err) {
>              goto err;
>          }

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 6/6] ppc/pnv: introduce Pnv8Chip and Pnv9Chip models
  2018-06-14 14:00 ` [Qemu-devel] [PATCH 6/6] ppc/pnv: introduce Pnv8Chip and Pnv9Chip models Cédric Le Goater
@ 2018-06-15  3:16   ` David Gibson
  0 siblings, 0 replies; 14+ messages in thread
From: David Gibson @ 2018-06-15  3:16 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 22217 bytes --]

On Thu, Jun 14, 2018 at 04:00:43PM +0200, Cédric Le Goater wrote:
> This is a major reshuffle of the PowerNV machine and chip models to
> introduce a machine type per processor. It is quite noisy but it
> doesn't change much the code flow.
> 
> It introduces a base PnvChip class from which the specific processor
> chip classes, Pnv8Chip and Pnv9Chip, inherit. Each of them needs to
> define an init and a realize routine which will create the controllers
> of the target processor.
> 
> For the moment, the base PnvChip class handles the XSCOM bus and the
> cores but the core creation will surely move to the specific processor
> chip classes because of the new XIVE interrupt controller in Power9.
> The base class also has pointers on the main controllers of the chip
> which are common to all processors : PSI, LPC, OCC. These controllers
> have some subtil differences in each processor version, but, globally,
> they are very similar and provide the same feature. This is how we
> have a console for instance.
> 
> >From there, we introduce two different machines : "powernv8" and
> "powernv9" but, a part from the XICSFabric interface, this is not
> strictly needed as it is the cpu type which determines the PnvChip
> class. Something to discuss.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  include/hw/ppc/pnv.h |  28 ++++-
>  hw/ppc/pnv.c         | 322 +++++++++++++++++++++++++++++++++------------------
>  hw/ppc/pnv_lpc.c     |   2 +-
>  3 files changed, 236 insertions(+), 116 deletions(-)
> 
> diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
> index e934e84f555e..4942add9458a 100644
> --- a/include/hw/ppc/pnv.h
> +++ b/include/hw/ppc/pnv.h
> @@ -57,12 +57,37 @@ typedef struct PnvChip {
>      MemoryRegion xscom_mmio;
>      MemoryRegion xscom;
>      AddressSpace xscom_as;
> +
> +    /* Base class controllers */
> +    PnvLpcController *lpc;
> +    PnvPsi       *psi;
> +    PnvOCC       *occ;

Having pointers here to full structures in the subclass seems
bizarrely pointless.

> +} PnvChip;
> +
> +#define TYPE_PNV8_CHIP "pnv8-chip"
> +#define PNV8_CHIP(obj) OBJECT_CHECK(Pnv8Chip, (obj), TYPE_PNV8_CHIP)
> +
> +typedef struct Pnv8Chip {
> +    /*< private >*/
> +    PnvChip      parent_obj;
> +
> +    /*< public >*/
>      MemoryRegion icp_mmio;
>  
>      PnvLpcController lpc;
>      PnvPsi       psi;
>      PnvOCC       occ;
> -} PnvChip;
> +} Pnv8Chip;
> +
> +#define TYPE_PNV9_CHIP "pnv9-chip"
> +#define PNV9_CHIP(obj) OBJECT_CHECK(Pnv9Chip, (obj), TYPE_PNV9_CHIP)
> +
> +typedef struct Pnv9Chip {
> +    /*< private >*/
> +    PnvChip      parent_obj;
> +
> +    /*< public >*/
> +} Pnv9Chip;
>  
>  typedef struct PnvChipClass {
>      /*< private >*/
> @@ -75,6 +100,7 @@ typedef struct PnvChipClass {
>  
>      hwaddr       xscom_base;
>  
> +    void (*realize)(PnvChip *chip, Error **errp);
>      uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id);
>      Object *(*intc_create)(PnvChip *chip, Object *child, Error **errp);
>  } PnvChipClass;
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index 7d99366daf90..60b56c7fe07b 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -267,7 +267,7 @@ static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t pir,
>  
>  static int pnv_chip_lpc_offset(PnvChip *chip, void *fdt)
>  {
> -    return fdt_path_offset(fdt, chip->lpc.isa_bus_name);
> +    return fdt_path_offset(fdt, chip->lpc->isa_bus_name);
>  }
>  
>  static void pnv_dt_chip(PnvChip *chip, void *fdt)
> @@ -516,7 +516,7 @@ static ISABus *pnv_isa_create(PnvChip *chip)
>  {
>      PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
>  
> -    return pnv_lpc_isa_create(&chip->lpc, pcc->chip_type);
> +    return pnv_lpc_isa_create(chip->lpc, pcc->chip_type);
>  }
>  
>  static void pnv_init(MachineState *machine)
> @@ -695,6 +695,106 @@ static Object *pnv_chip_power9_intc_create(PnvChip *chip, Object *child,
>   */
>  #define POWER9_CORE_MASK   (0xffffffffffffffull)
>  
> +static void pnv_chip_power8_initfn(Object *obj)

I'm trying to standardize on *_instance_init() for instance_init functions.

> +{
> +    Pnv8Chip *chip8 = PNV8_CHIP(obj);
> +    PnvChip *chip = PNV_CHIP(obj);
> +
> +    object_initialize(&chip8->lpc, sizeof(chip8->lpc), TYPE_PNV_LPC);
> +    object_property_add_child(obj, "lpc", OBJECT(&chip8->lpc), NULL);

Especially when you *also* have these child link properties which
would let you get to the sub-objects from the base ckass,

> +    object_initialize(&chip8->psi, sizeof(chip8->psi), TYPE_PNV_PSI);
> +    object_property_add_child(obj, "psi", OBJECT(&chip8->psi), NULL);
> +    object_property_add_const_link(OBJECT(&chip8->psi), "xics",
> +                                   OBJECT(qdev_get_machine()), &error_abort);
> +
> +    object_initialize(&chip8->occ, sizeof(chip8->occ), TYPE_PNV_OCC);
> +    object_property_add_child(obj, "occ", OBJECT(&chip8->occ), NULL);
> +    object_property_add_const_link(OBJECT(&chip8->occ), "psi",
> +                                   OBJECT(&chip8->psi), &error_abort);
> +
> +    /*
> +     * The LPC controller needs a few things from the chip : to know
> +     * if it's primary and PSI to generate interrupts
> +     */
> +    object_property_add_const_link(OBJECT(&chip8->lpc), "chip",
> +                                   OBJECT(chip8), &error_abort);
> +
> +    /* Intialize the controllers in the base class also */
> +    chip->lpc = &chip8->lpc;
> +    chip->psi = &chip8->psi;
> +    chip->occ = &chip8->occ;
> +}
> +
> +static void pnv_chip_icp_realize(Pnv8Chip *chip8, Error **errp)
> + {
> +    PnvChip *chip = PNV_CHIP(chip8);
> +    PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
> +    const char *typename = pnv_chip_core_typename(chip);
> +    size_t typesize = object_type_get_instance_size(typename);
> +    int i, j;
> +    char *name;
> +    XICSFabric *xi = XICS_FABRIC(qdev_get_machine());
> +
> +    name = g_strdup_printf("icp-%x", chip->chip_id);
> +    memory_region_init(&chip8->icp_mmio, OBJECT(chip), name, PNV_ICP_SIZE);
> +    sysbus_init_mmio(SYS_BUS_DEVICE(chip), &chip8->icp_mmio);
> +    g_free(name);
> +
> +    sysbus_mmio_map(SYS_BUS_DEVICE(chip), 1, PNV_ICP_BASE(chip));
> +
> +    /* Map the ICP registers for each thread */
> +    for (i = 0; i < chip->nr_cores; i++) {
> +        PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
> +        int core_hwid = CPU_CORE(pnv_core)->core_id;
> +
> +        for (j = 0; j < CPU_CORE(pnv_core)->nr_threads; j++) {
> +            uint32_t pir = pcc->core_pir(chip, core_hwid) + j;
> +            PnvICPState *icp = PNV_ICP(xics_icp_get(xi, pir));
> +
> +            memory_region_add_subregion(&chip8->icp_mmio, pir << 12,
> +                                        &icp->mmio);
> +        }
> +    }
> +}
> +
> +static void pnv_chip_power8_realize(PnvChip *chip, Error **errp)
> + {
> +    Pnv8Chip *chip8 = PNV8_CHIP(chip);
> +    Error *error = NULL;
> +
> +    /* Create LPC controller */
> +    object_property_set_bool(OBJECT(&chip8->lpc), true, "realized",
> +                             &error_fatal);
> +    pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip8->lpc.xscom_regs);
> +
> +    /* Interrupt Management Area. This is the memory region holding
> +     * all the Interrupt Control Presenter (ICP) registers */
> +    pnv_chip_icp_realize(chip8, &error);
> +    if (error) {
> +        error_propagate(errp, error);
> +        return;
> +    }
> +
> +    /* Processor Service Interface (PSI) Host Bridge */
> +    object_property_set_int(OBJECT(&chip8->psi), PNV_PSIHB_BASE(chip),
> +                            "bar", &error_fatal);
> +    object_property_set_bool(OBJECT(&chip8->psi), true, "realized", &error);
> +    if (error) {
> +        error_propagate(errp, error);
> +        return;
> +    }
> +    pnv_xscom_add_subregion(chip, PNV_XSCOM_PSIHB_BASE, &chip8->psi.xscom_regs);
> +
> +    /* Create the simplified OCC model */
> +    object_property_set_bool(OBJECT(&chip8->occ), true, "realized", &error);
> +    if (error) {
> +        error_propagate(errp, error);
> +        return;
> +    }
> +    pnv_xscom_add_subregion(chip, PNV_XSCOM_OCC_BASE, &chip8->occ.xscom_regs);
> +}
> +
>  static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -719,6 +819,7 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data)
>      k->cores_mask = POWER8_CORE_MASK;
>      k->core_pir = pnv_chip_core_pir_p8;
>      k->intc_create = pnv_chip_power8_intc_create;
> +    k->realize  = pnv_chip_power8_realize;
>      k->xscom_base = 0x003fc0000000000ull;
>      dc->desc = "PowerNV Chip POWER8";
>  }
> @@ -733,10 +834,20 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data)
>      k->cores_mask = POWER8_CORE_MASK;
>      k->core_pir = pnv_chip_core_pir_p8;
>      k->intc_create = pnv_chip_power8_intc_create;
> +    k->realize  = pnv_chip_power8_realize;
>      k->xscom_base = 0x003fc0000000000ull;
>      dc->desc = "PowerNV Chip POWER8NVL";
>  }
>  
> +static void pnv_chip_power9_initfn(Object *obj)
> +{
> +}
> +
> +static void pnv_chip_power9_realize(PnvChip *chip, Error **errp)
> +{
> +
> +}
> +
>  static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -747,6 +858,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
>      k->cores_mask = POWER9_CORE_MASK;
>      k->core_pir = pnv_chip_core_pir_p9;
>      k->intc_create = pnv_chip_power9_intc_create;
> +    k->realize  = pnv_chip_power9_realize;
>      k->xscom_base = 0x00603fc00000000ull;
>      dc->desc = "PowerNV Chip POWER9";
>  }
> @@ -781,62 +893,9 @@ static void pnv_chip_core_sanitize(PnvChip *chip, Error **errp)
>      }
>  }
>  
> -static void pnv_chip_init(Object *obj)
> +static void pnv_chip_initfn(Object *obj)
>  {
> -    PnvChip *chip = PNV_CHIP(obj);
> -    PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
> -
> -    chip->xscom_base = pcc->xscom_base;
> -
> -    object_initialize(&chip->lpc, sizeof(chip->lpc), TYPE_PNV_LPC);
> -    object_property_add_child(obj, "lpc", OBJECT(&chip->lpc), NULL);
> -
> -    object_initialize(&chip->psi, sizeof(chip->psi), TYPE_PNV_PSI);
> -    object_property_add_child(obj, "psi", OBJECT(&chip->psi), NULL);
> -    object_property_add_const_link(OBJECT(&chip->psi), "xics",
> -                                   OBJECT(qdev_get_machine()), &error_abort);
> -
> -    object_initialize(&chip->occ, sizeof(chip->occ), TYPE_PNV_OCC);
> -    object_property_add_child(obj, "occ", OBJECT(&chip->occ), NULL);
> -    object_property_add_const_link(OBJECT(&chip->occ), "psi",
> -                                   OBJECT(&chip->psi), &error_abort);
> -
> -    /*
> -     * The LPC controller needs a few things from the chip : to know
> -     * if it's primary and PSI to generate interrupts
> -     */
> -    object_property_add_const_link(OBJECT(&chip->lpc), "chip",
> -                                   OBJECT(chip), &error_abort);
> -}
> -
> -static void pnv_chip_icp_realize(PnvChip *chip, Error **errp)
> -{
> -    PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
> -    const char *typename = pnv_chip_core_typename(chip);
> -    size_t typesize = object_type_get_instance_size(typename);
> -    int i, j;
> -    char *name;
> -    XICSFabric *xi = XICS_FABRIC(qdev_get_machine());
> -
> -    name = g_strdup_printf("icp-%x", chip->chip_id);
> -    memory_region_init(&chip->icp_mmio, OBJECT(chip), name, PNV_ICP_SIZE);
> -    sysbus_init_mmio(SYS_BUS_DEVICE(chip), &chip->icp_mmio);
> -    g_free(name);
> -
> -    sysbus_mmio_map(SYS_BUS_DEVICE(chip), 1, PNV_ICP_BASE(chip));
> -
> -    /* Map the ICP registers for each thread */
> -    for (i = 0; i < chip->nr_cores; i++) {
> -        PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
> -        int core_hwid = CPU_CORE(pnv_core)->core_id;
> -
> -        for (j = 0; j < CPU_CORE(pnv_core)->nr_threads; j++) {
> -            uint32_t pir = pcc->core_pir(chip, core_hwid) + j;
> -            PnvICPState *icp = PNV_ICP(xics_icp_get(xi, pir));
> -
> -            memory_region_add_subregion(&chip->icp_mmio, pir << 12, &icp->mmio);
> -        }
> -    }
> +    PNV_CHIP(obj)->xscom_base = PNV_CHIP_GET_CLASS(obj)->xscom_base;
>  }
>  
>  static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
> @@ -904,6 +963,7 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
>  static void pnv_chip_realize(DeviceState *dev, Error **errp)
>  {
>      PnvChip *chip = PNV_CHIP(dev);
> +    PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
>      Error *error = NULL;
>  
>      /* XSCOM bridge */
> @@ -921,36 +981,7 @@ static void pnv_chip_realize(DeviceState *dev, Error **errp)
>          return;
>      }
>  
> -    /* Create LPC controller */
> -    object_property_set_bool(OBJECT(&chip->lpc), true, "realized",
> -                             &error_fatal);
> -    pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip->lpc.xscom_regs);
> -
> -    /* Interrupt Management Area. This is the memory region holding
> -     * all the Interrupt Control Presenter (ICP) registers */
> -    pnv_chip_icp_realize(chip, &error);
> -    if (error) {
> -        error_propagate(errp, error);
> -        return;
> -    }
> -
> -    /* Processor Service Interface (PSI) Host Bridge */
> -    object_property_set_int(OBJECT(&chip->psi), PNV_PSIHB_BASE(chip),
> -                            "bar", &error_fatal);
> -    object_property_set_bool(OBJECT(&chip->psi), true, "realized", &error);
> -    if (error) {
> -        error_propagate(errp, error);
> -        return;
> -    }
> -    pnv_xscom_add_subregion(chip, PNV_XSCOM_PSIHB_BASE, &chip->psi.xscom_regs);
> -
> -    /* Create the simplified OCC model */
> -    object_property_set_bool(OBJECT(&chip->occ), true, "realized", &error);
> -    if (error) {
> -        error_propagate(errp, error);
> -        return;
> -    }
> -    pnv_xscom_add_subregion(chip, PNV_XSCOM_OCC_BASE, &chip->occ.xscom_regs);
> +    pcc->realize(chip, errp);
>  }
>  
>  static Property pnv_chip_properties[] = {
> @@ -972,26 +1003,29 @@ static void pnv_chip_class_init(ObjectClass *klass, void *data)
>      dc->desc = "PowerNV Chip";
>  }
>  
> -static ICSState *pnv_ics_get(XICSFabric *xi, int irq)
> +static ICSState *pnv8_ics_get(XICSFabric *xi, int irq)
>  {
>      PnvMachineState *pnv = PNV_MACHINE(xi);
>      int i;
>  
>      for (i = 0; i < pnv->num_chips; i++) {
> -        if (ics_valid_irq(&pnv->chips[i]->psi.ics, irq)) {
> -            return &pnv->chips[i]->psi.ics;
> +        Pnv8Chip *chip = PNV8_CHIP(pnv->chips[i]);
> +
> +        if (ics_valid_irq(&chip->psi.ics, irq)) {
> +            return &chip->psi.ics;
>          }
>      }
>      return NULL;
>  }
>  
> -static void pnv_ics_resend(XICSFabric *xi)
> +static void pnv8_ics_resend(XICSFabric *xi)
>  {
>      PnvMachineState *pnv = PNV_MACHINE(xi);
>      int i;
>  
>      for (i = 0; i < pnv->num_chips; i++) {
> -        ics_resend(&pnv->chips[i]->psi.ics);
> +        Pnv8Chip *chip = PNV8_CHIP(pnv->chips[i]);
> +        ics_resend(&chip->psi.ics);
>      }
>  }
>  
> @@ -1011,15 +1045,14 @@ static PowerPCCPU *ppc_get_vcpu_by_pir(int pir)
>      return NULL;
>  }
>  
> -static ICPState *pnv_icp_get(XICSFabric *xi, int pir)
> +static ICPState *pnv8_icp_get(XICSFabric *xi, int pir)
>  {
>      PowerPCCPU *cpu = ppc_get_vcpu_by_pir(pir);
>  
>      return cpu ? ICP(cpu->intc) : NULL;
>  }
>  
> -static void pnv_pic_print_info(InterruptStatsProvider *obj,
> -                               Monitor *mon)
> +static void pnv8_pic_print_info(InterruptStatsProvider *obj, Monitor *mon)
>  {
>      PnvMachineState *pnv = PNV_MACHINE(obj);
>      int i;
> @@ -1032,7 +1065,8 @@ static void pnv_pic_print_info(InterruptStatsProvider *obj,
>      }
>  
>      for (i = 0; i < pnv->num_chips; i++) {
> -        ics_pic_print_info(&pnv->chips[i]->psi.ics, mon);
> +        Pnv8Chip *chip = PNV8_CHIP(pnv->chips[i]);
> +        ics_pic_print_info(&chip->psi.ics, mon);
>      }
>  }
>  
> @@ -1086,8 +1120,6 @@ static void pnv_machine_class_props_init(ObjectClass *oc)
>  static void pnv_machine_class_init(ObjectClass *oc, void *data)
>  {
>      MachineClass *mc = MACHINE_CLASS(oc);
> -    XICSFabricClass *xic = XICS_FABRIC_CLASS(oc);
> -    InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc);
>  
>      mc->desc = "IBM PowerNV (Non-Virtualized)";
>      mc->init = pnv_init;
> @@ -1099,48 +1131,110 @@ static void pnv_machine_class_init(ObjectClass *oc, void *data)
>      mc->no_parallel = 1;
>      mc->default_boot_order = NULL;
>      mc->default_ram_size = 1 * G_BYTE;
> -    xic->icp_get = pnv_icp_get;
> -    xic->ics_get = pnv_ics_get;
> -    xic->ics_resend = pnv_ics_resend;
> -    ispc->print_info = pnv_pic_print_info;
>  
>      pnv_machine_class_props_init(oc);
>  }
>  
> -#define DEFINE_PNV_CHIP_TYPE(type, class_initfn) \
> -    {                                            \
> -        .name          = type,                   \
> -        .class_init    = class_initfn,           \
> -        .parent        = TYPE_PNV_CHIP,          \
> +static void pnv8_machine_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    XICSFabricClass *xic = XICS_FABRIC_CLASS(oc);
> +    InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc);
> +
> +    /* Power8 is the default */
> +    mc->alias = "powernv";
> +    mc->is_default = 1;
> +
> +    xic->icp_get = pnv8_icp_get;
> +    xic->ics_get = pnv8_ics_get;
> +    xic->ics_resend = pnv8_ics_resend;
> +    ispc->print_info = pnv8_pic_print_info;
> +}
> +
> +static void pnv9_machine_class_init(ObjectClass *oc, void *data)
> +{
> +}
> +
> +#define DEFINE_PNV8_CHIP_TYPE(type, class_initfn) \
> +    {                                             \
> +        .name          = type,                    \
> +        .class_init    = class_initfn,            \
> +        .parent        = TYPE_PNV8_CHIP,          \
> +    }
> +
> +#define DEFINE_PNV9_CHIP_TYPE(type, class_initfn) \
> +    {                                             \
> +        .name          = type,                    \
> +        .class_init    = class_initfn,            \
> +        .parent        = TYPE_PNV9_CHIP,          \
>      }
>  
>  static const TypeInfo types[] = {
> +    /*
> +     * PowerNV machines and variants
> +     */
>      {
>          .name          = TYPE_PNV_MACHINE,
>          .parent        = TYPE_MACHINE,
> +        .abstract      = true,
>          .instance_size = sizeof(PnvMachineState),
>          .instance_init = pnv_machine_initfn,
>          .class_init    = pnv_machine_class_init,
>          .interfaces = (InterfaceInfo[]) {
> -            { TYPE_XICS_FABRIC },
>              { TYPE_INTERRUPT_STATS_PROVIDER },
>              { },
>          },
>      },
>      {
> +        .name          = MACHINE_TYPE_NAME("powernv9"),
> +        .parent        = TYPE_PNV_MACHINE,
> +        .class_init    = pnv9_machine_class_init,
> +    },
> +    {
> +        .name          = MACHINE_TYPE_NAME("powernv8"),
> +        .parent        = TYPE_PNV_MACHINE,
> +        .class_init    = pnv8_machine_class_init,
> +        .interfaces    = (InterfaceInfo[]) {
> +            { TYPE_XICS_FABRIC },
> +            { },
> +        },
> +    },
> +
> +    /* Power Chip */
> +    {
>          .name          = TYPE_PNV_CHIP,
>          .parent        = TYPE_SYS_BUS_DEVICE,
>          .class_init    = pnv_chip_class_init,
> -        .instance_init = pnv_chip_init,
> +        .instance_init = pnv_chip_initfn,
>          .instance_size = sizeof(PnvChip),
>          .class_size    = sizeof(PnvChipClass),
>          .abstract      = true,
>      },
> -    DEFINE_PNV_CHIP_TYPE(TYPE_PNV_CHIP_POWER9, pnv_chip_power9_class_init),
> -    DEFINE_PNV_CHIP_TYPE(TYPE_PNV_CHIP_POWER8, pnv_chip_power8_class_init),
> -    DEFINE_PNV_CHIP_TYPE(TYPE_PNV_CHIP_POWER8E, pnv_chip_power8e_class_init),
> -    DEFINE_PNV_CHIP_TYPE(TYPE_PNV_CHIP_POWER8NVL,
> -                         pnv_chip_power8nvl_class_init),
> +
> +    /*
> +     * P9 chips and variants
> +     */
> +    {
> +        .name          = TYPE_PNV9_CHIP,
> +        .parent        = TYPE_PNV_CHIP,
> +        .instance_init = pnv_chip_power9_initfn,
> +        .instance_size = sizeof(Pnv9Chip),
> +    },
> +    DEFINE_PNV9_CHIP_TYPE(TYPE_PNV_CHIP_POWER9, pnv_chip_power9_class_init),
> +
> +    /*
> +     * P8 chips and variants
> +     */
> +    {
> +        .name          = TYPE_PNV8_CHIP,
> +        .parent        = TYPE_PNV_CHIP,
> +        .instance_init = pnv_chip_power8_initfn,
> +        .instance_size = sizeof(Pnv8Chip),
> +    },
> +    DEFINE_PNV8_CHIP_TYPE(TYPE_PNV_CHIP_POWER8, pnv_chip_power8_class_init),
> +    DEFINE_PNV8_CHIP_TYPE(TYPE_PNV_CHIP_POWER8E, pnv_chip_power8e_class_init),
> +    DEFINE_PNV8_CHIP_TYPE(TYPE_PNV_CHIP_POWER8NVL,
> +                          pnv_chip_power8nvl_class_init),
>  };
>  
>  DEFINE_TYPES(types)
> diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
> index 7f13c4bcf52c..265d94c3240d 100644
> --- a/hw/ppc/pnv_lpc.c
> +++ b/hw/ppc/pnv_lpc.c
> @@ -435,7 +435,7 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
>          return;
>      }
>      chip = PNV_CHIP(obj);
> -    lpc->psi = &chip->psi;
> +    lpc->psi = chip->psi;
>      lpc->primary = chip->chip_id == 0;
>  
>      /* Reg inits */

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 1/6] ppc/pnv: introduce a 'primary' field under the LPC model
  2018-06-15  2:38   ` David Gibson
@ 2018-06-15 13:40     ` Cédric Le Goater
  0 siblings, 0 replies; 14+ messages in thread
From: Cédric Le Goater @ 2018-06-15 13:40 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel

On 06/15/2018 04:38 AM, David Gibson wrote:
> On Thu, Jun 14, 2018 at 04:00:38PM +0200, Cédric Le Goater wrote:
>> When a PowerNV system is started, the firmware (skiboot) looks for a
>> "primary" property to determine which LPC bus is the default on a
>> multichip system. This property is currently populated in the main
>> routine creating the device tree of a chip, which is the not the right
>> place to do so.
>>
>> Check the chip id to flag the LPC controller as "primary", or not, and
>> use that to add the property in the LPC device tree routine.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> 
> This doesn't seem particularly useful to me.  Is there ever likely to
> be a case where we want the primary LPC to be something other than the
> one on chip 0?
> 
> If not, we seem to be just creating properties and states and a bunch
> of stuff just to cache a (chip# == 0) test.

knowing that the LPC controller is on chip0 is important, that's how
we build the ISA bus of the machine and I am trying to untangle this
relation : 

	pnv->isa_bus <-> pnv->chip->lpc->regions 

The chip is in the middle and it is problematic to introduce an 
abstract PnvChip class. 

Still working on it.

Thanks,

C. 


>> ---
>>  include/hw/ppc/pnv_lpc.h |  2 ++
>>  hw/ppc/pnv.c             | 19 ++++++-------------
>>  hw/ppc/pnv_lpc.c         | 29 ++++++++++++++++++++---------
>>  3 files changed, 28 insertions(+), 22 deletions(-)
>>
>> diff --git a/include/hw/ppc/pnv_lpc.h b/include/hw/ppc/pnv_lpc.h
>> index 53fdd5bb6450..fddcb1c054b3 100644
>> --- a/include/hw/ppc/pnv_lpc.h
>> +++ b/include/hw/ppc/pnv_lpc.h
>> @@ -68,6 +68,8 @@ typedef struct PnvLpcController {
>>  
>>      /* PSI to generate interrupts */
>>      PnvPsi *psi;
>> +
>> +    bool   primary;
>>  } PnvLpcController;
>>  
>>  qemu_irq *pnv_lpc_isa_irq_create(PnvLpcController *lpc, int chip_type,
>> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
>> index 031488131629..b419d3323100 100644
>> --- a/hw/ppc/pnv.c
>> +++ b/hw/ppc/pnv.c
>> @@ -285,16 +285,6 @@ static void pnv_dt_chip(PnvChip *chip, void *fdt)
>>  
>>      pnv_dt_xscom(chip, fdt, 0);
>>  
>> -    /* The default LPC bus of a multichip system is on chip 0. It's
>> -     * recognized by the firmware (skiboot) using a "primary"
>> -     * property.
>> -     */
>> -    if (chip->chip_id == 0x0) {
>> -        int lpc_offset = pnv_chip_lpc_offset(chip, fdt);
>> -
>> -        _FDT((fdt_setprop(fdt, lpc_offset, "primary", NULL, 0)));
>> -    }
>> -
>>      for (i = 0; i < chip->nr_cores; i++) {
>>          PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
>>  
>> @@ -814,9 +804,12 @@ static void pnv_chip_init(Object *obj)
>>      object_property_add_const_link(OBJECT(&chip->occ), "psi",
>>                                     OBJECT(&chip->psi), &error_abort);
>>  
>> -    /* The LPC controller needs PSI to generate interrupts */
>> -    object_property_add_const_link(OBJECT(&chip->lpc), "psi",
>> -                                   OBJECT(&chip->psi), &error_abort);
>> +    /*
>> +     * The LPC controller needs a few things from the chip : to know
>> +     * if it's primary and PSI to generate interrupts
>> +     */
>> +    object_property_add_const_link(OBJECT(&chip->lpc), "chip",
>> +                                   OBJECT(chip), &error_abort);
>>  }
>>  
>>  static void pnv_chip_icp_realize(PnvChip *chip, Error **errp)
>> diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
>> index 402c4fefa886..1e70c8c19d52 100644
>> --- a/hw/ppc/pnv_lpc.c
>> +++ b/hw/ppc/pnv_lpc.c
>> @@ -113,6 +113,14 @@ static int pnv_lpc_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
>>      _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 2)));
>>      _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 1)));
>>      _FDT((fdt_setprop(fdt, offset, "compatible", compat, sizeof(compat))));
>> +
>> +    /*
>> +     * The default LPC bus of a multichip system is on chip 0. It's
>> +     * recognized by the firmware (skiboot) using a "primary" property.
>> +     */
>> +    if (PNV_LPC(dev)->primary) {
>> +        _FDT((fdt_setprop(fdt, offset, "primary", NULL, 0)));
>> +    }
>>      return 0;
>>  }
>>  
>> @@ -416,6 +424,18 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
>>      PnvLpcController *lpc = PNV_LPC(dev);
>>      Object *obj;
>>      Error *error = NULL;
>> +    PnvChip *chip;
>> +
>> +    /* get PSI object from chip */
>> +    obj = object_property_get_link(OBJECT(dev), "chip", &error);
>> +    if (!obj) {
>> +        error_propagate(errp, error);
>> +        error_prepend(errp, "required link 'chip' not found: ");
>> +        return;
>> +    }
>> +    chip = PNV_CHIP(obj);
>> +    lpc->psi = &chip->psi;
>> +    lpc->primary = chip->chip_id == 0;
>>  
>>      /* Reg inits */
>>      lpc->lpc_hc_fw_rd_acc_size = LPC_HC_FW_RD_4B;
>> @@ -460,15 +480,6 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
>>      pnv_xscom_region_init(&lpc->xscom_regs, OBJECT(dev),
>>                            &pnv_lpc_xscom_ops, lpc, "xscom-lpc",
>>                            PNV_XSCOM_LPC_SIZE);
>> -
>> -    /* get PSI object from chip */
>> -    obj = object_property_get_link(OBJECT(dev), "psi", &error);
>> -    if (!obj) {
>> -        error_setg(errp, "%s: required link 'psi' not found: %s",
>> -                   __func__, error_get_pretty(error));
>> -        return;
>> -    }
>> -    lpc->psi = PNV_PSI(obj);
>>  }
>>  
>>  static void pnv_lpc_class_init(ObjectClass *klass, void *data)
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2018-06-15 13:40 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-14 14:00 [Qemu-devel] [PATCH 0/6] ppc/pnv: new Pnv8Chip and Pnv9Chip models Cédric Le Goater
2018-06-14 14:00 ` [Qemu-devel] [PATCH 1/6] ppc/pnv: introduce a 'primary' field under the LPC model Cédric Le Goater
2018-06-15  2:38   ` David Gibson
2018-06-15 13:40     ` Cédric Le Goater
2018-06-14 14:00 ` [Qemu-devel] [PATCH 2/6] ppc/pnv: move the details of the ISA bus creation " Cédric Le Goater
2018-06-15  2:41   ` David Gibson
2018-06-14 14:00 ` [Qemu-devel] [PATCH 3/6] ppc/pnv: introduce an 'isa_bus_name' field " Cédric Le Goater
2018-06-15  2:47   ` David Gibson
2018-06-14 14:00 ` [Qemu-devel] [PATCH 4/6] ppc/pnv: introduce a pnv_chip_core_realize() routine Cédric Le Goater
2018-06-15  2:52   ` David Gibson
2018-06-14 14:00 ` [Qemu-devel] [PATCH 5/6] ppc/pnv: introduce a new intc_create() operation to the chip model Cédric Le Goater
2018-06-15  2:55   ` David Gibson
2018-06-14 14:00 ` [Qemu-devel] [PATCH 6/6] ppc/pnv: introduce Pnv8Chip and Pnv9Chip models Cédric Le Goater
2018-06-15  3:16   ` David Gibson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.