All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 00/15] ppc: add POWER9 support to the PowerNV platform
@ 2019-03-07 22:35 Cédric Le Goater
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 01/15] ppc/pnv: add a PSI bridge class model Cédric Le Goater
                   ` (14 more replies)
  0 siblings, 15 replies; 33+ messages in thread
From: Cédric Le Goater @ 2019-03-07 22:35 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

Hello,

Here is the second round of the patchset adding support for the POWER9
processor to the PowerNV machine. It includes POWER9 models for the
PSI host bridge, the LPC controller, and a minimalist OCC, some
extensions of the CPU core model to support POWER9 XSCOM addresses and
a new PnvQuad model controlling the power management state of group of
four cores on a POWER9 processor.

It should bring the POWER9 PowerNV platform to the same level as
POWER8, that is without PHBs.

A new skiboot image is not provided yet because I would like first to
have a tagged version of skiboot including the recent changes removing
support for DD1. Will come later.

Hopefully, this is good enough for QEMU 4.0.

Thanks,

C.

Changes in v2 :

 - introduced Pnv8Psi (XICS) and Pnv9Psi (XIVE) models
 - wrote a commit log for the changes in the LPC register ranges
 - added a 'dt_isa_nodename' to the chip
 - added new attributes to define XSCOM operations per CPU family and 
   a PSI IRQ number in the OCC class model
 - added a new attribute to define XSCOM operations per CPU family
   in the CPU core class model

Changes in v1 (since PnvXive was last sent) :

 - fixed compilation on clang (forward declarations)
 
 - simplified the hardwiring of the Physical CAM line. removed the
   'hw-cam' property. 
 - removed 'hwaddr offset' from the get_tctx() XiveRouter handler. It
   was a misunderstanding of the PC_THREAD_EN_REGx registers.
 - changed the CPU machine_data presenter type to 'Object *' to accept
   XiveTCTX
 - introduced a new dt_populate() operation to the chip model
 - introduced a new pic_print_info() operation to the chip model
 - removed 'chip_id' from PnvXive.
 - removed 'nr_irqs' and 'nr_ends' from PnvXive. Values are now
   calculated from the VST settings done by FW.   
 - removed 'type' field from the XiveVstInfo struct describing the VSTs
 - simplified pnv_xive_get_ic() grabbing a remote IC
 - introduced a pnv_xive_vst_size() helper computing the size of a VST
   table, direct or indirect. Used to computed the number of virtual
   structures entries provisioned by FW.
 - reworked pnv_xive_vst_addr_*() helpers. Fixed a bug when multiple
   pages are in use.
 - took into account the word_number when doing stores of the virtual
   structures.
 - the IPI and the END sub memory regions of the VC BAR are now
   resized and mapped when the EDT is configured, depending on how the
   VC region was segmented.
 - the XiveSource and the XiveENDSource memory regions are now resized
   and mapped when the VST are configured, depending on how much
   virtual structures entries were provisioned by FW.
 - removed PC_GCONF_CHIPID_OVR handling. Was for debug according to HW
   designers. xive->chip->chip_id is now used as the block id when
   needed.
 - reworked pic_print_info() to use the number of virtual structures
   entries provisioned by FW.

What has not changed (since PnvXive was sent) :

 - GETFIELD/SETFIELD macros. It would break the compatibility with
   skiboot in the register definitions. Still needs some thinking to
   find a common ground. P10 material for QEMU and skiboot probably.
 - The HW interface of XIVE is still bound to the register array. P10
   support will determine which is the best approach.

Cédric Le Goater (15):
  ppc/pnv: add a PSI bridge class model
  ppc/pnv: add a PSI bridge model for POWER9
  ppc/pnv: lpc: fix OPB address ranges
  ppc/pnv: add a LPC Controller class model
  ppc/pnv: add a 'dt_isa_nodename' to the chip
  ppc/pnv: add a LPC Controller model for POWER9
  ppc/pnv: add SerIRQ routing registers
  ppc/pnv: add a OCC model class
  ppc/pnv: add a OCC model for POWER9
  ppc/pnv: extend XSCOM core support for POWER9
  ppc/pnv: POWER9 XSCOM quad support
  ppc/pnv: activate XSCOM tests for POWER9
  ppc/pnv: add more dummy XSCOM addresses
  ppc/pnv: add a "ibm,opal/power-mgt" device tree node on POWER9
  target/ppc: add HV support for POWER9

 include/hw/ppc/pnv.h            |  19 +-
 include/hw/ppc/pnv_core.h       |  12 +
 include/hw/ppc/pnv_lpc.h        |  26 ++
 include/hw/ppc/pnv_occ.h        |  17 ++
 include/hw/ppc/pnv_psi.h        |  59 ++++-
 include/hw/ppc/pnv_xscom.h      |  18 +-
 hw/ppc/pnv.c                    | 134 +++++++++--
 hw/ppc/pnv_core.c               | 187 ++++++++++++++-
 hw/ppc/pnv_lpc.c                | 306 +++++++++++++++++++++---
 hw/ppc/pnv_occ.c                | 127 ++++++++--
 hw/ppc/pnv_psi.c                | 404 ++++++++++++++++++++++++++++++--
 hw/ppc/pnv_xscom.c              |  33 ++-
 target/ppc/translate_init.inc.c |   3 +-
 tests/pnv-xscom-test.c          |   2 -
 14 files changed, 1231 insertions(+), 116 deletions(-)

-- 
2.20.1

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

* [Qemu-devel] [PATCH v2 01/15] ppc/pnv: add a PSI bridge class model
  2019-03-07 22:35 [Qemu-devel] [PATCH v2 00/15] ppc: add POWER9 support to the PowerNV platform Cédric Le Goater
@ 2019-03-07 22:35 ` Cédric Le Goater
  2019-03-07 23:57   ` David Gibson
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 02/15] ppc/pnv: add a PSI bridge model for POWER9 Cédric Le Goater
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Cédric Le Goater @ 2019-03-07 22:35 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

To ease the introduction of the PSI bridge model for POWER9, abstract
the POWER chip differences in a PnvPsi class model and introduce a
specific Pnv8Psi type for POWER8. POWER8 interface to the interrupt
controller is still XICS whereas POWER9 uses the new XIVE model.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---

 Changes in v2 :

 - introduced a Pnv8Psi (XICS) model

 include/hw/ppc/pnv.h     |  2 +-
 include/hw/ppc/pnv_psi.h | 29 ++++++++++++++-
 hw/ppc/pnv.c             |  6 ++-
 hw/ppc/pnv_psi.c         | 79 ++++++++++++++++++++++++++++------------
 4 files changed, 87 insertions(+), 29 deletions(-)

diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index eb4bba25b3e9..3b5f9cd53184 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -71,7 +71,7 @@ typedef struct Pnv8Chip {
     MemoryRegion icp_mmio;
 
     PnvLpcController lpc;
-    PnvPsi       psi;
+    Pnv8Psi      psi;
     PnvOCC       occ;
 } Pnv8Chip;
 
diff --git a/include/hw/ppc/pnv_psi.h b/include/hw/ppc/pnv_psi.h
index 64ac73512e81..7087cbcb9ad7 100644
--- a/include/hw/ppc/pnv_psi.h
+++ b/include/hw/ppc/pnv_psi.h
@@ -39,7 +39,6 @@ typedef struct PnvPsi {
     uint64_t fsp_bar;
 
     /* Interrupt generation */
-    ICSState ics;
     qemu_irq *qirqs;
 
     /* Registers */
@@ -48,6 +47,32 @@ typedef struct PnvPsi {
     MemoryRegion xscom_regs;
 } PnvPsi;
 
+#define TYPE_PNV8_PSI TYPE_PNV_PSI "-POWER8"
+#define PNV8_PSI(obj) \
+    OBJECT_CHECK(Pnv8Psi, (obj), TYPE_PNV8_PSI)
+
+typedef struct Pnv8Psi {
+    PnvPsi   parent;
+
+    ICSState ics;
+} Pnv8Psi;
+
+#define PNV_PSI_CLASS(klass) \
+     OBJECT_CLASS_CHECK(PnvPsiClass, (klass), TYPE_PNV_PSI)
+#define PNV_PSI_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(PnvPsiClass, (obj), TYPE_PNV_PSI)
+
+typedef struct PnvPsiClass {
+    SysBusDeviceClass parent_class;
+
+    int chip_type;
+    uint32_t xscom_pcba;
+    uint32_t xscom_size;
+    uint64_t bar_mask;
+
+    void (*irq_set)(PnvPsi *psi, int, bool state);
+} PnvPsiClass;
+
 /* The PSI and FSP interrupts are muxed on the same IRQ number */
 typedef enum PnvPsiIrq {
     PSIHB_IRQ_PSI, /* internal use only */
@@ -61,6 +86,6 @@ typedef enum PnvPsiIrq {
 
 #define PSI_NUM_INTERRUPTS 6
 
-extern void pnv_psi_irq_set(PnvPsi *psi, PnvPsiIrq irq, bool state);
+void pnv_psi_irq_set(PnvPsi *psi, int irq, bool state);
 
 #endif /* _PPC_PNV_PSI_H */
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 7660eaa22cf9..5bb2332f167a 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -788,7 +788,7 @@ static void pnv_chip_power8_instance_init(Object *obj)
     Pnv8Chip *chip8 = PNV8_CHIP(obj);
 
     object_initialize_child(obj, "psi",  &chip8->psi, sizeof(chip8->psi),
-                            TYPE_PNV_PSI, &error_abort, NULL);
+                            TYPE_PNV8_PSI, &error_abort, NULL);
     object_property_add_const_link(OBJECT(&chip8->psi), "xics",
                                    OBJECT(qdev_get_machine()), &error_abort);
 
@@ -840,6 +840,7 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
     PnvChip *chip = PNV_CHIP(dev);
     Pnv8Chip *chip8 = PNV8_CHIP(dev);
+    Pnv8Psi *psi8 = &chip8->psi;
     Error *local_err = NULL;
 
     pcc->parent_realize(dev, &local_err);
@@ -856,7 +857,8 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
         error_propagate(errp, local_err);
         return;
     }
-    pnv_xscom_add_subregion(chip, PNV_XSCOM_PSIHB_BASE, &chip8->psi.xscom_regs);
+    pnv_xscom_add_subregion(chip, PNV_XSCOM_PSIHB_BASE,
+                            &PNV_PSI(psi8)->xscom_regs);
 
     /* Create LPC controller */
     object_property_set_bool(OBJECT(&chip8->lpc), true, "realized",
diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
index e61861bfd3c6..067f733f1e4a 100644
--- a/hw/ppc/pnv_psi.c
+++ b/hw/ppc/pnv_psi.c
@@ -118,10 +118,11 @@
 
 static void pnv_psi_set_bar(PnvPsi *psi, uint64_t bar)
 {
+    PnvPsiClass *ppc = PNV_PSI_GET_CLASS(psi);
     MemoryRegion *sysmem = get_system_memory();
     uint64_t old = psi->regs[PSIHB_XSCOM_BAR];
 
-    psi->regs[PSIHB_XSCOM_BAR] = bar & (PSIHB_BAR_MASK | PSIHB_BAR_EN);
+    psi->regs[PSIHB_XSCOM_BAR] = bar & (ppc->bar_mask | PSIHB_BAR_EN);
 
     /* Update MR, always remove it first */
     if (old & PSIHB_BAR_EN) {
@@ -130,7 +131,7 @@ static void pnv_psi_set_bar(PnvPsi *psi, uint64_t bar)
 
     /* Then add it back if needed */
     if (bar & PSIHB_BAR_EN) {
-        uint64_t addr = bar & PSIHB_BAR_MASK;
+        uint64_t addr = bar & ppc->bar_mask;
         memory_region_add_subregion(sysmem, addr, &psi->regs_mr);
     }
 }
@@ -154,7 +155,7 @@ static void pnv_psi_set_cr(PnvPsi *psi, uint64_t cr)
 
 static void pnv_psi_set_irsn(PnvPsi *psi, uint64_t val)
 {
-    ICSState *ics = &psi->ics;
+    ICSState *ics = &PNV8_PSI(psi)->ics;
 
     /* In this model we ignore the up/down enable bits for now
      * as SW doesn't use them (other than setting them at boot).
@@ -207,7 +208,12 @@ static const uint64_t stat_bits[] = {
     [PSIHB_IRQ_EXTERNAL]  = PSIHB_IRQ_STAT_EXT,
 };
 
-void pnv_psi_irq_set(PnvPsi *psi, PnvPsiIrq irq, bool state)
+void pnv_psi_irq_set(PnvPsi *psi, int irq, bool state)
+{
+    PNV_PSI_GET_CLASS(psi)->irq_set(psi, irq, state);
+}
+
+static void pnv_psi_power8_irq_set(PnvPsi *psi, int irq, bool state)
 {
     uint32_t xivr_reg;
     uint32_t stat_reg;
@@ -262,7 +268,7 @@ void pnv_psi_irq_set(PnvPsi *psi, PnvPsiIrq irq, bool state)
 
 static void pnv_psi_set_xivr(PnvPsi *psi, uint32_t reg, uint64_t val)
 {
-    ICSState *ics = &psi->ics;
+    ICSState *ics = &PNV8_PSI(psi)->ics;
     uint16_t server;
     uint8_t prio;
     uint8_t src;
@@ -451,11 +457,11 @@ static void pnv_psi_reset(void *dev)
     psi->regs[PSIHB_XSCOM_BAR] = psi->bar | PSIHB_BAR_EN;
 }
 
-static void pnv_psi_init(Object *obj)
+static void pnv_psi_power8_instance_init(Object *obj)
 {
-    PnvPsi *psi = PNV_PSI(obj);
+    Pnv8Psi *psi8 = PNV8_PSI(obj);
 
-    object_initialize_child(obj, "ics-psi",  &psi->ics, sizeof(psi->ics),
+    object_initialize_child(obj, "ics-psi",  &psi8->ics, sizeof(psi8->ics),
                             TYPE_ICS_SIMPLE, &error_abort, NULL);
 }
 
@@ -468,10 +474,10 @@ static const uint8_t irq_to_xivr[] = {
     PSIHB_XSCOM_XIVR_EXT,
 };
 
-static void pnv_psi_realize(DeviceState *dev, Error **errp)
+static void pnv_psi_power8_realize(DeviceState *dev, Error **errp)
 {
     PnvPsi *psi = PNV_PSI(dev);
-    ICSState *ics = &psi->ics;
+    ICSState *ics = &PNV8_PSI(psi)->ics;
     Object *obj;
     Error *err = NULL;
     unsigned int i;
@@ -524,28 +530,28 @@ static void pnv_psi_realize(DeviceState *dev, Error **errp)
     qemu_register_reset(pnv_psi_reset, dev);
 }
 
+static const char compat_p8[] = "ibm,power8-psihb-x\0ibm,psihb-x";
+
 static int pnv_psi_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
 {
-    const char compat[] = "ibm,power8-psihb-x\0ibm,psihb-x";
+    PnvPsiClass *ppc = PNV_PSI_GET_CLASS(dev);
     char *name;
     int offset;
-    uint32_t lpc_pcba = PNV_XSCOM_PSIHB_BASE;
     uint32_t reg[] = {
-        cpu_to_be32(lpc_pcba),
-        cpu_to_be32(PNV_XSCOM_PSIHB_SIZE)
+        cpu_to_be32(ppc->xscom_pcba),
+        cpu_to_be32(ppc->xscom_size)
     };
 
-    name = g_strdup_printf("psihb@%x", lpc_pcba);
+    name = g_strdup_printf("psihb@%x", ppc->xscom_pcba);
     offset = fdt_add_subnode(fdt, xscom_offset, name);
     _FDT(offset);
     g_free(name);
 
-    _FDT((fdt_setprop(fdt, offset, "reg", reg, sizeof(reg))));
-
-    _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 2)));
-    _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 1)));
-    _FDT((fdt_setprop(fdt, offset, "compatible", compat,
-                      sizeof(compat))));
+    _FDT(fdt_setprop(fdt, offset, "reg", reg, sizeof(reg)));
+    _FDT(fdt_setprop_cell(fdt, offset, "#address-cells", 2));
+    _FDT(fdt_setprop_cell(fdt, offset, "#size-cells", 1));
+    _FDT(fdt_setprop(fdt, offset, "compatible", compat_p8,
+                     sizeof(compat_p8)));
     return 0;
 }
 
@@ -555,6 +561,29 @@ static Property pnv_psi_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
+static void pnv_psi_power8_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PnvPsiClass *ppc = PNV_PSI_CLASS(klass);
+
+    dc->desc    = "PowerNV PSI Controller POWER8";
+    dc->realize = pnv_psi_power8_realize;
+
+    ppc->chip_type =  PNV_CHIP_POWER8;
+    ppc->xscom_pcba = PNV_XSCOM_PSIHB_BASE;
+    ppc->xscom_size = PNV_XSCOM_PSIHB_SIZE;
+    ppc->bar_mask   = PSIHB_BAR_MASK;
+    ppc->irq_set    = pnv_psi_power8_irq_set;
+}
+
+static const TypeInfo pnv_psi_power8_info = {
+    .name          = TYPE_PNV8_PSI,
+    .parent        = TYPE_PNV_PSI,
+    .instance_size = sizeof(Pnv8Psi),
+    .instance_init = pnv_psi_power8_instance_init,
+    .class_init    = pnv_psi_power8_class_init,
+};
+
 static void pnv_psi_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -562,7 +591,7 @@ static void pnv_psi_class_init(ObjectClass *klass, void *data)
 
     xdc->dt_xscom = pnv_psi_dt_xscom;
 
-    dc->realize = pnv_psi_realize;
+    dc->desc = "PowerNV PSI Controller";
     dc->props = pnv_psi_properties;
 }
 
@@ -570,8 +599,9 @@ static const TypeInfo pnv_psi_info = {
     .name          = TYPE_PNV_PSI,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(PnvPsi),
-    .instance_init = pnv_psi_init,
     .class_init    = pnv_psi_class_init,
+    .class_size    = sizeof(PnvPsiClass),
+    .abstract      = true,
     .interfaces    = (InterfaceInfo[]) {
         { TYPE_PNV_XSCOM_INTERFACE },
         { }
@@ -581,6 +611,7 @@ static const TypeInfo pnv_psi_info = {
 static void pnv_psi_register_types(void)
 {
     type_register_static(&pnv_psi_info);
+    type_register_static(&pnv_psi_power8_info);
 }
 
-type_init(pnv_psi_register_types)
+type_init(pnv_psi_register_types);
-- 
2.20.1

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

* [Qemu-devel] [PATCH v2 02/15] ppc/pnv: add a PSI bridge model for POWER9
  2019-03-07 22:35 [Qemu-devel] [PATCH v2 00/15] ppc: add POWER9 support to the PowerNV platform Cédric Le Goater
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 01/15] ppc/pnv: add a PSI bridge class model Cédric Le Goater
@ 2019-03-07 22:35 ` Cédric Le Goater
  2019-03-07 23:58   ` David Gibson
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 03/15] ppc/pnv: lpc: fix OPB address ranges Cédric Le Goater
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Cédric Le Goater @ 2019-03-07 22:35 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

The PSI bridge on POWER9 is very similar to POWER8. The BAR is still
set through XSCOM but the controls are now entirely done with MMIOs.
More interrupts are defined and the interrupt controller interface has
changed to XIVE. The POWER9 model is a first example of the usage of
the notify() handler of the XiveNotifier interface, linking the PSI
XiveSource to its owning device model.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---

 Changes in v2 :
 
  - introduced a Pnv9Psi (XIVE) model
  
 include/hw/ppc/pnv.h       |   6 +
 include/hw/ppc/pnv_psi.h   |  30 ++++
 include/hw/ppc/pnv_xscom.h |   3 +
 hw/ppc/pnv.c               |  18 ++
 hw/ppc/pnv_psi.c           | 329 ++++++++++++++++++++++++++++++++++++-
 5 files changed, 384 insertions(+), 2 deletions(-)

diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 3b5f9cd53184..8d80cb34eebb 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -84,6 +84,7 @@ typedef struct Pnv9Chip {
 
     /*< public >*/
     PnvXive      xive;
+    Pnv9Psi      psi;
 } Pnv9Chip;
 
 typedef struct PnvChipClass {
@@ -231,11 +232,16 @@ void pnv_bmc_powerdown(IPMIBmc *bmc);
 #define PNV9_XIVE_PC_SIZE            0x0000001000000000ull
 #define PNV9_XIVE_PC_BASE(chip)      PNV9_CHIP_BASE(chip, 0x0006018000000000ull)
 
+#define PNV9_PSIHB_SIZE              0x0000000000100000ull
+#define PNV9_PSIHB_BASE(chip)        PNV9_CHIP_BASE(chip, 0x0006030203000000ull)
+
 #define PNV9_XIVE_IC_SIZE            0x0000000000080000ull
 #define PNV9_XIVE_IC_BASE(chip)      PNV9_CHIP_BASE(chip, 0x0006030203100000ull)
 
 #define PNV9_XIVE_TM_SIZE            0x0000000000040000ull
 #define PNV9_XIVE_TM_BASE(chip)      PNV9_CHIP_BASE(chip, 0x0006030203180000ull)
 
+#define PNV9_PSIHB_ESB_SIZE          0x0000000000010000ull
+#define PNV9_PSIHB_ESB_BASE(chip)    PNV9_CHIP_BASE(chip, 0x00060302031c0000ull)
 
 #endif /* _PPC_PNV_H */
diff --git a/include/hw/ppc/pnv_psi.h b/include/hw/ppc/pnv_psi.h
index 7087cbcb9ad7..2c1b27e865bd 100644
--- a/include/hw/ppc/pnv_psi.h
+++ b/include/hw/ppc/pnv_psi.h
@@ -21,6 +21,7 @@
 
 #include "hw/sysbus.h"
 #include "hw/ppc/xics.h"
+#include "hw/ppc/xive.h"
 
 #define TYPE_PNV_PSI "pnv-psi"
 #define PNV_PSI(obj) \
@@ -57,6 +58,16 @@ typedef struct Pnv8Psi {
     ICSState ics;
 } Pnv8Psi;
 
+#define TYPE_PNV9_PSI TYPE_PNV_PSI "-POWER9"
+#define PNV9_PSI(obj) \
+    OBJECT_CHECK(Pnv9Psi, (obj), TYPE_PNV9_PSI)
+
+typedef struct Pnv9Psi {
+    PnvPsi   parent;
+
+    XiveSource source;
+} Pnv9Psi;
+
 #define PNV_PSI_CLASS(klass) \
      OBJECT_CLASS_CHECK(PnvPsiClass, (klass), TYPE_PNV_PSI)
 #define PNV_PSI_GET_CLASS(obj) \
@@ -88,4 +99,23 @@ typedef enum PnvPsiIrq {
 
 void pnv_psi_irq_set(PnvPsi *psi, int irq, bool state);
 
+/* P9 PSI Interrupts */
+#define PSIHB9_IRQ_PSI          0
+#define PSIHB9_IRQ_OCC          1
+#define PSIHB9_IRQ_FSI          2
+#define PSIHB9_IRQ_LPCHC        3
+#define PSIHB9_IRQ_LOCAL_ERR    4
+#define PSIHB9_IRQ_GLOBAL_ERR   5
+#define PSIHB9_IRQ_TPM          6
+#define PSIHB9_IRQ_LPC_SIRQ0    7
+#define PSIHB9_IRQ_LPC_SIRQ1    8
+#define PSIHB9_IRQ_LPC_SIRQ2    9
+#define PSIHB9_IRQ_LPC_SIRQ3    10
+#define PSIHB9_IRQ_SBE_I2C      11
+#define PSIHB9_IRQ_DIO          12
+#define PSIHB9_IRQ_PSU          13
+#define PSIHB9_NUM_IRQS         14
+
+void pnv_psi_pic_print_info(Pnv9Psi *psi, Monitor *mon);
+
 #endif /* _PPC_PNV_PSI_H */
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index 6623ec54a7a8..403a365ed274 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -73,6 +73,9 @@ typedef struct PnvXScomInterfaceClass {
 #define PNV_XSCOM_OCC_BASE        0x0066000
 #define PNV_XSCOM_OCC_SIZE        0x6000
 
+#define PNV9_XSCOM_PSIHB_BASE     0x5012900
+#define PNV9_XSCOM_PSIHB_SIZE     0x100
+
 #define PNV9_XSCOM_XIVE_BASE      0x5013000
 #define PNV9_XSCOM_XIVE_SIZE      0x300
 
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 5bb2332f167a..1cc454cbbc27 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -579,6 +579,7 @@ static void pnv_chip_power9_pic_print_info(PnvChip *chip, Monitor *mon)
     Pnv9Chip *chip9 = PNV9_CHIP(chip);
 
     pnv_xive_pic_print_info(&chip9->xive, mon);
+    pnv_psi_pic_print_info(&chip9->psi, mon);
 }
 
 static void pnv_init(MachineState *machine)
@@ -950,6 +951,11 @@ static void pnv_chip_power9_instance_init(Object *obj)
                             TYPE_PNV_XIVE, &error_abort, NULL);
     object_property_add_const_link(OBJECT(&chip9->xive), "chip", obj,
                                    &error_abort);
+
+    object_initialize_child(obj, "psi",  &chip9->psi, sizeof(chip9->psi),
+                            TYPE_PNV9_PSI, &error_abort, NULL);
+    object_property_add_const_link(OBJECT(&chip9->psi), "chip", obj,
+                                   &error_abort);
 }
 
 static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
@@ -957,6 +963,7 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
     Pnv9Chip *chip9 = PNV9_CHIP(dev);
     PnvChip *chip = PNV_CHIP(dev);
+    Pnv9Psi *psi9 = &chip9->psi;
     Error *local_err = NULL;
 
     pcc->parent_realize(dev, &local_err);
@@ -982,6 +989,17 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
     }
     pnv_xscom_add_subregion(chip, PNV9_XSCOM_XIVE_BASE,
                             &chip9->xive.xscom_regs);
+
+    /* Processor Service Interface (PSI) Host Bridge */
+    object_property_set_int(OBJECT(&chip9->psi), PNV9_PSIHB_BASE(chip),
+                            "bar", &error_fatal);
+    object_property_set_bool(OBJECT(&chip9->psi), true, "realized", &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    pnv_xscom_add_subregion(chip, PNV9_XSCOM_PSIHB_BASE,
+                            &PNV_PSI(psi9)->xscom_regs);
 }
 
 static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
index 067f733f1e4a..5a923e41518d 100644
--- a/hw/ppc/pnv_psi.c
+++ b/hw/ppc/pnv_psi.c
@@ -22,6 +22,7 @@
 #include "target/ppc/cpu.h"
 #include "qemu/log.h"
 #include "qapi/error.h"
+#include "monitor/monitor.h"
 
 #include "exec/address-spaces.h"
 
@@ -114,6 +115,9 @@
 #define PSIHB_BAR_MASK                  0x0003fffffff00000ull
 #define PSIHB_FSPBAR_MASK               0x0003ffff00000000ull
 
+#define PSIHB9_BAR_MASK                 0x00fffffffff00000ull
+#define PSIHB9_FSPBAR_MASK              0x00ffffff00000000ull
+
 #define PSIHB_REG(addr) (((addr) >> 3) + PSIHB_XSCOM_BAR)
 
 static void pnv_psi_set_bar(PnvPsi *psi, uint64_t bar)
@@ -531,6 +535,7 @@ static void pnv_psi_power8_realize(DeviceState *dev, Error **errp)
 }
 
 static const char compat_p8[] = "ibm,power8-psihb-x\0ibm,psihb-x";
+static const char compat_p9[] = "ibm,power9-psihb-x\0ibm,psihb-x";
 
 static int pnv_psi_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
 {
@@ -550,8 +555,13 @@ static int pnv_psi_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
     _FDT(fdt_setprop(fdt, offset, "reg", reg, sizeof(reg)));
     _FDT(fdt_setprop_cell(fdt, offset, "#address-cells", 2));
     _FDT(fdt_setprop_cell(fdt, offset, "#size-cells", 1));
-    _FDT(fdt_setprop(fdt, offset, "compatible", compat_p8,
-                     sizeof(compat_p8)));
+    if (ppc->chip_type == PNV_CHIP_POWER9) {
+        _FDT(fdt_setprop(fdt, offset, "compatible", compat_p9,
+                         sizeof(compat_p9)));
+    } else {
+        _FDT(fdt_setprop(fdt, offset, "compatible", compat_p8,
+                         sizeof(compat_p8)));
+    }
     return 0;
 }
 
@@ -584,6 +594,308 @@ static const TypeInfo pnv_psi_power8_info = {
     .class_init    = pnv_psi_power8_class_init,
 };
 
+
+/* Common registers */
+
+#define PSIHB9_CR                       0x20
+#define PSIHB9_SEMR                     0x28
+
+/* P9 registers */
+
+#define PSIHB9_INTERRUPT_CONTROL        0x58
+#define   PSIHB9_IRQ_METHOD             PPC_BIT(0)
+#define   PSIHB9_IRQ_RESET              PPC_BIT(1)
+#define PSIHB9_ESB_CI_BASE              0x60
+#define   PSIHB9_ESB_CI_VALID           1
+#define PSIHB9_ESB_NOTIF_ADDR           0x68
+#define   PSIHB9_ESB_NOTIF_VALID        1
+#define PSIHB9_IVT_OFFSET               0x70
+#define   PSIHB9_IVT_OFF_SHIFT          32
+
+#define PSIHB9_IRQ_LEVEL                0x78 /* assertion */
+#define   PSIHB9_IRQ_LEVEL_PSI          PPC_BIT(0)
+#define   PSIHB9_IRQ_LEVEL_OCC          PPC_BIT(1)
+#define   PSIHB9_IRQ_LEVEL_FSI          PPC_BIT(2)
+#define   PSIHB9_IRQ_LEVEL_LPCHC        PPC_BIT(3)
+#define   PSIHB9_IRQ_LEVEL_LOCAL_ERR    PPC_BIT(4)
+#define   PSIHB9_IRQ_LEVEL_GLOBAL_ERR   PPC_BIT(5)
+#define   PSIHB9_IRQ_LEVEL_TPM          PPC_BIT(6)
+#define   PSIHB9_IRQ_LEVEL_LPC_SIRQ1    PPC_BIT(7)
+#define   PSIHB9_IRQ_LEVEL_LPC_SIRQ2    PPC_BIT(8)
+#define   PSIHB9_IRQ_LEVEL_LPC_SIRQ3    PPC_BIT(9)
+#define   PSIHB9_IRQ_LEVEL_LPC_SIRQ4    PPC_BIT(10)
+#define   PSIHB9_IRQ_LEVEL_SBE_I2C      PPC_BIT(11)
+#define   PSIHB9_IRQ_LEVEL_DIO          PPC_BIT(12)
+#define   PSIHB9_IRQ_LEVEL_PSU          PPC_BIT(13)
+#define   PSIHB9_IRQ_LEVEL_I2C_C        PPC_BIT(14)
+#define   PSIHB9_IRQ_LEVEL_I2C_D        PPC_BIT(15)
+#define   PSIHB9_IRQ_LEVEL_I2C_E        PPC_BIT(16)
+#define   PSIHB9_IRQ_LEVEL_SBE          PPC_BIT(19)
+
+#define PSIHB9_IRQ_STAT                 0x80 /* P bit */
+#define   PSIHB9_IRQ_STAT_PSI           PPC_BIT(0)
+#define   PSIHB9_IRQ_STAT_OCC           PPC_BIT(1)
+#define   PSIHB9_IRQ_STAT_FSI           PPC_BIT(2)
+#define   PSIHB9_IRQ_STAT_LPCHC         PPC_BIT(3)
+#define   PSIHB9_IRQ_STAT_LOCAL_ERR     PPC_BIT(4)
+#define   PSIHB9_IRQ_STAT_GLOBAL_ERR    PPC_BIT(5)
+#define   PSIHB9_IRQ_STAT_TPM           PPC_BIT(6)
+#define   PSIHB9_IRQ_STAT_LPC_SIRQ1     PPC_BIT(7)
+#define   PSIHB9_IRQ_STAT_LPC_SIRQ2     PPC_BIT(8)
+#define   PSIHB9_IRQ_STAT_LPC_SIRQ3     PPC_BIT(9)
+#define   PSIHB9_IRQ_STAT_LPC_SIRQ4     PPC_BIT(10)
+#define   PSIHB9_IRQ_STAT_SBE_I2C       PPC_BIT(11)
+#define   PSIHB9_IRQ_STAT_DIO           PPC_BIT(12)
+#define   PSIHB9_IRQ_STAT_PSU           PPC_BIT(13)
+
+static void pnv_psi_notify(XiveNotifier *xf, uint32_t srcno)
+{
+    PnvPsi *psi = PNV_PSI(xf);
+    uint64_t notif_port = psi->regs[PSIHB_REG(PSIHB9_ESB_NOTIF_ADDR)];
+    bool valid = notif_port & PSIHB9_ESB_NOTIF_VALID;
+    uint64_t notify_addr = notif_port & ~PSIHB9_ESB_NOTIF_VALID;
+
+    uint32_t offset =
+        (psi->regs[PSIHB_REG(PSIHB9_IVT_OFFSET)] >> PSIHB9_IVT_OFF_SHIFT);
+    uint64_t lisn = cpu_to_be64(offset + srcno);
+
+    if (valid) {
+        cpu_physical_memory_write(notify_addr, &lisn, sizeof(lisn));
+    }
+}
+
+static uint64_t pnv_psi_p9_mmio_read(void *opaque, hwaddr addr, unsigned size)
+{
+    PnvPsi *psi = PNV_PSI(opaque);
+    uint32_t reg = PSIHB_REG(addr);
+    uint64_t val = -1;
+
+    switch (addr) {
+    case PSIHB9_CR:
+    case PSIHB9_SEMR:
+        /* FSP stuff */
+    case PSIHB9_INTERRUPT_CONTROL:
+    case PSIHB9_ESB_CI_BASE:
+    case PSIHB9_ESB_NOTIF_ADDR:
+    case PSIHB9_IVT_OFFSET:
+        val = psi->regs[reg];
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "PSI: read at 0x%" PRIx64 "\n", addr);
+    }
+
+    return val;
+}
+
+static void pnv_psi_p9_mmio_write(void *opaque, hwaddr addr,
+                                  uint64_t val, unsigned size)
+{
+    PnvPsi *psi = PNV_PSI(opaque);
+    Pnv9Psi *psi9 = PNV9_PSI(psi);
+    uint32_t reg = PSIHB_REG(addr);
+    MemoryRegion *sysmem = get_system_memory();
+
+    switch (addr) {
+    case PSIHB9_CR:
+    case PSIHB9_SEMR:
+        /* FSP stuff */
+        break;
+    case PSIHB9_INTERRUPT_CONTROL:
+        if (val & PSIHB9_IRQ_RESET) {
+            device_reset(DEVICE(&psi9->source));
+        }
+        psi->regs[reg] = val;
+        break;
+
+    case PSIHB9_ESB_CI_BASE:
+        if (!(val & PSIHB9_ESB_CI_VALID)) {
+            if (psi->regs[reg] & PSIHB9_ESB_CI_VALID) {
+                memory_region_del_subregion(sysmem, &psi9->source.esb_mmio);
+            }
+        } else {
+            if (!(psi->regs[reg] & PSIHB9_ESB_CI_VALID)) {
+                memory_region_add_subregion(sysmem,
+                                        val & ~PSIHB9_ESB_CI_VALID,
+                                        &psi9->source.esb_mmio);
+            }
+        }
+        psi->regs[reg] = val;
+        break;
+
+    case PSIHB9_ESB_NOTIF_ADDR:
+        psi->regs[reg] = val;
+        break;
+    case PSIHB9_IVT_OFFSET:
+        psi->regs[reg] = val;
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "PSI: write at 0x%" PRIx64 "\n", addr);
+    }
+}
+
+static const MemoryRegionOps pnv_psi_p9_mmio_ops = {
+    .read = pnv_psi_p9_mmio_read,
+    .write = pnv_psi_p9_mmio_write,
+    .endianness = DEVICE_BIG_ENDIAN,
+    .valid = {
+        .min_access_size = 8,
+        .max_access_size = 8,
+    },
+    .impl = {
+        .min_access_size = 8,
+        .max_access_size = 8,
+    },
+};
+
+static uint64_t pnv_psi_p9_xscom_read(void *opaque, hwaddr addr, unsigned size)
+{
+    /* No read are expected */
+    qemu_log_mask(LOG_GUEST_ERROR, "PSI: xscom read at 0x%" PRIx64 "\n", addr);
+    return -1;
+}
+
+static void pnv_psi_p9_xscom_write(void *opaque, hwaddr addr,
+                                uint64_t val, unsigned size)
+{
+    PnvPsi *psi = PNV_PSI(opaque);
+
+    /* XSCOM is only used to set the PSIHB MMIO region */
+    switch (addr >> 3) {
+    case PSIHB_XSCOM_BAR:
+        pnv_psi_set_bar(psi, val);
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "PSI: xscom write at 0x%" PRIx64 "\n",
+                      addr);
+    }
+}
+
+static const MemoryRegionOps pnv_psi_p9_xscom_ops = {
+    .read = pnv_psi_p9_xscom_read,
+    .write = pnv_psi_p9_xscom_write,
+    .endianness = DEVICE_BIG_ENDIAN,
+    .valid = {
+        .min_access_size = 8,
+        .max_access_size = 8,
+    },
+    .impl = {
+        .min_access_size = 8,
+        .max_access_size = 8,
+    }
+};
+
+static void pnv_psi_power9_irq_set(PnvPsi *psi, int irq, bool state)
+{
+    uint32_t irq_method = psi->regs[PSIHB_REG(PSIHB9_INTERRUPT_CONTROL)];
+
+    if (irq > PSIHB9_NUM_IRQS) {
+        qemu_log_mask(LOG_GUEST_ERROR, "PSI: Unsupported irq %d\n", irq);
+        return;
+    }
+
+    if (irq_method & PSIHB9_IRQ_METHOD) {
+        qemu_log_mask(LOG_GUEST_ERROR, "PSI: LSI IRQ method no supported\n");
+        return;
+    }
+
+    /* Update LSI levels */
+    if (state) {
+        psi->regs[PSIHB_REG(PSIHB9_IRQ_LEVEL)] |= PPC_BIT(irq);
+    } else {
+        psi->regs[PSIHB_REG(PSIHB9_IRQ_LEVEL)] &= ~PPC_BIT(irq);
+    }
+
+    qemu_set_irq(psi->qirqs[irq], state);
+}
+
+static void pnv_psi_power9_reset(void *dev)
+{
+    Pnv9Psi *psi = PNV9_PSI(dev);
+
+    pnv_psi_reset(dev);
+
+    if (memory_region_is_mapped(&psi->source.esb_mmio)) {
+        memory_region_del_subregion(get_system_memory(), &psi->source.esb_mmio);
+    }
+}
+
+static void pnv_psi_power9_instance_init(Object *obj)
+{
+    Pnv9Psi *psi = PNV9_PSI(obj);
+
+    object_initialize_child(obj, "source", &psi->source, sizeof(psi->source),
+                            TYPE_XIVE_SOURCE, &error_abort, NULL);
+}
+
+static void pnv_psi_power9_realize(DeviceState *dev, Error **errp)
+{
+    PnvPsi *psi = PNV_PSI(dev);
+    XiveSource *xsrc = &PNV9_PSI(psi)->source;
+    Error *local_err = NULL;
+    int i;
+
+    /* This is the only device with 4k ESB pages */
+    object_property_set_int(OBJECT(xsrc), XIVE_ESB_4K, "shift",
+                            &error_fatal);
+    object_property_set_int(OBJECT(xsrc), PSIHB9_NUM_IRQS, "nr-irqs",
+                            &error_fatal);
+    object_property_add_const_link(OBJECT(xsrc), "xive", OBJECT(psi),
+                                   &error_fatal);
+    object_property_set_bool(OBJECT(xsrc), true, "realized", &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    for (i = 0; i < xsrc->nr_irqs; i++) {
+        xive_source_irq_set_lsi(xsrc, i);
+    }
+
+    psi->qirqs = qemu_allocate_irqs(xive_source_set_irq, xsrc, xsrc->nr_irqs);
+
+    /* XSCOM region for PSI registers */
+    pnv_xscom_region_init(&psi->xscom_regs, OBJECT(dev), &pnv_psi_p9_xscom_ops,
+                psi, "xscom-psi", PNV9_XSCOM_PSIHB_SIZE);
+
+    /* MMIO region for PSI registers */
+    memory_region_init_io(&psi->regs_mr, OBJECT(dev), &pnv_psi_p9_mmio_ops, psi,
+                          "psihb", PNV9_PSIHB_SIZE);
+
+    pnv_psi_set_bar(psi, psi->bar | PSIHB_BAR_EN);
+
+    qemu_register_reset(pnv_psi_power9_reset, dev);
+}
+
+static void pnv_psi_power9_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PnvPsiClass *ppc = PNV_PSI_CLASS(klass);
+    XiveNotifierClass *xfc = XIVE_NOTIFIER_CLASS(klass);
+
+    dc->desc    = "PowerNV PSI Controller POWER9";
+    dc->realize = pnv_psi_power9_realize;
+
+    ppc->chip_type  = PNV_CHIP_POWER9;
+    ppc->xscom_pcba = PNV9_XSCOM_PSIHB_BASE;
+    ppc->xscom_size = PNV9_XSCOM_PSIHB_SIZE;
+    ppc->bar_mask   = PSIHB9_BAR_MASK;
+    ppc->irq_set    = pnv_psi_power9_irq_set;
+
+    xfc->notify      = pnv_psi_notify;
+}
+
+static const TypeInfo pnv_psi_power9_info = {
+    .name          = TYPE_PNV9_PSI,
+    .parent        = TYPE_PNV_PSI,
+    .instance_size = sizeof(Pnv9Psi),
+    .instance_init = pnv_psi_power9_instance_init,
+    .class_init    = pnv_psi_power9_class_init,
+    .interfaces = (InterfaceInfo[]) {
+            { TYPE_XIVE_NOTIFIER },
+            { },
+    },
+};
+
 static void pnv_psi_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -612,6 +924,19 @@ static void pnv_psi_register_types(void)
 {
     type_register_static(&pnv_psi_info);
     type_register_static(&pnv_psi_power8_info);
+    type_register_static(&pnv_psi_power9_info);
 }
 
 type_init(pnv_psi_register_types);
+
+void pnv_psi_pic_print_info(Pnv9Psi *psi9, Monitor *mon)
+{
+    PnvPsi *psi = PNV_PSI(psi9);
+
+    uint32_t offset =
+        (psi->regs[PSIHB_REG(PSIHB9_IVT_OFFSET)] >> PSIHB9_IVT_OFF_SHIFT);
+
+    monitor_printf(mon, "PSIHB Source %08x .. %08x\n",
+                  offset, offset + psi9->source.nr_irqs - 1);
+    xive_source_pic_print_info(&psi9->source, offset, mon);
+}
-- 
2.20.1

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

* [Qemu-devel] [PATCH v2 03/15] ppc/pnv: lpc: fix OPB address ranges
  2019-03-07 22:35 [Qemu-devel] [PATCH v2 00/15] ppc: add POWER9 support to the PowerNV platform Cédric Le Goater
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 01/15] ppc/pnv: add a PSI bridge class model Cédric Le Goater
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 02/15] ppc/pnv: add a PSI bridge model for POWER9 Cédric Le Goater
@ 2019-03-07 22:35 ` Cédric Le Goater
  2019-03-07 23:59   ` David Gibson
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 04/15] ppc/pnv: add a LPC Controller class model Cédric Le Goater
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Cédric Le Goater @ 2019-03-07 22:35 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

The PowerNV LPC Controller exposes different sets of registers for
each of the functional units it encompasses, among which the OPB
(On-Chip Peripheral Bus) Master and Arbitrer and the LPC HOST
Controller.

The mapping addresses of each register range are correct but the sizes
are too large. Fix the sizes and define the OPB Arbitrer range to fill
the gap between the OPB Master registers and the LPC HOST Controller
registers.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---

 Changes in v2 :

  - wrote a commit log

 hw/ppc/pnv_lpc.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index 9b18ce55e391..547be609cafe 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -89,10 +89,11 @@ enum {
 #define LPC_FW_OPB_SIZE         0x10000000
 
 #define LPC_OPB_REGS_OPB_ADDR   0xc0010000
-#define LPC_OPB_REGS_OPB_SIZE   0x00002000
+#define LPC_OPB_REGS_OPB_SIZE   0x00000060
+#define LPC_OPB_REGS_OPBA_ADDR  0xc0011000
+#define LPC_OPB_REGS_OPBA_SIZE  0x00000008
 #define LPC_HC_REGS_OPB_ADDR    0xc0012000
-#define LPC_HC_REGS_OPB_SIZE    0x00001000
-
+#define LPC_HC_REGS_OPB_SIZE    0x00000100
 
 static int pnv_lpc_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
 {
-- 
2.20.1

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

* [Qemu-devel] [PATCH v2 04/15] ppc/pnv: add a LPC Controller class model
  2019-03-07 22:35 [Qemu-devel] [PATCH v2 00/15] ppc: add POWER9 support to the PowerNV platform Cédric Le Goater
                   ` (2 preceding siblings ...)
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 03/15] ppc/pnv: lpc: fix OPB address ranges Cédric Le Goater
@ 2019-03-07 22:35 ` Cédric Le Goater
  2019-03-07 23:59   ` David Gibson
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 05/15] ppc/pnv: add a 'dt_isa_nodename' to the chip Cédric Le Goater
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Cédric Le Goater @ 2019-03-07 22:35 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

It will ease the introduction of the LPC Controller model for POWER9.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
 include/hw/ppc/pnv_lpc.h | 15 +++++++
 hw/ppc/pnv.c             |  2 +-
 hw/ppc/pnv_lpc.c         | 85 ++++++++++++++++++++++++++++------------
 3 files changed, 77 insertions(+), 25 deletions(-)

diff --git a/include/hw/ppc/pnv_lpc.h b/include/hw/ppc/pnv_lpc.h
index d657489b07ce..f3f24419b19a 100644
--- a/include/hw/ppc/pnv_lpc.h
+++ b/include/hw/ppc/pnv_lpc.h
@@ -24,6 +24,8 @@
 #define TYPE_PNV_LPC "pnv-lpc"
 #define PNV_LPC(obj) \
      OBJECT_CHECK(PnvLpcController, (obj), TYPE_PNV_LPC)
+#define TYPE_PNV8_LPC TYPE_PNV_LPC "-POWER8"
+#define PNV8_LPC(obj) OBJECT_CHECK(PnvLpcController, (obj), TYPE_PNV8_LPC)
 
 typedef struct PnvLpcController {
     DeviceState parent;
@@ -70,6 +72,19 @@ typedef struct PnvLpcController {
     PnvPsi *psi;
 } PnvLpcController;
 
+#define PNV_LPC_CLASS(klass) \
+     OBJECT_CLASS_CHECK(PnvLpcClass, (klass), TYPE_PNV_LPC)
+#define PNV_LPC_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(PnvLpcClass, (obj), TYPE_PNV_LPC)
+
+typedef struct PnvLpcClass {
+    DeviceClass parent_class;
+
+    int psi_irq;
+
+    DeviceRealize parent_realize;
+} PnvLpcClass;
+
 ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp);
 
 #endif /* _PPC_PNV_LPC_H */
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 1cc454cbbc27..922e3ec48bb5 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -794,7 +794,7 @@ static void pnv_chip_power8_instance_init(Object *obj)
                                    OBJECT(qdev_get_machine()), &error_abort);
 
     object_initialize_child(obj, "lpc",  &chip8->lpc, sizeof(chip8->lpc),
-                            TYPE_PNV_LPC, &error_abort, NULL);
+                            TYPE_PNV8_LPC, &error_abort, NULL);
     object_property_add_const_link(OBJECT(&chip8->lpc), "psi",
                                    OBJECT(&chip8->psi), &error_abort);
 
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index 547be609cafe..3c509a30a0af 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -245,6 +245,7 @@ static const MemoryRegionOps pnv_lpc_xscom_ops = {
 static void pnv_lpc_eval_irqs(PnvLpcController *lpc)
 {
     bool lpc_to_opb_irq = false;
+    PnvLpcClass *plc = PNV_LPC_GET_CLASS(lpc);
 
     /* Update LPC controller to OPB line */
     if (lpc->lpc_hc_irqser_ctrl & LPC_HC_IRQSER_EN) {
@@ -267,7 +268,7 @@ static void pnv_lpc_eval_irqs(PnvLpcController *lpc)
     lpc->opb_irq_stat |= lpc->opb_irq_input & lpc->opb_irq_mask;
 
     /* Reflect the interrupt */
-    pnv_psi_irq_set(lpc->psi, PSIHB_IRQ_LPC_I2C, lpc->opb_irq_stat != 0);
+    pnv_psi_irq_set(lpc->psi, plc->psi_irq, lpc->opb_irq_stat != 0);
 }
 
 static uint64_t lpc_hc_read(void *opaque, hwaddr addr, unsigned size)
@@ -419,11 +420,65 @@ static const MemoryRegionOps opb_master_ops = {
     },
 };
 
+static void pnv_lpc_power8_realize(DeviceState *dev, Error **errp)
+{
+    PnvLpcController *lpc = PNV_LPC(dev);
+    PnvLpcClass *plc = PNV_LPC_GET_CLASS(dev);
+    Error *local_err = NULL;
+
+    plc->parent_realize(dev, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    /* P8 uses a XSCOM region for LPC registers */
+    pnv_xscom_region_init(&lpc->xscom_regs, OBJECT(lpc),
+                          &pnv_lpc_xscom_ops, lpc, "xscom-lpc",
+                          PNV_XSCOM_LPC_SIZE);
+}
+
+static void pnv_lpc_power8_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass);
+    PnvLpcClass *plc = PNV_LPC_CLASS(klass);
+
+    dc->desc = "PowerNV LPC Controller POWER8";
+
+    xdc->dt_xscom = pnv_lpc_dt_xscom;
+
+    plc->psi_irq = PSIHB_IRQ_LPC_I2C;
+
+    device_class_set_parent_realize(dc, pnv_lpc_power8_realize,
+                                    &plc->parent_realize);
+}
+
+static const TypeInfo pnv_lpc_power8_info = {
+    .name          = TYPE_PNV8_LPC,
+    .parent        = TYPE_PNV_LPC,
+    .instance_size = sizeof(PnvLpcController),
+    .class_init    = pnv_lpc_power8_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_PNV_XSCOM_INTERFACE },
+        { }
+    }
+};
+
 static void pnv_lpc_realize(DeviceState *dev, Error **errp)
 {
     PnvLpcController *lpc = PNV_LPC(dev);
     Object *obj;
-    Error *error = NULL;
+    Error *local_err = NULL;
+
+    obj = object_property_get_link(OBJECT(dev), "psi", &local_err);
+    if (!obj) {
+        error_propagate(errp, local_err);
+        error_prepend(errp, "required link 'psi' not found: ");
+        return;
+    }
+    /* The LPC controller needs PSI to generate interrupts  */
+    lpc->psi = PNV_PSI(obj);
 
     /* Reg inits */
     lpc->lpc_hc_fw_rd_acc_size = LPC_HC_FW_RD_4B;
@@ -463,46 +518,28 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
                           "lpc-hc", LPC_HC_REGS_OPB_SIZE);
     memory_region_add_subregion(&lpc->opb_mr, LPC_HC_REGS_OPB_ADDR,
                                 &lpc->lpc_hc_regs);
-
-    /* XScom region for LPC registers */
-    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)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass);
-
-    xdc->dt_xscom = pnv_lpc_dt_xscom;
 
     dc->realize = pnv_lpc_realize;
+    dc->desc = "PowerNV LPC Controller";
 }
 
 static const TypeInfo pnv_lpc_info = {
     .name          = TYPE_PNV_LPC,
     .parent        = TYPE_DEVICE,
-    .instance_size = sizeof(PnvLpcController),
     .class_init    = pnv_lpc_class_init,
-    .interfaces = (InterfaceInfo[]) {
-        { TYPE_PNV_XSCOM_INTERFACE },
-        { }
-    }
+    .class_size    = sizeof(PnvLpcClass),
+    .abstract      = true,
 };
 
 static void pnv_lpc_register_types(void)
 {
     type_register_static(&pnv_lpc_info);
+    type_register_static(&pnv_lpc_power8_info);
 }
 
 type_init(pnv_lpc_register_types)
-- 
2.20.1

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

* [Qemu-devel] [PATCH v2 05/15] ppc/pnv: add a 'dt_isa_nodename' to the chip
  2019-03-07 22:35 [Qemu-devel] [PATCH v2 00/15] ppc: add POWER9 support to the PowerNV platform Cédric Le Goater
                   ` (3 preceding siblings ...)
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 04/15] ppc/pnv: add a LPC Controller class model Cédric Le Goater
@ 2019-03-07 22:35 ` Cédric Le Goater
  2019-03-08  0:01   ` David Gibson
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 06/15] ppc/pnv: add a LPC Controller model for POWER9 Cédric Le Goater
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Cédric Le Goater @ 2019-03-07 22:35 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

The ISA bus has a different DT nodename on POWER9. Compute the name
when the PnvChip is realized, that is before it is used by the machine
to populate the device tree with the ISA devices.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/pnv.h |  2 ++
 hw/ppc/pnv.c         | 18 +++++-------------
 2 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 8d80cb34eebb..c81f157f41a9 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -58,6 +58,8 @@ typedef struct PnvChip {
     MemoryRegion xscom_mmio;
     MemoryRegion xscom;
     AddressSpace xscom_as;
+
+    gchar        *dt_isa_nodename;
 } PnvChip;
 
 #define TYPE_PNV8_CHIP "pnv8-chip"
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 922e3ec48bb5..6625562d276d 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -417,24 +417,12 @@ static int pnv_dt_isa_device(DeviceState *dev, void *opaque)
     return 0;
 }
 
-static int pnv_chip_isa_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;
-}
-
 /* The default LPC bus of a multichip system is on chip 0. It's
  * recognized by the firmware (skiboot) using a "primary" property.
  */
 static void pnv_dt_isa(PnvMachineState *pnv, void *fdt)
 {
-    int isa_offset = pnv_chip_isa_offset(pnv->chips[0], fdt);
+    int isa_offset = fdt_path_offset(fdt, pnv->chips[0]->dt_isa_nodename);
     ForeachPopulateArgs args = {
         .fdt = fdt,
         .offset = isa_offset,
@@ -866,6 +854,10 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
                              &error_fatal);
     pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip8->lpc.xscom_regs);
 
+    chip->dt_isa_nodename = g_strdup_printf("/xscom@%" PRIx64 "/isa@%x",
+                                            (uint64_t) PNV_XSCOM_BASE(chip),
+                                            PNV_XSCOM_LPC_BASE);
+
     /* Interrupt Management Area. This is the memory region holding
      * all the Interrupt Control Presenter (ICP) registers */
     pnv_chip_icp_realize(chip8, &local_err);
-- 
2.20.1

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

* [Qemu-devel] [PATCH v2 06/15] ppc/pnv: add a LPC Controller model for POWER9
  2019-03-07 22:35 [Qemu-devel] [PATCH v2 00/15] ppc: add POWER9 support to the PowerNV platform Cédric Le Goater
                   ` (4 preceding siblings ...)
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 05/15] ppc/pnv: add a 'dt_isa_nodename' to the chip Cédric Le Goater
@ 2019-03-07 22:35 ` Cédric Le Goater
  2019-03-08  0:28   ` David Gibson
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 07/15] ppc/pnv: add SerIRQ routing registers Cédric Le Goater
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Cédric Le Goater @ 2019-03-07 22:35 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

The LPC Controller on POWER9 is very similar to the one found on
POWER8 but accesses are now done via on MMIOs, without the XSCOM and
ECCB logic. The device tree is populated differently so we add a
specific POWER9 routine for the purpose.

SerIRQ routing is yet to be done.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---

 Changes in v2:

 - defined a 'dt_isa_nodename' for the POWER9 chip

 include/hw/ppc/pnv.h     |   4 +
 include/hw/ppc/pnv_lpc.h |   9 ++
 hw/ppc/pnv.c             |  22 ++++-
 hw/ppc/pnv_lpc.c         | 200 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 234 insertions(+), 1 deletion(-)

diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index c81f157f41a9..1cd1ad622d0b 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -87,6 +87,7 @@ typedef struct Pnv9Chip {
     /*< public >*/
     PnvXive      xive;
     Pnv9Psi      psi;
+    PnvLpcController lpc;
 } Pnv9Chip;
 
 typedef struct PnvChipClass {
@@ -234,6 +235,9 @@ void pnv_bmc_powerdown(IPMIBmc *bmc);
 #define PNV9_XIVE_PC_SIZE            0x0000001000000000ull
 #define PNV9_XIVE_PC_BASE(chip)      PNV9_CHIP_BASE(chip, 0x0006018000000000ull)
 
+#define PNV9_LPCM_SIZE               0x0000000100000000ull
+#define PNV9_LPCM_BASE(chip)         PNV9_CHIP_BASE(chip, 0x0006030000000000ull)
+
 #define PNV9_PSIHB_SIZE              0x0000000000100000ull
 #define PNV9_PSIHB_BASE(chip)        PNV9_CHIP_BASE(chip, 0x0006030203000000ull)
 
diff --git a/include/hw/ppc/pnv_lpc.h b/include/hw/ppc/pnv_lpc.h
index f3f24419b19a..242b18081caa 100644
--- a/include/hw/ppc/pnv_lpc.h
+++ b/include/hw/ppc/pnv_lpc.h
@@ -27,6 +27,9 @@
 #define TYPE_PNV8_LPC TYPE_PNV_LPC "-POWER8"
 #define PNV8_LPC(obj) OBJECT_CHECK(PnvLpcController, (obj), TYPE_PNV8_LPC)
 
+#define TYPE_PNV9_LPC TYPE_PNV_LPC "-POWER9"
+#define PNV9_LPC(obj) OBJECT_CHECK(PnvLpcController, (obj), TYPE_PNV9_LPC)
+
 typedef struct PnvLpcController {
     DeviceState parent;
 
@@ -85,6 +88,12 @@ typedef struct PnvLpcClass {
     DeviceRealize parent_realize;
 } PnvLpcClass;
 
+/*
+ * Old compilers error on typdef forward declarations. Keep them happy.
+ */
+struct PnvChip;
+
 ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp);
+int pnv_dt_lpc(struct PnvChip *chip, void *fdt, int root_offset);
 
 #endif /* _PPC_PNV_LPC_H */
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 6625562d276d..918fae057b5c 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -306,6 +306,8 @@ static void pnv_chip_power9_dt_populate(PnvChip *chip, void *fdt)
     if (chip->ram_size) {
         pnv_dt_memory(fdt, chip->chip_id, chip->ram_start, chip->ram_size);
     }
+
+    pnv_dt_lpc(chip, fdt, 0);
 }
 
 static void pnv_dt_rtc(ISADevice *d, void *fdt, int lpc_off)
@@ -547,7 +549,8 @@ static ISABus *pnv_chip_power8nvl_isa_create(PnvChip *chip, Error **errp)
 
 static ISABus *pnv_chip_power9_isa_create(PnvChip *chip, Error **errp)
 {
-    return NULL;
+    Pnv9Chip *chip9 = PNV9_CHIP(chip);
+    return pnv_lpc_isa_create(&chip9->lpc, false, errp);
 }
 
 static ISABus *pnv_isa_create(PnvChip *chip, Error **errp)
@@ -948,6 +951,11 @@ static void pnv_chip_power9_instance_init(Object *obj)
                             TYPE_PNV9_PSI, &error_abort, NULL);
     object_property_add_const_link(OBJECT(&chip9->psi), "chip", obj,
                                    &error_abort);
+
+    object_initialize_child(obj, "lpc",  &chip9->lpc, sizeof(chip9->lpc),
+                            TYPE_PNV9_LPC, &error_abort, NULL);
+    object_property_add_const_link(OBJECT(&chip9->lpc), "psi",
+                                   OBJECT(&chip9->psi), &error_abort);
 }
 
 static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
@@ -992,6 +1000,18 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
     }
     pnv_xscom_add_subregion(chip, PNV9_XSCOM_PSIHB_BASE,
                             &PNV_PSI(psi9)->xscom_regs);
+
+    /* LPC */
+    object_property_set_bool(OBJECT(&chip9->lpc), true, "realized", &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    memory_region_add_subregion(get_system_memory(), PNV9_LPCM_BASE(chip),
+                                &chip9->lpc.xscom_regs);
+
+    chip->dt_isa_nodename = g_strdup_printf("/lpcm-opb@%" PRIx64 "/lpc@0",
+                                            (uint64_t) PNV9_LPCM_BASE(chip));
 }
 
 static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index 3c509a30a0af..6df694e0abc1 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -118,6 +118,100 @@ static int pnv_lpc_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
     return 0;
 }
 
+/* POWER9 only */
+int pnv_dt_lpc(PnvChip *chip, void *fdt, int root_offset)
+{
+    const char compat[] = "ibm,power9-lpcm-opb\0simple-bus";
+    const char lpc_compat[] = "ibm,power9-lpc\0ibm,lpc";
+    char *name;
+    int offset, lpcm_offset;
+    uint64_t lpcm_addr = PNV9_LPCM_BASE(chip);
+    uint32_t opb_ranges[8] = { 0,
+                               cpu_to_be32(lpcm_addr >> 32),
+                               cpu_to_be32((uint32_t)lpcm_addr),
+                               cpu_to_be32(PNV9_LPCM_SIZE / 2),
+                               cpu_to_be32(PNV9_LPCM_SIZE / 2),
+                               cpu_to_be32(lpcm_addr >> 32),
+                               cpu_to_be32(PNV9_LPCM_SIZE / 2),
+                               cpu_to_be32(PNV9_LPCM_SIZE / 2),
+    };
+    uint32_t opb_reg[4] = { cpu_to_be32(lpcm_addr >> 32),
+                            cpu_to_be32((uint32_t)lpcm_addr),
+                            cpu_to_be32(PNV9_LPCM_SIZE >> 32),
+                            cpu_to_be32((uint32_t)PNV9_LPCM_SIZE),
+    };
+    uint32_t reg[2];
+
+    /*
+     * OPB bus
+     */
+    name = g_strdup_printf("lpcm-opb@%"PRIx64, lpcm_addr);
+    lpcm_offset = fdt_add_subnode(fdt, root_offset, name);
+    _FDT(lpcm_offset);
+    g_free(name);
+
+    _FDT((fdt_setprop(fdt, lpcm_offset, "reg", opb_reg, sizeof(opb_reg))));
+    _FDT((fdt_setprop_cell(fdt, lpcm_offset, "#address-cells", 1)));
+    _FDT((fdt_setprop_cell(fdt, lpcm_offset, "#size-cells", 1)));
+    _FDT((fdt_setprop(fdt, lpcm_offset, "compatible", compat, sizeof(compat))));
+    _FDT((fdt_setprop_cell(fdt, lpcm_offset, "ibm,chip-id", chip->chip_id)));
+    _FDT((fdt_setprop(fdt, lpcm_offset, "ranges", opb_ranges,
+                      sizeof(opb_ranges))));
+
+    /*
+     * OPB Master registers
+     */
+    name = g_strdup_printf("opb-master@%x", LPC_OPB_REGS_OPB_ADDR);
+    offset = fdt_add_subnode(fdt, lpcm_offset, name);
+    _FDT(offset);
+    g_free(name);
+
+    reg[0] = cpu_to_be32(LPC_OPB_REGS_OPB_ADDR);
+    reg[1] = cpu_to_be32(LPC_OPB_REGS_OPB_SIZE);
+    _FDT((fdt_setprop(fdt, offset, "reg", reg, sizeof(reg))));
+    _FDT((fdt_setprop_string(fdt, offset, "compatible",
+                             "ibm,power9-lpcm-opb-master")));
+
+    /*
+     * OPB arbitrer registers
+     */
+    name = g_strdup_printf("opb-arbitrer@%x", LPC_OPB_REGS_OPBA_ADDR);
+    offset = fdt_add_subnode(fdt, lpcm_offset, name);
+    _FDT(offset);
+    g_free(name);
+
+    reg[0] = cpu_to_be32(LPC_OPB_REGS_OPBA_ADDR);
+    reg[1] = cpu_to_be32(LPC_OPB_REGS_OPBA_SIZE);
+    _FDT((fdt_setprop(fdt, offset, "reg", reg, sizeof(reg))));
+    _FDT((fdt_setprop_string(fdt, offset, "compatible",
+                             "ibm,power9-lpcm-opb-arbiter")));
+
+    /*
+     * LPC Host Controller registers
+     */
+    name = g_strdup_printf("lpc-controller@%x", LPC_HC_REGS_OPB_ADDR);
+    offset = fdt_add_subnode(fdt, lpcm_offset, name);
+    _FDT(offset);
+    g_free(name);
+
+    reg[0] = cpu_to_be32(LPC_HC_REGS_OPB_ADDR);
+    reg[1] = cpu_to_be32(LPC_HC_REGS_OPB_SIZE);
+    _FDT((fdt_setprop(fdt, offset, "reg", reg, sizeof(reg))));
+    _FDT((fdt_setprop_string(fdt, offset, "compatible",
+                             "ibm,power9-lpc-controller")));
+
+    name = g_strdup_printf("lpc@0");
+    offset = fdt_add_subnode(fdt, lpcm_offset, name);
+    _FDT(offset);
+    g_free(name);
+    _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 2)));
+    _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 1)));
+    _FDT((fdt_setprop(fdt, offset, "compatible", lpc_compat,
+                      sizeof(lpc_compat))));
+
+    return 0;
+}
+
 /*
  * These read/write handlers of the OPB address space should be common
  * with the P9 LPC Controller which uses direct MMIOs.
@@ -242,6 +336,74 @@ static const MemoryRegionOps pnv_lpc_xscom_ops = {
     .endianness = DEVICE_BIG_ENDIAN,
 };
 
+static uint64_t pnv_lpc_mmio_read(void *opaque, hwaddr addr, unsigned size)
+{
+    PnvLpcController *lpc = PNV_LPC(opaque);
+    uint64_t val = 0;
+    uint32_t opb_addr = addr & ECCB_CTL_ADDR_MASK;
+    MemTxResult result;
+
+    switch (size) {
+    case 4:
+        val = address_space_ldl(&lpc->opb_as, opb_addr, MEMTXATTRS_UNSPECIFIED,
+                                &result);
+        break;
+    case 1:
+        val = address_space_ldub(&lpc->opb_as, opb_addr, MEMTXATTRS_UNSPECIFIED,
+                                 &result);
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "OPB read failed at @0x%"
+                      HWADDR_PRIx " invalid size %d\n", addr, size);
+        return 0;
+    }
+
+    if (result != MEMTX_OK) {
+        qemu_log_mask(LOG_GUEST_ERROR, "OPB read failed at @0x%"
+                      HWADDR_PRIx "\n", addr);
+    }
+
+    return val;
+}
+
+static void pnv_lpc_mmio_write(void *opaque, hwaddr addr,
+                                uint64_t val, unsigned size)
+{
+    PnvLpcController *lpc = PNV_LPC(opaque);
+    uint32_t opb_addr = addr & ECCB_CTL_ADDR_MASK;
+    MemTxResult result;
+
+    switch (size) {
+    case 4:
+        address_space_stl(&lpc->opb_as, opb_addr, val, MEMTXATTRS_UNSPECIFIED,
+                          &result);
+         break;
+    case 1:
+        address_space_stb(&lpc->opb_as, opb_addr, val, MEMTXATTRS_UNSPECIFIED,
+                          &result);
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "OPB write failed at @0x%"
+                      HWADDR_PRIx " invalid size %d\n", addr, size);
+        return;
+    }
+
+    if (result != MEMTX_OK) {
+        qemu_log_mask(LOG_GUEST_ERROR, "OPB write failed at @0x%"
+                      HWADDR_PRIx "\n", addr);
+    }
+}
+
+static const MemoryRegionOps pnv_lpc_mmio_ops = {
+    .read = pnv_lpc_mmio_read,
+    .write = pnv_lpc_mmio_write,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 4,
+    },
+    .endianness = DEVICE_BIG_ENDIAN,
+};
+
 static void pnv_lpc_eval_irqs(PnvLpcController *lpc)
 {
     bool lpc_to_opb_irq = false;
@@ -465,6 +627,43 @@ static const TypeInfo pnv_lpc_power8_info = {
     }
 };
 
+static void pnv_lpc_power9_realize(DeviceState *dev, Error **errp)
+{
+    PnvLpcController *lpc = PNV_LPC(dev);
+    PnvLpcClass *plc = PNV_LPC_GET_CLASS(dev);
+    Error *local_err = NULL;
+
+    plc->parent_realize(dev, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    /* P9 uses a MMIO region */
+    memory_region_init_io(&lpc->xscom_regs, OBJECT(lpc), &pnv_lpc_mmio_ops,
+                          lpc, "lpcm", PNV9_LPCM_SIZE);
+}
+
+static void pnv_lpc_power9_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PnvLpcClass *plc = PNV_LPC_CLASS(klass);
+
+    dc->desc = "PowerNV LPC Controller POWER9";
+
+    plc->psi_irq = PSIHB9_IRQ_LPCHC;
+
+    device_class_set_parent_realize(dc, pnv_lpc_power9_realize,
+                                    &plc->parent_realize);
+}
+
+static const TypeInfo pnv_lpc_power9_info = {
+    .name          = TYPE_PNV9_LPC,
+    .parent        = TYPE_PNV_LPC,
+    .instance_size = sizeof(PnvLpcController),
+    .class_init    = pnv_lpc_power9_class_init,
+};
+
 static void pnv_lpc_realize(DeviceState *dev, Error **errp)
 {
     PnvLpcController *lpc = PNV_LPC(dev);
@@ -540,6 +739,7 @@ static void pnv_lpc_register_types(void)
 {
     type_register_static(&pnv_lpc_info);
     type_register_static(&pnv_lpc_power8_info);
+    type_register_static(&pnv_lpc_power9_info);
 }
 
 type_init(pnv_lpc_register_types)
-- 
2.20.1

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

* [Qemu-devel] [PATCH v2 07/15] ppc/pnv: add SerIRQ routing registers
  2019-03-07 22:35 [Qemu-devel] [PATCH v2 00/15] ppc: add POWER9 support to the PowerNV platform Cédric Le Goater
                   ` (5 preceding siblings ...)
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 06/15] ppc/pnv: add a LPC Controller model for POWER9 Cédric Le Goater
@ 2019-03-07 22:35 ` Cédric Le Goater
  2019-03-08  0:28   ` David Gibson
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 08/15] ppc/pnv: add a OCC model class Cédric Le Goater
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Cédric Le Goater @ 2019-03-07 22:35 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

This is just a simple reminder that SerIRQ routing should be
addressed.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/pnv_lpc.h |  2 ++
 hw/ppc/pnv_lpc.c         | 14 ++++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/include/hw/ppc/pnv_lpc.h b/include/hw/ppc/pnv_lpc.h
index 242b18081caa..413579792ed1 100644
--- a/include/hw/ppc/pnv_lpc.h
+++ b/include/hw/ppc/pnv_lpc.h
@@ -55,6 +55,8 @@ typedef struct PnvLpcController {
     MemoryRegion opb_master_regs;
 
     /* OPB Master LS registers */
+    uint32_t opb_irq_route0;
+    uint32_t opb_irq_route1;
     uint32_t opb_irq_stat;
     uint32_t opb_irq_mask;
     uint32_t opb_irq_pol;
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index 6df694e0abc1..641e2046db92 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -39,6 +39,8 @@ enum {
 };
 
 /* OPB Master LS registers */
+#define OPB_MASTER_LS_ROUTE0    0x8
+#define OPB_MASTER_LS_ROUTE1    0xC
 #define OPB_MASTER_LS_IRQ_STAT  0x50
 #define   OPB_MASTER_IRQ_LPC            0x00000800
 #define OPB_MASTER_LS_IRQ_MASK  0x54
@@ -521,6 +523,12 @@ static uint64_t opb_master_read(void *opaque, hwaddr addr, unsigned size)
     uint64_t val = 0xfffffffffffffffful;
 
     switch (addr) {
+    case OPB_MASTER_LS_ROUTE0: /* TODO */
+        val = lpc->opb_irq_route0;
+        break;
+    case OPB_MASTER_LS_ROUTE1: /* TODO */
+        val = lpc->opb_irq_route1;
+        break;
     case OPB_MASTER_LS_IRQ_STAT:
         val = lpc->opb_irq_stat;
         break;
@@ -547,6 +555,12 @@ static void opb_master_write(void *opaque, hwaddr addr,
     PnvLpcController *lpc = opaque;
 
     switch (addr) {
+    case OPB_MASTER_LS_ROUTE0: /* TODO */
+        lpc->opb_irq_route0 = val;
+        break;
+    case OPB_MASTER_LS_ROUTE1: /* TODO */
+        lpc->opb_irq_route1 = val;
+        break;
     case OPB_MASTER_LS_IRQ_STAT:
         lpc->opb_irq_stat &= ~val;
         pnv_lpc_eval_irqs(lpc);
-- 
2.20.1

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

* [Qemu-devel] [PATCH v2 08/15] ppc/pnv: add a OCC model class
  2019-03-07 22:35 [Qemu-devel] [PATCH v2 00/15] ppc: add POWER9 support to the PowerNV platform Cédric Le Goater
                   ` (6 preceding siblings ...)
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 07/15] ppc/pnv: add SerIRQ routing registers Cédric Le Goater
@ 2019-03-07 22:35 ` Cédric Le Goater
  2019-03-08  0:29   ` David Gibson
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 09/15] ppc/pnv: add a OCC model for POWER9 Cédric Le Goater
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Cédric Le Goater @ 2019-03-07 22:35 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

To ease the introduction of the OCC model for POWER9, provide a new
class attributes to define XSCOM operations per CPU family and a PSI
IRQ number.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---

 Changes in v2:

 - new attributes to define XSCOM operations per CPU family and a PSI
   IRQ number.

 include/hw/ppc/pnv_occ.h | 15 +++++++++++
 hw/ppc/pnv.c             |  2 +-
 hw/ppc/pnv_occ.c         | 55 +++++++++++++++++++++++++++-------------
 3 files changed, 54 insertions(+), 18 deletions(-)

diff --git a/include/hw/ppc/pnv_occ.h b/include/hw/ppc/pnv_occ.h
index 82f299dc76ff..dab5a05f8e99 100644
--- a/include/hw/ppc/pnv_occ.h
+++ b/include/hw/ppc/pnv_occ.h
@@ -23,6 +23,8 @@
 
 #define TYPE_PNV_OCC "pnv-occ"
 #define PNV_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV_OCC)
+#define TYPE_PNV8_OCC TYPE_PNV_OCC "-POWER8"
+#define PNV8_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV8_OCC)
 
 typedef struct PnvOCC {
     DeviceState xd;
@@ -35,4 +37,17 @@ typedef struct PnvOCC {
     MemoryRegion xscom_regs;
 } PnvOCC;
 
+#define PNV_OCC_CLASS(klass) \
+     OBJECT_CLASS_CHECK(PnvOCCClass, (klass), TYPE_PNV_OCC)
+#define PNV_OCC_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(PnvOCCClass, (obj), TYPE_PNV_OCC)
+
+typedef struct PnvOCCClass {
+    DeviceClass parent_class;
+
+    int xscom_size;
+    const MemoryRegionOps *xscom_ops;
+    int psi_irq;
+} PnvOCCClass;
+
 #endif /* _PPC_PNV_OCC_H */
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 918fae057b5c..6ae9ce679505 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -790,7 +790,7 @@ static void pnv_chip_power8_instance_init(Object *obj)
                                    OBJECT(&chip8->psi), &error_abort);
 
     object_initialize_child(obj, "occ",  &chip8->occ, sizeof(chip8->occ),
-                            TYPE_PNV_OCC, &error_abort, NULL);
+                            TYPE_PNV8_OCC, &error_abort, NULL);
     object_property_add_const_link(OBJECT(&chip8->occ), "psi",
                                    OBJECT(&chip8->psi), &error_abort);
 }
diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c
index 04880f26d612..ea725647c988 100644
--- a/hw/ppc/pnv_occ.c
+++ b/hw/ppc/pnv_occ.c
@@ -34,15 +34,17 @@
 static void pnv_occ_set_misc(PnvOCC *occ, uint64_t val)
 {
     bool irq_state;
+    PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
 
     val &= 0xffff000000000000ull;
 
     occ->occmisc = val;
     irq_state = !!(val >> 63);
-    pnv_psi_irq_set(occ->psi, PSIHB_IRQ_OCC, irq_state);
+    pnv_psi_irq_set(occ->psi, poc->psi_irq, irq_state);
 }
 
-static uint64_t pnv_occ_xscom_read(void *opaque, hwaddr addr, unsigned size)
+static uint64_t pnv_occ_power8_xscom_read(void *opaque, hwaddr addr,
+                                          unsigned size)
 {
     PnvOCC *occ = PNV_OCC(opaque);
     uint32_t offset = addr >> 3;
@@ -54,13 +56,13 @@ static uint64_t pnv_occ_xscom_read(void *opaque, hwaddr addr, unsigned size)
         break;
     default:
         qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
-                      HWADDR_PRIx "\n", addr);
+                      HWADDR_PRIx "\n", addr >> 3);
     }
     return val;
 }
 
-static void pnv_occ_xscom_write(void *opaque, hwaddr addr,
-                                uint64_t val, unsigned size)
+static void pnv_occ_power8_xscom_write(void *opaque, hwaddr addr,
+                                       uint64_t val, unsigned size)
 {
     PnvOCC *occ = PNV_OCC(opaque);
     uint32_t offset = addr >> 3;
@@ -77,13 +79,13 @@ static void pnv_occ_xscom_write(void *opaque, hwaddr addr,
         break;
     default:
         qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
-                      HWADDR_PRIx "\n", addr);
+                      HWADDR_PRIx "\n", addr >> 3);
     }
 }
 
-static const MemoryRegionOps pnv_occ_xscom_ops = {
-    .read = pnv_occ_xscom_read,
-    .write = pnv_occ_xscom_write,
+static const MemoryRegionOps pnv_occ_power8_xscom_ops = {
+    .read = pnv_occ_power8_xscom_read,
+    .write = pnv_occ_power8_xscom_write,
     .valid.min_access_size = 8,
     .valid.max_access_size = 8,
     .impl.min_access_size = 8,
@@ -91,27 +93,42 @@ static const MemoryRegionOps pnv_occ_xscom_ops = {
     .endianness = DEVICE_BIG_ENDIAN,
 };
 
+static void pnv_occ_power8_class_init(ObjectClass *klass, void *data)
+{
+    PnvOCCClass *poc = PNV_OCC_CLASS(klass);
+
+    poc->xscom_size = PNV_XSCOM_OCC_SIZE;
+    poc->xscom_ops = &pnv_occ_power8_xscom_ops;
+    poc->psi_irq = PSIHB_IRQ_OCC;
+}
+
+static const TypeInfo pnv_occ_power8_type_info = {
+    .name          = TYPE_PNV8_OCC,
+    .parent        = TYPE_PNV_OCC,
+    .instance_size = sizeof(PnvOCC),
+    .class_init    = pnv_occ_power8_class_init,
+};
 
 static void pnv_occ_realize(DeviceState *dev, Error **errp)
 {
     PnvOCC *occ = PNV_OCC(dev);
+    PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
     Object *obj;
-    Error *error = NULL;
+    Error *local_err = NULL;
 
     occ->occmisc = 0;
 
-    /* get PSI object from chip */
-    obj = object_property_get_link(OBJECT(dev), "psi", &error);
+    obj = object_property_get_link(OBJECT(dev), "psi", &local_err);
     if (!obj) {
-        error_setg(errp, "%s: required link 'psi' not found: %s",
-                   __func__, error_get_pretty(error));
+        error_propagate(errp, local_err);
+        error_prepend(errp, "required link 'psi' not found: ");
         return;
     }
     occ->psi = PNV_PSI(obj);
 
     /* XScom region for OCC registers */
-    pnv_xscom_region_init(&occ->xscom_regs, OBJECT(dev), &pnv_occ_xscom_ops,
-                  occ, "xscom-occ", PNV_XSCOM_OCC_SIZE);
+    pnv_xscom_region_init(&occ->xscom_regs, OBJECT(dev), poc->xscom_ops,
+                          occ, "xscom-occ", poc->xscom_size);
 }
 
 static void pnv_occ_class_init(ObjectClass *klass, void *data)
@@ -119,6 +136,7 @@ static void pnv_occ_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->realize = pnv_occ_realize;
+    dc->desc = "PowerNV OCC Controller";
 }
 
 static const TypeInfo pnv_occ_type_info = {
@@ -126,11 +144,14 @@ static const TypeInfo pnv_occ_type_info = {
     .parent        = TYPE_DEVICE,
     .instance_size = sizeof(PnvOCC),
     .class_init    = pnv_occ_class_init,
+    .class_size    = sizeof(PnvOCCClass),
+    .abstract      = true,
 };
 
 static void pnv_occ_register_types(void)
 {
     type_register_static(&pnv_occ_type_info);
+    type_register_static(&pnv_occ_power8_type_info);
 }
 
-type_init(pnv_occ_register_types)
+type_init(pnv_occ_register_types);
-- 
2.20.1

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

* [Qemu-devel] [PATCH v2 09/15] ppc/pnv: add a OCC model for POWER9
  2019-03-07 22:35 [Qemu-devel] [PATCH v2 00/15] ppc: add POWER9 support to the PowerNV platform Cédric Le Goater
                   ` (7 preceding siblings ...)
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 08/15] ppc/pnv: add a OCC model class Cédric Le Goater
@ 2019-03-07 22:35 ` Cédric Le Goater
  2019-03-08  0:30   ` David Gibson
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 10/15] ppc/pnv: extend XSCOM core support " Cédric Le Goater
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Cédric Le Goater @ 2019-03-07 22:35 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

The OCC on POWER9 is very similar to the one found on POWER8. Provide
the same routines with P9 values for the registers and IRQ number.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---

 Changes in v2 :

 - made use of the new class attributes for POWER9

 include/hw/ppc/pnv.h       |  1 +
 include/hw/ppc/pnv_occ.h   |  2 ++
 include/hw/ppc/pnv_xscom.h |  3 ++
 hw/ppc/pnv.c               | 13 +++++++
 hw/ppc/pnv_occ.c           | 72 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 91 insertions(+)

diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 1cd1ad622d0b..39888f9d52c1 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -88,6 +88,7 @@ typedef struct Pnv9Chip {
     PnvXive      xive;
     Pnv9Psi      psi;
     PnvLpcController lpc;
+    PnvOCC       occ;
 } Pnv9Chip;
 
 typedef struct PnvChipClass {
diff --git a/include/hw/ppc/pnv_occ.h b/include/hw/ppc/pnv_occ.h
index dab5a05f8e99..d22b65a71abe 100644
--- a/include/hw/ppc/pnv_occ.h
+++ b/include/hw/ppc/pnv_occ.h
@@ -25,6 +25,8 @@
 #define PNV_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV_OCC)
 #define TYPE_PNV8_OCC TYPE_PNV_OCC "-POWER8"
 #define PNV8_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV8_OCC)
+#define TYPE_PNV9_OCC TYPE_PNV_OCC "-POWER9"
+#define PNV9_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV9_OCC)
 
 typedef struct PnvOCC {
     DeviceState xd;
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index 403a365ed274..3292459fbb78 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -73,6 +73,9 @@ typedef struct PnvXScomInterfaceClass {
 #define PNV_XSCOM_OCC_BASE        0x0066000
 #define PNV_XSCOM_OCC_SIZE        0x6000
 
+#define PNV9_XSCOM_OCC_BASE       PNV_XSCOM_OCC_BASE
+#define PNV9_XSCOM_OCC_SIZE       0x8000
+
 #define PNV9_XSCOM_PSIHB_BASE     0x5012900
 #define PNV9_XSCOM_PSIHB_SIZE     0x100
 
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 6ae9ce679505..1559a733235b 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -956,6 +956,11 @@ static void pnv_chip_power9_instance_init(Object *obj)
                             TYPE_PNV9_LPC, &error_abort, NULL);
     object_property_add_const_link(OBJECT(&chip9->lpc), "psi",
                                    OBJECT(&chip9->psi), &error_abort);
+
+    object_initialize_child(obj, "occ",  &chip9->occ, sizeof(chip9->occ),
+                            TYPE_PNV9_OCC, &error_abort, NULL);
+    object_property_add_const_link(OBJECT(&chip9->occ), "psi",
+                                   OBJECT(&chip9->psi), &error_abort);
 }
 
 static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
@@ -1012,6 +1017,14 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
 
     chip->dt_isa_nodename = g_strdup_printf("/lpcm-opb@%" PRIx64 "/lpc@0",
                                             (uint64_t) PNV9_LPCM_BASE(chip));
+
+    /* Create the simplified OCC model */
+    object_property_set_bool(OBJECT(&chip9->occ), true, "realized", &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    pnv_xscom_add_subregion(chip, PNV9_XSCOM_OCC_BASE, &chip9->occ.xscom_regs);
 }
 
 static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c
index ea725647c988..fdd9296e1bc7 100644
--- a/hw/ppc/pnv_occ.c
+++ b/hw/ppc/pnv_occ.c
@@ -109,6 +109,77 @@ static const TypeInfo pnv_occ_power8_type_info = {
     .class_init    = pnv_occ_power8_class_init,
 };
 
+#define P9_OCB_OCI_OCCMISC              0x6080
+#define P9_OCB_OCI_OCCMISC_CLEAR        0x6081
+#define P9_OCB_OCI_OCCMISC_OR           0x6082
+
+
+static uint64_t pnv_occ_power9_xscom_read(void *opaque, hwaddr addr,
+                                          unsigned size)
+{
+    PnvOCC *occ = PNV_OCC(opaque);
+    uint32_t offset = addr >> 3;
+    uint64_t val = 0;
+
+    switch (offset) {
+    case P9_OCB_OCI_OCCMISC:
+        val = occ->occmisc;
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
+                      HWADDR_PRIx "\n", addr >> 3);
+    }
+    return val;
+}
+
+static void pnv_occ_power9_xscom_write(void *opaque, hwaddr addr,
+                                       uint64_t val, unsigned size)
+{
+    PnvOCC *occ = PNV_OCC(opaque);
+    uint32_t offset = addr >> 3;
+
+    switch (offset) {
+    case P9_OCB_OCI_OCCMISC_CLEAR:
+        pnv_occ_set_misc(occ, 0);
+        break;
+    case P9_OCB_OCI_OCCMISC_OR:
+        pnv_occ_set_misc(occ, occ->occmisc | val);
+        break;
+    case P9_OCB_OCI_OCCMISC:
+        pnv_occ_set_misc(occ, val);
+       break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
+                      HWADDR_PRIx "\n", addr >> 3);
+    }
+}
+
+static const MemoryRegionOps pnv_occ_power9_xscom_ops = {
+    .read = pnv_occ_power9_xscom_read,
+    .write = pnv_occ_power9_xscom_write,
+    .valid.min_access_size = 8,
+    .valid.max_access_size = 8,
+    .impl.min_access_size = 8,
+    .impl.max_access_size = 8,
+    .endianness = DEVICE_BIG_ENDIAN,
+};
+
+static void pnv_occ_power9_class_init(ObjectClass *klass, void *data)
+{
+    PnvOCCClass *poc = PNV_OCC_CLASS(klass);
+
+    poc->xscom_size = PNV9_XSCOM_OCC_SIZE;
+    poc->xscom_ops = &pnv_occ_power9_xscom_ops;
+    poc->psi_irq = PSIHB9_IRQ_OCC;
+}
+
+static const TypeInfo pnv_occ_power9_type_info = {
+    .name          = TYPE_PNV9_OCC,
+    .parent        = TYPE_PNV_OCC,
+    .instance_size = sizeof(PnvOCC),
+    .class_init    = pnv_occ_power9_class_init,
+};
+
 static void pnv_occ_realize(DeviceState *dev, Error **errp)
 {
     PnvOCC *occ = PNV_OCC(dev);
@@ -152,6 +223,7 @@ static void pnv_occ_register_types(void)
 {
     type_register_static(&pnv_occ_type_info);
     type_register_static(&pnv_occ_power8_type_info);
+    type_register_static(&pnv_occ_power9_type_info);
 }
 
 type_init(pnv_occ_register_types);
-- 
2.20.1

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

* [Qemu-devel] [PATCH v2 10/15] ppc/pnv: extend XSCOM core support for POWER9
  2019-03-07 22:35 [Qemu-devel] [PATCH v2 00/15] ppc: add POWER9 support to the PowerNV platform Cédric Le Goater
                   ` (8 preceding siblings ...)
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 09/15] ppc/pnv: add a OCC model for POWER9 Cédric Le Goater
@ 2019-03-07 22:35 ` Cédric Le Goater
  2019-03-08  0:31   ` David Gibson
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 11/15] ppc/pnv: POWER9 XSCOM quad support Cédric Le Goater
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Cédric Le Goater @ 2019-03-07 22:35 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

Provide a new class attribute to define XSCOM operations per CPU
family and add a couple of XSCOM addresses controlling the power
management states of the core on POWER9.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---

 Changes in v2 :

 - new class attribute to define XSCOM operations per CPU family

 include/hw/ppc/pnv_core.h |   2 +
 hw/ppc/pnv_core.c         | 100 +++++++++++++++++++++++++++++++++-----
 2 files changed, 89 insertions(+), 13 deletions(-)

diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h
index 6874bb847a01..cbe9ad36f32c 100644
--- a/include/hw/ppc/pnv_core.h
+++ b/include/hw/ppc/pnv_core.h
@@ -42,6 +42,8 @@ typedef struct PnvCore {
 
 typedef struct PnvCoreClass {
     DeviceClass parent_class;
+
+    const MemoryRegionOps *xscom_ops;
 } PnvCoreClass;
 
 #define PNV_CORE_TYPE_SUFFIX "-" TYPE_PNV_CORE
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 38179cdc53dc..171474e0805c 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -60,8 +60,8 @@ static void pnv_cpu_reset(void *opaque)
 #define PNV_XSCOM_EX_DTS_RESULT0     0x50000
 #define PNV_XSCOM_EX_DTS_RESULT1     0x50001
 
-static uint64_t pnv_core_xscom_read(void *opaque, hwaddr addr,
-                                    unsigned int width)
+static uint64_t pnv_core_power8_xscom_read(void *opaque, hwaddr addr,
+                                           unsigned int width)
 {
     uint32_t offset = addr >> 3;
     uint64_t val = 0;
@@ -82,16 +82,74 @@ static uint64_t pnv_core_xscom_read(void *opaque, hwaddr addr,
     return val;
 }
 
-static void pnv_core_xscom_write(void *opaque, hwaddr addr, uint64_t val,
-                                 unsigned int width)
+static void pnv_core_power8_xscom_write(void *opaque, hwaddr addr, uint64_t val,
+                                        unsigned int width)
 {
     qemu_log_mask(LOG_UNIMP, "Warning: writing to reg=0x%" HWADDR_PRIx "\n",
                   addr);
 }
 
-static const MemoryRegionOps pnv_core_xscom_ops = {
-    .read = pnv_core_xscom_read,
-    .write = pnv_core_xscom_write,
+static const MemoryRegionOps pnv_core_power8_xscom_ops = {
+    .read = pnv_core_power8_xscom_read,
+    .write = pnv_core_power8_xscom_write,
+    .valid.min_access_size = 8,
+    .valid.max_access_size = 8,
+    .impl.min_access_size = 8,
+    .impl.max_access_size = 8,
+    .endianness = DEVICE_BIG_ENDIAN,
+};
+
+
+/*
+ * POWER9 core controls
+ */
+#define PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_HYP 0xf010d
+#define PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_OTR 0xf010a
+
+static uint64_t pnv_core_power9_xscom_read(void *opaque, hwaddr addr,
+                                           unsigned int width)
+{
+    uint32_t offset = addr >> 3;
+    uint64_t val = 0;
+
+    /* The result should be 38 C */
+    switch (offset) {
+    case PNV_XSCOM_EX_DTS_RESULT0:
+        val = 0x26f024f023f0000ull;
+        break;
+    case PNV_XSCOM_EX_DTS_RESULT1:
+        val = 0x24f000000000000ull;
+        break;
+    case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_HYP:
+    case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_OTR:
+        val = 0x0;
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "Warning: reading reg=0x%" HWADDR_PRIx "\n",
+                  addr);
+    }
+
+    return val;
+}
+
+static void pnv_core_power9_xscom_write(void *opaque, hwaddr addr, uint64_t val,
+                                        unsigned int width)
+{
+    uint32_t offset = addr >> 3;
+
+    switch (offset) {
+    case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_HYP:
+    case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_OTR:
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "Warning: writing to reg=0x%" HWADDR_PRIx "\n",
+                      addr);
+    }
+}
+
+static const MemoryRegionOps pnv_core_power9_xscom_ops = {
+    .read = pnv_core_power9_xscom_read,
+    .write = pnv_core_power9_xscom_write,
     .valid.min_access_size = 8,
     .valid.max_access_size = 8,
     .impl.min_access_size = 8,
@@ -138,6 +196,7 @@ static void pnv_realize_vcpu(PowerPCCPU *cpu, PnvChip *chip, Error **errp)
 static void pnv_core_realize(DeviceState *dev, Error **errp)
 {
     PnvCore *pc = PNV_CORE(OBJECT(dev));
+    PnvCoreClass *pcc = PNV_CORE_GET_CLASS(pc);
     CPUCore *cc = CPU_CORE(OBJECT(dev));
     const char *typename = pnv_core_cpu_typename(pc);
     Error *local_err = NULL;
@@ -180,7 +239,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
     }
 
     snprintf(name, sizeof(name), "xscom-core.%d", cc->core_id);
-    pnv_xscom_region_init(&pc->xscom_regs, OBJECT(dev), &pnv_core_xscom_ops,
+    pnv_xscom_region_init(&pc->xscom_regs, OBJECT(dev), pcc->xscom_ops,
                           pc, name, PNV_XSCOM_EX_SIZE);
     return;
 
@@ -222,6 +281,20 @@ static Property pnv_core_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
+static void pnv_core_power8_class_init(ObjectClass *oc, void *data)
+{
+    PnvCoreClass *pcc = PNV_CORE_CLASS(oc);
+
+    pcc->xscom_ops = &pnv_core_power8_xscom_ops;
+}
+
+static void pnv_core_power9_class_init(ObjectClass *oc, void *data)
+{
+    PnvCoreClass *pcc = PNV_CORE_CLASS(oc);
+
+    pcc->xscom_ops = &pnv_core_power9_xscom_ops;
+}
+
 static void pnv_core_class_init(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
@@ -231,10 +304,11 @@ static void pnv_core_class_init(ObjectClass *oc, void *data)
     dc->props = pnv_core_properties;
 }
 
-#define DEFINE_PNV_CORE_TYPE(cpu_model)         \
+#define DEFINE_PNV_CORE_TYPE(family, cpu_model) \
     {                                           \
         .parent = TYPE_PNV_CORE,                \
         .name = PNV_CORE_TYPE_NAME(cpu_model),  \
+        .class_init = pnv_core_##family##_class_init, \
     }
 
 static const TypeInfo pnv_core_infos[] = {
@@ -246,10 +320,10 @@ static const TypeInfo pnv_core_infos[] = {
         .class_init = pnv_core_class_init,
         .abstract       = true,
     },
-    DEFINE_PNV_CORE_TYPE("power8e_v2.1"),
-    DEFINE_PNV_CORE_TYPE("power8_v2.0"),
-    DEFINE_PNV_CORE_TYPE("power8nvl_v1.0"),
-    DEFINE_PNV_CORE_TYPE("power9_v2.0"),
+    DEFINE_PNV_CORE_TYPE(power8, "power8e_v2.1"),
+    DEFINE_PNV_CORE_TYPE(power8, "power8_v2.0"),
+    DEFINE_PNV_CORE_TYPE(power8, "power8nvl_v1.0"),
+    DEFINE_PNV_CORE_TYPE(power9, "power9_v2.0"),
 };
 
 DEFINE_TYPES(pnv_core_infos)
-- 
2.20.1

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

* [Qemu-devel] [PATCH v2 11/15] ppc/pnv: POWER9 XSCOM quad support
  2019-03-07 22:35 [Qemu-devel] [PATCH v2 00/15] ppc: add POWER9 support to the PowerNV platform Cédric Le Goater
                   ` (9 preceding siblings ...)
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 10/15] ppc/pnv: extend XSCOM core support " Cédric Le Goater
@ 2019-03-07 22:35 ` Cédric Le Goater
  2019-03-08  0:32   ` David Gibson
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 12/15] ppc/pnv: activate XSCOM tests for POWER9 Cédric Le Goater
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Cédric Le Goater @ 2019-03-07 22:35 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

The POWER9 processor does not support per-core frequency control. The
cores are arranged in groups of four, along with their respective L2
and L3 caches, into a structure known as a Quad. The frequency must be
managed at the Quad level.

Provide a basic Quad model to fake the settings done by the firmware
on the Non-Cacheable Unit (NCU). Each core pair (EX) needs a special
BAR setting for the TIMA area of XIVE because it resides on the same
address on all chips.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/pnv.h       |  4 ++
 include/hw/ppc/pnv_core.h  | 10 +++++
 include/hw/ppc/pnv_xscom.h | 12 ++++--
 hw/ppc/pnv.c               | 38 ++++++++++++++++-
 hw/ppc/pnv_core.c          | 87 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 146 insertions(+), 5 deletions(-)

diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 39888f9d52c1..e5b00d373ed2 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -26,6 +26,7 @@
 #include "hw/ppc/pnv_psi.h"
 #include "hw/ppc/pnv_occ.h"
 #include "hw/ppc/pnv_xive.h"
+#include "hw/ppc/pnv_core.h"
 
 #define TYPE_PNV_CHIP "pnv-chip"
 #define PNV_CHIP(obj) OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP)
@@ -89,6 +90,9 @@ typedef struct Pnv9Chip {
     Pnv9Psi      psi;
     PnvLpcController lpc;
     PnvOCC       occ;
+
+    uint32_t     nr_quads;
+    PnvQuad      *quads;
 } Pnv9Chip;
 
 typedef struct PnvChipClass {
diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h
index cbe9ad36f32c..50cdb2b35838 100644
--- a/include/hw/ppc/pnv_core.h
+++ b/include/hw/ppc/pnv_core.h
@@ -58,4 +58,14 @@ static inline PnvCPUState *pnv_cpu_state(PowerPCCPU *cpu)
     return (PnvCPUState *)cpu->machine_data;
 }
 
+#define TYPE_PNV_QUAD "powernv-cpu-quad"
+#define PNV_QUAD(obj) \
+    OBJECT_CHECK(PnvQuad, (obj), TYPE_PNV_QUAD)
+
+typedef struct PnvQuad {
+    DeviceState parent_obj;
+
+    uint32_t id;
+    MemoryRegion xscom_regs;
+} PnvQuad;
 #endif /* _PPC_PNV_CORE_H */
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index 3292459fbb78..68dfae0dfe41 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -60,10 +60,6 @@ typedef struct PnvXScomInterfaceClass {
     (PNV_XSCOM_EX_CORE_BASE | ((uint64_t)(core) << 24))
 #define PNV_XSCOM_EX_SIZE         0x100000
 
-#define PNV_XSCOM_P9_EC_BASE(core) \
-    ((uint64_t)(((core) & 0x1F) + 0x20) << 24)
-#define PNV_XSCOM_P9_EC_SIZE      0x100000
-
 #define PNV_XSCOM_LPC_BASE        0xb0020
 #define PNV_XSCOM_LPC_SIZE        0x4
 
@@ -73,6 +69,14 @@ typedef struct PnvXScomInterfaceClass {
 #define PNV_XSCOM_OCC_BASE        0x0066000
 #define PNV_XSCOM_OCC_SIZE        0x6000
 
+#define PNV9_XSCOM_EC_BASE(core) \
+    ((uint64_t)(((core) & 0x1F) + 0x20) << 24)
+#define PNV9_XSCOM_EC_SIZE        0x100000
+
+#define PNV9_XSCOM_EQ_BASE(core) \
+    ((uint64_t)(((core) & 0x1C) + 0x40) << 22)
+#define PNV9_XSCOM_EQ_SIZE        0x100000
+
 #define PNV9_XSCOM_OCC_BASE       PNV_XSCOM_OCC_BASE
 #define PNV9_XSCOM_OCC_SIZE       0x8000
 
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 1559a733235b..e68d419203e8 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -963,6 +963,36 @@ static void pnv_chip_power9_instance_init(Object *obj)
                                    OBJECT(&chip9->psi), &error_abort);
 }
 
+static void pnv_chip_quad_realize(Pnv9Chip *chip9, Error **errp)
+{
+    PnvChip *chip = PNV_CHIP(chip9);
+    const char *typename = pnv_chip_core_typename(chip);
+    size_t typesize = object_type_get_instance_size(typename);
+    int i;
+
+    chip9->nr_quads = DIV_ROUND_UP(chip->nr_cores, 4);
+    chip9->quads = g_new0(PnvQuad, chip9->nr_quads);
+
+    for (i = 0; i < chip9->nr_quads; i++) {
+        char eq_name[32];
+        PnvQuad *eq = &chip9->quads[i];
+        PnvCore *pnv_core = PNV_CORE(chip->cores + (i * 4) * typesize);
+        int core_id = CPU_CORE(pnv_core)->core_id;
+
+        object_initialize(eq, sizeof(*eq), TYPE_PNV_QUAD);
+        snprintf(eq_name, sizeof(eq_name), "eq[%d]", core_id);
+
+        object_property_add_child(OBJECT(chip), eq_name, OBJECT(eq),
+                                  &error_fatal);
+        object_property_set_int(OBJECT(eq), core_id, "id", &error_fatal);
+        object_property_set_bool(OBJECT(eq), true, "realized", &error_fatal);
+        object_unref(OBJECT(eq));
+
+        pnv_xscom_add_subregion(chip, PNV9_XSCOM_EQ_BASE(eq->id),
+                                &eq->xscom_regs);
+    }
+}
+
 static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
 {
     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
@@ -977,6 +1007,12 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
         return;
     }
 
+    pnv_chip_quad_realize(chip9, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
     /* XIVE interrupt controller (POWER9) */
     object_property_set_int(OBJECT(&chip9->xive), PNV9_XIVE_IC_BASE(chip),
                             "ic-bar", &error_fatal);
@@ -1135,7 +1171,7 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
         if (!pnv_chip_is_power9(chip)) {
             xscom_core_base = PNV_XSCOM_EX_BASE(core_hwid);
         } else {
-            xscom_core_base = PNV_XSCOM_P9_EC_BASE(core_hwid);
+            xscom_core_base = PNV9_XSCOM_EC_BASE(core_hwid);
         }
 
         pnv_xscom_add_subregion(chip, xscom_core_base,
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 171474e0805c..5feeed6bc463 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -327,3 +327,90 @@ static const TypeInfo pnv_core_infos[] = {
 };
 
 DEFINE_TYPES(pnv_core_infos)
+
+/*
+ * POWER9 Quads
+ */
+
+#define P9X_EX_NCU_SPEC_BAR                     0x11010
+
+static uint64_t pnv_quad_xscom_read(void *opaque, hwaddr addr,
+                                    unsigned int width)
+{
+    uint32_t offset = addr >> 3;
+    uint64_t val = -1;
+
+    switch (offset) {
+    case P9X_EX_NCU_SPEC_BAR:
+    case P9X_EX_NCU_SPEC_BAR + 0x400: /* Second EX */
+        val = 0;
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "%s: writing @0x%08x\n", __func__,
+                      offset);
+    }
+
+    return val;
+}
+
+static void pnv_quad_xscom_write(void *opaque, hwaddr addr, uint64_t val,
+                                 unsigned int width)
+{
+    uint32_t offset = addr >> 3;
+
+    switch (offset) {
+    case P9X_EX_NCU_SPEC_BAR:
+    case P9X_EX_NCU_SPEC_BAR + 0x400: /* Second EX */
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "%s: writing @0x%08x\n", __func__,
+                  offset);
+    }
+}
+
+static const MemoryRegionOps pnv_quad_xscom_ops = {
+    .read = pnv_quad_xscom_read,
+    .write = pnv_quad_xscom_write,
+    .valid.min_access_size = 8,
+    .valid.max_access_size = 8,
+    .impl.min_access_size = 8,
+    .impl.max_access_size = 8,
+    .endianness = DEVICE_BIG_ENDIAN,
+};
+
+static void pnv_quad_realize(DeviceState *dev, Error **errp)
+{
+    PnvQuad *eq = PNV_QUAD(dev);
+    char name[32];
+
+    snprintf(name, sizeof(name), "xscom-quad.%d", eq->id);
+    pnv_xscom_region_init(&eq->xscom_regs, OBJECT(dev), &pnv_quad_xscom_ops,
+                          eq, name, PNV9_XSCOM_EQ_SIZE);
+}
+
+static Property pnv_quad_properties[] = {
+    DEFINE_PROP_UINT32("id", PnvQuad, id, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void pnv_quad_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = pnv_quad_realize;
+    dc->props = pnv_quad_properties;
+}
+
+static const TypeInfo pnv_quad_info = {
+    .name          = TYPE_PNV_QUAD,
+    .parent        = TYPE_DEVICE,
+    .instance_size = sizeof(PnvQuad),
+    .class_init    = pnv_quad_class_init,
+};
+
+static void pnv_core_register_types(void)
+{
+    type_register_static(&pnv_quad_info);
+}
+
+type_init(pnv_core_register_types)
-- 
2.20.1

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

* [Qemu-devel] [PATCH v2 12/15] ppc/pnv: activate XSCOM tests for POWER9
  2019-03-07 22:35 [Qemu-devel] [PATCH v2 00/15] ppc: add POWER9 support to the PowerNV platform Cédric Le Goater
                   ` (10 preceding siblings ...)
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 11/15] ppc/pnv: POWER9 XSCOM quad support Cédric Le Goater
@ 2019-03-07 22:35 ` Cédric Le Goater
  2019-03-08  0:33   ` David Gibson
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 13/15] ppc/pnv: add more dummy XSCOM addresses Cédric Le Goater
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Cédric Le Goater @ 2019-03-07 22:35 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

We now have enough support to let the XSCOM test run on POWER9.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 tests/pnv-xscom-test.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/tests/pnv-xscom-test.c b/tests/pnv-xscom-test.c
index 974f8da5b240..63d464048d53 100644
--- a/tests/pnv-xscom-test.c
+++ b/tests/pnv-xscom-test.c
@@ -39,7 +39,6 @@ static const PnvChip pnv_chips[] = {
         .cfam_id    = 0x120d304980000000ull,
         .first_core = 0x1,
     },
-#if 0 /* POWER9 support is not ready yet */
     {
         .chip_type  = PNV_CHIP_POWER9,
         .cpu_model  = "POWER9",
@@ -47,7 +46,6 @@ static const PnvChip pnv_chips[] = {
         .cfam_id    = 0x220d104900008000ull,
         .first_core = 0x0,
     },
-#endif
 };
 
 static uint64_t pnv_xscom_addr(const PnvChip *chip, uint32_t pcba)
-- 
2.20.1

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

* [Qemu-devel] [PATCH v2 13/15] ppc/pnv: add more dummy XSCOM addresses
  2019-03-07 22:35 [Qemu-devel] [PATCH v2 00/15] ppc: add POWER9 support to the PowerNV platform Cédric Le Goater
                   ` (11 preceding siblings ...)
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 12/15] ppc/pnv: activate XSCOM tests for POWER9 Cédric Le Goater
@ 2019-03-07 22:35 ` Cédric Le Goater
  2019-03-08  0:56   ` David Gibson
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 14/15] ppc/pnv: add a "ibm, opal/power-mgt" device tree node on POWER9 Cédric Le Goater
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 15/15] target/ppc: add HV support for POWER9 Cédric Le Goater
  14 siblings, 1 reply; 33+ messages in thread
From: Cédric Le Goater @ 2019-03-07 22:35 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

To improve OPAL/skiboot support. We don't need to strictly model these
XSCOM accesses.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/pnv_xscom.c | 33 +++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c
index 46fae41f32b0..c285ef514e88 100644
--- a/hw/ppc/pnv_xscom.c
+++ b/hw/ppc/pnv_xscom.c
@@ -64,11 +64,21 @@ static uint64_t xscom_read_default(PnvChip *chip, uint32_t pcba)
     switch (pcba) {
     case 0xf000f:
         return PNV_CHIP_GET_CLASS(chip)->chip_cfam_id;
+    case 0x18002:       /* ECID2 */
+        return 0;
+
     case 0x1010c00:     /* PIBAM FIR */
     case 0x1010c03:     /* PIBAM FIR MASK */
-    case 0x2020007:     /* ADU stuff */
-    case 0x2020009:     /* ADU stuff */
-    case 0x202000f:     /* ADU stuff */
+
+        /* P9 xscom reset */
+    case 0x0090018:     /* Receive status reg */
+    case 0x0090012:     /* log register */
+    case 0x0090013:     /* error register */
+
+        /* P8 xscom reset */
+    case 0x2020007:     /* ADU stuff, log register */
+    case 0x2020009:     /* ADU stuff, error register */
+    case 0x202000f:     /* ADU stuff, receive status register*/
         return 0;
     case 0x2013f00:     /* PBA stuff */
     case 0x2013f01:     /* PBA stuff */
@@ -100,9 +110,20 @@ static bool xscom_write_default(PnvChip *chip, uint32_t pcba, uint64_t val)
     case 0x1010c03:     /* PIBAM FIR MASK */
     case 0x1010c04:     /* PIBAM FIR MASK */
     case 0x1010c05:     /* PIBAM FIR MASK */
-    case 0x2020007:     /* ADU stuff */
-    case 0x2020009:     /* ADU stuff */
-    case 0x202000f:     /* ADU stuff */
+        /* P9 xscom reset */
+    case 0x0090018:     /* Receive status reg */
+    case 0x0090012:     /* log register */
+    case 0x0090013:     /* error register */
+
+        /* P8 xscom reset */
+    case 0x2020007:     /* ADU stuff, log register */
+    case 0x2020009:     /* ADU stuff, error register */
+    case 0x202000f:     /* ADU stuff, receive status register*/
+
+    case 0x2013028:     /* CAPP stuff */
+    case 0x201302a:     /* CAPP stuff */
+    case 0x2013801:     /* CAPP stuff */
+    case 0x2013802:     /* CAPP stuff */
         return true;
     default:
         return false;
-- 
2.20.1

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

* [Qemu-devel] [PATCH v2 14/15] ppc/pnv: add a "ibm, opal/power-mgt" device tree node on POWER9
  2019-03-07 22:35 [Qemu-devel] [PATCH v2 00/15] ppc: add POWER9 support to the PowerNV platform Cédric Le Goater
                   ` (12 preceding siblings ...)
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 13/15] ppc/pnv: add more dummy XSCOM addresses Cédric Le Goater
@ 2019-03-07 22:35 ` Cédric Le Goater
  2019-03-08  0:58   ` David Gibson
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 15/15] target/ppc: add HV support for POWER9 Cédric Le Goater
  14 siblings, 1 reply; 33+ messages in thread
From: Cédric Le Goater @ 2019-03-07 22:35 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

Activate only stop0 and stop1 levels. We should not need more levels
when under QEMU.

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

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index e68d419203e8..8be4d4cbf785 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -438,6 +438,16 @@ static void pnv_dt_isa(PnvMachineState *pnv, void *fdt)
                        &args);
 }
 
+static void pnv_dt_power_mgt(void *fdt)
+{
+    int off;
+
+    off = fdt_add_subnode(fdt, 0, "ibm,opal");
+    off = fdt_add_subnode(fdt, off, "power-mgt");
+
+    _FDT(fdt_setprop_cell(fdt, off, "ibm,enabled-stop-levels", 0xc0000000));
+}
+
 static void *pnv_dt_create(MachineState *machine)
 {
     const char plat_compat[] = "qemu,powernv\0ibm,powernv";
@@ -493,6 +503,11 @@ static void *pnv_dt_create(MachineState *machine)
         pnv_dt_bmc_sensors(pnv->bmc, fdt);
     }
 
+    /* Create an extra node for power management on Power9 */
+    if (pnv_is_power9(pnv)) {
+        pnv_dt_power_mgt(fdt);
+    }
+
     return fdt;
 }
 
-- 
2.20.1

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

* [Qemu-devel] [PATCH v2 15/15] target/ppc: add HV support for POWER9
  2019-03-07 22:35 [Qemu-devel] [PATCH v2 00/15] ppc: add POWER9 support to the PowerNV platform Cédric Le Goater
                   ` (13 preceding siblings ...)
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 14/15] ppc/pnv: add a "ibm, opal/power-mgt" device tree node on POWER9 Cédric Le Goater
@ 2019-03-07 22:35 ` Cédric Le Goater
  2019-03-08  0:59   ` David Gibson
  14 siblings, 1 reply; 33+ messages in thread
From: Cédric Le Goater @ 2019-03-07 22:35 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Cédric Le Goater

We now have enough support to boot a PowerNV machine with a POWER9
processor. Allow HV mode on POWER9.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 target/ppc/translate_init.inc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index af70a3b78c9a..0bd555eb1913 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -8895,7 +8895,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBSYNC |
-                       PPC_64B | PPC_64BX | PPC_ALTIVEC |
+                       PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
                        PPC_SEGMENT_64B | PPC_SLBI |
                        PPC_POPCNTB | PPC_POPCNTWD |
                        PPC_CILDST;
@@ -8907,6 +8907,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
                         PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
                         PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL;
     pcc->msr_mask = (1ull << MSR_SF) |
+                    (1ull << MSR_SHV) |
                     (1ull << MSR_TM) |
                     (1ull << MSR_VR) |
                     (1ull << MSR_VSX) |
-- 
2.20.1

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

* Re: [Qemu-devel] [PATCH v2 01/15] ppc/pnv: add a PSI bridge class model
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 01/15] ppc/pnv: add a PSI bridge class model Cédric Le Goater
@ 2019-03-07 23:57   ` David Gibson
  0 siblings, 0 replies; 33+ messages in thread
From: David Gibson @ 2019-03-07 23:57 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Mar 07, 2019 at 11:35:34PM +0100, Cédric Le Goater wrote:
> To ease the introduction of the PSI bridge model for POWER9, abstract
> the POWER chip differences in a PnvPsi class model and introduce a
> specific Pnv8Psi type for POWER8. POWER8 interface to the interrupt
> controller is still XICS whereas POWER9 uses the new XIVE model.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Applied, thanks.

> ---
> 
>  Changes in v2 :
> 
>  - introduced a Pnv8Psi (XICS) model
> 
>  include/hw/ppc/pnv.h     |  2 +-
>  include/hw/ppc/pnv_psi.h | 29 ++++++++++++++-
>  hw/ppc/pnv.c             |  6 ++-
>  hw/ppc/pnv_psi.c         | 79 ++++++++++++++++++++++++++++------------
>  4 files changed, 87 insertions(+), 29 deletions(-)
> 
> diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
> index eb4bba25b3e9..3b5f9cd53184 100644
> --- a/include/hw/ppc/pnv.h
> +++ b/include/hw/ppc/pnv.h
> @@ -71,7 +71,7 @@ typedef struct Pnv8Chip {
>      MemoryRegion icp_mmio;
>  
>      PnvLpcController lpc;
> -    PnvPsi       psi;
> +    Pnv8Psi      psi;
>      PnvOCC       occ;
>  } Pnv8Chip;
>  
> diff --git a/include/hw/ppc/pnv_psi.h b/include/hw/ppc/pnv_psi.h
> index 64ac73512e81..7087cbcb9ad7 100644
> --- a/include/hw/ppc/pnv_psi.h
> +++ b/include/hw/ppc/pnv_psi.h
> @@ -39,7 +39,6 @@ typedef struct PnvPsi {
>      uint64_t fsp_bar;
>  
>      /* Interrupt generation */
> -    ICSState ics;
>      qemu_irq *qirqs;
>  
>      /* Registers */
> @@ -48,6 +47,32 @@ typedef struct PnvPsi {
>      MemoryRegion xscom_regs;
>  } PnvPsi;
>  
> +#define TYPE_PNV8_PSI TYPE_PNV_PSI "-POWER8"
> +#define PNV8_PSI(obj) \
> +    OBJECT_CHECK(Pnv8Psi, (obj), TYPE_PNV8_PSI)
> +
> +typedef struct Pnv8Psi {
> +    PnvPsi   parent;
> +
> +    ICSState ics;
> +} Pnv8Psi;
> +
> +#define PNV_PSI_CLASS(klass) \
> +     OBJECT_CLASS_CHECK(PnvPsiClass, (klass), TYPE_PNV_PSI)
> +#define PNV_PSI_GET_CLASS(obj) \
> +     OBJECT_GET_CLASS(PnvPsiClass, (obj), TYPE_PNV_PSI)
> +
> +typedef struct PnvPsiClass {
> +    SysBusDeviceClass parent_class;
> +
> +    int chip_type;
> +    uint32_t xscom_pcba;
> +    uint32_t xscom_size;
> +    uint64_t bar_mask;
> +
> +    void (*irq_set)(PnvPsi *psi, int, bool state);
> +} PnvPsiClass;
> +
>  /* The PSI and FSP interrupts are muxed on the same IRQ number */
>  typedef enum PnvPsiIrq {
>      PSIHB_IRQ_PSI, /* internal use only */
> @@ -61,6 +86,6 @@ typedef enum PnvPsiIrq {
>  
>  #define PSI_NUM_INTERRUPTS 6
>  
> -extern void pnv_psi_irq_set(PnvPsi *psi, PnvPsiIrq irq, bool state);
> +void pnv_psi_irq_set(PnvPsi *psi, int irq, bool state);
>  
>  #endif /* _PPC_PNV_PSI_H */
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index 7660eaa22cf9..5bb2332f167a 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -788,7 +788,7 @@ static void pnv_chip_power8_instance_init(Object *obj)
>      Pnv8Chip *chip8 = PNV8_CHIP(obj);
>  
>      object_initialize_child(obj, "psi",  &chip8->psi, sizeof(chip8->psi),
> -                            TYPE_PNV_PSI, &error_abort, NULL);
> +                            TYPE_PNV8_PSI, &error_abort, NULL);
>      object_property_add_const_link(OBJECT(&chip8->psi), "xics",
>                                     OBJECT(qdev_get_machine()), &error_abort);
>  
> @@ -840,6 +840,7 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
>      PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
>      PnvChip *chip = PNV_CHIP(dev);
>      Pnv8Chip *chip8 = PNV8_CHIP(dev);
> +    Pnv8Psi *psi8 = &chip8->psi;
>      Error *local_err = NULL;
>  
>      pcc->parent_realize(dev, &local_err);
> @@ -856,7 +857,8 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
>          error_propagate(errp, local_err);
>          return;
>      }
> -    pnv_xscom_add_subregion(chip, PNV_XSCOM_PSIHB_BASE, &chip8->psi.xscom_regs);
> +    pnv_xscom_add_subregion(chip, PNV_XSCOM_PSIHB_BASE,
> +                            &PNV_PSI(psi8)->xscom_regs);
>  
>      /* Create LPC controller */
>      object_property_set_bool(OBJECT(&chip8->lpc), true, "realized",
> diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
> index e61861bfd3c6..067f733f1e4a 100644
> --- a/hw/ppc/pnv_psi.c
> +++ b/hw/ppc/pnv_psi.c
> @@ -118,10 +118,11 @@
>  
>  static void pnv_psi_set_bar(PnvPsi *psi, uint64_t bar)
>  {
> +    PnvPsiClass *ppc = PNV_PSI_GET_CLASS(psi);
>      MemoryRegion *sysmem = get_system_memory();
>      uint64_t old = psi->regs[PSIHB_XSCOM_BAR];
>  
> -    psi->regs[PSIHB_XSCOM_BAR] = bar & (PSIHB_BAR_MASK | PSIHB_BAR_EN);
> +    psi->regs[PSIHB_XSCOM_BAR] = bar & (ppc->bar_mask | PSIHB_BAR_EN);
>  
>      /* Update MR, always remove it first */
>      if (old & PSIHB_BAR_EN) {
> @@ -130,7 +131,7 @@ static void pnv_psi_set_bar(PnvPsi *psi, uint64_t bar)
>  
>      /* Then add it back if needed */
>      if (bar & PSIHB_BAR_EN) {
> -        uint64_t addr = bar & PSIHB_BAR_MASK;
> +        uint64_t addr = bar & ppc->bar_mask;
>          memory_region_add_subregion(sysmem, addr, &psi->regs_mr);
>      }
>  }
> @@ -154,7 +155,7 @@ static void pnv_psi_set_cr(PnvPsi *psi, uint64_t cr)
>  
>  static void pnv_psi_set_irsn(PnvPsi *psi, uint64_t val)
>  {
> -    ICSState *ics = &psi->ics;
> +    ICSState *ics = &PNV8_PSI(psi)->ics;
>  
>      /* In this model we ignore the up/down enable bits for now
>       * as SW doesn't use them (other than setting them at boot).
> @@ -207,7 +208,12 @@ static const uint64_t stat_bits[] = {
>      [PSIHB_IRQ_EXTERNAL]  = PSIHB_IRQ_STAT_EXT,
>  };
>  
> -void pnv_psi_irq_set(PnvPsi *psi, PnvPsiIrq irq, bool state)
> +void pnv_psi_irq_set(PnvPsi *psi, int irq, bool state)
> +{
> +    PNV_PSI_GET_CLASS(psi)->irq_set(psi, irq, state);
> +}
> +
> +static void pnv_psi_power8_irq_set(PnvPsi *psi, int irq, bool state)
>  {
>      uint32_t xivr_reg;
>      uint32_t stat_reg;
> @@ -262,7 +268,7 @@ void pnv_psi_irq_set(PnvPsi *psi, PnvPsiIrq irq, bool state)
>  
>  static void pnv_psi_set_xivr(PnvPsi *psi, uint32_t reg, uint64_t val)
>  {
> -    ICSState *ics = &psi->ics;
> +    ICSState *ics = &PNV8_PSI(psi)->ics;
>      uint16_t server;
>      uint8_t prio;
>      uint8_t src;
> @@ -451,11 +457,11 @@ static void pnv_psi_reset(void *dev)
>      psi->regs[PSIHB_XSCOM_BAR] = psi->bar | PSIHB_BAR_EN;
>  }
>  
> -static void pnv_psi_init(Object *obj)
> +static void pnv_psi_power8_instance_init(Object *obj)
>  {
> -    PnvPsi *psi = PNV_PSI(obj);
> +    Pnv8Psi *psi8 = PNV8_PSI(obj);
>  
> -    object_initialize_child(obj, "ics-psi",  &psi->ics, sizeof(psi->ics),
> +    object_initialize_child(obj, "ics-psi",  &psi8->ics, sizeof(psi8->ics),
>                              TYPE_ICS_SIMPLE, &error_abort, NULL);
>  }
>  
> @@ -468,10 +474,10 @@ static const uint8_t irq_to_xivr[] = {
>      PSIHB_XSCOM_XIVR_EXT,
>  };
>  
> -static void pnv_psi_realize(DeviceState *dev, Error **errp)
> +static void pnv_psi_power8_realize(DeviceState *dev, Error **errp)
>  {
>      PnvPsi *psi = PNV_PSI(dev);
> -    ICSState *ics = &psi->ics;
> +    ICSState *ics = &PNV8_PSI(psi)->ics;
>      Object *obj;
>      Error *err = NULL;
>      unsigned int i;
> @@ -524,28 +530,28 @@ static void pnv_psi_realize(DeviceState *dev, Error **errp)
>      qemu_register_reset(pnv_psi_reset, dev);
>  }
>  
> +static const char compat_p8[] = "ibm,power8-psihb-x\0ibm,psihb-x";
> +
>  static int pnv_psi_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
>  {
> -    const char compat[] = "ibm,power8-psihb-x\0ibm,psihb-x";
> +    PnvPsiClass *ppc = PNV_PSI_GET_CLASS(dev);
>      char *name;
>      int offset;
> -    uint32_t lpc_pcba = PNV_XSCOM_PSIHB_BASE;
>      uint32_t reg[] = {
> -        cpu_to_be32(lpc_pcba),
> -        cpu_to_be32(PNV_XSCOM_PSIHB_SIZE)
> +        cpu_to_be32(ppc->xscom_pcba),
> +        cpu_to_be32(ppc->xscom_size)
>      };
>  
> -    name = g_strdup_printf("psihb@%x", lpc_pcba);
> +    name = g_strdup_printf("psihb@%x", ppc->xscom_pcba);
>      offset = fdt_add_subnode(fdt, xscom_offset, name);
>      _FDT(offset);
>      g_free(name);
>  
> -    _FDT((fdt_setprop(fdt, offset, "reg", reg, sizeof(reg))));
> -
> -    _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 2)));
> -    _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 1)));
> -    _FDT((fdt_setprop(fdt, offset, "compatible", compat,
> -                      sizeof(compat))));
> +    _FDT(fdt_setprop(fdt, offset, "reg", reg, sizeof(reg)));
> +    _FDT(fdt_setprop_cell(fdt, offset, "#address-cells", 2));
> +    _FDT(fdt_setprop_cell(fdt, offset, "#size-cells", 1));
> +    _FDT(fdt_setprop(fdt, offset, "compatible", compat_p8,
> +                     sizeof(compat_p8)));
>      return 0;
>  }
>  
> @@ -555,6 +561,29 @@ static Property pnv_psi_properties[] = {
>      DEFINE_PROP_END_OF_LIST(),
>  };
>  
> +static void pnv_psi_power8_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    PnvPsiClass *ppc = PNV_PSI_CLASS(klass);
> +
> +    dc->desc    = "PowerNV PSI Controller POWER8";
> +    dc->realize = pnv_psi_power8_realize;
> +
> +    ppc->chip_type =  PNV_CHIP_POWER8;
> +    ppc->xscom_pcba = PNV_XSCOM_PSIHB_BASE;
> +    ppc->xscom_size = PNV_XSCOM_PSIHB_SIZE;
> +    ppc->bar_mask   = PSIHB_BAR_MASK;
> +    ppc->irq_set    = pnv_psi_power8_irq_set;
> +}
> +
> +static const TypeInfo pnv_psi_power8_info = {
> +    .name          = TYPE_PNV8_PSI,
> +    .parent        = TYPE_PNV_PSI,
> +    .instance_size = sizeof(Pnv8Psi),
> +    .instance_init = pnv_psi_power8_instance_init,
> +    .class_init    = pnv_psi_power8_class_init,
> +};
> +
>  static void pnv_psi_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -562,7 +591,7 @@ static void pnv_psi_class_init(ObjectClass *klass, void *data)
>  
>      xdc->dt_xscom = pnv_psi_dt_xscom;
>  
> -    dc->realize = pnv_psi_realize;
> +    dc->desc = "PowerNV PSI Controller";
>      dc->props = pnv_psi_properties;
>  }
>  
> @@ -570,8 +599,9 @@ static const TypeInfo pnv_psi_info = {
>      .name          = TYPE_PNV_PSI,
>      .parent        = TYPE_SYS_BUS_DEVICE,
>      .instance_size = sizeof(PnvPsi),
> -    .instance_init = pnv_psi_init,
>      .class_init    = pnv_psi_class_init,
> +    .class_size    = sizeof(PnvPsiClass),
> +    .abstract      = true,
>      .interfaces    = (InterfaceInfo[]) {
>          { TYPE_PNV_XSCOM_INTERFACE },
>          { }
> @@ -581,6 +611,7 @@ static const TypeInfo pnv_psi_info = {
>  static void pnv_psi_register_types(void)
>  {
>      type_register_static(&pnv_psi_info);
> +    type_register_static(&pnv_psi_power8_info);
>  }
>  
> -type_init(pnv_psi_register_types)
> +type_init(pnv_psi_register_types);

-- 
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] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v2 02/15] ppc/pnv: add a PSI bridge model for POWER9
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 02/15] ppc/pnv: add a PSI bridge model for POWER9 Cédric Le Goater
@ 2019-03-07 23:58   ` David Gibson
  0 siblings, 0 replies; 33+ messages in thread
From: David Gibson @ 2019-03-07 23:58 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Mar 07, 2019 at 11:35:35PM +0100, Cédric Le Goater wrote:
> The PSI bridge on POWER9 is very similar to POWER8. The BAR is still
> set through XSCOM but the controls are now entirely done with MMIOs.
> More interrupts are defined and the interrupt controller interface has
> changed to XIVE. The POWER9 model is a first example of the usage of
> the notify() handler of the XiveNotifier interface, linking the PSI
> XiveSource to its owning device model.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Applied, thanks.

> ---
> 
>  Changes in v2 :
>  
>   - introduced a Pnv9Psi (XIVE) model
>   
>  include/hw/ppc/pnv.h       |   6 +
>  include/hw/ppc/pnv_psi.h   |  30 ++++
>  include/hw/ppc/pnv_xscom.h |   3 +
>  hw/ppc/pnv.c               |  18 ++
>  hw/ppc/pnv_psi.c           | 329 ++++++++++++++++++++++++++++++++++++-
>  5 files changed, 384 insertions(+), 2 deletions(-)
> 
> diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
> index 3b5f9cd53184..8d80cb34eebb 100644
> --- a/include/hw/ppc/pnv.h
> +++ b/include/hw/ppc/pnv.h
> @@ -84,6 +84,7 @@ typedef struct Pnv9Chip {
>  
>      /*< public >*/
>      PnvXive      xive;
> +    Pnv9Psi      psi;
>  } Pnv9Chip;
>  
>  typedef struct PnvChipClass {
> @@ -231,11 +232,16 @@ void pnv_bmc_powerdown(IPMIBmc *bmc);
>  #define PNV9_XIVE_PC_SIZE            0x0000001000000000ull
>  #define PNV9_XIVE_PC_BASE(chip)      PNV9_CHIP_BASE(chip, 0x0006018000000000ull)
>  
> +#define PNV9_PSIHB_SIZE              0x0000000000100000ull
> +#define PNV9_PSIHB_BASE(chip)        PNV9_CHIP_BASE(chip, 0x0006030203000000ull)
> +
>  #define PNV9_XIVE_IC_SIZE            0x0000000000080000ull
>  #define PNV9_XIVE_IC_BASE(chip)      PNV9_CHIP_BASE(chip, 0x0006030203100000ull)
>  
>  #define PNV9_XIVE_TM_SIZE            0x0000000000040000ull
>  #define PNV9_XIVE_TM_BASE(chip)      PNV9_CHIP_BASE(chip, 0x0006030203180000ull)
>  
> +#define PNV9_PSIHB_ESB_SIZE          0x0000000000010000ull
> +#define PNV9_PSIHB_ESB_BASE(chip)    PNV9_CHIP_BASE(chip, 0x00060302031c0000ull)
>  
>  #endif /* _PPC_PNV_H */
> diff --git a/include/hw/ppc/pnv_psi.h b/include/hw/ppc/pnv_psi.h
> index 7087cbcb9ad7..2c1b27e865bd 100644
> --- a/include/hw/ppc/pnv_psi.h
> +++ b/include/hw/ppc/pnv_psi.h
> @@ -21,6 +21,7 @@
>  
>  #include "hw/sysbus.h"
>  #include "hw/ppc/xics.h"
> +#include "hw/ppc/xive.h"
>  
>  #define TYPE_PNV_PSI "pnv-psi"
>  #define PNV_PSI(obj) \
> @@ -57,6 +58,16 @@ typedef struct Pnv8Psi {
>      ICSState ics;
>  } Pnv8Psi;
>  
> +#define TYPE_PNV9_PSI TYPE_PNV_PSI "-POWER9"
> +#define PNV9_PSI(obj) \
> +    OBJECT_CHECK(Pnv9Psi, (obj), TYPE_PNV9_PSI)
> +
> +typedef struct Pnv9Psi {
> +    PnvPsi   parent;
> +
> +    XiveSource source;
> +} Pnv9Psi;
> +
>  #define PNV_PSI_CLASS(klass) \
>       OBJECT_CLASS_CHECK(PnvPsiClass, (klass), TYPE_PNV_PSI)
>  #define PNV_PSI_GET_CLASS(obj) \
> @@ -88,4 +99,23 @@ typedef enum PnvPsiIrq {
>  
>  void pnv_psi_irq_set(PnvPsi *psi, int irq, bool state);
>  
> +/* P9 PSI Interrupts */
> +#define PSIHB9_IRQ_PSI          0
> +#define PSIHB9_IRQ_OCC          1
> +#define PSIHB9_IRQ_FSI          2
> +#define PSIHB9_IRQ_LPCHC        3
> +#define PSIHB9_IRQ_LOCAL_ERR    4
> +#define PSIHB9_IRQ_GLOBAL_ERR   5
> +#define PSIHB9_IRQ_TPM          6
> +#define PSIHB9_IRQ_LPC_SIRQ0    7
> +#define PSIHB9_IRQ_LPC_SIRQ1    8
> +#define PSIHB9_IRQ_LPC_SIRQ2    9
> +#define PSIHB9_IRQ_LPC_SIRQ3    10
> +#define PSIHB9_IRQ_SBE_I2C      11
> +#define PSIHB9_IRQ_DIO          12
> +#define PSIHB9_IRQ_PSU          13
> +#define PSIHB9_NUM_IRQS         14
> +
> +void pnv_psi_pic_print_info(Pnv9Psi *psi, Monitor *mon);
> +
>  #endif /* _PPC_PNV_PSI_H */
> diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
> index 6623ec54a7a8..403a365ed274 100644
> --- a/include/hw/ppc/pnv_xscom.h
> +++ b/include/hw/ppc/pnv_xscom.h
> @@ -73,6 +73,9 @@ typedef struct PnvXScomInterfaceClass {
>  #define PNV_XSCOM_OCC_BASE        0x0066000
>  #define PNV_XSCOM_OCC_SIZE        0x6000
>  
> +#define PNV9_XSCOM_PSIHB_BASE     0x5012900
> +#define PNV9_XSCOM_PSIHB_SIZE     0x100
> +
>  #define PNV9_XSCOM_XIVE_BASE      0x5013000
>  #define PNV9_XSCOM_XIVE_SIZE      0x300
>  
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index 5bb2332f167a..1cc454cbbc27 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -579,6 +579,7 @@ static void pnv_chip_power9_pic_print_info(PnvChip *chip, Monitor *mon)
>      Pnv9Chip *chip9 = PNV9_CHIP(chip);
>  
>      pnv_xive_pic_print_info(&chip9->xive, mon);
> +    pnv_psi_pic_print_info(&chip9->psi, mon);
>  }
>  
>  static void pnv_init(MachineState *machine)
> @@ -950,6 +951,11 @@ static void pnv_chip_power9_instance_init(Object *obj)
>                              TYPE_PNV_XIVE, &error_abort, NULL);
>      object_property_add_const_link(OBJECT(&chip9->xive), "chip", obj,
>                                     &error_abort);
> +
> +    object_initialize_child(obj, "psi",  &chip9->psi, sizeof(chip9->psi),
> +                            TYPE_PNV9_PSI, &error_abort, NULL);
> +    object_property_add_const_link(OBJECT(&chip9->psi), "chip", obj,
> +                                   &error_abort);
>  }
>  
>  static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
> @@ -957,6 +963,7 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
>      PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
>      Pnv9Chip *chip9 = PNV9_CHIP(dev);
>      PnvChip *chip = PNV_CHIP(dev);
> +    Pnv9Psi *psi9 = &chip9->psi;
>      Error *local_err = NULL;
>  
>      pcc->parent_realize(dev, &local_err);
> @@ -982,6 +989,17 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
>      }
>      pnv_xscom_add_subregion(chip, PNV9_XSCOM_XIVE_BASE,
>                              &chip9->xive.xscom_regs);
> +
> +    /* Processor Service Interface (PSI) Host Bridge */
> +    object_property_set_int(OBJECT(&chip9->psi), PNV9_PSIHB_BASE(chip),
> +                            "bar", &error_fatal);
> +    object_property_set_bool(OBJECT(&chip9->psi), true, "realized", &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +    pnv_xscom_add_subregion(chip, PNV9_XSCOM_PSIHB_BASE,
> +                            &PNV_PSI(psi9)->xscom_regs);
>  }
>  
>  static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
> diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
> index 067f733f1e4a..5a923e41518d 100644
> --- a/hw/ppc/pnv_psi.c
> +++ b/hw/ppc/pnv_psi.c
> @@ -22,6 +22,7 @@
>  #include "target/ppc/cpu.h"
>  #include "qemu/log.h"
>  #include "qapi/error.h"
> +#include "monitor/monitor.h"
>  
>  #include "exec/address-spaces.h"
>  
> @@ -114,6 +115,9 @@
>  #define PSIHB_BAR_MASK                  0x0003fffffff00000ull
>  #define PSIHB_FSPBAR_MASK               0x0003ffff00000000ull
>  
> +#define PSIHB9_BAR_MASK                 0x00fffffffff00000ull
> +#define PSIHB9_FSPBAR_MASK              0x00ffffff00000000ull
> +
>  #define PSIHB_REG(addr) (((addr) >> 3) + PSIHB_XSCOM_BAR)
>  
>  static void pnv_psi_set_bar(PnvPsi *psi, uint64_t bar)
> @@ -531,6 +535,7 @@ static void pnv_psi_power8_realize(DeviceState *dev, Error **errp)
>  }
>  
>  static const char compat_p8[] = "ibm,power8-psihb-x\0ibm,psihb-x";
> +static const char compat_p9[] = "ibm,power9-psihb-x\0ibm,psihb-x";
>  
>  static int pnv_psi_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
>  {
> @@ -550,8 +555,13 @@ static int pnv_psi_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
>      _FDT(fdt_setprop(fdt, offset, "reg", reg, sizeof(reg)));
>      _FDT(fdt_setprop_cell(fdt, offset, "#address-cells", 2));
>      _FDT(fdt_setprop_cell(fdt, offset, "#size-cells", 1));
> -    _FDT(fdt_setprop(fdt, offset, "compatible", compat_p8,
> -                     sizeof(compat_p8)));
> +    if (ppc->chip_type == PNV_CHIP_POWER9) {
> +        _FDT(fdt_setprop(fdt, offset, "compatible", compat_p9,
> +                         sizeof(compat_p9)));
> +    } else {
> +        _FDT(fdt_setprop(fdt, offset, "compatible", compat_p8,
> +                         sizeof(compat_p8)));
> +    }
>      return 0;
>  }
>  
> @@ -584,6 +594,308 @@ static const TypeInfo pnv_psi_power8_info = {
>      .class_init    = pnv_psi_power8_class_init,
>  };
>  
> +
> +/* Common registers */
> +
> +#define PSIHB9_CR                       0x20
> +#define PSIHB9_SEMR                     0x28
> +
> +/* P9 registers */
> +
> +#define PSIHB9_INTERRUPT_CONTROL        0x58
> +#define   PSIHB9_IRQ_METHOD             PPC_BIT(0)
> +#define   PSIHB9_IRQ_RESET              PPC_BIT(1)
> +#define PSIHB9_ESB_CI_BASE              0x60
> +#define   PSIHB9_ESB_CI_VALID           1
> +#define PSIHB9_ESB_NOTIF_ADDR           0x68
> +#define   PSIHB9_ESB_NOTIF_VALID        1
> +#define PSIHB9_IVT_OFFSET               0x70
> +#define   PSIHB9_IVT_OFF_SHIFT          32
> +
> +#define PSIHB9_IRQ_LEVEL                0x78 /* assertion */
> +#define   PSIHB9_IRQ_LEVEL_PSI          PPC_BIT(0)
> +#define   PSIHB9_IRQ_LEVEL_OCC          PPC_BIT(1)
> +#define   PSIHB9_IRQ_LEVEL_FSI          PPC_BIT(2)
> +#define   PSIHB9_IRQ_LEVEL_LPCHC        PPC_BIT(3)
> +#define   PSIHB9_IRQ_LEVEL_LOCAL_ERR    PPC_BIT(4)
> +#define   PSIHB9_IRQ_LEVEL_GLOBAL_ERR   PPC_BIT(5)
> +#define   PSIHB9_IRQ_LEVEL_TPM          PPC_BIT(6)
> +#define   PSIHB9_IRQ_LEVEL_LPC_SIRQ1    PPC_BIT(7)
> +#define   PSIHB9_IRQ_LEVEL_LPC_SIRQ2    PPC_BIT(8)
> +#define   PSIHB9_IRQ_LEVEL_LPC_SIRQ3    PPC_BIT(9)
> +#define   PSIHB9_IRQ_LEVEL_LPC_SIRQ4    PPC_BIT(10)
> +#define   PSIHB9_IRQ_LEVEL_SBE_I2C      PPC_BIT(11)
> +#define   PSIHB9_IRQ_LEVEL_DIO          PPC_BIT(12)
> +#define   PSIHB9_IRQ_LEVEL_PSU          PPC_BIT(13)
> +#define   PSIHB9_IRQ_LEVEL_I2C_C        PPC_BIT(14)
> +#define   PSIHB9_IRQ_LEVEL_I2C_D        PPC_BIT(15)
> +#define   PSIHB9_IRQ_LEVEL_I2C_E        PPC_BIT(16)
> +#define   PSIHB9_IRQ_LEVEL_SBE          PPC_BIT(19)
> +
> +#define PSIHB9_IRQ_STAT                 0x80 /* P bit */
> +#define   PSIHB9_IRQ_STAT_PSI           PPC_BIT(0)
> +#define   PSIHB9_IRQ_STAT_OCC           PPC_BIT(1)
> +#define   PSIHB9_IRQ_STAT_FSI           PPC_BIT(2)
> +#define   PSIHB9_IRQ_STAT_LPCHC         PPC_BIT(3)
> +#define   PSIHB9_IRQ_STAT_LOCAL_ERR     PPC_BIT(4)
> +#define   PSIHB9_IRQ_STAT_GLOBAL_ERR    PPC_BIT(5)
> +#define   PSIHB9_IRQ_STAT_TPM           PPC_BIT(6)
> +#define   PSIHB9_IRQ_STAT_LPC_SIRQ1     PPC_BIT(7)
> +#define   PSIHB9_IRQ_STAT_LPC_SIRQ2     PPC_BIT(8)
> +#define   PSIHB9_IRQ_STAT_LPC_SIRQ3     PPC_BIT(9)
> +#define   PSIHB9_IRQ_STAT_LPC_SIRQ4     PPC_BIT(10)
> +#define   PSIHB9_IRQ_STAT_SBE_I2C       PPC_BIT(11)
> +#define   PSIHB9_IRQ_STAT_DIO           PPC_BIT(12)
> +#define   PSIHB9_IRQ_STAT_PSU           PPC_BIT(13)
> +
> +static void pnv_psi_notify(XiveNotifier *xf, uint32_t srcno)
> +{
> +    PnvPsi *psi = PNV_PSI(xf);
> +    uint64_t notif_port = psi->regs[PSIHB_REG(PSIHB9_ESB_NOTIF_ADDR)];
> +    bool valid = notif_port & PSIHB9_ESB_NOTIF_VALID;
> +    uint64_t notify_addr = notif_port & ~PSIHB9_ESB_NOTIF_VALID;
> +
> +    uint32_t offset =
> +        (psi->regs[PSIHB_REG(PSIHB9_IVT_OFFSET)] >> PSIHB9_IVT_OFF_SHIFT);
> +    uint64_t lisn = cpu_to_be64(offset + srcno);
> +
> +    if (valid) {
> +        cpu_physical_memory_write(notify_addr, &lisn, sizeof(lisn));
> +    }
> +}
> +
> +static uint64_t pnv_psi_p9_mmio_read(void *opaque, hwaddr addr, unsigned size)
> +{
> +    PnvPsi *psi = PNV_PSI(opaque);
> +    uint32_t reg = PSIHB_REG(addr);
> +    uint64_t val = -1;
> +
> +    switch (addr) {
> +    case PSIHB9_CR:
> +    case PSIHB9_SEMR:
> +        /* FSP stuff */
> +    case PSIHB9_INTERRUPT_CONTROL:
> +    case PSIHB9_ESB_CI_BASE:
> +    case PSIHB9_ESB_NOTIF_ADDR:
> +    case PSIHB9_IVT_OFFSET:
> +        val = psi->regs[reg];
> +        break;
> +    default:
> +        qemu_log_mask(LOG_GUEST_ERROR, "PSI: read at 0x%" PRIx64 "\n", addr);
> +    }
> +
> +    return val;
> +}
> +
> +static void pnv_psi_p9_mmio_write(void *opaque, hwaddr addr,
> +                                  uint64_t val, unsigned size)
> +{
> +    PnvPsi *psi = PNV_PSI(opaque);
> +    Pnv9Psi *psi9 = PNV9_PSI(psi);
> +    uint32_t reg = PSIHB_REG(addr);
> +    MemoryRegion *sysmem = get_system_memory();
> +
> +    switch (addr) {
> +    case PSIHB9_CR:
> +    case PSIHB9_SEMR:
> +        /* FSP stuff */
> +        break;
> +    case PSIHB9_INTERRUPT_CONTROL:
> +        if (val & PSIHB9_IRQ_RESET) {
> +            device_reset(DEVICE(&psi9->source));
> +        }
> +        psi->regs[reg] = val;
> +        break;
> +
> +    case PSIHB9_ESB_CI_BASE:
> +        if (!(val & PSIHB9_ESB_CI_VALID)) {
> +            if (psi->regs[reg] & PSIHB9_ESB_CI_VALID) {
> +                memory_region_del_subregion(sysmem, &psi9->source.esb_mmio);
> +            }
> +        } else {
> +            if (!(psi->regs[reg] & PSIHB9_ESB_CI_VALID)) {
> +                memory_region_add_subregion(sysmem,
> +                                        val & ~PSIHB9_ESB_CI_VALID,
> +                                        &psi9->source.esb_mmio);
> +            }
> +        }
> +        psi->regs[reg] = val;
> +        break;
> +
> +    case PSIHB9_ESB_NOTIF_ADDR:
> +        psi->regs[reg] = val;
> +        break;
> +    case PSIHB9_IVT_OFFSET:
> +        psi->regs[reg] = val;
> +        break;
> +    default:
> +        qemu_log_mask(LOG_GUEST_ERROR, "PSI: write at 0x%" PRIx64 "\n", addr);
> +    }
> +}
> +
> +static const MemoryRegionOps pnv_psi_p9_mmio_ops = {
> +    .read = pnv_psi_p9_mmio_read,
> +    .write = pnv_psi_p9_mmio_write,
> +    .endianness = DEVICE_BIG_ENDIAN,
> +    .valid = {
> +        .min_access_size = 8,
> +        .max_access_size = 8,
> +    },
> +    .impl = {
> +        .min_access_size = 8,
> +        .max_access_size = 8,
> +    },
> +};
> +
> +static uint64_t pnv_psi_p9_xscom_read(void *opaque, hwaddr addr, unsigned size)
> +{
> +    /* No read are expected */
> +    qemu_log_mask(LOG_GUEST_ERROR, "PSI: xscom read at 0x%" PRIx64 "\n", addr);
> +    return -1;
> +}
> +
> +static void pnv_psi_p9_xscom_write(void *opaque, hwaddr addr,
> +                                uint64_t val, unsigned size)
> +{
> +    PnvPsi *psi = PNV_PSI(opaque);
> +
> +    /* XSCOM is only used to set the PSIHB MMIO region */
> +    switch (addr >> 3) {
> +    case PSIHB_XSCOM_BAR:
> +        pnv_psi_set_bar(psi, val);
> +        break;
> +    default:
> +        qemu_log_mask(LOG_GUEST_ERROR, "PSI: xscom write at 0x%" PRIx64 "\n",
> +                      addr);
> +    }
> +}
> +
> +static const MemoryRegionOps pnv_psi_p9_xscom_ops = {
> +    .read = pnv_psi_p9_xscom_read,
> +    .write = pnv_psi_p9_xscom_write,
> +    .endianness = DEVICE_BIG_ENDIAN,
> +    .valid = {
> +        .min_access_size = 8,
> +        .max_access_size = 8,
> +    },
> +    .impl = {
> +        .min_access_size = 8,
> +        .max_access_size = 8,
> +    }
> +};
> +
> +static void pnv_psi_power9_irq_set(PnvPsi *psi, int irq, bool state)
> +{
> +    uint32_t irq_method = psi->regs[PSIHB_REG(PSIHB9_INTERRUPT_CONTROL)];
> +
> +    if (irq > PSIHB9_NUM_IRQS) {
> +        qemu_log_mask(LOG_GUEST_ERROR, "PSI: Unsupported irq %d\n", irq);
> +        return;
> +    }
> +
> +    if (irq_method & PSIHB9_IRQ_METHOD) {
> +        qemu_log_mask(LOG_GUEST_ERROR, "PSI: LSI IRQ method no supported\n");
> +        return;
> +    }
> +
> +    /* Update LSI levels */
> +    if (state) {
> +        psi->regs[PSIHB_REG(PSIHB9_IRQ_LEVEL)] |= PPC_BIT(irq);
> +    } else {
> +        psi->regs[PSIHB_REG(PSIHB9_IRQ_LEVEL)] &= ~PPC_BIT(irq);
> +    }
> +
> +    qemu_set_irq(psi->qirqs[irq], state);
> +}
> +
> +static void pnv_psi_power9_reset(void *dev)
> +{
> +    Pnv9Psi *psi = PNV9_PSI(dev);
> +
> +    pnv_psi_reset(dev);
> +
> +    if (memory_region_is_mapped(&psi->source.esb_mmio)) {
> +        memory_region_del_subregion(get_system_memory(), &psi->source.esb_mmio);
> +    }
> +}
> +
> +static void pnv_psi_power9_instance_init(Object *obj)
> +{
> +    Pnv9Psi *psi = PNV9_PSI(obj);
> +
> +    object_initialize_child(obj, "source", &psi->source, sizeof(psi->source),
> +                            TYPE_XIVE_SOURCE, &error_abort, NULL);
> +}
> +
> +static void pnv_psi_power9_realize(DeviceState *dev, Error **errp)
> +{
> +    PnvPsi *psi = PNV_PSI(dev);
> +    XiveSource *xsrc = &PNV9_PSI(psi)->source;
> +    Error *local_err = NULL;
> +    int i;
> +
> +    /* This is the only device with 4k ESB pages */
> +    object_property_set_int(OBJECT(xsrc), XIVE_ESB_4K, "shift",
> +                            &error_fatal);
> +    object_property_set_int(OBJECT(xsrc), PSIHB9_NUM_IRQS, "nr-irqs",
> +                            &error_fatal);
> +    object_property_add_const_link(OBJECT(xsrc), "xive", OBJECT(psi),
> +                                   &error_fatal);
> +    object_property_set_bool(OBJECT(xsrc), true, "realized", &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +
> +    for (i = 0; i < xsrc->nr_irqs; i++) {
> +        xive_source_irq_set_lsi(xsrc, i);
> +    }
> +
> +    psi->qirqs = qemu_allocate_irqs(xive_source_set_irq, xsrc, xsrc->nr_irqs);
> +
> +    /* XSCOM region for PSI registers */
> +    pnv_xscom_region_init(&psi->xscom_regs, OBJECT(dev), &pnv_psi_p9_xscom_ops,
> +                psi, "xscom-psi", PNV9_XSCOM_PSIHB_SIZE);
> +
> +    /* MMIO region for PSI registers */
> +    memory_region_init_io(&psi->regs_mr, OBJECT(dev), &pnv_psi_p9_mmio_ops, psi,
> +                          "psihb", PNV9_PSIHB_SIZE);
> +
> +    pnv_psi_set_bar(psi, psi->bar | PSIHB_BAR_EN);
> +
> +    qemu_register_reset(pnv_psi_power9_reset, dev);
> +}
> +
> +static void pnv_psi_power9_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    PnvPsiClass *ppc = PNV_PSI_CLASS(klass);
> +    XiveNotifierClass *xfc = XIVE_NOTIFIER_CLASS(klass);
> +
> +    dc->desc    = "PowerNV PSI Controller POWER9";
> +    dc->realize = pnv_psi_power9_realize;
> +
> +    ppc->chip_type  = PNV_CHIP_POWER9;
> +    ppc->xscom_pcba = PNV9_XSCOM_PSIHB_BASE;
> +    ppc->xscom_size = PNV9_XSCOM_PSIHB_SIZE;
> +    ppc->bar_mask   = PSIHB9_BAR_MASK;
> +    ppc->irq_set    = pnv_psi_power9_irq_set;
> +
> +    xfc->notify      = pnv_psi_notify;
> +}
> +
> +static const TypeInfo pnv_psi_power9_info = {
> +    .name          = TYPE_PNV9_PSI,
> +    .parent        = TYPE_PNV_PSI,
> +    .instance_size = sizeof(Pnv9Psi),
> +    .instance_init = pnv_psi_power9_instance_init,
> +    .class_init    = pnv_psi_power9_class_init,
> +    .interfaces = (InterfaceInfo[]) {
> +            { TYPE_XIVE_NOTIFIER },
> +            { },
> +    },
> +};
> +
>  static void pnv_psi_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> @@ -612,6 +924,19 @@ static void pnv_psi_register_types(void)
>  {
>      type_register_static(&pnv_psi_info);
>      type_register_static(&pnv_psi_power8_info);
> +    type_register_static(&pnv_psi_power9_info);
>  }
>  
>  type_init(pnv_psi_register_types);
> +
> +void pnv_psi_pic_print_info(Pnv9Psi *psi9, Monitor *mon)
> +{
> +    PnvPsi *psi = PNV_PSI(psi9);
> +
> +    uint32_t offset =
> +        (psi->regs[PSIHB_REG(PSIHB9_IVT_OFFSET)] >> PSIHB9_IVT_OFF_SHIFT);
> +
> +    monitor_printf(mon, "PSIHB Source %08x .. %08x\n",
> +                  offset, offset + psi9->source.nr_irqs - 1);
> +    xive_source_pic_print_info(&psi9->source, offset, mon);
> +}

-- 
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] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v2 03/15] ppc/pnv: lpc: fix OPB address ranges
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 03/15] ppc/pnv: lpc: fix OPB address ranges Cédric Le Goater
@ 2019-03-07 23:59   ` David Gibson
  0 siblings, 0 replies; 33+ messages in thread
From: David Gibson @ 2019-03-07 23:59 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Mar 07, 2019 at 11:35:36PM +0100, Cédric Le Goater wrote:
> The PowerNV LPC Controller exposes different sets of registers for
> each of the functional units it encompasses, among which the OPB
> (On-Chip Peripheral Bus) Master and Arbitrer and the LPC HOST
> Controller.
> 
> The mapping addresses of each register range are correct but the sizes
> are too large. Fix the sizes and define the OPB Arbitrer range to fill
> the gap between the OPB Master registers and the LPC HOST Controller
> registers.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Applied, thanks.

> ---
> 
>  Changes in v2 :
> 
>   - wrote a commit log
> 
>  hw/ppc/pnv_lpc.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
> index 9b18ce55e391..547be609cafe 100644
> --- a/hw/ppc/pnv_lpc.c
> +++ b/hw/ppc/pnv_lpc.c
> @@ -89,10 +89,11 @@ enum {
>  #define LPC_FW_OPB_SIZE         0x10000000
>  
>  #define LPC_OPB_REGS_OPB_ADDR   0xc0010000
> -#define LPC_OPB_REGS_OPB_SIZE   0x00002000
> +#define LPC_OPB_REGS_OPB_SIZE   0x00000060
> +#define LPC_OPB_REGS_OPBA_ADDR  0xc0011000
> +#define LPC_OPB_REGS_OPBA_SIZE  0x00000008
>  #define LPC_HC_REGS_OPB_ADDR    0xc0012000
> -#define LPC_HC_REGS_OPB_SIZE    0x00001000
> -
> +#define LPC_HC_REGS_OPB_SIZE    0x00000100
>  
>  static int pnv_lpc_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
>  {

-- 
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] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v2 04/15] ppc/pnv: add a LPC Controller class model
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 04/15] ppc/pnv: add a LPC Controller class model Cédric Le Goater
@ 2019-03-07 23:59   ` David Gibson
  0 siblings, 0 replies; 33+ messages in thread
From: David Gibson @ 2019-03-07 23:59 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Mar 07, 2019 at 11:35:37PM +0100, Cédric Le Goater wrote:
> It will ease the introduction of the LPC Controller model for POWER9.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

Applied, thanks.

> ---
>  include/hw/ppc/pnv_lpc.h | 15 +++++++
>  hw/ppc/pnv.c             |  2 +-
>  hw/ppc/pnv_lpc.c         | 85 ++++++++++++++++++++++++++++------------
>  3 files changed, 77 insertions(+), 25 deletions(-)
> 
> diff --git a/include/hw/ppc/pnv_lpc.h b/include/hw/ppc/pnv_lpc.h
> index d657489b07ce..f3f24419b19a 100644
> --- a/include/hw/ppc/pnv_lpc.h
> +++ b/include/hw/ppc/pnv_lpc.h
> @@ -24,6 +24,8 @@
>  #define TYPE_PNV_LPC "pnv-lpc"
>  #define PNV_LPC(obj) \
>       OBJECT_CHECK(PnvLpcController, (obj), TYPE_PNV_LPC)
> +#define TYPE_PNV8_LPC TYPE_PNV_LPC "-POWER8"
> +#define PNV8_LPC(obj) OBJECT_CHECK(PnvLpcController, (obj), TYPE_PNV8_LPC)
>  
>  typedef struct PnvLpcController {
>      DeviceState parent;
> @@ -70,6 +72,19 @@ typedef struct PnvLpcController {
>      PnvPsi *psi;
>  } PnvLpcController;
>  
> +#define PNV_LPC_CLASS(klass) \
> +     OBJECT_CLASS_CHECK(PnvLpcClass, (klass), TYPE_PNV_LPC)
> +#define PNV_LPC_GET_CLASS(obj) \
> +     OBJECT_GET_CLASS(PnvLpcClass, (obj), TYPE_PNV_LPC)
> +
> +typedef struct PnvLpcClass {
> +    DeviceClass parent_class;
> +
> +    int psi_irq;
> +
> +    DeviceRealize parent_realize;
> +} PnvLpcClass;
> +
>  ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp);
>  
>  #endif /* _PPC_PNV_LPC_H */
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index 1cc454cbbc27..922e3ec48bb5 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -794,7 +794,7 @@ static void pnv_chip_power8_instance_init(Object *obj)
>                                     OBJECT(qdev_get_machine()), &error_abort);
>  
>      object_initialize_child(obj, "lpc",  &chip8->lpc, sizeof(chip8->lpc),
> -                            TYPE_PNV_LPC, &error_abort, NULL);
> +                            TYPE_PNV8_LPC, &error_abort, NULL);
>      object_property_add_const_link(OBJECT(&chip8->lpc), "psi",
>                                     OBJECT(&chip8->psi), &error_abort);
>  
> diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
> index 547be609cafe..3c509a30a0af 100644
> --- a/hw/ppc/pnv_lpc.c
> +++ b/hw/ppc/pnv_lpc.c
> @@ -245,6 +245,7 @@ static const MemoryRegionOps pnv_lpc_xscom_ops = {
>  static void pnv_lpc_eval_irqs(PnvLpcController *lpc)
>  {
>      bool lpc_to_opb_irq = false;
> +    PnvLpcClass *plc = PNV_LPC_GET_CLASS(lpc);
>  
>      /* Update LPC controller to OPB line */
>      if (lpc->lpc_hc_irqser_ctrl & LPC_HC_IRQSER_EN) {
> @@ -267,7 +268,7 @@ static void pnv_lpc_eval_irqs(PnvLpcController *lpc)
>      lpc->opb_irq_stat |= lpc->opb_irq_input & lpc->opb_irq_mask;
>  
>      /* Reflect the interrupt */
> -    pnv_psi_irq_set(lpc->psi, PSIHB_IRQ_LPC_I2C, lpc->opb_irq_stat != 0);
> +    pnv_psi_irq_set(lpc->psi, plc->psi_irq, lpc->opb_irq_stat != 0);
>  }
>  
>  static uint64_t lpc_hc_read(void *opaque, hwaddr addr, unsigned size)
> @@ -419,11 +420,65 @@ static const MemoryRegionOps opb_master_ops = {
>      },
>  };
>  
> +static void pnv_lpc_power8_realize(DeviceState *dev, Error **errp)
> +{
> +    PnvLpcController *lpc = PNV_LPC(dev);
> +    PnvLpcClass *plc = PNV_LPC_GET_CLASS(dev);
> +    Error *local_err = NULL;
> +
> +    plc->parent_realize(dev, &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +
> +    /* P8 uses a XSCOM region for LPC registers */
> +    pnv_xscom_region_init(&lpc->xscom_regs, OBJECT(lpc),
> +                          &pnv_lpc_xscom_ops, lpc, "xscom-lpc",
> +                          PNV_XSCOM_LPC_SIZE);
> +}
> +
> +static void pnv_lpc_power8_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass);
> +    PnvLpcClass *plc = PNV_LPC_CLASS(klass);
> +
> +    dc->desc = "PowerNV LPC Controller POWER8";
> +
> +    xdc->dt_xscom = pnv_lpc_dt_xscom;
> +
> +    plc->psi_irq = PSIHB_IRQ_LPC_I2C;
> +
> +    device_class_set_parent_realize(dc, pnv_lpc_power8_realize,
> +                                    &plc->parent_realize);
> +}
> +
> +static const TypeInfo pnv_lpc_power8_info = {
> +    .name          = TYPE_PNV8_LPC,
> +    .parent        = TYPE_PNV_LPC,
> +    .instance_size = sizeof(PnvLpcController),
> +    .class_init    = pnv_lpc_power8_class_init,
> +    .interfaces = (InterfaceInfo[]) {
> +        { TYPE_PNV_XSCOM_INTERFACE },
> +        { }
> +    }
> +};
> +
>  static void pnv_lpc_realize(DeviceState *dev, Error **errp)
>  {
>      PnvLpcController *lpc = PNV_LPC(dev);
>      Object *obj;
> -    Error *error = NULL;
> +    Error *local_err = NULL;
> +
> +    obj = object_property_get_link(OBJECT(dev), "psi", &local_err);
> +    if (!obj) {
> +        error_propagate(errp, local_err);
> +        error_prepend(errp, "required link 'psi' not found: ");
> +        return;
> +    }
> +    /* The LPC controller needs PSI to generate interrupts  */
> +    lpc->psi = PNV_PSI(obj);
>  
>      /* Reg inits */
>      lpc->lpc_hc_fw_rd_acc_size = LPC_HC_FW_RD_4B;
> @@ -463,46 +518,28 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
>                            "lpc-hc", LPC_HC_REGS_OPB_SIZE);
>      memory_region_add_subregion(&lpc->opb_mr, LPC_HC_REGS_OPB_ADDR,
>                                  &lpc->lpc_hc_regs);
> -
> -    /* XScom region for LPC registers */
> -    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)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> -    PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass);
> -
> -    xdc->dt_xscom = pnv_lpc_dt_xscom;
>  
>      dc->realize = pnv_lpc_realize;
> +    dc->desc = "PowerNV LPC Controller";
>  }
>  
>  static const TypeInfo pnv_lpc_info = {
>      .name          = TYPE_PNV_LPC,
>      .parent        = TYPE_DEVICE,
> -    .instance_size = sizeof(PnvLpcController),
>      .class_init    = pnv_lpc_class_init,
> -    .interfaces = (InterfaceInfo[]) {
> -        { TYPE_PNV_XSCOM_INTERFACE },
> -        { }
> -    }
> +    .class_size    = sizeof(PnvLpcClass),
> +    .abstract      = true,
>  };
>  
>  static void pnv_lpc_register_types(void)
>  {
>      type_register_static(&pnv_lpc_info);
> +    type_register_static(&pnv_lpc_power8_info);
>  }
>  
>  type_init(pnv_lpc_register_types)

-- 
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] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/15] ppc/pnv: add a 'dt_isa_nodename' to the chip
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 05/15] ppc/pnv: add a 'dt_isa_nodename' to the chip Cédric Le Goater
@ 2019-03-08  0:01   ` David Gibson
  2019-03-08  6:55     ` Cédric Le Goater
  0 siblings, 1 reply; 33+ messages in thread
From: David Gibson @ 2019-03-08  0:01 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Mar 07, 2019 at 11:35:38PM +0100, Cédric Le Goater wrote:
> The ISA bus has a different DT nodename on POWER9. Compute the name
> when the PnvChip is realized, that is before it is used by the machine
> to populate the device tree with the ISA devices.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

I still tend to think that passing an offset into pnv_dt_isa would
have been a better solution, but this will serve.  Applied.

> ---
>  include/hw/ppc/pnv.h |  2 ++
>  hw/ppc/pnv.c         | 18 +++++-------------
>  2 files changed, 7 insertions(+), 13 deletions(-)
> 
> diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
> index 8d80cb34eebb..c81f157f41a9 100644
> --- a/include/hw/ppc/pnv.h
> +++ b/include/hw/ppc/pnv.h
> @@ -58,6 +58,8 @@ typedef struct PnvChip {
>      MemoryRegion xscom_mmio;
>      MemoryRegion xscom;
>      AddressSpace xscom_as;
> +
> +    gchar        *dt_isa_nodename;
>  } PnvChip;
>  
>  #define TYPE_PNV8_CHIP "pnv8-chip"
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index 922e3ec48bb5..6625562d276d 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -417,24 +417,12 @@ static int pnv_dt_isa_device(DeviceState *dev, void *opaque)
>      return 0;
>  }
>  
> -static int pnv_chip_isa_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;
> -}
> -
>  /* The default LPC bus of a multichip system is on chip 0. It's
>   * recognized by the firmware (skiboot) using a "primary" property.
>   */
>  static void pnv_dt_isa(PnvMachineState *pnv, void *fdt)
>  {
> -    int isa_offset = pnv_chip_isa_offset(pnv->chips[0], fdt);
> +    int isa_offset = fdt_path_offset(fdt, pnv->chips[0]->dt_isa_nodename);
>      ForeachPopulateArgs args = {
>          .fdt = fdt,
>          .offset = isa_offset,
> @@ -866,6 +854,10 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
>                               &error_fatal);
>      pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip8->lpc.xscom_regs);
>  
> +    chip->dt_isa_nodename = g_strdup_printf("/xscom@%" PRIx64 "/isa@%x",
> +                                            (uint64_t) PNV_XSCOM_BASE(chip),
> +                                            PNV_XSCOM_LPC_BASE);
> +
>      /* Interrupt Management Area. This is the memory region holding
>       * all the Interrupt Control Presenter (ICP) registers */
>      pnv_chip_icp_realize(chip8, &local_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] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v2 06/15] ppc/pnv: add a LPC Controller model for POWER9
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 06/15] ppc/pnv: add a LPC Controller model for POWER9 Cédric Le Goater
@ 2019-03-08  0:28   ` David Gibson
  0 siblings, 0 replies; 33+ messages in thread
From: David Gibson @ 2019-03-08  0:28 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Mar 07, 2019 at 11:35:39PM +0100, Cédric Le Goater wrote:
> The LPC Controller on POWER9 is very similar to the one found on
> POWER8 but accesses are now done via on MMIOs, without the XSCOM and
> ECCB logic. The device tree is populated differently so we add a
> specific POWER9 routine for the purpose.
> 
> SerIRQ routing is yet to be done.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

[snip]
> +static uint64_t pnv_lpc_mmio_read(void *opaque, hwaddr addr, unsigned size)
> +{
> +    PnvLpcController *lpc = PNV_LPC(opaque);
> +    uint64_t val = 0;
> +    uint32_t opb_addr = addr & ECCB_CTL_ADDR_MASK;
> +    MemTxResult result;
> +
> +    switch (size) {
> +    case 4:
> +        val = address_space_ldl(&lpc->opb_as, opb_addr, MEMTXATTRS_UNSPECIFIED,
> +                                &result);

This extra level of indirection via the opb_as still seems very
dubious to me.  But I guess it's something we can fix later, so,
applied.


> +        break;
> +    case 1:
> +        val = address_space_ldub(&lpc->opb_as, opb_addr, MEMTXATTRS_UNSPECIFIED,
> +                                 &result);
> +        break;
> +    default:
> +        qemu_log_mask(LOG_GUEST_ERROR, "OPB read failed at @0x%"
> +                      HWADDR_PRIx " invalid size %d\n", addr, size);
> +        return 0;
> +    }
> +
> +    if (result != MEMTX_OK) {
> +        qemu_log_mask(LOG_GUEST_ERROR, "OPB read failed at @0x%"
> +                      HWADDR_PRIx "\n", addr);
> +    }
> +
> +    return val;
> +}
> +
> +static void pnv_lpc_mmio_write(void *opaque, hwaddr addr,
> +                                uint64_t val, unsigned size)
> +{
> +    PnvLpcController *lpc = PNV_LPC(opaque);
> +    uint32_t opb_addr = addr & ECCB_CTL_ADDR_MASK;
> +    MemTxResult result;
> +
> +    switch (size) {
> +    case 4:
> +        address_space_stl(&lpc->opb_as, opb_addr, val, MEMTXATTRS_UNSPECIFIED,
> +                          &result);
> +         break;
> +    case 1:
> +        address_space_stb(&lpc->opb_as, opb_addr, val, MEMTXATTRS_UNSPECIFIED,
> +                          &result);
> +        break;
> +    default:
> +        qemu_log_mask(LOG_GUEST_ERROR, "OPB write failed at @0x%"
> +                      HWADDR_PRIx " invalid size %d\n", addr, size);
> +        return;
> +    }
> +
> +    if (result != MEMTX_OK) {
> +        qemu_log_mask(LOG_GUEST_ERROR, "OPB write failed at @0x%"
> +                      HWADDR_PRIx "\n", addr);
> +    }
> +}
> +
> +static const MemoryRegionOps pnv_lpc_mmio_ops = {
> +    .read = pnv_lpc_mmio_read,
> +    .write = pnv_lpc_mmio_write,
> +    .impl = {
> +        .min_access_size = 1,
> +        .max_access_size = 4,
> +    },
> +    .endianness = DEVICE_BIG_ENDIAN,
> +};
> +
>  static void pnv_lpc_eval_irqs(PnvLpcController *lpc)
>  {
>      bool lpc_to_opb_irq = false;
> @@ -465,6 +627,43 @@ static const TypeInfo pnv_lpc_power8_info = {
>      }
>  };
>  
> +static void pnv_lpc_power9_realize(DeviceState *dev, Error **errp)
> +{
> +    PnvLpcController *lpc = PNV_LPC(dev);
> +    PnvLpcClass *plc = PNV_LPC_GET_CLASS(dev);
> +    Error *local_err = NULL;
> +
> +    plc->parent_realize(dev, &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +
> +    /* P9 uses a MMIO region */
> +    memory_region_init_io(&lpc->xscom_regs, OBJECT(lpc), &pnv_lpc_mmio_ops,
> +                          lpc, "lpcm", PNV9_LPCM_SIZE);
> +}
> +
> +static void pnv_lpc_power9_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    PnvLpcClass *plc = PNV_LPC_CLASS(klass);
> +
> +    dc->desc = "PowerNV LPC Controller POWER9";
> +
> +    plc->psi_irq = PSIHB9_IRQ_LPCHC;
> +
> +    device_class_set_parent_realize(dc, pnv_lpc_power9_realize,
> +                                    &plc->parent_realize);
> +}
> +
> +static const TypeInfo pnv_lpc_power9_info = {
> +    .name          = TYPE_PNV9_LPC,
> +    .parent        = TYPE_PNV_LPC,
> +    .instance_size = sizeof(PnvLpcController),
> +    .class_init    = pnv_lpc_power9_class_init,
> +};
> +
>  static void pnv_lpc_realize(DeviceState *dev, Error **errp)
>  {
>      PnvLpcController *lpc = PNV_LPC(dev);
> @@ -540,6 +739,7 @@ static void pnv_lpc_register_types(void)
>  {
>      type_register_static(&pnv_lpc_info);
>      type_register_static(&pnv_lpc_power8_info);
> +    type_register_static(&pnv_lpc_power9_info);
>  }
>  
>  type_init(pnv_lpc_register_types)

-- 
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] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v2 07/15] ppc/pnv: add SerIRQ routing registers
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 07/15] ppc/pnv: add SerIRQ routing registers Cédric Le Goater
@ 2019-03-08  0:28   ` David Gibson
  0 siblings, 0 replies; 33+ messages in thread
From: David Gibson @ 2019-03-08  0:28 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Mar 07, 2019 at 11:35:40PM +0100, Cédric Le Goater wrote:
> This is just a simple reminder that SerIRQ routing should be
> addressed.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---

Applied, thanks.

>  include/hw/ppc/pnv_lpc.h |  2 ++
>  hw/ppc/pnv_lpc.c         | 14 ++++++++++++++
>  2 files changed, 16 insertions(+)
> 
> diff --git a/include/hw/ppc/pnv_lpc.h b/include/hw/ppc/pnv_lpc.h
> index 242b18081caa..413579792ed1 100644
> --- a/include/hw/ppc/pnv_lpc.h
> +++ b/include/hw/ppc/pnv_lpc.h
> @@ -55,6 +55,8 @@ typedef struct PnvLpcController {
>      MemoryRegion opb_master_regs;
>  
>      /* OPB Master LS registers */
> +    uint32_t opb_irq_route0;
> +    uint32_t opb_irq_route1;
>      uint32_t opb_irq_stat;
>      uint32_t opb_irq_mask;
>      uint32_t opb_irq_pol;
> diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
> index 6df694e0abc1..641e2046db92 100644
> --- a/hw/ppc/pnv_lpc.c
> +++ b/hw/ppc/pnv_lpc.c
> @@ -39,6 +39,8 @@ enum {
>  };
>  
>  /* OPB Master LS registers */
> +#define OPB_MASTER_LS_ROUTE0    0x8
> +#define OPB_MASTER_LS_ROUTE1    0xC
>  #define OPB_MASTER_LS_IRQ_STAT  0x50
>  #define   OPB_MASTER_IRQ_LPC            0x00000800
>  #define OPB_MASTER_LS_IRQ_MASK  0x54
> @@ -521,6 +523,12 @@ static uint64_t opb_master_read(void *opaque, hwaddr addr, unsigned size)
>      uint64_t val = 0xfffffffffffffffful;
>  
>      switch (addr) {
> +    case OPB_MASTER_LS_ROUTE0: /* TODO */
> +        val = lpc->opb_irq_route0;
> +        break;
> +    case OPB_MASTER_LS_ROUTE1: /* TODO */
> +        val = lpc->opb_irq_route1;
> +        break;
>      case OPB_MASTER_LS_IRQ_STAT:
>          val = lpc->opb_irq_stat;
>          break;
> @@ -547,6 +555,12 @@ static void opb_master_write(void *opaque, hwaddr addr,
>      PnvLpcController *lpc = opaque;
>  
>      switch (addr) {
> +    case OPB_MASTER_LS_ROUTE0: /* TODO */
> +        lpc->opb_irq_route0 = val;
> +        break;
> +    case OPB_MASTER_LS_ROUTE1: /* TODO */
> +        lpc->opb_irq_route1 = val;
> +        break;
>      case OPB_MASTER_LS_IRQ_STAT:
>          lpc->opb_irq_stat &= ~val;
>          pnv_lpc_eval_irqs(lpc);

-- 
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] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v2 08/15] ppc/pnv: add a OCC model class
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 08/15] ppc/pnv: add a OCC model class Cédric Le Goater
@ 2019-03-08  0:29   ` David Gibson
  0 siblings, 0 replies; 33+ messages in thread
From: David Gibson @ 2019-03-08  0:29 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Mar 07, 2019 at 11:35:41PM +0100, Cédric Le Goater wrote:
> To ease the introduction of the OCC model for POWER9, provide a new
> class attributes to define XSCOM operations per CPU family and a PSI
> IRQ number.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

Applied, thanks.

> ---
> 
>  Changes in v2:
> 
>  - new attributes to define XSCOM operations per CPU family and a PSI
>    IRQ number.
> 
>  include/hw/ppc/pnv_occ.h | 15 +++++++++++
>  hw/ppc/pnv.c             |  2 +-
>  hw/ppc/pnv_occ.c         | 55 +++++++++++++++++++++++++++-------------
>  3 files changed, 54 insertions(+), 18 deletions(-)
> 
> diff --git a/include/hw/ppc/pnv_occ.h b/include/hw/ppc/pnv_occ.h
> index 82f299dc76ff..dab5a05f8e99 100644
> --- a/include/hw/ppc/pnv_occ.h
> +++ b/include/hw/ppc/pnv_occ.h
> @@ -23,6 +23,8 @@
>  
>  #define TYPE_PNV_OCC "pnv-occ"
>  #define PNV_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV_OCC)
> +#define TYPE_PNV8_OCC TYPE_PNV_OCC "-POWER8"
> +#define PNV8_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV8_OCC)
>  
>  typedef struct PnvOCC {
>      DeviceState xd;
> @@ -35,4 +37,17 @@ typedef struct PnvOCC {
>      MemoryRegion xscom_regs;
>  } PnvOCC;
>  
> +#define PNV_OCC_CLASS(klass) \
> +     OBJECT_CLASS_CHECK(PnvOCCClass, (klass), TYPE_PNV_OCC)
> +#define PNV_OCC_GET_CLASS(obj) \
> +     OBJECT_GET_CLASS(PnvOCCClass, (obj), TYPE_PNV_OCC)
> +
> +typedef struct PnvOCCClass {
> +    DeviceClass parent_class;
> +
> +    int xscom_size;
> +    const MemoryRegionOps *xscom_ops;
> +    int psi_irq;
> +} PnvOCCClass;
> +
>  #endif /* _PPC_PNV_OCC_H */
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index 918fae057b5c..6ae9ce679505 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -790,7 +790,7 @@ static void pnv_chip_power8_instance_init(Object *obj)
>                                     OBJECT(&chip8->psi), &error_abort);
>  
>      object_initialize_child(obj, "occ",  &chip8->occ, sizeof(chip8->occ),
> -                            TYPE_PNV_OCC, &error_abort, NULL);
> +                            TYPE_PNV8_OCC, &error_abort, NULL);
>      object_property_add_const_link(OBJECT(&chip8->occ), "psi",
>                                     OBJECT(&chip8->psi), &error_abort);
>  }
> diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c
> index 04880f26d612..ea725647c988 100644
> --- a/hw/ppc/pnv_occ.c
> +++ b/hw/ppc/pnv_occ.c
> @@ -34,15 +34,17 @@
>  static void pnv_occ_set_misc(PnvOCC *occ, uint64_t val)
>  {
>      bool irq_state;
> +    PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
>  
>      val &= 0xffff000000000000ull;
>  
>      occ->occmisc = val;
>      irq_state = !!(val >> 63);
> -    pnv_psi_irq_set(occ->psi, PSIHB_IRQ_OCC, irq_state);
> +    pnv_psi_irq_set(occ->psi, poc->psi_irq, irq_state);
>  }
>  
> -static uint64_t pnv_occ_xscom_read(void *opaque, hwaddr addr, unsigned size)
> +static uint64_t pnv_occ_power8_xscom_read(void *opaque, hwaddr addr,
> +                                          unsigned size)
>  {
>      PnvOCC *occ = PNV_OCC(opaque);
>      uint32_t offset = addr >> 3;
> @@ -54,13 +56,13 @@ static uint64_t pnv_occ_xscom_read(void *opaque, hwaddr addr, unsigned size)
>          break;
>      default:
>          qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
> -                      HWADDR_PRIx "\n", addr);
> +                      HWADDR_PRIx "\n", addr >> 3);
>      }
>      return val;
>  }
>  
> -static void pnv_occ_xscom_write(void *opaque, hwaddr addr,
> -                                uint64_t val, unsigned size)
> +static void pnv_occ_power8_xscom_write(void *opaque, hwaddr addr,
> +                                       uint64_t val, unsigned size)
>  {
>      PnvOCC *occ = PNV_OCC(opaque);
>      uint32_t offset = addr >> 3;
> @@ -77,13 +79,13 @@ static void pnv_occ_xscom_write(void *opaque, hwaddr addr,
>          break;
>      default:
>          qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
> -                      HWADDR_PRIx "\n", addr);
> +                      HWADDR_PRIx "\n", addr >> 3);
>      }
>  }
>  
> -static const MemoryRegionOps pnv_occ_xscom_ops = {
> -    .read = pnv_occ_xscom_read,
> -    .write = pnv_occ_xscom_write,
> +static const MemoryRegionOps pnv_occ_power8_xscom_ops = {
> +    .read = pnv_occ_power8_xscom_read,
> +    .write = pnv_occ_power8_xscom_write,
>      .valid.min_access_size = 8,
>      .valid.max_access_size = 8,
>      .impl.min_access_size = 8,
> @@ -91,27 +93,42 @@ static const MemoryRegionOps pnv_occ_xscom_ops = {
>      .endianness = DEVICE_BIG_ENDIAN,
>  };
>  
> +static void pnv_occ_power8_class_init(ObjectClass *klass, void *data)
> +{
> +    PnvOCCClass *poc = PNV_OCC_CLASS(klass);
> +
> +    poc->xscom_size = PNV_XSCOM_OCC_SIZE;
> +    poc->xscom_ops = &pnv_occ_power8_xscom_ops;
> +    poc->psi_irq = PSIHB_IRQ_OCC;
> +}
> +
> +static const TypeInfo pnv_occ_power8_type_info = {
> +    .name          = TYPE_PNV8_OCC,
> +    .parent        = TYPE_PNV_OCC,
> +    .instance_size = sizeof(PnvOCC),
> +    .class_init    = pnv_occ_power8_class_init,
> +};
>  
>  static void pnv_occ_realize(DeviceState *dev, Error **errp)
>  {
>      PnvOCC *occ = PNV_OCC(dev);
> +    PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
>      Object *obj;
> -    Error *error = NULL;
> +    Error *local_err = NULL;
>  
>      occ->occmisc = 0;
>  
> -    /* get PSI object from chip */
> -    obj = object_property_get_link(OBJECT(dev), "psi", &error);
> +    obj = object_property_get_link(OBJECT(dev), "psi", &local_err);
>      if (!obj) {
> -        error_setg(errp, "%s: required link 'psi' not found: %s",
> -                   __func__, error_get_pretty(error));
> +        error_propagate(errp, local_err);
> +        error_prepend(errp, "required link 'psi' not found: ");
>          return;
>      }
>      occ->psi = PNV_PSI(obj);
>  
>      /* XScom region for OCC registers */
> -    pnv_xscom_region_init(&occ->xscom_regs, OBJECT(dev), &pnv_occ_xscom_ops,
> -                  occ, "xscom-occ", PNV_XSCOM_OCC_SIZE);
> +    pnv_xscom_region_init(&occ->xscom_regs, OBJECT(dev), poc->xscom_ops,
> +                          occ, "xscom-occ", poc->xscom_size);
>  }
>  
>  static void pnv_occ_class_init(ObjectClass *klass, void *data)
> @@ -119,6 +136,7 @@ static void pnv_occ_class_init(ObjectClass *klass, void *data)
>      DeviceClass *dc = DEVICE_CLASS(klass);
>  
>      dc->realize = pnv_occ_realize;
> +    dc->desc = "PowerNV OCC Controller";
>  }
>  
>  static const TypeInfo pnv_occ_type_info = {
> @@ -126,11 +144,14 @@ static const TypeInfo pnv_occ_type_info = {
>      .parent        = TYPE_DEVICE,
>      .instance_size = sizeof(PnvOCC),
>      .class_init    = pnv_occ_class_init,
> +    .class_size    = sizeof(PnvOCCClass),
> +    .abstract      = true,
>  };
>  
>  static void pnv_occ_register_types(void)
>  {
>      type_register_static(&pnv_occ_type_info);
> +    type_register_static(&pnv_occ_power8_type_info);
>  }
>  
> -type_init(pnv_occ_register_types)
> +type_init(pnv_occ_register_types);

-- 
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] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v2 09/15] ppc/pnv: add a OCC model for POWER9
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 09/15] ppc/pnv: add a OCC model for POWER9 Cédric Le Goater
@ 2019-03-08  0:30   ` David Gibson
  0 siblings, 0 replies; 33+ messages in thread
From: David Gibson @ 2019-03-08  0:30 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Mar 07, 2019 at 11:35:42PM +0100, Cédric Le Goater wrote:
> The OCC on POWER9 is very similar to the one found on POWER8. Provide
> the same routines with P9 values for the registers and IRQ number.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Applied, thanks.

> ---
> 
>  Changes in v2 :
> 
>  - made use of the new class attributes for POWER9
> 
>  include/hw/ppc/pnv.h       |  1 +
>  include/hw/ppc/pnv_occ.h   |  2 ++
>  include/hw/ppc/pnv_xscom.h |  3 ++
>  hw/ppc/pnv.c               | 13 +++++++
>  hw/ppc/pnv_occ.c           | 72 ++++++++++++++++++++++++++++++++++++++
>  5 files changed, 91 insertions(+)
> 
> diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
> index 1cd1ad622d0b..39888f9d52c1 100644
> --- a/include/hw/ppc/pnv.h
> +++ b/include/hw/ppc/pnv.h
> @@ -88,6 +88,7 @@ typedef struct Pnv9Chip {
>      PnvXive      xive;
>      Pnv9Psi      psi;
>      PnvLpcController lpc;
> +    PnvOCC       occ;
>  } Pnv9Chip;
>  
>  typedef struct PnvChipClass {
> diff --git a/include/hw/ppc/pnv_occ.h b/include/hw/ppc/pnv_occ.h
> index dab5a05f8e99..d22b65a71abe 100644
> --- a/include/hw/ppc/pnv_occ.h
> +++ b/include/hw/ppc/pnv_occ.h
> @@ -25,6 +25,8 @@
>  #define PNV_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV_OCC)
>  #define TYPE_PNV8_OCC TYPE_PNV_OCC "-POWER8"
>  #define PNV8_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV8_OCC)
> +#define TYPE_PNV9_OCC TYPE_PNV_OCC "-POWER9"
> +#define PNV9_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV9_OCC)
>  
>  typedef struct PnvOCC {
>      DeviceState xd;
> diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
> index 403a365ed274..3292459fbb78 100644
> --- a/include/hw/ppc/pnv_xscom.h
> +++ b/include/hw/ppc/pnv_xscom.h
> @@ -73,6 +73,9 @@ typedef struct PnvXScomInterfaceClass {
>  #define PNV_XSCOM_OCC_BASE        0x0066000
>  #define PNV_XSCOM_OCC_SIZE        0x6000
>  
> +#define PNV9_XSCOM_OCC_BASE       PNV_XSCOM_OCC_BASE
> +#define PNV9_XSCOM_OCC_SIZE       0x8000
> +
>  #define PNV9_XSCOM_PSIHB_BASE     0x5012900
>  #define PNV9_XSCOM_PSIHB_SIZE     0x100
>  
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index 6ae9ce679505..1559a733235b 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -956,6 +956,11 @@ static void pnv_chip_power9_instance_init(Object *obj)
>                              TYPE_PNV9_LPC, &error_abort, NULL);
>      object_property_add_const_link(OBJECT(&chip9->lpc), "psi",
>                                     OBJECT(&chip9->psi), &error_abort);
> +
> +    object_initialize_child(obj, "occ",  &chip9->occ, sizeof(chip9->occ),
> +                            TYPE_PNV9_OCC, &error_abort, NULL);
> +    object_property_add_const_link(OBJECT(&chip9->occ), "psi",
> +                                   OBJECT(&chip9->psi), &error_abort);
>  }
>  
>  static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
> @@ -1012,6 +1017,14 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
>  
>      chip->dt_isa_nodename = g_strdup_printf("/lpcm-opb@%" PRIx64 "/lpc@0",
>                                              (uint64_t) PNV9_LPCM_BASE(chip));
> +
> +    /* Create the simplified OCC model */
> +    object_property_set_bool(OBJECT(&chip9->occ), true, "realized", &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +    pnv_xscom_add_subregion(chip, PNV9_XSCOM_OCC_BASE, &chip9->occ.xscom_regs);
>  }
>  
>  static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
> diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c
> index ea725647c988..fdd9296e1bc7 100644
> --- a/hw/ppc/pnv_occ.c
> +++ b/hw/ppc/pnv_occ.c
> @@ -109,6 +109,77 @@ static const TypeInfo pnv_occ_power8_type_info = {
>      .class_init    = pnv_occ_power8_class_init,
>  };
>  
> +#define P9_OCB_OCI_OCCMISC              0x6080
> +#define P9_OCB_OCI_OCCMISC_CLEAR        0x6081
> +#define P9_OCB_OCI_OCCMISC_OR           0x6082
> +
> +
> +static uint64_t pnv_occ_power9_xscom_read(void *opaque, hwaddr addr,
> +                                          unsigned size)
> +{
> +    PnvOCC *occ = PNV_OCC(opaque);
> +    uint32_t offset = addr >> 3;
> +    uint64_t val = 0;
> +
> +    switch (offset) {
> +    case P9_OCB_OCI_OCCMISC:
> +        val = occ->occmisc;
> +        break;
> +    default:
> +        qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
> +                      HWADDR_PRIx "\n", addr >> 3);
> +    }
> +    return val;
> +}
> +
> +static void pnv_occ_power9_xscom_write(void *opaque, hwaddr addr,
> +                                       uint64_t val, unsigned size)
> +{
> +    PnvOCC *occ = PNV_OCC(opaque);
> +    uint32_t offset = addr >> 3;
> +
> +    switch (offset) {
> +    case P9_OCB_OCI_OCCMISC_CLEAR:
> +        pnv_occ_set_misc(occ, 0);
> +        break;
> +    case P9_OCB_OCI_OCCMISC_OR:
> +        pnv_occ_set_misc(occ, occ->occmisc | val);
> +        break;
> +    case P9_OCB_OCI_OCCMISC:
> +        pnv_occ_set_misc(occ, val);
> +       break;
> +    default:
> +        qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
> +                      HWADDR_PRIx "\n", addr >> 3);
> +    }
> +}
> +
> +static const MemoryRegionOps pnv_occ_power9_xscom_ops = {
> +    .read = pnv_occ_power9_xscom_read,
> +    .write = pnv_occ_power9_xscom_write,
> +    .valid.min_access_size = 8,
> +    .valid.max_access_size = 8,
> +    .impl.min_access_size = 8,
> +    .impl.max_access_size = 8,
> +    .endianness = DEVICE_BIG_ENDIAN,
> +};
> +
> +static void pnv_occ_power9_class_init(ObjectClass *klass, void *data)
> +{
> +    PnvOCCClass *poc = PNV_OCC_CLASS(klass);
> +
> +    poc->xscom_size = PNV9_XSCOM_OCC_SIZE;
> +    poc->xscom_ops = &pnv_occ_power9_xscom_ops;
> +    poc->psi_irq = PSIHB9_IRQ_OCC;
> +}
> +
> +static const TypeInfo pnv_occ_power9_type_info = {
> +    .name          = TYPE_PNV9_OCC,
> +    .parent        = TYPE_PNV_OCC,
> +    .instance_size = sizeof(PnvOCC),
> +    .class_init    = pnv_occ_power9_class_init,
> +};
> +
>  static void pnv_occ_realize(DeviceState *dev, Error **errp)
>  {
>      PnvOCC *occ = PNV_OCC(dev);
> @@ -152,6 +223,7 @@ static void pnv_occ_register_types(void)
>  {
>      type_register_static(&pnv_occ_type_info);
>      type_register_static(&pnv_occ_power8_type_info);
> +    type_register_static(&pnv_occ_power9_type_info);
>  }
>  
>  type_init(pnv_occ_register_types);

-- 
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] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v2 10/15] ppc/pnv: extend XSCOM core support for POWER9
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 10/15] ppc/pnv: extend XSCOM core support " Cédric Le Goater
@ 2019-03-08  0:31   ` David Gibson
  0 siblings, 0 replies; 33+ messages in thread
From: David Gibson @ 2019-03-08  0:31 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Mar 07, 2019 at 11:35:43PM +0100, Cédric Le Goater wrote:
> Provide a new class attribute to define XSCOM operations per CPU
> family and add a couple of XSCOM addresses controlling the power
> management states of the core on POWER9.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Applied, thanks.

> ---
> 
>  Changes in v2 :
> 
>  - new class attribute to define XSCOM operations per CPU family
> 
>  include/hw/ppc/pnv_core.h |   2 +
>  hw/ppc/pnv_core.c         | 100 +++++++++++++++++++++++++++++++++-----
>  2 files changed, 89 insertions(+), 13 deletions(-)
> 
> diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h
> index 6874bb847a01..cbe9ad36f32c 100644
> --- a/include/hw/ppc/pnv_core.h
> +++ b/include/hw/ppc/pnv_core.h
> @@ -42,6 +42,8 @@ typedef struct PnvCore {
>  
>  typedef struct PnvCoreClass {
>      DeviceClass parent_class;
> +
> +    const MemoryRegionOps *xscom_ops;
>  } PnvCoreClass;
>  
>  #define PNV_CORE_TYPE_SUFFIX "-" TYPE_PNV_CORE
> diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
> index 38179cdc53dc..171474e0805c 100644
> --- a/hw/ppc/pnv_core.c
> +++ b/hw/ppc/pnv_core.c
> @@ -60,8 +60,8 @@ static void pnv_cpu_reset(void *opaque)
>  #define PNV_XSCOM_EX_DTS_RESULT0     0x50000
>  #define PNV_XSCOM_EX_DTS_RESULT1     0x50001
>  
> -static uint64_t pnv_core_xscom_read(void *opaque, hwaddr addr,
> -                                    unsigned int width)
> +static uint64_t pnv_core_power8_xscom_read(void *opaque, hwaddr addr,
> +                                           unsigned int width)
>  {
>      uint32_t offset = addr >> 3;
>      uint64_t val = 0;
> @@ -82,16 +82,74 @@ static uint64_t pnv_core_xscom_read(void *opaque, hwaddr addr,
>      return val;
>  }
>  
> -static void pnv_core_xscom_write(void *opaque, hwaddr addr, uint64_t val,
> -                                 unsigned int width)
> +static void pnv_core_power8_xscom_write(void *opaque, hwaddr addr, uint64_t val,
> +                                        unsigned int width)
>  {
>      qemu_log_mask(LOG_UNIMP, "Warning: writing to reg=0x%" HWADDR_PRIx "\n",
>                    addr);
>  }
>  
> -static const MemoryRegionOps pnv_core_xscom_ops = {
> -    .read = pnv_core_xscom_read,
> -    .write = pnv_core_xscom_write,
> +static const MemoryRegionOps pnv_core_power8_xscom_ops = {
> +    .read = pnv_core_power8_xscom_read,
> +    .write = pnv_core_power8_xscom_write,
> +    .valid.min_access_size = 8,
> +    .valid.max_access_size = 8,
> +    .impl.min_access_size = 8,
> +    .impl.max_access_size = 8,
> +    .endianness = DEVICE_BIG_ENDIAN,
> +};
> +
> +
> +/*
> + * POWER9 core controls
> + */
> +#define PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_HYP 0xf010d
> +#define PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_OTR 0xf010a
> +
> +static uint64_t pnv_core_power9_xscom_read(void *opaque, hwaddr addr,
> +                                           unsigned int width)
> +{
> +    uint32_t offset = addr >> 3;
> +    uint64_t val = 0;
> +
> +    /* The result should be 38 C */
> +    switch (offset) {
> +    case PNV_XSCOM_EX_DTS_RESULT0:
> +        val = 0x26f024f023f0000ull;
> +        break;
> +    case PNV_XSCOM_EX_DTS_RESULT1:
> +        val = 0x24f000000000000ull;
> +        break;
> +    case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_HYP:
> +    case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_OTR:
> +        val = 0x0;
> +        break;
> +    default:
> +        qemu_log_mask(LOG_UNIMP, "Warning: reading reg=0x%" HWADDR_PRIx "\n",
> +                  addr);
> +    }
> +
> +    return val;
> +}
> +
> +static void pnv_core_power9_xscom_write(void *opaque, hwaddr addr, uint64_t val,
> +                                        unsigned int width)
> +{
> +    uint32_t offset = addr >> 3;
> +
> +    switch (offset) {
> +    case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_HYP:
> +    case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_OTR:
> +        break;
> +    default:
> +        qemu_log_mask(LOG_UNIMP, "Warning: writing to reg=0x%" HWADDR_PRIx "\n",
> +                      addr);
> +    }
> +}
> +
> +static const MemoryRegionOps pnv_core_power9_xscom_ops = {
> +    .read = pnv_core_power9_xscom_read,
> +    .write = pnv_core_power9_xscom_write,
>      .valid.min_access_size = 8,
>      .valid.max_access_size = 8,
>      .impl.min_access_size = 8,
> @@ -138,6 +196,7 @@ static void pnv_realize_vcpu(PowerPCCPU *cpu, PnvChip *chip, Error **errp)
>  static void pnv_core_realize(DeviceState *dev, Error **errp)
>  {
>      PnvCore *pc = PNV_CORE(OBJECT(dev));
> +    PnvCoreClass *pcc = PNV_CORE_GET_CLASS(pc);
>      CPUCore *cc = CPU_CORE(OBJECT(dev));
>      const char *typename = pnv_core_cpu_typename(pc);
>      Error *local_err = NULL;
> @@ -180,7 +239,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
>      }
>  
>      snprintf(name, sizeof(name), "xscom-core.%d", cc->core_id);
> -    pnv_xscom_region_init(&pc->xscom_regs, OBJECT(dev), &pnv_core_xscom_ops,
> +    pnv_xscom_region_init(&pc->xscom_regs, OBJECT(dev), pcc->xscom_ops,
>                            pc, name, PNV_XSCOM_EX_SIZE);
>      return;
>  
> @@ -222,6 +281,20 @@ static Property pnv_core_properties[] = {
>      DEFINE_PROP_END_OF_LIST(),
>  };
>  
> +static void pnv_core_power8_class_init(ObjectClass *oc, void *data)
> +{
> +    PnvCoreClass *pcc = PNV_CORE_CLASS(oc);
> +
> +    pcc->xscom_ops = &pnv_core_power8_xscom_ops;
> +}
> +
> +static void pnv_core_power9_class_init(ObjectClass *oc, void *data)
> +{
> +    PnvCoreClass *pcc = PNV_CORE_CLASS(oc);
> +
> +    pcc->xscom_ops = &pnv_core_power9_xscom_ops;
> +}
> +
>  static void pnv_core_class_init(ObjectClass *oc, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(oc);
> @@ -231,10 +304,11 @@ static void pnv_core_class_init(ObjectClass *oc, void *data)
>      dc->props = pnv_core_properties;
>  }
>  
> -#define DEFINE_PNV_CORE_TYPE(cpu_model)         \
> +#define DEFINE_PNV_CORE_TYPE(family, cpu_model) \
>      {                                           \
>          .parent = TYPE_PNV_CORE,                \
>          .name = PNV_CORE_TYPE_NAME(cpu_model),  \
> +        .class_init = pnv_core_##family##_class_init, \
>      }
>  
>  static const TypeInfo pnv_core_infos[] = {
> @@ -246,10 +320,10 @@ static const TypeInfo pnv_core_infos[] = {
>          .class_init = pnv_core_class_init,
>          .abstract       = true,
>      },
> -    DEFINE_PNV_CORE_TYPE("power8e_v2.1"),
> -    DEFINE_PNV_CORE_TYPE("power8_v2.0"),
> -    DEFINE_PNV_CORE_TYPE("power8nvl_v1.0"),
> -    DEFINE_PNV_CORE_TYPE("power9_v2.0"),
> +    DEFINE_PNV_CORE_TYPE(power8, "power8e_v2.1"),
> +    DEFINE_PNV_CORE_TYPE(power8, "power8_v2.0"),
> +    DEFINE_PNV_CORE_TYPE(power8, "power8nvl_v1.0"),
> +    DEFINE_PNV_CORE_TYPE(power9, "power9_v2.0"),
>  };
>  
>  DEFINE_TYPES(pnv_core_infos)

-- 
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] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v2 11/15] ppc/pnv: POWER9 XSCOM quad support
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 11/15] ppc/pnv: POWER9 XSCOM quad support Cédric Le Goater
@ 2019-03-08  0:32   ` David Gibson
  0 siblings, 0 replies; 33+ messages in thread
From: David Gibson @ 2019-03-08  0:32 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Mar 07, 2019 at 11:35:44PM +0100, Cédric Le Goater wrote:
> The POWER9 processor does not support per-core frequency control. The
> cores are arranged in groups of four, along with their respective L2
> and L3 caches, into a structure known as a Quad. The frequency must be
> managed at the Quad level.
> 
> Provide a basic Quad model to fake the settings done by the firmware
> on the Non-Cacheable Unit (NCU). Each core pair (EX) needs a special
> BAR setting for the TIMA area of XIVE because it resides on the same
> address on all chips.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Applied, thanks.

> ---
>  include/hw/ppc/pnv.h       |  4 ++
>  include/hw/ppc/pnv_core.h  | 10 +++++
>  include/hw/ppc/pnv_xscom.h | 12 ++++--
>  hw/ppc/pnv.c               | 38 ++++++++++++++++-
>  hw/ppc/pnv_core.c          | 87 ++++++++++++++++++++++++++++++++++++++
>  5 files changed, 146 insertions(+), 5 deletions(-)
> 
> diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
> index 39888f9d52c1..e5b00d373ed2 100644
> --- a/include/hw/ppc/pnv.h
> +++ b/include/hw/ppc/pnv.h
> @@ -26,6 +26,7 @@
>  #include "hw/ppc/pnv_psi.h"
>  #include "hw/ppc/pnv_occ.h"
>  #include "hw/ppc/pnv_xive.h"
> +#include "hw/ppc/pnv_core.h"
>  
>  #define TYPE_PNV_CHIP "pnv-chip"
>  #define PNV_CHIP(obj) OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP)
> @@ -89,6 +90,9 @@ typedef struct Pnv9Chip {
>      Pnv9Psi      psi;
>      PnvLpcController lpc;
>      PnvOCC       occ;
> +
> +    uint32_t     nr_quads;
> +    PnvQuad      *quads;
>  } Pnv9Chip;
>  
>  typedef struct PnvChipClass {
> diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h
> index cbe9ad36f32c..50cdb2b35838 100644
> --- a/include/hw/ppc/pnv_core.h
> +++ b/include/hw/ppc/pnv_core.h
> @@ -58,4 +58,14 @@ static inline PnvCPUState *pnv_cpu_state(PowerPCCPU *cpu)
>      return (PnvCPUState *)cpu->machine_data;
>  }
>  
> +#define TYPE_PNV_QUAD "powernv-cpu-quad"
> +#define PNV_QUAD(obj) \
> +    OBJECT_CHECK(PnvQuad, (obj), TYPE_PNV_QUAD)
> +
> +typedef struct PnvQuad {
> +    DeviceState parent_obj;
> +
> +    uint32_t id;
> +    MemoryRegion xscom_regs;
> +} PnvQuad;
>  #endif /* _PPC_PNV_CORE_H */
> diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
> index 3292459fbb78..68dfae0dfe41 100644
> --- a/include/hw/ppc/pnv_xscom.h
> +++ b/include/hw/ppc/pnv_xscom.h
> @@ -60,10 +60,6 @@ typedef struct PnvXScomInterfaceClass {
>      (PNV_XSCOM_EX_CORE_BASE | ((uint64_t)(core) << 24))
>  #define PNV_XSCOM_EX_SIZE         0x100000
>  
> -#define PNV_XSCOM_P9_EC_BASE(core) \
> -    ((uint64_t)(((core) & 0x1F) + 0x20) << 24)
> -#define PNV_XSCOM_P9_EC_SIZE      0x100000
> -
>  #define PNV_XSCOM_LPC_BASE        0xb0020
>  #define PNV_XSCOM_LPC_SIZE        0x4
>  
> @@ -73,6 +69,14 @@ typedef struct PnvXScomInterfaceClass {
>  #define PNV_XSCOM_OCC_BASE        0x0066000
>  #define PNV_XSCOM_OCC_SIZE        0x6000
>  
> +#define PNV9_XSCOM_EC_BASE(core) \
> +    ((uint64_t)(((core) & 0x1F) + 0x20) << 24)
> +#define PNV9_XSCOM_EC_SIZE        0x100000
> +
> +#define PNV9_XSCOM_EQ_BASE(core) \
> +    ((uint64_t)(((core) & 0x1C) + 0x40) << 22)
> +#define PNV9_XSCOM_EQ_SIZE        0x100000
> +
>  #define PNV9_XSCOM_OCC_BASE       PNV_XSCOM_OCC_BASE
>  #define PNV9_XSCOM_OCC_SIZE       0x8000
>  
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index 1559a733235b..e68d419203e8 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -963,6 +963,36 @@ static void pnv_chip_power9_instance_init(Object *obj)
>                                     OBJECT(&chip9->psi), &error_abort);
>  }
>  
> +static void pnv_chip_quad_realize(Pnv9Chip *chip9, Error **errp)
> +{
> +    PnvChip *chip = PNV_CHIP(chip9);
> +    const char *typename = pnv_chip_core_typename(chip);
> +    size_t typesize = object_type_get_instance_size(typename);
> +    int i;
> +
> +    chip9->nr_quads = DIV_ROUND_UP(chip->nr_cores, 4);
> +    chip9->quads = g_new0(PnvQuad, chip9->nr_quads);
> +
> +    for (i = 0; i < chip9->nr_quads; i++) {
> +        char eq_name[32];
> +        PnvQuad *eq = &chip9->quads[i];
> +        PnvCore *pnv_core = PNV_CORE(chip->cores + (i * 4) * typesize);
> +        int core_id = CPU_CORE(pnv_core)->core_id;
> +
> +        object_initialize(eq, sizeof(*eq), TYPE_PNV_QUAD);
> +        snprintf(eq_name, sizeof(eq_name), "eq[%d]", core_id);
> +
> +        object_property_add_child(OBJECT(chip), eq_name, OBJECT(eq),
> +                                  &error_fatal);
> +        object_property_set_int(OBJECT(eq), core_id, "id", &error_fatal);
> +        object_property_set_bool(OBJECT(eq), true, "realized", &error_fatal);
> +        object_unref(OBJECT(eq));
> +
> +        pnv_xscom_add_subregion(chip, PNV9_XSCOM_EQ_BASE(eq->id),
> +                                &eq->xscom_regs);
> +    }
> +}
> +
>  static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
>  {
>      PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
> @@ -977,6 +1007,12 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
>          return;
>      }
>  
> +    pnv_chip_quad_realize(chip9, &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +
>      /* XIVE interrupt controller (POWER9) */
>      object_property_set_int(OBJECT(&chip9->xive), PNV9_XIVE_IC_BASE(chip),
>                              "ic-bar", &error_fatal);
> @@ -1135,7 +1171,7 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
>          if (!pnv_chip_is_power9(chip)) {
>              xscom_core_base = PNV_XSCOM_EX_BASE(core_hwid);
>          } else {
> -            xscom_core_base = PNV_XSCOM_P9_EC_BASE(core_hwid);
> +            xscom_core_base = PNV9_XSCOM_EC_BASE(core_hwid);
>          }
>  
>          pnv_xscom_add_subregion(chip, xscom_core_base,
> diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
> index 171474e0805c..5feeed6bc463 100644
> --- a/hw/ppc/pnv_core.c
> +++ b/hw/ppc/pnv_core.c
> @@ -327,3 +327,90 @@ static const TypeInfo pnv_core_infos[] = {
>  };
>  
>  DEFINE_TYPES(pnv_core_infos)
> +
> +/*
> + * POWER9 Quads
> + */
> +
> +#define P9X_EX_NCU_SPEC_BAR                     0x11010
> +
> +static uint64_t pnv_quad_xscom_read(void *opaque, hwaddr addr,
> +                                    unsigned int width)
> +{
> +    uint32_t offset = addr >> 3;
> +    uint64_t val = -1;
> +
> +    switch (offset) {
> +    case P9X_EX_NCU_SPEC_BAR:
> +    case P9X_EX_NCU_SPEC_BAR + 0x400: /* Second EX */
> +        val = 0;
> +        break;
> +    default:
> +        qemu_log_mask(LOG_UNIMP, "%s: writing @0x%08x\n", __func__,
> +                      offset);
> +    }
> +
> +    return val;
> +}
> +
> +static void pnv_quad_xscom_write(void *opaque, hwaddr addr, uint64_t val,
> +                                 unsigned int width)
> +{
> +    uint32_t offset = addr >> 3;
> +
> +    switch (offset) {
> +    case P9X_EX_NCU_SPEC_BAR:
> +    case P9X_EX_NCU_SPEC_BAR + 0x400: /* Second EX */
> +        break;
> +    default:
> +        qemu_log_mask(LOG_UNIMP, "%s: writing @0x%08x\n", __func__,
> +                  offset);
> +    }
> +}
> +
> +static const MemoryRegionOps pnv_quad_xscom_ops = {
> +    .read = pnv_quad_xscom_read,
> +    .write = pnv_quad_xscom_write,
> +    .valid.min_access_size = 8,
> +    .valid.max_access_size = 8,
> +    .impl.min_access_size = 8,
> +    .impl.max_access_size = 8,
> +    .endianness = DEVICE_BIG_ENDIAN,
> +};
> +
> +static void pnv_quad_realize(DeviceState *dev, Error **errp)
> +{
> +    PnvQuad *eq = PNV_QUAD(dev);
> +    char name[32];
> +
> +    snprintf(name, sizeof(name), "xscom-quad.%d", eq->id);
> +    pnv_xscom_region_init(&eq->xscom_regs, OBJECT(dev), &pnv_quad_xscom_ops,
> +                          eq, name, PNV9_XSCOM_EQ_SIZE);
> +}
> +
> +static Property pnv_quad_properties[] = {
> +    DEFINE_PROP_UINT32("id", PnvQuad, id, 0),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void pnv_quad_class_init(ObjectClass *oc, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(oc);
> +
> +    dc->realize = pnv_quad_realize;
> +    dc->props = pnv_quad_properties;
> +}
> +
> +static const TypeInfo pnv_quad_info = {
> +    .name          = TYPE_PNV_QUAD,
> +    .parent        = TYPE_DEVICE,
> +    .instance_size = sizeof(PnvQuad),
> +    .class_init    = pnv_quad_class_init,
> +};
> +
> +static void pnv_core_register_types(void)
> +{
> +    type_register_static(&pnv_quad_info);
> +}
> +
> +type_init(pnv_core_register_types)

-- 
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] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v2 12/15] ppc/pnv: activate XSCOM tests for POWER9
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 12/15] ppc/pnv: activate XSCOM tests for POWER9 Cédric Le Goater
@ 2019-03-08  0:33   ` David Gibson
  0 siblings, 0 replies; 33+ messages in thread
From: David Gibson @ 2019-03-08  0:33 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Mar 07, 2019 at 11:35:45PM +0100, Cédric Le Goater wrote:
> We now have enough support to let the XSCOM test run on POWER9.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Applied, thanks.

> ---
>  tests/pnv-xscom-test.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/tests/pnv-xscom-test.c b/tests/pnv-xscom-test.c
> index 974f8da5b240..63d464048d53 100644
> --- a/tests/pnv-xscom-test.c
> +++ b/tests/pnv-xscom-test.c
> @@ -39,7 +39,6 @@ static const PnvChip pnv_chips[] = {
>          .cfam_id    = 0x120d304980000000ull,
>          .first_core = 0x1,
>      },
> -#if 0 /* POWER9 support is not ready yet */
>      {
>          .chip_type  = PNV_CHIP_POWER9,
>          .cpu_model  = "POWER9",
> @@ -47,7 +46,6 @@ static const PnvChip pnv_chips[] = {
>          .cfam_id    = 0x220d104900008000ull,
>          .first_core = 0x0,
>      },
> -#endif
>  };
>  
>  static uint64_t pnv_xscom_addr(const PnvChip *chip, uint32_t pcba)

-- 
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] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v2 13/15] ppc/pnv: add more dummy XSCOM addresses
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 13/15] ppc/pnv: add more dummy XSCOM addresses Cédric Le Goater
@ 2019-03-08  0:56   ` David Gibson
  0 siblings, 0 replies; 33+ messages in thread
From: David Gibson @ 2019-03-08  0:56 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Mar 07, 2019 at 11:35:46PM +0100, Cédric Le Goater wrote:
> To improve OPAL/skiboot support. We don't need to strictly model these
> XSCOM accesses.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Applied, thanks.

> ---
>  hw/ppc/pnv_xscom.c | 33 +++++++++++++++++++++++++++------
>  1 file changed, 27 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c
> index 46fae41f32b0..c285ef514e88 100644
> --- a/hw/ppc/pnv_xscom.c
> +++ b/hw/ppc/pnv_xscom.c
> @@ -64,11 +64,21 @@ static uint64_t xscom_read_default(PnvChip *chip, uint32_t pcba)
>      switch (pcba) {
>      case 0xf000f:
>          return PNV_CHIP_GET_CLASS(chip)->chip_cfam_id;
> +    case 0x18002:       /* ECID2 */
> +        return 0;
> +
>      case 0x1010c00:     /* PIBAM FIR */
>      case 0x1010c03:     /* PIBAM FIR MASK */
> -    case 0x2020007:     /* ADU stuff */
> -    case 0x2020009:     /* ADU stuff */
> -    case 0x202000f:     /* ADU stuff */
> +
> +        /* P9 xscom reset */
> +    case 0x0090018:     /* Receive status reg */
> +    case 0x0090012:     /* log register */
> +    case 0x0090013:     /* error register */
> +
> +        /* P8 xscom reset */
> +    case 0x2020007:     /* ADU stuff, log register */
> +    case 0x2020009:     /* ADU stuff, error register */
> +    case 0x202000f:     /* ADU stuff, receive status register*/
>          return 0;
>      case 0x2013f00:     /* PBA stuff */
>      case 0x2013f01:     /* PBA stuff */
> @@ -100,9 +110,20 @@ static bool xscom_write_default(PnvChip *chip, uint32_t pcba, uint64_t val)
>      case 0x1010c03:     /* PIBAM FIR MASK */
>      case 0x1010c04:     /* PIBAM FIR MASK */
>      case 0x1010c05:     /* PIBAM FIR MASK */
> -    case 0x2020007:     /* ADU stuff */
> -    case 0x2020009:     /* ADU stuff */
> -    case 0x202000f:     /* ADU stuff */
> +        /* P9 xscom reset */
> +    case 0x0090018:     /* Receive status reg */
> +    case 0x0090012:     /* log register */
> +    case 0x0090013:     /* error register */
> +
> +        /* P8 xscom reset */
> +    case 0x2020007:     /* ADU stuff, log register */
> +    case 0x2020009:     /* ADU stuff, error register */
> +    case 0x202000f:     /* ADU stuff, receive status register*/
> +
> +    case 0x2013028:     /* CAPP stuff */
> +    case 0x201302a:     /* CAPP stuff */
> +    case 0x2013801:     /* CAPP stuff */
> +    case 0x2013802:     /* CAPP stuff */
>          return true;
>      default:
>          return false;

-- 
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] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v2 14/15] ppc/pnv: add a "ibm, opal/power-mgt" device tree node on POWER9
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 14/15] ppc/pnv: add a "ibm, opal/power-mgt" device tree node on POWER9 Cédric Le Goater
@ 2019-03-08  0:58   ` David Gibson
  0 siblings, 0 replies; 33+ messages in thread
From: David Gibson @ 2019-03-08  0:58 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Mar 07, 2019 at 11:35:47PM +0100, Cédric Le Goater wrote:
> Activate only stop0 and stop1 levels. We should not need more levels
> when under QEMU.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Applied, although..

> ---
>  hw/ppc/pnv.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index e68d419203e8..8be4d4cbf785 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -438,6 +438,16 @@ static void pnv_dt_isa(PnvMachineState *pnv, void *fdt)
>                         &args);
>  }
>  
> +static void pnv_dt_power_mgt(void *fdt)
> +{
> +    int off;
> +
> +    off = fdt_add_subnode(fdt, 0, "ibm,opal");
> +    off = fdt_add_subnode(fdt, off, "power-mgt");
> +
> +    _FDT(fdt_setprop_cell(fdt, off, "ibm,enabled-stop-levels", 0xc0000000));
> +}
> +
>  static void *pnv_dt_create(MachineState *machine)
>  {
>      const char plat_compat[] = "qemu,powernv\0ibm,powernv";
> @@ -493,6 +503,11 @@ static void *pnv_dt_create(MachineState *machine)
>          pnv_dt_bmc_sensors(pnv->bmc, fdt);
>      }
>  
> +    /* Create an extra node for power management on Power9 */
> +    if (pnv_is_power9(pnv)) {

.. as always, I think specific code calling generic helpers is a
better pattern than generic code conditionally calling specific details.

> +        pnv_dt_power_mgt(fdt);
> +    }
> +
>      return fdt;
>  }
>  

-- 
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] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v2 15/15] target/ppc: add HV support for POWER9
  2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 15/15] target/ppc: add HV support for POWER9 Cédric Le Goater
@ 2019-03-08  0:59   ` David Gibson
  0 siblings, 0 replies; 33+ messages in thread
From: David Gibson @ 2019-03-08  0:59 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Thu, Mar 07, 2019 at 11:35:48PM +0100, Cédric Le Goater wrote:
> We now have enough support to boot a PowerNV machine with a POWER9
> processor. Allow HV mode on POWER9.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Applied.

> ---
>  target/ppc/translate_init.inc.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
> index af70a3b78c9a..0bd555eb1913 100644
> --- a/target/ppc/translate_init.inc.c
> +++ b/target/ppc/translate_init.inc.c
> @@ -8895,7 +8895,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
>                         PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
>                         PPC_MEM_SYNC | PPC_MEM_EIEIO |
>                         PPC_MEM_TLBSYNC |
> -                       PPC_64B | PPC_64BX | PPC_ALTIVEC |
> +                       PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
>                         PPC_SEGMENT_64B | PPC_SLBI |
>                         PPC_POPCNTB | PPC_POPCNTWD |
>                         PPC_CILDST;
> @@ -8907,6 +8907,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
>                          PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
>                          PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL;
>      pcc->msr_mask = (1ull << MSR_SF) |
> +                    (1ull << MSR_SHV) |
>                      (1ull << MSR_TM) |
>                      (1ull << MSR_VR) |
>                      (1ull << MSR_VSX) |

-- 
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] 33+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/15] ppc/pnv: add a 'dt_isa_nodename' to the chip
  2019-03-08  0:01   ` David Gibson
@ 2019-03-08  6:55     ` Cédric Le Goater
  2019-03-08 11:08       ` David Gibson
  0 siblings, 1 reply; 33+ messages in thread
From: Cédric Le Goater @ 2019-03-08  6:55 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel

On 3/8/19 1:01 AM, David Gibson wrote:
> On Thu, Mar 07, 2019 at 11:35:38PM +0100, Cédric Le Goater wrote:
>> The ISA bus has a different DT nodename on POWER9. Compute the name
>> when the PnvChip is realized, that is before it is used by the machine
>> to populate the device tree with the ISA devices.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> 
> I still tend to think that passing an offset into pnv_dt_isa would
> have been a better solution, but this will serve.  Applied.

Do you mean something like below possibly ? 

   int isa_offset = fdt_path_offset(fdt, pnv->chips[0]->dt_isa_nodename);

   /* Populate ISA devices on chip 0 */
   pnv_dt_isa(pnv->isa_bus, fdt, isa_offset);


pnv_dt_isa() is called at the machine level but we could change it
to be called at the chip level for chip0 only.

C.


>> ---
>>  include/hw/ppc/pnv.h |  2 ++
>>  hw/ppc/pnv.c         | 18 +++++-------------
>>  2 files changed, 7 insertions(+), 13 deletions(-)
>>
>> diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
>> index 8d80cb34eebb..c81f157f41a9 100644
>> --- a/include/hw/ppc/pnv.h
>> +++ b/include/hw/ppc/pnv.h
>> @@ -58,6 +58,8 @@ typedef struct PnvChip {
>>      MemoryRegion xscom_mmio;
>>      MemoryRegion xscom;
>>      AddressSpace xscom_as;
>> +
>> +    gchar        *dt_isa_nodename;
>>  } PnvChip;
>>  
>>  #define TYPE_PNV8_CHIP "pnv8-chip"
>> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
>> index 922e3ec48bb5..6625562d276d 100644
>> --- a/hw/ppc/pnv.c
>> +++ b/hw/ppc/pnv.c
>> @@ -417,24 +417,12 @@ static int pnv_dt_isa_device(DeviceState *dev, void *opaque)
>>      return 0;
>>  }
>>  
>> -static int pnv_chip_isa_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;
>> -}
>> -
>>  /* The default LPC bus of a multichip system is on chip 0. It's
>>   * recognized by the firmware (skiboot) using a "primary" property.
>>   */
>>  static void pnv_dt_isa(PnvMachineState *pnv, void *fdt)
>>  {
>> -    int isa_offset = pnv_chip_isa_offset(pnv->chips[0], fdt);
>> +    int isa_offset = fdt_path_offset(fdt, pnv->chips[0]->dt_isa_nodename);
>>      ForeachPopulateArgs args = {
>>          .fdt = fdt,
>>          .offset = isa_offset,
>> @@ -866,6 +854,10 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
>>                               &error_fatal);
>>      pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip8->lpc.xscom_regs);
>>  
>> +    chip->dt_isa_nodename = g_strdup_printf("/xscom@%" PRIx64 "/isa@%x",
>> +                                            (uint64_t) PNV_XSCOM_BASE(chip),
>> +                                            PNV_XSCOM_LPC_BASE);
>> +
>>      /* Interrupt Management Area. This is the memory region holding
>>       * all the Interrupt Control Presenter (ICP) registers */
>>      pnv_chip_icp_realize(chip8, &local_err);
> 

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

* Re: [Qemu-devel] [PATCH v2 05/15] ppc/pnv: add a 'dt_isa_nodename' to the chip
  2019-03-08  6:55     ` Cédric Le Goater
@ 2019-03-08 11:08       ` David Gibson
  0 siblings, 0 replies; 33+ messages in thread
From: David Gibson @ 2019-03-08 11:08 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

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

On Fri, Mar 08, 2019 at 07:55:33AM +0100, Cédric Le Goater wrote:
> On 3/8/19 1:01 AM, David Gibson wrote:
> > On Thu, Mar 07, 2019 at 11:35:38PM +0100, Cédric Le Goater wrote:
> >> The ISA bus has a different DT nodename on POWER9. Compute the name
> >> when the PnvChip is realized, that is before it is used by the machine
> >> to populate the device tree with the ISA devices.
> >>
> >> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> > 
> > I still tend to think that passing an offset into pnv_dt_isa would
> > have been a better solution, but this will serve.  Applied.
> 
> Do you mean something like below possibly ? 
> 
>    int isa_offset = fdt_path_offset(fdt, pnv->chips[0]->dt_isa_nodename);
> 
>    /* Populate ISA devices on chip 0 */
>    pnv_dt_isa(pnv->isa_bus, fdt, isa_offset);

Yes, although if you do it from the same code that constructed the isa
node in the first place, you should already know its offset without
having to look it up by name.

> pnv_dt_isa() is called at the machine level but we could change it
> to be called at the chip level for chip0 only.

Either or; the machine is already divided into power8 and power9
versions, isn't it?

> 
> C.
> 
> 
> >> ---
> >>  include/hw/ppc/pnv.h |  2 ++
> >>  hw/ppc/pnv.c         | 18 +++++-------------
> >>  2 files changed, 7 insertions(+), 13 deletions(-)
> >>
> >> diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
> >> index 8d80cb34eebb..c81f157f41a9 100644
> >> --- a/include/hw/ppc/pnv.h
> >> +++ b/include/hw/ppc/pnv.h
> >> @@ -58,6 +58,8 @@ typedef struct PnvChip {
> >>      MemoryRegion xscom_mmio;
> >>      MemoryRegion xscom;
> >>      AddressSpace xscom_as;
> >> +
> >> +    gchar        *dt_isa_nodename;
> >>  } PnvChip;
> >>  
> >>  #define TYPE_PNV8_CHIP "pnv8-chip"
> >> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> >> index 922e3ec48bb5..6625562d276d 100644
> >> --- a/hw/ppc/pnv.c
> >> +++ b/hw/ppc/pnv.c
> >> @@ -417,24 +417,12 @@ static int pnv_dt_isa_device(DeviceState *dev, void *opaque)
> >>      return 0;
> >>  }
> >>  
> >> -static int pnv_chip_isa_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;
> >> -}
> >> -
> >>  /* The default LPC bus of a multichip system is on chip 0. It's
> >>   * recognized by the firmware (skiboot) using a "primary" property.
> >>   */
> >>  static void pnv_dt_isa(PnvMachineState *pnv, void *fdt)
> >>  {
> >> -    int isa_offset = pnv_chip_isa_offset(pnv->chips[0], fdt);
> >> +    int isa_offset = fdt_path_offset(fdt, pnv->chips[0]->dt_isa_nodename);
> >>      ForeachPopulateArgs args = {
> >>          .fdt = fdt,
> >>          .offset = isa_offset,
> >> @@ -866,6 +854,10 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
> >>                               &error_fatal);
> >>      pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip8->lpc.xscom_regs);
> >>  
> >> +    chip->dt_isa_nodename = g_strdup_printf("/xscom@%" PRIx64 "/isa@%x",
> >> +                                            (uint64_t) PNV_XSCOM_BASE(chip),
> >> +                                            PNV_XSCOM_LPC_BASE);
> >> +
> >>      /* Interrupt Management Area. This is the memory region holding
> >>       * all the Interrupt Control Presenter (ICP) registers */
> >>      pnv_chip_icp_realize(chip8, &local_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] 33+ messages in thread

end of thread, other threads:[~2019-03-08 12:11 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-07 22:35 [Qemu-devel] [PATCH v2 00/15] ppc: add POWER9 support to the PowerNV platform Cédric Le Goater
2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 01/15] ppc/pnv: add a PSI bridge class model Cédric Le Goater
2019-03-07 23:57   ` David Gibson
2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 02/15] ppc/pnv: add a PSI bridge model for POWER9 Cédric Le Goater
2019-03-07 23:58   ` David Gibson
2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 03/15] ppc/pnv: lpc: fix OPB address ranges Cédric Le Goater
2019-03-07 23:59   ` David Gibson
2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 04/15] ppc/pnv: add a LPC Controller class model Cédric Le Goater
2019-03-07 23:59   ` David Gibson
2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 05/15] ppc/pnv: add a 'dt_isa_nodename' to the chip Cédric Le Goater
2019-03-08  0:01   ` David Gibson
2019-03-08  6:55     ` Cédric Le Goater
2019-03-08 11:08       ` David Gibson
2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 06/15] ppc/pnv: add a LPC Controller model for POWER9 Cédric Le Goater
2019-03-08  0:28   ` David Gibson
2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 07/15] ppc/pnv: add SerIRQ routing registers Cédric Le Goater
2019-03-08  0:28   ` David Gibson
2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 08/15] ppc/pnv: add a OCC model class Cédric Le Goater
2019-03-08  0:29   ` David Gibson
2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 09/15] ppc/pnv: add a OCC model for POWER9 Cédric Le Goater
2019-03-08  0:30   ` David Gibson
2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 10/15] ppc/pnv: extend XSCOM core support " Cédric Le Goater
2019-03-08  0:31   ` David Gibson
2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 11/15] ppc/pnv: POWER9 XSCOM quad support Cédric Le Goater
2019-03-08  0:32   ` David Gibson
2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 12/15] ppc/pnv: activate XSCOM tests for POWER9 Cédric Le Goater
2019-03-08  0:33   ` David Gibson
2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 13/15] ppc/pnv: add more dummy XSCOM addresses Cédric Le Goater
2019-03-08  0:56   ` David Gibson
2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 14/15] ppc/pnv: add a "ibm, opal/power-mgt" device tree node on POWER9 Cédric Le Goater
2019-03-08  0:58   ` David Gibson
2019-03-07 22:35 ` [Qemu-devel] [PATCH v2 15/15] target/ppc: add HV support for POWER9 Cédric Le Goater
2019-03-08  0:59   ` 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.