All of lore.kernel.org
 help / color / mirror / Atom feed
* [PULL 00/88] ppc-for-5.0 queue 20191217
@ 2019-12-17  4:41 David Gibson
  2019-12-17  4:41 ` [PULL 01/88] ppc/pnv: Add a PNOR model David Gibson
                   ` (88 more replies)
  0 siblings, 89 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:41 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

The following changes since commit cb88904a54903ef6ba21a68a61d9cd51e2166304:

  Merge remote-tracking branch 'remotes/amarkovic/tags/mips-queue-dec-16-2019' into staging (2019-12-16 14:07:56 +0000)

are available in the Git repository at:

  git://github.com/dgibson/qemu.git tags/ppc-for-5.0-20191217

for you to fetch changes up to a363e9ed8731f45674260932a340a0d81c4b0a6f:

  pseries: Update SLOF firmware image (2019-12-17 11:40:23 +1100)

----------------------------------------------------------------
ppc patch queue 2019-12-17

This is the first pull request for the qemu-5.0 branch.  It has a lot
of accumulated changes, including:

    * SLOF update to support boot using the IOMMU (will become
      necessary for secure guests)

    * Clean ups to pnv handling of chip models

    * A number of extensions to the powernv machine model

    * TCG extensions to allow powernv emulated systems to run KVM guests

    * Outline support for POWER10 chips in powernv

    * Cleanups to the ibm,client-architecture-support feature negotiation path

    * XIVE reworks to better handle the powernv machine

    * Improvements to not waste interrupt queues and other semi-scarce
      resources when using XIVE under KVM

----------------------------------------------------------------
Alexey Kardashevskiy (1):
      pseries: Update SLOF firmware image

Cédric Le Goater (40):
      ppc/pnv: Add a PNOR model
      ppc/pnv: Add a "/qemu" device tree node
      ppc/pnv: Add a LPC "ranges" property
      ppc/xive: Record the IPB in the associated NVT
      ppc/xive: Introduce helpers for the NVT id
      ppc/pnv: Remove pnv_xive_vst_size() routine
      ppc/pnv: Quiesce some XIVE errors
      ppc/xive: Introduce OS CAM line helpers
      ppc/xive: Check V bit in TM_PULL_POOL_CTX
      ipmi: Add support to customize OEM functions
      ppc/pnv: Add HIOMAP commands
      ppc/pnv: Create BMC devices at machine init
      ppc/xive: Introduce a XivePresenter interface
      ppc/xive: Implement the XivePresenter interface
      ppc/pnv: Loop on the threads of the chip to find a matching NVT
      ppc: Introduce a ppc_cpu_pir() helper
      ppc/pnv: Introduce a pnv_xive_is_cpu_enabled() helper
      ppc/pnv: Fix TIMA indirect access
      ppc/xive: Introduce a XiveFabric interface
      ppc/pnv: Implement the XiveFabric interface
      ppc/spapr: Implement the XiveFabric interface
      ppc/xive: Use the XiveFabric and XivePresenter interfaces
      ppc/xive: Extend the TIMA operation with a XivePresenter parameter
      ppc/pnv: Clarify how the TIMA is accessed on a multichip system
      ppc/xive: Move the TIMA operations to the controller model
      ppc/xive: Remove the get_tctx() XiveRouter handler
      ppc/xive: Introduce a xive_tctx_ipb_update() helper
      ppc/xive: Synthesize interrupt from the saved IPB in the NVT
      ppc/pnv: Introduce a pnv_xive_block_id() helper
      ppc/pnv: Extend XiveRouter with a get_block_id() handler
      ppc/pnv: Dump the XIVE NVT table
      target/ppc: Add POWER10 DD1.0 model information
      ppc/pnv: Introduce a POWER10 PnvChip and a powernv10 machine
      ppc/psi: cleanup definitions
      ppc/pnv: add a PSI bridge model for POWER10
      ppc/pnv: add a LPC Controller model for POWER10
      ppc/pnv: Loop on the whole hierarchy to populate the DT with the XSCOM nodes
      ppc/pnv: populate the DT with realized XSCOM devices
      ppc/pnv: Introduce PBA registers
      ppc/pnv: Fix OCC common area region mapping

David Gibson (4):
      spapr: Don't trigger a CAS reboot for XICS/XIVE mode changeover
      spapr: Improve handling of fdt buffer size
      spapr: Fold h_cas_compose_response() into h_client_architecture_support()
      spapr: Simplify ovec diff

Greg Kurz (38):
      ppc/pnv: Drop "chip" link from POWER9 PSI object
      xive: Link "cpu" property to XiveTCTX::cs pointer
      xive: Link "xive" property to XiveSource::xive pointer
      xive: Link "xive" property to XiveEndSource::xrtr pointer
      ppc/pnv: Link "psi" property to PnvLpc::psi pointer
      ppc/pnv: Link "psi" property to PnvOCC::psi pointer
      ppc/pnv: Link "chip" property to PnvHomer::chip pointer
      ppc/pnv: Link "chip" property to PnvCore::chip pointer
      ppc/pnv: Link "chip" property to PnvXive::chip pointer
      xics: Link ICS_PROP_XICS property to ICSState::xics pointer
      xics: Link ICP_PROP_XICS property to ICPState::xics pointer
      xics: Link ICP_PROP_CPU property to ICPState::cs pointer
      spapr: Abort if XICS interrupt controller cannot be initialized
      xive/kvm: Trigger interrupts from userspace
      ppc/pnv: Instantiate cores separately
      linux-headers: Update
      spapr: Pass the maximum number of vCPUs to the KVM interrupt controller
      spapr/xics: Configure number of servers in KVM
      spapr/xive: Configure number of servers in KVM
      ppc: Deassert the external interrupt pin in KVM on reset
      xics: Don't deassert outputs
      ppc: Don't use CPUPPCState::irq_input_state with modern Book3s CPU models
      ppc: Ignore the CPU_INTERRUPT_EXITTB interrupt with KVM
      ppc: Make PPCVirtualHypervisor an incomplete type
      ppc/pnv: Make PnvXScomInterface an incomplete type
      ppc: Drop useless extern annotation for functions
      ppc/pnv: Introduce PnvPsiClass::compat
      ppc/pnv: Drop PnvPsiClass::chip_type
      ppc/pnv: Introduce PnvMachineClass and PnvMachineClass::compat
      ppc/pnv: Introduce PnvMachineClass::dt_power_mgt()
      ppc/pnv: Drop pnv_is_power9() and pnv_is_power10() helpers
      ppc/pnv: Introduce PnvChipClass::intc_print_info() method
      ppc/pnv: Introduce PnvChipClass::xscom_core_base() method
      ppc/pnv: Pass XSCOM base address and address size to pnv_dt_xscom()
      ppc/pnv: Pass content of the "compatible" property to pnv_dt_xscom()
      ppc/pnv: Drop pnv_chip_is_power9() and pnv_chip_is_power10() helpers
      ppc/pnv: Introduce PnvChipClass::xscom_pcba() method
      ppc/pnv: Drop PnvChipClass::type

Suraj Jitindar Singh (4):
      target/ppc: Implement the VTB for HV access
      target/ppc: Work [S]PURR implementation and add HV support
      target/ppc: Add SPR ASDR
      target/ppc: Add SPR TBU40

Vladimir Sementsov-Ogievskiy (1):
      ppc: well form kvmppc_hint_smt_possible error hint helper

 hw/intc/pnv_xive.c                           | 415 ++++++++++++++--------
 hw/intc/spapr_xive.c                         | 102 +++++-
 hw/intc/spapr_xive_kvm.c                     |  42 ++-
 hw/intc/xics.c                               |  59 +---
 hw/intc/xics_kvm.c                           |  24 +-
 hw/intc/xics_spapr.c                         |   5 +-
 hw/intc/xive.c                               | 398 +++++++++++----------
 hw/ipmi/ipmi_bmc_sim.c                       |  50 +--
 hw/ppc/Makefile.objs                         |   4 +-
 hw/ppc/pnv.c                                 | 504 ++++++++++++++++++++++-----
 hw/ppc/pnv_bmc.c                             | 116 ++++++
 hw/ppc/pnv_core.c                            |  20 +-
 hw/ppc/pnv_homer.c                           | 129 ++++++-
 hw/ppc/pnv_lpc.c                             |  76 ++--
 hw/ppc/pnv_occ.c                             |  31 +-
 hw/ppc/pnv_pnor.c                            | 135 +++++++
 hw/ppc/pnv_psi.c                             |  54 ++-
 hw/ppc/pnv_xscom.c                           |  79 +----
 hw/ppc/ppc.c                                 |  79 +++--
 hw/ppc/spapr.c                               | 133 +++----
 hw/ppc/spapr_hcall.c                         |  90 +++--
 hw/ppc/spapr_irq.c                           |  30 +-
 hw/ppc/spapr_ovec.c                          |  30 +-
 include/hw/ipmi/ipmi.h                       |  42 +++
 include/hw/ppc/pnv.h                         | 109 ++++--
 include/hw/ppc/pnv_homer.h                   |   3 +
 include/hw/ppc/pnv_lpc.h                     |   6 +-
 include/hw/ppc/pnv_occ.h                     |   8 +-
 include/hw/ppc/pnv_pnor.h                    |  30 ++
 include/hw/ppc/pnv_psi.h                     |   5 +-
 include/hw/ppc/pnv_xive.h                    |   3 -
 include/hw/ppc/pnv_xscom.h                   |  58 ++-
 include/hw/ppc/ppc.h                         |   7 +-
 include/hw/ppc/spapr.h                       |   4 +-
 include/hw/ppc/spapr_irq.h                   |  10 +-
 include/hw/ppc/spapr_ovec.h                  |   4 +-
 include/hw/ppc/spapr_vio.h                   |   6 +-
 include/hw/ppc/spapr_xive.h                  |   3 +-
 include/hw/ppc/xics_spapr.h                  |   3 +-
 include/hw/ppc/xive.h                        |  72 +++-
 include/hw/ppc/xive_regs.h                   |  25 ++
 include/standard-headers/linux/ethtool.h     |   6 +
 include/standard-headers/linux/virtio_ring.h |   2 +-
 linux-headers/asm-arm/kvm.h                  |   3 +-
 linux-headers/asm-arm64/kvm.h                |   5 +-
 linux-headers/asm-mips/unistd_n32.h          |   1 +
 linux-headers/asm-mips/unistd_n64.h          |   1 +
 linux-headers/asm-mips/unistd_o32.h          |   1 +
 linux-headers/asm-powerpc/kvm.h              |   3 +
 linux-headers/linux/kvm.h                    |  11 +
 linux-headers/linux/psp-sev.h                |   3 +
 linux-user/ppc/cpu_loop.c                    |   5 +
 pc-bios/README                               |   2 +-
 pc-bios/slof.bin                             | Bin 931040 -> 931032 bytes
 roms/SLOF                                    |   2 +-
 target/ppc/compat.c                          |  21 +-
 target/ppc/cpu-models.c                      |   3 +
 target/ppc/cpu-models.h                      |   3 +
 target/ppc/cpu.h                             |  14 +-
 target/ppc/helper.h                          |   4 +
 target/ppc/helper_regs.h                     |   5 +
 target/ppc/kvm.c                             |   6 +-
 target/ppc/kvm_ppc.h                         |   4 +-
 target/ppc/timebase_helper.c                 |  20 ++
 target/ppc/translate_init.inc.c              | 283 ++++++++++++++-
 65 files changed, 2455 insertions(+), 956 deletions(-)
 create mode 100644 hw/ppc/pnv_pnor.c
 create mode 100644 include/hw/ppc/pnv_pnor.h


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

* [PULL 01/88] ppc/pnv: Add a PNOR model
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
@ 2019-12-17  4:41 ` David Gibson
  2020-01-07 14:43   ` Peter Maydell
  2019-12-17  4:41 ` [PULL 02/88] ppc/pnv: Add a "/qemu" device tree node David Gibson
                   ` (87 subsequent siblings)
  88 siblings, 1 reply; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:41 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, Cédric Le Goater, qemu-ppc,
	clg, David Gibson

From: Cédric Le Goater <clg@fr.ibm.com>

On a POWERPC PowerNV system, the host firmware is stored in a PNOR
flash chip which contents is mapped on the LPC bus. This model adds a
simple dummy device to map the contents of a block device in the host
address space.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191021131215.3693-2-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/Makefile.objs      |   4 +-
 hw/ppc/pnv.c              |  14 ++++
 hw/ppc/pnv_pnor.c         | 135 ++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/pnv.h      |   3 +
 include/hw/ppc/pnv_pnor.h |  25 +++++++
 5 files changed, 180 insertions(+), 1 deletion(-)
 create mode 100644 hw/ppc/pnv_pnor.c
 create mode 100644 include/hw/ppc/pnv_pnor.h

diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index 580bb4f0dd..101e9fc591 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -9,7 +9,9 @@ obj-$(CONFIG_PSERIES) += spapr_tpm_proxy.o
 obj-$(CONFIG_SPAPR_RNG) +=  spapr_rng.o
 # IBM PowerNV
 obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_core.o pnv_lpc.o pnv_psi.o pnv_occ.o pnv_bmc.o
-obj-$(CONFIG_POWERNV) += pnv_homer.o
+obj-$(CONFIG_POWERNV) += pnv_homer.o pnv_pnor.o
+
+
 ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy)
 obj-y += spapr_pci_vfio.o spapr_pci_nvlink2.o
 endif
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 627c08e5b9..d0c1d42277 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -44,6 +44,7 @@
 #include "hw/ppc/xics.h"
 #include "hw/qdev-properties.h"
 #include "hw/ppc/pnv_xscom.h"
+#include "hw/ppc/pnv_pnor.h"
 
 #include "hw/isa/isa.h"
 #include "hw/boards.h"
@@ -633,6 +634,8 @@ static void pnv_init(MachineState *machine)
     long fw_size;
     int i;
     char *chip_typename;
+    DriveInfo *pnor = drive_get(IF_MTD, 0, 0);
+    DeviceState *dev;
 
     /* allocate RAM */
     if (machine->ram_size < (1 * GiB)) {
@@ -644,6 +647,17 @@ static void pnv_init(MachineState *machine)
                                          machine->ram_size);
     memory_region_add_subregion(get_system_memory(), 0, ram);
 
+    /*
+     * Create our simple PNOR device
+     */
+    dev = qdev_create(NULL, TYPE_PNV_PNOR);
+    if (pnor) {
+        qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(pnor),
+                            &error_abort);
+    }
+    qdev_init_nofail(dev);
+    pnv->pnor = PNV_PNOR(dev);
+
     /* load skiboot firmware  */
     if (bios_name == NULL) {
         bios_name = FW_FILE_NAME;
diff --git a/hw/ppc/pnv_pnor.c b/hw/ppc/pnv_pnor.c
new file mode 100644
index 0000000000..bfb1e92b03
--- /dev/null
+++ b/hw/ppc/pnv_pnor.c
@@ -0,0 +1,135 @@
+/*
+ * QEMU PowerNV PNOR simple model
+ *
+ * Copyright (c) 2015-2019, IBM Corporation.
+ *
+ * This code is licensed under the GPL version 2 or later. See the
+ * COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qemu/log.h"
+#include "sysemu/block-backend.h"
+#include "sysemu/blockdev.h"
+#include "hw/loader.h"
+#include "hw/ppc/pnv_pnor.h"
+#include "hw/qdev-properties.h"
+
+static uint64_t pnv_pnor_read(void *opaque, hwaddr addr, unsigned size)
+{
+    PnvPnor *s = PNV_PNOR(opaque);
+    uint64_t ret = 0;
+    int i;
+
+    for (i = 0; i < size; i++) {
+        ret |= (uint64_t) s->storage[addr + i] << (8 * (size - i - 1));
+    }
+
+    return ret;
+}
+
+static void pnv_pnor_update(PnvPnor *s, int offset, int size)
+{
+    int offset_end;
+
+    if (s->blk) {
+        return;
+    }
+
+    offset_end = offset + size;
+    offset = QEMU_ALIGN_DOWN(offset, BDRV_SECTOR_SIZE);
+    offset_end = QEMU_ALIGN_UP(offset_end, BDRV_SECTOR_SIZE);
+
+    blk_pwrite(s->blk, offset, s->storage + offset,
+               offset_end - offset, 0);
+}
+
+static void pnv_pnor_write(void *opaque, hwaddr addr, uint64_t data,
+                           unsigned size)
+{
+    PnvPnor *s = PNV_PNOR(opaque);
+    int i;
+
+    for (i = 0; i < size; i++) {
+        s->storage[addr + i] = (data >> (8 * (size - i - 1))) & 0xFF;
+    }
+    pnv_pnor_update(s, addr, size);
+}
+
+/*
+ * TODO: Check endianness: skiboot is BIG, Aspeed AHB is LITTLE, flash
+ * is BIG.
+ */
+static const MemoryRegionOps pnv_pnor_ops = {
+    .read = pnv_pnor_read,
+    .write = pnv_pnor_write,
+    .endianness = DEVICE_BIG_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 4,
+    },
+};
+
+static void pnv_pnor_realize(DeviceState *dev, Error **errp)
+{
+    PnvPnor *s = PNV_PNOR(dev);
+    int ret;
+
+    if (s->blk) {
+        uint64_t perm = BLK_PERM_CONSISTENT_READ |
+                        (blk_is_read_only(s->blk) ? 0 : BLK_PERM_WRITE);
+        ret = blk_set_perm(s->blk, perm, BLK_PERM_ALL, errp);
+        if (ret < 0) {
+            return;
+        }
+
+        s->size = blk_getlength(s->blk);
+        if (s->size <= 0) {
+            error_setg(errp, "failed to get flash size");
+            return;
+        }
+
+        s->storage = blk_blockalign(s->blk, s->size);
+
+        if (blk_pread(s->blk, 0, s->storage, s->size) != s->size) {
+            error_setg(errp, "failed to read the initial flash content");
+            return;
+        }
+    } else {
+        s->storage = blk_blockalign(NULL, s->size);
+        memset(s->storage, 0xFF, s->size);
+    }
+
+    memory_region_init_io(&s->mmio, OBJECT(s), &pnv_pnor_ops, s,
+                          TYPE_PNV_PNOR, s->size);
+}
+
+static Property pnv_pnor_properties[] = {
+    DEFINE_PROP_UINT32("size", PnvPnor, size, 128 << 20),
+    DEFINE_PROP_DRIVE("drive", PnvPnor, blk),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void pnv_pnor_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = pnv_pnor_realize;
+    dc->props = pnv_pnor_properties;
+}
+
+static const TypeInfo pnv_pnor_info = {
+    .name          = TYPE_PNV_PNOR,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PnvPnor),
+    .class_init    = pnv_pnor_class_init,
+};
+
+static void pnv_pnor_register_types(void)
+{
+    type_register_static(&pnv_pnor_info);
+}
+
+type_init(pnv_pnor_register_types)
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 0b4c722e6b..5ecd3ba6ed 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -24,6 +24,7 @@
 #include "hw/sysbus.h"
 #include "hw/ipmi/ipmi.h"
 #include "hw/ppc/pnv_lpc.h"
+#include "hw/ppc/pnv_pnor.h"
 #include "hw/ppc/pnv_psi.h"
 #include "hw/ppc/pnv_occ.h"
 #include "hw/ppc/pnv_homer.h"
@@ -175,6 +176,8 @@ typedef struct PnvMachineState {
 
     IPMIBmc      *bmc;
     Notifier     powerdown_notifier;
+
+    PnvPnor      *pnor;
 } PnvMachineState;
 
 static inline bool pnv_chip_is_power9(const PnvChip *chip)
diff --git a/include/hw/ppc/pnv_pnor.h b/include/hw/ppc/pnv_pnor.h
new file mode 100644
index 0000000000..dec811695c
--- /dev/null
+++ b/include/hw/ppc/pnv_pnor.h
@@ -0,0 +1,25 @@
+/*
+ * QEMU PowerNV PNOR simple model
+ *
+ * Copyright (c) 2019, IBM Corporation.
+ *
+ * This code is licensed under the GPL version 2 or later. See the
+ * COPYING file in the top-level directory.
+ */
+#ifndef _PPC_PNV_PNOR_H
+#define _PPC_PNV_PNOR_H
+
+#define TYPE_PNV_PNOR  "pnv-pnor"
+#define PNV_PNOR(obj)  OBJECT_CHECK(PnvPnor, (obj), TYPE_PNV_PNOR)
+
+typedef struct PnvPnor {
+    SysBusDevice   parent_obj;
+
+    BlockBackend   *blk;
+
+    uint8_t        *storage;
+    uint32_t       size;
+    MemoryRegion   mmio;
+} PnvPnor;
+
+#endif /* _PPC_PNV_PNOR_H */
-- 
2.23.0



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

* [PULL 02/88] ppc/pnv: Add a "/qemu" device tree node
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
  2019-12-17  4:41 ` [PULL 01/88] ppc/pnv: Add a PNOR model David Gibson
@ 2019-12-17  4:41 ` David Gibson
  2019-12-17  4:41 ` [PULL 03/88] ppc/pnv: Drop "chip" link from POWER9 PSI object David Gibson
                   ` (86 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:41 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

It helps skiboot identifying that is running on a QEMU platform. The
compatible string will define the POWERPC processor version.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191106142129.4908-1-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index d0c1d42277..416caab6f6 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -480,6 +480,9 @@ static void *pnv_dt_create(MachineState *machine)
     fdt = g_malloc0(FDT_MAX_SIZE);
     _FDT((fdt_create_empty_tree(fdt, FDT_MAX_SIZE)));
 
+    /* /qemu node */
+    _FDT((fdt_add_subnode(fdt, 0, "qemu")));
+
     /* Root node */
     _FDT((fdt_setprop_cell(fdt, 0, "#address-cells", 0x2)));
     _FDT((fdt_setprop_cell(fdt, 0, "#size-cells", 0x2)));
-- 
2.23.0



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

* [PULL 03/88] ppc/pnv: Drop "chip" link from POWER9 PSI object
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
  2019-12-17  4:41 ` [PULL 01/88] ppc/pnv: Add a PNOR model David Gibson
  2019-12-17  4:41 ` [PULL 02/88] ppc/pnv: Add a "/qemu" device tree node David Gibson
@ 2019-12-17  4:41 ` David Gibson
  2019-12-17  4:41 ` [PULL 04/88] xive: Link "cpu" property to XiveTCTX::cs pointer David Gibson
                   ` (85 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:41 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

It has no apparent user.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157383383118.166856.2588933416368211047.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 416caab6f6..4e9ddc05ad 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1096,8 +1096,6 @@ static void pnv_chip_power9_instance_init(Object *obj)
 
     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);
 
     object_initialize_child(obj, "lpc",  &chip9->lpc, sizeof(chip9->lpc),
                             TYPE_PNV9_LPC, &error_abort, NULL);
-- 
2.23.0



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

* [PULL 04/88] xive: Link "cpu" property to XiveTCTX::cs pointer
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (2 preceding siblings ...)
  2019-12-17  4:41 ` [PULL 03/88] ppc/pnv: Drop "chip" link from POWER9 PSI object David Gibson
@ 2019-12-17  4:41 ` David Gibson
  2019-12-17  4:41 ` [PULL 05/88] xive: Link "xive" property to XiveSource::xive pointer David Gibson
                   ` (84 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:41 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The TCTX object has both a pointer and a "cpu" property pointing to the
vCPU object. Confusing bugs could arise if these ever go out of sync.

Change the property definition so that it explicitely sets the pointer.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157383332669.165747.2484056603605646820.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/xive.c | 22 +++++++++-------------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 75dce82fb2..9376e84aff 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -580,19 +580,11 @@ static void xive_tctx_realize(DeviceState *dev, Error **errp)
     XiveTCTX *tctx = XIVE_TCTX(dev);
     PowerPCCPU *cpu;
     CPUPPCState *env;
-    Object *obj;
     Error *local_err = NULL;
 
-    obj = object_property_get_link(OBJECT(dev), "cpu", &local_err);
-    if (!obj) {
-        error_propagate(errp, local_err);
-        error_prepend(errp, "required link 'cpu' not found: ");
-        return;
-    }
-
-    cpu = POWERPC_CPU(obj);
-    tctx->cs = CPU(obj);
+    assert(tctx->cs);
 
+    cpu = POWERPC_CPU(tctx->cs);
     env = &cpu->env;
     switch (PPC_INPUT(env)) {
     case PPC_FLAGS_INPUT_POWER9:
@@ -662,6 +654,11 @@ static const VMStateDescription vmstate_xive_tctx = {
     },
 };
 
+static Property xive_tctx_properties[] = {
+    DEFINE_PROP_LINK("cpu", XiveTCTX, cs, TYPE_CPU, CPUState *),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void xive_tctx_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -669,6 +666,7 @@ static void xive_tctx_class_init(ObjectClass *klass, void *data)
     dc->desc = "XIVE Interrupt Thread Context";
     dc->realize = xive_tctx_realize;
     dc->vmsd = &vmstate_xive_tctx;
+    dc->props = xive_tctx_properties;
     /*
      * Reason: part of XIVE interrupt controller, needs to be wired up
      * by xive_tctx_create().
@@ -691,8 +689,7 @@ Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp)
     obj = object_new(TYPE_XIVE_TCTX);
     object_property_add_child(cpu, TYPE_XIVE_TCTX, obj, &error_abort);
     object_unref(obj);
-    object_ref(cpu);
-    object_property_add_const_link(obj, "cpu", cpu, &error_abort);
+    object_property_set_link(obj, cpu, "cpu", &error_abort);
     object_property_set_bool(obj, true, "realized", &local_err);
     if (local_err) {
         goto error;
@@ -710,7 +707,6 @@ void xive_tctx_destroy(XiveTCTX *tctx)
 {
     Object *obj = OBJECT(tctx);
 
-    object_unref(object_property_get_link(obj, "cpu", &error_abort));
     object_unparent(obj);
 }
 
-- 
2.23.0



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

* [PULL 05/88] xive: Link "xive" property to XiveSource::xive pointer
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (3 preceding siblings ...)
  2019-12-17  4:41 ` [PULL 04/88] xive: Link "cpu" property to XiveTCTX::cs pointer David Gibson
@ 2019-12-17  4:41 ` David Gibson
  2019-12-17  4:42 ` [PULL 06/88] xive: Link "xive" property to XiveEndSource::xrtr pointer David Gibson
                   ` (83 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:41 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The source object has both a pointer and a "xive" property pointing to the
notifier object. Confusing bugs could arise if these ever go out of sync.

Change the property definition so that it explicitely sets the pointer.
The property isn't optional : not being able to set the link is a bug
and QEMU should rather abort than exit in this case.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157383333227.165747.12901571295951957951.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/pnv_xive.c   |  4 ++--
 hw/intc/spapr_xive.c |  4 ++--
 hw/intc/xive.c       | 13 +++----------
 hw/ppc/pnv_psi.c     |  3 +--
 4 files changed, 8 insertions(+), 16 deletions(-)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 348f2fdd26..9e23dc705d 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -1695,8 +1695,8 @@ static void pnv_xive_realize(DeviceState *dev, Error **errp)
      */
     object_property_set_int(OBJECT(xsrc), PNV_XIVE_NR_IRQS, "nr-irqs",
                             &error_fatal);
-    object_property_add_const_link(OBJECT(xsrc), "xive", OBJECT(xive),
-                                   &error_fatal);
+    object_property_set_link(OBJECT(xsrc), OBJECT(xive), "xive",
+                             &error_abort);
     object_property_set_bool(OBJECT(xsrc), true, "realized", &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 9cb8d38a3b..10890aeeeb 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -276,8 +276,8 @@ static void spapr_xive_realize(DeviceState *dev, Error **errp)
      */
     object_property_set_int(OBJECT(xsrc), xive->nr_irqs, "nr-irqs",
                             &error_fatal);
-    object_property_add_const_link(OBJECT(xsrc), "xive", OBJECT(xive),
-                                   &error_fatal);
+    object_property_set_link(OBJECT(xsrc), OBJECT(xive), "xive",
+                             &error_abort);
     object_property_set_bool(OBJECT(xsrc), true, "realized", &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 9376e84aff..2eac15efa6 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1060,17 +1060,8 @@ static void xive_source_reset(void *dev)
 static void xive_source_realize(DeviceState *dev, Error **errp)
 {
     XiveSource *xsrc = XIVE_SOURCE(dev);
-    Object *obj;
-    Error *local_err = NULL;
-
-    obj = object_property_get_link(OBJECT(dev), "xive", &local_err);
-    if (!obj) {
-        error_propagate(errp, local_err);
-        error_prepend(errp, "required link 'xive' not found: ");
-        return;
-    }
 
-    xsrc->xive = XIVE_NOTIFIER(obj);
+    assert(xsrc->xive);
 
     if (!xsrc->nr_irqs) {
         error_setg(errp, "Number of interrupt needs to be greater than 0");
@@ -1116,6 +1107,8 @@ static Property xive_source_properties[] = {
     DEFINE_PROP_UINT64("flags", XiveSource, esb_flags, 0),
     DEFINE_PROP_UINT32("nr-irqs", XiveSource, nr_irqs, 0),
     DEFINE_PROP_UINT32("shift", XiveSource, esb_shift, XIVE_ESB_64K_2PAGE),
+    DEFINE_PROP_LINK("xive", XiveSource, xive, TYPE_XIVE_NOTIFIER,
+                     XiveNotifier *),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
index 68d0dfacfe..a360515a86 100644
--- a/hw/ppc/pnv_psi.c
+++ b/hw/ppc/pnv_psi.c
@@ -851,8 +851,7 @@ static void pnv_psi_power9_realize(DeviceState *dev, Error **errp)
                             &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_link(OBJECT(xsrc), OBJECT(psi), "xive", &error_abort);
     object_property_set_bool(OBJECT(xsrc), true, "realized", &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
-- 
2.23.0



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

* [PULL 06/88] xive: Link "xive" property to XiveEndSource::xrtr pointer
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (4 preceding siblings ...)
  2019-12-17  4:41 ` [PULL 05/88] xive: Link "xive" property to XiveSource::xive pointer David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 07/88] ppc/pnv: Link "psi" property to PnvLpc::psi pointer David Gibson
                   ` (82 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The END source object has both a pointer and a "xive" property pointing to
the router object. Confusing bugs could arise if these ever go out of sync.

Change the property definition so that it explicitely sets the pointer.
The property isn't optional : not being able to set the link is a bug
and QEMU should rather abort than exit in this case.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157383333784.165747.5298512574054268786.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/pnv_xive.c   |  4 ++--
 hw/intc/spapr_xive.c |  4 ++--
 hw/intc/xive.c       | 13 +++----------
 3 files changed, 7 insertions(+), 14 deletions(-)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 9e23dc705d..6aa7aeed6f 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -1705,8 +1705,8 @@ static void pnv_xive_realize(DeviceState *dev, Error **errp)
 
     object_property_set_int(OBJECT(end_xsrc), PNV_XIVE_NR_ENDS, "nr-ends",
                             &error_fatal);
-    object_property_add_const_link(OBJECT(end_xsrc), "xive", OBJECT(xive),
-                                   &error_fatal);
+    object_property_set_link(OBJECT(end_xsrc), OBJECT(xive), "xive",
+                             &error_abort);
     object_property_set_bool(OBJECT(end_xsrc), true, "realized", &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 10890aeeeb..729246e906 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -290,8 +290,8 @@ static void spapr_xive_realize(DeviceState *dev, Error **errp)
      */
     object_property_set_int(OBJECT(end_xsrc), xive->nr_irqs, "nr-ends",
                             &error_fatal);
-    object_property_add_const_link(OBJECT(end_xsrc), "xive", OBJECT(xive),
-                                   &error_fatal);
+    object_property_set_link(OBJECT(end_xsrc), OBJECT(xive), "xive",
+                             &error_abort);
     object_property_set_bool(OBJECT(end_xsrc), true, "realized", &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 2eac15efa6..3d472e29c8 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1814,17 +1814,8 @@ static const MemoryRegionOps xive_end_source_ops = {
 static void xive_end_source_realize(DeviceState *dev, Error **errp)
 {
     XiveENDSource *xsrc = XIVE_END_SOURCE(dev);
-    Object *obj;
-    Error *local_err = NULL;
-
-    obj = object_property_get_link(OBJECT(dev), "xive", &local_err);
-    if (!obj) {
-        error_propagate(errp, local_err);
-        error_prepend(errp, "required link 'xive' not found: ");
-        return;
-    }
 
-    xsrc->xrtr = XIVE_ROUTER(obj);
+    assert(xsrc->xrtr);
 
     if (!xsrc->nr_ends) {
         error_setg(errp, "Number of interrupt needs to be greater than 0");
@@ -1850,6 +1841,8 @@ static Property xive_end_source_properties[] = {
     DEFINE_PROP_UINT8("block-id", XiveENDSource, block_id, 0),
     DEFINE_PROP_UINT32("nr-ends", XiveENDSource, nr_ends, 0),
     DEFINE_PROP_UINT32("shift", XiveENDSource, esb_shift, XIVE_ESB_64K),
+    DEFINE_PROP_LINK("xive", XiveENDSource, xrtr, TYPE_XIVE_ROUTER,
+                     XiveRouter *),
     DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.23.0



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

* [PULL 07/88] ppc/pnv: Link "psi" property to PnvLpc::psi pointer
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (5 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 06/88] xive: Link "xive" property to XiveEndSource::xrtr pointer David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 08/88] ppc/pnv: Link "psi" property to PnvOCC::psi pointer David Gibson
                   ` (81 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The LPC object has both a pointer and a "psi" property pointing to the
PSI object. Confusing bugs could arise if these ever go out of sync.

Change the property definition so that it explicitely sets the pointer.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157383334342.165747.3159314903077305653.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c     |  8 ++++----
 hw/ppc/pnv_lpc.c | 19 ++++++++-----------
 2 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 4e9ddc05ad..201facc701 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -901,8 +901,6 @@ static void pnv_chip_power8_instance_init(Object *obj)
 
     object_initialize_child(obj, "lpc",  &chip8->lpc, sizeof(chip8->lpc),
                             TYPE_PNV8_LPC, &error_abort, NULL);
-    object_property_add_const_link(OBJECT(&chip8->lpc), "psi",
-                                   OBJECT(&chip8->psi), &error_abort);
 
     object_initialize_child(obj, "occ",  &chip8->occ, sizeof(chip8->occ),
                             TYPE_PNV8_OCC, &error_abort, NULL);
@@ -981,6 +979,8 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
                             &PNV_PSI(psi8)->xscom_regs);
 
     /* Create LPC controller */
+    object_property_set_link(OBJECT(&chip8->lpc), OBJECT(&chip8->psi), "psi",
+                             &error_abort);
     object_property_set_bool(OBJECT(&chip8->lpc), true, "realized",
                              &error_fatal);
     pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip8->lpc.xscom_regs);
@@ -1099,8 +1099,6 @@ static void pnv_chip_power9_instance_init(Object *obj)
 
     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);
 
     object_initialize_child(obj, "occ",  &chip9->occ, sizeof(chip9->occ),
                             TYPE_PNV9_OCC, &error_abort, NULL);
@@ -1199,6 +1197,8 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
                             &PNV_PSI(psi9)->xscom_regs);
 
     /* LPC */
+    object_property_set_link(OBJECT(&chip9->lpc), OBJECT(&chip9->psi), "psi",
+                             &error_abort);
     object_property_set_bool(OBJECT(&chip9->lpc), true, "realized", &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index 9466d4a1be..fb9f930320 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -24,7 +24,7 @@
 #include "qemu/module.h"
 #include "hw/irq.h"
 #include "hw/isa/isa.h"
-
+#include "hw/qdev-properties.h"
 #include "hw/ppc/pnv.h"
 #include "hw/ppc/pnv_lpc.h"
 #include "hw/ppc/pnv_xscom.h"
@@ -682,17 +682,8 @@ static const TypeInfo pnv_lpc_power9_info = {
 static void pnv_lpc_realize(DeviceState *dev, Error **errp)
 {
     PnvLpcController *lpc = PNV_LPC(dev);
-    Object *obj;
-    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);
+    assert(lpc->psi);
 
     /* Reg inits */
     lpc->lpc_hc_fw_rd_acc_size = LPC_HC_FW_RD_4B;
@@ -734,12 +725,18 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
                                 &lpc->lpc_hc_regs);
 }
 
+static Property pnv_lpc_properties[] = {
+    DEFINE_PROP_LINK("psi", PnvLpcController, psi, TYPE_PNV_PSI, PnvPsi *),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void pnv_lpc_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->realize = pnv_lpc_realize;
     dc->desc = "PowerNV LPC Controller";
+    dc->props = pnv_lpc_properties;
 }
 
 static const TypeInfo pnv_lpc_info = {
-- 
2.23.0



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

* [PULL 08/88] ppc/pnv: Link "psi" property to PnvOCC::psi pointer
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (6 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 07/88] ppc/pnv: Link "psi" property to PnvLpc::psi pointer David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 09/88] ppc/pnv: Link "chip" property to PnvHomer::chip pointer David Gibson
                   ` (80 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The OCC object has both a pointer and a "psi" property pointing to the
PSI object. Confusing bugs could arise if these ever go out of sync.

Change the property definition so that it explicitely sets the pointer.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157383334894.165747.7617090757862105199.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c     |  8 ++++----
 hw/ppc/pnv_occ.c | 20 +++++++++-----------
 2 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 201facc701..ce24a4ee99 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -904,8 +904,6 @@ static void pnv_chip_power8_instance_init(Object *obj)
 
     object_initialize_child(obj, "occ",  &chip8->occ, sizeof(chip8->occ),
                             TYPE_PNV8_OCC, &error_abort, NULL);
-    object_property_add_const_link(OBJECT(&chip8->occ), "psi",
-                                   OBJECT(&chip8->psi), &error_abort);
 
     object_initialize_child(obj, "homer",  &chip8->homer, sizeof(chip8->homer),
                             TYPE_PNV8_HOMER, &error_abort, NULL);
@@ -1000,6 +998,8 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
     }
 
     /* Create the simplified OCC model */
+    object_property_set_link(OBJECT(&chip8->occ), OBJECT(&chip8->psi), "psi",
+                             &error_abort);
     object_property_set_bool(OBJECT(&chip8->occ), true, "realized", &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
@@ -1102,8 +1102,6 @@ static void pnv_chip_power9_instance_init(Object *obj)
 
     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);
 
     object_initialize_child(obj, "homer",  &chip9->homer, sizeof(chip9->homer),
                             TYPE_PNV9_HOMER, &error_abort, NULL);
@@ -1211,6 +1209,8 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
                                             (uint64_t) PNV9_LPCM_BASE(chip));
 
     /* Create the simplified OCC model */
+    object_property_set_link(OBJECT(&chip9->occ), OBJECT(&chip9->psi), "psi",
+                             &error_abort);
     object_property_set_bool(OBJECT(&chip9->occ), true, "realized", &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c
index 785653bb67..765c0a6ce5 100644
--- a/hw/ppc/pnv_occ.c
+++ b/hw/ppc/pnv_occ.c
@@ -21,7 +21,7 @@
 #include "qapi/error.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
-
+#include "hw/qdev-properties.h"
 #include "hw/ppc/pnv.h"
 #include "hw/ppc/pnv_xscom.h"
 #include "hw/ppc/pnv_occ.h"
@@ -257,18 +257,10 @@ static void pnv_occ_realize(DeviceState *dev, Error **errp)
 {
     PnvOCC *occ = PNV_OCC(dev);
     PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
-    Object *obj;
-    Error *local_err = NULL;
 
-    occ->occmisc = 0;
+    assert(occ->psi);
 
-    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;
-    }
-    occ->psi = PNV_PSI(obj);
+    occ->occmisc = 0;
 
     /* XScom region for OCC registers */
     pnv_xscom_region_init(&occ->xscom_regs, OBJECT(dev), poc->xscom_ops,
@@ -279,12 +271,18 @@ static void pnv_occ_realize(DeviceState *dev, Error **errp)
                           occ, "occ-common-area", poc->sram_size);
 }
 
+static Property pnv_occ_properties[] = {
+    DEFINE_PROP_LINK("psi", PnvOCC, psi, TYPE_PNV_PSI, PnvPsi *),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 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";
+    dc->props = pnv_occ_properties;
 }
 
 static const TypeInfo pnv_occ_type_info = {
-- 
2.23.0



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

* [PULL 09/88] ppc/pnv: Link "chip" property to PnvHomer::chip pointer
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (7 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 08/88] ppc/pnv: Link "psi" property to PnvOCC::psi pointer David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 10/88] ppc/pnv: Link "chip" property to PnvCore::chip pointer David Gibson
                   ` (79 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The homer object has both a pointer and a "chip" property pointing to the
chip object. Confusing bugs could arise if these ever go out of sync.

Change the property definition so that it explicitely sets the pointer.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157383335451.165747.32301068645427993.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c       |  8 ++++----
 hw/ppc/pnv_homer.c | 20 ++++++++++----------
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index ce24a4ee99..3fa24a2d60 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -907,8 +907,6 @@ static void pnv_chip_power8_instance_init(Object *obj)
 
     object_initialize_child(obj, "homer",  &chip8->homer, sizeof(chip8->homer),
                             TYPE_PNV8_HOMER, &error_abort, NULL);
-    object_property_add_const_link(OBJECT(&chip8->homer), "chip", obj,
-                                   &error_abort);
 }
 
 static void pnv_chip_icp_realize(Pnv8Chip *chip8, Error **errp)
@@ -1012,6 +1010,8 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
                                 &chip8->occ.sram_regs);
 
     /* HOMER */
+    object_property_set_link(OBJECT(&chip8->homer), OBJECT(chip), "chip",
+                             &error_abort);
     object_property_set_bool(OBJECT(&chip8->homer), true, "realized",
                              &local_err);
     if (local_err) {
@@ -1105,8 +1105,6 @@ static void pnv_chip_power9_instance_init(Object *obj)
 
     object_initialize_child(obj, "homer",  &chip9->homer, sizeof(chip9->homer),
                             TYPE_PNV9_HOMER, &error_abort, NULL);
-    object_property_add_const_link(OBJECT(&chip9->homer), "chip", obj,
-                                   &error_abort);
 }
 
 static void pnv_chip_quad_realize(Pnv9Chip *chip9, Error **errp)
@@ -1223,6 +1221,8 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
                                 &chip9->occ.sram_regs);
 
     /* HOMER */
+    object_property_set_link(OBJECT(&chip9->homer), OBJECT(chip), "chip",
+                             &error_abort);
     object_property_set_bool(OBJECT(&chip9->homer), true, "realized",
                              &local_err);
     if (local_err) {
diff --git a/hw/ppc/pnv_homer.c b/hw/ppc/pnv_homer.c
index cc881a3b32..994a378108 100644
--- a/hw/ppc/pnv_homer.c
+++ b/hw/ppc/pnv_homer.c
@@ -22,6 +22,7 @@
 #include "exec/memory.h"
 #include "sysemu/cpus.h"
 #include "hw/qdev-core.h"
+#include "hw/qdev-properties.h"
 #include "hw/ppc/pnv.h"
 #include "hw/ppc/pnv_homer.h"
 
@@ -229,28 +230,27 @@ static void pnv_homer_realize(DeviceState *dev, Error **errp)
 {
     PnvHomer *homer = PNV_HOMER(dev);
     PnvHomerClass *hmrc = PNV_HOMER_GET_CLASS(homer);
-    Object *obj;
-    Error *local_err = NULL;
-
-    obj = object_property_get_link(OBJECT(dev), "chip", &local_err);
-    if (!obj) {
-        error_propagate(errp, local_err);
-        error_prepend(errp, "required link 'chip' not found: ");
-        return;
-    }
-    homer->chip = PNV_CHIP(obj);
+
+    assert(homer->chip);
+
     /* homer region */
     memory_region_init_io(&homer->regs, OBJECT(dev),
                           hmrc->homer_ops, homer, "homer-main-memory",
                           hmrc->homer_size);
 }
 
+static Property pnv_homer_properties[] = {
+    DEFINE_PROP_LINK("chip", PnvHomer, chip, TYPE_PNV_CHIP, PnvChip *),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void pnv_homer_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->realize = pnv_homer_realize;
     dc->desc = "PowerNV HOMER Memory";
+    dc->props = pnv_homer_properties;
 }
 
 static const TypeInfo pnv_homer_type_info = {
-- 
2.23.0



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

* [PULL 10/88] ppc/pnv: Link "chip" property to PnvCore::chip pointer
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (8 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 09/88] ppc/pnv: Link "chip" property to PnvHomer::chip pointer David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 11/88] ppc/pnv: Link "chip" property to PnvXive::chip pointer David Gibson
                   ` (78 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The core object has both a pointer and a "chip" property pointing to the
chip object. Confusing bugs could arise if these ever go out of sync.

Change the property definition so that it explicitely sets the pointer.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157383336007.165747.1524120147081367440.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c      |  4 ++--
 hw/ppc/pnv_core.c | 10 ++--------
 2 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 3fa24a2d60..2bf8a3b23b 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1327,8 +1327,8 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
         object_property_set_int(OBJECT(pnv_core),
                                 pcc->core_pir(chip, core_hwid),
                                 "pir", &error_fatal);
-        object_property_add_const_link(OBJECT(pnv_core), "chip",
-                                       OBJECT(chip), &error_fatal);
+        object_property_set_link(OBJECT(pnv_core), OBJECT(chip), "chip",
+                                 &error_abort);
         object_property_set_bool(OBJECT(pnv_core), true, "realized",
                                  &error_fatal);
 
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 61b3d3ce22..5ab75bde6c 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -217,15 +217,8 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
     void *obj;
     int i, j;
     char name[32];
-    Object *chip;
 
-    chip = object_property_get_link(OBJECT(dev), "chip", &local_err);
-    if (!chip) {
-        error_propagate_prepend(errp, local_err,
-                                "required link 'chip' not found: ");
-        return;
-    }
-    pc->chip = PNV_CHIP(chip);
+    assert(pc->chip);
 
     pc->threads = g_new(PowerPCCPU *, cc->nr_threads);
     for (i = 0; i < cc->nr_threads; i++) {
@@ -297,6 +290,7 @@ static void pnv_core_unrealize(DeviceState *dev, Error **errp)
 
 static Property pnv_core_properties[] = {
     DEFINE_PROP_UINT32("pir", PnvCore, pir, 0),
+    DEFINE_PROP_LINK("chip", PnvCore, chip, TYPE_PNV_CHIP, PnvChip *),
     DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.23.0



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

* [PULL 11/88] ppc/pnv: Link "chip" property to PnvXive::chip pointer
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (9 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 10/88] ppc/pnv: Link "chip" property to PnvCore::chip pointer David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 12/88] xics: Link ICS_PROP_XICS property to ICSState::xics pointer David Gibson
                   ` (77 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The XIVE object has both a pointer and a "chip" property pointing to the
chip object. Confusing bugs could arise if these ever go out of sync.

Change the property definition so that it explicitely sets the pointer.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157383336564.165747.10250365296928442882.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/pnv_xive.c | 13 +++----------
 hw/ppc/pnv.c       |  4 ++--
 2 files changed, 5 insertions(+), 12 deletions(-)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 6aa7aeed6f..4e56c2e468 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -1675,17 +1675,8 @@ static void pnv_xive_realize(DeviceState *dev, Error **errp)
     XiveSource *xsrc = &xive->ipi_source;
     XiveENDSource *end_xsrc = &xive->end_source;
     Error *local_err = NULL;
-    Object *obj;
 
-    obj = object_property_get_link(OBJECT(dev), "chip", &local_err);
-    if (!obj) {
-        error_propagate(errp, local_err);
-        error_prepend(errp, "required link 'chip' not found: ");
-        return;
-    }
-
-    /* The PnvChip id identifies the XIVE interrupt controller. */
-    xive->chip = PNV_CHIP(obj);
+    assert(xive->chip);
 
     /*
      * The XiveSource and XiveENDSource objects are realized with the
@@ -1800,6 +1791,8 @@ static Property pnv_xive_properties[] = {
     DEFINE_PROP_UINT64("vc-bar", PnvXive, vc_base, 0),
     DEFINE_PROP_UINT64("pc-bar", PnvXive, pc_base, 0),
     DEFINE_PROP_UINT64("tm-bar", PnvXive, tm_base, 0),
+    /* The PnvChip id identifies the XIVE interrupt controller. */
+    DEFINE_PROP_LINK("chip", PnvXive, chip, TYPE_PNV_CHIP, PnvChip *),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 2bf8a3b23b..a2a8b97330 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1091,8 +1091,6 @@ static void pnv_chip_power9_instance_init(Object *obj)
 
     object_initialize_child(obj, "xive", &chip9->xive, sizeof(chip9->xive),
                             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);
@@ -1172,6 +1170,8 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
                             "pc-bar", &error_fatal);
     object_property_set_int(OBJECT(&chip9->xive), PNV9_XIVE_TM_BASE(chip),
                             "tm-bar", &error_fatal);
+    object_property_set_link(OBJECT(&chip9->xive), OBJECT(chip), "chip",
+                             &error_abort);
     object_property_set_bool(OBJECT(&chip9->xive), true, "realized",
                              &local_err);
     if (local_err) {
-- 
2.23.0



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

* [PULL 12/88] xics: Link ICS_PROP_XICS property to ICSState::xics pointer
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (10 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 11/88] ppc/pnv: Link "chip" property to PnvXive::chip pointer David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 13/88] xics: Link ICP_PROP_XICS property to ICPState::xics pointer David Gibson
                   ` (76 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The ICS object has both a pointer and an ICS_PROP_XICS property pointing
to the XICS fabric. Confusing bugs could arise if these ever go out of
sync.

Change the property definition so that it explicitely sets the pointer.
The property isn't optional : not being able to set the link is a bug
and QEMU should rather abort than exit in this case.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157403283596.409804.17347207690271971987.stgit@bahia.lan>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/xics.c     | 13 +++----------
 hw/ppc/pnv_psi.c   |  3 +--
 hw/ppc/spapr_irq.c |  9 ++-------
 3 files changed, 6 insertions(+), 19 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index e7ac9ba618..f7a4548089 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -609,17 +609,8 @@ static void ics_reset_handler(void *dev)
 static void ics_realize(DeviceState *dev, Error **errp)
 {
     ICSState *ics = ICS(dev);
-    Error *local_err = NULL;
-    Object *obj;
 
-    obj = object_property_get_link(OBJECT(dev), ICS_PROP_XICS, &local_err);
-    if (!obj) {
-        error_propagate_prepend(errp, local_err,
-                                "required link '" ICS_PROP_XICS
-                                "' not found: ");
-        return;
-    }
-    ics->xics = XICS_FABRIC(obj);
+    assert(ics->xics);
 
     if (!ics->nr_irqs) {
         error_setg(errp, "Number of interrupts needs to be greater 0");
@@ -699,6 +690,8 @@ static const VMStateDescription vmstate_ics = {
 
 static Property ics_properties[] = {
     DEFINE_PROP_UINT32("nr-irqs", ICSState, nr_irqs, 0),
+    DEFINE_PROP_LINK(ICS_PROP_XICS, ICSState, xics, TYPE_XICS_FABRIC,
+                     XICSFabric *),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
index a360515a86..7e725aaf2b 100644
--- a/hw/ppc/pnv_psi.c
+++ b/hw/ppc/pnv_psi.c
@@ -497,8 +497,7 @@ static void pnv_psi_power8_realize(DeviceState *dev, Error **errp)
     }
 
     /* Create PSI interrupt control source */
-    object_property_add_const_link(OBJECT(ics), ICS_PROP_XICS, obj,
-                                   &error_abort);
+    object_property_set_link(OBJECT(ics), obj, ICS_PROP_XICS, &error_abort);
     object_property_set_int(OBJECT(ics), PSI_NUM_INTERRUPTS, "nr-irqs", &err);
     if (err) {
         error_propagate(errp, err);
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index d6bb7fd2d6..fbdda14372 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -319,13 +319,8 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
             return;
         }
 
-        object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
-                                       &local_err);
-        if (local_err) {
-            error_propagate(errp, local_err);
-            return;
-        }
-
+        object_property_set_link(obj, OBJECT(spapr), ICS_PROP_XICS,
+                                 &error_abort);
         object_property_set_int(obj, smc->nr_xirqs, "nr-irqs", &local_err);
         if (local_err) {
             error_propagate(errp, local_err);
-- 
2.23.0



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

* [PULL 13/88] xics: Link ICP_PROP_XICS property to ICPState::xics pointer
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (11 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 12/88] xics: Link ICS_PROP_XICS property to ICSState::xics pointer David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 14/88] xics: Link ICP_PROP_CPU property to ICPState::cs pointer David Gibson
                   ` (75 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The ICP object has both a pointer and an ICP_PROP_XICS property pointing
to the XICS fabric. Confusing bugs could arise if these ever go out of
sync.

Change the property definition so that it explicitly sets the pointer.
The property isn't optional : not being able to set the link is a bug
and QEMU should rather abort than exit in this case.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157403284152.409804.17114564311521923733.stgit@bahia.lan>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/xics.c | 22 +++++++++-------------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index f7a4548089..35dddb8867 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -310,15 +310,7 @@ static void icp_realize(DeviceState *dev, Error **errp)
     Object *obj;
     Error *err = NULL;
 
-    obj = object_property_get_link(OBJECT(dev), ICP_PROP_XICS, &err);
-    if (!obj) {
-        error_propagate_prepend(errp, err,
-                                "required link '" ICP_PROP_XICS
-                                "' not found: ");
-        return;
-    }
-
-    icp->xics = XICS_FABRIC(obj);
+    assert(icp->xics);
 
     obj = object_property_get_link(OBJECT(dev), ICP_PROP_CPU, &err);
     if (!obj) {
@@ -368,12 +360,19 @@ static void icp_unrealize(DeviceState *dev, Error **errp)
     vmstate_unregister(NULL, &vmstate_icp_server, icp);
 }
 
+static Property icp_properties[] = {
+    DEFINE_PROP_LINK(ICP_PROP_XICS, ICPState, xics, TYPE_XICS_FABRIC,
+                     XICSFabric *),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void icp_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->realize = icp_realize;
     dc->unrealize = icp_unrealize;
+    dc->props = icp_properties;
     /*
      * Reason: part of XICS interrupt controller, needs to be wired up
      * by icp_create().
@@ -397,9 +396,7 @@ Object *icp_create(Object *cpu, const char *type, XICSFabric *xi, Error **errp)
     obj = object_new(type);
     object_property_add_child(cpu, type, obj, &error_abort);
     object_unref(obj);
-    object_ref(OBJECT(xi));
-    object_property_add_const_link(obj, ICP_PROP_XICS, OBJECT(xi),
-                                   &error_abort);
+    object_property_set_link(obj, OBJECT(xi), ICP_PROP_XICS, &error_abort);
     object_ref(cpu);
     object_property_add_const_link(obj, ICP_PROP_CPU, cpu, &error_abort);
     object_property_set_bool(obj, true, "realized", &local_err);
@@ -417,7 +414,6 @@ void icp_destroy(ICPState *icp)
     Object *obj = OBJECT(icp);
 
     object_unref(object_property_get_link(obj, ICP_PROP_CPU, &error_abort));
-    object_unref(object_property_get_link(obj, ICP_PROP_XICS, &error_abort));
     object_unparent(obj);
 }
 
-- 
2.23.0



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

* [PULL 14/88] xics: Link ICP_PROP_CPU property to ICPState::cs pointer
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (12 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 13/88] xics: Link ICP_PROP_XICS property to ICPState::xics pointer David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 15/88] spapr: Abort if XICS interrupt controller cannot be initialized David Gibson
                   ` (74 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The ICP object has both a pointer and an ICP_PROP_CPU property pointing
to the cpu. Confusing bugs could arise if these ever go out of sync.

Change the property definition so that it explicitly sets the pointer.
The property isn't optional : not being able to set the link is a bug
and QEMU should rather abort than exit in this case.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157403284709.409804.16142099083325945141.stgit@bahia.lan>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/xics.c | 21 ++++-----------------
 1 file changed, 4 insertions(+), 17 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 35dddb8867..0b259a09c5 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -305,25 +305,13 @@ void icp_reset(ICPState *icp)
 static void icp_realize(DeviceState *dev, Error **errp)
 {
     ICPState *icp = ICP(dev);
-    PowerPCCPU *cpu;
     CPUPPCState *env;
-    Object *obj;
     Error *err = NULL;
 
     assert(icp->xics);
+    assert(icp->cs);
 
-    obj = object_property_get_link(OBJECT(dev), ICP_PROP_CPU, &err);
-    if (!obj) {
-        error_propagate_prepend(errp, err,
-                                "required link '" ICP_PROP_CPU
-                                "' not found: ");
-        return;
-    }
-
-    cpu = POWERPC_CPU(obj);
-    icp->cs = CPU(obj);
-
-    env = &cpu->env;
+    env = &POWERPC_CPU(icp->cs)->env;
     switch (PPC_INPUT(env)) {
     case PPC_FLAGS_INPUT_POWER7:
         icp->output = env->irq_inputs[POWER7_INPUT_INT];
@@ -363,6 +351,7 @@ static void icp_unrealize(DeviceState *dev, Error **errp)
 static Property icp_properties[] = {
     DEFINE_PROP_LINK(ICP_PROP_XICS, ICPState, xics, TYPE_XICS_FABRIC,
                      XICSFabric *),
+    DEFINE_PROP_LINK(ICP_PROP_CPU, ICPState, cs, TYPE_CPU, CPUState *),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -397,8 +386,7 @@ Object *icp_create(Object *cpu, const char *type, XICSFabric *xi, Error **errp)
     object_property_add_child(cpu, type, obj, &error_abort);
     object_unref(obj);
     object_property_set_link(obj, OBJECT(xi), ICP_PROP_XICS, &error_abort);
-    object_ref(cpu);
-    object_property_add_const_link(obj, ICP_PROP_CPU, cpu, &error_abort);
+    object_property_set_link(obj, cpu, ICP_PROP_CPU, &error_abort);
     object_property_set_bool(obj, true, "realized", &local_err);
     if (local_err) {
         object_unparent(obj);
@@ -413,7 +401,6 @@ void icp_destroy(ICPState *icp)
 {
     Object *obj = OBJECT(icp);
 
-    object_unref(object_property_get_link(obj, ICP_PROP_CPU, &error_abort));
     object_unparent(obj);
 }
 
-- 
2.23.0



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

* [PULL 15/88] spapr: Abort if XICS interrupt controller cannot be initialized
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (13 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 14/88] xics: Link ICP_PROP_CPU property to ICPState::cs pointer David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 16/88] ppc/pnv: Add a LPC "ranges" property David Gibson
                   ` (73 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

Failing to set any of the ICS property should really never happen:
- object_property_add_child() always succeed unless the child object
  already has a parent, which isn't the case here obviously since the
  ICS has just been created with object_new()
- the ICS has an "nr-irqs" property than can be set as long as the ICS
  isn't realized

In both cases, an error indicates there is a bug in QEMU. Propagating the
error, ie. exiting QEMU since spapr_irq_init() is called with &error_fatal
doesn't make much sense. Abort instead. This is consistent with what is
done with XIVE : both qdev_create() and qdev_prop_set_uint32() abort QEMU
on error.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157403285265.409804.8683093665795248192.stgit@bahia.lan>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_irq.c | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index fbdda14372..d4a54afc86 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -313,20 +313,11 @@ void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
         Object *obj;
 
         obj = object_new(TYPE_ICS_SPAPR);
-        object_property_add_child(OBJECT(spapr), "ics", obj, &local_err);
-        if (local_err) {
-            error_propagate(errp, local_err);
-            return;
-        }
 
+        object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort);
         object_property_set_link(obj, OBJECT(spapr), ICS_PROP_XICS,
                                  &error_abort);
-        object_property_set_int(obj, smc->nr_xirqs, "nr-irqs", &local_err);
-        if (local_err) {
-            error_propagate(errp, local_err);
-            return;
-        }
-
+        object_property_set_int(obj, smc->nr_xirqs, "nr-irqs", &error_abort);
         object_property_set_bool(obj, true, "realized", &local_err);
         if (local_err) {
             error_propagate(errp, local_err);
-- 
2.23.0



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

* [PULL 16/88] ppc/pnv: Add a LPC "ranges" property
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (14 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 15/88] spapr: Abort if XICS interrupt controller cannot be initialized David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 17/88] ppc/xive: Record the IPB in the associated NVT David Gibson
                   ` (72 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

And fix a typo in the MEM address space definition.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191118091908.15044-1-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv_lpc.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index fb9f930320..c5a85c38c7 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -86,7 +86,7 @@ enum {
 #define ISA_FW_SIZE             0x10000000
 #define LPC_IO_OPB_ADDR         0xd0010000
 #define LPC_IO_OPB_SIZE         0x00010000
-#define LPC_MEM_OPB_ADDR        0xe0010000
+#define LPC_MEM_OPB_ADDR        0xe0000000
 #define LPC_MEM_OPB_SIZE        0x10000000
 #define LPC_FW_OPB_ADDR         0xf0000000
 #define LPC_FW_OPB_SIZE         0x10000000
@@ -143,6 +143,16 @@ int pnv_dt_lpc(PnvChip *chip, void *fdt, int root_offset)
                             cpu_to_be32(PNV9_LPCM_SIZE >> 32),
                             cpu_to_be32((uint32_t)PNV9_LPCM_SIZE),
     };
+    uint32_t lpc_ranges[12] = { 0, 0,
+                                cpu_to_be32(LPC_MEM_OPB_ADDR),
+                                cpu_to_be32(LPC_MEM_OPB_SIZE),
+                                cpu_to_be32(1), 0,
+                                cpu_to_be32(LPC_IO_OPB_ADDR),
+                                cpu_to_be32(LPC_IO_OPB_SIZE),
+                                cpu_to_be32(3), 0,
+                                cpu_to_be32(LPC_FW_OPB_ADDR),
+                                cpu_to_be32(LPC_FW_OPB_SIZE),
+    };
     uint32_t reg[2];
 
     /*
@@ -211,6 +221,8 @@ int pnv_dt_lpc(PnvChip *chip, void *fdt, int root_offset)
     _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 1)));
     _FDT((fdt_setprop(fdt, offset, "compatible", lpc_compat,
                       sizeof(lpc_compat))));
+    _FDT((fdt_setprop(fdt, offset, "ranges", lpc_ranges,
+                      sizeof(lpc_ranges))));
 
     return 0;
 }
-- 
2.23.0



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

* [PULL 17/88] ppc/xive: Record the IPB in the associated NVT
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (15 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 16/88] ppc/pnv: Add a LPC "ranges" property David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 18/88] ppc/xive: Introduce helpers for the NVT id David Gibson
                   ` (71 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

When an interrupt can not be presented to a vCPU, because it is not
running on any of the HW treads, the XIVE presenter updates the
Interrupt Pending Buffer register of the associated XIVE NVT
structure. This is only done if backlog is activated in the END but
this is generally the case.

The current code assumes that the fields of the NVT structure is
architected with the same layout of the thread interrupt context
registers. Fix this assumption and define an offset for the IPB
register backup value in the NVT.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191115162436.30548-2-clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/xive.c             | 11 +++++++++--
 include/hw/ppc/xive_regs.h |  1 +
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 3d472e29c8..177663d2b4 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1607,14 +1607,21 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk,
      * - logical server : forward request to IVPE (not supported)
      */
     if (xive_end_is_backlog(&end)) {
+        uint8_t ipb;
+
         if (format == 1) {
             qemu_log_mask(LOG_GUEST_ERROR,
                           "XIVE: END %x/%x invalid config: F1 & backlog\n",
                           end_blk, end_idx);
             return;
         }
-        /* Record the IPB in the associated NVT structure */
-        ipb_update((uint8_t *) &nvt.w4, priority);
+        /*
+         * Record the IPB in the associated NVT structure for later
+         * use. The presenter will resend the interrupt when the vCPU
+         * is dispatched again on a HW thread.
+         */
+        ipb = xive_get_field32(NVT_W4_IPB, nvt.w4) | priority_to_ipb(priority);
+        nvt.w4 = xive_set_field32(NVT_W4_IPB, nvt.w4, ipb);
         xive_router_write_nvt(xrtr, nvt_blk, nvt_idx, &nvt, 4);
 
         /*
diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index 55307cd153..530f232b04 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -255,6 +255,7 @@ typedef struct XiveNVT {
         uint32_t        w2;
         uint32_t        w3;
         uint32_t        w4;
+#define NVT_W4_IPB               PPC_BITMASK32(16, 23)
         uint32_t        w5;
         uint32_t        w6;
         uint32_t        w7;
-- 
2.23.0



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

* [PULL 18/88] ppc/xive: Introduce helpers for the NVT id
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (16 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 17/88] ppc/xive: Record the IPB in the associated NVT David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 19/88] ppc/pnv: Remove pnv_xive_vst_size() routine David Gibson
                   ` (70 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

Each vCPU in the system is identified with an NVT identifier which is
pushed in the OS CAM line (QW1W2) of the HW thread interrupt context
register when the vCPU is dispatched on a HW thread. This identifier
is used by the presenter subengine to find a matching target to notify
of an event. It is also used to fetch the associate NVT structure
which may contain pending interrupts that need a resend.

Add a couple of helpers for the NVT ids. The NVT space is 19 bits
wide, giving a maximum of 512K per chip.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191115162436.30548-3-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 include/hw/ppc/xive.h      |  5 -----
 include/hw/ppc/xive_regs.h | 21 +++++++++++++++++++++
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index 8fd439ec9b..fa7adf87fe 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -418,11 +418,6 @@ Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp);
 void xive_tctx_reset(XiveTCTX *tctx);
 void xive_tctx_destroy(XiveTCTX *tctx);
 
-static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
-{
-    return (nvt_blk << 19) | nvt_idx;
-}
-
 /*
  * KVM XIVE device helpers
  */
diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index 530f232b04..1a5622f8de 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -272,4 +272,25 @@ typedef struct XiveNVT {
 
 #define xive_nvt_is_valid(nvt)    (be32_to_cpu((nvt)->w0) & NVT_W0_VALID)
 
+/*
+ * The VP number space in a block is defined by the END_W6_NVT_INDEX
+ * field of the XIVE END
+ */
+#define XIVE_NVT_SHIFT                19
+
+static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
+{
+    return (nvt_blk << XIVE_NVT_SHIFT) | nvt_idx;
+}
+
+static inline uint32_t xive_nvt_idx(uint32_t cam_line)
+{
+    return cam_line & ((1 << XIVE_NVT_SHIFT) - 1);
+}
+
+static inline uint32_t xive_nvt_blk(uint32_t cam_line)
+{
+    return (cam_line >> XIVE_NVT_SHIFT) & 0xf;
+}
+
 #endif /* PPC_XIVE_REGS_H */
-- 
2.23.0



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

* [PULL 19/88] ppc/pnv: Remove pnv_xive_vst_size() routine
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (17 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 18/88] ppc/xive: Introduce helpers for the NVT id David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 20/88] xive/kvm: Trigger interrupts from userspace David Gibson
                   ` (69 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

pnv_xive_vst_size() tries to compute the size of a VSD table from the
information given by FW. The number of entries of the table are
deduced from the result and the MMIO regions of the ESBs and the END
ESBs are then resized accordingly with the computed value. This
reduces the number of elements that can be addressed by the ESB pages.

The maximum number of elements of a direct table can contain is simply:

   Table size / sizeof(XIVE structure)

An indirect table is a one page array of VSDs pointing to subpages
containing XIVE virtual structures and the maximum number of elements
an indirect table can contain :

   (PAGE_SIZE / sizeof(vsd)) * (PAGE_SIZE / sizeof(XIVE structure))

which gives us 16M for XiveENDs, 8M for XiveNVTs. That's more than the
associated VC and PC BARS can address.

The result returned by pnv_xive_vst_size() for indirect tables is
incorrect and can not be used to reduce the size of the MMIO region of
a XIVE resource using an indirect table, such as ENDs in skiboot.

Remove pnv_xive_vst_size() and use a simpler form for direct tables
only. Keep the resizing of the MMIO region for direct tables only as
this is still useful for the ESB MMIO window.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191115162436.30548-4-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/pnv_xive.c | 112 +++++++++++++++++----------------------------
 1 file changed, 43 insertions(+), 69 deletions(-)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 4e56c2e468..a4d80fd5e7 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -123,36 +123,22 @@ static uint64_t pnv_xive_vst_page_size_allowed(uint32_t page_shift)
          page_shift == 21 || page_shift == 24;
 }
 
-static uint64_t pnv_xive_vst_size(uint64_t vsd)
-{
-    uint64_t vst_tsize = 1ull << (GETFIELD(VSD_TSIZE, vsd) + 12);
-
-    /*
-     * Read the first descriptor to get the page size of the indirect
-     * table.
-     */
-    if (VSD_INDIRECT & vsd) {
-        uint32_t nr_pages = vst_tsize / XIVE_VSD_SIZE;
-        uint32_t page_shift;
-
-        vsd = ldq_be_dma(&address_space_memory, vsd & VSD_ADDRESS_MASK);
-        page_shift = GETFIELD(VSD_TSIZE, vsd) + 12;
-
-        if (!pnv_xive_vst_page_size_allowed(page_shift)) {
-            return 0;
-        }
-
-        return nr_pages * (1ull << page_shift);
-    }
-
-    return vst_tsize;
-}
-
 static uint64_t pnv_xive_vst_addr_direct(PnvXive *xive, uint32_t type,
                                          uint64_t vsd, uint32_t idx)
 {
     const XiveVstInfo *info = &vst_infos[type];
     uint64_t vst_addr = vsd & VSD_ADDRESS_MASK;
+    uint64_t vst_tsize = 1ull << (GETFIELD(VSD_TSIZE, vsd) + 12);
+    uint32_t idx_max;
+
+    idx_max = vst_tsize / info->size - 1;
+    if (idx > idx_max) {
+#ifdef XIVE_DEBUG
+        xive_error(xive, "VST: %s entry %x out of range [ 0 .. %x ] !?",
+                   info->name, idx, idx_max);
+#endif
+        return 0;
+    }
 
     return vst_addr + idx * info->size;
 }
@@ -215,7 +201,6 @@ static uint64_t pnv_xive_vst_addr(PnvXive *xive, uint32_t type, uint8_t blk,
 {
     const XiveVstInfo *info = &vst_infos[type];
     uint64_t vsd;
-    uint32_t idx_max;
 
     if (blk >= info->max_blocks) {
         xive_error(xive, "VST: invalid block id %d for VST %s %d !?",
@@ -232,15 +217,6 @@ static uint64_t pnv_xive_vst_addr(PnvXive *xive, uint32_t type, uint8_t blk,
         return xive ? pnv_xive_vst_addr(xive, type, blk, idx) : 0;
     }
 
-    idx_max = pnv_xive_vst_size(vsd) / info->size - 1;
-    if (idx > idx_max) {
-#ifdef XIVE_DEBUG
-        xive_error(xive, "VST: %s entry %x/%x out of range [ 0 .. %x ] !?",
-                   info->name, blk, idx, idx_max);
-#endif
-        return 0;
-    }
-
     if (VSD_INDIRECT & vsd) {
         return pnv_xive_vst_addr_indirect(xive, type, vsd, idx);
     }
@@ -453,19 +429,12 @@ static uint64_t pnv_xive_pc_size(PnvXive *xive)
     return (~xive->regs[CQ_PC_BARM >> 3] + 1) & CQ_PC_BARM_MASK;
 }
 
-static uint32_t pnv_xive_nr_ipis(PnvXive *xive)
+static uint32_t pnv_xive_nr_ipis(PnvXive *xive, uint8_t blk)
 {
-    uint8_t blk = xive->chip->chip_id;
-
-    return pnv_xive_vst_size(xive->vsds[VST_TSEL_SBE][blk]) * SBE_PER_BYTE;
-}
-
-static uint32_t pnv_xive_nr_ends(PnvXive *xive)
-{
-    uint8_t blk = xive->chip->chip_id;
+    uint64_t vsd = xive->vsds[VST_TSEL_SBE][blk];
+    uint64_t vst_tsize = 1ull << (GETFIELD(VSD_TSIZE, vsd) + 12);
 
-    return pnv_xive_vst_size(xive->vsds[VST_TSEL_EQDT][blk])
-        / vst_infos[VST_TSEL_EQDT].size;
+    return VSD_INDIRECT & vsd ? 0 : vst_tsize * SBE_PER_BYTE;
 }
 
 /*
@@ -598,6 +567,7 @@ static void pnv_xive_vst_set_exclusive(PnvXive *xive, uint8_t type,
     XiveSource *xsrc = &xive->ipi_source;
     const XiveVstInfo *info = &vst_infos[type];
     uint32_t page_shift = GETFIELD(VSD_TSIZE, vsd) + 12;
+    uint64_t vst_tsize = 1ull << page_shift;
     uint64_t vst_addr = vsd & VSD_ADDRESS_MASK;
 
     /* Basic checks */
@@ -633,11 +603,16 @@ static void pnv_xive_vst_set_exclusive(PnvXive *xive, uint8_t type,
 
     case VST_TSEL_EQDT:
         /*
-         * Backing store pages for the END. Compute the number of ENDs
-         * provisioned by FW and resize the END ESB window accordingly.
+         * Backing store pages for the END.
+         *
+         * If the table is direct, we can compute the number of PQ
+         * entries provisioned by FW (such as skiboot) and resize the
+         * END ESB window accordingly.
          */
-        memory_region_set_size(&end_xsrc->esb_mmio, pnv_xive_nr_ends(xive) *
-                               (1ull << (end_xsrc->esb_shift + 1)));
+        if (!(VSD_INDIRECT & vsd)) {
+            memory_region_set_size(&end_xsrc->esb_mmio, (vst_tsize / info->size)
+                                   * (1ull << xsrc->esb_shift));
+        }
         memory_region_add_subregion(&xive->end_edt_mmio, 0,
                                     &end_xsrc->esb_mmio);
         break;
@@ -646,11 +621,16 @@ static void pnv_xive_vst_set_exclusive(PnvXive *xive, uint8_t type,
         /*
          * Backing store pages for the source PQ bits. The model does
          * not use these PQ bits backed in RAM because the XiveSource
-         * model has its own. Compute the number of IRQs provisioned
-         * by FW and resize the IPI ESB window accordingly.
+         * model has its own.
+         *
+         * If the table is direct, we can compute the number of PQ
+         * entries provisioned by FW (such as skiboot) and resize the
+         * ESB window accordingly.
          */
-        memory_region_set_size(&xsrc->esb_mmio, pnv_xive_nr_ipis(xive) *
-                               (1ull << xsrc->esb_shift));
+        if (!(VSD_INDIRECT & vsd)) {
+            memory_region_set_size(&xsrc->esb_mmio, vst_tsize * SBE_PER_BYTE
+                                   * (1ull << xsrc->esb_shift));
+        }
         memory_region_add_subregion(&xive->ipi_edt_mmio, 0, &xsrc->esb_mmio);
         break;
 
@@ -1579,8 +1559,7 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
     XiveRouter *xrtr = XIVE_ROUTER(xive);
     uint8_t blk = xive->chip->chip_id;
     uint32_t srcno0 = XIVE_EAS(blk, 0);
-    uint32_t nr_ipis = pnv_xive_nr_ipis(xive);
-    uint32_t nr_ends = pnv_xive_nr_ends(xive);
+    uint32_t nr_ipis = pnv_xive_nr_ipis(xive, blk);
     XiveEAS eas;
     XiveEND end;
     int i;
@@ -1600,21 +1579,16 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
         }
     }
 
-    monitor_printf(mon, "XIVE[%x] ENDT %08x .. %08x\n", blk, 0, nr_ends - 1);
-    for (i = 0; i < nr_ends; i++) {
-        if (xive_router_get_end(xrtr, blk, i, &end)) {
-            break;
-        }
-        xive_end_pic_print_info(&end, i, mon);
+    monitor_printf(mon, "XIVE[%x] ENDT\n", blk);
+    i = 0;
+    while (!xive_router_get_end(xrtr, blk, i, &end)) {
+        xive_end_pic_print_info(&end, i++, mon);
     }
 
-    monitor_printf(mon, "XIVE[%x] END Escalation %08x .. %08x\n", blk, 0,
-                   nr_ends - 1);
-    for (i = 0; i < nr_ends; i++) {
-        if (xive_router_get_end(xrtr, blk, i, &end)) {
-            break;
-        }
-        xive_end_eas_pic_print_info(&end, i, mon);
+    monitor_printf(mon, "XIVE[%x] END Escalation EAT\n", blk);
+    i = 0;
+    while (!xive_router_get_end(xrtr, blk, i, &end)) {
+        xive_end_eas_pic_print_info(&end, i++, mon);
     }
 }
 
-- 
2.23.0



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

* [PULL 20/88] xive/kvm: Trigger interrupts from userspace
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (18 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 19/88] ppc/pnv: Remove pnv_xive_vst_size() routine David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 21/88] ppc/pnv: Quiesce some XIVE errors David Gibson
                   ` (68 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

When using the XIVE KVM device, the trigger page is directly accessible
in QEMU. Unlike with XICS, no need to ask KVM to fire the interrupt. A
simple store on the trigger page does the job.

Just call xive_esb_trigger().

This may improve performance of emulated devices that go through
qemu_set_irq(), eg. virtio devices created with ioeventfd=off or
configured by the guest to use LSI interrupts, which aren't really
recommended setups.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157408992731.494439.3405812941731584740.stgit@bahia.lan>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/spapr_xive_kvm.c | 16 ++--------------
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
index 08012ac7cd..69e73552f1 100644
--- a/hw/intc/spapr_xive_kvm.c
+++ b/hw/intc/spapr_xive_kvm.c
@@ -354,32 +354,20 @@ static void kvmppc_xive_source_get_state(XiveSource *xsrc)
 void kvmppc_xive_source_set_irq(void *opaque, int srcno, int val)
 {
     XiveSource *xsrc = opaque;
-    SpaprXive *xive = SPAPR_XIVE(xsrc->xive);
-    struct kvm_irq_level args;
-    int rc;
-
-    /* The KVM XIVE device should be in use */
-    assert(xive->fd != -1);
 
-    args.irq = srcno;
     if (!xive_source_irq_is_lsi(xsrc, srcno)) {
         if (!val) {
             return;
         }
-        args.level = KVM_INTERRUPT_SET;
     } else {
         if (val) {
             xsrc->status[srcno] |= XIVE_STATUS_ASSERTED;
-            args.level = KVM_INTERRUPT_SET_LEVEL;
         } else {
             xsrc->status[srcno] &= ~XIVE_STATUS_ASSERTED;
-            args.level = KVM_INTERRUPT_UNSET;
         }
     }
-    rc = kvm_vm_ioctl(kvm_state, KVM_IRQ_LINE, &args);
-    if (rc < 0) {
-        error_report("XIVE: kvm_irq_line() failed : %s", strerror(errno));
-    }
+
+    xive_esb_trigger(xsrc, srcno);
 }
 
 /*
-- 
2.23.0



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

* [PULL 21/88] ppc/pnv: Quiesce some XIVE errors
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (19 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 20/88] xive/kvm: Trigger interrupts from userspace David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 22/88] ppc/xive: Introduce OS CAM line helpers David Gibson
                   ` (67 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

When dumping the END and NVT tables, the error logging is too noisy.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191115162436.30548-6-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/pnv_xive.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index a4d80fd5e7..9a771f6407 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -29,7 +29,7 @@
 
 #include "pnv_xive_regs.h"
 
-#define XIVE_DEBUG
+#undef XIVE_DEBUG
 
 /*
  * Virtual structures table (VST)
@@ -157,7 +157,9 @@ static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, uint32_t type,
     vsd = ldq_be_dma(&address_space_memory, vsd_addr);
 
     if (!(vsd & VSD_ADDRESS_MASK)) {
+#ifdef XIVE_DEBUG
         xive_error(xive, "VST: invalid %s entry %x !?", info->name, idx);
+#endif
         return 0;
     }
 
@@ -178,7 +180,9 @@ static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, uint32_t type,
         vsd = ldq_be_dma(&address_space_memory, vsd_addr);
 
         if (!(vsd & VSD_ADDRESS_MASK)) {
+#ifdef XIVE_DEBUG
             xive_error(xive, "VST: invalid %s entry %x !?", info->name, idx);
+#endif
             return 0;
         }
 
-- 
2.23.0



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

* [PULL 22/88] ppc/xive: Introduce OS CAM line helpers
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (20 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 21/88] ppc/pnv: Quiesce some XIVE errors David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 23/88] ppc/xive: Check V bit in TM_PULL_POOL_CTX David Gibson
                   ` (66 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

The OS CAM line has a special encoding exploited by the HW. Provide
helper routines to hide the details to the TIMA command handlers. This
also clarifies the endianness of different variables : 'qw1w2' is
big-endian and 'cam' is native.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191115162436.30548-7-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/xive.c | 41 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 38 insertions(+), 3 deletions(-)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 177663d2b4..42e9a11ef7 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -337,14 +337,49 @@ static void xive_tm_set_os_pending(XiveTCTX *tctx, hwaddr offset,
     xive_tctx_notify(tctx, TM_QW1_OS);
 }
 
+static void xive_os_cam_decode(uint32_t cam, uint8_t *nvt_blk,
+                               uint32_t *nvt_idx, bool *vo)
+{
+    if (nvt_blk) {
+        *nvt_blk = xive_nvt_blk(cam);
+    }
+    if (nvt_idx) {
+        *nvt_idx = xive_nvt_idx(cam);
+    }
+    if (vo) {
+        *vo = !!(cam & TM_QW1W2_VO);
+    }
+}
+
+static uint32_t xive_tctx_get_os_cam(XiveTCTX *tctx, uint8_t *nvt_blk,
+                                     uint32_t *nvt_idx, bool *vo)
+{
+    uint32_t qw1w2 = xive_tctx_word2(&tctx->regs[TM_QW1_OS]);
+    uint32_t cam = be32_to_cpu(qw1w2);
+
+    xive_os_cam_decode(cam, nvt_blk, nvt_idx, vo);
+    return qw1w2;
+}
+
+static void xive_tctx_set_os_cam(XiveTCTX *tctx, uint32_t qw1w2)
+{
+    memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2, 4);
+}
+
 static uint64_t xive_tm_pull_os_ctx(XiveTCTX *tctx, hwaddr offset,
                                     unsigned size)
 {
-    uint32_t qw1w2_prev = xive_tctx_word2(&tctx->regs[TM_QW1_OS]);
     uint32_t qw1w2;
+    uint32_t qw1w2_new;
+    uint8_t nvt_blk;
+    uint32_t nvt_idx;
+    bool vo;
 
-    qw1w2 = xive_set_field32(TM_QW1W2_VO, qw1w2_prev, 0);
-    memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2, 4);
+    qw1w2 = xive_tctx_get_os_cam(tctx, &nvt_blk, &nvt_idx, &vo);
+
+    /* Invalidate CAM line */
+    qw1w2_new = xive_set_field32(TM_QW1W2_VO, qw1w2, 0);
+    xive_tctx_set_os_cam(tctx, qw1w2_new);
     return qw1w2;
 }
 
-- 
2.23.0



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

* [PULL 23/88] ppc/xive: Check V bit in TM_PULL_POOL_CTX
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (21 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 22/88] ppc/xive: Introduce OS CAM line helpers David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 24/88] ipmi: Add support to customize OEM functions David Gibson
                   ` (65 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

A context should be 'valid' when pulled from the thread interrupt
context registers.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191115162436.30548-8-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/xive.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 42e9a11ef7..511e1a9363 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -377,6 +377,11 @@ static uint64_t xive_tm_pull_os_ctx(XiveTCTX *tctx, hwaddr offset,
 
     qw1w2 = xive_tctx_get_os_cam(tctx, &nvt_blk, &nvt_idx, &vo);
 
+    if (!vo) {
+        qemu_log_mask(LOG_GUEST_ERROR, "XIVE: pulling invalid NVT %x/%x !?\n",
+                      nvt_blk, nvt_idx);
+    }
+
     /* Invalidate CAM line */
     qw1w2_new = xive_set_field32(TM_QW1W2_VO, qw1w2, 0);
     xive_tctx_set_os_cam(tctx, qw1w2_new);
-- 
2.23.0



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

* [PULL 24/88] ipmi: Add support to customize OEM functions
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (22 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 23/88] ppc/xive: Check V bit in TM_PULL_POOL_CTX David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 25/88] ppc/pnv: Add HIOMAP commands David Gibson
                   ` (64 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, Corey Minyard, aik, qemu-devel, groug, qemu-ppc, clg,
	David Gibson

From: Cédric Le Goater <clg@kaod.org>

The routine ipmi_register_oem_netfn() lets external modules register
command handlers for OEM functions. Required for the PowerNV machine.

Cc: Corey Minyard <cminyard@mvista.com>
Reviewed-by: Corey Minyard <cminyard@mvista.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191028070027.22752-2-clg@kaod.org>
Acked-by: Corey Minyard <cminyard@mvista.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ipmi/ipmi_bmc_sim.c | 50 +++++-------------------------------------
 include/hw/ipmi/ipmi.h | 42 +++++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+), 44 deletions(-)

diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
index 71e56f3b13..6670cf039d 100644
--- a/hw/ipmi/ipmi_bmc_sim.c
+++ b/hw/ipmi/ipmi_bmc_sim.c
@@ -167,32 +167,14 @@ typedef struct IPMISensor {
 #define MAX_SENSORS 20
 #define IPMI_WATCHDOG_SENSOR 0
 
-typedef struct IPMIBmcSim IPMIBmcSim;
-typedef struct RspBuffer RspBuffer;
-
 #define MAX_NETFNS 64
 
-typedef struct IPMICmdHandler {
-    void (*cmd_handler)(IPMIBmcSim *s,
-                        uint8_t *cmd, unsigned int cmd_len,
-                        RspBuffer *rsp);
-    unsigned int cmd_len_min;
-} IPMICmdHandler;
-
-typedef struct IPMINetfn {
-    unsigned int cmd_nums;
-    const IPMICmdHandler *cmd_handlers;
-} IPMINetfn;
-
 typedef struct IPMIRcvBufEntry {
     QTAILQ_ENTRY(IPMIRcvBufEntry) entry;
     uint8_t len;
     uint8_t buf[MAX_IPMI_MSG_SIZE];
 } IPMIRcvBufEntry;
 
-#define TYPE_IPMI_BMC_SIMULATOR "ipmi-bmc-sim"
-#define IPMI_BMC_SIMULATOR(obj) OBJECT_CHECK(IPMIBmcSim, (obj), \
-                                        TYPE_IPMI_BMC_SIMULATOR)
 struct IPMIBmcSim {
     IPMIBmc parent;
 
@@ -279,28 +261,8 @@ struct IPMIBmcSim {
 #define IPMI_BMC_WATCHDOG_ACTION_POWER_DOWN      2
 #define IPMI_BMC_WATCHDOG_ACTION_POWER_CYCLE     3
 
-struct RspBuffer {
-    uint8_t buffer[MAX_IPMI_MSG_SIZE];
-    unsigned int len;
-};
-
 #define RSP_BUFFER_INITIALIZER { }
 
-static inline void rsp_buffer_set_error(RspBuffer *rsp, uint8_t byte)
-{
-    rsp->buffer[2] = byte;
-}
-
-/* Add a byte to the response. */
-static inline void rsp_buffer_push(RspBuffer *rsp, uint8_t byte)
-{
-    if (rsp->len >= sizeof(rsp->buffer)) {
-        rsp_buffer_set_error(rsp, IPMI_CC_REQUEST_DATA_TRUNCATED);
-        return;
-    }
-    rsp->buffer[rsp->len++] = byte;
-}
-
 static inline void rsp_buffer_pushmore(RspBuffer *rsp, uint8_t *bytes,
                                        unsigned int n)
 {
@@ -630,8 +592,8 @@ static void ipmi_init_sensors_from_sdrs(IPMIBmcSim *s)
     }
 }
 
-static int ipmi_register_netfn(IPMIBmcSim *s, unsigned int netfn,
-                               const IPMINetfn *netfnd)
+int ipmi_sim_register_netfn(IPMIBmcSim *s, unsigned int netfn,
+                        const IPMINetfn *netfnd)
 {
     if ((netfn & 1) || (netfn >= MAX_NETFNS) || (s->netfns[netfn / 2])) {
         return -1;
@@ -1860,10 +1822,10 @@ static const IPMINetfn storage_netfn = {
 
 static void register_cmds(IPMIBmcSim *s)
 {
-    ipmi_register_netfn(s, IPMI_NETFN_CHASSIS, &chassis_netfn);
-    ipmi_register_netfn(s, IPMI_NETFN_SENSOR_EVENT, &sensor_event_netfn);
-    ipmi_register_netfn(s, IPMI_NETFN_APP, &app_netfn);
-    ipmi_register_netfn(s, IPMI_NETFN_STORAGE, &storage_netfn);
+    ipmi_sim_register_netfn(s, IPMI_NETFN_CHASSIS, &chassis_netfn);
+    ipmi_sim_register_netfn(s, IPMI_NETFN_SENSOR_EVENT, &sensor_event_netfn);
+    ipmi_sim_register_netfn(s, IPMI_NETFN_APP, &app_netfn);
+    ipmi_sim_register_netfn(s, IPMI_NETFN_STORAGE, &storage_netfn);
 }
 
 static uint8_t init_sdrs[] = {
diff --git a/include/hw/ipmi/ipmi.h b/include/hw/ipmi/ipmi.h
index 6f2413b39b..8a99d958bb 100644
--- a/include/hw/ipmi/ipmi.h
+++ b/include/hw/ipmi/ipmi.h
@@ -55,6 +55,7 @@ enum ipmi_op {
 #define IPMI_CC_COMMAND_NOT_SUPPORTED                    0xd5
 
 #define IPMI_NETFN_APP                0x06
+#define IPMI_NETFN_OEM                0x3a
 
 #define IPMI_DEBUG 1
 
@@ -265,4 +266,45 @@ int ipmi_bmc_sdr_find(IPMIBmc *b, uint16_t recid,
                       const struct ipmi_sdr_compact **sdr, uint16_t *nextrec);
 void ipmi_bmc_gen_event(IPMIBmc *b, uint8_t *evt, bool log);
 
+#define TYPE_IPMI_BMC_SIMULATOR "ipmi-bmc-sim"
+#define IPMI_BMC_SIMULATOR(obj) OBJECT_CHECK(IPMIBmcSim, (obj), \
+                                        TYPE_IPMI_BMC_SIMULATOR)
+
+typedef struct IPMIBmcSim IPMIBmcSim;
+
+typedef struct RspBuffer {
+    uint8_t buffer[MAX_IPMI_MSG_SIZE];
+    unsigned int len;
+} RspBuffer;
+
+static inline void rsp_buffer_set_error(RspBuffer *rsp, uint8_t byte)
+{
+    rsp->buffer[2] = byte;
+}
+
+/* Add a byte to the response. */
+static inline void rsp_buffer_push(RspBuffer *rsp, uint8_t byte)
+{
+    if (rsp->len >= sizeof(rsp->buffer)) {
+        rsp_buffer_set_error(rsp, IPMI_CC_REQUEST_DATA_TRUNCATED);
+        return;
+    }
+    rsp->buffer[rsp->len++] = byte;
+}
+
+typedef struct IPMICmdHandler {
+    void (*cmd_handler)(IPMIBmcSim *s,
+                        uint8_t *cmd, unsigned int cmd_len,
+                        RspBuffer *rsp);
+    unsigned int cmd_len_min;
+} IPMICmdHandler;
+
+typedef struct IPMINetfn {
+    unsigned int cmd_nums;
+    const IPMICmdHandler *cmd_handlers;
+} IPMINetfn;
+
+int ipmi_sim_register_netfn(IPMIBmcSim *s, unsigned int netfn,
+                            const IPMINetfn *netfnd);
+
 #endif
-- 
2.23.0



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

* [PULL 25/88] ppc/pnv: Add HIOMAP commands
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (23 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 24/88] ipmi: Add support to customize OEM functions David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 26/88] ppc/pnv: Create BMC devices at machine init David Gibson
                   ` (63 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson,
	Joel Stanley

From: Cédric Le Goater <clg@kaod.org>

This activates HIOMAP support on the QEMU PowerNV machine. The PnvPnor
model is used to access the flash contents. The model simply maps the
contents at a fix offset and enables or disables the mapping.

HIOMAP Protocol description :

  https://github.com/openbmc/hiomapd/blob/master/Documentation/protocol.md

Reviewed-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191028070027.22752-3-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c              |   1 +
 hw/ppc/pnv_bmc.c          | 102 ++++++++++++++++++++++++++++++++++++++
 hw/ppc/pnv_lpc.c          |  13 +++++
 include/hw/ppc/pnv.h      |   1 +
 include/hw/ppc/pnv_pnor.h |   5 ++
 5 files changed, 122 insertions(+)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index a2a8b97330..c3ac0d6d5b 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -569,6 +569,7 @@ static void pnv_reset(MachineState *machine)
     obj = object_resolve_path_type("", "ipmi-bmc-sim", NULL);
     if (obj) {
         pnv->bmc = IPMI_BMC(obj);
+        pnv_bmc_hiomap(pnv->bmc);
     }
 
     fdt = pnv_dt_create(machine);
diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c
index dc5e918cb7..aa5c89586c 100644
--- a/hw/ppc/pnv_bmc.c
+++ b/hw/ppc/pnv_bmc.c
@@ -114,3 +114,105 @@ void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt)
                                sdr->sensor_type)));
     }
 }
+
+/*
+ * HIOMAP protocol handler
+ */
+#define HIOMAP_C_RESET                  1
+#define HIOMAP_C_GET_INFO               2
+#define HIOMAP_C_GET_FLASH_INFO         3
+#define HIOMAP_C_CREATE_READ_WINDOW     4
+#define HIOMAP_C_CLOSE_WINDOW           5
+#define HIOMAP_C_CREATE_WRITE_WINDOW    6
+#define HIOMAP_C_MARK_DIRTY             7
+#define HIOMAP_C_FLUSH                  8
+#define HIOMAP_C_ACK                    9
+#define HIOMAP_C_ERASE                  10
+#define HIOMAP_C_DEVICE_NAME            11
+#define HIOMAP_C_LOCK                   12
+
+#define BLOCK_SHIFT                     12 /* 4K */
+
+static uint16_t bytes_to_blocks(uint32_t bytes)
+{
+    return bytes >> BLOCK_SHIFT;
+}
+
+static void hiomap_cmd(IPMIBmcSim *ibs, uint8_t *cmd, unsigned int cmd_len,
+                       RspBuffer *rsp)
+{
+    PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
+    PnvPnor *pnor = pnv->pnor;
+    uint32_t pnor_size = pnor->size;
+    uint32_t pnor_addr = PNOR_SPI_OFFSET;
+    bool readonly = false;
+
+    rsp_buffer_push(rsp, cmd[2]);
+    rsp_buffer_push(rsp, cmd[3]);
+
+    switch (cmd[2]) {
+    case HIOMAP_C_MARK_DIRTY:
+    case HIOMAP_C_FLUSH:
+    case HIOMAP_C_ERASE:
+    case HIOMAP_C_ACK:
+        break;
+
+    case HIOMAP_C_GET_INFO:
+        rsp_buffer_push(rsp, 2);  /* Version 2 */
+        rsp_buffer_push(rsp, BLOCK_SHIFT); /* block size */
+        rsp_buffer_push(rsp, 0);  /* Timeout */
+        rsp_buffer_push(rsp, 0);  /* Timeout */
+        break;
+
+    case HIOMAP_C_GET_FLASH_INFO:
+        rsp_buffer_push(rsp, bytes_to_blocks(pnor_size) & 0xFF);
+        rsp_buffer_push(rsp, bytes_to_blocks(pnor_size) >> 8);
+        rsp_buffer_push(rsp, 0x01);  /* erase size */
+        rsp_buffer_push(rsp, 0x00);  /* erase size */
+        break;
+
+    case HIOMAP_C_CREATE_READ_WINDOW:
+        readonly = true;
+        /* Fall through */
+
+    case HIOMAP_C_CREATE_WRITE_WINDOW:
+        memory_region_set_readonly(&pnor->mmio, readonly);
+        memory_region_set_enabled(&pnor->mmio, true);
+
+        rsp_buffer_push(rsp, bytes_to_blocks(pnor_addr) & 0xFF);
+        rsp_buffer_push(rsp, bytes_to_blocks(pnor_addr) >> 8);
+        rsp_buffer_push(rsp, bytes_to_blocks(pnor_size) & 0xFF);
+        rsp_buffer_push(rsp, bytes_to_blocks(pnor_size) >> 8);
+        rsp_buffer_push(rsp, 0x00); /* offset */
+        rsp_buffer_push(rsp, 0x00); /* offset */
+        break;
+
+    case HIOMAP_C_CLOSE_WINDOW:
+        memory_region_set_enabled(&pnor->mmio, false);
+        break;
+
+    case HIOMAP_C_DEVICE_NAME:
+    case HIOMAP_C_RESET:
+    case HIOMAP_C_LOCK:
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "HIOMAP: unknow command %02X\n", cmd[2]);
+        break;
+    }
+}
+
+#define HIOMAP   0x5a
+
+static const IPMICmdHandler hiomap_cmds[] = {
+    [HIOMAP] = { hiomap_cmd, 3 },
+};
+
+static const IPMINetfn hiomap_netfn = {
+    .cmd_nums = ARRAY_SIZE(hiomap_cmds),
+    .cmd_handlers = hiomap_cmds
+};
+
+int pnv_bmc_hiomap(IPMIBmc *bmc)
+{
+    return ipmi_sim_register_netfn(IPMI_BMC_SIMULATOR(bmc),
+                                   IPMI_NETFN_OEM, &hiomap_netfn);
+}
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index c5a85c38c7..dd5374c838 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -810,6 +810,7 @@ ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp)
     ISABus *isa_bus;
     qemu_irq *irqs;
     qemu_irq_handler handler;
+    PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
 
     /* let isa_bus_new() create its own bridge on SysBus otherwise
      * devices speficied on the command line won't find the bus and
@@ -834,5 +835,17 @@ ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp)
     irqs = qemu_allocate_irqs(handler, lpc, ISA_NUM_IRQS);
 
     isa_bus_irqs(isa_bus, irqs);
+
+    /*
+     * TODO: Map PNOR on the LPC FW address space on demand ?
+     */
+    memory_region_add_subregion(&lpc->isa_fw, PNOR_SPI_OFFSET,
+                                &pnv->pnor->mmio);
+    /*
+     * Start disabled. The HIOMAP protocol will activate the mapping
+     * with HIOMAP_C_CREATE_WRITE_WINDOW
+     */
+    memory_region_set_enabled(&pnv->pnor->mmio, false);
+
     return isa_bus;
 }
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 5ecd3ba6ed..07c56c05ad 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -198,6 +198,7 @@ static inline bool pnv_is_power9(PnvMachineState *pnv)
  */
 void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt);
 void pnv_bmc_powerdown(IPMIBmc *bmc);
+int pnv_bmc_hiomap(IPMIBmc *bmc);
 
 /*
  * POWER8 MMIO base addresses
diff --git a/include/hw/ppc/pnv_pnor.h b/include/hw/ppc/pnv_pnor.h
index dec811695c..c3dd28643c 100644
--- a/include/hw/ppc/pnv_pnor.h
+++ b/include/hw/ppc/pnv_pnor.h
@@ -9,6 +9,11 @@
 #ifndef _PPC_PNV_PNOR_H
 #define _PPC_PNV_PNOR_H
 
+/*
+ * PNOR offset on the LPC FW address space
+ */
+#define PNOR_SPI_OFFSET         0x0c000000UL
+
 #define TYPE_PNV_PNOR  "pnv-pnor"
 #define PNV_PNOR(obj)  OBJECT_CHECK(PnvPnor, (obj), TYPE_PNV_PNOR)
 
-- 
2.23.0



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

* [PULL 26/88] ppc/pnv: Create BMC devices at machine init
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (24 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 25/88] ppc/pnv: Add HIOMAP commands David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 27/88] ppc/xive: Introduce a XivePresenter interface David Gibson
                   ` (62 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

The BMC of the OpenPOWER systems monitors the machine state using
sensors, controls the power and controls the access to the PNOR flash
device containing the firmware image required to boot the host.

QEMU models the power cycle process, access to the sensors and access
to the PNOR device. But, for these features to be available, the QEMU
PowerNV machine needs two extras devices on the command line, an IPMI
BT device for communication and a BMC backend device:

  -device ipmi-bmc-sim,id=bmc0 -device isa-ipmi-bt,bmc=bmc0,irq=10

The BMC properties are then defined accordingly in the device tree and
OPAL self adapts. If a BMC device and an IPMI BT device are not
available, OPAL does not try to communicate with the BMC in any
manner. This is not how real systems behave.

To be closer to the default behavior, create an IPMI BMC simulator
device and an IPMI BT device at machine initialization time. We loose
the ability to define an external BMC device but there are benefits:

  - a better match with real systems,
  - a better test coverage of the OPAL code,
  - system powerdown and reset commands that work,
  - a QEMU device tree compliant with the specifications (*).

(*) Still needs a MBOX device.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191121162340.11049-1-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c         | 33 ++++++++++++++++-----------------
 hw/ppc/pnv_bmc.c     | 20 +++++++++++++++++---
 include/hw/ppc/pnv.h |  2 +-
 3 files changed, 34 insertions(+), 21 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index c3ac0d6d5b..f0adb06c8d 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -551,27 +551,10 @@ static void pnv_powerdown_notify(Notifier *n, void *opaque)
 
 static void pnv_reset(MachineState *machine)
 {
-    PnvMachineState *pnv = PNV_MACHINE(machine);
     void *fdt;
-    Object *obj;
 
     qemu_devices_reset();
 
-    /*
-     * OpenPOWER systems have a BMC, which can be defined on the
-     * command line with:
-     *
-     *   -device ipmi-bmc-sim,id=bmc0
-     *
-     * This is the internal simulator but it could also be an external
-     * BMC.
-     */
-    obj = object_resolve_path_type("", "ipmi-bmc-sim", NULL);
-    if (obj) {
-        pnv->bmc = IPMI_BMC(obj);
-        pnv_bmc_hiomap(pnv->bmc);
-    }
-
     fdt = pnv_dt_create(machine);
 
     /* Pack resulting tree */
@@ -629,6 +612,16 @@ static bool pnv_match_cpu(const char *default_type, const char *cpu_type)
     return ppc_default->pvr_match(ppc_default, ppc->pvr);
 }
 
+static void pnv_ipmi_bt_init(ISABus *bus, IPMIBmc *bmc, uint32_t irq)
+{
+    Object *obj;
+
+    obj = OBJECT(isa_create(bus, "isa-ipmi-bt"));
+    object_property_set_link(obj, OBJECT(bmc), "bmc", &error_fatal);
+    object_property_set_int(obj, irq, "irq", &error_fatal);
+    object_property_set_bool(obj, true, "realized", &error_fatal);
+}
+
 static void pnv_init(MachineState *machine)
 {
     PnvMachineState *pnv = PNV_MACHINE(machine);
@@ -751,6 +744,9 @@ static void pnv_init(MachineState *machine)
     }
     g_free(chip_typename);
 
+    /* Create the machine BMC simulator */
+    pnv->bmc = pnv_bmc_create();
+
     /* Instantiate ISA bus on chip 0 */
     pnv->isa_bus = pnv_isa_create(pnv->chips[0], &error_fatal);
 
@@ -760,6 +756,9 @@ static void pnv_init(MachineState *machine)
     /* Create an RTC ISA device too */
     mc146818_rtc_init(pnv->isa_bus, 2000, NULL);
 
+    /* Create the IPMI BT device for communication with the BMC */
+    pnv_ipmi_bt_init(pnv->isa_bus, pnv->bmc, 10);
+
     /*
      * OpenPOWER systems use a IPMI SEL Event message to notify the
      * host to powerdown
diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c
index aa5c89586c..07fa1e1c7e 100644
--- a/hw/ppc/pnv_bmc.c
+++ b/hw/ppc/pnv_bmc.c
@@ -17,6 +17,8 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qapi/error.h"
 #include "target/ppc/cpu.h"
 #include "qemu/log.h"
 #include "hw/ipmi/ipmi.h"
@@ -211,8 +213,20 @@ static const IPMINetfn hiomap_netfn = {
     .cmd_handlers = hiomap_cmds
 };
 
-int pnv_bmc_hiomap(IPMIBmc *bmc)
+/*
+ * Instantiate the machine BMC. PowerNV uses the QEMU internal
+ * simulator but it could also be external.
+ */
+IPMIBmc *pnv_bmc_create(void)
 {
-    return ipmi_sim_register_netfn(IPMI_BMC_SIMULATOR(bmc),
-                                   IPMI_NETFN_OEM, &hiomap_netfn);
+    Object *obj;
+
+    obj = object_new(TYPE_IPMI_BMC_SIMULATOR);
+    object_property_set_bool(obj, true, "realized", &error_fatal);
+
+    /* Install the HIOMAP protocol handlers to access the PNOR */
+    ipmi_sim_register_netfn(IPMI_BMC_SIMULATOR(obj), IPMI_NETFN_OEM,
+                            &hiomap_netfn);
+
+    return IPMI_BMC(obj);
 }
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 07c56c05ad..90f1343ed0 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -198,7 +198,7 @@ static inline bool pnv_is_power9(PnvMachineState *pnv)
  */
 void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt);
 void pnv_bmc_powerdown(IPMIBmc *bmc);
-int pnv_bmc_hiomap(IPMIBmc *bmc);
+IPMIBmc *pnv_bmc_create(void);
 
 /*
  * POWER8 MMIO base addresses
-- 
2.23.0



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

* [PULL 27/88] ppc/xive: Introduce a XivePresenter interface
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (25 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 26/88] ppc/pnv: Create BMC devices at machine init David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 28/88] ppc/xive: Implement the " David Gibson
                   ` (61 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

When the XIVE IVRE sub-engine (XiveRouter) looks for a Notification
Virtual Target (NVT) to notify, it broadcasts a message on the
PowerBUS to find an XIVE IVPE sub-engine (Presenter) with the NVT
dispatched on one of its HW threads, and then forwards the
notification if any response was received.

The current XIVE presenter model is sufficient for the pseries machine
because it has a single interrupt controller device, but the PowerNV
machine can have multiple chips each having its own interrupt
controller. In this case, the XIVE presenter model is too simple and
the CAM line matching should scan all chips of the system.

To start fixing this issue, we first extend the XIVE Router model with
a new XivePresenter QOM interface representing the XIVE IVPE
sub-engine. This interface exposes a 'match_nvt' handler which the
sPAPR and PowerNV XIVE Router models will need to implement to perform
the CAM line matching.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191125065820.927-2-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/xive.c        | 26 +++++++++++++++++---------
 include/hw/ppc/xive.h | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 9 deletions(-)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 511e1a9363..344bb3f3bc 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1363,9 +1363,10 @@ static uint32_t xive_tctx_hw_cam_line(XiveTCTX *tctx)
 /*
  * The thread context register words are in big-endian format.
  */
-static int xive_presenter_tctx_match(XiveTCTX *tctx, uint8_t format,
-                                     uint8_t nvt_blk, uint32_t nvt_idx,
-                                     bool cam_ignore, uint32_t logic_serv)
+int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
+                              uint8_t format,
+                              uint8_t nvt_blk, uint32_t nvt_idx,
+                              bool cam_ignore, uint32_t logic_serv)
 {
     uint32_t cam = xive_nvt_cam_line(nvt_blk, nvt_idx);
     uint32_t qw3w2 = xive_tctx_word2(&tctx->regs[TM_QW3_HV_PHYS]);
@@ -1422,11 +1423,6 @@ static int xive_presenter_tctx_match(XiveTCTX *tctx, uint8_t format,
     return -1;
 }
 
-typedef struct XiveTCTXMatch {
-    XiveTCTX *tctx;
-    uint8_t ring;
-} XiveTCTXMatch;
-
 static bool xive_presenter_match(XiveRouter *xrtr, uint8_t format,
                                  uint8_t nvt_blk, uint32_t nvt_idx,
                                  bool cam_ignore, uint8_t priority,
@@ -1460,7 +1456,8 @@ static bool xive_presenter_match(XiveRouter *xrtr, uint8_t format,
          * Check the thread context CAM lines and record matches. We
          * will handle CPU exception delivery later
          */
-        ring = xive_presenter_tctx_match(tctx, format, nvt_blk, nvt_idx,
+        ring = xive_presenter_tctx_match(XIVE_PRESENTER(xrtr), tctx, format,
+                                         nvt_blk, nvt_idx,
                                          cam_ignore, logic_serv);
         /*
          * Save the context and follow on to catch duplicates, that we
@@ -1754,6 +1751,7 @@ static const TypeInfo xive_router_info = {
     .class_init    = xive_router_class_init,
     .interfaces    = (InterfaceInfo[]) {
         { TYPE_XIVE_NOTIFIER },
+        { TYPE_XIVE_PRESENTER },
         { }
     }
 };
@@ -1923,10 +1921,20 @@ static const TypeInfo xive_notifier_info = {
     .class_size = sizeof(XiveNotifierClass),
 };
 
+/*
+ * XIVE Presenter
+ */
+static const TypeInfo xive_presenter_info = {
+    .name = TYPE_XIVE_PRESENTER,
+    .parent = TYPE_INTERFACE,
+    .class_size = sizeof(XivePresenterClass),
+};
+
 static void xive_register_types(void)
 {
     type_register_static(&xive_source_info);
     type_register_static(&xive_notifier_info);
+    type_register_static(&xive_presenter_info);
     type_register_static(&xive_router_info);
     type_register_static(&xive_end_source_info);
     type_register_static(&xive_tctx_info);
diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index fa7adf87fe..f9aa0fa0da 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -367,6 +367,38 @@ int xive_router_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
 XiveTCTX *xive_router_get_tctx(XiveRouter *xrtr, CPUState *cs);
 void xive_router_notify(XiveNotifier *xn, uint32_t lisn);
 
+/*
+ * XIVE Presenter
+ */
+
+typedef struct XiveTCTXMatch {
+    XiveTCTX *tctx;
+    uint8_t ring;
+} XiveTCTXMatch;
+
+typedef struct XivePresenter XivePresenter;
+
+#define TYPE_XIVE_PRESENTER "xive-presenter"
+#define XIVE_PRESENTER(obj)                                     \
+    INTERFACE_CHECK(XivePresenter, (obj), TYPE_XIVE_PRESENTER)
+#define XIVE_PRESENTER_CLASS(klass)                                     \
+    OBJECT_CLASS_CHECK(XivePresenterClass, (klass), TYPE_XIVE_PRESENTER)
+#define XIVE_PRESENTER_GET_CLASS(obj)                                   \
+    OBJECT_GET_CLASS(XivePresenterClass, (obj), TYPE_XIVE_PRESENTER)
+
+typedef struct XivePresenterClass {
+    InterfaceClass parent;
+    int (*match_nvt)(XivePresenter *xptr, uint8_t format,
+                     uint8_t nvt_blk, uint32_t nvt_idx,
+                     bool cam_ignore, uint8_t priority,
+                     uint32_t logic_serv, XiveTCTXMatch *match);
+} XivePresenterClass;
+
+int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
+                              uint8_t format,
+                              uint8_t nvt_blk, uint32_t nvt_idx,
+                              bool cam_ignore, uint32_t logic_serv);
+
 /*
  * XIVE END ESBs
  */
-- 
2.23.0



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

* [PULL 28/88] ppc/xive: Implement the XivePresenter interface
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (26 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 27/88] ppc/xive: Introduce a XivePresenter interface David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 29/88] ppc/pnv: Instantiate cores separately David Gibson
                   ` (60 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

Each XIVE Router model, sPAPR and PowerNV, now implements the 'match_nvt'
handler of the XivePresenter QOM interface. This is simply moving code
and taking into account the new API.

To be noted that the xive_router_get_tctx() helper is not used anymore
when doing CAM matching and will be removed later on after other changes.

The XIVE presenter model is still too simple for the PowerNV machine
and the CAM matching algo is not correct on multichip system. Subsequent
patches will introduce more changes to scan all chips of the system.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191125065820.927-3-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/pnv_xive.c   | 41 +++++++++++++++++++++++++++++++++++
 hw/intc/spapr_xive.c | 49 ++++++++++++++++++++++++++++++++++++++++++
 hw/intc/xive.c       | 51 ++++++--------------------------------------
 3 files changed, 97 insertions(+), 44 deletions(-)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 9a771f6407..8055de89cf 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -372,6 +372,45 @@ static int pnv_xive_get_eas(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
     return pnv_xive_vst_read(xive, VST_TSEL_IVT, blk, idx, eas);
 }
 
+static int pnv_xive_match_nvt(XivePresenter *xptr, uint8_t format,
+                              uint8_t nvt_blk, uint32_t nvt_idx,
+                              bool cam_ignore, uint8_t priority,
+                              uint32_t logic_serv, XiveTCTXMatch *match)
+{
+    CPUState *cs;
+    int count = 0;
+
+    CPU_FOREACH(cs) {
+        PowerPCCPU *cpu = POWERPC_CPU(cs);
+        XiveTCTX *tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
+        int ring;
+
+        /*
+         * Check the thread context CAM lines and record matches.
+         */
+        ring = xive_presenter_tctx_match(xptr, tctx, format, nvt_blk, nvt_idx,
+                                         cam_ignore, logic_serv);
+        /*
+         * Save the context and follow on to catch duplicates, that we
+         * don't support yet.
+         */
+        if (ring != -1) {
+            if (match->tctx) {
+                qemu_log_mask(LOG_GUEST_ERROR, "XIVE: already found a "
+                              "thread context NVT %x/%x\n",
+                              nvt_blk, nvt_idx);
+                return -1;
+            }
+
+            match->ring = ring;
+            match->tctx = tctx;
+            count++;
+        }
+    }
+
+    return count;
+}
+
 static XiveTCTX *pnv_xive_get_tctx(XiveRouter *xrtr, CPUState *cs)
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);
@@ -1780,6 +1819,7 @@ static void pnv_xive_class_init(ObjectClass *klass, void *data)
     PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass);
     XiveRouterClass *xrc = XIVE_ROUTER_CLASS(klass);
     XiveNotifierClass *xnc = XIVE_NOTIFIER_CLASS(klass);
+    XivePresenterClass *xpc = XIVE_PRESENTER_CLASS(klass);
 
     xdc->dt_xscom = pnv_xive_dt_xscom;
 
@@ -1795,6 +1835,7 @@ static void pnv_xive_class_init(ObjectClass *klass, void *data)
     xrc->get_tctx = pnv_xive_get_tctx;
 
     xnc->notify = pnv_xive_notify;
+    xpc->match_nvt  = pnv_xive_match_nvt;
 };
 
 static const TypeInfo pnv_xive_info = {
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 729246e906..bb3b2dfdb7 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -405,6 +405,52 @@ static XiveTCTX *spapr_xive_get_tctx(XiveRouter *xrtr, CPUState *cs)
     return spapr_cpu_state(cpu)->tctx;
 }
 
+static int spapr_xive_match_nvt(XivePresenter *xptr, uint8_t format,
+                                uint8_t nvt_blk, uint32_t nvt_idx,
+                                bool cam_ignore, uint8_t priority,
+                                uint32_t logic_serv, XiveTCTXMatch *match)
+{
+    CPUState *cs;
+    int count = 0;
+
+    CPU_FOREACH(cs) {
+        PowerPCCPU *cpu = POWERPC_CPU(cs);
+        XiveTCTX *tctx = spapr_cpu_state(cpu)->tctx;
+        int ring;
+
+        /*
+         * Skip partially initialized vCPUs. This can happen when
+         * vCPUs are hotplugged.
+         */
+        if (!tctx) {
+            continue;
+        }
+
+        /*
+         * Check the thread context CAM lines and record matches.
+         */
+        ring = xive_presenter_tctx_match(xptr, tctx, format, nvt_blk, nvt_idx,
+                                         cam_ignore, logic_serv);
+        /*
+         * Save the matching thread interrupt context and follow on to
+         * check for duplicates which are invalid.
+         */
+        if (ring != -1) {
+            if (match->tctx) {
+                qemu_log_mask(LOG_GUEST_ERROR, "XIVE: already found a thread "
+                              "context NVT %x/%x\n", nvt_blk, nvt_idx);
+                return -1;
+            }
+
+            match->ring = ring;
+            match->tctx = tctx;
+            count++;
+        }
+    }
+
+    return count;
+}
+
 static const VMStateDescription vmstate_spapr_xive_end = {
     .name = TYPE_SPAPR_XIVE "/end",
     .version_id = 1,
@@ -684,6 +730,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     XiveRouterClass *xrc = XIVE_ROUTER_CLASS(klass);
     SpaprInterruptControllerClass *sicc = SPAPR_INTC_CLASS(klass);
+    XivePresenterClass *xpc = XIVE_PRESENTER_CLASS(klass);
 
     dc->desc    = "sPAPR XIVE Interrupt Controller";
     dc->props   = spapr_xive_properties;
@@ -708,6 +755,8 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
     sicc->print_info = spapr_xive_print_info;
     sicc->dt = spapr_xive_dt;
     sicc->post_load = spapr_xive_post_load;
+
+    xpc->match_nvt  = spapr_xive_match_nvt;
 }
 
 static const TypeInfo spapr_xive_info = {
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 344bb3f3bc..da6196ca95 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1428,51 +1428,14 @@ static bool xive_presenter_match(XiveRouter *xrtr, uint8_t format,
                                  bool cam_ignore, uint8_t priority,
                                  uint32_t logic_serv, XiveTCTXMatch *match)
 {
-    CPUState *cs;
+    XivePresenter *xptr = XIVE_PRESENTER(xrtr);
+    XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr);
+    int count;
 
-    /*
-     * TODO (PowerNV): handle chip_id overwrite of block field for
-     * hardwired CAM compares
-     */
-
-    CPU_FOREACH(cs) {
-        XiveTCTX *tctx = xive_router_get_tctx(xrtr, cs);
-        int ring;
-
-        /*
-         * Skip partially initialized vCPUs. This can happen when
-         * vCPUs are hotplugged.
-         */
-        if (!tctx) {
-            continue;
-        }
-
-        /*
-         * HW checks that the CPU is enabled in the Physical Thread
-         * Enable Register (PTER).
-         */
-
-        /*
-         * Check the thread context CAM lines and record matches. We
-         * will handle CPU exception delivery later
-         */
-        ring = xive_presenter_tctx_match(XIVE_PRESENTER(xrtr), tctx, format,
-                                         nvt_blk, nvt_idx,
-                                         cam_ignore, logic_serv);
-        /*
-         * Save the context and follow on to catch duplicates, that we
-         * don't support yet.
-         */
-        if (ring != -1) {
-            if (match->tctx) {
-                qemu_log_mask(LOG_GUEST_ERROR, "XIVE: already found a thread "
-                              "context NVT %x/%x\n", nvt_blk, nvt_idx);
-                return false;
-            }
-
-            match->ring = ring;
-            match->tctx = tctx;
-        }
+    count = xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, cam_ignore,
+                           priority, logic_serv, match);
+    if (count < 0) {
+        return false;
     }
 
     if (!match->tctx) {
-- 
2.23.0



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

* [PULL 29/88] ppc/pnv: Instantiate cores separately
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (27 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 28/88] ppc/xive: Implement the " David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 30/88] ppc/pnv: Loop on the threads of the chip to find a matching NVT David Gibson
                   ` (59 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

Allocating a big void * array to store multiple objects isn't a
recommended practice for various reasons:
 - no compile time type checking
 - potential dangling pointers if a reference on an individual is
  taken and the array is freed later on
 - duplicate boiler plate everywhere the array is browsed through

Allocate an array of pointers and populate it instead.

Signed-off-by: Greg Kurz <groug@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191125065820.927-4-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c         | 30 ++++++++++++------------------
 include/hw/ppc/pnv.h |  2 +-
 2 files changed, 13 insertions(+), 19 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index f0adb06c8d..d899c83e52 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -280,14 +280,12 @@ static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t pir,
 
 static void pnv_chip_power8_dt_populate(PnvChip *chip, void *fdt)
 {
-    const char *typename = pnv_chip_core_typename(chip);
-    size_t typesize = object_type_get_instance_size(typename);
     int i;
 
     pnv_dt_xscom(chip, fdt, 0);
 
     for (i = 0; i < chip->nr_cores; i++) {
-        PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
+        PnvCore *pnv_core = chip->cores[i];
 
         pnv_dt_core(chip, pnv_core, fdt);
 
@@ -302,14 +300,12 @@ static void pnv_chip_power8_dt_populate(PnvChip *chip, void *fdt)
 
 static void pnv_chip_power9_dt_populate(PnvChip *chip, void *fdt)
 {
-    const char *typename = pnv_chip_core_typename(chip);
-    size_t typesize = object_type_get_instance_size(typename);
     int i;
 
     pnv_dt_xscom(chip, fdt, 0);
 
     for (i = 0; i < chip->nr_cores; i++) {
-        PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
+        PnvCore *pnv_core = chip->cores[i];
 
         pnv_dt_core(chip, pnv_core, fdt);
     }
@@ -913,8 +909,6 @@ static void pnv_chip_icp_realize(Pnv8Chip *chip8, Error **errp)
  {
     PnvChip *chip = PNV_CHIP(chip8);
     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
-    const char *typename = pnv_chip_core_typename(chip);
-    size_t typesize = object_type_get_instance_size(typename);
     int i, j;
     char *name;
     XICSFabric *xi = XICS_FABRIC(qdev_get_machine());
@@ -928,7 +922,7 @@ static void pnv_chip_icp_realize(Pnv8Chip *chip8, Error **errp)
 
     /* Map the ICP registers for each thread */
     for (i = 0; i < chip->nr_cores; i++) {
-        PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
+        PnvCore *pnv_core = chip->cores[i];
         int core_hwid = CPU_CORE(pnv_core)->core_id;
 
         for (j = 0; j < CPU_CORE(pnv_core)->nr_threads; j++) {
@@ -1108,8 +1102,6 @@ static void pnv_chip_power9_instance_init(Object *obj)
 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);
@@ -1118,7 +1110,7 @@ static void pnv_chip_quad_realize(Pnv9Chip *chip9, Error **errp)
     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);
+        PnvCore *pnv_core = chip->cores[i * 4];
         int core_id = CPU_CORE(pnv_core)->core_id;
 
         snprintf(eq_name, sizeof(eq_name), "eq[%d]", core_id);
@@ -1290,7 +1282,6 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
     Error *error = NULL;
     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
     const char *typename = pnv_chip_core_typename(chip);
-    size_t typesize = object_type_get_instance_size(typename);
     int i, core_hwid;
 
     if (!object_class_by_name(typename)) {
@@ -1305,21 +1296,24 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
         return;
     }
 
-    chip->cores = g_malloc0(typesize * chip->nr_cores);
+    chip->cores = g_new0(PnvCore *, chip->nr_cores);
 
     for (i = 0, core_hwid = 0; (core_hwid < sizeof(chip->cores_mask) * 8)
              && (i < chip->nr_cores); core_hwid++) {
         char core_name[32];
-        void *pnv_core = chip->cores + i * typesize;
+        PnvCore *pnv_core;
         uint64_t xscom_core_base;
 
         if (!(chip->cores_mask & (1ull << core_hwid))) {
             continue;
         }
 
+        pnv_core = PNV_CORE(object_new(typename));
+
         snprintf(core_name, sizeof(core_name), "core[%d]", core_hwid);
-        object_initialize_child(OBJECT(chip), core_name, pnv_core, typesize,
-                                typename, &error_fatal, NULL);
+        object_property_add_child(OBJECT(chip), core_name, OBJECT(pnv_core),
+                                  &error_abort);
+        chip->cores[i] = pnv_core;
         object_property_set_int(OBJECT(pnv_core), ms->smp.threads, "nr-threads",
                                 &error_fatal);
         object_property_set_int(OBJECT(pnv_core), core_hwid,
@@ -1340,7 +1334,7 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
         }
 
         pnv_xscom_add_subregion(chip, xscom_core_base,
-                                &PNV_CORE(pnv_core)->xscom_regs);
+                                &pnv_core->xscom_regs);
         i++;
     }
 }
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 90f1343ed0..03cb429f21 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -56,7 +56,7 @@ typedef struct PnvChip {
 
     uint32_t     nr_cores;
     uint64_t     cores_mask;
-    void         *cores;
+    PnvCore      **cores;
 
     MemoryRegion xscom_mmio;
     MemoryRegion xscom;
-- 
2.23.0



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

* [PULL 30/88] ppc/pnv: Loop on the threads of the chip to find a matching NVT
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (28 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 29/88] ppc/pnv: Instantiate cores separately David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 31/88] ppc: Introduce a ppc_cpu_pir() helper David Gibson
                   ` (58 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

CPU_FOREACH() loops on all the CPUs of the machine which is incorrect.
Each XIVE Presenter should scan only the HW threads of the chip it
belongs to.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191125065820.927-5-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/pnv_xive.c | 61 ++++++++++++++++++++++++++--------------------
 1 file changed, 35 insertions(+), 26 deletions(-)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 8055de89cf..9798bd9e72 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -377,34 +377,43 @@ static int pnv_xive_match_nvt(XivePresenter *xptr, uint8_t format,
                               bool cam_ignore, uint8_t priority,
                               uint32_t logic_serv, XiveTCTXMatch *match)
 {
-    CPUState *cs;
+    PnvXive *xive = PNV_XIVE(xptr);
+    PnvChip *chip = xive->chip;
     int count = 0;
-
-    CPU_FOREACH(cs) {
-        PowerPCCPU *cpu = POWERPC_CPU(cs);
-        XiveTCTX *tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
-        int ring;
-
-        /*
-         * Check the thread context CAM lines and record matches.
-         */
-        ring = xive_presenter_tctx_match(xptr, tctx, format, nvt_blk, nvt_idx,
-                                         cam_ignore, logic_serv);
-        /*
-         * Save the context and follow on to catch duplicates, that we
-         * don't support yet.
-         */
-        if (ring != -1) {
-            if (match->tctx) {
-                qemu_log_mask(LOG_GUEST_ERROR, "XIVE: already found a "
-                              "thread context NVT %x/%x\n",
-                              nvt_blk, nvt_idx);
-                return -1;
+    int i, j;
+
+    for (i = 0; i < chip->nr_cores; i++) {
+        PnvCore *pc = chip->cores[i];
+        CPUCore *cc = CPU_CORE(pc);
+
+        for (j = 0; j < cc->nr_threads; j++) {
+            PowerPCCPU *cpu = pc->threads[j];
+            XiveTCTX *tctx;
+            int ring;
+
+            tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
+
+            /*
+             * Check the thread context CAM lines and record matches.
+             */
+            ring = xive_presenter_tctx_match(xptr, tctx, format, nvt_blk,
+                                             nvt_idx, cam_ignore, logic_serv);
+            /*
+             * Save the context and follow on to catch duplicates, that we
+             * don't support yet.
+             */
+            if (ring != -1) {
+                if (match->tctx) {
+                    qemu_log_mask(LOG_GUEST_ERROR, "XIVE: already found a "
+                                  "thread context NVT %x/%x\n",
+                                  nvt_blk, nvt_idx);
+                    return -1;
+                }
+
+                match->ring = ring;
+                match->tctx = tctx;
+                count++;
             }
-
-            match->ring = ring;
-            match->tctx = tctx;
-            count++;
         }
     }
 
-- 
2.23.0



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

* [PULL 31/88] ppc: Introduce a ppc_cpu_pir() helper
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (29 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 30/88] ppc/pnv: Loop on the threads of the chip to find a matching NVT David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 32/88] ppc/pnv: Introduce a pnv_xive_is_cpu_enabled() helper David Gibson
                   ` (57 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191125065820.927-6-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/ppc.c         | 9 +++++++--
 include/hw/ppc/ppc.h | 1 +
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 52a18eb7d7..8dd982fc1e 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -1495,15 +1495,20 @@ void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val)
     }
 }
 
+int ppc_cpu_pir(PowerPCCPU *cpu)
+{
+    CPUPPCState *env = &cpu->env;
+    return env->spr_cb[SPR_PIR].default_value;
+}
+
 PowerPCCPU *ppc_get_vcpu_by_pir(int pir)
 {
     CPUState *cs;
 
     CPU_FOREACH(cs) {
         PowerPCCPU *cpu = POWERPC_CPU(cs);
-        CPUPPCState *env = &cpu->env;
 
-        if (env->spr_cb[SPR_PIR].default_value == pir) {
+        if (ppc_cpu_pir(cpu) == pir) {
             return cpu;
         }
     }
diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h
index 4bdcb8bacd..585be6ab98 100644
--- a/include/hw/ppc/ppc.h
+++ b/include/hw/ppc/ppc.h
@@ -5,6 +5,7 @@
 
 void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level);
 PowerPCCPU *ppc_get_vcpu_by_pir(int pir);
+int ppc_cpu_pir(PowerPCCPU *cpu);
 
 /* PowerPC hardware exceptions management helpers */
 typedef void (*clk_setup_cb)(void *opaque, uint32_t freq);
-- 
2.23.0



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

* [PULL 32/88] ppc/pnv: Introduce a pnv_xive_is_cpu_enabled() helper
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (30 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 31/88] ppc: Introduce a ppc_cpu_pir() helper David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 33/88] ppc/pnv: Fix TIMA indirect access David Gibson
                   ` (56 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

and use this helper to exclude CPUs which are not enabled in the XIVE
controller.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191125065820.927-7-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/pnv_xive.c   | 19 +++++++++++++++++++
 include/hw/ppc/pnv.h |  5 +++++
 2 files changed, 24 insertions(+)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 9798bd9e72..ec8349ee4a 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -372,6 +372,21 @@ static int pnv_xive_get_eas(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
     return pnv_xive_vst_read(xive, VST_TSEL_IVT, blk, idx, eas);
 }
 
+/*
+ * One bit per thread id. The first register PC_THREAD_EN_REG0 covers
+ * the first cores 0-15 (normal) of the chip or 0-7 (fused). The
+ * second register covers cores 16-23 (normal) or 8-11 (fused).
+ */
+static bool pnv_xive_is_cpu_enabled(PnvXive *xive, PowerPCCPU *cpu)
+{
+    int pir = ppc_cpu_pir(cpu);
+    uint32_t fc = PNV9_PIR2FUSEDCORE(pir);
+    uint64_t reg = fc < 8 ? PC_THREAD_EN_REG0 : PC_THREAD_EN_REG1;
+    uint32_t bit = pir & 0x3f;
+
+    return xive->regs[reg >> 3] & PPC_BIT(bit);
+}
+
 static int pnv_xive_match_nvt(XivePresenter *xptr, uint8_t format,
                               uint8_t nvt_blk, uint32_t nvt_idx,
                               bool cam_ignore, uint8_t priority,
@@ -391,6 +406,10 @@ static int pnv_xive_match_nvt(XivePresenter *xptr, uint8_t format,
             XiveTCTX *tctx;
             int ring;
 
+            if (!pnv_xive_is_cpu_enabled(xive, cpu)) {
+                continue;
+            }
+
             tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
 
             /*
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 03cb429f21..12b0169a40 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -99,6 +99,11 @@ typedef struct Pnv9Chip {
     PnvQuad      *quads;
 } Pnv9Chip;
 
+/*
+ * A SMT8 fused core is a pair of SMT4 cores.
+ */
+#define PNV9_PIR2FUSEDCORE(pir) (((pir) >> 3) & 0xf)
+
 typedef struct PnvChipClass {
     /*< private >*/
     SysBusDeviceClass parent_class;
-- 
2.23.0



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

* [PULL 33/88] ppc/pnv: Fix TIMA indirect access
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (31 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 32/88] ppc/pnv: Introduce a pnv_xive_is_cpu_enabled() helper David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 34/88] ppc/xive: Introduce a XiveFabric interface David Gibson
                   ` (55 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

When the TIMA of a CPU needs to be accessed from the indirect page,
the thread id of the target CPU is first stored in the PC_TCTXT_INDIR0
register. This thread id is relative to the chip and not to the system.

Introduce a helper routine to look for a CPU of a given PIR and fix
pnv_xive_get_indirect_tctx() to scan only the threads of the local
chip and not the whole machine.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191125065820.927-8-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/pnv_xive.c   | 13 +++++++------
 hw/ppc/pnv.c         | 17 +++++++++++++++++
 include/hw/ppc/pnv.h |  2 ++
 3 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index ec8349ee4a..b2ab2ccc91 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -1400,12 +1400,13 @@ static const MemoryRegionOps pnv_xive_ic_lsi_ops = {
  */
 
 /*
- * When the TIMA is accessed from the indirect page, the thread id
- * (PIR) has to be configured in the IC registers before. This is used
- * for resets and for debug purpose also.
+ * When the TIMA is accessed from the indirect page, the thread id of
+ * the target CPU is configured in the PC_TCTXT_INDIR0 register before
+ * use. This is used for resets and for debug purpose also.
  */
 static XiveTCTX *pnv_xive_get_indirect_tctx(PnvXive *xive)
 {
+    PnvChip *chip = xive->chip;
     uint64_t tctxt_indir = xive->regs[PC_TCTXT_INDIR0 >> 3];
     PowerPCCPU *cpu = NULL;
     int pir;
@@ -1415,15 +1416,15 @@ static XiveTCTX *pnv_xive_get_indirect_tctx(PnvXive *xive)
         return NULL;
     }
 
-    pir = GETFIELD(PC_TCTXT_INDIR_THRDID, tctxt_indir) & 0xff;
-    cpu = ppc_get_vcpu_by_pir(pir);
+    pir = (chip->chip_id << 8) | GETFIELD(PC_TCTXT_INDIR_THRDID, tctxt_indir);
+    cpu = pnv_chip_find_cpu(chip, pir);
     if (!cpu) {
         xive_error(xive, "IC: invalid PIR %x for indirect access", pir);
         return NULL;
     }
 
     /* Check that HW thread is XIVE enabled */
-    if (!(xive->regs[PC_THREAD_EN_REG0 >> 3] & PPC_BIT(pir & 0x3f))) {
+    if (!pnv_xive_is_cpu_enabled(xive, cpu)) {
         xive_error(xive, "IC: CPU %x is not enabled", pir);
     }
 
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index d899c83e52..8f688f4efc 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1371,6 +1371,23 @@ static void pnv_chip_class_init(ObjectClass *klass, void *data)
     dc->desc = "PowerNV Chip";
 }
 
+PowerPCCPU *pnv_chip_find_cpu(PnvChip *chip, uint32_t pir)
+{
+    int i, j;
+
+    for (i = 0; i < chip->nr_cores; i++) {
+        PnvCore *pc = chip->cores[i];
+        CPUCore *cc = CPU_CORE(pc);
+
+        for (j = 0; j < cc->nr_threads; j++) {
+            if (ppc_cpu_pir(pc->threads[j]) == pir) {
+                return pc->threads[j];
+            }
+        }
+    }
+    return NULL;
+}
+
 static ICSState *pnv_ics_get(XICSFabric *xi, int irq)
 {
     PnvMachineState *pnv = PNV_MACHINE(xi);
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 12b0169a40..a58cfea3f2 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -162,6 +162,8 @@ typedef struct PnvChipClass {
 #define PNV_CHIP_INDEX(chip)                                    \
     (((chip)->chip_id >> 2) * 2 + ((chip)->chip_id & 0x3))
 
+PowerPCCPU *pnv_chip_find_cpu(PnvChip *chip, uint32_t pir);
+
 #define TYPE_PNV_MACHINE       MACHINE_TYPE_NAME("powernv")
 #define PNV_MACHINE(obj) \
     OBJECT_CHECK(PnvMachineState, (obj), TYPE_PNV_MACHINE)
-- 
2.23.0



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

* [PULL 34/88] ppc/xive: Introduce a XiveFabric interface
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (32 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 33/88] ppc/pnv: Fix TIMA indirect access David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 35/88] ppc/pnv: Implement the " David Gibson
                   ` (54 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

The XiveFabric QOM interface acts as the PowerBUS interface between
the interrupt controller and the system and should be implemented by
the QEMU machine. On HW, the XIVE sub-engine is responsible for the
communication with the other chip is the Common Queue (CQ) bridge
unit.

This interface offers a 'match_nvt' handler to perform the CAM line
matching when looking for a XIVE Presenter with a dispatched NVT.

Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191125065820.927-9-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/xive.c        | 10 ++++++++++
 include/hw/ppc/xive.h | 22 ++++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index da6196ca95..1c9e58f8de 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1893,8 +1893,18 @@ static const TypeInfo xive_presenter_info = {
     .class_size = sizeof(XivePresenterClass),
 };
 
+/*
+ * XIVE Fabric
+ */
+static const TypeInfo xive_fabric_info = {
+    .name = TYPE_XIVE_FABRIC,
+    .parent = TYPE_INTERFACE,
+    .class_size = sizeof(XiveFabricClass),
+};
+
 static void xive_register_types(void)
 {
+    type_register_static(&xive_fabric_info);
     type_register_static(&xive_source_info);
     type_register_static(&xive_notifier_info);
     type_register_static(&xive_presenter_info);
diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index f9aa0fa0da..b00af98877 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -399,6 +399,28 @@ int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
                               uint8_t nvt_blk, uint32_t nvt_idx,
                               bool cam_ignore, uint32_t logic_serv);
 
+/*
+ * XIVE Fabric (Interface between Interrupt Controller and Machine)
+ */
+
+typedef struct XiveFabric XiveFabric;
+
+#define TYPE_XIVE_FABRIC "xive-fabric"
+#define XIVE_FABRIC(obj)                                     \
+    INTERFACE_CHECK(XiveFabric, (obj), TYPE_XIVE_FABRIC)
+#define XIVE_FABRIC_CLASS(klass)                                     \
+    OBJECT_CLASS_CHECK(XiveFabricClass, (klass), TYPE_XIVE_FABRIC)
+#define XIVE_FABRIC_GET_CLASS(obj)                                   \
+    OBJECT_GET_CLASS(XiveFabricClass, (obj), TYPE_XIVE_FABRIC)
+
+typedef struct XiveFabricClass {
+    InterfaceClass parent;
+    int (*match_nvt)(XiveFabric *xfb, uint8_t format,
+                     uint8_t nvt_blk, uint32_t nvt_idx,
+                     bool cam_ignore, uint8_t priority,
+                     uint32_t logic_serv, XiveTCTXMatch *match);
+} XiveFabricClass;
+
 /*
  * XIVE END ESBs
  */
-- 
2.23.0



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

* [PULL 35/88] ppc/pnv: Implement the XiveFabric interface
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (33 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 34/88] ppc/xive: Introduce a XiveFabric interface David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 36/88] ppc/spapr: " David Gibson
                   ` (53 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

The CAM line matching on the PowerNV machine now scans all chips of
the system and all CPUs of a chip to find a dispatched NVT in the
thread contexts.

Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191125065820.927-10-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 8f688f4efc..5b8b07f6ae 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1443,6 +1443,35 @@ static void pnv_pic_print_info(InterruptStatsProvider *obj,
     }
 }
 
+static int pnv_match_nvt(XiveFabric *xfb, uint8_t format,
+                         uint8_t nvt_blk, uint32_t nvt_idx,
+                         bool cam_ignore, uint8_t priority,
+                         uint32_t logic_serv,
+                         XiveTCTXMatch *match)
+{
+    PnvMachineState *pnv = PNV_MACHINE(xfb);
+    int total_count = 0;
+    int i;
+
+    for (i = 0; i < pnv->num_chips; i++) {
+        Pnv9Chip *chip9 = PNV9_CHIP(pnv->chips[i]);
+        XivePresenter *xptr = XIVE_PRESENTER(&chip9->xive);
+        XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr);
+        int count;
+
+        count = xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, cam_ignore,
+                               priority, logic_serv, match);
+
+        if (count < 0) {
+            return count;
+        }
+
+        total_count += count;
+    }
+
+    return total_count;
+}
+
 static void pnv_get_num_chips(Object *obj, Visitor *v, const char *name,
                               void *opaque, Error **errp)
 {
@@ -1506,9 +1535,11 @@ static void pnv_machine_power8_class_init(ObjectClass *oc, void *data)
 static void pnv_machine_power9_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
+    XiveFabricClass *xfc = XIVE_FABRIC_CLASS(oc);
 
     mc->desc = "IBM PowerNV (Non-Virtualized) POWER9";
     mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power9_v2.0");
+    xfc->match_nvt = pnv_match_nvt;
 
     mc->alias = "powernv";
 }
@@ -1555,6 +1586,10 @@ static const TypeInfo types[] = {
         .name          = MACHINE_TYPE_NAME("powernv9"),
         .parent        = TYPE_PNV_MACHINE,
         .class_init    = pnv_machine_power9_class_init,
+        .interfaces = (InterfaceInfo[]) {
+            { TYPE_XIVE_FABRIC },
+            { },
+        },
     },
     {
         .name          = MACHINE_TYPE_NAME("powernv8"),
-- 
2.23.0



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

* [PULL 36/88] ppc/spapr: Implement the XiveFabric interface
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (34 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 35/88] ppc/pnv: Implement the " David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 37/88] ppc/xive: Use the XiveFabric and XivePresenter interfaces David Gibson
                   ` (52 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

The CAM line matching sequence in the pseries machine does not change
much apart from the use of the new QOM interfaces. There is an extra
indirection because of the sPAPR IRQ backend of the machine. Only the
XIVE backend implements the new 'match_nvt' handler.

Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191125065820.927-11-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 3ae7db1563..d9c9a2bcee 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4275,6 +4275,42 @@ static void spapr_pic_print_info(InterruptStatsProvider *obj,
                    kvm_irqchip_in_kernel() ? "in-kernel" : "emulated");
 }
 
+static int spapr_match_nvt(XiveFabric *xfb, uint8_t format,
+                           uint8_t nvt_blk, uint32_t nvt_idx,
+                           bool cam_ignore, uint8_t priority,
+                           uint32_t logic_serv, XiveTCTXMatch *match)
+{
+    SpaprMachineState *spapr = SPAPR_MACHINE(xfb);
+    XivePresenter *xptr = XIVE_PRESENTER(spapr->xive);
+    XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr);
+    int count;
+
+    /* This is a XIVE only operation */
+    assert(spapr->active_intc == SPAPR_INTC(spapr->xive));
+
+    count = xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, cam_ignore,
+                           priority, logic_serv, match);
+    if (count < 0) {
+        return count;
+    }
+
+    /*
+     * When we implement the save and restore of the thread interrupt
+     * contexts in the enter/exit CPU handlers of the machine and the
+     * escalations in QEMU, we should be able to handle non dispatched
+     * vCPUs.
+     *
+     * Until this is done, the sPAPR machine should find at least one
+     * matching context always.
+     */
+    if (count == 0) {
+        qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVT %x/%x is not dispatched\n",
+                      nvt_blk, nvt_idx);
+    }
+
+    return count;
+}
+
 int spapr_get_vcpu_id(PowerPCCPU *cpu)
 {
     return cpu->vcpu_id;
@@ -4371,6 +4407,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
     PPCVirtualHypervisorClass *vhc = PPC_VIRTUAL_HYPERVISOR_CLASS(oc);
     XICSFabricClass *xic = XICS_FABRIC_CLASS(oc);
     InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc);
+    XiveFabricClass *xfc = XIVE_FABRIC_CLASS(oc);
 
     mc->desc = "pSeries Logical Partition (PAPR compliant)";
     mc->ignore_boot_device_suffixes = true;
@@ -4447,6 +4484,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
     smc->linux_pci_probe = true;
     smc->smp_threads_vsmt = true;
     smc->nr_xirqs = SPAPR_NR_XIRQS;
+    xfc->match_nvt = spapr_match_nvt;
 }
 
 static const TypeInfo spapr_machine_info = {
@@ -4465,6 +4503,7 @@ static const TypeInfo spapr_machine_info = {
         { TYPE_PPC_VIRTUAL_HYPERVISOR },
         { TYPE_XICS_FABRIC },
         { TYPE_INTERRUPT_STATS_PROVIDER },
+        { TYPE_XIVE_FABRIC },
         { }
     },
 };
-- 
2.23.0



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

* [PULL 37/88] ppc/xive: Use the XiveFabric and XivePresenter interfaces
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (35 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 36/88] ppc/spapr: " David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 38/88] ppc/xive: Extend the TIMA operation with a XivePresenter parameter David Gibson
                   ` (51 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

Now that the machines have handlers implementing the XiveFabric and
XivePresenter interfaces, remove xive_presenter_match() and make use
of the 'match_nvt' handler of the machine.

Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191125065820.927-12-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/xive.c | 48 +++++++++++++++++-------------------------------
 1 file changed, 17 insertions(+), 31 deletions(-)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 1c9e58f8de..8e683847bf 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1423,30 +1423,6 @@ int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
     return -1;
 }
 
-static bool xive_presenter_match(XiveRouter *xrtr, uint8_t format,
-                                 uint8_t nvt_blk, uint32_t nvt_idx,
-                                 bool cam_ignore, uint8_t priority,
-                                 uint32_t logic_serv, XiveTCTXMatch *match)
-{
-    XivePresenter *xptr = XIVE_PRESENTER(xrtr);
-    XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr);
-    int count;
-
-    count = xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, cam_ignore,
-                           priority, logic_serv, match);
-    if (count < 0) {
-        return false;
-    }
-
-    if (!match->tctx) {
-        qemu_log_mask(LOG_UNIMP, "XIVE: NVT %x/%x is not dispatched\n",
-                      nvt_blk, nvt_idx);
-        return false;
-    }
-
-    return true;
-}
-
 /*
  * This is our simple Xive Presenter Engine model. It is merged in the
  * Router as it does not require an extra object.
@@ -1462,22 +1438,32 @@ static bool xive_presenter_match(XiveRouter *xrtr, uint8_t format,
  *
  * The parameters represent what is sent on the PowerBus
  */
-static bool xive_presenter_notify(XiveRouter *xrtr, uint8_t format,
+static bool xive_presenter_notify(uint8_t format,
                                   uint8_t nvt_blk, uint32_t nvt_idx,
                                   bool cam_ignore, uint8_t priority,
                                   uint32_t logic_serv)
 {
+    XiveFabric *xfb = XIVE_FABRIC(qdev_get_machine());
+    XiveFabricClass *xfc = XIVE_FABRIC_GET_CLASS(xfb);
     XiveTCTXMatch match = { .tctx = NULL, .ring = 0 };
-    bool found;
+    int count;
 
-    found = xive_presenter_match(xrtr, format, nvt_blk, nvt_idx, cam_ignore,
-                                 priority, logic_serv, &match);
-    if (found) {
+    /*
+     * Ask the machine to scan the interrupt controllers for a match
+     */
+    count = xfc->match_nvt(xfb, format, nvt_blk, nvt_idx, cam_ignore,
+                           priority, logic_serv, &match);
+    if (count < 0) {
+        return false;
+    }
+
+    /* handle CPU exception delivery */
+    if (count) {
         ipb_update(&match.tctx->regs[match.ring], priority);
         xive_tctx_notify(match.tctx, match.ring);
     }
 
-    return found;
+    return !!count;
 }
 
 /*
@@ -1590,7 +1576,7 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk,
         return;
     }
 
-    found = xive_presenter_notify(xrtr, format, nvt_blk, nvt_idx,
+    found = xive_presenter_notify(format, nvt_blk, nvt_idx,
                           xive_get_field32(END_W7_F0_IGNORE, end.w7),
                           priority,
                           xive_get_field32(END_W7_F1_LOG_SERVER_ID, end.w7));
-- 
2.23.0



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

* [PULL 38/88] ppc/xive: Extend the TIMA operation with a XivePresenter parameter
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (36 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 37/88] ppc/xive: Use the XiveFabric and XivePresenter interfaces David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 39/88] linux-headers: Update David Gibson
                   ` (50 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

The TIMA operations are performed on behalf of the XIVE IVPE sub-engine
(Presenter) on the thread interrupt context registers. The current
operations supported by the model are simple and do not require access
to the controller but more complex operations will need access to the
controller NVT table and to its configuration.

Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191125065820.927-13-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/pnv_xive.c    |  4 +--
 hw/intc/xive.c        | 58 ++++++++++++++++++++++++-------------------
 include/hw/ppc/xive.h |  7 +++---
 3 files changed, 38 insertions(+), 31 deletions(-)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index b2ab2ccc91..95e9de312c 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -1436,7 +1436,7 @@ static void xive_tm_indirect_write(void *opaque, hwaddr offset,
 {
     XiveTCTX *tctx = pnv_xive_get_indirect_tctx(PNV_XIVE(opaque));
 
-    xive_tctx_tm_write(tctx, offset, value, size);
+    xive_tctx_tm_write(XIVE_PRESENTER(opaque), tctx, offset, value, size);
 }
 
 static uint64_t xive_tm_indirect_read(void *opaque, hwaddr offset,
@@ -1444,7 +1444,7 @@ static uint64_t xive_tm_indirect_read(void *opaque, hwaddr offset,
 {
     XiveTCTX *tctx = pnv_xive_get_indirect_tctx(PNV_XIVE(opaque));
 
-    return xive_tctx_tm_read(tctx, offset, size);
+    return xive_tctx_tm_read(XIVE_PRESENTER(opaque), tctx, offset, size);
 }
 
 static const MemoryRegionOps xive_tm_indirect_ops = {
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 8e683847bf..9e7e5ea57c 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -144,19 +144,20 @@ static inline uint32_t xive_tctx_word2(uint8_t *ring)
  * XIVE Thread Interrupt Management Area (TIMA)
  */
 
-static void xive_tm_set_hv_cppr(XiveTCTX *tctx, hwaddr offset,
-                                uint64_t value, unsigned size)
+static void xive_tm_set_hv_cppr(XivePresenter *xptr, XiveTCTX *tctx,
+                                hwaddr offset, uint64_t value, unsigned size)
 {
     xive_tctx_set_cppr(tctx, TM_QW3_HV_PHYS, value & 0xff);
 }
 
-static uint64_t xive_tm_ack_hv_reg(XiveTCTX *tctx, hwaddr offset, unsigned size)
+static uint64_t xive_tm_ack_hv_reg(XivePresenter *xptr, XiveTCTX *tctx,
+                                   hwaddr offset, unsigned size)
 {
     return xive_tctx_accept(tctx, TM_QW3_HV_PHYS);
 }
 
-static uint64_t xive_tm_pull_pool_ctx(XiveTCTX *tctx, hwaddr offset,
-                                      unsigned size)
+static uint64_t xive_tm_pull_pool_ctx(XivePresenter *xptr, XiveTCTX *tctx,
+                                      hwaddr offset, unsigned size)
 {
     uint32_t qw2w2_prev = xive_tctx_word2(&tctx->regs[TM_QW2_HV_POOL]);
     uint32_t qw2w2;
@@ -166,13 +167,14 @@ static uint64_t xive_tm_pull_pool_ctx(XiveTCTX *tctx, hwaddr offset,
     return qw2w2;
 }
 
-static void xive_tm_vt_push(XiveTCTX *tctx, hwaddr offset,
+static void xive_tm_vt_push(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
                             uint64_t value, unsigned size)
 {
     tctx->regs[TM_QW3_HV_PHYS + TM_WORD2] = value & 0xff;
 }
 
-static uint64_t xive_tm_vt_poll(XiveTCTX *tctx, hwaddr offset, unsigned size)
+static uint64_t xive_tm_vt_poll(XivePresenter *xptr, XiveTCTX *tctx,
+                                hwaddr offset, unsigned size)
 {
     return tctx->regs[TM_QW3_HV_PHYS + TM_WORD2] & 0xff;
 }
@@ -315,13 +317,14 @@ static uint64_t xive_tm_raw_read(XiveTCTX *tctx, hwaddr offset, unsigned size)
  * state changes (side effects) in addition to setting/returning the
  * interrupt management area context of the processor thread.
  */
-static uint64_t xive_tm_ack_os_reg(XiveTCTX *tctx, hwaddr offset, unsigned size)
+static uint64_t xive_tm_ack_os_reg(XivePresenter *xptr, XiveTCTX *tctx,
+                                   hwaddr offset, unsigned size)
 {
     return xive_tctx_accept(tctx, TM_QW1_OS);
 }
 
-static void xive_tm_set_os_cppr(XiveTCTX *tctx, hwaddr offset,
-                                uint64_t value, unsigned size)
+static void xive_tm_set_os_cppr(XivePresenter *xptr, XiveTCTX *tctx,
+                                hwaddr offset, uint64_t value, unsigned size)
 {
     xive_tctx_set_cppr(tctx, TM_QW1_OS, value & 0xff);
 }
@@ -330,8 +333,8 @@ static void xive_tm_set_os_cppr(XiveTCTX *tctx, hwaddr offset,
  * Adjust the IPB to allow a CPU to process event queues of other
  * priorities during one physical interrupt cycle.
  */
-static void xive_tm_set_os_pending(XiveTCTX *tctx, hwaddr offset,
-                                   uint64_t value, unsigned size)
+static void xive_tm_set_os_pending(XivePresenter *xptr, XiveTCTX *tctx,
+                                   hwaddr offset, uint64_t value, unsigned size)
 {
     ipb_update(&tctx->regs[TM_QW1_OS], value & 0xff);
     xive_tctx_notify(tctx, TM_QW1_OS);
@@ -366,8 +369,8 @@ static void xive_tctx_set_os_cam(XiveTCTX *tctx, uint32_t qw1w2)
     memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2, 4);
 }
 
-static uint64_t xive_tm_pull_os_ctx(XiveTCTX *tctx, hwaddr offset,
-                                    unsigned size)
+static uint64_t xive_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
+                                    hwaddr offset, unsigned size)
 {
     uint32_t qw1w2;
     uint32_t qw1w2_new;
@@ -396,9 +399,11 @@ typedef struct XiveTmOp {
     uint8_t  page_offset;
     uint32_t op_offset;
     unsigned size;
-    void     (*write_handler)(XiveTCTX *tctx, hwaddr offset, uint64_t value,
-                              unsigned size);
-    uint64_t (*read_handler)(XiveTCTX *tctx, hwaddr offset, unsigned size);
+    void     (*write_handler)(XivePresenter *xptr, XiveTCTX *tctx,
+                              hwaddr offset,
+                              uint64_t value, unsigned size);
+    uint64_t (*read_handler)(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
+                             unsigned size);
 } XiveTmOp;
 
 static const XiveTmOp xive_tm_operations[] = {
@@ -444,8 +449,8 @@ static const XiveTmOp *xive_tm_find_op(hwaddr offset, unsigned size, bool write)
 /*
  * TIMA MMIO handlers
  */
-void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, uint64_t value,
-                        unsigned size)
+void xive_tctx_tm_write(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
+                        uint64_t value, unsigned size)
 {
     const XiveTmOp *xto;
 
@@ -462,7 +467,7 @@ void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, uint64_t value,
             qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid write access at TIMA "
                           "@%"HWADDR_PRIx"\n", offset);
         } else {
-            xto->write_handler(tctx, offset, value, size);
+            xto->write_handler(xptr, tctx, offset, value, size);
         }
         return;
     }
@@ -472,7 +477,7 @@ void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, uint64_t value,
      */
     xto = xive_tm_find_op(offset, size, true);
     if (xto) {
-        xto->write_handler(tctx, offset, value, size);
+        xto->write_handler(xptr, tctx, offset, value, size);
         return;
     }
 
@@ -482,7 +487,8 @@ void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, uint64_t value,
     xive_tm_raw_write(tctx, offset, value, size);
 }
 
-uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size)
+uint64_t xive_tctx_tm_read(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
+                           unsigned size)
 {
     const XiveTmOp *xto;
 
@@ -500,7 +506,7 @@ uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size)
                           "@%"HWADDR_PRIx"\n", offset);
             return -1;
         }
-        return xto->read_handler(tctx, offset, size);
+        return xto->read_handler(xptr, tctx, offset, size);
     }
 
     /*
@@ -508,7 +514,7 @@ uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size)
      */
     xto = xive_tm_find_op(offset, size, false);
     if (xto) {
-        return xto->read_handler(tctx, offset, size);
+        return xto->read_handler(xptr, tctx, offset, size);
     }
 
     /*
@@ -522,14 +528,14 @@ static void xive_tm_write(void *opaque, hwaddr offset,
 {
     XiveTCTX *tctx = xive_router_get_tctx(XIVE_ROUTER(opaque), current_cpu);
 
-    xive_tctx_tm_write(tctx, offset, value, size);
+    xive_tctx_tm_write(XIVE_PRESENTER(opaque), tctx, offset, value, size);
 }
 
 static uint64_t xive_tm_read(void *opaque, hwaddr offset, unsigned size)
 {
     XiveTCTX *tctx = xive_router_get_tctx(XIVE_ROUTER(opaque), current_cpu);
 
-    return xive_tctx_tm_read(tctx, offset, size);
+    return xive_tctx_tm_read(XIVE_PRESENTER(opaque), tctx, offset, size);
 }
 
 const MemoryRegionOps xive_tm_ops = {
diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index b00af98877..97bbcddb38 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -463,9 +463,10 @@ typedef struct XiveENDSource {
 #define XIVE_TM_USER_PAGE       0x3
 
 extern const MemoryRegionOps xive_tm_ops;
-void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, uint64_t value,
-                        unsigned size);
-uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size);
+void xive_tctx_tm_write(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
+                        uint64_t value, unsigned size);
+uint64_t xive_tctx_tm_read(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
+                           unsigned size);
 
 void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon);
 Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp);
-- 
2.23.0



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

* [PULL 39/88] linux-headers: Update
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (37 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 38/88] ppc/xive: Extend the TIMA operation with a XivePresenter parameter David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 40/88] spapr: Pass the maximum number of vCPUs to the KVM interrupt controller David Gibson
                   ` (49 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

Update to mainline commit be2eca94d144 ("Merge tag 'for-linus-5.5-1'`
of git://github.com/cminyard/linux-ipmi")

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157478677756.67101.11558821804418331832.stgit@bahia.tlslab.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 include/standard-headers/linux/ethtool.h     |  6 ++++++
 include/standard-headers/linux/virtio_ring.h |  2 +-
 linux-headers/asm-arm/kvm.h                  |  3 ++-
 linux-headers/asm-arm64/kvm.h                |  5 ++++-
 linux-headers/asm-mips/unistd_n32.h          |  1 +
 linux-headers/asm-mips/unistd_n64.h          |  1 +
 linux-headers/asm-mips/unistd_o32.h          |  1 +
 linux-headers/asm-powerpc/kvm.h              |  3 +++
 linux-headers/linux/kvm.h                    | 11 +++++++++++
 linux-headers/linux/psp-sev.h                |  3 +++
 10 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/include/standard-headers/linux/ethtool.h b/include/standard-headers/linux/ethtool.h
index 4ff422b635..6e8a10ee10 100644
--- a/include/standard-headers/linux/ethtool.h
+++ b/include/standard-headers/linux/ethtool.h
@@ -1507,6 +1507,11 @@ enum ethtool_link_mode_bit_indices {
 	ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT	 = 66,
 	ETHTOOL_LINK_MODE_100baseT1_Full_BIT		 = 67,
 	ETHTOOL_LINK_MODE_1000baseT1_Full_BIT		 = 68,
+	ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT	 = 69,
+	ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT	 = 70,
+	ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT = 71,
+	ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT	 = 72,
+	ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT	 = 73,
 
 	/* must be last entry */
 	__ETHTOOL_LINK_MODE_MASK_NBITS
@@ -1618,6 +1623,7 @@ enum ethtool_link_mode_bit_indices {
 #define SPEED_56000		56000
 #define SPEED_100000		100000
 #define SPEED_200000		200000
+#define SPEED_400000		400000
 
 #define SPEED_UNKNOWN		-1
 
diff --git a/include/standard-headers/linux/virtio_ring.h b/include/standard-headers/linux/virtio_ring.h
index 306cd41147..f230fed479 100644
--- a/include/standard-headers/linux/virtio_ring.h
+++ b/include/standard-headers/linux/virtio_ring.h
@@ -167,7 +167,7 @@ static inline void vring_init(struct vring *vr, unsigned int num, void *p,
 {
 	vr->num = num;
 	vr->desc = p;
-	vr->avail = p + num*sizeof(struct vring_desc);
+	vr->avail = (struct vring_avail *)((char *)p + num * sizeof(struct vring_desc));
 	vr->used = (void *)(((uintptr_t)&vr->avail->ring[num] + sizeof(__virtio16)
 		+ align-1) & ~(align - 1));
 }
diff --git a/linux-headers/asm-arm/kvm.h b/linux-headers/asm-arm/kvm.h
index 9d379d3372..0db5644e27 100644
--- a/linux-headers/asm-arm/kvm.h
+++ b/linux-headers/asm-arm/kvm.h
@@ -131,8 +131,9 @@ struct kvm_vcpu_events {
 	struct {
 		__u8 serror_pending;
 		__u8 serror_has_esr;
+		__u8 ext_dabt_pending;
 		/* Align it to 8 bytes */
-		__u8 pad[6];
+		__u8 pad[5];
 		__u64 serror_esr;
 	} exception;
 	__u32 reserved[12];
diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h
index 0ce6e49f3a..920af01c8b 100644
--- a/linux-headers/asm-arm64/kvm.h
+++ b/linux-headers/asm-arm64/kvm.h
@@ -164,8 +164,9 @@ struct kvm_vcpu_events {
 	struct {
 		__u8 serror_pending;
 		__u8 serror_has_esr;
+		__u8 ext_dabt_pending;
 		/* Align it to 8 bytes */
-		__u8 pad[6];
+		__u8 pad[5];
 		__u64 serror_esr;
 	} exception;
 	__u32 reserved[12];
@@ -323,6 +324,8 @@ struct kvm_vcpu_events {
 #define KVM_ARM_VCPU_TIMER_CTRL		1
 #define   KVM_ARM_VCPU_TIMER_IRQ_VTIMER		0
 #define   KVM_ARM_VCPU_TIMER_IRQ_PTIMER		1
+#define KVM_ARM_VCPU_PVTIME_CTRL	2
+#define   KVM_ARM_VCPU_PVTIME_IPA	0
 
 /* KVM_IRQ_LINE irq field index values */
 #define KVM_ARM_IRQ_VCPU2_SHIFT		28
diff --git a/linux-headers/asm-mips/unistd_n32.h b/linux-headers/asm-mips/unistd_n32.h
index 7dffe8e34e..659d5c9ade 100644
--- a/linux-headers/asm-mips/unistd_n32.h
+++ b/linux-headers/asm-mips/unistd_n32.h
@@ -364,6 +364,7 @@
 #define __NR_fsmount	(__NR_Linux + 432)
 #define __NR_fspick	(__NR_Linux + 433)
 #define __NR_pidfd_open	(__NR_Linux + 434)
+#define __NR_clone3	(__NR_Linux + 435)
 
 
 #endif /* _ASM_MIPS_UNISTD_N32_H */
diff --git a/linux-headers/asm-mips/unistd_n64.h b/linux-headers/asm-mips/unistd_n64.h
index f4592d6fc5..4b6310a05c 100644
--- a/linux-headers/asm-mips/unistd_n64.h
+++ b/linux-headers/asm-mips/unistd_n64.h
@@ -340,6 +340,7 @@
 #define __NR_fsmount	(__NR_Linux + 432)
 #define __NR_fspick	(__NR_Linux + 433)
 #define __NR_pidfd_open	(__NR_Linux + 434)
+#define __NR_clone3	(__NR_Linux + 435)
 
 
 #endif /* _ASM_MIPS_UNISTD_N64_H */
diff --git a/linux-headers/asm-mips/unistd_o32.h b/linux-headers/asm-mips/unistd_o32.h
index 04c6728352..4ce7b4e288 100644
--- a/linux-headers/asm-mips/unistd_o32.h
+++ b/linux-headers/asm-mips/unistd_o32.h
@@ -410,6 +410,7 @@
 #define __NR_fsmount	(__NR_Linux + 432)
 #define __NR_fspick	(__NR_Linux + 433)
 #define __NR_pidfd_open	(__NR_Linux + 434)
+#define __NR_clone3	(__NR_Linux + 435)
 
 
 #endif /* _ASM_MIPS_UNISTD_O32_H */
diff --git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kvm.h
index b0f72dea8b..264e266a85 100644
--- a/linux-headers/asm-powerpc/kvm.h
+++ b/linux-headers/asm-powerpc/kvm.h
@@ -667,6 +667,8 @@ struct kvm_ppc_cpu_char {
 
 /* PPC64 eXternal Interrupt Controller Specification */
 #define KVM_DEV_XICS_GRP_SOURCES	1	/* 64-bit source attributes */
+#define KVM_DEV_XICS_GRP_CTRL		2
+#define   KVM_DEV_XICS_NR_SERVERS	1
 
 /* Layout of 64-bit source attribute values */
 #define  KVM_XICS_DESTINATION_SHIFT	0
@@ -683,6 +685,7 @@ struct kvm_ppc_cpu_char {
 #define KVM_DEV_XIVE_GRP_CTRL		1
 #define   KVM_DEV_XIVE_RESET		1
 #define   KVM_DEV_XIVE_EQ_SYNC		2
+#define   KVM_DEV_XIVE_NR_SERVERS	3
 #define KVM_DEV_XIVE_GRP_SOURCE		2	/* 64-bit source identifier */
 #define KVM_DEV_XIVE_GRP_SOURCE_CONFIG	3	/* 64-bit source identifier */
 #define KVM_DEV_XIVE_GRP_EQ_CONFIG	4	/* 64-bit EQ identifier */
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 3d9b18f7f8..3b27a1ae85 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -235,6 +235,7 @@ struct kvm_hyperv_exit {
 #define KVM_EXIT_S390_STSI        25
 #define KVM_EXIT_IOAPIC_EOI       26
 #define KVM_EXIT_HYPERV           27
+#define KVM_EXIT_ARM_NISV         28
 
 /* For KVM_EXIT_INTERNAL_ERROR */
 /* Emulate instruction failed. */
@@ -394,6 +395,11 @@ struct kvm_run {
 		} eoi;
 		/* KVM_EXIT_HYPERV */
 		struct kvm_hyperv_exit hyperv;
+		/* KVM_EXIT_ARM_NISV */
+		struct {
+			__u64 esr_iss;
+			__u64 fault_ipa;
+		} arm_nisv;
 		/* Fix the size of the union. */
 		char padding[256];
 	};
@@ -1000,6 +1006,9 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_PMU_EVENT_FILTER 173
 #define KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 174
 #define KVM_CAP_HYPERV_DIRECT_TLBFLUSH 175
+#define KVM_CAP_PPC_GUEST_DEBUG_SSTEP 176
+#define KVM_CAP_ARM_NISV_TO_USER 177
+#define KVM_CAP_ARM_INJECT_EXT_DABT 178
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1227,6 +1236,8 @@ enum kvm_device_type {
 #define KVM_DEV_TYPE_ARM_VGIC_ITS	KVM_DEV_TYPE_ARM_VGIC_ITS
 	KVM_DEV_TYPE_XIVE,
 #define KVM_DEV_TYPE_XIVE		KVM_DEV_TYPE_XIVE
+	KVM_DEV_TYPE_ARM_PV_TIME,
+#define KVM_DEV_TYPE_ARM_PV_TIME	KVM_DEV_TYPE_ARM_PV_TIME
 	KVM_DEV_TYPE_MAX,
 };
 
diff --git a/linux-headers/linux/psp-sev.h b/linux-headers/linux/psp-sev.h
index 34c39690c0..31f971e896 100644
--- a/linux-headers/linux/psp-sev.h
+++ b/linux-headers/linux/psp-sev.h
@@ -58,6 +58,9 @@ typedef enum {
 	SEV_RET_HWSEV_RET_PLATFORM,
 	SEV_RET_HWSEV_RET_UNSAFE,
 	SEV_RET_UNSUPPORTED,
+	SEV_RET_INVALID_PARAM,
+	SEV_RET_RESOURCE_LIMIT,
+	SEV_RET_SECURE_DATA_INVALID,
 	SEV_RET_MAX,
 } sev_ret_code;
 
-- 
2.23.0



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

* [PULL 40/88] spapr: Pass the maximum number of vCPUs to the KVM interrupt controller
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (38 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 39/88] linux-headers: Update David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 41/88] spapr/xics: Configure number of servers in KVM David Gibson
                   ` (48 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The XIVE and XICS-on-XIVE KVM devices on POWER9 hosts can greatly reduce
their consumption of some scarce HW resources, namely Virtual Presenter
identifiers, if they know the maximum number of vCPUs that may run in the
VM.

Prepare ground for this by passing the value down to xics_kvm_connect()
and kvmppc_xive_connect(). This is purely mechanical, no functional
change.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157478678301.67101.2717368060417156338.stgit@bahia.tlslab.ibm.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/spapr_xive.c        |  6 ++++--
 hw/intc/spapr_xive_kvm.c    |  3 ++-
 hw/intc/xics_kvm.c          |  3 ++-
 hw/intc/xics_spapr.c        |  5 +++--
 hw/ppc/spapr_irq.c          |  8 +++++---
 include/hw/ppc/spapr_irq.h  | 10 ++++++++--
 include/hw/ppc/spapr_xive.h |  3 ++-
 include/hw/ppc/xics_spapr.h |  3 ++-
 8 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index bb3b2dfdb7..18a043a277 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -697,12 +697,14 @@ static void spapr_xive_dt(SpaprInterruptController *intc, uint32_t nr_servers,
                      plat_res_int_priorities, sizeof(plat_res_int_priorities)));
 }
 
-static int spapr_xive_activate(SpaprInterruptController *intc, Error **errp)
+static int spapr_xive_activate(SpaprInterruptController *intc,
+                               uint32_t nr_servers, Error **errp)
 {
     SpaprXive *xive = SPAPR_XIVE(intc);
 
     if (kvm_enabled()) {
-        int rc = spapr_irq_init_kvm(kvmppc_xive_connect, intc, errp);
+        int rc = spapr_irq_init_kvm(kvmppc_xive_connect, intc, nr_servers,
+                                    errp);
         if (rc < 0) {
             return rc;
         }
diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
index 69e73552f1..46c7609bd8 100644
--- a/hw/intc/spapr_xive_kvm.c
+++ b/hw/intc/spapr_xive_kvm.c
@@ -728,7 +728,8 @@ static void *kvmppc_xive_mmap(SpaprXive *xive, int pgoff, size_t len,
  * All the XIVE memory regions are now backed by mappings from the KVM
  * XIVE device.
  */
-int kvmppc_xive_connect(SpaprInterruptController *intc, Error **errp)
+int kvmppc_xive_connect(SpaprInterruptController *intc, uint32_t nr_servers,
+                        Error **errp)
 {
     SpaprXive *xive = SPAPR_XIVE(intc);
     XiveSource *xsrc = &xive->source;
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 954c424b36..a1f1b7b0d3 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -342,7 +342,8 @@ void ics_kvm_set_irq(ICSState *ics, int srcno, int val)
     }
 }
 
-int xics_kvm_connect(SpaprInterruptController *intc, Error **errp)
+int xics_kvm_connect(SpaprInterruptController *intc, uint32_t nr_servers,
+                     Error **errp)
 {
     ICSState *ics = ICS_SPAPR(intc);
     int rc;
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index b3705dab0e..8ae4f41459 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -422,10 +422,11 @@ static int xics_spapr_post_load(SpaprInterruptController *intc, int version_id)
     return 0;
 }
 
-static int xics_spapr_activate(SpaprInterruptController *intc, Error **errp)
+static int xics_spapr_activate(SpaprInterruptController *intc,
+                               uint32_t nr_servers, Error **errp)
 {
     if (kvm_enabled()) {
-        return spapr_irq_init_kvm(xics_kvm_connect, intc, errp);
+        return spapr_irq_init_kvm(xics_kvm_connect, intc, nr_servers, errp);
     }
     return 0;
 }
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index d4a54afc86..07e08d6544 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -70,15 +70,16 @@ void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num)
     bitmap_clear(spapr->irq_map, irq - SPAPR_IRQ_MSI, num);
 }
 
-int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
+int spapr_irq_init_kvm(SpaprInterruptControllerInitKvm fn,
                        SpaprInterruptController *intc,
+                       uint32_t nr_servers,
                        Error **errp)
 {
     MachineState *machine = MACHINE(qdev_get_machine());
     Error *local_err = NULL;
 
     if (kvm_enabled() && machine_kernel_irqchip_allowed(machine)) {
-        if (fn(intc, &local_err) < 0) {
+        if (fn(intc, nr_servers, &local_err) < 0) {
             if (machine_kernel_irqchip_required(machine)) {
                 error_prepend(&local_err,
                               "kernel_irqchip requested but unavailable: ");
@@ -481,6 +482,7 @@ static void set_active_intc(SpaprMachineState *spapr,
                             SpaprInterruptController *new_intc)
 {
     SpaprInterruptControllerClass *sicc;
+    uint32_t nr_servers = spapr_max_server_number(spapr);
 
     assert(new_intc);
 
@@ -498,7 +500,7 @@ static void set_active_intc(SpaprMachineState *spapr,
 
     sicc = SPAPR_INTC_GET_CLASS(new_intc);
     if (sicc->activate) {
-        sicc->activate(new_intc, &error_fatal);
+        sicc->activate(new_intc, nr_servers, &error_fatal);
     }
 
     spapr->active_intc = new_intc;
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index ff814d13de..ca8cb44213 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -43,7 +43,8 @@ typedef struct SpaprInterruptController SpaprInterruptController;
 typedef struct SpaprInterruptControllerClass {
     InterfaceClass parent;
 
-    int (*activate)(SpaprInterruptController *intc, Error **errp);
+    int (*activate)(SpaprInterruptController *intc, uint32_t nr_servers,
+                    Error **errp);
     void (*deactivate)(SpaprInterruptController *intc);
 
     /*
@@ -98,8 +99,13 @@ qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq);
 int spapr_irq_post_load(SpaprMachineState *spapr, int version_id);
 void spapr_irq_reset(SpaprMachineState *spapr, Error **errp);
 int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp);
-int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **),
+
+typedef int (*SpaprInterruptControllerInitKvm)(SpaprInterruptController *,
+                                               uint32_t, Error **);
+
+int spapr_irq_init_kvm(SpaprInterruptControllerInitKvm fn,
                        SpaprInterruptController *intc,
+                       uint32_t nr_servers,
                        Error **errp);
 
 /*
diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
index 742b7e834f..3a103c224d 100644
--- a/include/hw/ppc/spapr_xive.h
+++ b/include/hw/ppc/spapr_xive.h
@@ -66,7 +66,8 @@ int spapr_xive_end_to_target(uint8_t end_blk, uint32_t end_idx,
 /*
  * KVM XIVE device helpers
  */
-int kvmppc_xive_connect(SpaprInterruptController *intc, Error **errp);
+int kvmppc_xive_connect(SpaprInterruptController *intc, uint32_t nr_servers,
+                        Error **errp);
 void kvmppc_xive_disconnect(SpaprInterruptController *intc);
 void kvmppc_xive_reset(SpaprXive *xive, Error **errp);
 void kvmppc_xive_set_source_config(SpaprXive *xive, uint32_t lisn, XiveEAS *eas,
diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
index 28b87038c8..1c65c96e3c 100644
--- a/include/hw/ppc/xics_spapr.h
+++ b/include/hw/ppc/xics_spapr.h
@@ -32,7 +32,8 @@
 #define TYPE_ICS_SPAPR "ics-spapr"
 #define ICS_SPAPR(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SPAPR)
 
-int xics_kvm_connect(SpaprInterruptController *intc, Error **errp);
+int xics_kvm_connect(SpaprInterruptController *intc, uint32_t nr_servers,
+                     Error **errp);
 void xics_kvm_disconnect(SpaprInterruptController *intc);
 bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr);
 
-- 
2.23.0



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

* [PULL 41/88] spapr/xics: Configure number of servers in KVM
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (39 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 40/88] spapr: Pass the maximum number of vCPUs to the KVM interrupt controller David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 42/88] spapr/xive: " David Gibson
                   ` (47 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The XICS-on-XIVE KVM devices now has an attribute to configure the number
of interrupt servers. This allows to greatly optimize the usage of the VP
space in the XIVE HW, and thus to start a lot more VMs.

Only set this attribute if available in order to support older POWER9 KVM
and pre-POWER9 XICS KVM devices.

The XICS-on-XIVE KVM device now reports the exhaustion of VPs upon the
connection of the first VCPU. Check that in order to have a chance to
provide a hint to the user.
`
Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157478678846.67101.9660531022460517710.stgit@bahia.tlslab.ibm.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/xics_kvm.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index a1f1b7b0d3..8d6156578f 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -165,8 +165,15 @@ void icp_kvm_realize(DeviceState *dev, Error **errp)
 
     ret = kvm_vcpu_enable_cap(cs, KVM_CAP_IRQ_XICS, 0, kernel_xics_fd, vcpu_id);
     if (ret < 0) {
-        error_setg(errp, "Unable to connect CPU%ld to kernel XICS: %s", vcpu_id,
-                   strerror(errno));
+        Error *local_err = NULL;
+
+        error_setg(&local_err, "Unable to connect CPU%ld to kernel XICS: %s",
+                   vcpu_id, strerror(errno));
+        if (errno == ENOSPC) {
+            error_append_hint(&local_err, "Try -smp maxcpus=N with N < %u\n",
+                              MACHINE(qdev_get_machine())->smp.max_cpus);
+        }
+        error_propagate(errp, local_err);
         return;
     }
     enabled_icp = g_malloc(sizeof(*enabled_icp));
@@ -399,6 +406,16 @@ int xics_kvm_connect(SpaprInterruptController *intc, uint32_t nr_servers,
         goto fail;
     }
 
+    /* Tell KVM about the # of VCPUs we may have (POWER9 and newer only) */
+    if (kvm_device_check_attr(rc, KVM_DEV_XICS_GRP_CTRL,
+                              KVM_DEV_XICS_NR_SERVERS)) {
+        if (kvm_device_access(rc, KVM_DEV_XICS_GRP_CTRL,
+                              KVM_DEV_XICS_NR_SERVERS, &nr_servers, true,
+                              &local_err)) {
+            goto fail;
+        }
+    }
+
     kernel_xics_fd = rc;
     kvm_kernel_irqchip = true;
     kvm_msi_via_irqfd_allowed = true;
-- 
2.23.0



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

* [PULL 42/88] spapr/xive: Configure number of servers in KVM
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (40 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 41/88] spapr/xics: Configure number of servers in KVM David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 43/88] ppc/pnv: Clarify how the TIMA is accessed on a multichip system David Gibson
                   ` (46 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The XIVE KVM devices now has an attribute to configure the number of
interrupt servers. This allows to greatly optimize the usage of the VP
space in the XIVE HW, and thus to start a lot more VMs.

Only set this attribute if available in order to support older POWER9
KVM.

The XIVE KVM device now reports the exhaustion of VPs upon the
connection of the first VCPU. Check that in order to have a chance
to provide a hint to the user.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157478679392.67101.7843580591407950866.stgit@bahia.tlslab.ibm.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/spapr_xive_kvm.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
index 46c7609bd8..32b2809210 100644
--- a/hw/intc/spapr_xive_kvm.c
+++ b/hw/intc/spapr_xive_kvm.c
@@ -152,7 +152,8 @@ void kvmppc_xive_cpu_synchronize_state(XiveTCTX *tctx, Error **errp)
 
 void kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp)
 {
-    SpaprXive *xive = SPAPR_MACHINE(qdev_get_machine())->xive;
+    MachineState *ms = MACHINE(qdev_get_machine());
+    SpaprXive *xive = SPAPR_MACHINE(ms)->xive;
     unsigned long vcpu_id;
     int ret;
 
@@ -171,8 +172,16 @@ void kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp)
     ret = kvm_vcpu_enable_cap(tctx->cs, KVM_CAP_PPC_IRQ_XIVE, 0, xive->fd,
                               vcpu_id, 0);
     if (ret < 0) {
-        error_setg(errp, "XIVE: unable to connect CPU%ld to KVM device: %s",
+        Error *local_err = NULL;
+
+        error_setg(&local_err,
+                   "XIVE: unable to connect CPU%ld to KVM device: %s",
                    vcpu_id, strerror(errno));
+        if (errno == ENOSPC) {
+            error_append_hint(&local_err, "Try -smp maxcpus=N with N < %u\n",
+                              ms->smp.max_cpus);
+        }
+        error_propagate(errp, local_err);
         return;
     }
 
@@ -758,6 +767,16 @@ int kvmppc_xive_connect(SpaprInterruptController *intc, uint32_t nr_servers,
         return -1;
     }
 
+    /* Tell KVM about the # of VCPUs we may have */
+    if (kvm_device_check_attr(xive->fd, KVM_DEV_XIVE_GRP_CTRL,
+                              KVM_DEV_XIVE_NR_SERVERS)) {
+        if (kvm_device_access(xive->fd, KVM_DEV_XIVE_GRP_CTRL,
+                              KVM_DEV_XIVE_NR_SERVERS, &nr_servers, true,
+                              &local_err)) {
+            goto fail;
+        }
+    }
+
     /*
      * 1. Source ESB pages - KVM mapping
      */
-- 
2.23.0



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

* [PULL 43/88] ppc/pnv: Clarify how the TIMA is accessed on a multichip system
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (41 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 42/88] spapr/xive: " David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 44/88] ppc/xive: Move the TIMA operations to the controller model David Gibson
                   ` (45 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

The TIMA region gives access to the thread interrupt context registers
of a CPU. It is mapped at the same address on all chips and can be
accessed by any CPU of the system. To identify the chip from which the
access is being done, the PowerBUS uses a 'chip' field in the
load/store messages. QEMU does not model these messages, instead, we
extract the chip id from the CPU PIR and do a lookup at the machine
level to fetch the targeted interrupt controller.

Introduce pnv_get_chip() and pnv_xive_tm_get_xive() helpers to clarify
this process in pnv_xive_get_tctx(). The latter will be removed in the
subsequent patches but the same principle will be kept.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191125065820.927-14-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/pnv_xive.c   | 40 +++++++++++++++++++++++-----------------
 hw/ppc/pnv.c         | 14 ++++++++++++++
 include/hw/ppc/pnv.h |  3 +++
 3 files changed, 40 insertions(+), 17 deletions(-)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 95e9de312c..db9d9c11a8 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -439,31 +439,37 @@ static int pnv_xive_match_nvt(XivePresenter *xptr, uint8_t format,
     return count;
 }
 
+/*
+ * The TIMA MMIO space is shared among the chips and to identify the
+ * chip from which the access is being done, we extract the chip id
+ * from the PIR.
+ */
+static PnvXive *pnv_xive_tm_get_xive(PowerPCCPU *cpu)
+{
+    int pir = ppc_cpu_pir(cpu);
+    PnvChip *chip;
+    PnvXive *xive;
+
+    chip = pnv_get_chip(PNV9_PIR2CHIP(pir));
+    assert(chip);
+    xive = &PNV9_CHIP(chip)->xive;
+
+    if (!pnv_xive_is_cpu_enabled(xive, cpu)) {
+        xive_error(xive, "IC: CPU %x is not enabled", pir);
+    }
+    return xive;
+}
+
 static XiveTCTX *pnv_xive_get_tctx(XiveRouter *xrtr, CPUState *cs)
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);
-    XiveTCTX *tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
-    PnvXive *xive = NULL;
-    CPUPPCState *env = &cpu->env;
-    int pir = env->spr_cb[SPR_PIR].default_value;
+    PnvXive *xive = pnv_xive_tm_get_xive(cpu);
 
-    /*
-     * Perform an extra check on the HW thread enablement.
-     *
-     * The TIMA is shared among the chips and to identify the chip
-     * from which the access is being done, we extract the chip id
-     * from the PIR.
-     */
-    xive = pnv_xive_get_ic((pir >> 8) & 0xf);
     if (!xive) {
         return NULL;
     }
 
-    if (!(xive->regs[PC_THREAD_EN_REG0 >> 3] & PPC_BIT(pir & 0x3f))) {
-        xive_error(PNV_XIVE(xrtr), "IC: CPU %x is not enabled", pir);
-    }
-
-    return tctx;
+    return XIVE_TCTX(pnv_cpu_state(cpu)->intc);
 }
 
 /*
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 5b8b07f6ae..fa656858b2 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1472,6 +1472,20 @@ static int pnv_match_nvt(XiveFabric *xfb, uint8_t format,
     return total_count;
 }
 
+PnvChip *pnv_get_chip(uint32_t chip_id)
+{
+    PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
+    int i;
+
+    for (i = 0; i < pnv->num_chips; i++) {
+        PnvChip *chip = pnv->chips[i];
+        if (chip->chip_id == chip_id) {
+            return chip;
+        }
+    }
+    return NULL;
+}
+
 static void pnv_get_num_chips(Object *obj, Visitor *v, const char *name,
                               void *opaque, Error **errp)
 {
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index a58cfea3f2..3a7bc3c57e 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -103,6 +103,7 @@ typedef struct Pnv9Chip {
  * A SMT8 fused core is a pair of SMT4 cores.
  */
 #define PNV9_PIR2FUSEDCORE(pir) (((pir) >> 3) & 0xf)
+#define PNV9_PIR2CHIP(pir)      (((pir) >> 8) & 0x7f)
 
 typedef struct PnvChipClass {
     /*< private >*/
@@ -197,6 +198,8 @@ static inline bool pnv_is_power9(PnvMachineState *pnv)
     return pnv_chip_is_power9(pnv->chips[0]);
 }
 
+PnvChip *pnv_get_chip(uint32_t chip_id);
+
 #define PNV_FDT_ADDR          0x01000000
 #define PNV_TIMEBASE_FREQ     512000000ULL
 
-- 
2.23.0



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

* [PULL 44/88] ppc/xive: Move the TIMA operations to the controller model
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (42 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 43/88] ppc/pnv: Clarify how the TIMA is accessed on a multichip system David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 45/88] ppc/xive: Remove the get_tctx() XiveRouter handler David Gibson
                   ` (44 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

On the P9 Processor, the thread interrupt context registers of a CPU
can be accessed "directly" when by load/store from the CPU or
"indirectly" by the IC through an indirect TIMA page. This requires to
configure first the PC_TCTXT_INDIRx registers.

Today, we rely on the get_tctx() handler to deduce from the CPU PIR
the chip from which the TIMA access is being done. By handling the
TIMA memory ops under the interrupt controller model of each machine,
we can uniformize the TIMA direct and indirect ops under PowerNV. We
can also check that the CPUs have been enabled in the XIVE controller.

This prepares ground for the future versions of XIVE.

Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191125065820.927-15-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/pnv_xive.c    | 35 ++++++++++++++++++++++++++++++++++-
 hw/intc/spapr_xive.c  | 33 +++++++++++++++++++++++++++++++--
 hw/intc/xive.c        | 29 -----------------------------
 include/hw/ppc/xive.h |  1 -
 4 files changed, 65 insertions(+), 33 deletions(-)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index db9d9c11a8..c14a2d1869 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -1467,6 +1467,39 @@ static const MemoryRegionOps xive_tm_indirect_ops = {
     },
 };
 
+static void pnv_xive_tm_write(void *opaque, hwaddr offset,
+                              uint64_t value, unsigned size)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(current_cpu);
+    PnvXive *xive = pnv_xive_tm_get_xive(cpu);
+    XiveTCTX *tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
+
+    xive_tctx_tm_write(XIVE_PRESENTER(xive), tctx, offset, value, size);
+}
+
+static uint64_t pnv_xive_tm_read(void *opaque, hwaddr offset, unsigned size)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(current_cpu);
+    PnvXive *xive = pnv_xive_tm_get_xive(cpu);
+    XiveTCTX *tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
+
+    return xive_tctx_tm_read(XIVE_PRESENTER(xive), tctx, offset, size);
+}
+
+const MemoryRegionOps pnv_xive_tm_ops = {
+    .read = pnv_xive_tm_read,
+    .write = pnv_xive_tm_write,
+    .endianness = DEVICE_BIG_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 8,
+    },
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 8,
+    },
+};
+
 /*
  * Interrupt controller XSCOM region.
  */
@@ -1809,7 +1842,7 @@ static void pnv_xive_realize(DeviceState *dev, Error **errp)
                           "xive-pc", PNV9_XIVE_PC_SIZE);
 
     /* Thread Interrupt Management Area (Direct) */
-    memory_region_init_io(&xive->tm_mmio, OBJECT(xive), &xive_tm_ops,
+    memory_region_init_io(&xive->tm_mmio, OBJECT(xive), &pnv_xive_tm_ops,
                           xive, "xive-tima", PNV9_XIVE_TM_SIZE);
 
     qemu_register_reset(pnv_xive_reset, dev);
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 18a043a277..40891543e0 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -205,6 +205,35 @@ void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable)
     memory_region_set_enabled(&xive->end_source.esb_mmio, false);
 }
 
+static void spapr_xive_tm_write(void *opaque, hwaddr offset,
+                          uint64_t value, unsigned size)
+{
+    XiveTCTX *tctx = spapr_cpu_state(POWERPC_CPU(current_cpu))->tctx;
+
+    xive_tctx_tm_write(XIVE_PRESENTER(opaque), tctx, offset, value, size);
+}
+
+static uint64_t spapr_xive_tm_read(void *opaque, hwaddr offset, unsigned size)
+{
+    XiveTCTX *tctx = spapr_cpu_state(POWERPC_CPU(current_cpu))->tctx;
+
+    return xive_tctx_tm_read(XIVE_PRESENTER(opaque), tctx, offset, size);
+}
+
+const MemoryRegionOps spapr_xive_tm_ops = {
+    .read = spapr_xive_tm_read,
+    .write = spapr_xive_tm_write,
+    .endianness = DEVICE_BIG_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 8,
+    },
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 8,
+    },
+};
+
 static void spapr_xive_end_reset(XiveEND *end)
 {
     memset(end, 0, sizeof(*end));
@@ -314,8 +343,8 @@ static void spapr_xive_realize(DeviceState *dev, Error **errp)
     qemu_register_reset(spapr_xive_reset, dev);
 
     /* TIMA initialization */
-    memory_region_init_io(&xive->tm_mmio, OBJECT(xive), &xive_tm_ops, xive,
-                          "xive.tima", 4ull << TM_SHIFT);
+    memory_region_init_io(&xive->tm_mmio, OBJECT(xive), &spapr_xive_tm_ops,
+                          xive, "xive.tima", 4ull << TM_SHIFT);
     sysbus_init_mmio(SYS_BUS_DEVICE(xive), &xive->tm_mmio);
 
     /*
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 9e7e5ea57c..0ca7099f4e 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -523,35 +523,6 @@ uint64_t xive_tctx_tm_read(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
     return xive_tm_raw_read(tctx, offset, size);
 }
 
-static void xive_tm_write(void *opaque, hwaddr offset,
-                          uint64_t value, unsigned size)
-{
-    XiveTCTX *tctx = xive_router_get_tctx(XIVE_ROUTER(opaque), current_cpu);
-
-    xive_tctx_tm_write(XIVE_PRESENTER(opaque), tctx, offset, value, size);
-}
-
-static uint64_t xive_tm_read(void *opaque, hwaddr offset, unsigned size)
-{
-    XiveTCTX *tctx = xive_router_get_tctx(XIVE_ROUTER(opaque), current_cpu);
-
-    return xive_tctx_tm_read(XIVE_PRESENTER(opaque), tctx, offset, size);
-}
-
-const MemoryRegionOps xive_tm_ops = {
-    .read = xive_tm_read,
-    .write = xive_tm_write,
-    .endianness = DEVICE_BIG_ENDIAN,
-    .valid = {
-        .min_access_size = 1,
-        .max_access_size = 8,
-    },
-    .impl = {
-        .min_access_size = 1,
-        .max_access_size = 8,
-    },
-};
-
 static char *xive_tctx_ring_print(uint8_t *ring)
 {
     uint32_t w2 = xive_tctx_word2(ring);
diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index 97bbcddb38..dcf8974515 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -462,7 +462,6 @@ typedef struct XiveENDSource {
 #define XIVE_TM_OS_PAGE         0x2
 #define XIVE_TM_USER_PAGE       0x3
 
-extern const MemoryRegionOps xive_tm_ops;
 void xive_tctx_tm_write(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
                         uint64_t value, unsigned size);
 uint64_t xive_tctx_tm_read(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
-- 
2.23.0



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

* [PULL 45/88] ppc/xive: Remove the get_tctx() XiveRouter handler
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (43 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 44/88] ppc/xive: Move the TIMA operations to the controller model David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 46/88] ppc/xive: Introduce a xive_tctx_ipb_update() helper David Gibson
                   ` (43 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

It is now unused.

Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191125065820.927-16-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/pnv_xive.c    | 13 -------------
 hw/intc/spapr_xive.c  |  8 --------
 hw/intc/xive.c        |  7 -------
 include/hw/ppc/xive.h |  2 --
 4 files changed, 30 deletions(-)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index c14a2d1869..216ebc150a 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -460,18 +460,6 @@ static PnvXive *pnv_xive_tm_get_xive(PowerPCCPU *cpu)
     return xive;
 }
 
-static XiveTCTX *pnv_xive_get_tctx(XiveRouter *xrtr, CPUState *cs)
-{
-    PowerPCCPU *cpu = POWERPC_CPU(cs);
-    PnvXive *xive = pnv_xive_tm_get_xive(cpu);
-
-    if (!xive) {
-        return NULL;
-    }
-
-    return XIVE_TCTX(pnv_cpu_state(cpu)->intc);
-}
-
 /*
  * The internal sources (IPIs) of the interrupt controller have no
  * knowledge of the XIVE chip on which they reside. Encode the block
@@ -1900,7 +1888,6 @@ static void pnv_xive_class_init(ObjectClass *klass, void *data)
     xrc->write_end = pnv_xive_write_end;
     xrc->get_nvt = pnv_xive_get_nvt;
     xrc->write_nvt = pnv_xive_write_nvt;
-    xrc->get_tctx = pnv_xive_get_tctx;
 
     xnc->notify = pnv_xive_notify;
     xpc->match_nvt  = pnv_xive_match_nvt;
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 40891543e0..b785066da5 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -427,13 +427,6 @@ static int spapr_xive_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk,
     g_assert_not_reached();
 }
 
-static XiveTCTX *spapr_xive_get_tctx(XiveRouter *xrtr, CPUState *cs)
-{
-    PowerPCCPU *cpu = POWERPC_CPU(cs);
-
-    return spapr_cpu_state(cpu)->tctx;
-}
-
 static int spapr_xive_match_nvt(XivePresenter *xptr, uint8_t format,
                                 uint8_t nvt_blk, uint32_t nvt_idx,
                                 bool cam_ignore, uint8_t priority,
@@ -773,7 +766,6 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
     xrc->write_end = spapr_xive_write_end;
     xrc->get_nvt = spapr_xive_get_nvt;
     xrc->write_nvt = spapr_xive_write_nvt;
-    xrc->get_tctx = spapr_xive_get_tctx;
 
     sicc->activate = spapr_xive_activate;
     sicc->deactivate = spapr_xive_deactivate;
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 0ca7099f4e..4bff3abdc3 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1317,13 +1317,6 @@ int xive_router_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
    return xrc->write_nvt(xrtr, nvt_blk, nvt_idx, nvt, word_number);
 }
 
-XiveTCTX *xive_router_get_tctx(XiveRouter *xrtr, CPUState *cs)
-{
-    XiveRouterClass *xrc = XIVE_ROUTER_GET_CLASS(xrtr);
-
-    return xrc->get_tctx(xrtr, cs);
-}
-
 /*
  * Encode the HW CAM line in the block group mode format :
  *
diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index dcf8974515..24315480e7 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -351,7 +351,6 @@ typedef struct XiveRouterClass {
                    XiveNVT *nvt);
     int (*write_nvt)(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
                      XiveNVT *nvt, uint8_t word_number);
-    XiveTCTX *(*get_tctx)(XiveRouter *xrtr, CPUState *cs);
 } XiveRouterClass;
 
 int xive_router_get_eas(XiveRouter *xrtr, uint8_t eas_blk, uint32_t eas_idx,
@@ -364,7 +363,6 @@ int xive_router_get_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
                         XiveNVT *nvt);
 int xive_router_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
                           XiveNVT *nvt, uint8_t word_number);
-XiveTCTX *xive_router_get_tctx(XiveRouter *xrtr, CPUState *cs);
 void xive_router_notify(XiveNotifier *xn, uint32_t lisn);
 
 /*
-- 
2.23.0



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

* [PULL 46/88] ppc/xive: Introduce a xive_tctx_ipb_update() helper
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (44 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 45/88] ppc/xive: Remove the get_tctx() XiveRouter handler David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 47/88] ppc/xive: Synthesize interrupt from the saved IPB in the NVT David Gibson
                   ` (42 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

We will use it to resend missed interrupts when a vCPU context is
pushed on a HW thread.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191125065820.927-17-clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/xive.c        | 21 +++++++++++----------
 include/hw/ppc/xive.h |  1 +
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 4bff3abdc3..7047e45dac 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -47,12 +47,6 @@ static uint8_t ipb_to_pipr(uint8_t ibp)
     return ibp ? clz32((uint32_t)ibp << 24) : 0xff;
 }
 
-static void ipb_update(uint8_t *regs, uint8_t priority)
-{
-    regs[TM_IPB] |= priority_to_ipb(priority);
-    regs[TM_PIPR] = ipb_to_pipr(regs[TM_IPB]);
-}
-
 static uint8_t exception_mask(uint8_t ring)
 {
     switch (ring) {
@@ -135,6 +129,15 @@ static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t ring, uint8_t cppr)
     xive_tctx_notify(tctx, ring);
 }
 
+void xive_tctx_ipb_update(XiveTCTX *tctx, uint8_t ring, uint8_t ipb)
+{
+    uint8_t *regs = &tctx->regs[ring];
+
+    regs[TM_IPB] |= ipb;
+    regs[TM_PIPR] = ipb_to_pipr(regs[TM_IPB]);
+    xive_tctx_notify(tctx, ring);
+}
+
 static inline uint32_t xive_tctx_word2(uint8_t *ring)
 {
     return *((uint32_t *) &ring[TM_WORD2]);
@@ -336,8 +339,7 @@ static void xive_tm_set_os_cppr(XivePresenter *xptr, XiveTCTX *tctx,
 static void xive_tm_set_os_pending(XivePresenter *xptr, XiveTCTX *tctx,
                                    hwaddr offset, uint64_t value, unsigned size)
 {
-    ipb_update(&tctx->regs[TM_QW1_OS], value & 0xff);
-    xive_tctx_notify(tctx, TM_QW1_OS);
+    xive_tctx_ipb_update(tctx, TM_QW1_OS, priority_to_ipb(value & 0xff));
 }
 
 static void xive_os_cam_decode(uint32_t cam, uint8_t *nvt_blk,
@@ -1429,8 +1431,7 @@ static bool xive_presenter_notify(uint8_t format,
 
     /* handle CPU exception delivery */
     if (count) {
-        ipb_update(&match.tctx->regs[match.ring], priority);
-        xive_tctx_notify(match.tctx, match.ring);
+        xive_tctx_ipb_update(match.tctx, match.ring, priority_to_ipb(priority));
     }
 
     return !!count;
diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index 24315480e7..9c0bf2c301 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -469,6 +469,7 @@ void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon);
 Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp);
 void xive_tctx_reset(XiveTCTX *tctx);
 void xive_tctx_destroy(XiveTCTX *tctx);
+void xive_tctx_ipb_update(XiveTCTX *tctx, uint8_t ring, uint8_t ipb);
 
 /*
  * KVM XIVE device helpers
-- 
2.23.0



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

* [PULL 47/88] ppc/xive: Synthesize interrupt from the saved IPB in the NVT
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (45 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 46/88] ppc/xive: Introduce a xive_tctx_ipb_update() helper David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 48/88] ppc/pnv: Introduce a pnv_xive_block_id() helper David Gibson
                   ` (41 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

When a vCPU is dispatched on a HW thread, its context is pushed in the
thread registers and it is activated by setting the VO bit in the CAM
line word2. The HW grabs the associated NVT, pulls the IPB bits and
merges them with the IPB of the new context. If interrupts were missed
while the vCPU was not dispatched, these are synthesized in this
sequence.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191125065820.927-18-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/xive.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 7047e45dac..e022bb7afd 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -393,6 +393,57 @@ static uint64_t xive_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
     return qw1w2;
 }
 
+static void xive_tctx_need_resend(XiveRouter *xrtr, XiveTCTX *tctx,
+                                  uint8_t nvt_blk, uint32_t nvt_idx)
+{
+    XiveNVT nvt;
+    uint8_t ipb;
+
+    /*
+     * Grab the associated NVT to pull the pending bits, and merge
+     * them with the IPB of the thread interrupt context registers
+     */
+    if (xive_router_get_nvt(xrtr, nvt_blk, nvt_idx, &nvt)) {
+        qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid NVT %x/%x\n",
+                          nvt_blk, nvt_idx);
+        return;
+    }
+
+    ipb = xive_get_field32(NVT_W4_IPB, nvt.w4);
+
+    if (ipb) {
+        /* Reset the NVT value */
+        nvt.w4 = xive_set_field32(NVT_W4_IPB, nvt.w4, 0);
+        xive_router_write_nvt(xrtr, nvt_blk, nvt_idx, &nvt, 4);
+
+        /* Merge in current context */
+        xive_tctx_ipb_update(tctx, TM_QW1_OS, ipb);
+    }
+}
+
+/*
+ * Updating the OS CAM line can trigger a resend of interrupt
+ */
+static void xive_tm_push_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
+                                hwaddr offset, uint64_t value, unsigned size)
+{
+    uint32_t cam = value;
+    uint32_t qw1w2 = cpu_to_be32(cam);
+    uint8_t nvt_blk;
+    uint32_t nvt_idx;
+    bool vo;
+
+    xive_os_cam_decode(cam, &nvt_blk, &nvt_idx, &vo);
+
+    /* First update the registers */
+    xive_tctx_set_os_cam(tctx, qw1w2);
+
+    /* Check the interrupt pending bits */
+    if (vo) {
+        xive_tctx_need_resend(XIVE_ROUTER(xptr), tctx, nvt_blk, nvt_idx);
+    }
+}
+
 /*
  * Define a mapping of "special" operations depending on the TIMA page
  * offset and the size of the operation.
@@ -414,6 +465,7 @@ static const XiveTmOp xive_tm_operations[] = {
      * effects
      */
     { XIVE_TM_OS_PAGE, TM_QW1_OS + TM_CPPR,   1, xive_tm_set_os_cppr, NULL },
+    { XIVE_TM_HV_PAGE, TM_QW1_OS + TM_WORD2,     4, xive_tm_push_os_ctx, NULL },
     { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_CPPR, 1, xive_tm_set_hv_cppr, NULL },
     { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, xive_tm_vt_push, NULL },
     { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, NULL, xive_tm_vt_poll },
-- 
2.23.0



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

* [PULL 48/88] ppc/pnv: Introduce a pnv_xive_block_id() helper
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (46 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 47/88] ppc/xive: Synthesize interrupt from the saved IPB in the NVT David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 49/88] ppc/pnv: Extend XiveRouter with a get_block_id() handler David Gibson
                   ` (40 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

When PC_TCTXT_CHIPID_OVERRIDE is configured, the PC_TCTXT_CHIPID field
overrides the hardwired chip ID in the Powerbus operations and for CAM
compares. This is typically used in the one block-per-chip configuration
to associate a unique block id number to each IC of the system.

Simplify the model with a pnv_xive_block_id() helper and remove
'tctx_chipid' which becomes useless.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191125065820.927-19-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/pnv_xive.c        | 64 ++++++++++++++++++++-------------------
 include/hw/ppc/pnv_xive.h |  3 --
 2 files changed, 33 insertions(+), 34 deletions(-)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 216ebc150a..23e73641f2 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -85,13 +85,30 @@ static inline uint64_t SETFIELD(uint64_t mask, uint64_t word,
     return (word & ~mask) | ((value << ctz64(mask)) & mask);
 }
 
+/*
+ * When PC_TCTXT_CHIPID_OVERRIDE is configured, the PC_TCTXT_CHIPID
+ * field overrides the hardwired chip ID in the Powerbus operations
+ * and for CAM compares
+ */
+static uint8_t pnv_xive_block_id(PnvXive *xive)
+{
+    uint8_t blk = xive->chip->chip_id;
+    uint64_t cfg_val = xive->regs[PC_TCTXT_CFG >> 3];
+
+    if (cfg_val & PC_TCTXT_CHIPID_OVERRIDE) {
+        blk = GETFIELD(PC_TCTXT_CHIPID, cfg_val);
+    }
+
+    return blk;
+}
+
 /*
  * Remote access to controllers. HW uses MMIOs. For now, a simple scan
  * of the chips is good enough.
  *
  * TODO: Block scope support
  */
-static PnvXive *pnv_xive_get_ic(uint8_t blk)
+static PnvXive *pnv_xive_get_remote(uint8_t blk)
 {
     PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
     int i;
@@ -100,7 +117,7 @@ static PnvXive *pnv_xive_get_ic(uint8_t blk)
         Pnv9Chip *chip9 = PNV9_CHIP(pnv->chips[i]);
         PnvXive *xive = &chip9->xive;
 
-        if (xive->chip->chip_id == blk) {
+        if (pnv_xive_block_id(xive) == blk) {
             return xive;
         }
     }
@@ -216,7 +233,7 @@ static uint64_t pnv_xive_vst_addr(PnvXive *xive, uint32_t type, uint8_t blk,
 
     /* Remote VST access */
     if (GETFIELD(VSD_MODE, vsd) == VSD_MODE_FORWARD) {
-        xive = pnv_xive_get_ic(blk);
+        xive = pnv_xive_get_remote(blk);
 
         return xive ? pnv_xive_vst_addr(xive, type, blk, idx) : 0;
     }
@@ -364,7 +381,10 @@ static int pnv_xive_get_eas(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
 {
     PnvXive *xive = PNV_XIVE(xrtr);
 
-    if (pnv_xive_get_ic(blk) != xive) {
+    /*
+     * EAT lookups should be local to the IC
+     */
+    if (pnv_xive_block_id(xive) != blk) {
         xive_error(xive, "VST: EAS %x is remote !?", XIVE_EAS(blk, idx));
         return -1;
     }
@@ -470,7 +490,7 @@ static PnvXive *pnv_xive_tm_get_xive(PowerPCCPU *cpu)
 static void pnv_xive_notify(XiveNotifier *xn, uint32_t srcno)
 {
     PnvXive *xive = PNV_XIVE(xn);
-    uint8_t blk = xive->chip->chip_id;
+    uint8_t blk = pnv_xive_block_id(xive);
 
     xive_router_notify(xn, XIVE_EAS(blk, srcno));
 }
@@ -834,20 +854,7 @@ static void pnv_xive_ic_reg_write(void *opaque, hwaddr offset,
     case PC_TCTXT_CFG:
         /*
          * TODO: block group support
-         *
-         * PC_TCTXT_CFG_BLKGRP_EN
-         * PC_TCTXT_CFG_HARD_CHIPID_BLK :
-         *   Moves the chipid into block field for hardwired CAM compares.
-         *   Block offset value is adjusted to 0b0..01 & ThrdId
-         *
-         *   Will require changes in xive_presenter_tctx_match(). I am
-         *   not sure how to handle that yet.
          */
-
-        /* Overrides hardwired chip ID with the chip ID field */
-        if (val & PC_TCTXT_CHIPID_OVERRIDE) {
-            xive->tctx_chipid = GETFIELD(PC_TCTXT_CHIPID, val);
-        }
         break;
     case PC_TCTXT_TRACK:
         /*
@@ -1656,19 +1663,20 @@ static const MemoryRegionOps pnv_xive_pc_ops = {
 void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
 {
     XiveRouter *xrtr = XIVE_ROUTER(xive);
-    uint8_t blk = xive->chip->chip_id;
+    uint8_t blk = pnv_xive_block_id(xive);
+    uint8_t chip_id = xive->chip->chip_id;
     uint32_t srcno0 = XIVE_EAS(blk, 0);
     uint32_t nr_ipis = pnv_xive_nr_ipis(xive, blk);
     XiveEAS eas;
     XiveEND end;
     int i;
 
-    monitor_printf(mon, "XIVE[%x] Source %08x .. %08x\n", blk, srcno0,
-                   srcno0 + nr_ipis - 1);
+    monitor_printf(mon, "XIVE[%x] #%d Source %08x .. %08x\n", chip_id, blk,
+                   srcno0, srcno0 + nr_ipis - 1);
     xive_source_pic_print_info(&xive->ipi_source, srcno0, mon);
 
-    monitor_printf(mon, "XIVE[%x] EAT %08x .. %08x\n", blk, srcno0,
-                   srcno0 + nr_ipis - 1);
+    monitor_printf(mon, "XIVE[%x] #%d EAT %08x .. %08x\n", chip_id, blk,
+                   srcno0, srcno0 + nr_ipis - 1);
     for (i = 0; i < nr_ipis; i++) {
         if (xive_router_get_eas(xrtr, blk, i, &eas)) {
             break;
@@ -1678,13 +1686,13 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
         }
     }
 
-    monitor_printf(mon, "XIVE[%x] ENDT\n", blk);
+    monitor_printf(mon, "XIVE[%x] #%d ENDT\n", chip_id, blk);
     i = 0;
     while (!xive_router_get_end(xrtr, blk, i, &end)) {
         xive_end_pic_print_info(&end, i++, mon);
     }
 
-    monitor_printf(mon, "XIVE[%x] END Escalation EAT\n", blk);
+    monitor_printf(mon, "XIVE[%x] #%d END Escalation EAT\n", chip_id, blk);
     i = 0;
     while (!xive_router_get_end(xrtr, blk, i, &end)) {
         xive_end_eas_pic_print_info(&end, i++, mon);
@@ -1697,12 +1705,6 @@ static void pnv_xive_reset(void *dev)
     XiveSource *xsrc = &xive->ipi_source;
     XiveENDSource *end_xsrc = &xive->end_source;
 
-    /*
-     * Use the PnvChip id to identify the XIVE interrupt controller.
-     * It can be overriden by configuration at runtime.
-     */
-    xive->tctx_chipid = xive->chip->chip_id;
-
     /* Default page size (Should be changed at runtime to 64k) */
     xive->ic_shift = xive->vc_shift = xive->pc_shift = 12;
 
diff --git a/include/hw/ppc/pnv_xive.h b/include/hw/ppc/pnv_xive.h
index 4fdaa9247d..f4c7caad40 100644
--- a/include/hw/ppc/pnv_xive.h
+++ b/include/hw/ppc/pnv_xive.h
@@ -72,9 +72,6 @@ typedef struct PnvXive {
     /* Interrupt controller registers */
     uint64_t      regs[0x300];
 
-    /* Can be configured by FW */
-    uint32_t      tctx_chipid;
-
     /*
      * Virtual Structure Descriptor tables : EAT, SBE, ENDT, NVTT, IRQ
      * These are in a SRAM protected by ECC.
-- 
2.23.0



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

* [PULL 49/88] ppc/pnv: Extend XiveRouter with a get_block_id() handler
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (47 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 48/88] ppc/pnv: Introduce a pnv_xive_block_id() helper David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 50/88] ppc/pnv: Dump the XIVE NVT table David Gibson
                   ` (39 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

When doing CAM line compares, fetch the block id from the interrupt
controller which can have set the PC_TCTXT_CHIPID field.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191125065820.927-20-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/pnv_xive.c    |  6 ++++++
 hw/intc/spapr_xive.c  |  6 ++++++
 hw/intc/xive.c        | 21 ++++++++++++++++-----
 include/hw/ppc/xive.h |  2 +-
 4 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 23e73641f2..43c760efd1 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -459,6 +459,11 @@ static int pnv_xive_match_nvt(XivePresenter *xptr, uint8_t format,
     return count;
 }
 
+static uint8_t pnv_xive_get_block_id(XiveRouter *xrtr)
+{
+    return pnv_xive_block_id(PNV_XIVE(xrtr));
+}
+
 /*
  * The TIMA MMIO space is shared among the chips and to identify the
  * chip from which the access is being done, we extract the chip id
@@ -1890,6 +1895,7 @@ static void pnv_xive_class_init(ObjectClass *klass, void *data)
     xrc->write_end = pnv_xive_write_end;
     xrc->get_nvt = pnv_xive_get_nvt;
     xrc->write_nvt = pnv_xive_write_nvt;
+    xrc->get_block_id = pnv_xive_get_block_id;
 
     xnc->notify = pnv_xive_notify;
     xpc->match_nvt  = pnv_xive_match_nvt;
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index b785066da5..57305c56d7 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -473,6 +473,11 @@ static int spapr_xive_match_nvt(XivePresenter *xptr, uint8_t format,
     return count;
 }
 
+static uint8_t spapr_xive_get_block_id(XiveRouter *xrtr)
+{
+    return SPAPR_XIVE_BLOCK_ID;
+}
+
 static const VMStateDescription vmstate_spapr_xive_end = {
     .name = TYPE_SPAPR_XIVE "/end",
     .version_id = 1,
@@ -766,6 +771,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
     xrc->write_end = spapr_xive_write_end;
     xrc->get_nvt = spapr_xive_get_nvt;
     xrc->write_nvt = spapr_xive_write_nvt;
+    xrc->get_block_id = spapr_xive_get_block_id;
 
     sicc->activate = spapr_xive_activate;
     sicc->deactivate = spapr_xive_deactivate;
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index e022bb7afd..d4c6e21703 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1371,17 +1371,25 @@ int xive_router_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
    return xrc->write_nvt(xrtr, nvt_blk, nvt_idx, nvt, word_number);
 }
 
+static int xive_router_get_block_id(XiveRouter *xrtr)
+{
+   XiveRouterClass *xrc = XIVE_ROUTER_GET_CLASS(xrtr);
+
+   return xrc->get_block_id(xrtr);
+}
+
 /*
  * Encode the HW CAM line in the block group mode format :
  *
  *   chip << 19 | 0000000 0 0001 thread (7Bit)
  */
-static uint32_t xive_tctx_hw_cam_line(XiveTCTX *tctx)
+static uint32_t xive_tctx_hw_cam_line(XivePresenter *xptr, XiveTCTX *tctx)
 {
     CPUPPCState *env = &POWERPC_CPU(tctx->cs)->env;
     uint32_t pir = env->spr_cb[SPR_PIR].default_value;
+    uint8_t blk = xive_router_get_block_id(XIVE_ROUTER(xptr));
 
-    return xive_nvt_cam_line((pir >> 8) & 0xf, 1 << 7 | (pir & 0x7f));
+    return xive_nvt_cam_line(blk, 1 << 7 | (pir & 0x7f));
 }
 
 /*
@@ -1418,7 +1426,7 @@ int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
 
         /* PHYS ring */
         if ((be32_to_cpu(qw3w2) & TM_QW3W2_VT) &&
-            cam == xive_tctx_hw_cam_line(tctx)) {
+            cam == xive_tctx_hw_cam_line(xptr, tctx)) {
             return TM_QW3_HV_PHYS;
         }
 
@@ -1755,7 +1763,11 @@ static uint64_t xive_end_source_read(void *opaque, hwaddr addr, unsigned size)
     uint8_t pq;
     uint64_t ret = -1;
 
-    end_blk = xsrc->block_id;
+    /*
+     * The block id should be deduced from the load address on the END
+     * ESB MMIO but our model only supports a single block per XIVE chip.
+     */
+    end_blk = xive_router_get_block_id(xsrc->xrtr);
     end_idx = addr >> (xsrc->esb_shift + 1);
 
     if (xive_router_get_end(xsrc->xrtr, end_blk, end_idx, &end)) {
@@ -1855,7 +1867,6 @@ static void xive_end_source_realize(DeviceState *dev, Error **errp)
 }
 
 static Property xive_end_source_properties[] = {
-    DEFINE_PROP_UINT8("block-id", XiveENDSource, block_id, 0),
     DEFINE_PROP_UINT32("nr-ends", XiveENDSource, nr_ends, 0),
     DEFINE_PROP_UINT32("shift", XiveENDSource, esb_shift, XIVE_ESB_64K),
     DEFINE_PROP_LINK("xive", XiveENDSource, xrtr, TYPE_XIVE_ROUTER,
diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index 9c0bf2c301..1b7b89098f 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -351,6 +351,7 @@ typedef struct XiveRouterClass {
                    XiveNVT *nvt);
     int (*write_nvt)(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
                      XiveNVT *nvt, uint8_t word_number);
+    uint8_t (*get_block_id)(XiveRouter *xrtr);
 } XiveRouterClass;
 
 int xive_router_get_eas(XiveRouter *xrtr, uint8_t eas_blk, uint32_t eas_idx,
@@ -431,7 +432,6 @@ typedef struct XiveENDSource {
     DeviceState parent;
 
     uint32_t        nr_ends;
-    uint8_t         block_id;
 
     /* ESB memory region */
     uint32_t        esb_shift;
-- 
2.23.0



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

* [PULL 50/88] ppc/pnv: Dump the XIVE NVT table
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (48 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 49/88] ppc/pnv: Extend XiveRouter with a get_block_id() handler David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 51/88] ppc: well form kvmppc_hint_smt_possible error hint helper David Gibson
                   ` (38 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

This is useful to dump the saved contexts of the vCPUs : configuration
of the base END index of the vCPU and the Interrupt Pending Buffer
register, which is updated when an interrupt can not be presented.

When dumping the NVT table, we skip empty indirect pages which are not
necessarily allocated.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191125065820.927-21-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/pnv_xive.c         | 64 ++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/xive_regs.h |  3 ++
 2 files changed, 67 insertions(+)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 43c760efd1..a0a69b98a7 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -527,6 +527,44 @@ static uint32_t pnv_xive_nr_ipis(PnvXive *xive, uint8_t blk)
     return VSD_INDIRECT & vsd ? 0 : vst_tsize * SBE_PER_BYTE;
 }
 
+/*
+ * Compute the number of entries per indirect subpage.
+ */
+static uint64_t pnv_xive_vst_per_subpage(PnvXive *xive, uint32_t type)
+{
+    uint8_t blk = pnv_xive_block_id(xive);
+    uint64_t vsd = xive->vsds[type][blk];
+    const XiveVstInfo *info = &vst_infos[type];
+    uint64_t vsd_addr;
+    uint32_t page_shift;
+
+    /* For direct tables, fake a valid value */
+    if (!(VSD_INDIRECT & vsd)) {
+        return 1;
+    }
+
+    /* Get the page size of the indirect table. */
+    vsd_addr = vsd & VSD_ADDRESS_MASK;
+    vsd = ldq_be_dma(&address_space_memory, vsd_addr);
+
+    if (!(vsd & VSD_ADDRESS_MASK)) {
+#ifdef XIVE_DEBUG
+        xive_error(xive, "VST: invalid %s entry %x !?", info->name, idx);
+#endif
+        return 0;
+    }
+
+    page_shift = GETFIELD(VSD_TSIZE, vsd) + 12;
+
+    if (!pnv_xive_vst_page_size_allowed(page_shift)) {
+        xive_error(xive, "VST: invalid %s page shift %d", info->name,
+                   page_shift);
+        return 0;
+    }
+
+    return (1ull << page_shift) / info->size;
+}
+
 /*
  * EDT Table
  *
@@ -1665,6 +1703,21 @@ static const MemoryRegionOps pnv_xive_pc_ops = {
     },
 };
 
+static void xive_nvt_pic_print_info(XiveNVT *nvt, uint32_t nvt_idx,
+                                    Monitor *mon)
+{
+    uint8_t  eq_blk = xive_get_field32(NVT_W1_EQ_BLOCK, nvt->w1);
+    uint32_t eq_idx = xive_get_field32(NVT_W1_EQ_INDEX, nvt->w1);
+
+    if (!xive_nvt_is_valid(nvt)) {
+        return;
+    }
+
+    monitor_printf(mon, "  %08x end:%02x/%04x IPB:%02x\n", nvt_idx,
+                   eq_blk, eq_idx,
+                   xive_get_field32(NVT_W4_IPB, nvt->w4));
+}
+
 void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
 {
     XiveRouter *xrtr = XIVE_ROUTER(xive);
@@ -1674,7 +1727,9 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
     uint32_t nr_ipis = pnv_xive_nr_ipis(xive, blk);
     XiveEAS eas;
     XiveEND end;
+    XiveNVT nvt;
     int i;
+    uint64_t xive_nvt_per_subpage;
 
     monitor_printf(mon, "XIVE[%x] #%d Source %08x .. %08x\n", chip_id, blk,
                    srcno0, srcno0 + nr_ipis - 1);
@@ -1702,6 +1757,15 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon)
     while (!xive_router_get_end(xrtr, blk, i, &end)) {
         xive_end_eas_pic_print_info(&end, i++, mon);
     }
+
+    monitor_printf(mon, "XIVE[%x] #%d NVTT %08x .. %08x\n", chip_id, blk,
+                   0, XIVE_NVT_COUNT - 1);
+    xive_nvt_per_subpage = pnv_xive_vst_per_subpage(xive, VST_TSEL_VPDT);
+    for (i = 0; i < XIVE_NVT_COUNT; i += xive_nvt_per_subpage) {
+        while (!xive_router_get_nvt(xrtr, blk, i, &nvt)) {
+            xive_nvt_pic_print_info(&nvt, i++, mon);
+        }
+    }
 }
 
 static void pnv_xive_reset(void *dev)
diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index 1a5622f8de..09f243600c 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -252,6 +252,8 @@ typedef struct XiveNVT {
         uint32_t        w0;
 #define NVT_W0_VALID             PPC_BIT32(0)
         uint32_t        w1;
+#define NVT_W1_EQ_BLOCK          PPC_BITMASK32(0, 3)
+#define NVT_W1_EQ_INDEX          PPC_BITMASK32(4, 31)
         uint32_t        w2;
         uint32_t        w3;
         uint32_t        w4;
@@ -277,6 +279,7 @@ typedef struct XiveNVT {
  * field of the XIVE END
  */
 #define XIVE_NVT_SHIFT                19
+#define XIVE_NVT_COUNT                (1 << XIVE_NVT_SHIFT)
 
 static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
 {
-- 
2.23.0



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

* [PULL 51/88] ppc: well form kvmppc_hint_smt_possible error hint helper
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (49 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 50/88] ppc/pnv: Dump the XIVE NVT table David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  6:32   ` Markus Armbruster
  2019-12-17  4:42 ` [PULL 52/88] spapr: Don't trigger a CAS reboot for XICS/XIVE mode changeover David Gibson
                   ` (37 subsequent siblings)
  88 siblings, 1 reply; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, Vladimir Sementsov-Ogievskiy, aik, qemu-devel, groug,
	qemu-ppc, clg, Marc-André Lureau, David Gibson

From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>

Make kvmppc_hint_smt_possible hint append helper well formed:
rename errp to errp_in, as it is IN-parameter here (which is unusual
for errp), rename function to be kvmppc_error_append_*_hint.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20191127191434.20945-1-vsementsov@virtuozzo.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr.c       | 2 +-
 target/ppc/kvm.c     | 6 +++---
 target/ppc/kvm_ppc.h | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index d9c9a2bcee..e3c7d487b8 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2564,7 +2564,7 @@ static void spapr_set_vsmt_mode(SpaprMachineState *spapr, Error **errp)
                                       " requires the use of VSMT mode %d.\n",
                                       smp_threads, kvm_smt, spapr->vsmt);
                 }
-                kvmppc_hint_smt_possible(&local_err);
+                kvmppc_error_append_smt_possible_hint(&local_err);
                 goto out;
             }
         }
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index c77f9848ec..7406d18945 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -2076,7 +2076,7 @@ int kvmppc_set_smt_threads(int smt)
     return ret;
 }
 
-void kvmppc_hint_smt_possible(Error **errp)
+void kvmppc_error_append_smt_possible_hint(Error **errp_in)
 {
     int i;
     GString *g;
@@ -2091,10 +2091,10 @@ void kvmppc_hint_smt_possible(Error **errp)
             }
         }
         s = g_string_free(g, false);
-        error_append_hint(errp, "%s.\n", s);
+        error_append_hint(errp_in, "%s.\n", s);
         g_free(s);
     } else {
-        error_append_hint(errp,
+        error_append_hint(errp_in,
                           "This KVM seems to be too old to support VSMT.\n");
     }
 }
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
index 98bd7d5da6..47b08a4030 100644
--- a/target/ppc/kvm_ppc.h
+++ b/target/ppc/kvm_ppc.h
@@ -28,7 +28,7 @@ void kvmppc_set_papr(PowerPCCPU *cpu);
 int kvmppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr);
 void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy);
 int kvmppc_smt_threads(void);
-void kvmppc_hint_smt_possible(Error **errp);
+void kvmppc_error_append_smt_possible_hint(Error **errp_in);
 int kvmppc_set_smt_threads(int smt);
 int kvmppc_clear_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits);
 int kvmppc_or_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits);
@@ -164,7 +164,7 @@ static inline int kvmppc_smt_threads(void)
     return 1;
 }
 
-static inline void kvmppc_hint_smt_possible(Error **errp)
+static inline void kvmppc_error_append_smt_possible_hint(Error **errp_in)
 {
     return;
 }
-- 
2.23.0



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

* [PULL 52/88] spapr: Don't trigger a CAS reboot for XICS/XIVE mode changeover
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (50 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 51/88] ppc: well form kvmppc_hint_smt_possible error hint helper David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 53/88] spapr: Improve handling of fdt buffer size David Gibson
                   ` (36 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, Cedric Le Goater, qemu-ppc, clg,
	David Gibson

PAPR allows the interrupt controller used on a POWER9 machine (XICS or
XIVE) to be selected by the guest operating system, by using the
ibm,client-architecture-support (CAS) feature negotiation call.

Currently, if the guest selects an interrupt controller different from the
one selected at initial boot, this causes the system to be reset with the
new model and the boot starts again.  This means we run through the SLOF
boot process twice, as well as any other bootloader (e.g. grub) in use
before the OS calls CAS.  This can be confusing and/or inconvenient for
users.

Thanks to two fairly recent changes, we no longer need this reboot.  1) we
now completely regenerate the device tree when CAS is called (meaning we
don't need special case updates for all the device tree changes caused by
the interrupt controller mode change),  2) we now have explicit code paths
to activate and deactivate the different interrupt controllers, rather than
just implicitly calling those at machine reset time.

We can therefore eliminate the reboot for changing irq mode, simply by
putting a call to spapr_irq_update_active_intc() before we call
spapr_h_cas_compose_response() (which gives the updated device tree to
the guest firmware and OS).

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cedric Le Goater <clg@fr.ibm.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/ppc/spapr_hcall.c | 33 +++++++++++++--------------------
 1 file changed, 13 insertions(+), 20 deletions(-)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 140f05c1c6..05a7ca275b 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1767,21 +1767,10 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
     }
     spapr->cas_pre_isa3_guest = !spapr_ovec_test(ov1_guest, OV1_PPC_3_00);
     spapr_ovec_cleanup(ov1_guest);
-    if (!spapr->cas_reboot) {
-        /* If spapr_machine_reset() did not set up a HPT but one is necessary
-         * (because the guest isn't going to use radix) then set it up here. */
-        if ((spapr->patb_entry & PATE1_GR) && !guest_radix) {
-            /* legacy hash or new hash: */
-            spapr_setup_hpt_and_vrma(spapr);
-        }
-        spapr->cas_reboot =
-            (spapr_h_cas_compose_response(spapr, args[1], args[2],
-                                          ov5_updates) != 0);
-    }
 
     /*
-     * Ensure the guest asks for an interrupt mode we support; otherwise
-     * terminate the boot.
+     * Ensure the guest asks for an interrupt mode we support;
+     * otherwise terminate the boot.
      */
     if (guest_xive) {
         if (!spapr->irq->xive) {
@@ -1797,14 +1786,18 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
         }
     }
 
-    /*
-     * Generate a machine reset when we have an update of the
-     * interrupt mode. Only required when the machine supports both
-     * modes.
-     */
+    spapr_irq_update_active_intc(spapr);
+
     if (!spapr->cas_reboot) {
-        spapr->cas_reboot = spapr_ovec_test(ov5_updates, OV5_XIVE_EXPLOIT)
-            && spapr->irq->xics && spapr->irq->xive;
+        /* If spapr_machine_reset() did not set up a HPT but one is necessary
+         * (because the guest isn't going to use radix) then set it up here. */
+        if ((spapr->patb_entry & PATE1_GR) && !guest_radix) {
+            /* legacy hash or new hash: */
+            spapr_setup_hpt_and_vrma(spapr);
+        }
+        spapr->cas_reboot =
+            (spapr_h_cas_compose_response(spapr, args[1], args[2],
+                                          ov5_updates) != 0);
     }
 
     spapr_ovec_cleanup(ov5_updates);
-- 
2.23.0



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

* [PULL 53/88] spapr: Improve handling of fdt buffer size
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (51 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 52/88] spapr: Don't trigger a CAS reboot for XICS/XIVE mode changeover David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 54/88] spapr: Fold h_cas_compose_response() into h_client_architecture_support() David Gibson
                   ` (35 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, Cedric Le Goater, qemu-ppc, clg,
	David Gibson

Previously, spapr_build_fdt() constructed the device tree in a fixed
buffer of size FDT_MAX_SIZE.  This is a bit inflexible, but more
importantly it's awkward for the case where we use it during CAS.  In
that case the guest firmware supplies a buffer and we have to
awkwardly check that what we generated fits into it afterwards, after
doing a lot of size checks during spapr_build_fdt().

Simplify this by having spapr_build_fdt() take a 'space' parameter.
For the CAS case, we pass in the buffer size provided by SLOF, for the
machine init case, we continue to pass FDT_MAX_SIZE.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cedric Le Goater <clg@fr.ibm.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/ppc/spapr.c | 33 +++++++++++----------------------
 1 file changed, 11 insertions(+), 22 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index e3c7d487b8..df5bea1bd4 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -917,7 +917,8 @@ static bool spapr_hotplugged_dev_before_cas(void)
     return false;
 }
 
-static void *spapr_build_fdt(SpaprMachineState *spapr, bool reset);
+static void *spapr_build_fdt(SpaprMachineState *spapr, bool reset,
+                             size_t space);
 
 int spapr_h_cas_compose_response(SpaprMachineState *spapr,
                                  target_ulong addr, target_ulong size,
@@ -930,24 +931,17 @@ int spapr_h_cas_compose_response(SpaprMachineState *spapr,
         return 1;
     }
 
-    if (size < sizeof(hdr) || size > FW_MAX_SIZE) {
-        error_report("SLOF provided an unexpected CAS buffer size "
-                     TARGET_FMT_lu " (min: %zu, max: %u)",
-                     size, sizeof(hdr), FW_MAX_SIZE);
+    if (size < sizeof(hdr)) {
+        error_report("SLOF provided insufficient CAS buffer "
+                     TARGET_FMT_lu " (min: %zu)", size, sizeof(hdr));
         exit(EXIT_FAILURE);
     }
 
     size -= sizeof(hdr);
 
-    fdt = spapr_build_fdt(spapr, false);
+    fdt = spapr_build_fdt(spapr, false, size);
     _FDT((fdt_pack(fdt)));
 
-    if (fdt_totalsize(fdt) + sizeof(hdr) > size) {
-        g_free(fdt);
-        trace_spapr_cas_failed(size);
-        return -1;
-    }
-
     cpu_physical_memory_write(addr, &hdr, sizeof(hdr));
     cpu_physical_memory_write(addr + sizeof(hdr), fdt, fdt_totalsize(fdt));
     trace_spapr_cas_continue(fdt_totalsize(fdt) + sizeof(hdr));
@@ -1197,7 +1191,8 @@ static void spapr_dt_hypervisor(SpaprMachineState *spapr, void *fdt)
     }
 }
 
-static void *spapr_build_fdt(SpaprMachineState *spapr, bool reset)
+static void *spapr_build_fdt(SpaprMachineState *spapr, bool reset,
+                             size_t space)
 {
     MachineState *machine = MACHINE(spapr);
     MachineClass *mc = MACHINE_GET_CLASS(machine);
@@ -1207,8 +1202,8 @@ static void *spapr_build_fdt(SpaprMachineState *spapr, bool reset)
     SpaprPhbState *phb;
     char *buf;
 
-    fdt = g_malloc0(FDT_MAX_SIZE);
-    _FDT((fdt_create_empty_tree(fdt, FDT_MAX_SIZE)));
+    fdt = g_malloc0(space);
+    _FDT((fdt_create_empty_tree(fdt, space)));
 
     /* Root node */
     _FDT(fdt_setprop_string(fdt, 0, "device_type", "chrp"));
@@ -1723,19 +1718,13 @@ static void spapr_machine_reset(MachineState *machine)
      */
     fdt_addr = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FDT_MAX_SIZE;
 
-    fdt = spapr_build_fdt(spapr, true);
+    fdt = spapr_build_fdt(spapr, true, FDT_MAX_SIZE);
 
     rc = fdt_pack(fdt);
 
     /* Should only fail if we've built a corrupted tree */
     assert(rc == 0);
 
-    if (fdt_totalsize(fdt) > FDT_MAX_SIZE) {
-        error_report("FDT too big ! 0x%x bytes (max is 0x%x)",
-                     fdt_totalsize(fdt), FDT_MAX_SIZE);
-        exit(1);
-    }
-
     /* Load the fdt */
     qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt));
     cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt));
-- 
2.23.0



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

* [PULL 54/88] spapr: Fold h_cas_compose_response() into h_client_architecture_support()
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (52 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 53/88] spapr: Improve handling of fdt buffer size David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 55/88] spapr: Simplify ovec diff David Gibson
                   ` (34 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, Cedric Le Goater, qemu-ppc, clg,
	David Gibson

spapr_h_cas_compose_response() handles the last piece of the PAPR feature
negotiation process invoked via the ibm,client-architecture-support OF
call.  Its only caller is h_client_architecture_support() which handles
most of the rest of that process.

I believe it was placed in a separate file originally to handle some
fiddly dependencies between functions, but mostly it's just confusing
to have the CAS process split into two pieces like this.  Now that
compose response is simplified (by just generating the whole device
tree anew), it's cleaner to just fold it into
h_client_architecture_support().

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cedric Le Goater <clg@fr.ibm.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
---
 hw/ppc/spapr.c         | 61 +-----------------------------------------
 hw/ppc/spapr_hcall.c   | 55 ++++++++++++++++++++++++++++++++++---
 include/hw/ppc/spapr.h |  4 +--
 3 files changed, 54 insertions(+), 66 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index df5bea1bd4..3dedb41d48 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -76,7 +76,6 @@
 #include "hw/nmi.h"
 #include "hw/intc/intc.h"
 
-#include "qemu/cutils.h"
 #include "hw/ppc/spapr_cpu_core.h"
 #include "hw/mem/memory-device.h"
 #include "hw/ppc/spapr_tpm_proxy.h"
@@ -897,63 +896,6 @@ out:
     return ret;
 }
 
-static bool spapr_hotplugged_dev_before_cas(void)
-{
-    Object *drc_container, *obj;
-    ObjectProperty *prop;
-    ObjectPropertyIterator iter;
-
-    drc_container = container_get(object_get_root(), "/dr-connector");
-    object_property_iter_init(&iter, drc_container);
-    while ((prop = object_property_iter_next(&iter))) {
-        if (!strstart(prop->type, "link<", NULL)) {
-            continue;
-        }
-        obj = object_property_get_link(drc_container, prop->name, NULL);
-        if (spapr_drc_needed(obj)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-static void *spapr_build_fdt(SpaprMachineState *spapr, bool reset,
-                             size_t space);
-
-int spapr_h_cas_compose_response(SpaprMachineState *spapr,
-                                 target_ulong addr, target_ulong size,
-                                 SpaprOptionVector *ov5_updates)
-{
-    void *fdt;
-    SpaprDeviceTreeUpdateHeader hdr = { .version_id = 1 };
-
-    if (spapr_hotplugged_dev_before_cas()) {
-        return 1;
-    }
-
-    if (size < sizeof(hdr)) {
-        error_report("SLOF provided insufficient CAS buffer "
-                     TARGET_FMT_lu " (min: %zu)", size, sizeof(hdr));
-        exit(EXIT_FAILURE);
-    }
-
-    size -= sizeof(hdr);
-
-    fdt = spapr_build_fdt(spapr, false, size);
-    _FDT((fdt_pack(fdt)));
-
-    cpu_physical_memory_write(addr, &hdr, sizeof(hdr));
-    cpu_physical_memory_write(addr + sizeof(hdr), fdt, fdt_totalsize(fdt));
-    trace_spapr_cas_continue(fdt_totalsize(fdt) + sizeof(hdr));
-
-    g_free(spapr->fdt_blob);
-    spapr->fdt_size = fdt_totalsize(fdt);
-    spapr->fdt_initial_size = spapr->fdt_size;
-    spapr->fdt_blob = fdt;
-
-    return 0;
-}
-
 static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
 {
     MachineState *ms = MACHINE(spapr);
@@ -1191,8 +1133,7 @@ static void spapr_dt_hypervisor(SpaprMachineState *spapr, void *fdt)
     }
 }
 
-static void *spapr_build_fdt(SpaprMachineState *spapr, bool reset,
-                             size_t space)
+void *spapr_build_fdt(SpaprMachineState *spapr, bool reset, size_t space)
 {
     MachineState *machine = MACHINE(spapr);
     MachineClass *mc = MACHINE_GET_CLASS(machine);
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 05a7ca275b..0f19be794c 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1,4 +1,5 @@
 #include "qemu/osdep.h"
+#include "qemu/cutils.h"
 #include "qapi/error.h"
 #include "sysemu/hw_accel.h"
 #include "sysemu/runstate.h"
@@ -15,6 +16,7 @@
 #include "cpu-models.h"
 #include "trace.h"
 #include "kvm_ppc.h"
+#include "hw/ppc/fdt.h"
 #include "hw/ppc/spapr_ovec.h"
 #include "mmu-book3s-v3.h"
 #include "hw/mem/memory-device.h"
@@ -1638,6 +1640,26 @@ static uint32_t cas_check_pvr(SpaprMachineState *spapr, PowerPCCPU *cpu,
     return best_compat;
 }
 
+static bool spapr_hotplugged_dev_before_cas(void)
+{
+    Object *drc_container, *obj;
+    ObjectProperty *prop;
+    ObjectPropertyIterator iter;
+
+    drc_container = container_get(object_get_root(), "/dr-connector");
+    object_property_iter_init(&iter, drc_container);
+    while ((prop = object_property_iter_next(&iter))) {
+        if (!strstart(prop->type, "link<", NULL)) {
+            continue;
+        }
+        obj = object_property_get_link(drc_container, prop->name, NULL);
+        if (spapr_drc_needed(obj)) {
+            return true;
+        }
+    }
+    return false;
+}
+
 static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
                                                   SpaprMachineState *spapr,
                                                   target_ulong opcode,
@@ -1645,6 +1667,8 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
 {
     /* Working address in data buffer */
     target_ulong addr = ppc64_phys_to_real(args[0]);
+    target_ulong fdt_buf = args[1];
+    target_ulong fdt_bufsize = args[2];
     target_ulong ov_table;
     uint32_t cas_pvr;
     SpaprOptionVector *ov1_guest, *ov5_guest, *ov5_cas_old, *ov5_updates;
@@ -1788,16 +1812,41 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
 
     spapr_irq_update_active_intc(spapr);
 
+    if (spapr_hotplugged_dev_before_cas()) {
+        spapr->cas_reboot = true;
+    }
+
     if (!spapr->cas_reboot) {
+        void *fdt;
+        SpaprDeviceTreeUpdateHeader hdr = { .version_id = 1 };
+
         /* If spapr_machine_reset() did not set up a HPT but one is necessary
          * (because the guest isn't going to use radix) then set it up here. */
         if ((spapr->patb_entry & PATE1_GR) && !guest_radix) {
             /* legacy hash or new hash: */
             spapr_setup_hpt_and_vrma(spapr);
         }
-        spapr->cas_reboot =
-            (spapr_h_cas_compose_response(spapr, args[1], args[2],
-                                          ov5_updates) != 0);
+
+        if (fdt_bufsize < sizeof(hdr)) {
+            error_report("SLOF provided insufficient CAS buffer "
+                         TARGET_FMT_lu " (min: %zu)", fdt_bufsize, sizeof(hdr));
+            exit(EXIT_FAILURE);
+        }
+
+        fdt_bufsize -= sizeof(hdr);
+
+        fdt = spapr_build_fdt(spapr, false, fdt_bufsize);
+        _FDT((fdt_pack(fdt)));
+
+        cpu_physical_memory_write(fdt_buf, &hdr, sizeof(hdr));
+        cpu_physical_memory_write(fdt_buf + sizeof(hdr), fdt,
+                                  fdt_totalsize(fdt));
+        trace_spapr_cas_continue(fdt_totalsize(fdt) + sizeof(hdr));
+
+        g_free(spapr->fdt_blob);
+        spapr->fdt_size = fdt_totalsize(fdt);
+        spapr->fdt_initial_size = spapr->fdt_size;
+        spapr->fdt_blob = fdt;
     }
 
     spapr_ovec_cleanup(ov5_updates);
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index d5ab5ea7b2..61f005c6f6 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -766,11 +766,9 @@ struct SpaprEventLogEntry {
     QTAILQ_ENTRY(SpaprEventLogEntry) next;
 };
 
+void *spapr_build_fdt(SpaprMachineState *spapr, bool reset, size_t space);
 void spapr_events_init(SpaprMachineState *sm);
 void spapr_dt_events(SpaprMachineState *sm, void *fdt);
-int spapr_h_cas_compose_response(SpaprMachineState *sm,
-                                 target_ulong addr, target_ulong size,
-                                 SpaprOptionVector *ov5_updates);
 void close_htab_fd(SpaprMachineState *spapr);
 void spapr_setup_hpt_and_vrma(SpaprMachineState *spapr);
 void spapr_free_hpt(SpaprMachineState *spapr);
-- 
2.23.0



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

* [PULL 55/88] spapr: Simplify ovec diff
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (53 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 54/88] spapr: Fold h_cas_compose_response() into h_client_architecture_support() David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 56/88] ppc: Deassert the external interrupt pin in KVM on reset David Gibson
                   ` (33 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, Mike Roth, aik, qemu-devel, groug, Cedric Le Goater,
	qemu-ppc, clg, David Gibson

spapr_ovec_diff(ov, old, new) has somewhat complex semantics.  ov is set
to those bits which are in new but not old, and it returns as a boolean
whether or not there are any bits in old but not new.

It turns out that both callers only care about the second, not the first.
This is basically equivalent to a bitmap subset operation, which is easier
to understand and implement.  So replace spapr_ovec_diff() with
spapr_ovec_subset().

Cc: Mike Roth <mdroth@linux.vnet.ibm.com>

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cedric Le Goater <clg@fr.ibm.com>
---
 hw/ppc/spapr.c              | 14 +++-----------
 hw/ppc/spapr_hcall.c        |  8 ++------
 hw/ppc/spapr_ovec.c         | 30 ++++++++++--------------------
 include/hw/ppc/spapr_ovec.h |  4 +---
 4 files changed, 16 insertions(+), 40 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 3dedb41d48..f11422fc41 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1840,8 +1840,6 @@ static bool spapr_ov5_cas_needed(void *opaque)
 {
     SpaprMachineState *spapr = opaque;
     SpaprOptionVector *ov5_mask = spapr_ovec_new();
-    SpaprOptionVector *ov5_legacy = spapr_ovec_new();
-    SpaprOptionVector *ov5_removed = spapr_ovec_new();
     bool cas_needed;
 
     /* Prior to the introduction of SpaprOptionVector, we had two option
@@ -1873,17 +1871,11 @@ static bool spapr_ov5_cas_needed(void *opaque)
     spapr_ovec_set(ov5_mask, OV5_DRCONF_MEMORY);
     spapr_ovec_set(ov5_mask, OV5_DRMEM_V2);
 
-    /* spapr_ovec_diff returns true if bits were removed. we avoid using
-     * the mask itself since in the future it's possible "legacy" bits may be
-     * removed via machine options, which could generate a false positive
-     * that breaks migration.
-     */
-    spapr_ovec_intersect(ov5_legacy, spapr->ov5, ov5_mask);
-    cas_needed = spapr_ovec_diff(ov5_removed, spapr->ov5, ov5_legacy);
+    /* We need extra information if we have any bits outside the mask
+     * defined above */
+    cas_needed = !spapr_ovec_subset(spapr->ov5, ov5_mask);
 
     spapr_ovec_cleanup(ov5_mask);
-    spapr_ovec_cleanup(ov5_legacy);
-    spapr_ovec_cleanup(ov5_removed);
 
     return cas_needed;
 }
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 0f19be794c..f1799b1b70 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1671,7 +1671,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
     target_ulong fdt_bufsize = args[2];
     target_ulong ov_table;
     uint32_t cas_pvr;
-    SpaprOptionVector *ov1_guest, *ov5_guest, *ov5_cas_old, *ov5_updates;
+    SpaprOptionVector *ov1_guest, *ov5_guest, *ov5_cas_old;
     bool guest_radix;
     Error *local_err = NULL;
     bool raw_mode_supported = false;
@@ -1770,9 +1770,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
     /* capabilities that have been added since CAS-generated guest reset.
      * if capabilities have since been removed, generate another reset
      */
-    ov5_updates = spapr_ovec_new();
-    spapr->cas_reboot = spapr_ovec_diff(ov5_updates,
-                                        ov5_cas_old, spapr->ov5_cas);
+    spapr->cas_reboot = !spapr_ovec_subset(ov5_cas_old, spapr->ov5_cas);
     spapr_ovec_cleanup(ov5_cas_old);
     /* Now that processing is finished, set the radix/hash bit for the
      * guest if it requested a valid mode; otherwise terminate the boot. */
@@ -1849,8 +1847,6 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
         spapr->fdt_blob = fdt;
     }
 
-    spapr_ovec_cleanup(ov5_updates);
-
     if (spapr->cas_reboot) {
         qemu_system_reset_request(SHUTDOWN_CAUSE_SUBSYSTEM_RESET);
     }
diff --git a/hw/ppc/spapr_ovec.c b/hw/ppc/spapr_ovec.c
index 811fadf143..0ff6d1aeae 100644
--- a/hw/ppc/spapr_ovec.c
+++ b/hw/ppc/spapr_ovec.c
@@ -76,31 +76,21 @@ void spapr_ovec_intersect(SpaprOptionVector *ov,
     bitmap_and(ov->bitmap, ov1->bitmap, ov2->bitmap, OV_MAXBITS);
 }
 
-/* returns true if options bits were removed, false otherwise */
-bool spapr_ovec_diff(SpaprOptionVector *ov,
-                     SpaprOptionVector *ov_old,
-                     SpaprOptionVector *ov_new)
+/* returns true if ov1 has a subset of bits in ov2 */
+bool spapr_ovec_subset(SpaprOptionVector *ov1, SpaprOptionVector *ov2)
 {
-    unsigned long *change_mask = bitmap_new(OV_MAXBITS);
-    unsigned long *removed_bits = bitmap_new(OV_MAXBITS);
-    bool bits_were_removed = false;
+    unsigned long *tmp = bitmap_new(OV_MAXBITS);
+    bool result;
 
-    g_assert(ov);
-    g_assert(ov_old);
-    g_assert(ov_new);
-
-    bitmap_xor(change_mask, ov_old->bitmap, ov_new->bitmap, OV_MAXBITS);
-    bitmap_and(ov->bitmap, ov_new->bitmap, change_mask, OV_MAXBITS);
-    bitmap_and(removed_bits, ov_old->bitmap, change_mask, OV_MAXBITS);
+    g_assert(ov1);
+    g_assert(ov2);
 
-    if (!bitmap_empty(removed_bits, OV_MAXBITS)) {
-        bits_were_removed = true;
-    }
+    bitmap_andnot(tmp, ov1->bitmap, ov2->bitmap, OV_MAXBITS);
+    result = bitmap_empty(tmp, OV_MAXBITS);
 
-    g_free(change_mask);
-    g_free(removed_bits);
+    g_free(tmp);
 
-    return bits_were_removed;
+    return result;
 }
 
 void spapr_ovec_cleanup(SpaprOptionVector *ov)
diff --git a/include/hw/ppc/spapr_ovec.h b/include/hw/ppc/spapr_ovec.h
index 7891e9caac..2bed517a2b 100644
--- a/include/hw/ppc/spapr_ovec.h
+++ b/include/hw/ppc/spapr_ovec.h
@@ -66,9 +66,7 @@ SpaprOptionVector *spapr_ovec_clone(SpaprOptionVector *ov_orig);
 void spapr_ovec_intersect(SpaprOptionVector *ov,
                           SpaprOptionVector *ov1,
                           SpaprOptionVector *ov2);
-bool spapr_ovec_diff(SpaprOptionVector *ov,
-                     SpaprOptionVector *ov_old,
-                     SpaprOptionVector *ov_new);
+bool spapr_ovec_subset(SpaprOptionVector *ov1, SpaprOptionVector *ov2);
 void spapr_ovec_cleanup(SpaprOptionVector *ov);
 void spapr_ovec_set(SpaprOptionVector *ov, long bitnr);
 void spapr_ovec_clear(SpaprOptionVector *ov, long bitnr);
-- 
2.23.0



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

* [PULL 56/88] ppc: Deassert the external interrupt pin in KVM on reset
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (54 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 55/88] spapr: Simplify ovec diff David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 57/88] xics: Don't deassert outputs David Gibson
                   ` (32 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg,
	Satheesh Rajendran, David Gibson

From: Greg Kurz <groug@kaod.org>

When a CPU is reset, QEMU makes sure no interrupt is pending by clearing
CPUPPCstate::pending_interrupts in ppc_cpu_reset(). In the case of a
complete machine emulation, eg. a sPAPR machine, an external interrupt
request could still be pending in KVM though, eg. an IPI. It will be
eventually presented to the guest, which is supposed to acknowledge it at
the interrupt controller. If the interrupt controller is emulated in QEMU,
either XICS or XIVE, ppc_set_irq() won't deassert the external interrupt
pin in KVM since it isn't pending anymore for QEMU. When the vCPU re-enters
the guest, the interrupt request is still pending and the vCPU will try
again to acknowledge it. This causes an infinite loop and eventually hangs
the guest.

The code has been broken since the beginning. The issue wasn't hit before
because accel=kvm,kernel-irqchip=off is an awkward setup that never got
used until recently with the LC92x IBM systems (aka, Boston).

Add a ppc_irq_reset() function to do the necessary cleanup, ie. deassert
the IRQ pins of the CPU in QEMU and most importantly the external interrupt
pin for this vCPU in KVM.

Reported-by: Satheesh Rajendran <sathnaga@linux.vnet.ibm.com>
Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157548861740.3650476.16879693165328764758.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/ppc.c                    | 8 ++++++++
 include/hw/ppc/ppc.h            | 2 ++
 target/ppc/translate_init.inc.c | 1 +
 3 files changed, 11 insertions(+)

diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 8dd982fc1e..fab73f1b1f 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -1515,3 +1515,11 @@ PowerPCCPU *ppc_get_vcpu_by_pir(int pir)
 
     return NULL;
 }
+
+void ppc_irq_reset(PowerPCCPU *cpu)
+{
+    CPUPPCState *env = &cpu->env;
+
+    env->irq_input_state = 0;
+    kvmppc_set_interrupt(cpu, PPC_INTERRUPT_EXT, 0);
+}
diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h
index 585be6ab98..89e1dd065a 100644
--- a/include/hw/ppc/ppc.h
+++ b/include/hw/ppc/ppc.h
@@ -77,6 +77,7 @@ static inline void ppc970_irq_init(PowerPCCPU *cpu) {}
 static inline void ppcPOWER7_irq_init(PowerPCCPU *cpu) {}
 static inline void ppcPOWER9_irq_init(PowerPCCPU *cpu) {}
 static inline void ppce500_irq_init(PowerPCCPU *cpu) {}
+static inline void ppc_irq_reset(PowerPCCPU *cpu) {}
 #else
 void ppc40x_irq_init(PowerPCCPU *cpu);
 void ppce500_irq_init(PowerPCCPU *cpu);
@@ -84,6 +85,7 @@ void ppc6xx_irq_init(PowerPCCPU *cpu);
 void ppc970_irq_init(PowerPCCPU *cpu);
 void ppcPOWER7_irq_init(PowerPCCPU *cpu);
 void ppcPOWER9_irq_init(PowerPCCPU *cpu);
+void ppc_irq_reset(PowerPCCPU *cpu);
 #endif
 
 /* PPC machines for OpenBIOS */
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index ba726dec4d..64a838095c 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -10461,6 +10461,7 @@ static void ppc_cpu_reset(CPUState *s)
     env->pending_interrupts = 0;
     s->exception_index = POWERPC_EXCP_NONE;
     env->error_code = 0;
+    ppc_irq_reset(cpu);
 
     /* tininess for underflow is detected before rounding */
     set_float_detect_tininess(float_tininess_before_rounding,
-- 
2.23.0



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

* [PULL 57/88] xics: Don't deassert outputs
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (55 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 56/88] ppc: Deassert the external interrupt pin in KVM on reset David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 58/88] ppc: Don't use CPUPPCState::irq_input_state with modern Book3s CPU models David Gibson
                   ` (31 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The correct way to do this is to deassert the input pins on the CPU side.
This is the case since a previous change.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157548862298.3650476.1228720391270249433.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/xics.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 0b259a09c5..1952009e6d 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -289,9 +289,6 @@ void icp_reset(ICPState *icp)
     icp->pending_priority = 0xff;
     icp->mfrr = 0xff;
 
-    /* Make all outputs are deasserted */
-    qemu_set_irq(icp->output, 0);
-
     if (kvm_irqchip_in_kernel()) {
         Error *local_err = NULL;
 
-- 
2.23.0



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

* [PULL 58/88] ppc: Don't use CPUPPCState::irq_input_state with modern Book3s CPU models
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (56 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 57/88] xics: Don't deassert outputs David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 59/88] ppc: Ignore the CPU_INTERRUPT_EXITTB interrupt with KVM David Gibson
                   ` (30 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The power7_set_irq() and power9_set_irq() functions set this but it is
never used actually. Modern Book3s compatible CPUs are only supported
by the pnv and spapr machines. They have an interrupt controller, XICS
for POWER7/8 and XIVE for POWER9, whose models don't require to track
IRQ input states at the CPU level.

Drop these lines to avoid confusion.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157548862861.3650476.16622818876928044450.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/ppc.c     | 16 ++--------------
 target/ppc/cpu.h |  4 +++-
 2 files changed, 5 insertions(+), 15 deletions(-)

diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index fab73f1b1f..45834f98d1 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -275,10 +275,9 @@ void ppc970_irq_init(PowerPCCPU *cpu)
 static void power7_set_irq(void *opaque, int pin, int level)
 {
     PowerPCCPU *cpu = opaque;
-    CPUPPCState *env = &cpu->env;
 
     LOG_IRQ("%s: env %p pin %d level %d\n", __func__,
-                env, pin, level);
+            &cpu->env, pin, level);
 
     switch (pin) {
     case POWER7_INPUT_INT:
@@ -292,11 +291,6 @@ static void power7_set_irq(void *opaque, int pin, int level)
         LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin);
         return;
     }
-    if (level) {
-        env->irq_input_state |= 1 << pin;
-    } else {
-        env->irq_input_state &= ~(1 << pin);
-    }
 }
 
 void ppcPOWER7_irq_init(PowerPCCPU *cpu)
@@ -311,10 +305,9 @@ void ppcPOWER7_irq_init(PowerPCCPU *cpu)
 static void power9_set_irq(void *opaque, int pin, int level)
 {
     PowerPCCPU *cpu = opaque;
-    CPUPPCState *env = &cpu->env;
 
     LOG_IRQ("%s: env %p pin %d level %d\n", __func__,
-                env, pin, level);
+            &cpu->env, pin, level);
 
     switch (pin) {
     case POWER9_INPUT_INT:
@@ -334,11 +327,6 @@ static void power9_set_irq(void *opaque, int pin, int level)
         LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin);
         return;
     }
-    if (level) {
-        env->irq_input_state |= 1 << pin;
-    } else {
-        env->irq_input_state &= ~(1 << pin);
-    }
 }
 
 void ppcPOWER9_irq_init(PowerPCCPU *cpu)
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index e3e82327b7..f9528fc29d 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1090,7 +1090,9 @@ struct CPUPPCState {
 #if !defined(CONFIG_USER_ONLY)
     /*
      * This is the IRQ controller, which is implementation dependent
-     * and only relevant when emulating a complete machine.
+     * and only relevant when emulating a complete machine. Note that
+     * this isn't used by recent Book3s compatible CPUs (POWER7 and
+     * newer).
      */
     uint32_t irq_input_state;
     void **irq_inputs;
-- 
2.23.0



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

* [PULL 59/88] ppc: Ignore the CPU_INTERRUPT_EXITTB interrupt with KVM
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (57 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 58/88] ppc: Don't use CPUPPCState::irq_input_state with modern Book3s CPU models David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 60/88] ppc: Make PPCVirtualHypervisor an incomplete type David Gibson
                   ` (29 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

This only makes sense with an emulated CPU. Don't set the bit in
CPUState::interrupt_request when using KVM to avoid confusions.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157548863423.3650476.16424649423510075159.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/helper_regs.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/target/ppc/helper_regs.h b/target/ppc/helper_regs.h
index 85dfe7687f..d78c2af63e 100644
--- a/target/ppc/helper_regs.h
+++ b/target/ppc/helper_regs.h
@@ -22,6 +22,7 @@
 
 #include "qemu/main-loop.h"
 #include "exec/exec-all.h"
+#include "sysemu/kvm.h"
 
 /* Swap temporary saved registers with GPRs */
 static inline void hreg_swap_gpr_tgpr(CPUPPCState *env)
@@ -102,6 +103,10 @@ static inline void hreg_compute_hflags(CPUPPCState *env)
 
 static inline void cpu_interrupt_exittb(CPUState *cs)
 {
+    if (!kvm_enabled()) {
+        return;
+    }
+
     if (!qemu_mutex_iothread_locked()) {
         qemu_mutex_lock_iothread();
         cpu_interrupt(cs, CPU_INTERRUPT_EXITTB);
-- 
2.23.0



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

* [PULL 60/88] ppc: Make PPCVirtualHypervisor an incomplete type
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (58 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 59/88] ppc: Ignore the CPU_INTERRUPT_EXITTB interrupt with KVM David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 61/88] target/ppc: Add POWER10 DD1.0 model information David Gibson
                   ` (28 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

PPCVirtualHypervisor is an interface instance. It should never be
dereferenced. Drop the dummy type definition for extra safety, which
is the common practice with QOM interfaces.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157589808041.21182.18121655959115011353.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/cpu.h | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index f9528fc29d..60cf030ce6 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1222,10 +1222,6 @@ PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr);
 PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr);
 PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc);
 
-struct PPCVirtualHypervisor {
-    Object parent;
-};
-
 struct PPCVirtualHypervisorClass {
     InterfaceClass parent;
     void (*hypercall)(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu);
-- 
2.23.0



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

* [PULL 61/88] target/ppc: Add POWER10 DD1.0 model information
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (59 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 60/88] ppc: Make PPCVirtualHypervisor an incomplete type David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 62/88] ppc/pnv: Introduce a POWER10 PnvChip and a powernv10 machine David Gibson
                   ` (27 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

This includes in QEMU a new CPU model for the POWER10 processor with
the same capabilities of a POWER9 process. The model will be extended
when support is completed.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191205184454.10722-2-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/compat.c             |  21 +++-
 target/ppc/cpu-models.c         |   3 +
 target/ppc/cpu-models.h         |   3 +
 target/ppc/cpu.h                |   1 +
 target/ppc/translate_init.inc.c | 215 ++++++++++++++++++++++++++++++++
 5 files changed, 237 insertions(+), 6 deletions(-)

diff --git a/target/ppc/compat.c b/target/ppc/compat.c
index 7de4bf3122..f48df25944 100644
--- a/target/ppc/compat.c
+++ b/target/ppc/compat.c
@@ -51,36 +51,38 @@ static const CompatInfo compat_table[] = {
     { /* POWER6, ISA2.05 */
         .name = "power6",
         .pvr = CPU_POWERPC_LOGICAL_2_05,
-        .pcr = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 |
-               PCR_COMPAT_2_05 | PCR_TM_DIS | PCR_VSX_DIS,
+        .pcr = PCR_COMPAT_3_10 | PCR_COMPAT_3_00 | PCR_COMPAT_2_07 |
+               PCR_COMPAT_2_06 | PCR_COMPAT_2_05 | PCR_TM_DIS | PCR_VSX_DIS,
         .pcr_level = PCR_COMPAT_2_05,
         .max_vthreads = 2,
     },
     { /* POWER7, ISA2.06 */
         .name = "power7",
         .pvr = CPU_POWERPC_LOGICAL_2_06,
-        .pcr = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_TM_DIS,
+        .pcr = PCR_COMPAT_3_10 | PCR_COMPAT_3_00 | PCR_COMPAT_2_07 |
+               PCR_COMPAT_2_06 | PCR_TM_DIS,
         .pcr_level = PCR_COMPAT_2_06,
         .max_vthreads = 4,
     },
     {
         .name = "power7+",
         .pvr = CPU_POWERPC_LOGICAL_2_06_PLUS,
-        .pcr = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_TM_DIS,
+        .pcr = PCR_COMPAT_3_10 | PCR_COMPAT_3_00 | PCR_COMPAT_2_07 |
+               PCR_COMPAT_2_06 | PCR_TM_DIS,
         .pcr_level = PCR_COMPAT_2_06,
         .max_vthreads = 4,
     },
     { /* POWER8, ISA2.07 */
         .name = "power8",
         .pvr = CPU_POWERPC_LOGICAL_2_07,
-        .pcr = PCR_COMPAT_3_00 | PCR_COMPAT_2_07,
+        .pcr = PCR_COMPAT_3_10 | PCR_COMPAT_3_00 | PCR_COMPAT_2_07,
         .pcr_level = PCR_COMPAT_2_07,
         .max_vthreads = 8,
     },
     { /* POWER9, ISA3.00 */
         .name = "power9",
         .pvr = CPU_POWERPC_LOGICAL_3_00,
-        .pcr = PCR_COMPAT_3_00,
+        .pcr = PCR_COMPAT_3_10 | PCR_COMPAT_3_00,
         .pcr_level = PCR_COMPAT_3_00,
         /*
          * POWER9 hardware only supports 4 threads / core, but this
@@ -91,6 +93,13 @@ static const CompatInfo compat_table[] = {
          */
         .max_vthreads = 8,
     },
+    { /* POWER10, ISA3.10 */
+        .name = "power10",
+        .pvr = CPU_POWERPC_LOGICAL_3_10,
+        .pcr = PCR_COMPAT_3_10,
+        .pcr_level = PCR_COMPAT_3_10,
+        .max_vthreads = 8,
+    },
 };
 
 static const CompatInfo *compat_by_pvr(uint32_t pvr)
diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c
index 086548e9b9..4ad16863c0 100644
--- a/target/ppc/cpu-models.c
+++ b/target/ppc/cpu-models.c
@@ -774,6 +774,8 @@
                 "POWER9 v1.0")
     POWERPC_DEF("power9_v2.0",   CPU_POWERPC_POWER9_DD20,            POWER9,
                 "POWER9 v2.0")
+    POWERPC_DEF("power10_v1.0",  CPU_POWERPC_POWER10_DD1,            POWER10,
+                "POWER10 v1.0")
 #endif /* defined (TARGET_PPC64) */
 
 /***************************************************************************/
@@ -950,6 +952,7 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
     { "power8", "power8_v2.0" },
     { "power8nvl", "power8nvl_v1.0" },
     { "power9", "power9_v2.0" },
+    { "power10", "power10_v1.0" },
 #endif
 
     /* Generic PowerPCs */
diff --git a/target/ppc/cpu-models.h b/target/ppc/cpu-models.h
index 4fdb73034d..ce750b2d55 100644
--- a/target/ppc/cpu-models.h
+++ b/target/ppc/cpu-models.h
@@ -373,6 +373,8 @@ enum {
     CPU_POWERPC_POWER9_BASE        = 0x004E0000,
     CPU_POWERPC_POWER9_DD1         = 0x004E0100,
     CPU_POWERPC_POWER9_DD20        = 0x004E1200,
+    CPU_POWERPC_POWER10_BASE       = 0x00800000,
+    CPU_POWERPC_POWER10_DD1        = 0x00800100,
     CPU_POWERPC_970_v22            = 0x00390202,
     CPU_POWERPC_970FX_v10          = 0x00391100,
     CPU_POWERPC_970FX_v20          = 0x003C0200,
@@ -409,6 +411,7 @@ enum {
     CPU_POWERPC_LOGICAL_2_06_PLUS  = 0x0F100003,
     CPU_POWERPC_LOGICAL_2_07       = 0x0F000004,
     CPU_POWERPC_LOGICAL_3_00       = 0x0F000005,
+    CPU_POWERPC_LOGICAL_3_10       = 0x0F000006,
 };
 
 /* System version register (used on MPC 8xxx)                                */
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 60cf030ce6..fbec1b0cd5 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -2364,6 +2364,7 @@ enum {
     PCR_COMPAT_2_06     = PPC_BIT(61),
     PCR_COMPAT_2_07     = PPC_BIT(60),
     PCR_COMPAT_3_00     = PPC_BIT(59),
+    PCR_COMPAT_3_10     = PPC_BIT(58),
     PCR_VEC_DIS         = PPC_BIT(0), /* Vec. disable (bit NA since POWER8) */
     PCR_VSX_DIS         = PPC_BIT(1), /* VSX disable (bit NA since POWER8) */
     PCR_TM_DIS          = PPC_BIT(2), /* Trans. memory disable (POWER8) */
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 64a838095c..7364d36b07 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -3354,6 +3354,11 @@ static void init_excp_POWER9(CPUPPCState *env)
 #endif
 }
 
+static void init_excp_POWER10(CPUPPCState *env)
+{
+    init_excp_POWER9(env);
+}
+
 #endif
 
 /*****************************************************************************/
@@ -8996,6 +9001,216 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
     pcc->lpcr_pm = LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE | LPCR_OEE;
 }
 
+#ifdef CONFIG_SOFTMMU
+/*
+ * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
+ * Encoded as array of int_32s in the form:
+ *  0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
+ *  x -> AP encoding
+ *  y -> radix mode supported page size (encoded as a shift)
+ */
+static struct ppc_radix_page_info POWER10_radix_page_info = {
+    .count = 4,
+    .entries = {
+        0x0000000c, /*  4K - enc: 0x0 */
+        0xa0000010, /* 64K - enc: 0x5 */
+        0x20000015, /*  2M - enc: 0x1 */
+        0x4000001e  /*  1G - enc: 0x2 */
+    }
+};
+#endif /* CONFIG_SOFTMMU */
+
+static void init_proc_POWER10(CPUPPCState *env)
+{
+    /* Common Registers */
+    init_proc_book3s_common(env);
+    gen_spr_book3s_207_dbg(env);
+
+    /* POWER8 Specific Registers */
+    gen_spr_book3s_ids(env);
+    gen_spr_amr(env);
+    gen_spr_iamr(env);
+    gen_spr_book3s_purr(env);
+    gen_spr_power5p_common(env);
+    gen_spr_power5p_lpar(env);
+    gen_spr_power5p_ear(env);
+    gen_spr_power6_common(env);
+    gen_spr_power6_dbg(env);
+    gen_spr_power8_tce_address_control(env);
+    gen_spr_power8_ids(env);
+    gen_spr_power8_ebb(env);
+    gen_spr_power8_fscr(env);
+    gen_spr_power8_pmu_sup(env);
+    gen_spr_power8_pmu_user(env);
+    gen_spr_power8_tm(env);
+    gen_spr_power8_pspb(env);
+    gen_spr_vtb(env);
+    gen_spr_power8_ic(env);
+    gen_spr_power8_book4(env);
+    gen_spr_power8_rpr(env);
+    gen_spr_power9_mmu(env);
+
+    /* POWER9 Specific registers */
+    spr_register_kvm(env, SPR_TIDR, "TIDR", NULL, NULL,
+                     spr_read_generic, spr_write_generic,
+                     KVM_REG_PPC_TIDR, 0);
+
+    /* FIXME: Filter fields properly based on privilege level */
+    spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL,
+                        spr_read_generic, spr_write_generic,
+                        KVM_REG_PPC_PSSCR, 0);
+
+    /* env variables */
+    env->dcache_line_size = 128;
+    env->icache_line_size = 128;
+
+    /* Allocate hardware IRQ controller */
+    init_excp_POWER10(env);
+    ppcPOWER9_irq_init(env_archcpu(env));
+}
+
+static bool ppc_pvr_match_power10(PowerPCCPUClass *pcc, uint32_t pvr)
+{
+    if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER10_BASE) {
+        return true;
+    }
+    return false;
+}
+
+static bool cpu_has_work_POWER10(CPUState *cs)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+
+    if (cs->halted) {
+        uint64_t psscr = env->spr[SPR_PSSCR];
+
+        if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
+            return false;
+        }
+
+        /* If EC is clear, just return true on any pending interrupt */
+        if (!(psscr & PSSCR_EC)) {
+            return true;
+        }
+        /* External Exception */
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
+            (env->spr[SPR_LPCR] & LPCR_EEE)) {
+            bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
+            if (heic == 0 || !msr_hv || msr_pr) {
+                return true;
+            }
+        }
+        /* Decrementer Exception */
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
+            (env->spr[SPR_LPCR] & LPCR_DEE)) {
+            return true;
+        }
+        /* Machine Check or Hypervisor Maintenance Exception */
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK |
+            1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) {
+            return true;
+        }
+        /* Privileged Doorbell Exception */
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
+            (env->spr[SPR_LPCR] & LPCR_PDEE)) {
+            return true;
+        }
+        /* Hypervisor Doorbell Exception */
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
+            (env->spr[SPR_LPCR] & LPCR_HDEE)) {
+            return true;
+        }
+        /* Hypervisor virtualization exception */
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) &&
+            (env->spr[SPR_LPCR] & LPCR_HVEE)) {
+            return true;
+        }
+        if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
+            return true;
+        }
+        return false;
+    } else {
+        return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
+    }
+}
+
+POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+    CPUClass *cc = CPU_CLASS(oc);
+
+    dc->fw_name = "PowerPC,POWER10";
+    dc->desc = "POWER10";
+    dc->props = powerpc_servercpu_properties;
+    pcc->pvr_match = ppc_pvr_match_power10;
+    pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07 |
+                    PCR_COMPAT_3_00;
+    pcc->pcr_supported = PCR_COMPAT_3_10 | PCR_COMPAT_3_00 | PCR_COMPAT_2_07 |
+                         PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
+    pcc->init_proc = init_proc_POWER10;
+    pcc->check_pow = check_pow_nocheck;
+    cc->has_work = cpu_has_work_POWER10;
+    pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
+                       PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+                       PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+                       PPC_FLOAT_FRSQRTES |
+                       PPC_FLOAT_STFIWX |
+                       PPC_FLOAT_EXT |
+                       PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+                       PPC_MEM_SYNC | PPC_MEM_EIEIO |
+                       PPC_MEM_TLBSYNC |
+                       PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
+                       PPC_SEGMENT_64B | PPC_SLBI |
+                       PPC_POPCNTB | PPC_POPCNTWD |
+                       PPC_CILDST;
+    pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
+                        PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
+                        PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
+                        PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
+                        PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
+                        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) |
+                    (1ull << MSR_EE) |
+                    (1ull << MSR_PR) |
+                    (1ull << MSR_FP) |
+                    (1ull << MSR_ME) |
+                    (1ull << MSR_FE0) |
+                    (1ull << MSR_SE) |
+                    (1ull << MSR_DE) |
+                    (1ull << MSR_FE1) |
+                    (1ull << MSR_IR) |
+                    (1ull << MSR_DR) |
+                    (1ull << MSR_PMM) |
+                    (1ull << MSR_RI) |
+                    (1ull << MSR_LE);
+    pcc->mmu_model = POWERPC_MMU_3_00;
+#if defined(CONFIG_SOFTMMU)
+    pcc->handle_mmu_fault = ppc64_v3_handle_mmu_fault;
+    /* segment page size remain the same */
+    pcc->hash64_opts = &ppc_hash64_opts_POWER7;
+    pcc->radix_page_info = &POWER10_radix_page_info;
+    pcc->lrg_decr_bits = 56;
+#endif
+    pcc->excp_model = POWERPC_EXCP_POWER9;
+    pcc->bus_model = PPC_FLAGS_INPUT_POWER9;
+    pcc->bfd_mach = bfd_mach_ppc64;
+    pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
+                 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
+                 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
+                 POWERPC_FLAG_VSX | POWERPC_FLAG_TM;
+    pcc->l1_dcache_size = 0x8000;
+    pcc->l1_icache_size = 0x8000;
+    pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
+    pcc->lpcr_pm = LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE | LPCR_OEE;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp)
 {
-- 
2.23.0



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

* [PULL 62/88] ppc/pnv: Introduce a POWER10 PnvChip and a powernv10 machine
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (60 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 61/88] target/ppc: Add POWER10 DD1.0 model information David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 63/88] ppc/psi: cleanup definitions David Gibson
                   ` (26 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

This is an empty shell with the XSCOM bus and cores. The chip controllers
will come later.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191205184454.10722-3-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c               | 158 +++++++++++++++++++++++++++++++++++--
 hw/ppc/pnv_core.c          |  10 +++
 hw/ppc/pnv_xscom.c         |  23 ++++--
 include/hw/ppc/pnv.h       |  33 ++++++++
 include/hw/ppc/pnv_xscom.h |  19 +++++
 5 files changed, 232 insertions(+), 11 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index fa656858b2..d99cd72840 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -317,6 +317,23 @@ static void pnv_chip_power9_dt_populate(PnvChip *chip, void *fdt)
     pnv_dt_lpc(chip, fdt, 0);
 }
 
+static void pnv_chip_power10_dt_populate(PnvChip *chip, void *fdt)
+{
+    int i;
+
+    pnv_dt_xscom(chip, fdt, 0);
+
+    for (i = 0; i < chip->nr_cores; i++) {
+        PnvCore *pnv_core = chip->cores[i];
+
+        pnv_dt_core(chip, pnv_core, fdt);
+    }
+
+    if (chip->ram_size) {
+        pnv_dt_memory(fdt, chip->chip_id, chip->ram_start, chip->ram_size);
+    }
+}
+
 static void pnv_dt_rtc(ISADevice *d, void *fdt, int lpc_off)
 {
     uint32_t io_base = d->ioport_id;
@@ -467,6 +484,7 @@ static void *pnv_dt_create(MachineState *machine)
 {
     const char plat_compat8[] = "qemu,powernv8\0qemu,powernv\0ibm,powernv";
     const char plat_compat9[] = "qemu,powernv9\0ibm,powernv";
+    const char plat_compat10[] = "qemu,powernv10\0ibm,powernv";
     PnvMachineState *pnv = PNV_MACHINE(machine);
     void *fdt;
     char *buf;
@@ -484,7 +502,10 @@ static void *pnv_dt_create(MachineState *machine)
     _FDT((fdt_setprop_cell(fdt, 0, "#size-cells", 0x2)));
     _FDT((fdt_setprop_string(fdt, 0, "model",
                              "IBM PowerNV (emulated by qemu)")));
-    if (pnv_is_power9(pnv)) {
+    if (pnv_is_power10(pnv)) {
+        _FDT((fdt_setprop(fdt, 0, "compatible", plat_compat10,
+                          sizeof(plat_compat10))));
+    } else if (pnv_is_power9(pnv)) {
         _FDT((fdt_setprop(fdt, 0, "compatible", plat_compat9,
                           sizeof(plat_compat9))));
     } else {
@@ -528,8 +549,8 @@ 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)) {
+    /* Create an extra node for power management on Power9 and Power10 */
+    if (pnv_is_power9(pnv) || pnv_is_power10(pnv)) {
         pnv_dt_power_mgt(fdt);
     }
 
@@ -578,6 +599,12 @@ static ISABus *pnv_chip_power9_isa_create(PnvChip *chip, Error **errp)
     return pnv_lpc_isa_create(&chip9->lpc, false, errp);
 }
 
+static ISABus *pnv_chip_power10_isa_create(PnvChip *chip, Error **errp)
+{
+    error_setg(errp, "No ISA bus!");
+    return NULL;
+}
+
 static ISABus *pnv_isa_create(PnvChip *chip, Error **errp)
 {
     return PNV_CHIP_GET_CLASS(chip)->isa_create(chip, errp);
@@ -618,6 +645,13 @@ static void pnv_ipmi_bt_init(ISABus *bus, IPMIBmc *bmc, uint32_t irq)
     object_property_set_bool(obj, true, "realized", &error_fatal);
 }
 
+static void pnv_chip_power10_pic_print_info(PnvChip *chip, Monitor *mon)
+{
+    /*
+     * No interrupt controller yet
+     */;
+}
+
 static void pnv_init(MachineState *machine)
 {
     PnvMachineState *pnv = PNV_MACHINE(machine);
@@ -822,6 +856,11 @@ static uint32_t pnv_chip_core_pir_p9(PnvChip *chip, uint32_t core_id)
     return (chip->chip_id << 8) | (core_id << 2);
 }
 
+static uint32_t pnv_chip_core_pir_p10(PnvChip *chip, uint32_t core_id)
+{
+    return (chip->chip_id << 8) | (core_id << 2);
+}
+
 static void pnv_chip_power9_intc_create(PnvChip *chip, PowerPCCPU *cpu,
                                         Error **errp)
 {
@@ -859,6 +898,27 @@ static void pnv_chip_power9_intc_destroy(PnvChip *chip, PowerPCCPU *cpu)
     pnv_cpu->intc = NULL;
 }
 
+static void pnv_chip_power10_intc_create(PnvChip *chip, PowerPCCPU *cpu,
+                                        Error **errp)
+{
+    PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
+
+    /* Will be defined when the interrupt controller is */
+    pnv_cpu->intc = NULL;
+}
+
+static void pnv_chip_power10_intc_reset(PnvChip *chip, PowerPCCPU *cpu)
+{
+    ;
+}
+
+static void pnv_chip_power10_intc_destroy(PnvChip *chip, PowerPCCPU *cpu)
+{
+    PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
+
+    pnv_cpu->intc = NULL;
+}
+
 /*
  * Allowed core identifiers on a POWER8 Processor Chip :
  *
@@ -886,6 +946,9 @@ static void pnv_chip_power9_intc_destroy(PnvChip *chip, PowerPCCPU *cpu)
  */
 #define POWER9_CORE_MASK   (0xffffffffffffffull)
 
+
+#define POWER10_CORE_MASK  (0xffffffffffffffull)
+
 static void pnv_chip_power8_instance_init(Object *obj)
 {
     Pnv8Chip *chip8 = PNV8_CHIP(obj);
@@ -1246,6 +1309,56 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
                                     &k->parent_realize);
 }
 
+static void pnv_chip_power10_instance_init(Object *obj)
+{
+    /*
+     * No controllers yet
+     */
+    ;
+}
+
+static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
+{
+    PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
+    PnvChip *chip = PNV_CHIP(dev);
+    Error *local_err = NULL;
+
+    /* XSCOM bridge is first */
+    pnv_xscom_realize(chip, PNV10_XSCOM_SIZE, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(chip), 0, PNV10_XSCOM_BASE(chip));
+
+    pcc->parent_realize(dev, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+}
+
+static void pnv_chip_power10_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PnvChipClass *k = PNV_CHIP_CLASS(klass);
+
+    k->chip_type = PNV_CHIP_POWER10;
+    k->chip_cfam_id = 0x120da04900008000ull; /* P10 DD1.0 (with NX) */
+    k->cores_mask = POWER10_CORE_MASK;
+    k->core_pir = pnv_chip_core_pir_p10;
+    k->intc_create = pnv_chip_power10_intc_create;
+    k->intc_reset = pnv_chip_power10_intc_reset;
+    k->intc_destroy = pnv_chip_power10_intc_destroy;
+    k->isa_create = pnv_chip_power10_isa_create;
+    k->dt_populate = pnv_chip_power10_dt_populate;
+    k->pic_print_info = pnv_chip_power10_pic_print_info;
+    dc->desc = "PowerNV Chip POWER10";
+
+    device_class_set_parent_realize(dc, pnv_chip_power10_realize,
+                                    &k->parent_realize);
+}
+
 static void pnv_chip_core_sanitize(PnvChip *chip, Error **errp)
 {
     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
@@ -1327,10 +1440,12 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
                                  &error_fatal);
 
         /* Each core has an XSCOM MMIO region */
-        if (!pnv_chip_is_power9(chip)) {
-            xscom_core_base = PNV_XSCOM_EX_BASE(core_hwid);
-        } else {
+        if (pnv_chip_is_power10(chip)) {
+            xscom_core_base = PNV10_XSCOM_EC_BASE(core_hwid);
+        } else if (pnv_chip_is_power9(chip)) {
             xscom_core_base = PNV9_XSCOM_EC_BASE(core_hwid);
+        } else {
+            xscom_core_base = PNV_XSCOM_EX_BASE(core_hwid);
         }
 
         pnv_xscom_add_subregion(chip, xscom_core_base,
@@ -1558,6 +1673,14 @@ static void pnv_machine_power9_class_init(ObjectClass *oc, void *data)
     mc->alias = "powernv";
 }
 
+static void pnv_machine_power10_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+
+    mc->desc = "IBM PowerNV (Non-Virtualized) POWER10";
+    mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power10_v1.0");
+}
+
 static void pnv_machine_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
@@ -1595,7 +1718,19 @@ static void pnv_machine_class_init(ObjectClass *oc, void *data)
         .parent        = TYPE_PNV9_CHIP,          \
     }
 
+#define DEFINE_PNV10_CHIP_TYPE(type, class_initfn) \
+    {                                              \
+        .name          = type,                     \
+        .class_init    = class_initfn,             \
+        .parent        = TYPE_PNV10_CHIP,          \
+    }
+
 static const TypeInfo types[] = {
+    {
+        .name          = MACHINE_TYPE_NAME("powernv10"),
+        .parent        = TYPE_PNV_MACHINE,
+        .class_init    = pnv_machine_power10_class_init,
+    },
     {
         .name          = MACHINE_TYPE_NAME("powernv9"),
         .parent        = TYPE_PNV_MACHINE,
@@ -1635,6 +1770,17 @@ static const TypeInfo types[] = {
         .abstract      = true,
     },
 
+    /*
+     * P10 chip and variants
+     */
+    {
+        .name          = TYPE_PNV10_CHIP,
+        .parent        = TYPE_PNV_CHIP,
+        .instance_init = pnv_chip_power10_instance_init,
+        .instance_size = sizeof(Pnv10Chip),
+    },
+    DEFINE_PNV10_CHIP_TYPE(TYPE_PNV_CHIP_POWER10, pnv_chip_power10_class_init),
+
     /*
      * P9 chip and variants
      */
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 5ab75bde6c..2651044278 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -247,6 +247,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
     }
 
     snprintf(name, sizeof(name), "xscom-core.%d", cc->core_id);
+    /* TODO: check PNV_XSCOM_EX_SIZE for p10 */
     pnv_xscom_region_init(&pc->xscom_regs, OBJECT(dev), pcc->xscom_ops,
                           pc, name, PNV_XSCOM_EX_SIZE);
 
@@ -308,6 +309,14 @@ static void pnv_core_power9_class_init(ObjectClass *oc, void *data)
     pcc->xscom_ops = &pnv_core_power9_xscom_ops;
 }
 
+static void pnv_core_power10_class_init(ObjectClass *oc, void *data)
+{
+    PnvCoreClass *pcc = PNV_CORE_CLASS(oc);
+
+    /* TODO: Use the P9 XSCOMs for now on P10 */
+    pcc->xscom_ops = &pnv_core_power9_xscom_ops;
+}
+
 static void pnv_core_class_init(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
@@ -337,6 +346,7 @@ static const TypeInfo pnv_core_infos[] = {
     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_PNV_CORE_TYPE(power10, "power10_v1.0"),
 };
 
 DEFINE_TYPES(pnv_core_infos)
diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c
index f01d788a65..b3d3b6e350 100644
--- a/hw/ppc/pnv_xscom.c
+++ b/hw/ppc/pnv_xscom.c
@@ -69,10 +69,16 @@ static uint32_t pnv_xscom_pcba(PnvChip *chip, uint64_t addr)
 {
     addr &= (PNV_XSCOM_SIZE - 1);
 
-    if (pnv_chip_is_power9(chip)) {
-        return addr >> 3;
-    } else {
+    switch (PNV_CHIP_GET_CLASS(chip)->chip_type) {
+    case PNV_CHIP_POWER8E:
+    case PNV_CHIP_POWER8:
+    case PNV_CHIP_POWER8NVL:
         return ((addr >> 4) & ~0xfull) | ((addr >> 3) & 0xf);
+    case PNV_CHIP_POWER9:
+    case PNV_CHIP_POWER10:
+        return addr >> 3;
+    default:
+        g_assert_not_reached();
     }
 }
 
@@ -307,6 +313,7 @@ static int xscom_dt_child(Object *child, void *opaque)
 
 static const char compat_p8[] = "ibm,power8-xscom\0ibm,xscom";
 static const char compat_p9[] = "ibm,power9-xscom\0ibm,xscom";
+static const char compat_p10[] = "ibm,power10-xscom\0ibm,xscom";
 
 int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset)
 {
@@ -315,7 +322,10 @@ int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset)
     ForeachPopulateArgs args;
     char *name;
 
-    if (pnv_chip_is_power9(chip)) {
+    if (pnv_chip_is_power10(chip)) {
+        reg[0] = cpu_to_be64(PNV10_XSCOM_BASE(chip));
+        reg[1] = cpu_to_be64(PNV10_XSCOM_SIZE);
+    } else if (pnv_chip_is_power9(chip)) {
         reg[0] = cpu_to_be64(PNV9_XSCOM_BASE(chip));
         reg[1] = cpu_to_be64(PNV9_XSCOM_SIZE);
     } else {
@@ -332,7 +342,10 @@ int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset)
     _FDT((fdt_setprop_cell(fdt, xscom_offset, "#size-cells", 1)));
     _FDT((fdt_setprop(fdt, xscom_offset, "reg", reg, sizeof(reg))));
 
-    if (pnv_chip_is_power9(chip)) {
+    if (pnv_chip_is_power10(chip)) {
+        _FDT((fdt_setprop(fdt, xscom_offset, "compatible", compat_p10,
+                          sizeof(compat_p10))));
+    } else if (pnv_chip_is_power9(chip)) {
         _FDT((fdt_setprop(fdt, xscom_offset, "compatible", compat_p9,
                           sizeof(compat_p9))));
     } else {
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 3a7bc3c57e..bfa61edfba 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -43,6 +43,7 @@ typedef enum PnvChipType {
     PNV_CHIP_POWER8,      /* AKA Venice */
     PNV_CHIP_POWER8NVL,   /* AKA Naples */
     PNV_CHIP_POWER9,      /* AKA Nimbus */
+    PNV_CHIP_POWER10,     /* AKA TBD */
 } PnvChipType;
 
 typedef struct PnvChip {
@@ -105,6 +106,14 @@ typedef struct Pnv9Chip {
 #define PNV9_PIR2FUSEDCORE(pir) (((pir) >> 3) & 0xf)
 #define PNV9_PIR2CHIP(pir)      (((pir) >> 8) & 0x7f)
 
+#define TYPE_PNV10_CHIP "pnv10-chip"
+#define PNV10_CHIP(obj) OBJECT_CHECK(Pnv10Chip, (obj), TYPE_PNV10_CHIP)
+
+typedef struct Pnv10Chip {
+    /*< private >*/
+    PnvChip      parent_obj;
+} Pnv10Chip;
+
 typedef struct PnvChipClass {
     /*< private >*/
     SysBusDeviceClass parent_class;
@@ -144,6 +153,10 @@ typedef struct PnvChipClass {
 #define PNV_CHIP_POWER9(obj) \
     OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP_POWER9)
 
+#define TYPE_PNV_CHIP_POWER10 PNV_CHIP_TYPE_NAME("power10_v1.0")
+#define PNV_CHIP_POWER10(obj) \
+    OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP_POWER10)
+
 /*
  * This generates a HW chip id depending on an index, as found on a
  * two socket system with dual chip modules :
@@ -203,6 +216,16 @@ PnvChip *pnv_get_chip(uint32_t chip_id);
 #define PNV_FDT_ADDR          0x01000000
 #define PNV_TIMEBASE_FREQ     512000000ULL
 
+static inline bool pnv_chip_is_power10(const PnvChip *chip)
+{
+    return PNV_CHIP_GET_CLASS(chip)->chip_type == PNV_CHIP_POWER10;
+}
+
+static inline bool pnv_is_power10(PnvMachineState *pnv)
+{
+    return pnv_chip_is_power10(pnv->chips[0]);
+}
+
 /*
  * BMC helpers
  */
@@ -293,4 +316,14 @@ IPMIBmc *pnv_bmc_create(void);
 #define PNV9_HOMER_SIZE              0x0000000000300000ull
 #define PNV9_HOMER_BASE(chip)                                           \
     (0x203ffd800000ull + ((uint64_t)PNV_CHIP_INDEX(chip)) * PNV9_HOMER_SIZE)
+
+/*
+ * POWER10 MMIO base addresses - 16TB stride per chip
+ */
+#define PNV10_CHIP_BASE(chip, base)   \
+    ((base) + ((uint64_t) (chip)->chip_id << 44))
+
+#define PNV10_XSCOM_SIZE             0x0000000400000000ull
+#define PNV10_XSCOM_BASE(chip)       PNV10_CHIP_BASE(chip, 0x00603fc00000000ull)
+
 #endif /* PPC_PNV_H */
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index 67641ed278..790eb3d8f3 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -70,6 +70,9 @@ typedef struct PnvXScomInterfaceClass {
 #define PNV_XSCOM_OCC_BASE        0x0066000
 #define PNV_XSCOM_OCC_SIZE        0x6000
 
+/*
+ * Layout of the XSCOM PCB addresses (POWER 9)
+ */
 #define PNV9_XSCOM_EC_BASE(core) \
     ((uint64_t)(((core) & 0x1F) + 0x20) << 24)
 #define PNV9_XSCOM_EC_SIZE        0x100000
@@ -87,6 +90,22 @@ typedef struct PnvXScomInterfaceClass {
 #define PNV9_XSCOM_XIVE_BASE      0x5013000
 #define PNV9_XSCOM_XIVE_SIZE      0x300
 
+/*
+ * Layout of the XSCOM PCB addresses (POWER 10)
+ */
+#define PNV10_XSCOM_EQ_CHIPLET(core)  (0x20 + ((core) >> 2))
+#define PNV10_XSCOM_EQ(chiplet)       ((chiplet) << 24)
+#define PNV10_XSCOM_EC(proc)                    \
+    ((0x2 << 16) | ((1 << (3 - (proc))) << 12))
+
+#define PNV10_XSCOM_EQ_BASE(core)     \
+    ((uint64_t) PNV10_XSCOM_EQ(PNV10_XSCOM_EQ_CHIPLET(core)))
+#define PNV10_XSCOM_EQ_SIZE        0x100000
+
+#define PNV10_XSCOM_EC_BASE(core) \
+    ((uint64_t) PNV10_XSCOM_EQ_BASE(core) | PNV10_XSCOM_EC(core & 0x3))
+#define PNV10_XSCOM_EC_SIZE        0x100000
+
 extern void pnv_xscom_realize(PnvChip *chip, uint64_t size, Error **errp);
 extern int pnv_dt_xscom(PnvChip *chip, void *fdt, int offset);
 
-- 
2.23.0



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

* [PULL 63/88] ppc/psi: cleanup definitions
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (61 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 62/88] ppc/pnv: Introduce a POWER10 PnvChip and a powernv10 machine David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 64/88] ppc/pnv: add a PSI bridge model for POWER10 David Gibson
                   ` (25 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191205184454.10722-4-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv_psi.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
index 7e725aaf2b..e6c266ac4a 100644
--- a/hw/ppc/pnv_psi.c
+++ b/hw/ppc/pnv_psi.c
@@ -608,9 +608,12 @@ static const TypeInfo pnv_psi_power8_info = {
 #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_CI_64K             PPC_BIT(1)
+#define   PSIHB9_ESB_CI_ADDR_MASK       PPC_BITMASK(8, 47)
+#define   PSIHB9_ESB_CI_VALID           PPC_BIT(63)
 #define PSIHB9_ESB_NOTIF_ADDR           0x68
-#define   PSIHB9_ESB_NOTIF_VALID        1
+#define   PSIHB9_ESB_NOTIF_ADDR_MASK    PPC_BITMASK(8, 60)
+#define   PSIHB9_ESB_NOTIF_VALID        PPC_BIT(63)
 #define PSIHB9_IVT_OFFSET               0x70
 #define   PSIHB9_IVT_OFF_SHIFT          32
 
-- 
2.23.0



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

* [PULL 64/88] ppc/pnv: add a PSI bridge model for POWER10
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (62 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 63/88] ppc/psi: cleanup definitions David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:42 ` [PULL 65/88] ppc/pnv: add a LPC Controller " David Gibson
                   ` (24 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

The POWER10 PSIHB controller is very similar to the one on POWER9. We
should probably introduce a common PnvPsiXive object.

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

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191205184454.10722-5-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c               | 27 ++++++++++++++++++++-------
 hw/ppc/pnv_psi.c           | 25 ++++++++++++++++++++++++-
 include/hw/ppc/pnv.h       |  9 +++++++++
 include/hw/ppc/pnv_psi.h   |  2 ++
 include/hw/ppc/pnv_xscom.h |  3 +++
 5 files changed, 58 insertions(+), 8 deletions(-)

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



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

* [PULL 65/88] ppc/pnv: add a LPC Controller model for POWER10
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (63 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 64/88] ppc/pnv: add a PSI bridge model for POWER10 David Gibson
@ 2019-12-17  4:42 ` David Gibson
  2019-12-17  4:43 ` [PULL 66/88] target/ppc: Implement the VTB for HV access David Gibson
                   ` (23 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:42 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

Same a POWER9, only the MMIO window changes.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191205184454.10722-6-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c             | 25 ++++++++++++++++++++++---
 hw/ppc/pnv_lpc.c         | 30 ++++++++++++++++++++++--------
 include/hw/ppc/pnv.h     |  4 ++++
 include/hw/ppc/pnv_lpc.h |  6 +++++-
 4 files changed, 53 insertions(+), 12 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 09263ab747..67d0ad55b8 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -314,7 +314,7 @@ static void pnv_chip_power9_dt_populate(PnvChip *chip, void *fdt)
         pnv_dt_memory(fdt, chip->chip_id, chip->ram_start, chip->ram_size);
     }
 
-    pnv_dt_lpc(chip, fdt, 0);
+    pnv_dt_lpc(chip, fdt, 0, PNV9_LPCM_BASE(chip), PNV9_LPCM_SIZE);
 }
 
 static void pnv_chip_power10_dt_populate(PnvChip *chip, void *fdt)
@@ -332,6 +332,8 @@ static void pnv_chip_power10_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, PNV10_LPCM_BASE(chip), PNV10_LPCM_SIZE);
 }
 
 static void pnv_dt_rtc(ISADevice *d, void *fdt, int lpc_off)
@@ -601,8 +603,8 @@ static ISABus *pnv_chip_power9_isa_create(PnvChip *chip, Error **errp)
 
 static ISABus *pnv_chip_power10_isa_create(PnvChip *chip, Error **errp)
 {
-    error_setg(errp, "No ISA bus!");
-    return NULL;
+    Pnv10Chip *chip10 = PNV10_CHIP(chip);
+    return pnv_lpc_isa_create(&chip10->lpc, false, errp);
 }
 
 static ISABus *pnv_isa_create(PnvChip *chip, Error **errp)
@@ -1315,6 +1317,8 @@ static void pnv_chip_power10_instance_init(Object *obj)
 
     object_initialize_child(obj, "psi",  &chip10->psi, sizeof(chip10->psi),
                             TYPE_PNV10_PSI, &error_abort, NULL);
+    object_initialize_child(obj, "lpc",  &chip10->lpc, sizeof(chip10->lpc),
+                            TYPE_PNV10_LPC, &error_abort, NULL);
 }
 
 static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
@@ -1349,6 +1353,21 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
     }
     pnv_xscom_add_subregion(chip, PNV10_XSCOM_PSIHB_BASE,
                             &PNV_PSI(&chip10->psi)->xscom_regs);
+
+    /* LPC */
+    object_property_set_link(OBJECT(&chip10->lpc), OBJECT(&chip10->psi), "psi",
+                             &error_abort);
+    object_property_set_bool(OBJECT(&chip10->lpc), true, "realized",
+                             &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    memory_region_add_subregion(get_system_memory(), PNV10_LPCM_BASE(chip),
+                                &chip10->lpc.xscom_regs);
+
+    chip->dt_isa_nodename = g_strdup_printf("/lpcm-opb@%" PRIx64 "/lpc@0",
+                                            (uint64_t) PNV10_LPCM_BASE(chip));
 }
 
 static void pnv_chip_power10_class_init(ObjectClass *klass, void *data)
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index dd5374c838..18256d9ba3 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -122,26 +122,26 @@ static int pnv_lpc_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
 }
 
 /* POWER9 only */
-int pnv_dt_lpc(PnvChip *chip, void *fdt, int root_offset)
+int pnv_dt_lpc(PnvChip *chip, void *fdt, int root_offset, uint64_t lpcm_addr,
+               uint64_t lpcm_size)
 {
     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_size / 2),
+                               cpu_to_be32(lpcm_size / 2),
                                cpu_to_be32(lpcm_addr >> 32),
-                               cpu_to_be32(PNV9_LPCM_SIZE / 2),
-                               cpu_to_be32(PNV9_LPCM_SIZE / 2),
+                               cpu_to_be32(lpcm_size / 2),
+                               cpu_to_be32(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),
+                            cpu_to_be32(lpcm_size >> 32),
+                            cpu_to_be32((uint32_t)lpcm_size),
     };
     uint32_t lpc_ranges[12] = { 0, 0,
                                 cpu_to_be32(LPC_MEM_OPB_ADDR),
@@ -691,6 +691,19 @@ static const TypeInfo pnv_lpc_power9_info = {
     .class_init    = pnv_lpc_power9_class_init,
 };
 
+static void pnv_lpc_power10_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->desc = "PowerNV LPC Controller POWER10";
+}
+
+static const TypeInfo pnv_lpc_power10_info = {
+    .name          = TYPE_PNV10_LPC,
+    .parent        = TYPE_PNV9_LPC,
+    .class_init    = pnv_lpc_power10_class_init,
+};
+
 static void pnv_lpc_realize(DeviceState *dev, Error **errp)
 {
     PnvLpcController *lpc = PNV_LPC(dev);
@@ -764,6 +777,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_register_static(&pnv_lpc_power10_info);
 }
 
 type_init(pnv_lpc_register_types)
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 47b7370b27..56d1161515 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -115,6 +115,7 @@ typedef struct Pnv10Chip {
 
     /*< public >*/
     Pnv9Psi      psi;
+    PnvLpcController lpc;
 } Pnv10Chip;
 
 typedef struct PnvChipClass {
@@ -329,6 +330,9 @@ IPMIBmc *pnv_bmc_create(void);
 #define PNV10_XSCOM_SIZE             0x0000000400000000ull
 #define PNV10_XSCOM_BASE(chip)       PNV10_CHIP_BASE(chip, 0x00603fc00000000ull)
 
+#define PNV10_LPCM_SIZE             0x0000000100000000ull
+#define PNV10_LPCM_BASE(chip)       PNV10_CHIP_BASE(chip, 0x0006030000000000ull)
+
 #define PNV10_PSIHB_ESB_SIZE        0x0000000000100000ull
 #define PNV10_PSIHB_ESB_BASE(chip)  PNV10_CHIP_BASE(chip, 0x0006030202000000ull)
 
diff --git a/include/hw/ppc/pnv_lpc.h b/include/hw/ppc/pnv_lpc.h
index f659410716..c1ec85d5e2 100644
--- a/include/hw/ppc/pnv_lpc.h
+++ b/include/hw/ppc/pnv_lpc.h
@@ -31,6 +31,9 @@
 #define TYPE_PNV9_LPC TYPE_PNV_LPC "-POWER9"
 #define PNV9_LPC(obj) OBJECT_CHECK(PnvLpcController, (obj), TYPE_PNV9_LPC)
 
+#define TYPE_PNV10_LPC TYPE_PNV_LPC "-POWER10"
+#define PNV10_LPC(obj) OBJECT_CHECK(PnvLpcController, (obj), TYPE_PNV10_LPC)
+
 typedef struct PnvLpcController {
     DeviceState parent;
 
@@ -97,6 +100,7 @@ typedef struct PnvLpcClass {
 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);
+int pnv_dt_lpc(struct PnvChip *chip, void *fdt, int root_offset,
+               uint64_t lpcm_addr, uint64_t lpcm_size);
 
 #endif /* PPC_PNV_LPC_H */
-- 
2.23.0



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

* [PULL 66/88] target/ppc: Implement the VTB for HV access
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (64 preceding siblings ...)
  2019-12-17  4:42 ` [PULL 65/88] ppc/pnv: add a LPC Controller " David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 67/88] target/ppc: Work [S]PURR implementation and add HV support David Gibson
                   ` (22 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg,
	Suraj Jitindar Singh, David Gibson

From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>

The virtual timebase register (VTB) is a 64-bit register which
increments at the same rate as the timebase register, present on POWER8
and later processors.

The register is able to be read/written by the hypervisor and read by
the supervisor. All other accesses are illegal.

Currently the VTB is just an alias for the timebase (TB) register.

Implement the VTB so that is can be read/written independent of the TB.
Make use of the existing method for accessing timebase facilities where
by the compensation is stored and used to compute the value on reads/is
updated on writes.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
[ clg: rebased on current ppc tree ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191128134700.16091-2-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/ppc.c                    | 16 ++++++++++++++++
 include/hw/ppc/ppc.h            |  1 +
 linux-user/ppc/cpu_loop.c       |  5 +++++
 target/ppc/cpu.h                |  2 ++
 target/ppc/helper.h             |  2 ++
 target/ppc/timebase_helper.c    | 10 ++++++++++
 target/ppc/translate_init.inc.c | 19 +++++++++++++++----
 7 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 45834f98d1..d8c402811f 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -682,6 +682,22 @@ void cpu_ppc_store_atbu (CPUPPCState *env, uint32_t value)
                      &tb_env->atb_offset, ((uint64_t)value << 32) | tb);
 }
 
+uint64_t cpu_ppc_load_vtb(CPUPPCState *env)
+{
+    ppc_tb_t *tb_env = env->tb_env;
+
+    return cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
+                          tb_env->vtb_offset);
+}
+
+void cpu_ppc_store_vtb(CPUPPCState *env, uint64_t value)
+{
+    ppc_tb_t *tb_env = env->tb_env;
+
+    cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
+                     &tb_env->vtb_offset, value);
+}
+
 static void cpu_ppc_tb_stop (CPUPPCState *env)
 {
     ppc_tb_t *tb_env = env->tb_env;
diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h
index 89e1dd065a..d7a95608f6 100644
--- a/include/hw/ppc/ppc.h
+++ b/include/hw/ppc/ppc.h
@@ -24,6 +24,7 @@ struct ppc_tb_t {
     /* Time base management */
     int64_t  tb_offset;    /* Compensation                    */
     int64_t  atb_offset;   /* Compensation                    */
+    int64_t  vtb_offset;
     uint32_t tb_freq;      /* TB frequency                    */
     /* Decrementer management */
     uint64_t decr_next;    /* Tick for next decr interrupt    */
diff --git a/linux-user/ppc/cpu_loop.c b/linux-user/ppc/cpu_loop.c
index d5704def29..5b27f8603e 100644
--- a/linux-user/ppc/cpu_loop.c
+++ b/linux-user/ppc/cpu_loop.c
@@ -47,6 +47,11 @@ uint32_t cpu_ppc_load_atbu(CPUPPCState *env)
     return cpu_ppc_get_tb(env) >> 32;
 }
 
+uint64_t cpu_ppc_load_vtb(CPUPPCState *env)
+{
+    return cpu_ppc_get_tb(env);
+}
+
 uint32_t cpu_ppc601_load_rtcu(CPUPPCState *env)
 __attribute__ (( alias ("cpu_ppc_load_tbu") ));
 
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index fbec1b0cd5..eb7d2c7637 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1303,6 +1303,8 @@ uint64_t cpu_ppc_load_atbl(CPUPPCState *env);
 uint32_t cpu_ppc_load_atbu(CPUPPCState *env);
 void cpu_ppc_store_atbl(CPUPPCState *env, uint32_t value);
 void cpu_ppc_store_atbu(CPUPPCState *env, uint32_t value);
+uint64_t cpu_ppc_load_vtb(CPUPPCState *env);
+void cpu_ppc_store_vtb(CPUPPCState *env, uint64_t value);
 bool ppc_decr_clear_on_delivery(CPUPPCState *env);
 target_ulong cpu_ppc_load_decr(CPUPPCState *env);
 void cpu_ppc_store_decr(CPUPPCState *env, target_ulong value);
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index f843814b8a..a5f53bb421 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -649,6 +649,7 @@ DEF_HELPER_FLAGS_1(load_tbl, TCG_CALL_NO_RWG, tl, env)
 DEF_HELPER_FLAGS_1(load_tbu, TCG_CALL_NO_RWG, tl, env)
 DEF_HELPER_FLAGS_1(load_atbl, TCG_CALL_NO_RWG, tl, env)
 DEF_HELPER_FLAGS_1(load_atbu, TCG_CALL_NO_RWG, tl, env)
+DEF_HELPER_FLAGS_1(load_vtb, TCG_CALL_NO_RWG, tl, env)
 DEF_HELPER_FLAGS_1(load_601_rtcl, TCG_CALL_NO_RWG, tl, env)
 DEF_HELPER_FLAGS_1(load_601_rtcu, TCG_CALL_NO_RWG, tl, env)
 #if !defined(CONFIG_USER_ONLY)
@@ -669,6 +670,7 @@ DEF_HELPER_FLAGS_1(load_decr, TCG_CALL_NO_RWG, tl, env)
 DEF_HELPER_FLAGS_2(store_decr, TCG_CALL_NO_RWG, void, env, tl)
 DEF_HELPER_FLAGS_1(load_hdecr, TCG_CALL_NO_RWG, tl, env)
 DEF_HELPER_FLAGS_2(store_hdecr, TCG_CALL_NO_RWG, void, env, tl)
+DEF_HELPER_FLAGS_2(store_vtb, TCG_CALL_NO_RWG, void, env, tl)
 DEF_HELPER_2(store_hid0_601, void, env, tl)
 DEF_HELPER_3(store_403_pbr, void, env, i32, tl)
 DEF_HELPER_FLAGS_1(load_40x_pit, TCG_CALL_NO_RWG, tl, env)
diff --git a/target/ppc/timebase_helper.c b/target/ppc/timebase_helper.c
index 73363e08ae..8c3c2fe67c 100644
--- a/target/ppc/timebase_helper.c
+++ b/target/ppc/timebase_helper.c
@@ -45,6 +45,11 @@ target_ulong helper_load_atbu(CPUPPCState *env)
     return cpu_ppc_load_atbu(env);
 }
 
+target_ulong helper_load_vtb(CPUPPCState *env)
+{
+    return cpu_ppc_load_vtb(env);
+}
+
 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
 target_ulong helper_load_purr(CPUPPCState *env)
 {
@@ -113,6 +118,11 @@ void helper_store_hdecr(CPUPPCState *env, target_ulong val)
     cpu_ppc_store_hdecr(env, val);
 }
 
+void helper_store_vtb(CPUPPCState *env, target_ulong val)
+{
+    cpu_ppc_store_vtb(env, val);
+}
+
 target_ulong helper_load_40x_pit(CPUPPCState *env)
 {
     return load_40x_pit(env);
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 7364d36b07..226aecf8f4 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -312,6 +312,16 @@ static void spr_write_hdecr(DisasContext *ctx, int sprn, int gprn)
     }
 }
 
+static void spr_read_vtb(DisasContext *ctx, int gprn, int sprn)
+{
+    gen_helper_load_vtb(cpu_gpr[gprn], cpu_env);
+}
+
+static void spr_write_vtb(DisasContext *ctx, int sprn, int gprn)
+{
+    gen_helper_store_vtb(cpu_env, cpu_gpr[gprn]);
+}
+
 #endif
 #endif
 
@@ -8174,10 +8184,11 @@ static void gen_spr_power8_ebb(CPUPPCState *env)
 /* Virtual Time Base */
 static void gen_spr_vtb(CPUPPCState *env)
 {
-    spr_register_kvm(env, SPR_VTB, "VTB",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_tbl, SPR_NOACCESS,
-                 KVM_REG_PPC_VTB, 0x00000000);
+    spr_register_kvm_hv(env, SPR_VTB, "VTB",
+                        SPR_NOACCESS, SPR_NOACCESS,
+                        &spr_read_vtb, SPR_NOACCESS,
+                        &spr_read_vtb, &spr_write_vtb,
+                        KVM_REG_PPC_VTB, 0x00000000);
 }
 
 static void gen_spr_power8_fscr(CPUPPCState *env)
-- 
2.23.0



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

* [PULL 67/88] target/ppc: Work [S]PURR implementation and add HV support
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (65 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 66/88] target/ppc: Implement the VTB for HV access David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 68/88] target/ppc: Add SPR ASDR David Gibson
                   ` (21 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg,
	Suraj Jitindar Singh, David Gibson

From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>

The Processor Utilisation of Resources Register (PURR) and Scaled
Processor Utilisation of Resources Register (SPURR) provide an estimate
of the resources used by the thread, present on POWER7 and later
processors.

Currently the [S]PURR registers simply count at the rate of the
timebase.

Preserve this behaviour but rework the implementation to store an offset
like the timebase rather than doing the calculation manually. Also allow
hypervisor write access to the register along with the currently
available read access.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
[ clg: rebased on current ppc tree ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191128134700.16091-3-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/ppc.c                    | 17 +++++++----------
 include/hw/ppc/ppc.h            |  3 +--
 target/ppc/cpu.h                |  1 +
 target/ppc/helper.h             |  1 +
 target/ppc/timebase_helper.c    |  5 +++++
 target/ppc/translate_init.inc.c | 23 +++++++++++++++--------
 6 files changed, 30 insertions(+), 20 deletions(-)

diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index d8c402811f..2856d69495 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -809,12 +809,9 @@ target_ulong cpu_ppc_load_hdecr(CPUPPCState *env)
 uint64_t cpu_ppc_load_purr (CPUPPCState *env)
 {
     ppc_tb_t *tb_env = env->tb_env;
-    uint64_t diff;
 
-    diff = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - tb_env->purr_start;
-
-    return tb_env->purr_load +
-        muldiv64(diff, tb_env->tb_freq, NANOSECONDS_PER_SECOND);
+    return cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
+                          tb_env->purr_offset);
 }
 
 /* When decrementer expires,
@@ -973,12 +970,12 @@ static void cpu_ppc_hdecr_cb(void *opaque)
     cpu_ppc_hdecr_excp(cpu);
 }
 
-static void cpu_ppc_store_purr(PowerPCCPU *cpu, uint64_t value)
+void cpu_ppc_store_purr(CPUPPCState *env, uint64_t value)
 {
-    ppc_tb_t *tb_env = cpu->env.tb_env;
+    ppc_tb_t *tb_env = env->tb_env;
 
-    tb_env->purr_load = value;
-    tb_env->purr_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
+                     &tb_env->purr_offset, value);
 }
 
 static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq)
@@ -995,7 +992,7 @@ static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq)
      */
     _cpu_ppc_store_decr(cpu, 0xFFFFFFFF, 0xFFFFFFFF, 32);
     _cpu_ppc_store_hdecr(cpu, 0xFFFFFFFF, 0xFFFFFFFF, 32);
-    cpu_ppc_store_purr(cpu, 0x0000000000000000ULL);
+    cpu_ppc_store_purr(env, 0x0000000000000000ULL);
 }
 
 static void timebase_save(PPCTimebase *tb)
diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h
index d7a95608f6..4ea5436095 100644
--- a/include/hw/ppc/ppc.h
+++ b/include/hw/ppc/ppc.h
@@ -33,8 +33,7 @@ struct ppc_tb_t {
     /* Hypervisor decrementer management */
     uint64_t hdecr_next;    /* Tick for next hdecr interrupt  */
     QEMUTimer *hdecr_timer;
-    uint64_t purr_load;
-    uint64_t purr_start;
+    int64_t purr_offset;
     void *opaque;
     uint32_t flags;
 };
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index eb7d2c7637..da44cc8809 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1311,6 +1311,7 @@ void cpu_ppc_store_decr(CPUPPCState *env, target_ulong value);
 target_ulong cpu_ppc_load_hdecr(CPUPPCState *env);
 void cpu_ppc_store_hdecr(CPUPPCState *env, target_ulong value);
 uint64_t cpu_ppc_load_purr(CPUPPCState *env);
+void cpu_ppc_store_purr(CPUPPCState *env, uint64_t value);
 uint32_t cpu_ppc601_load_rtcl(CPUPPCState *env);
 uint32_t cpu_ppc601_load_rtcu(CPUPPCState *env);
 #if !defined(CONFIG_USER_ONLY)
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index a5f53bb421..356a14d8a6 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -655,6 +655,7 @@ DEF_HELPER_FLAGS_1(load_601_rtcu, TCG_CALL_NO_RWG, tl, env)
 #if !defined(CONFIG_USER_ONLY)
 #if defined(TARGET_PPC64)
 DEF_HELPER_FLAGS_1(load_purr, TCG_CALL_NO_RWG, tl, env)
+DEF_HELPER_FLAGS_2(store_purr, TCG_CALL_NO_RWG, void, env, tl)
 DEF_HELPER_2(store_ptcr, void, env, tl)
 #endif
 DEF_HELPER_2(store_sdr1, void, env, tl)
diff --git a/target/ppc/timebase_helper.c b/target/ppc/timebase_helper.c
index 8c3c2fe67c..2395295b77 100644
--- a/target/ppc/timebase_helper.c
+++ b/target/ppc/timebase_helper.c
@@ -55,6 +55,11 @@ target_ulong helper_load_purr(CPUPPCState *env)
 {
     return (target_ulong)cpu_ppc_load_purr(env);
 }
+
+void helper_store_purr(CPUPPCState *env, target_ulong val)
+{
+    cpu_ppc_store_purr(env, val);
+}
 #endif
 
 target_ulong helper_load_601_rtcl(CPUPPCState *env)
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 226aecf8f4..c5e4d45569 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -287,6 +287,11 @@ static void spr_read_purr(DisasContext *ctx, int gprn, int sprn)
     gen_helper_load_purr(cpu_gpr[gprn], cpu_env);
 }
 
+static void spr_write_purr(DisasContext *ctx, int sprn, int gprn)
+{
+    gen_helper_store_purr(cpu_env, cpu_gpr[gprn]);
+}
+
 /* HDECR */
 static void spr_read_hdecr(DisasContext *ctx, int gprn, int sprn)
 {
@@ -8013,14 +8018,16 @@ static void gen_spr_book3s_purr(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
-    spr_register_kvm(env, SPR_PURR,   "PURR",
-                     &spr_read_purr, SPR_NOACCESS,
-                     &spr_read_purr, SPR_NOACCESS,
-                     KVM_REG_PPC_PURR, 0x00000000);
-    spr_register_kvm(env, SPR_SPURR,   "SPURR",
-                     &spr_read_purr, SPR_NOACCESS,
-                     &spr_read_purr, SPR_NOACCESS,
-                     KVM_REG_PPC_SPURR, 0x00000000);
+    spr_register_kvm_hv(env, SPR_PURR,   "PURR",
+                        &spr_read_purr, SPR_NOACCESS,
+                        &spr_read_purr, SPR_NOACCESS,
+                        &spr_read_purr, &spr_write_purr,
+                        KVM_REG_PPC_PURR, 0x00000000);
+    spr_register_kvm_hv(env, SPR_SPURR,   "SPURR",
+                        &spr_read_purr, SPR_NOACCESS,
+                        &spr_read_purr, SPR_NOACCESS,
+                        &spr_read_purr, &spr_write_purr,
+                        KVM_REG_PPC_SPURR, 0x00000000);
 #endif
 }
 
-- 
2.23.0



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

* [PULL 68/88] target/ppc: Add SPR ASDR
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (66 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 67/88] target/ppc: Work [S]PURR implementation and add HV support David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 69/88] target/ppc: Add SPR TBU40 David Gibson
                   ` (20 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg,
	Suraj Jitindar Singh, David Gibson

From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>

The Access Segment Descriptor Register (ASDR) provides information about
the storage element when taking a hypervisor storage interrupt. When
performing nested radix address translation, this is normally the guest
real address. This register is present on POWER9 processors and later.

Implement the ADSR, note read and write access is limited to the
hypervisor.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191128134700.16091-4-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/cpu.h                | 1 +
 target/ppc/translate_init.inc.c | 6 ++++++
 2 files changed, 7 insertions(+)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index da44cc8809..e99850c3ae 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1778,6 +1778,7 @@ typedef PowerPCCPU ArchCPU;
 #define SPR_MPC_MD_DBRAM1     (0x32A)
 #define SPR_RCPU_L2U_RA3      (0x32B)
 #define SPR_TAR               (0x32F)
+#define SPR_ASDR              (0x330)
 #define SPR_IC                (0x350)
 #define SPR_VTB               (0x351)
 #define SPR_MMCRC             (0x353)
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index c5e4d45569..c850a9d065 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -8295,6 +8295,12 @@ static void gen_spr_power9_mmu(CPUPPCState *env)
                         SPR_NOACCESS, SPR_NOACCESS,
                         &spr_read_generic, &spr_write_ptcr,
                         KVM_REG_PPC_PTCR, 0x00000000);
+    /* Address Segment Descriptor Register */
+    spr_register_hv(env, SPR_ASDR, "ASDR",
+                    SPR_NOACCESS, SPR_NOACCESS,
+                    SPR_NOACCESS, SPR_NOACCESS,
+                    &spr_read_generic, &spr_write_generic,
+                    0x0000000000000000);
 #endif
 }
 
-- 
2.23.0



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

* [PULL 69/88] target/ppc: Add SPR TBU40
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (67 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 68/88] target/ppc: Add SPR ASDR David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 70/88] ppc/pnv: Loop on the whole hierarchy to populate the DT with the XSCOM nodes David Gibson
                   ` (19 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg,
	Suraj Jitindar Singh, David Gibson

From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>

The spr TBU40 is used to set the upper 40 bits of the timebase
register, present on POWER5+ and later processors.

This register can only be written by the hypervisor, and cannot be read.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191128134700.16091-5-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/ppc.c                    | 13 +++++++++++++
 target/ppc/cpu.h                |  1 +
 target/ppc/helper.h             |  1 +
 target/ppc/timebase_helper.c    |  5 +++++
 target/ppc/translate_init.inc.c | 19 +++++++++++++++++++
 5 files changed, 39 insertions(+)

diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 2856d69495..4c5fa29399 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -698,6 +698,19 @@ void cpu_ppc_store_vtb(CPUPPCState *env, uint64_t value)
                      &tb_env->vtb_offset, value);
 }
 
+void cpu_ppc_store_tbu40(CPUPPCState *env, uint64_t value)
+{
+    ppc_tb_t *tb_env = env->tb_env;
+    uint64_t tb;
+
+    tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
+                        tb_env->tb_offset);
+    tb &= 0xFFFFFFUL;
+    tb |= (value & ~0xFFFFFFUL);
+    cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
+                     &tb_env->tb_offset, tb);
+}
+
 static void cpu_ppc_tb_stop (CPUPPCState *env)
 {
     ppc_tb_t *tb_env = env->tb_env;
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index e99850c3ae..103bfe9dc2 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1310,6 +1310,7 @@ target_ulong cpu_ppc_load_decr(CPUPPCState *env);
 void cpu_ppc_store_decr(CPUPPCState *env, target_ulong value);
 target_ulong cpu_ppc_load_hdecr(CPUPPCState *env);
 void cpu_ppc_store_hdecr(CPUPPCState *env, target_ulong value);
+void cpu_ppc_store_tbu40(CPUPPCState *env, uint64_t value);
 uint64_t cpu_ppc_load_purr(CPUPPCState *env);
 void cpu_ppc_store_purr(CPUPPCState *env, uint64_t value);
 uint32_t cpu_ppc601_load_rtcl(CPUPPCState *env);
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 356a14d8a6..cd0dfe383a 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -672,6 +672,7 @@ DEF_HELPER_FLAGS_2(store_decr, TCG_CALL_NO_RWG, void, env, tl)
 DEF_HELPER_FLAGS_1(load_hdecr, TCG_CALL_NO_RWG, tl, env)
 DEF_HELPER_FLAGS_2(store_hdecr, TCG_CALL_NO_RWG, void, env, tl)
 DEF_HELPER_FLAGS_2(store_vtb, TCG_CALL_NO_RWG, void, env, tl)
+DEF_HELPER_FLAGS_2(store_tbu40, TCG_CALL_NO_RWG, void, env, tl)
 DEF_HELPER_2(store_hid0_601, void, env, tl)
 DEF_HELPER_3(store_403_pbr, void, env, i32, tl)
 DEF_HELPER_FLAGS_1(load_40x_pit, TCG_CALL_NO_RWG, tl, env)
diff --git a/target/ppc/timebase_helper.c b/target/ppc/timebase_helper.c
index 2395295b77..703bd9ed18 100644
--- a/target/ppc/timebase_helper.c
+++ b/target/ppc/timebase_helper.c
@@ -128,6 +128,11 @@ void helper_store_vtb(CPUPPCState *env, target_ulong val)
     cpu_ppc_store_vtb(env, val);
 }
 
+void helper_store_tbu40(CPUPPCState *env, target_ulong val)
+{
+    cpu_ppc_store_tbu40(env, val);
+}
+
 target_ulong helper_load_40x_pit(CPUPPCState *env)
 {
     return load_40x_pit(env);
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index c850a9d065..d33d65dff7 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -327,6 +327,11 @@ static void spr_write_vtb(DisasContext *ctx, int sprn, int gprn)
     gen_helper_store_vtb(cpu_env, cpu_gpr[gprn]);
 }
 
+static void spr_write_tbu40(DisasContext *ctx, int sprn, int gprn)
+{
+    gen_helper_store_tbu40(cpu_env, cpu_gpr[gprn]);
+}
+
 #endif
 #endif
 
@@ -7853,6 +7858,16 @@ static void gen_spr_power5p_ear(CPUPPCState *env)
                  0x00000000);
 }
 
+static void gen_spr_power5p_tb(CPUPPCState *env)
+{
+    /* TBU40 (High 40 bits of the Timebase register */
+    spr_register_hv(env, SPR_TBU40, "TBU40",
+                    SPR_NOACCESS, SPR_NOACCESS,
+                    SPR_NOACCESS, SPR_NOACCESS,
+                    SPR_NOACCESS, &spr_write_tbu40,
+                    0x00000000);
+}
+
 #if !defined(CONFIG_USER_ONLY)
 static void spr_write_hmer(DisasContext *ctx, int sprn, int gprn)
 {
@@ -8404,6 +8419,7 @@ static void init_proc_power5plus(CPUPPCState *env)
     gen_spr_power5p_common(env);
     gen_spr_power5p_lpar(env);
     gen_spr_power5p_ear(env);
+    gen_spr_power5p_tb(env);
 
     /* env variables */
     env->dcache_line_size = 128;
@@ -8516,6 +8532,7 @@ static void init_proc_POWER7(CPUPPCState *env)
     gen_spr_power5p_common(env);
     gen_spr_power5p_lpar(env);
     gen_spr_power5p_ear(env);
+    gen_spr_power5p_tb(env);
     gen_spr_power6_common(env);
     gen_spr_power6_dbg(env);
     gen_spr_power7_book4(env);
@@ -8657,6 +8674,7 @@ static void init_proc_POWER8(CPUPPCState *env)
     gen_spr_power5p_common(env);
     gen_spr_power5p_lpar(env);
     gen_spr_power5p_ear(env);
+    gen_spr_power5p_tb(env);
     gen_spr_power6_common(env);
     gen_spr_power6_dbg(env);
     gen_spr_power8_tce_address_control(env);
@@ -8847,6 +8865,7 @@ static void init_proc_POWER9(CPUPPCState *env)
     gen_spr_power5p_common(env);
     gen_spr_power5p_lpar(env);
     gen_spr_power5p_ear(env);
+    gen_spr_power5p_tb(env);
     gen_spr_power6_common(env);
     gen_spr_power6_dbg(env);
     gen_spr_power8_tce_address_control(env);
-- 
2.23.0



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

* [PULL 70/88] ppc/pnv: Loop on the whole hierarchy to populate the DT with the XSCOM nodes
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (68 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 69/88] target/ppc: Add SPR TBU40 David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 71/88] ppc/pnv: populate the DT with realized XSCOM devices David Gibson
                   ` (18 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

Some PnvXScomInterface objects lie a bit deeper (PnvPBCQState) than
the first layer, so we need to loop on the whole object hierarchy to
catch them.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191210135845.19773-2-clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
[dwg: Corrected error in comment]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv_xscom.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c
index b3d3b6e350..760571037b 100644
--- a/hw/ppc/pnv_xscom.c
+++ b/hw/ppc/pnv_xscom.c
@@ -358,7 +358,12 @@ int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset)
     args.fdt = fdt;
     args.xscom_offset = xscom_offset;
 
-    object_child_foreach(OBJECT(chip), xscom_dt_child, &args);
+    /*
+     * Loop on the whole object hierarchy to catch all
+     * PnvXScomInterface objects which can lie a bit deeper than the
+     * first layer.
+     */
+    object_child_foreach_recursive(OBJECT(chip), xscom_dt_child, &args);
     return 0;
 }
 
-- 
2.23.0



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

* [PULL 71/88] ppc/pnv: populate the DT with realized XSCOM devices
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (69 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 70/88] ppc/pnv: Loop on the whole hierarchy to populate the DT with the XSCOM nodes David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 72/88] ppc/pnv: Make PnvXScomInterface an incomplete type David Gibson
                   ` (17 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg,
	Philippe Mathieu-Daudé,
	David Gibson

From: Cédric Le Goater <clg@kaod.org>

Some devices could be initialized in the instance_init handler but not
realized for configuration reasons. Nodes should not be added in the DT
for such devices.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191210135845.19773-3-clg@kaod.org>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv_xscom.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c
index 760571037b..fd48d4ee37 100644
--- a/hw/ppc/pnv_xscom.c
+++ b/hw/ppc/pnv_xscom.c
@@ -304,7 +304,10 @@ static int xscom_dt_child(Object *child, void *opaque)
         PnvXScomInterface *xd = PNV_XSCOM_INTERFACE(child);
         PnvXScomInterfaceClass *xc = PNV_XSCOM_INTERFACE_GET_CLASS(xd);
 
-        if (xc->dt_xscom) {
+        /*
+         * Only "realized" devices should be configured in the DT
+         */
+        if (xc->dt_xscom && DEVICE(child)->realized) {
             _FDT((xc->dt_xscom(xd, args->fdt, args->xscom_offset)));
         }
     }
-- 
2.23.0



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

* [PULL 72/88] ppc/pnv: Make PnvXScomInterface an incomplete type
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (70 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 71/88] ppc/pnv: populate the DT with realized XSCOM devices David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 73/88] ppc/pnv: Introduce PBA registers David Gibson
                   ` (16 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg,
	Philippe Mathieu-Daudé,
	David Gibson

From: Greg Kurz <groug@kaod.org>

PnvXScomInterface is an interface instance. It should never be
dereferenced. Drop the dummy type definition for extra safety,
which is the common practice with QOM interfaces.

While here also convert the bogus OBJECT_CHECK() to INTERFACE_CHECK().

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157608025541.186670.1577861507610404326.stgit@bahia.lan>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 include/hw/ppc/pnv_xscom.h | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index a40d2a2a2a..5ad2735d1a 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -22,13 +22,11 @@
 
 #include "qom/object.h"
 
-typedef struct PnvXScomInterface {
-    Object parent;
-} PnvXScomInterface;
+typedef struct PnvXScomInterface PnvXScomInterface;
 
 #define TYPE_PNV_XSCOM_INTERFACE "pnv-xscom-interface"
 #define PNV_XSCOM_INTERFACE(obj) \
-     OBJECT_CHECK(PnvXScomInterface, (obj), TYPE_PNV_XSCOM_INTERFACE)
+    INTERFACE_CHECK(PnvXScomInterface, (obj), TYPE_PNV_XSCOM_INTERFACE)
 #define PNV_XSCOM_INTERFACE_CLASS(klass)                \
     OBJECT_CLASS_CHECK(PnvXScomInterfaceClass, (klass), \
                        TYPE_PNV_XSCOM_INTERFACE)
-- 
2.23.0



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

* [PULL 73/88] ppc/pnv: Introduce PBA registers
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (71 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 72/88] ppc/pnv: Make PnvXScomInterface an incomplete type David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 74/88] ppc/pnv: Fix OCC common area region mapping David Gibson
                   ` (15 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

The PBA bridge unit (Power Bus Access) connects the OCC (On Chip
Controller) to the Power bus and System Memory. The PBA is used to
gather sensor data, for power management, for sleep states, for
initial boot, among other things.

The PBA logic provides a set of four registers PowerBus Access Base
Address Registers (PBABAR0..3) which map the OCC address space to the
PowerBus space. These registers are setup by the initial FW and define
the PowerBus Range of system memory that can be accessed by PBA.

The current modeling of the PBABAR registers is done under the common
XSCOM handlers. We introduce a specific XSCOM regions for these
registers and fix :

 - BAR sizes and BAR masks
 - The mapping of the OCC common area. It is common to all chips and
   should be mapped once.  We will address per-OCC area in the next
   change.
 - OCC common area is in BAR 3 on P8

Inspired by previous work of Balamuruhan S <bala24@linux.ibm.com>

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191211082912.2625-2-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c               |  12 +++-
 hw/ppc/pnv_homer.c         | 109 +++++++++++++++++++++++++++++++++++++
 hw/ppc/pnv_xscom.c         |  32 -----------
 include/hw/ppc/pnv.h       |  16 ++----
 include/hw/ppc/pnv_homer.h |   3 +
 include/hw/ppc/pnv_xscom.h |   6 ++
 6 files changed, 134 insertions(+), 44 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 67d0ad55b8..af7317a86d 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1065,7 +1065,7 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
     pnv_xscom_add_subregion(chip, PNV_XSCOM_OCC_BASE, &chip8->occ.xscom_regs);
 
     /* OCC SRAM model */
-    memory_region_add_subregion(get_system_memory(), PNV_OCC_COMMON_AREA(chip),
+    memory_region_add_subregion(get_system_memory(), PNV_OCC_COMMON_AREA_BASE,
                                 &chip8->occ.sram_regs);
 
     /* HOMER */
@@ -1077,6 +1077,10 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
         error_propagate(errp, local_err);
         return;
     }
+    /* Homer Xscom region */
+    pnv_xscom_add_subregion(chip, PNV_XSCOM_PBA_BASE, &chip8->homer.pba_regs);
+
+    /* Homer mmio region */
     memory_region_add_subregion(get_system_memory(), PNV_HOMER_BASE(chip),
                                 &chip8->homer.regs);
 }
@@ -1274,7 +1278,7 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
     pnv_xscom_add_subregion(chip, PNV9_XSCOM_OCC_BASE, &chip9->occ.xscom_regs);
 
     /* OCC SRAM model */
-    memory_region_add_subregion(get_system_memory(), PNV9_OCC_COMMON_AREA(chip),
+    memory_region_add_subregion(get_system_memory(), PNV9_OCC_COMMON_AREA_BASE,
                                 &chip9->occ.sram_regs);
 
     /* HOMER */
@@ -1286,6 +1290,10 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
         error_propagate(errp, local_err);
         return;
     }
+    /* Homer Xscom region */
+    pnv_xscom_add_subregion(chip, PNV9_XSCOM_PBA_BASE, &chip9->homer.pba_regs);
+
+    /* Homer mmio region */
     memory_region_add_subregion(get_system_memory(), PNV9_HOMER_BASE(chip),
                                 &chip9->homer.regs);
 }
diff --git a/hw/ppc/pnv_homer.c b/hw/ppc/pnv_homer.c
index 994a378108..a08b7914f7 100644
--- a/hw/ppc/pnv_homer.c
+++ b/hw/ppc/pnv_homer.c
@@ -17,6 +17,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/log.h"
 #include "qapi/error.h"
 #include "exec/hwaddr.h"
 #include "exec/memory.h"
@@ -25,6 +26,7 @@
 #include "hw/qdev-properties.h"
 #include "hw/ppc/pnv.h"
 #include "hw/ppc/pnv_homer.h"
+#include "hw/ppc/pnv_xscom.h"
 
 
 static bool core_max_array(PnvHomer *homer, hwaddr addr)
@@ -114,10 +116,67 @@ static const MemoryRegionOps pnv_power8_homer_ops = {
     .endianness = DEVICE_BIG_ENDIAN,
 };
 
+/* P8 PBA BARs */
+#define PBA_BAR0                     0x00
+#define PBA_BAR1                     0x01
+#define PBA_BAR2                     0x02
+#define PBA_BAR3                     0x03
+#define PBA_BARMASK0                 0x04
+#define PBA_BARMASK1                 0x05
+#define PBA_BARMASK2                 0x06
+#define PBA_BARMASK3                 0x07
+
+static uint64_t pnv_homer_power8_pba_read(void *opaque, hwaddr addr,
+                                          unsigned size)
+{
+    PnvHomer *homer = PNV_HOMER(opaque);
+    PnvChip *chip = homer->chip;
+    uint32_t reg = addr >> 3;
+    uint64_t val = 0;
+
+    switch (reg) {
+    case PBA_BAR0:
+        val = PNV_HOMER_BASE(chip);
+        break;
+    case PBA_BARMASK0: /* P8 homer region mask */
+        val = (PNV_HOMER_SIZE - 1) & 0x300000;
+        break;
+    case PBA_BAR3: /* P8 occ common area */
+        val = PNV_OCC_COMMON_AREA_BASE;
+        break;
+    case PBA_BARMASK3: /* P8 occ common area mask */
+        val = (PNV_OCC_COMMON_AREA_SIZE - 1) & 0x700000;
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "PBA: read to unimplemented register: Ox%"
+                      HWADDR_PRIx "\n", addr >> 3);
+    }
+    return val;
+}
+
+static void pnv_homer_power8_pba_write(void *opaque, hwaddr addr,
+                                         uint64_t val, unsigned size)
+{
+    qemu_log_mask(LOG_UNIMP, "PBA: write to unimplemented register: Ox%"
+                  HWADDR_PRIx "\n", addr >> 3);
+}
+
+static const MemoryRegionOps pnv_homer_power8_pba_ops = {
+    .read = pnv_homer_power8_pba_read,
+    .write = pnv_homer_power8_pba_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_homer_power8_class_init(ObjectClass *klass, void *data)
 {
     PnvHomerClass *homer = PNV_HOMER_CLASS(klass);
 
+    homer->pba_size = PNV_XSCOM_PBA_SIZE;
+    homer->pba_ops = &pnv_homer_power8_pba_ops;
     homer->homer_size = PNV_HOMER_SIZE;
     homer->homer_ops = &pnv_power8_homer_ops;
     homer->core_max_base = PNV8_CORE_MAX_BASE;
@@ -210,10 +269,57 @@ static const MemoryRegionOps pnv_power9_homer_ops = {
     .endianness = DEVICE_BIG_ENDIAN,
 };
 
+static uint64_t pnv_homer_power9_pba_read(void *opaque, hwaddr addr,
+                                          unsigned size)
+{
+    PnvHomer *homer = PNV_HOMER(opaque);
+    PnvChip *chip = homer->chip;
+    uint32_t reg = addr >> 3;
+    uint64_t val = 0;
+
+    switch (reg) {
+    case PBA_BAR0:
+        val = PNV9_HOMER_BASE(chip);
+        break;
+    case PBA_BARMASK0: /* P9 homer region mask */
+        val = (PNV9_HOMER_SIZE - 1) & 0x300000;
+        break;
+    case PBA_BAR2: /* P9 occ common area */
+        val = PNV9_OCC_COMMON_AREA_BASE;
+        break;
+    case PBA_BARMASK2: /* P9 occ common area size */
+        val = (PNV9_OCC_COMMON_AREA_SIZE - 1) & 0x700000;
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "PBA: read to unimplemented register: Ox%"
+                      HWADDR_PRIx "\n", addr >> 3);
+    }
+    return val;
+}
+
+static void pnv_homer_power9_pba_write(void *opaque, hwaddr addr,
+                                         uint64_t val, unsigned size)
+{
+    qemu_log_mask(LOG_UNIMP, "PBA: write to unimplemented register: Ox%"
+                  HWADDR_PRIx "\n", addr >> 3);
+}
+
+static const MemoryRegionOps pnv_homer_power9_pba_ops = {
+    .read = pnv_homer_power9_pba_read,
+    .write = pnv_homer_power9_pba_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_homer_power9_class_init(ObjectClass *klass, void *data)
 {
     PnvHomerClass *homer = PNV_HOMER_CLASS(klass);
 
+    homer->pba_size = PNV9_XSCOM_PBA_SIZE;
+    homer->pba_ops = &pnv_homer_power9_pba_ops;
     homer->homer_size = PNV9_HOMER_SIZE;
     homer->homer_ops = &pnv_power9_homer_ops;
     homer->core_max_base = PNV9_CORE_MAX_BASE;
@@ -233,6 +339,9 @@ static void pnv_homer_realize(DeviceState *dev, Error **errp)
 
     assert(homer->chip);
 
+    pnv_xscom_region_init(&homer->pba_regs, OBJECT(dev), hmrc->pba_ops,
+                          homer, "xscom-pba", hmrc->pba_size);
+
     /* homer region */
     memory_region_init_io(&homer->regs, OBJECT(dev),
                           hmrc->homer_ops, homer, "homer-main-memory",
diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c
index fd48d4ee37..df926003f2 100644
--- a/hw/ppc/pnv_xscom.c
+++ b/hw/ppc/pnv_xscom.c
@@ -36,16 +36,6 @@
 #define PRD_P9_IPOLL_REG_MASK           0x000F0033
 #define PRD_P9_IPOLL_REG_STATUS         0x000F0034
 
-/* PBA BARs */
-#define P8_PBA_BAR0                     0x2013f00
-#define P8_PBA_BAR2                     0x2013f02
-#define P8_PBA_BARMASK0                 0x2013f04
-#define P8_PBA_BARMASK2                 0x2013f06
-#define P9_PBA_BAR0                     0x5012b00
-#define P9_PBA_BAR2                     0x5012b02
-#define P9_PBA_BARMASK0                 0x5012b04
-#define P9_PBA_BARMASK2                 0x5012b06
-
 static void xscom_complete(CPUState *cs, uint64_t hmer_bits)
 {
     /*
@@ -90,26 +80,6 @@ static uint64_t xscom_read_default(PnvChip *chip, uint32_t pcba)
     case 0x18002:       /* ECID2 */
         return 0;
 
-    case P9_PBA_BAR0:
-        return PNV9_HOMER_BASE(chip);
-    case P8_PBA_BAR0:
-        return PNV_HOMER_BASE(chip);
-
-    case P9_PBA_BARMASK0: /* P9 homer region size */
-        return PNV9_HOMER_SIZE;
-    case P8_PBA_BARMASK0: /* P8 homer region size */
-        return PNV_HOMER_SIZE;
-
-    case P9_PBA_BAR2: /* P9 occ common area */
-        return PNV9_OCC_COMMON_AREA(chip);
-    case P8_PBA_BAR2: /* P8 occ common area */
-        return PNV_OCC_COMMON_AREA(chip);
-
-    case P9_PBA_BARMASK2: /* P9 occ common area size */
-        return PNV9_OCC_COMMON_AREA_SIZE;
-    case P8_PBA_BARMASK2: /* P8 occ common area size */
-        return PNV_OCC_COMMON_AREA_SIZE;
-
     case 0x1010c00:     /* PIBAM FIR */
     case 0x1010c03:     /* PIBAM FIR MASK */
 
@@ -130,9 +100,7 @@ static uint64_t xscom_read_default(PnvChip *chip, uint32_t pcba)
     case 0x202000f:     /* ADU stuff, receive status register*/
         return 0;
     case 0x2013f01:     /* PBA stuff */
-    case 0x2013f03:     /* PBA stuff */
     case 0x2013f05:     /* PBA stuff */
-    case 0x2013f07:     /* PBA stuff */
         return 0;
     case 0x2013028:     /* CAPP stuff */
     case 0x201302a:     /* CAPP stuff */
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 56d1161515..301c7e62fa 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -244,12 +244,10 @@ IPMIBmc *pnv_bmc_create(void);
 #define PNV_XSCOM_BASE(chip)                                            \
     (0x0003fc0000000000ull + ((uint64_t)(chip)->chip_id) * PNV_XSCOM_SIZE)
 
-#define PNV_OCC_COMMON_AREA_SIZE    0x0000000000700000ull
-#define PNV_OCC_COMMON_AREA(chip)                                       \
-    (0x7fff800000ull + ((uint64_t)PNV_CHIP_INDEX(chip) * \
-                         PNV_OCC_COMMON_AREA_SIZE))
+#define PNV_OCC_COMMON_AREA_SIZE    0x0000000000800000ull
+#define PNV_OCC_COMMON_AREA_BASE    0x7fff800000ull
 
-#define PNV_HOMER_SIZE              0x0000000000300000ull
+#define PNV_HOMER_SIZE              0x0000000000400000ull
 #define PNV_HOMER_BASE(chip)                                            \
     (0x7ffd800000ull + ((uint64_t)PNV_CHIP_INDEX(chip)) * PNV_HOMER_SIZE)
 
@@ -312,12 +310,10 @@ IPMIBmc *pnv_bmc_create(void);
 #define PNV9_XSCOM_SIZE              0x0000000400000000ull
 #define PNV9_XSCOM_BASE(chip)        PNV9_CHIP_BASE(chip, 0x00603fc00000000ull)
 
-#define PNV9_OCC_COMMON_AREA_SIZE    0x0000000000700000ull
-#define PNV9_OCC_COMMON_AREA(chip)                                      \
-    (0x203fff800000ull + ((uint64_t)PNV_CHIP_INDEX(chip) * \
-                           PNV9_OCC_COMMON_AREA_SIZE))
+#define PNV9_OCC_COMMON_AREA_SIZE    0x0000000000800000ull
+#define PNV9_OCC_COMMON_AREA_BASE    0x203fff800000ull
 
-#define PNV9_HOMER_SIZE              0x0000000000300000ull
+#define PNV9_HOMER_SIZE              0x0000000000400000ull
 #define PNV9_HOMER_BASE(chip)                                           \
     (0x203ffd800000ull + ((uint64_t)PNV_CHIP_INDEX(chip)) * PNV9_HOMER_SIZE)
 
diff --git a/include/hw/ppc/pnv_homer.h b/include/hw/ppc/pnv_homer.h
index abaec43c2d..1e91c950f6 100644
--- a/include/hw/ppc/pnv_homer.h
+++ b/include/hw/ppc/pnv_homer.h
@@ -33,6 +33,7 @@ typedef struct PnvHomer {
     DeviceState parent;
 
     struct PnvChip *chip;
+    MemoryRegion pba_regs;
     MemoryRegion regs;
 } PnvHomer;
 
@@ -44,6 +45,8 @@ typedef struct PnvHomer {
 typedef struct PnvHomerClass {
     DeviceClass parent_class;
 
+    int pba_size;
+    const MemoryRegionOps *pba_ops;
     int homer_size;
     const MemoryRegionOps *homer_ops;
 
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index 5ad2735d1a..09188d74b0 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -68,6 +68,9 @@ typedef struct PnvXScomInterfaceClass {
 #define PNV_XSCOM_OCC_BASE        0x0066000
 #define PNV_XSCOM_OCC_SIZE        0x6000
 
+#define PNV_XSCOM_PBA_BASE        0x2013f00
+#define PNV_XSCOM_PBA_SIZE        0x40
+
 /*
  * Layout of the XSCOM PCB addresses (POWER 9)
  */
@@ -82,6 +85,9 @@ typedef struct PnvXScomInterfaceClass {
 #define PNV9_XSCOM_OCC_BASE       PNV_XSCOM_OCC_BASE
 #define PNV9_XSCOM_OCC_SIZE       0x8000
 
+#define PNV9_XSCOM_PBA_BASE       0x5012b00
+#define PNV9_XSCOM_PBA_SIZE       0x40
+
 #define PNV9_XSCOM_PSIHB_BASE     0x5012900
 #define PNV9_XSCOM_PSIHB_SIZE     0x100
 
-- 
2.23.0



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

* [PULL 74/88] ppc/pnv: Fix OCC common area region mapping
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (72 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 73/88] ppc/pnv: Introduce PBA registers David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 75/88] ppc: Drop useless extern annotation for functions David Gibson
                   ` (14 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Cédric Le Goater <clg@kaod.org>

The OCC common area is mapped at a unique address on the system and
each OCC is assigned a segment to expose its sensor data :

  -------------------------------------------------------------------------
  | Start (Offset from | End           | Size     |Description            |
  | BAR2 base address) |               |          |                       |
  -------------------------------------------------------------------------
  |    0x00580000      |  0x005A57FF   |150kB     |OCC 0 Sensor Data Block|
  |    0x005A5800      |  0x005CAFFF   |150kB     |OCC 1 Sensor Data Block|
  |        :           |       :       |  :       |            :          |
  |    0x00686800      |  0x006ABFFF   |150kB     |OCC 7 Sensor Data Block|
  |    0x006AC000      |  0x006FFFFF   |336kB     |Reserved               |
  -------------------------------------------------------------------------

Maximum size is 1.5MB.

We could define a "OCC common area" memory region at the machine level
and sub regions for each OCC. But it adds some extra complexity to the
models. Fix the current layout with a simpler model.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20191211082912.2625-3-clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c             |  4 ++--
 hw/ppc/pnv_occ.c         | 11 ++++-------
 include/hw/ppc/pnv.h     |  4 ++++
 include/hw/ppc/pnv_occ.h |  8 ++++++--
 4 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index af7317a86d..0be0b6b411 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1065,7 +1065,7 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
     pnv_xscom_add_subregion(chip, PNV_XSCOM_OCC_BASE, &chip8->occ.xscom_regs);
 
     /* OCC SRAM model */
-    memory_region_add_subregion(get_system_memory(), PNV_OCC_COMMON_AREA_BASE,
+    memory_region_add_subregion(get_system_memory(), PNV_OCC_SENSOR_BASE(chip),
                                 &chip8->occ.sram_regs);
 
     /* HOMER */
@@ -1278,7 +1278,7 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
     pnv_xscom_add_subregion(chip, PNV9_XSCOM_OCC_BASE, &chip9->occ.xscom_regs);
 
     /* OCC SRAM model */
-    memory_region_add_subregion(get_system_memory(), PNV9_OCC_COMMON_AREA_BASE,
+    memory_region_add_subregion(get_system_memory(), PNV9_OCC_SENSOR_BASE(chip),
                                 &chip9->occ.sram_regs);
 
     /* HOMER */
diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c
index 765c0a6ce5..924fdabc9e 100644
--- a/hw/ppc/pnv_occ.c
+++ b/hw/ppc/pnv_occ.c
@@ -167,9 +167,7 @@ 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->sram_size = PNV_OCC_COMMON_AREA_SIZE;
     poc->xscom_ops = &pnv_occ_power8_xscom_ops;
-    poc->sram_ops = &pnv_occ_sram_ops;
     poc->psi_irq = PSIHB_IRQ_OCC;
 }
 
@@ -240,9 +238,7 @@ 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->sram_size = PNV9_OCC_COMMON_AREA_SIZE;
     poc->xscom_ops = &pnv_occ_power9_xscom_ops;
-    poc->sram_ops = &pnv_occ_sram_ops;
     poc->psi_irq = PSIHB9_IRQ_OCC;
 }
 
@@ -266,9 +262,10 @@ static void pnv_occ_realize(DeviceState *dev, Error **errp)
     pnv_xscom_region_init(&occ->xscom_regs, OBJECT(dev), poc->xscom_ops,
                           occ, "xscom-occ", poc->xscom_size);
 
-    /* XScom region for OCC SRAM registers */
-    pnv_xscom_region_init(&occ->sram_regs, OBJECT(dev), poc->sram_ops,
-                          occ, "occ-common-area", poc->sram_size);
+    /* OCC common area mmio region for OCC SRAM registers */
+    memory_region_init_io(&occ->sram_regs, OBJECT(dev), &pnv_occ_sram_ops,
+                          occ, "occ-common-area",
+                          PNV_OCC_SENSOR_DATA_BLOCK_SIZE);
 }
 
 static Property pnv_occ_properties[] = {
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 301c7e62fa..92f80b1cce 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -246,6 +246,8 @@ IPMIBmc *pnv_bmc_create(void);
 
 #define PNV_OCC_COMMON_AREA_SIZE    0x0000000000800000ull
 #define PNV_OCC_COMMON_AREA_BASE    0x7fff800000ull
+#define PNV_OCC_SENSOR_BASE(chip)   (PNV_OCC_COMMON_AREA_BASE + \
+    PNV_OCC_SENSOR_DATA_BLOCK_BASE(PNV_CHIP_INDEX(chip)))
 
 #define PNV_HOMER_SIZE              0x0000000000400000ull
 #define PNV_HOMER_BASE(chip)                                            \
@@ -312,6 +314,8 @@ IPMIBmc *pnv_bmc_create(void);
 
 #define PNV9_OCC_COMMON_AREA_SIZE    0x0000000000800000ull
 #define PNV9_OCC_COMMON_AREA_BASE    0x203fff800000ull
+#define PNV9_OCC_SENSOR_BASE(chip)   (PNV9_OCC_COMMON_AREA_BASE +       \
+    PNV_OCC_SENSOR_DATA_BLOCK_BASE(PNV_CHIP_INDEX(chip)))
 
 #define PNV9_HOMER_SIZE              0x0000000000400000ull
 #define PNV9_HOMER_BASE(chip)                                           \
diff --git a/include/hw/ppc/pnv_occ.h b/include/hw/ppc/pnv_occ.h
index 66b0989be6..f8d3061419 100644
--- a/include/hw/ppc/pnv_occ.h
+++ b/include/hw/ppc/pnv_occ.h
@@ -29,6 +29,9 @@
 #define TYPE_PNV9_OCC TYPE_PNV_OCC "-POWER9"
 #define PNV9_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV9_OCC)
 
+#define PNV_OCC_SENSOR_DATA_BLOCK_OFFSET 0x00580000
+#define PNV_OCC_SENSOR_DATA_BLOCK_SIZE   0x00025800
+
 typedef struct PnvOCC {
     DeviceState xd;
 
@@ -50,10 +53,11 @@ typedef struct PnvOCCClass {
     DeviceClass parent_class;
 
     int xscom_size;
-    int sram_size;
     const MemoryRegionOps *xscom_ops;
-    const MemoryRegionOps *sram_ops;
     int psi_irq;
 } PnvOCCClass;
 
+#define PNV_OCC_SENSOR_DATA_BLOCK_BASE(i)                               \
+    (PNV_OCC_SENSOR_DATA_BLOCK_OFFSET + (i) * PNV_OCC_SENSOR_DATA_BLOCK_SIZE)
+
 #endif /* PPC_PNV_OCC_H */
-- 
2.23.0



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

* [PULL 75/88] ppc: Drop useless extern annotation for functions
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (73 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 74/88] ppc/pnv: Fix OCC common area region mapping David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 76/88] ppc/pnv: Introduce PnvPsiClass::compat David Gibson
                   ` (13 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg,
	Philippe Mathieu-Daudé,
	David Gibson

From: Greg Kurz <groug@kaod.org>

Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <157623837421.360005.412120366652768311.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 include/hw/ppc/pnv_xscom.h | 22 +++++++++++-----------
 include/hw/ppc/spapr_vio.h |  6 +++---
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index 09188d74b0..2bdb7ae84f 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -113,16 +113,16 @@ typedef struct PnvXScomInterfaceClass {
 #define PNV10_XSCOM_PSIHB_BASE     0x3011D00
 #define PNV10_XSCOM_PSIHB_SIZE     0x100
 
-extern void pnv_xscom_realize(PnvChip *chip, uint64_t size, Error **errp);
-extern int pnv_dt_xscom(PnvChip *chip, void *fdt, int offset);
-
-extern void pnv_xscom_add_subregion(PnvChip *chip, hwaddr offset,
-                                    MemoryRegion *mr);
-extern void pnv_xscom_region_init(MemoryRegion *mr,
-                                  struct Object *owner,
-                                  const MemoryRegionOps *ops,
-                                  void *opaque,
-                                  const char *name,
-                                  uint64_t size);
+void pnv_xscom_realize(PnvChip *chip, uint64_t size, Error **errp);
+int pnv_dt_xscom(PnvChip *chip, void *fdt, int offset);
+
+void pnv_xscom_add_subregion(PnvChip *chip, hwaddr offset,
+                             MemoryRegion *mr);
+void pnv_xscom_region_init(MemoryRegion *mr,
+                           struct Object *owner,
+                           const MemoryRegionOps *ops,
+                           void *opaque,
+                           const char *name,
+                           uint64_t size);
 
 #endif /* PPC_PNV_XSCOM_H */
diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index 72762ed16b..ce6d9b0c66 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -80,10 +80,10 @@ struct SpaprVioBus {
     uint32_t next_reg;
 };
 
-extern SpaprVioBus *spapr_vio_bus_init(void);
-extern SpaprVioDevice *spapr_vio_find_by_reg(SpaprVioBus *bus, uint32_t reg);
+SpaprVioBus *spapr_vio_bus_init(void);
+SpaprVioDevice *spapr_vio_find_by_reg(SpaprVioBus *bus, uint32_t reg);
 void spapr_dt_vdevice(SpaprVioBus *bus, void *fdt);
-extern gchar *spapr_vio_stdout_path(SpaprVioBus *bus);
+gchar *spapr_vio_stdout_path(SpaprVioBus *bus);
 
 static inline void spapr_vio_irq_pulse(SpaprVioDevice *dev)
 {
-- 
2.23.0



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

* [PULL 76/88] ppc/pnv: Introduce PnvPsiClass::compat
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (74 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 75/88] ppc: Drop useless extern annotation for functions David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 77/88] ppc/pnv: Drop PnvPsiClass::chip_type David Gibson
                   ` (12 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The Processor Service Interface (PSI) model has a chip_type class level
attribute, which is used to generate the content of the "compatible" DT
property according to the CPU type.

Since the PSI model already has specialized classes for each supported
CPU type, it seems cleaner to achieve this with QOM. Provide the content
of the "compatible" property with a new class level attribute.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157623837974.360005.14706607446188964477.stgit@bahia.lan>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv_psi.c         | 25 +++++++++++--------------
 include/hw/ppc/pnv_psi.h |  2 ++
 2 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
index 572924388b..98a82b25e0 100644
--- a/hw/ppc/pnv_psi.c
+++ b/hw/ppc/pnv_psi.c
@@ -536,10 +536,6 @@ static void pnv_psi_power8_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 const char compat_p9[] = "ibm,power9-psihb-x\0ibm,psihb-x";
-static const char compat_p10[] = "ibm,power10-psihb-x\0ibm,psihb-x";
-
 static int pnv_psi_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
 {
     PnvPsiClass *ppc = PNV_PSI_GET_CLASS(dev);
@@ -558,16 +554,8 @@ static int pnv_psi_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
     _FDT(fdt_setprop(fdt, offset, "reg", reg, sizeof(reg)));
     _FDT(fdt_setprop_cell(fdt, offset, "#address-cells", 2));
     _FDT(fdt_setprop_cell(fdt, offset, "#size-cells", 1));
-    if (ppc->chip_type == PNV_CHIP_POWER10) {
-        _FDT(fdt_setprop(fdt, offset, "compatible", compat_p10,
-                         sizeof(compat_p10)));
-    } else if (ppc->chip_type == PNV_CHIP_POWER9) {
-        _FDT(fdt_setprop(fdt, offset, "compatible", compat_p9,
-                         sizeof(compat_p9)));
-    } else {
-        _FDT(fdt_setprop(fdt, offset, "compatible", compat_p8,
-                         sizeof(compat_p8)));
-    }
+    _FDT(fdt_setprop(fdt, offset, "compatible", ppc->compat,
+                     ppc->compat_size));
     return 0;
 }
 
@@ -581,6 +569,7 @@ static void pnv_psi_power8_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     PnvPsiClass *ppc = PNV_PSI_CLASS(klass);
+    static const char compat[] = "ibm,power8-psihb-x\0ibm,psihb-x";
 
     dc->desc    = "PowerNV PSI Controller POWER8";
     dc->realize = pnv_psi_power8_realize;
@@ -590,6 +579,8 @@ static void pnv_psi_power8_class_init(ObjectClass *klass, void *data)
     ppc->xscom_size = PNV_XSCOM_PSIHB_SIZE;
     ppc->bar_mask   = PSIHB_BAR_MASK;
     ppc->irq_set    = pnv_psi_power8_irq_set;
+    ppc->compat     = compat;
+    ppc->compat_size = sizeof(compat);
 }
 
 static const TypeInfo pnv_psi_power8_info = {
@@ -888,6 +879,7 @@ 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);
+    static const char compat[] = "ibm,power9-psihb-x\0ibm,psihb-x";
 
     dc->desc    = "PowerNV PSI Controller POWER9";
     dc->realize = pnv_psi_power9_realize;
@@ -897,6 +889,8 @@ static void pnv_psi_power9_class_init(ObjectClass *klass, void *data)
     ppc->xscom_size = PNV9_XSCOM_PSIHB_SIZE;
     ppc->bar_mask   = PSIHB9_BAR_MASK;
     ppc->irq_set    = pnv_psi_power9_irq_set;
+    ppc->compat     = compat;
+    ppc->compat_size = sizeof(compat);
 
     xfc->notify      = pnv_psi_notify;
 }
@@ -917,12 +911,15 @@ static void pnv_psi_power10_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     PnvPsiClass *ppc = PNV_PSI_CLASS(klass);
+    static const char compat[] = "ibm,power10-psihb-x\0ibm,psihb-x";
 
     dc->desc    = "PowerNV PSI Controller POWER10";
 
     ppc->chip_type  = PNV_CHIP_POWER10;
     ppc->xscom_pcba = PNV10_XSCOM_PSIHB_BASE;
     ppc->xscom_size = PNV10_XSCOM_PSIHB_SIZE;
+    ppc->compat     = compat;
+    ppc->compat_size = sizeof(compat);
 }
 
 static const TypeInfo pnv_psi_power10_info = {
diff --git a/include/hw/ppc/pnv_psi.h b/include/hw/ppc/pnv_psi.h
index a044aab304..fc068c95e5 100644
--- a/include/hw/ppc/pnv_psi.h
+++ b/include/hw/ppc/pnv_psi.h
@@ -83,6 +83,8 @@ typedef struct PnvPsiClass {
     uint32_t xscom_pcba;
     uint32_t xscom_size;
     uint64_t bar_mask;
+    const char *compat;
+    int compat_size;
 
     void (*irq_set)(PnvPsi *psi, int, bool state);
 } PnvPsiClass;
-- 
2.23.0



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

* [PULL 77/88] ppc/pnv: Drop PnvPsiClass::chip_type
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (75 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 76/88] ppc/pnv: Introduce PnvPsiClass::compat David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 78/88] ppc/pnv: Introduce PnvMachineClass and PnvMachineClass::compat David Gibson
                   ` (11 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

It isn't used anymore.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157623838530.360005.15470128760871845396.stgit@bahia.lan>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv_psi.c         | 3 ---
 include/hw/ppc/pnv_psi.h | 1 -
 2 files changed, 4 deletions(-)

diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
index 98a82b25e0..75e20d9da0 100644
--- a/hw/ppc/pnv_psi.c
+++ b/hw/ppc/pnv_psi.c
@@ -574,7 +574,6 @@ static void pnv_psi_power8_class_init(ObjectClass *klass, void *data)
     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;
@@ -884,7 +883,6 @@ static void pnv_psi_power9_class_init(ObjectClass *klass, void *data)
     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;
@@ -915,7 +913,6 @@ static void pnv_psi_power10_class_init(ObjectClass *klass, void *data)
 
     dc->desc    = "PowerNV PSI Controller POWER10";
 
-    ppc->chip_type  = PNV_CHIP_POWER10;
     ppc->xscom_pcba = PNV10_XSCOM_PSIHB_BASE;
     ppc->xscom_size = PNV10_XSCOM_PSIHB_SIZE;
     ppc->compat     = compat;
diff --git a/include/hw/ppc/pnv_psi.h b/include/hw/ppc/pnv_psi.h
index fc068c95e5..f0f5b55197 100644
--- a/include/hw/ppc/pnv_psi.h
+++ b/include/hw/ppc/pnv_psi.h
@@ -79,7 +79,6 @@ typedef struct Pnv9Psi {
 typedef struct PnvPsiClass {
     SysBusDeviceClass parent_class;
 
-    int chip_type;
     uint32_t xscom_pcba;
     uint32_t xscom_size;
     uint64_t bar_mask;
-- 
2.23.0



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

* [PULL 78/88] ppc/pnv: Introduce PnvMachineClass and PnvMachineClass::compat
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (76 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 77/88] ppc/pnv: Drop PnvPsiClass::chip_type David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 79/88] ppc/pnv: Introduce PnvMachineClass::dt_power_mgt() David Gibson
                   ` (10 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The pnv_dt_create() function generates different contents for the
"compatible" property of the root node in the DT, depending on the
CPU type. This is open coded with multiple ifs using pnv_is_powerXX()
helpers.

It seems cleaner to achieve with QOM. Introduce a base class for the
powernv machine and a compat attribute that each child class can use
to provide the value for the "compatible" property.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157623839085.360005.4046508784077843216.stgit@bahia.lan>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
[dwg: Folded in small fix Greg spotted after posting]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c         | 32 ++++++++++++++++++--------------
 include/hw/ppc/pnv.h | 13 +++++++++++++
 2 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 0be0b6b411..97845e7bde 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -484,9 +484,7 @@ static void pnv_dt_power_mgt(void *fdt)
 
 static void *pnv_dt_create(MachineState *machine)
 {
-    const char plat_compat8[] = "qemu,powernv8\0qemu,powernv\0ibm,powernv";
-    const char plat_compat9[] = "qemu,powernv9\0ibm,powernv";
-    const char plat_compat10[] = "qemu,powernv10\0ibm,powernv";
+    PnvMachineClass *pmc = PNV_MACHINE_GET_CLASS(machine);
     PnvMachineState *pnv = PNV_MACHINE(machine);
     void *fdt;
     char *buf;
@@ -504,17 +502,7 @@ static void *pnv_dt_create(MachineState *machine)
     _FDT((fdt_setprop_cell(fdt, 0, "#size-cells", 0x2)));
     _FDT((fdt_setprop_string(fdt, 0, "model",
                              "IBM PowerNV (emulated by qemu)")));
-    if (pnv_is_power10(pnv)) {
-        _FDT((fdt_setprop(fdt, 0, "compatible", plat_compat10,
-                          sizeof(plat_compat10))));
-    } else if (pnv_is_power9(pnv)) {
-        _FDT((fdt_setprop(fdt, 0, "compatible", plat_compat9,
-                          sizeof(plat_compat9))));
-    } else {
-        _FDT((fdt_setprop(fdt, 0, "compatible", plat_compat8,
-                          sizeof(plat_compat8))));
-    }
-
+    _FDT((fdt_setprop(fdt, 0, "compatible", pmc->compat, pmc->compat_size)));
 
     buf =  qemu_uuid_unparse_strdup(&qemu_uuid);
     _FDT((fdt_setprop_string(fdt, 0, "vm,uuid", buf)));
@@ -1692,6 +1680,8 @@ static void pnv_machine_power8_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
     XICSFabricClass *xic = XICS_FABRIC_CLASS(oc);
+    PnvMachineClass *pmc = PNV_MACHINE_CLASS(oc);
+    static const char compat[] = "qemu,powernv8\0qemu,powernv\0ibm,powernv";
 
     mc->desc = "IBM PowerNV (Non-Virtualized) POWER8";
     mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");
@@ -1699,26 +1689,39 @@ static void pnv_machine_power8_class_init(ObjectClass *oc, void *data)
     xic->icp_get = pnv_icp_get;
     xic->ics_get = pnv_ics_get;
     xic->ics_resend = pnv_ics_resend;
+
+    pmc->compat = compat;
+    pmc->compat_size = sizeof(compat);
 }
 
 static void pnv_machine_power9_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
     XiveFabricClass *xfc = XIVE_FABRIC_CLASS(oc);
+    PnvMachineClass *pmc = PNV_MACHINE_CLASS(oc);
+    static const char compat[] = "qemu,powernv9\0ibm,powernv";
 
     mc->desc = "IBM PowerNV (Non-Virtualized) POWER9";
     mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power9_v2.0");
     xfc->match_nvt = pnv_match_nvt;
 
     mc->alias = "powernv";
+
+    pmc->compat = compat;
+    pmc->compat_size = sizeof(compat);
 }
 
 static void pnv_machine_power10_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
+    PnvMachineClass *pmc = PNV_MACHINE_CLASS(oc);
+    static const char compat[] = "qemu,powernv10\0ibm,powernv";
 
     mc->desc = "IBM PowerNV (Non-Virtualized) POWER10";
     mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power10_v1.0");
+
+    pmc->compat = compat;
+    pmc->compat_size = sizeof(compat);
 }
 
 static void pnv_machine_class_init(ObjectClass *oc, void *data)
@@ -1796,6 +1799,7 @@ static const TypeInfo types[] = {
         .instance_size = sizeof(PnvMachineState),
         .instance_init = pnv_machine_instance_init,
         .class_init    = pnv_machine_class_init,
+        .class_size    = sizeof(PnvMachineClass),
         .interfaces = (InterfaceInfo[]) {
             { TYPE_INTERRUPT_STATS_PROVIDER },
             { },
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 92f80b1cce..d534746bd4 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -185,6 +185,19 @@ PowerPCCPU *pnv_chip_find_cpu(PnvChip *chip, uint32_t pir);
 #define TYPE_PNV_MACHINE       MACHINE_TYPE_NAME("powernv")
 #define PNV_MACHINE(obj) \
     OBJECT_CHECK(PnvMachineState, (obj), TYPE_PNV_MACHINE)
+#define PNV_MACHINE_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(PnvMachineClass, obj, TYPE_PNV_MACHINE)
+#define PNV_MACHINE_CLASS(klass) \
+    OBJECT_CLASS_CHECK(PnvMachineClass, klass, TYPE_PNV_MACHINE)
+
+typedef struct PnvMachineClass {
+    /*< private >*/
+    MachineClass parent_class;
+
+    /*< public >*/
+    const char *compat;
+    int compat_size;
+} PnvMachineClass;
 
 typedef struct PnvMachineState {
     /*< private >*/
-- 
2.23.0



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

* [PULL 79/88] ppc/pnv: Introduce PnvMachineClass::dt_power_mgt()
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (77 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 78/88] ppc/pnv: Introduce PnvMachineClass and PnvMachineClass::compat David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 80/88] ppc/pnv: Drop pnv_is_power9() and pnv_is_power10() helpers David Gibson
                   ` (9 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

We add an extra node to advertise power management on some machines,
namely powernv9 and powernv10. This is achieved by using the
pnv_is_power9() and pnv_is_power10() helpers.

This can be achieved with QOM. Add a method to the base class for
powernv machines and have it implemented by machine types that
support power management instead.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157623839642.360005.9243510140436689941.stgit@bahia.lan>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c         | 10 ++++++----
 include/hw/ppc/pnv.h |  8 ++++++--
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 97845e7bde..a2ad7258f8 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -472,7 +472,7 @@ static void pnv_dt_isa(PnvMachineState *pnv, void *fdt)
                        &args);
 }
 
-static void pnv_dt_power_mgt(void *fdt)
+static void pnv_dt_power_mgt(PnvMachineState *pnv, void *fdt)
 {
     int off;
 
@@ -539,9 +539,9 @@ static void *pnv_dt_create(MachineState *machine)
         pnv_dt_bmc_sensors(pnv->bmc, fdt);
     }
 
-    /* Create an extra node for power management on Power9 and Power10 */
-    if (pnv_is_power9(pnv) || pnv_is_power10(pnv)) {
-        pnv_dt_power_mgt(fdt);
+    /* Create an extra node for power management on machines that support it */
+    if (pmc->dt_power_mgt) {
+        pmc->dt_power_mgt(pnv, fdt);
     }
 
     return fdt;
@@ -1709,6 +1709,7 @@ static void pnv_machine_power9_class_init(ObjectClass *oc, void *data)
 
     pmc->compat = compat;
     pmc->compat_size = sizeof(compat);
+    pmc->dt_power_mgt = pnv_dt_power_mgt;
 }
 
 static void pnv_machine_power10_class_init(ObjectClass *oc, void *data)
@@ -1722,6 +1723,7 @@ static void pnv_machine_power10_class_init(ObjectClass *oc, void *data)
 
     pmc->compat = compat;
     pmc->compat_size = sizeof(compat);
+    pmc->dt_power_mgt = pnv_dt_power_mgt;
 }
 
 static void pnv_machine_class_init(ObjectClass *oc, void *data)
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index d534746bd4..8a42c199b6 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -190,6 +190,8 @@ PowerPCCPU *pnv_chip_find_cpu(PnvChip *chip, uint32_t pir);
 #define PNV_MACHINE_CLASS(klass) \
     OBJECT_CLASS_CHECK(PnvMachineClass, klass, TYPE_PNV_MACHINE)
 
+typedef struct PnvMachineState PnvMachineState;
+
 typedef struct PnvMachineClass {
     /*< private >*/
     MachineClass parent_class;
@@ -197,9 +199,11 @@ typedef struct PnvMachineClass {
     /*< public >*/
     const char *compat;
     int compat_size;
+
+    void (*dt_power_mgt)(PnvMachineState *pnv, void *fdt);
 } PnvMachineClass;
 
-typedef struct PnvMachineState {
+struct PnvMachineState {
     /*< private >*/
     MachineState parent_obj;
 
@@ -216,7 +220,7 @@ typedef struct PnvMachineState {
     Notifier     powerdown_notifier;
 
     PnvPnor      *pnor;
-} PnvMachineState;
+};
 
 static inline bool pnv_chip_is_power9(const PnvChip *chip)
 {
-- 
2.23.0



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

* [PULL 80/88] ppc/pnv: Drop pnv_is_power9() and pnv_is_power10() helpers
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (78 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 79/88] ppc/pnv: Introduce PnvMachineClass::dt_power_mgt() David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 81/88] ppc/pnv: Introduce PnvChipClass::intc_print_info() method David Gibson
                   ` (8 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

They aren't used anymore.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157623840200.360005.1300941274565357363.stgit@bahia.lan>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 include/hw/ppc/pnv.h | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 8a42c199b6..c213bdd5ec 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -227,11 +227,6 @@ static inline bool pnv_chip_is_power9(const PnvChip *chip)
     return PNV_CHIP_GET_CLASS(chip)->chip_type == PNV_CHIP_POWER9;
 }
 
-static inline bool pnv_is_power9(PnvMachineState *pnv)
-{
-    return pnv_chip_is_power9(pnv->chips[0]);
-}
-
 PnvChip *pnv_get_chip(uint32_t chip_id);
 
 #define PNV_FDT_ADDR          0x01000000
@@ -242,11 +237,6 @@ static inline bool pnv_chip_is_power10(const PnvChip *chip)
     return PNV_CHIP_GET_CLASS(chip)->chip_type == PNV_CHIP_POWER10;
 }
 
-static inline bool pnv_is_power10(PnvMachineState *pnv)
-{
-    return pnv_chip_is_power10(pnv->chips[0]);
-}
-
 /*
  * BMC helpers
  */
-- 
2.23.0



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

* [PULL 81/88] ppc/pnv: Introduce PnvChipClass::intc_print_info() method
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (79 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 80/88] ppc/pnv: Drop pnv_is_power9() and pnv_is_power10() helpers David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 82/88] ppc/pnv: Introduce PnvChipClass::xscom_core_base() method David Gibson
                   ` (7 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The pnv_pic_print_info() callback checks the type of the chip in order
to forward to the request appropriate interrupt controller. This can
be achieved with QOM. Introduce a method for this in the base chip class
and implement it in child classes.

This also prepares ground for the upcoming interrupt controller of POWER10
chips.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157623840755.360005.5002022339473369934.stgit@bahia.lan>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c         | 30 +++++++++++++++++++++++++-----
 include/hw/ppc/pnv.h |  1 +
 2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index a2ad7258f8..35416d1b3f 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -831,6 +831,12 @@ static void pnv_chip_power8_intc_destroy(PnvChip *chip, PowerPCCPU *cpu)
     pnv_cpu->intc = NULL;
 }
 
+static void pnv_chip_power8_intc_print_info(PnvChip *chip, PowerPCCPU *cpu,
+                                            Monitor *mon)
+{
+    icp_pic_print_info(ICP(pnv_cpu_state(cpu)->intc), mon);
+}
+
 /*
  *    0:48  Reserved - Read as zeroes
  *   49:52  Node ID
@@ -888,6 +894,12 @@ static void pnv_chip_power9_intc_destroy(PnvChip *chip, PowerPCCPU *cpu)
     pnv_cpu->intc = NULL;
 }
 
+static void pnv_chip_power9_intc_print_info(PnvChip *chip, PowerPCCPU *cpu,
+                                            Monitor *mon)
+{
+    xive_tctx_pic_print_info(XIVE_TCTX(pnv_cpu_state(cpu)->intc), mon);
+}
+
 static void pnv_chip_power10_intc_create(PnvChip *chip, PowerPCCPU *cpu,
                                         Error **errp)
 {
@@ -909,6 +921,11 @@ static void pnv_chip_power10_intc_destroy(PnvChip *chip, PowerPCCPU *cpu)
     pnv_cpu->intc = NULL;
 }
 
+static void pnv_chip_power10_intc_print_info(PnvChip *chip, PowerPCCPU *cpu,
+                                             Monitor *mon)
+{
+}
+
 /*
  * Allowed core identifiers on a POWER8 Processor Chip :
  *
@@ -1085,6 +1102,7 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
     k->intc_create = pnv_chip_power8_intc_create;
     k->intc_reset = pnv_chip_power8_intc_reset;
     k->intc_destroy = pnv_chip_power8_intc_destroy;
+    k->intc_print_info = pnv_chip_power8_intc_print_info;
     k->isa_create = pnv_chip_power8_isa_create;
     k->dt_populate = pnv_chip_power8_dt_populate;
     k->pic_print_info = pnv_chip_power8_pic_print_info;
@@ -1106,6 +1124,7 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data)
     k->intc_create = pnv_chip_power8_intc_create;
     k->intc_reset = pnv_chip_power8_intc_reset;
     k->intc_destroy = pnv_chip_power8_intc_destroy;
+    k->intc_print_info = pnv_chip_power8_intc_print_info;
     k->isa_create = pnv_chip_power8_isa_create;
     k->dt_populate = pnv_chip_power8_dt_populate;
     k->pic_print_info = pnv_chip_power8_pic_print_info;
@@ -1127,6 +1146,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data)
     k->intc_create = pnv_chip_power8_intc_create;
     k->intc_reset = pnv_chip_power8_intc_reset;
     k->intc_destroy = pnv_chip_power8_intc_destroy;
+    k->intc_print_info = pnv_chip_power8_intc_print_info;
     k->isa_create = pnv_chip_power8nvl_isa_create;
     k->dt_populate = pnv_chip_power8_dt_populate;
     k->pic_print_info = pnv_chip_power8_pic_print_info;
@@ -1298,6 +1318,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
     k->intc_create = pnv_chip_power9_intc_create;
     k->intc_reset = pnv_chip_power9_intc_reset;
     k->intc_destroy = pnv_chip_power9_intc_destroy;
+    k->intc_print_info = pnv_chip_power9_intc_print_info;
     k->isa_create = pnv_chip_power9_isa_create;
     k->dt_populate = pnv_chip_power9_dt_populate;
     k->pic_print_info = pnv_chip_power9_pic_print_info;
@@ -1378,6 +1399,7 @@ static void pnv_chip_power10_class_init(ObjectClass *klass, void *data)
     k->intc_create = pnv_chip_power10_intc_create;
     k->intc_reset = pnv_chip_power10_intc_reset;
     k->intc_destroy = pnv_chip_power10_intc_destroy;
+    k->intc_print_info = pnv_chip_power10_intc_print_info;
     k->isa_create = pnv_chip_power10_isa_create;
     k->dt_populate = pnv_chip_power10_dt_populate;
     k->pic_print_info = pnv_chip_power10_pic_print_info;
@@ -1574,11 +1596,9 @@ static void pnv_pic_print_info(InterruptStatsProvider *obj,
     CPU_FOREACH(cs) {
         PowerPCCPU *cpu = POWERPC_CPU(cs);
 
-        if (pnv_chip_is_power9(pnv->chips[0])) {
-            xive_tctx_pic_print_info(XIVE_TCTX(pnv_cpu_state(cpu)->intc), mon);
-        } else {
-            icp_pic_print_info(ICP(pnv_cpu_state(cpu)->intc), mon);
-        }
+        /* XXX: loop on each chip/core/thread instead of CPU_FOREACH() */
+        PNV_CHIP_GET_CLASS(pnv->chips[0])->intc_print_info(pnv->chips[0], cpu,
+                                                           mon);
     }
 
     for (i = 0; i < pnv->num_chips; i++) {
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index c213bdd5ec..7d2402784d 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -133,6 +133,7 @@ typedef struct PnvChipClass {
     void (*intc_create)(PnvChip *chip, PowerPCCPU *cpu, Error **errp);
     void (*intc_reset)(PnvChip *chip, PowerPCCPU *cpu);
     void (*intc_destroy)(PnvChip *chip, PowerPCCPU *cpu);
+    void (*intc_print_info)(PnvChip *chip, PowerPCCPU *cpu, Monitor *mon);
     ISABus *(*isa_create)(PnvChip *chip, Error **errp);
     void (*dt_populate)(PnvChip *chip, void *fdt);
     void (*pic_print_info)(PnvChip *chip, Monitor *mon);
-- 
2.23.0



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

* [PULL 82/88] ppc/pnv: Introduce PnvChipClass::xscom_core_base() method
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (80 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 81/88] ppc/pnv: Introduce PnvChipClass::intc_print_info() method David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 83/88] ppc/pnv: Pass XSCOM base address and address size to pnv_dt_xscom() David Gibson
                   ` (6 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The pnv_chip_core_realize() function configures the XSCOM MMIO subregion
for each core of a single chip. The base address of the subregion depends
on the CPU type. Its computation is currently open-code using the
pnv_chip_is_powerXX() helpers. This can be achieved with QOM. Introduce
a method for this in the base chip class and implement it in child classes.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157623841311.360005.4705705734873339545.stgit@bahia.lan>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c         | 31 ++++++++++++++++++++++++-------
 include/hw/ppc/pnv.h |  1 +
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 35416d1b3f..16f4e407ee 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -615,6 +615,24 @@ static void pnv_chip_power9_pic_print_info(PnvChip *chip, Monitor *mon)
     pnv_psi_pic_print_info(&chip9->psi, mon);
 }
 
+static uint64_t pnv_chip_power8_xscom_core_base(PnvChip *chip,
+                                                uint32_t core_id)
+{
+    return PNV_XSCOM_EX_BASE(core_id);
+}
+
+static uint64_t pnv_chip_power9_xscom_core_base(PnvChip *chip,
+                                                uint32_t core_id)
+{
+    return PNV9_XSCOM_EC_BASE(core_id);
+}
+
+static uint64_t pnv_chip_power10_xscom_core_base(PnvChip *chip,
+                                                 uint32_t core_id)
+{
+    return PNV10_XSCOM_EC_BASE(core_id);
+}
+
 static bool pnv_match_cpu(const char *default_type, const char *cpu_type)
 {
     PowerPCCPUClass *ppc_default =
@@ -1106,6 +1124,7 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
     k->isa_create = pnv_chip_power8_isa_create;
     k->dt_populate = pnv_chip_power8_dt_populate;
     k->pic_print_info = pnv_chip_power8_pic_print_info;
+    k->xscom_core_base = pnv_chip_power8_xscom_core_base;
     dc->desc = "PowerNV Chip POWER8E";
 
     device_class_set_parent_realize(dc, pnv_chip_power8_realize,
@@ -1128,6 +1147,7 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data)
     k->isa_create = pnv_chip_power8_isa_create;
     k->dt_populate = pnv_chip_power8_dt_populate;
     k->pic_print_info = pnv_chip_power8_pic_print_info;
+    k->xscom_core_base = pnv_chip_power8_xscom_core_base;
     dc->desc = "PowerNV Chip POWER8";
 
     device_class_set_parent_realize(dc, pnv_chip_power8_realize,
@@ -1150,6 +1170,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data)
     k->isa_create = pnv_chip_power8nvl_isa_create;
     k->dt_populate = pnv_chip_power8_dt_populate;
     k->pic_print_info = pnv_chip_power8_pic_print_info;
+    k->xscom_core_base = pnv_chip_power8_xscom_core_base;
     dc->desc = "PowerNV Chip POWER8NVL";
 
     device_class_set_parent_realize(dc, pnv_chip_power8_realize,
@@ -1322,6 +1343,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
     k->isa_create = pnv_chip_power9_isa_create;
     k->dt_populate = pnv_chip_power9_dt_populate;
     k->pic_print_info = pnv_chip_power9_pic_print_info;
+    k->xscom_core_base = pnv_chip_power9_xscom_core_base;
     dc->desc = "PowerNV Chip POWER9";
 
     device_class_set_parent_realize(dc, pnv_chip_power9_realize,
@@ -1403,6 +1425,7 @@ static void pnv_chip_power10_class_init(ObjectClass *klass, void *data)
     k->isa_create = pnv_chip_power10_isa_create;
     k->dt_populate = pnv_chip_power10_dt_populate;
     k->pic_print_info = pnv_chip_power10_pic_print_info;
+    k->xscom_core_base = pnv_chip_power10_xscom_core_base;
     dc->desc = "PowerNV Chip POWER10";
 
     device_class_set_parent_realize(dc, pnv_chip_power10_realize,
@@ -1490,13 +1513,7 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
                                  &error_fatal);
 
         /* Each core has an XSCOM MMIO region */
-        if (pnv_chip_is_power10(chip)) {
-            xscom_core_base = PNV10_XSCOM_EC_BASE(core_hwid);
-        } else if (pnv_chip_is_power9(chip)) {
-            xscom_core_base = PNV9_XSCOM_EC_BASE(core_hwid);
-        } else {
-            xscom_core_base = PNV_XSCOM_EX_BASE(core_hwid);
-        }
+        xscom_core_base = pcc->xscom_core_base(chip, core_hwid);
 
         pnv_xscom_add_subregion(chip, xscom_core_base,
                                 &pnv_core->xscom_regs);
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 7d2402784d..17ca9a14ac 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -137,6 +137,7 @@ typedef struct PnvChipClass {
     ISABus *(*isa_create)(PnvChip *chip, Error **errp);
     void (*dt_populate)(PnvChip *chip, void *fdt);
     void (*pic_print_info)(PnvChip *chip, Monitor *mon);
+    uint64_t (*xscom_core_base)(PnvChip *chip, uint32_t core_id);
 } PnvChipClass;
 
 #define PNV_CHIP_TYPE_SUFFIX "-" TYPE_PNV_CHIP
-- 
2.23.0



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

* [PULL 83/88] ppc/pnv: Pass XSCOM base address and address size to pnv_dt_xscom()
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (81 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 82/88] ppc/pnv: Introduce PnvChipClass::xscom_core_base() method David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 84/88] ppc/pnv: Pass content of the "compatible" property " David Gibson
                   ` (5 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

Since pnv_dt_xscom() is called from chip specific dt_populate() hooks,
it shouldn't have to guess the chip type in order to populate the "reg"
property. Just pass the base address and address size as arguments.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157623841868.360005.17577624823547136435.stgit@bahia.lan>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c               | 12 +++++++++---
 hw/ppc/pnv_xscom.c         | 16 +++-------------
 include/hw/ppc/pnv_xscom.h |  3 ++-
 3 files changed, 14 insertions(+), 17 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 16f4e407ee..c0a5703b74 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -282,7 +282,9 @@ static void pnv_chip_power8_dt_populate(PnvChip *chip, void *fdt)
 {
     int i;
 
-    pnv_dt_xscom(chip, fdt, 0);
+    pnv_dt_xscom(chip, fdt, 0,
+                 cpu_to_be64(PNV_XSCOM_BASE(chip)),
+                 cpu_to_be64(PNV_XSCOM_SIZE));
 
     for (i = 0; i < chip->nr_cores; i++) {
         PnvCore *pnv_core = chip->cores[i];
@@ -302,7 +304,9 @@ static void pnv_chip_power9_dt_populate(PnvChip *chip, void *fdt)
 {
     int i;
 
-    pnv_dt_xscom(chip, fdt, 0);
+    pnv_dt_xscom(chip, fdt, 0,
+                 cpu_to_be64(PNV9_XSCOM_BASE(chip)),
+                 cpu_to_be64(PNV9_XSCOM_SIZE));
 
     for (i = 0; i < chip->nr_cores; i++) {
         PnvCore *pnv_core = chip->cores[i];
@@ -321,7 +325,9 @@ static void pnv_chip_power10_dt_populate(PnvChip *chip, void *fdt)
 {
     int i;
 
-    pnv_dt_xscom(chip, fdt, 0);
+    pnv_dt_xscom(chip, fdt, 0,
+                 cpu_to_be64(PNV10_XSCOM_BASE(chip)),
+                 cpu_to_be64(PNV10_XSCOM_SIZE));
 
     for (i = 0; i < chip->nr_cores; i++) {
         PnvCore *pnv_core = chip->cores[i];
diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c
index df926003f2..8189767eb0 100644
--- a/hw/ppc/pnv_xscom.c
+++ b/hw/ppc/pnv_xscom.c
@@ -286,24 +286,14 @@ static const char compat_p8[] = "ibm,power8-xscom\0ibm,xscom";
 static const char compat_p9[] = "ibm,power9-xscom\0ibm,xscom";
 static const char compat_p10[] = "ibm,power10-xscom\0ibm,xscom";
 
-int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset)
+int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset,
+                 uint64_t xscom_base, uint64_t xscom_size)
 {
-    uint64_t reg[2];
+    uint64_t reg[] = { xscom_base, xscom_size };
     int xscom_offset;
     ForeachPopulateArgs args;
     char *name;
 
-    if (pnv_chip_is_power10(chip)) {
-        reg[0] = cpu_to_be64(PNV10_XSCOM_BASE(chip));
-        reg[1] = cpu_to_be64(PNV10_XSCOM_SIZE);
-    } else if (pnv_chip_is_power9(chip)) {
-        reg[0] = cpu_to_be64(PNV9_XSCOM_BASE(chip));
-        reg[1] = cpu_to_be64(PNV9_XSCOM_SIZE);
-    } else {
-        reg[0] = cpu_to_be64(PNV_XSCOM_BASE(chip));
-        reg[1] = cpu_to_be64(PNV_XSCOM_SIZE);
-    }
-
     name = g_strdup_printf("xscom@%" PRIx64, be64_to_cpu(reg[0]));
     xscom_offset = fdt_add_subnode(fdt, root_offset, name);
     _FDT(xscom_offset);
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index 2bdb7ae84f..ad53f788b4 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -114,7 +114,8 @@ typedef struct PnvXScomInterfaceClass {
 #define PNV10_XSCOM_PSIHB_SIZE     0x100
 
 void pnv_xscom_realize(PnvChip *chip, uint64_t size, Error **errp);
-int pnv_dt_xscom(PnvChip *chip, void *fdt, int offset);
+int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset,
+                 uint64_t xscom_base, uint64_t xscom_size);
 
 void pnv_xscom_add_subregion(PnvChip *chip, hwaddr offset,
                              MemoryRegion *mr);
-- 
2.23.0



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

* [PULL 84/88] ppc/pnv: Pass content of the "compatible" property to pnv_dt_xscom()
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (82 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 83/88] ppc/pnv: Pass XSCOM base address and address size to pnv_dt_xscom() David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 85/88] ppc/pnv: Drop pnv_chip_is_power9() and pnv_chip_is_power10() helpers David Gibson
                   ` (4 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

Since pnv_dt_xscom() is called from chip specific dt_populate() hooks,
it shouldn't have to guess the chip type in order to populate the
"compatible" property. Just pass the compat string and its size as
arguments.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157623842430.360005.9513965612524265862.stgit@bahia.lan>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c               | 12 +++++++++---
 hw/ppc/pnv_xscom.c         | 20 +++-----------------
 include/hw/ppc/pnv_xscom.h |  3 ++-
 3 files changed, 14 insertions(+), 21 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index c0a5703b74..b3388038c6 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -280,11 +280,13 @@ static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t pir,
 
 static void pnv_chip_power8_dt_populate(PnvChip *chip, void *fdt)
 {
+    static const char compat[] = "ibm,power8-xscom\0ibm,xscom";
     int i;
 
     pnv_dt_xscom(chip, fdt, 0,
                  cpu_to_be64(PNV_XSCOM_BASE(chip)),
-                 cpu_to_be64(PNV_XSCOM_SIZE));
+                 cpu_to_be64(PNV_XSCOM_SIZE),
+                 compat, sizeof(compat));
 
     for (i = 0; i < chip->nr_cores; i++) {
         PnvCore *pnv_core = chip->cores[i];
@@ -302,11 +304,13 @@ static void pnv_chip_power8_dt_populate(PnvChip *chip, void *fdt)
 
 static void pnv_chip_power9_dt_populate(PnvChip *chip, void *fdt)
 {
+    static const char compat[] = "ibm,power9-xscom\0ibm,xscom";
     int i;
 
     pnv_dt_xscom(chip, fdt, 0,
                  cpu_to_be64(PNV9_XSCOM_BASE(chip)),
-                 cpu_to_be64(PNV9_XSCOM_SIZE));
+                 cpu_to_be64(PNV9_XSCOM_SIZE),
+                 compat, sizeof(compat));
 
     for (i = 0; i < chip->nr_cores; i++) {
         PnvCore *pnv_core = chip->cores[i];
@@ -323,11 +327,13 @@ static void pnv_chip_power9_dt_populate(PnvChip *chip, void *fdt)
 
 static void pnv_chip_power10_dt_populate(PnvChip *chip, void *fdt)
 {
+    static const char compat[] = "ibm,power10-xscom\0ibm,xscom";
     int i;
 
     pnv_dt_xscom(chip, fdt, 0,
                  cpu_to_be64(PNV10_XSCOM_BASE(chip)),
-                 cpu_to_be64(PNV10_XSCOM_SIZE));
+                 cpu_to_be64(PNV10_XSCOM_SIZE),
+                 compat, sizeof(compat));
 
     for (i = 0; i < chip->nr_cores; i++) {
         PnvCore *pnv_core = chip->cores[i];
diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c
index 8189767eb0..5ae9dfbb88 100644
--- a/hw/ppc/pnv_xscom.c
+++ b/hw/ppc/pnv_xscom.c
@@ -282,12 +282,9 @@ static int xscom_dt_child(Object *child, void *opaque)
     return 0;
 }
 
-static const char compat_p8[] = "ibm,power8-xscom\0ibm,xscom";
-static const char compat_p9[] = "ibm,power9-xscom\0ibm,xscom";
-static const char compat_p10[] = "ibm,power10-xscom\0ibm,xscom";
-
 int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset,
-                 uint64_t xscom_base, uint64_t xscom_size)
+                 uint64_t xscom_base, uint64_t xscom_size,
+                 const char *compat, int compat_size)
 {
     uint64_t reg[] = { xscom_base, xscom_size };
     int xscom_offset;
@@ -302,18 +299,7 @@ int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset,
     _FDT((fdt_setprop_cell(fdt, xscom_offset, "#address-cells", 1)));
     _FDT((fdt_setprop_cell(fdt, xscom_offset, "#size-cells", 1)));
     _FDT((fdt_setprop(fdt, xscom_offset, "reg", reg, sizeof(reg))));
-
-    if (pnv_chip_is_power10(chip)) {
-        _FDT((fdt_setprop(fdt, xscom_offset, "compatible", compat_p10,
-                          sizeof(compat_p10))));
-    } else if (pnv_chip_is_power9(chip)) {
-        _FDT((fdt_setprop(fdt, xscom_offset, "compatible", compat_p9,
-                          sizeof(compat_p9))));
-    } else {
-        _FDT((fdt_setprop(fdt, xscom_offset, "compatible", compat_p8,
-                          sizeof(compat_p8))));
-    }
-
+    _FDT((fdt_setprop(fdt, xscom_offset, "compatible", compat, compat_size)));
     _FDT((fdt_setprop(fdt, xscom_offset, "scom-controller", NULL, 0)));
 
     args.fdt = fdt;
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index ad53f788b4..f74c81a980 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -115,7 +115,8 @@ typedef struct PnvXScomInterfaceClass {
 
 void pnv_xscom_realize(PnvChip *chip, uint64_t size, Error **errp);
 int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset,
-                 uint64_t xscom_base, uint64_t xscom_size);
+                 uint64_t xscom_base, uint64_t xscom_size,
+                 const char *compat, int compat_size);
 
 void pnv_xscom_add_subregion(PnvChip *chip, hwaddr offset,
                              MemoryRegion *mr);
-- 
2.23.0



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

* [PULL 85/88] ppc/pnv: Drop pnv_chip_is_power9() and pnv_chip_is_power10() helpers
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (83 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 84/88] ppc/pnv: Pass content of the "compatible" property " David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 86/88] ppc/pnv: Introduce PnvChipClass::xscom_pcba() method David Gibson
                   ` (3 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

They aren't used anymore.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157623842986.360005.1787401623906380181.stgit@bahia.lan>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 include/hw/ppc/pnv.h | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 17ca9a14ac..7a134a15d3 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -224,21 +224,11 @@ struct PnvMachineState {
     PnvPnor      *pnor;
 };
 
-static inline bool pnv_chip_is_power9(const PnvChip *chip)
-{
-    return PNV_CHIP_GET_CLASS(chip)->chip_type == PNV_CHIP_POWER9;
-}
-
 PnvChip *pnv_get_chip(uint32_t chip_id);
 
 #define PNV_FDT_ADDR          0x01000000
 #define PNV_TIMEBASE_FREQ     512000000ULL
 
-static inline bool pnv_chip_is_power10(const PnvChip *chip)
-{
-    return PNV_CHIP_GET_CLASS(chip)->chip_type == PNV_CHIP_POWER10;
-}
-
 /*
  * BMC helpers
  */
-- 
2.23.0



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

* [PULL 86/88] ppc/pnv: Introduce PnvChipClass::xscom_pcba() method
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (84 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 85/88] ppc/pnv: Drop pnv_chip_is_power9() and pnv_chip_is_power10() helpers David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 87/88] ppc/pnv: Drop PnvChipClass::type David Gibson
                   ` (2 subsequent siblings)
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

The XSCOM bus is implemented with a QOM interface, which is mostly
generic from a CPU type standpoint, except for the computation of
addresses on the Pervasive Connect Bus (PCB) network. This is handled
by the pnv_xscom_pcba() function with a switch statement based on
the chip_type class level attribute of the CPU chip.

This can be achieved using QOM. Also the address argument is masked with
PNV_XSCOM_SIZE - 1, which is for POWER8 only. Addresses may have different
sizes with other CPU types. Have each CPU chip type handle the appropriate
computation with a QOM xscom_pcba() method.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157623843543.360005.13996472463887521794.stgit@bahia.lan>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c         | 23 +++++++++++++++++++++++
 hw/ppc/pnv_xscom.c   | 14 +-------------
 include/hw/ppc/pnv.h |  1 +
 3 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index b3388038c6..41e5d762df 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1120,6 +1120,12 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
                                 &chip8->homer.regs);
 }
 
+static uint32_t pnv_chip_power8_xscom_pcba(PnvChip *chip, uint64_t addr)
+{
+    addr &= (PNV_XSCOM_SIZE - 1);
+    return ((addr >> 4) & ~0xfull) | ((addr >> 3) & 0xf);
+}
+
 static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -1137,6 +1143,7 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
     k->dt_populate = pnv_chip_power8_dt_populate;
     k->pic_print_info = pnv_chip_power8_pic_print_info;
     k->xscom_core_base = pnv_chip_power8_xscom_core_base;
+    k->xscom_pcba = pnv_chip_power8_xscom_pcba;
     dc->desc = "PowerNV Chip POWER8E";
 
     device_class_set_parent_realize(dc, pnv_chip_power8_realize,
@@ -1160,6 +1167,7 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data)
     k->dt_populate = pnv_chip_power8_dt_populate;
     k->pic_print_info = pnv_chip_power8_pic_print_info;
     k->xscom_core_base = pnv_chip_power8_xscom_core_base;
+    k->xscom_pcba = pnv_chip_power8_xscom_pcba;
     dc->desc = "PowerNV Chip POWER8";
 
     device_class_set_parent_realize(dc, pnv_chip_power8_realize,
@@ -1183,6 +1191,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data)
     k->dt_populate = pnv_chip_power8_dt_populate;
     k->pic_print_info = pnv_chip_power8_pic_print_info;
     k->xscom_core_base = pnv_chip_power8_xscom_core_base;
+    k->xscom_pcba = pnv_chip_power8_xscom_pcba;
     dc->desc = "PowerNV Chip POWER8NVL";
 
     device_class_set_parent_realize(dc, pnv_chip_power8_realize,
@@ -1339,6 +1348,12 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
                                 &chip9->homer.regs);
 }
 
+static uint32_t pnv_chip_power9_xscom_pcba(PnvChip *chip, uint64_t addr)
+{
+    addr &= (PNV9_XSCOM_SIZE - 1);
+    return addr >> 3;
+}
+
 static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -1356,6 +1371,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
     k->dt_populate = pnv_chip_power9_dt_populate;
     k->pic_print_info = pnv_chip_power9_pic_print_info;
     k->xscom_core_base = pnv_chip_power9_xscom_core_base;
+    k->xscom_pcba = pnv_chip_power9_xscom_pcba;
     dc->desc = "PowerNV Chip POWER9";
 
     device_class_set_parent_realize(dc, pnv_chip_power9_realize,
@@ -1421,6 +1437,12 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
                                             (uint64_t) PNV10_LPCM_BASE(chip));
 }
 
+static uint32_t pnv_chip_power10_xscom_pcba(PnvChip *chip, uint64_t addr)
+{
+    addr &= (PNV10_XSCOM_SIZE - 1);
+    return addr >> 3;
+}
+
 static void pnv_chip_power10_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -1438,6 +1460,7 @@ static void pnv_chip_power10_class_init(ObjectClass *klass, void *data)
     k->dt_populate = pnv_chip_power10_dt_populate;
     k->pic_print_info = pnv_chip_power10_pic_print_info;
     k->xscom_core_base = pnv_chip_power10_xscom_core_base;
+    k->xscom_pcba = pnv_chip_power10_xscom_pcba;
     dc->desc = "PowerNV Chip POWER10";
 
     device_class_set_parent_realize(dc, pnv_chip_power10_realize,
diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c
index 5ae9dfbb88..b681c72575 100644
--- a/hw/ppc/pnv_xscom.c
+++ b/hw/ppc/pnv_xscom.c
@@ -57,19 +57,7 @@ static void xscom_complete(CPUState *cs, uint64_t hmer_bits)
 
 static uint32_t pnv_xscom_pcba(PnvChip *chip, uint64_t addr)
 {
-    addr &= (PNV_XSCOM_SIZE - 1);
-
-    switch (PNV_CHIP_GET_CLASS(chip)->chip_type) {
-    case PNV_CHIP_POWER8E:
-    case PNV_CHIP_POWER8:
-    case PNV_CHIP_POWER8NVL:
-        return ((addr >> 4) & ~0xfull) | ((addr >> 3) & 0xf);
-    case PNV_CHIP_POWER9:
-    case PNV_CHIP_POWER10:
-        return addr >> 3;
-    default:
-        g_assert_not_reached();
-    }
+    return PNV_CHIP_GET_CLASS(chip)->xscom_pcba(chip, addr);
 }
 
 static uint64_t xscom_read_default(PnvChip *chip, uint32_t pcba)
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 7a134a15d3..4972e93c26 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -138,6 +138,7 @@ typedef struct PnvChipClass {
     void (*dt_populate)(PnvChip *chip, void *fdt);
     void (*pic_print_info)(PnvChip *chip, Monitor *mon);
     uint64_t (*xscom_core_base)(PnvChip *chip, uint32_t core_id);
+    uint32_t (*xscom_pcba)(PnvChip *chip, uint64_t addr);
 } PnvChipClass;
 
 #define PNV_CHIP_TYPE_SUFFIX "-" TYPE_PNV_CHIP
-- 
2.23.0



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

* [PULL 87/88] ppc/pnv: Drop PnvChipClass::type
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (85 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 86/88] ppc/pnv: Introduce PnvChipClass::xscom_pcba() method David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17  4:43 ` [PULL 88/88] pseries: Update SLOF firmware image David Gibson
  2019-12-17 14:32 ` [PULL 00/88] ppc-for-5.0 queue 20191217 Peter Maydell
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Greg Kurz <groug@kaod.org>

It isn't used anymore.

Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <157623844102.360005.12070225703151669294.stgit@bahia.lan>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c         | 5 -----
 include/hw/ppc/pnv.h | 9 ---------
 2 files changed, 14 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 41e5d762df..f77e7ca84e 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1131,7 +1131,6 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     PnvChipClass *k = PNV_CHIP_CLASS(klass);
 
-    k->chip_type = PNV_CHIP_POWER8E;
     k->chip_cfam_id = 0x221ef04980000000ull;  /* P8 Murano DD2.1 */
     k->cores_mask = POWER8E_CORE_MASK;
     k->core_pir = pnv_chip_core_pir_p8;
@@ -1155,7 +1154,6 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     PnvChipClass *k = PNV_CHIP_CLASS(klass);
 
-    k->chip_type = PNV_CHIP_POWER8;
     k->chip_cfam_id = 0x220ea04980000000ull; /* P8 Venice DD2.0 */
     k->cores_mask = POWER8_CORE_MASK;
     k->core_pir = pnv_chip_core_pir_p8;
@@ -1179,7 +1177,6 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     PnvChipClass *k = PNV_CHIP_CLASS(klass);
 
-    k->chip_type = PNV_CHIP_POWER8NVL;
     k->chip_cfam_id = 0x120d304980000000ull;  /* P8 Naples DD1.0 */
     k->cores_mask = POWER8_CORE_MASK;
     k->core_pir = pnv_chip_core_pir_p8;
@@ -1359,7 +1356,6 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     PnvChipClass *k = PNV_CHIP_CLASS(klass);
 
-    k->chip_type = PNV_CHIP_POWER9;
     k->chip_cfam_id = 0x220d104900008000ull; /* P9 Nimbus DD2.0 */
     k->cores_mask = POWER9_CORE_MASK;
     k->core_pir = pnv_chip_core_pir_p9;
@@ -1448,7 +1444,6 @@ static void pnv_chip_power10_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     PnvChipClass *k = PNV_CHIP_CLASS(klass);
 
-    k->chip_type = PNV_CHIP_POWER10;
     k->chip_cfam_id = 0x120da04900008000ull; /* P10 DD1.0 (with NX) */
     k->cores_mask = POWER10_CORE_MASK;
     k->core_pir = pnv_chip_core_pir_p10;
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 4972e93c26..f78fd0dd96 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -38,14 +38,6 @@
 #define PNV_CHIP_GET_CLASS(obj) \
      OBJECT_GET_CLASS(PnvChipClass, (obj), TYPE_PNV_CHIP)
 
-typedef enum PnvChipType {
-    PNV_CHIP_POWER8E,     /* AKA Murano (default) */
-    PNV_CHIP_POWER8,      /* AKA Venice */
-    PNV_CHIP_POWER8NVL,   /* AKA Naples */
-    PNV_CHIP_POWER9,      /* AKA Nimbus */
-    PNV_CHIP_POWER10,     /* AKA TBD */
-} PnvChipType;
-
 typedef struct PnvChip {
     /*< private >*/
     SysBusDevice parent_obj;
@@ -123,7 +115,6 @@ typedef struct PnvChipClass {
     SysBusDeviceClass parent_class;
 
     /*< public >*/
-    PnvChipType  chip_type;
     uint64_t     chip_cfam_id;
     uint64_t     cores_mask;
 
-- 
2.23.0



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

* [PULL 88/88] pseries: Update SLOF firmware image
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (86 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 87/88] ppc/pnv: Drop PnvChipClass::type David Gibson
@ 2019-12-17  4:43 ` David Gibson
  2019-12-17 14:32 ` [PULL 00/88] ppc-for-5.0 queue 20191217 Peter Maydell
  88 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-17  4:43 UTC (permalink / raw)
  To: peter.maydell
  Cc: lvivier, aik, qemu-devel, groug, qemu-ppc, clg, David Gibson

From: Alexey Kardashevskiy <aik@ozlabs.ru>

This fixes PCI bridges support regression.

This enables IOMMU support in virtio drivers.

The full list of changes is:

Alexey Kardashevskiy (12):
      allocator: Fix format strings for DEBUG
      virtio: Make virtio_set_qaddr static
      client: Load initramdisk location
      sloffs: Fix -Wunused-result gcc warnings in read/write
      pci-phb: Reimplement dma-map-in/out
      virtio: Store queue descriptors in virtio_device
      virtio-net: Init queues after features negotiation
      virtio: Enable IOMMU
      ibm,client-architecture-support: Fix stack handling
      fdt: Fix updating the tree at H_CAS
      version: update to 20191206
      version: update to 20191217

Michael Roth (1):
      dma: Define default dma methods for using by client/package instances

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 pc-bios/README   |   2 +-
 pc-bios/slof.bin | Bin 931040 -> 931032 bytes
 roms/SLOF        |   2 +-
 3 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/pc-bios/README b/pc-bios/README
index 91218c69e9..269d99afe0 100644
--- a/pc-bios/README
+++ b/pc-bios/README
@@ -17,7 +17,7 @@
 - SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware
   implementation for certain IBM POWER hardware.  The sources are at
   https://github.com/aik/SLOF, and the image currently in qemu is
-  built from git tag qemu-slof-20191209.
+  built from git tag qemu-slof-20191217.
 
 - sgabios (the Serial Graphics Adapter option ROM) provides a means for
   legacy x86 software to communicate with an attached serial console as
diff --git a/pc-bios/slof.bin b/pc-bios/slof.bin
index 50fc9b1e1cb837809c38fed1e9099b262e8600f1..78d8b26cbb88a1913c3b262fd5be29ff89afd554 100644
GIT binary patch
delta 217484
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%0Ad<bz)vR8#vhbSF%AoOfq
z{kTmJ8(vZZ5B8n#5%sl*9RA&j@Ih-X0R6Z(1hnwr94`mF$)h_cQ_%(T?;$e#P279P
zmKAT}rW<xI-{OPPmDi+0v}<2+xZm#IQf*AlxRJ%?(6bUi-s5wyQtn1+ZxN4Ghi<Ib
z5=zSrRXlDa9;gdcki45G*jZ174DoY=7%5+n7?$1p_scVH;c`x|b<$MDdxw@FYq}g<
z#k;5V8%?N2wfq*<;9B<^Jg^3xhiJt^Gf&ZX%C%Lvauai>JYL18^$(-!*sLRR?x8do
z+XKgGE1L4Hd5@p9^NNYmdW;VWt-@nxnSYF1JcV91Ksn6$fvs1I0=|MnaF}qO*T`Xh
z3<vo$93-42Eu0FYCa6$`94k51<O!@+IaACJ%2^tr5XH8oML2zr3B=Ta5yZKT%2A$T
zdPG9g<$KCUdenT0(4uzs7p9b<5bmX2oE4`26j|_iUpEYyB8!nKvViIDDS(d&MizfI
zoaUGoPBWF9=GW=eV^3n+L+O7MIl~S^li@00m-(w6-{Wo(C@k~z^Sp2Pl&@7lhA5%d
zh!Pr=1HDz0Pz@*guHi(xv~Z%QT1N>85*q)XL4wDN9w{R}uNZIyw*9Kct2s)D(xZcI
z%9w6O2PvqhJ4`(~xalyz*1Z{e?CE#2bIQ2V|H#^tG+?A^dM7nC(Ue_;v63ZWqTfbe
zF7DU0$F+|XE^u)ota$-7>~+LfW0<&_j;)X#Oi&<K@W-}?R(3}0w397YqD26Q;euF$
z4c9(Rol%iW#zyz57hZC&y6?H0L!f)}TBX+)K^N=BIfSoVG&(@-cnFC$1Ra5|c2gl-
zfVxw2lNfZQMT60VbF;z!9B(y!{Obzg=ndY`S1_<=s)G;&@=-s{8?M}o$M7+FSV2|*
z1>%OW2ZQ?g`ckVd#)-N?9|r%`!hhF=Qd!V{!{cP6c)>V^o|aaQz(qCeh7YX``p|2;
zJqYsQe{oS|A`w8;*pDEIDCqEMmN9S+Qduw`mhg~~=5*Yz>)F@yj66XbR7PGV<qdmN
zO{jB+9aS(#O(4T|vdJxa)M5g;pnO+wf*@tWgzJ-Li|FhDHR3Q>NYv>M?!G~H_j^=}
zEeN-8_1}G<aIxaXSo=_oerh#Mj*5l=J@k^7Bc}r=Q{)JISLOtg-ka~fmz5{^5Rc)t
z2oXmfu?BJsOiYQg;4$+2S{=m^7*lo?Q(V$jW-d))?bCN^8}wTV*akvmyy}}b;K-jk
zN{!Gn8k|qhqz8KX+aD=?sXGe?EsgZSL$(Ifh`k8H6kb!{O4>{&cL~g0LQjG_jUc2M
zg!U7m`Xpx7H(`Vq1ly&KXZvVXc&&(4(fAT>X?$4<7+FvF!8}KxR!J6V52phPooKBZ
zD+*C4XhrW#dUT*sq`l9(pezMSRBc@ldeObW8tVv@^(Uf)LrT(Efc=%7!bU62afsZn
z&1Z*`YY|9eoj|M5WFRM3F`k@QmI4KBuZI4JhnZC1`d4P2eG0z%JOW%e2#OwN{~D5p
zI8!9v5qfcD0KswAr=P6IViwQQ8Icr?I0EMs1Kv+zm#7a37>m2mi*#9qXkZ~G3Qk^(
zT=^xlI0Bz5^Qpg!nGu;sCH7!^rDt)+y~BzTL-c5SXjVnW&=py2znS&o$uzpeM{8l&
zpeZ*uB<)WKesR8)qXJ-v9l>uDMBjQtIbI)<mSymOE^Ib?55{AYS+8fIA=`~K4VNc<
zHTNcFmDvg{vj^AD0#_E!fXotY`uHVZ4Fu}PuqfK4CQE?BXklL8ltZd5#`TNMl!hcY
zDJY596N0t24`PoBD&d7=gfna_YvYM(n|f%whjH}mTyTvSR76rjwbsKpUV=iwOsiY2
z`A9is&-Zw*8Q-ZG#PCXXG~T|IA{H@Mvm$<@91C3NLSn+2_e89n?~0>mwZ1gkk>2+Z
zFz%*ovI%0v>g7;5spdaok?bVdhW`B*TR9kCX4B<Kvwc%B(L!^~&UfyoXKWEJC$?Y%
zYv2Qw>MIt|9(C6dXdl=BJo+J=mtEfHgWC`bTX5;@eLix&@}d-Up?0VfSfqa`t6?Z>
z%Tns#kxR$1_SUs9mbGLoTX+zM>R?2ebr<tq8ArQ?|5AEs<a6X7M&4KQ-1|J*gD44Z
zc?BHU{Pfjg;jq2rF2r2r&LIX`Gw(K)*;cf{nbSSc%QWUA9o`Lf!4Bba&yzMAd0o^o
zDaSaUx#1pgF2yWCt1fs>ZF5%^^@1Htny{rXD;+113E3;MdfTxmn-RIDo`tO0kG+<0
zh+Y@eWqax;Z1Jp#wYdvnje&F=S=zJ7LeqEf4LDFTd%ne0F)zkOt^7VyJ@?=OLNeY7
zq7@^>oBH*!$Cc#3v^nK#whyN?TX)}q&X9q`!t%4=pAI6!+k}Iq)vRA`e8$k+0VmT6
zPR?}CuFn`c`ywng%i+#}>&U$~B&{$L`!!kEugS85duCaYg}oUZIAJNOFI^!aI{Kl8
zC^jKUfo^1O{K>T3fr!?!u&0w5l7^!pLCjmdZAeo-Jt$ot@NOQ+JGi_F9t`GA07rL#
zqYE^D;4J(ioET&dmyW|!Oho@5<xS$os}UjK(&VYl8SKG9Wl-#M|C`)xJDLj6Hlv+I
z=y<lBKR1Qa(EEjIcGd007i5~s)Zch$p+1A+6`yBBUr#!8Y?Ps6gNgrP>q0NWqZdPG
zd<A7#m*Q9ib7T#M`W)s$H|9O>wRB85^VwGDWCgr^CE^!jTH+Pspr6T6W#dzxhhdbL
zr6{$)-jkiL*+DEIpfUr$Mn(SnLl{DTne}(x-IMHLcrOI&O<Xhde2G27FR@qnC62}a
ziE#2WW}(GDZL>K7pD0TtLY^<-^$8zG2(#~^J;YCxKP27qUVv2sCoxH133#wALMlM`
zw1RL1J`M{q1WO)AQwdx71QeXkBZ%mL_hIU1z9l5A01jgXU`F&_qgDW^!F|FyV;e>O
z^mpE;3rT|ZXb5li(co5zjIZJS!aw;+H3wOerpbz@L_g{4r-j@_GyYUBvlybAj8U9R
zo}ADzx?VfqS|6+m2VD$rMNvZ)sb8yTK_A&lRHGmFhRM%r5b>;YBBk~dlzE=(OlcKl
zA>BG2{agjXm@JJm1!JopczQhgrD8;n68Ku8Lx0xQPx$lzZmXIZTF^!S*DiQO^Z5>0
z@*(!gn?1!R6RA3a34~nSM29rA9g<v2n*3}gl~GeTWk#UEdqUMp5J>3TMJOW~)uBx7
z(KJCzzU#WM;GGeXG=SurF`)X!uR0X_#|ol{soKME(iSzl4mT~n?6@}>8(X<;;SJhk
z3?1|qj-25k3NDOvdrtjCH!w^&z&qGW#R6MNF7@-8<A9cPeQ=`;<u~Vh?8oHL%!m$i
z8gooha~uKB$J2=uU5HG#SM-ebQZVux$bJFWs$d_L$niS@pQ#`d`PIsG#ggm7t{Yqz
zMZ-i7nsV6Aw>(PEK_3A8loo@b#}T~|RKUf3uPQmQO@#(9&j%UEkkudYK^^u}u^u^p
zdV|h4hIr_L3sg0E0jwVT0JO%ZDEb;j)GgNd@D>z)PdC>1Ra=W#ow9bUe8~6Cj>9@1
zeqHT_CWfTpu(SfF-<C^nv1()3n6(zGsbe^bgdG;n>APhQt@#SGV&LejvJ3BOduYWy
zFw_j%<gB@qIQ9OERn!F-oBdu$8Vt3{eF6KN){)rEACA4wD#J+O_~E*9CuIz!Atu+Y
zHuGb%A`xvhZ{{Z|1Fo74=4fUznD(U2Cb83ICkkFeJg3H0Ez|#zOH4Qd>r)B-_s#tE
z(Nu0M*PXjl(W~{fm^%XJDN?4zCUuH>jgBdQ0Yk5(Kmj)apZ}N->S6c=pwo!g+4&}A
z&ZGtEOxr_Ok1$GVedA+Z@JJV8Fd|JqChx}j1IA$I1)mZh@KUt)EHPq=Il(vr9k#a=
z)XjOW7<;KZx&7KP&agS-DyW;erQpK!PYT=GvR9aT+Y95yM|v=kg%nyQ4~C^CGzTL*
z^8Z$;2z6+hCT2aS;QJxep#M+)5_^#++8&}!69^@p7)LY}qGAfYGivTbM;QFRXCH>Y
z7(vCH7C{BY6m#gT2R&;YQ=CFffs?SCF$GS-{%cI}o}nU;nu;mV&TnIiF|C6Nato?g
zN=^R$D{)^upSdnUgw_~tR;xY?nap0uqaxHLq6u^_Mqe;sZoKC#?}oQ-+-JE(`m(i1
zi#mW?Qsz`}eObPO`^#Jko+@+8!)I|z(Isoo@~-_6cUshH!OkCBLT%UIt7GDr#S7K)
zUdhCTS94BJY5kPn-dPc)A_{Bk)|R=F17%LX^HctNE{aX^>}Pyxm*ObHz#l?TUp5Xi
zEs(r2<#Yab?w0M(;f>|uSUKt(?ksx!?Y}@S_sVl$@=Kl1qGBzUt6oQ-@d~XNu`=}f
z&;1MRg5Qv@_#*)BulRE@u4~t!2nh7CFzSc{)^7BAFkU55ove>TCr5qF{}*%zf5V?e
zt4F@!8<EOB58#&P&-3Sy@_x%b+`Z*HyoymQCx3?>-zl>4J2X-(`(5CFYg3$H%`5i$
z8!zz1oR>&vJ+69|$V2sfBtTs~e=ck*7{=`D`B0Xe75(MGi#+dUUb>!_eu=LRwJAc?
zm-rhzG+R9vf6se_@W1F+l&gQ_Kl9!4$WPqQSIFf*<NfeOvhinN<0XV&c;C=`)Txl?
ze!-h95BabEf|sX;-mf&p`xcvAw~JY@y0Fs4GDqP4FK86uGAAR?;$BO6OY8k>|A$}W
z{C??e#MRL+WMv~>)?Ls1HI3*z|4{b4iWhHkrS&S_!R+jJU*)&)&?;-*daJ})@g6>0
z4!+LEOkJ!dchIe*3t*1G!YkAk+Gl!z$oiqI!s-+Gj=*9yA0Z9xqV&QK2$$>@+Fs=d
zEc!rJUPni_%27A)rsr1w-WzyXteZLqr%m9bO;rg=&#y1RM1ifBd&^`_fZxqi{gnZT
zpJ%^*UR)A*jj%=&L&aU+ZwV0}g<|u2(K^{aRP;0lqa(TkiEdQOkWi5&o;1tsP|>x+
z*+ND!bl|!*?@5bX9xCn)JqxTxc{WtM)lGS7I1q9+36Gt_5jr-(9D%uzS{pHpzv8cL
zBYJT$>-#Mx(U+f+{Y+xy5bRGqImgcD-=JOw|B&ZOej^Y-z6uhPda$-heV+8nwWtCu
zJ8Tl3ROOwq#~QWj#B1(V3!ihZny?Yg-K8k0^{5Yi5)ljXl>F7I5Ue=@vvG4dOzgqi
zPEqZI1i{L7qAMRQtJ{e?Fv#ZH#GwAwc7AU(G1NR1vsAiyC}!gw^4r9CF}q&wMHO6U
zuDMM-+i4!v!nC1IU#xjgF~6(5Sjq8H>E#aMIlSpw94=<!a{%YU#h_4o($`NpW&4g|
zEMAzjm_?L-Zbz|^;~l34v&a)qMai5_B283P`ZskF|K>5u*HDC`Hi}lVIkY^|g-)6^
z4XoTQ-r$we8Hp~flkQ0Idy#oVHbe>sKPXc=iwUI7okf@UDasP)@)xEdn<L=RV@52I
z(^rR>jDbY{ln-Q8XR!<2bK+7Usd*QSA2{6JRro{0sJF7JtB91#qA)r~r7ueS9Uo|L
zbrS>Q8t}6FF<l-vHW9SuJ#9kXD@LBz$g|3-ZlY`Eqm<P5D5y7gr~n(@&~BjN&QSJz
zg+qt#7+Y`&4zp5K9_<ErDSZdtG4C$M#%!nA1a~huw(hpucCb-|Mt|1T8=&4#*GPAF
zv8U5;%EB<u(XDe*x*Xg?^zeil*%qDXB&BdL+Nc&rYttF9t63i;qIBGey20;a))u&U
zHIF)FSA7SrRc~(MQEJD~Dj57El}@zClRZRPr>Ch<g+1^}j==ar>FOy~iFAx;PiXL+
za#J*H>y$hm4F%lcZ-^G{xES}Nyxt3A^ntYWM)qzwxwq&po{5$Dy+v~3ej>T*+c(^_
zp|$Fr*I*zSn<;N)U)+lHF{gf;A)|=$D5^o9oQ^<xsXW(P%nrklX7#5ctg%G5j^lNS
zCfCx~K4X>(En;yf?j}8xEo&@jywrc)BE|}M<WYUaKwc{6_7%Si-Kr2y_Z2cM-_9p0
zO}rJoV!5dw`d2BB_k$H2Gs}?v;+-M+m_918=UeP(I=_NgA?ew9{1@uE<xTyj^LNT$
z`ol(_HA(9LxV&c}gaM#vms<yj+59j*zaVCYVJ@1WhF6*sw9az=K+z|<&YJhE&(6nx
zNJL@I>K+>`WuYT57D_%4#L9fKW}uiV$||HK782f8B~t*~lvQFM(kJJ}!rYh3##r$}
zw+4zLh?4dBjm3?p%6vw2Q6Ue<!9urH`4i&BUqk5O@=y_B!o#1(iibJTTy7N}aQcf?
z>=PR;{_TmPYlwbLY8;}8<n7z4WmT%!(_uZ)znSGq6J0}V(TPU6Ax%6SzO5SL=&f5q
zo#}%k+HoSQU0Efuu|BTsP3asbmJTR;Q{6~1mH8+#U4KVeB~JOV<HaHq<8kQ{`#)s^
z%PRd1<HTw%N)qJqbn#U5JZjbv==m){rK&6SJ6_29(BE^s(0Ev?j??3WjGX`{0WFvy
zMu-xeXHS3@LpL&zyH4h3h-r9x{&0o}@J>o6F(F%FE3uA1_i|Z139c<nuDwG9x}745
z%Keij<JC=FlY1PL+wJ0RzF9WfL3z5|o+-w`@tw;Qi#vr;9Z<v6N|xBQn?END9u2;D
znFGVw^+*49hq%N;oz}dP!*atEm{6*$oFaPTospU;;-9?pM4~`E!A@AC;_LPg{YRz=
z1PQfxp&O`P|JmtKbbfTpOz{#zgqLTECq{RpdUc*azTR?&IF;TN@FEZHo4Dzyi~wn`
zffFk8bHu%!)+yA&QB`_&`_1xfj(DtBxE@0kj<Q+3CRA^)I)`B!;Ru9%FI~CN$M!$U
z4Y^`ppKUe6p2TvriCJ(e+a6(j6s_oJNr=^5Y-#^(HU6AgVzCydJmI+UP%0<(x$oLm
zqlU9k-Ja@+1q$2v7!7r3m^^={cu$m?{gro#ky`2!#p9#Qr1PlhMyYlOE=SjG!%o6u
z%&d2_jZy`qgShb3_lWyMsnuV6k2oNBf4_CUc!FMkugb#!bn~CjBk6vDmkNcW6JnLn
zA=DcES@TNI%9KS=9j|mPg6a&BRf{l_ZuU1W!i+opQ$ng+Wr(QhN<F3NLOQ0Dij=Bx
z%zd)$NtpHqs}m#8bS0C@)yBxGQB~OIt)@|?E@5xZ<!HKg%71*Z*d`*bd{2lVtdB|4
z|J;zSrDBFS=90&k!r5#)D^0({L_1GT{+$>jww;q}e<vnU_UYe=Cn-H=8T1Y5;$=Yl
zLY`hGMnr5oN4KBGJ&yw)+6*{~V)Ol?X~ed(WTYkQx78}Rf7?0bJ5Ft@n~J?HFmm%p
z`9*OcZ+n2qpOdZ!L?5xOR&II#M)0vb^MHs)_Lc|r(u4=~(wqlT+F5RTP%K61pIu@A
z@4oF^^J3)MDeJ!i4Nf#;eSXs%X?qAR55!9zqQ0G#)eoWiZfSa0@2c%#o$A7eksT`c
zKCJgR;Sn7>{}C~+9VcQ~p;gw&P7jMAM6LD_y;{g}R9mE21rxN%lbE&btY<xLY;I@j
zBHQ}7Z4I(`IpR{lGs_Vz<;wg=DS1vFdQ?0Bp8WlOFS^5bHu`OU5I^AIoJ?3DdUYW}
zxbC-|^`u=`a+ObQ2a$y<pkbNP`52Aem;SwviFShOR2Hbg^#4*IKH&o}K1J9vc+#Ft
zORcoG*}kMtKyW*KV}czb*%N2}hE?PoL3OzoE^gbGvcfB5XH4ur@26g?iN30114LOO
zbBYw(eqRxEn4A1(R+Bq2`7f^#$tDa~>;?p+k<zt6bPdDy=MJ-@>61cPf@EscmAN}C
zNGk73VoJ5(2FTJKvGe=lJ+Y>bM=KG(wIfO?%aR=l!^+k1=()P<J1p}2285swN$b;4
zzag>!z;oEn&XrN6lsqg^7wiaLpEp~*78u8w9WBa&_xDjohI2-R3P!yIWB)BO#mh{%
z!whE5%%{3W{Ea@GQTuesRpd(o&h@D<y7e;c84=UD*3R^uQYxTI*1Szy<??61?d!7o
z88PV2*D3ebEPix<i?aV<@gvpbe`oQd;d1h`;*KGaWa<l6nv{RRzNl{;#u?l4-ej@a
zjPWm_*MMm2KKaWXW?A*Dcn~Ykgc8ge6J^g*sIE=UEfos@s!B!IX#4a5%`bph%X3%;
z-Z)tt@Z!aW9d`LkDdsbqto$P;3NGhv6l;*G-H2G*F1?#D^!c)S6a30M39{#AgkH8(
zjPsRv)GXMHrtI>_W<*$aS+`mIp|c&n-<*8c4x3@P(;ZFkub0cWh%sYMe?@|!9ffi5
z#n!4o0HHug-CH~Cg-KD_>SY+L0IsCiEO_JREU`#svUUp^N%dQ#xF&F^tLHXMDNitI
z-3HFU;5N|%U^_rqInl3s6LqS#iLTv<6--OG5?+N7ERT&+B&oOo#i-=mDmrVFwmc_B
zcCeF-sS0Fjlg{Tv?<rpp!4zi*6y$0QirP7v-Z@2iscFoV;=_p!f`4bZ%~H3-hIMB5
zNJmq(QeK+Wj9A)C$A*rklLz&e=YM?;t53U(+zwN-N&9vL2{!-U?GPYxYj&tUMeW4w
zVUyWAVHS4(rk$A1QFv$<=A(R>;={NWNuLk7U&tySf-<+?wp$3^X0yqfCmW^xd93Js
z$#;E`FWt|Jm-<)O*}KXPv1K=xxDPI`>Djt^Yph;t4;rnN-aTSXD3-&ZW7-R@4$Dz{
z#S5YNj;5p0vUV?G);ZE#4%A1by<Cj!q!ilG^jGCo05R8>gR@TZ<#J4$E?EQ6IXk&F
z@SKvNx6NT%SUH-GJSt85#2>H~<K2e{_^dp;Pb}t3rR@bc;3sS4!WUp{OXcAgAg87B
z@(bcw5G$w<y~AAAylq}b)7yWMdn*v(xa8>yF|Kpv(B5=U=9uCG2KH**f-hXsvY(<_
ztK7ODJWZ5`_lu`ME#pOTFTmax#jtdzoxP=En_;^GP5Aywop-m`ss!Uq5Z2XYUa-C`
zr=m@o`-PKz-1{Ey<1U|sYv{jrs++I<!_jn4y^MSb=Cf4Ryd-8tltt-1{rP*nc-{$V
zeHp^Sx1nB!FpKcck4O?_OrCvN^b%zz*+`{JWx^}s&!WsK>t2CKminEqQV23cnh!$t
z^JVry@p-38P~MCi-}O4>*~etcpTy@7T-0k=Q!kYZU!%F*EMI;N0xUMmn%58`l$qtS
zLokq~{^CR8PeN=>kSTsdC=baEeu%qR{^A#D-JgRqJlL5!O@C@ZoA+ES^0=IQSd8sv
z!=th-TwdKkC}1UkQK<EAKa90Sbd8-=#;B^e#i0i)P%LCPnszObIe$eLv*m`rihJeA
zH?Tkt{8fws-=p4uMDX768_+479K9j>Ml0K*%Zy|@c&X}ab7N2D%bGXD05LUGHohVL
zO_XkzSC5EjXlT??(L1`@&R$VWAgVeO)bQk5^4;4TWX@5j6AtB$iqE^b?ChnFi83%J
z8!bEsEQ{R!CS=v<Km4Znx8P^}701Ld4Ie!^dmO929Z@ps1XzX9o)B-vY%LwAi!15*
z9lpdqJF1fU?5Iduz2k6F-j2$ouXnipu_wiI8r1XnDe+hr{nc4&49@6(tk3U&;q78F
z=RJ&fl|22PNDkeK4_Qu^HSdY8vhVw%678OOA0|{Q8{Zc*y6-gE*-kaH7zeyBD`I&&
zOXR}SK*KlnPK#ZkZaaItNG3#x&Rx+KiGgeZP7q6?FQ~Ay`oN`0<swIVKR}<{vho9E
z(sdueqF~^EgB&)<!G9C8#ED}6+P}dqL1*wLeC)<$4txXf?_yh=i)PN!_-|a84qi>Z
zK?kELW~7%>IvBPg?Uq$FA{lL5uffbxAiW=om7UzlcYWi+jigAd^j<A8^<FF6|3kbH
zT9Djlms6hp2k;A|=_B!M*z);Vr$6xC2P(dgz!dg^KN3%LgZ*z%R_kbbN;zpdH$+~H
zoO?#B3@bpi@oG_AZ?CL910U*?{XWKQR_s6iu}I?LM9G$a!v8yE)IVWfZaL?lVr;r<
z8Sf2|+On&dVXyASNhNxSD9e}JowX;<P#%S1`f)GbIUxB`Qzc7!<GWk`gpVnZ4gVAq
za=pk6!T!7JVA~UP{1UQt$%)N5OCDd9v*7KtGW&@?LPjBF@h3JC9?CXNMGQ^H^E7dg
z{8I8zpFYmxWdXc+T~Zp4&J>@;AbDlgSu|9P0{{h7YOS<<iqu-a?Nh9Cfs^qW2C_gd
z`%L^Z+J#_|u78d)UThvrjZi;JW501p=jUQthYh=N1d2fP)#UBSI`TP$R=VY!cmXo2
zI454?7?>}=arvEJ(ma*#-|#QdLqN4Fz7iL>%U|-f7@>*HCVBi@L?B-5!ef!@mc<vu
z0U%lHpgs5&UmaxbmRsw@J>i>8w6>r_#^f&td1XjF#@i)r^=g3U*2AB9Wko%8)?ZsM
zI@0k$!$s)nc4@gJMuw?%oug^_hjQ*EtRa?T&bcK15L#?!t8(Sbmqm)qxQt2CCo3*v
zdaaTn-;2A1&m^7SizYG3C!IfFS+-rC`vJZ2`c3~9w{vV{_iPYP^q)g->d{SRb;gFB
zV~9zeuU(D73OUc0ko2~%SXMW{A&mA((~sgp2c>^WyV;)|O%Dv0*MGz~q|2T^VZy?y
z`zNJ-4L@Pk0sPpXku32q`&s-+6DPL%E&nTqhKSLXGW!~)13=d`ENVtq$f|2_;(+I`
ziL8jx6*#U5u@>?uXhev0Eh^fsi+cni_?pDf?#UI&UoqEf#iP$a)ee-|M}GnpI#3!v
z`mC&L5)X^ym*w1mcu^!*$l3xPwb`N#=#C*UdWo>-0Byh03o*%Gj;`43)TRzitt1jx
z;ztKz1)Swypg8nd+XH3ssfQg+_g*3408Zb0PTScf^@y%t+)no(39Tp#EthaDK74dV
z{iM;AR|bx*xH16UtmfJzk$Oa$g?2YWg=Iq9N1ch(v=Q;i6*$*#Ln>PN-RLtZU$X<$
zxw5wClt8EKqtEIbjIl|VruFKR{4%Ajz7X2<R1*g}jsSkz3F59ODYZ&gYTB4Ksa4+3
z!Omq(`%}B*3hFd<R#t>)eJ~XAbclABNIfiLL$&w2C7^kY$X?oQs=IW|)Iioko%XkH
zqqX7PlV2`PNj+j`nY*bCW2IqUvmIR;+*TXfC-pE@E{#vEO37mfybF@?o>$F0!liWG
zg49ZXL0j!9j&IzV!ZbMlN_i$sn~L`R{n}|ed9T#>3j5=$5pnxm^v)jkjPcr{*av5E
zpeQc&w5+{N>&<;z+G_*iQ%}<krj7Nf)wp0lx0LA?B3uuLYd+y4w?ZzaDDDKlq}W~?
z3!^A*uVslnOrB}4%@V2Aa&QMoAnhMAyMrcSpmiOPorX8R!nHgq-W#qB8hwO#FB<PV
zd@zPBFHL8dLNnG=9<fv(mqxD^;$x5E3}73*k024!Q5%F!(}a%N?*O)U)E*<kQD*I7
zf*Z`*P=ZIy+6yMPr$26wXM7}|y&&*rLnp0Eo3yjZt9_NSwv#rV(E3Gy?GqK!6`>6s
zpLUT(q~NVV?r{)k^2*d|+Ka_I_@R!bshx;1N7Ixg1otCS_r0l{>VZLEu3%r=QI+qd
zU6!>G+C4<icDvSVOxk7NPJDz8*D*k&lsdILF6{?$ig?xWfcLw!I_%-!mT1Q(_14>1
zVSG|#>43C4x#@Oo0eaSWyY^y4+7E-)hi**Y5t5PeJUiekM-zu4wZ*xNzTi+&kIQzp
zfKp-1-=CD)(;9Z)!`hW*;!-ELRDYOEf(BL^KdwCtt_p8SwablflQ!r{))uddZb}_b
z-$`t|EM1+o@!@Hg$xJZb2M)%k{ea^UeIU<w#>k~LNP8Ep7r}f378|g_fYn{Jv7K3>
z4I~6RK$hmcFwRtOO1mf{yJ`cdYD!maF?3>YSDm6MO6wiX2$RHLbVu6tqF6AUg*P^F
z#8Ha0%!tA;VYo`7wEF~P&={rlYM0hPOj4($rJI)QF_DB5ah<8LZXCn3a{!CN10|>M
zO>y+cTE%!Ue6TX~mkCB*IXQq)E=W6zmT^HKbdz=U-uyN1@SH0M#1u;&9#uLpt&W~c
z2aan`aO1maH3X?n^4q?%D8HWa^&~<_ttKW)Gr=3+!OXN@2v&xrT~_%^Qcn{sIhEF^
z%EQurfX;tPgy;`bK^0DSwC-I_R5+R@JxzIzritGYtWQDzv%71vv2{|>T^rwS;#Wp-
zqWlGE(z=9~ar&9tL;HOg*UK{QlxKQqeUeU8kUOE-x^5TmqsMyxK1ev&gTM?obs{~Z
zYz&?00B<?5SGNR%me5nD?R|^K+y-UREA7S!Nl$GJ7Lxs<Vc>88M|!~zWXoTAX+wKG
zk2RA+Ee<agaUbpz{X(^pF*Me^-BI|?u+|l!<(%HyK%Av{31DUh=;Q_NWx~~8pW2;|
zPY`SW#D_u;TeM-(wnR%psP1FOMG;mh^hE8vtloq9I7S=jnS;F*<yNfEKacxL_@V~T
z@Qgk7z+QSzv?XYXeV(td`T}L8ci^M711Mq-#0Fz~l$#U#?7<OXU}KANQ;YIWD92e+
z;E&DaO?5i$HVF|Z#J5#rv>u3fPXk1|fV!atsyZq}Gf}|YDnt5c1H+=M?_f{i`R5zt
zs6N^qomAiI-W%7>`i;u2k{gg68U@|NbqeEgPmS!?*T}U>S6?l;QwfYag%|;;C_E=@
zd6Gw&DTCq;vW826aryr9eYI%<3&2qWpiKF4!vJk2LZR9LT7cref!e#B`%@i9)7V0S
zdJsJJnEyzuhA&LH{FmdjZ#ZJOnnBuwpyRg<)n4Fn`9>T_Q8JwOMDMkFW(|507&gZx
zX6v<!6TNf{buZd=C1`J<!Gz&j@3>;b#32~_T=E%-ris;L*@;;bi&LBdbzzDeruF0?
zw{#EJ26e)f%r>hCr3?ztcyXLp9vZI2_Zq6Ut{qK7l{SO#p2R<m9P*0f_2KZV`O-N;
z`vclNI|8#^vA=PIwvtC<=Fz_pg$qzPA!cr>NRAsKcl%35VXEmy_d3kUd3)*h!Sv)l
zd%b1-pwp{&d1d4nZ5J%y&=}Bn$*8d)Tp_JvA=XN{VJtKOG3{85!p~pEB1D;3<4>`|
zSmMlf7NbN>BHOxTQYWO<f|+7`Wq@cA`4RY%n-(PxC2E5@M3IE(`sEe-#2R@yQS07k
zA_A-vn5LRKK-_I07W@YRNH-05g?a%PDr1wt43`B-@VIEcHc7h&E0#)WOVK`uC+?Z5
z<+alnlj!haS)2;?`uM9-wYD6^)oI#&&Bb-nI!<d66RZ7J8!VSw{LXZWI^6Q|c<qlj
z@yet8#S<Wj=-6Q|s?FKK<T4X&&`u~recMS1R|ZZ>kjFE$zG1P{sVlKaHe_h;@K||h
zqV@)WYm)YdXzPEeZ$o{X47mgKtww#DOt=H}t@4*Uw70s&l7?J~pOj!gs{w7YBpY9d
zuCr?$u>sa-*ZOuIPLe_#%+#8ez5sXQShP&YR4y$)6Bx&Si&6E8^krgL?ecOayi=Ca
z4^ciRIj`JFryWVPP)@w>o%D7&)+<@sNPHS@Sr$|!UAA{XGBI+nL+jP$E#<3QH~!}L
z(&>N*a0zEJ^yhVHoeWlRK0a9+cxMS&a&lmjJvg7i)MFHTdF5O2tgBF7IUMheFjAwU
zxJh=3_;AS8NO;)#^;+}Fv9}Serk)^<Y?utT8l`y(d@eq1KLzu$G9?mkee9$xB7$%C
z1`6YGJ2!TcUG|%*y#!sanF{VE`c2ccows#4aTwp;`bR3J?!>q!v=x2V=3R+BahPP@
zjph$D7Sgx`8MSw5cVO8Pdp8>6g<Ixn*pHRAdD=`<N#X?D2AnWc{(U7*%&O*TKZjsu
zIh3cxi+v`4ZJu_4^NiOT@&^n5FZXGyu;{7XczS*>`NyT24bSq-Qms#~OTSWA=?|jC
zp4+}TbY%wzq{4CI(x)4j<t5Pf5ksW?caU>88L|wEhNFJxGA*2o?8|=F{o3E!iIYs)
z+}cO{(~XlCjFR>h+Ng~QxKdZJ0!|}aR<6*xh+OP(1M*q&zzVIam{TQfk70WA>7{pJ
z-AY(@8`yVa-9XrLb?mt%dhy&^SwpoFbdars8olryrvYoFb0v_lx+c(|=Q=BOI6vEf
zMy)&}omV3p2;HfJ1|4gm!Pg?Drx#U9Zvn7M^yFfrc(Kn&SLtwxS%*uF{NEY*_gCuq
z57a6sA1Ks@!wh|eAZb+jJ=0PC;MJkqsIme^y9#ItI`HX0rwff&LiHFlJVxEMIDw!#
zB|0!DJ?_*gKVGB5_1QYyfjfR4V7v6Buf%|Q8)COXbhl6C%U3;Gl-OOXBki#nutC-m
z4X2(gH?k`l^z@5H{)<&cx>iB?omcC|v$qsAxBhCSj!~&&h=T?<ubK7y*9=O2o1Xql
zjSk;%8PG_-X~4HF(y|)lEA`^zOo!FkIy{x2!}qIn_&1BJBy^t+8uZ+M)adXGvPoM%
zW(G8Bf9#XCHO+na)U1m6=lbY;Zq)vlQ?FI)lr@B1r6<2Oh<@YM)8EwU@H}o$t_7M|
z2bFs6cQyt21)cT<BfAcJHH6F*kpHIVi#p0Brq{e=(7$Y?FV{%#I-p^bh(N85^+SRV
zfAks9Xy9ijzDWqQY(4vm0k0Y8O^A0Nhh#*F4%-^(4z+r^Ljyt5Vg+n^Zbt*ljOFSR
zDD~;tQ7#>JtJGn1t*oNrY#lgtpd;gd;n@YkqMxGNMOckGi3u{hST(4CK{>^&Q%or_
zV1o`*vvp{5%37-B)sqvPI-FRm!%0T|9ZXN(fxV;kK*y#C0RwBQQ!kxnq-PlET=SME
zfn}uN@sz~wH7m#$>-|`46fZU^=hw=T7PXeT^jb@O2CR{mrxZ~IN_1MwbXxa&b)@?n
zboc<ql#nrI1axHKvgxI+8XZ2Apr8!j06Tx!tY<E7khTrYb^gF~oX0o7ehoTqm#iTa
zy+}Nkt=D|ar^A8<9Tql7=hF&}fV>y~2>3503vYsge6`O18ke5E&LSJAic?QMWwh{A
zjh=qmX24n<mO`VS0lHZSxU)>DO1*GPl@7N$b-2wU&CjCPptaqrXYVkIciQx{uU3bz
zTci)@a@Vt3ltGdo(YZb1(@~Dr;7k}4OLS1B=N>Z}IN{aPr(6cCRZ#9L0m0MqEdo$*
zBA}Ou53q++iX;>oK#ncdhKY|YvX=62VoZ6mRJ&JvlAu%k#Gw3HiJtzF8L&aR{)jqe
zJz1M=K%W6?6qJAaBZic1*$7Od<h))YzD>|EFB&!BK-8!;AYdePo1XmHfQ?=~eYIAH
z*Ny7eOQdBJ(BVNg!DFyW9hxjU40GzRU9AqoYY3{@i2ziXYIQTPd%E<r#iqj;L@k?v
zmY^pGl;|*4Ps_(QL#N{m+_)-PL%4`02pE(Hne{4zTsj<Vq=(>idJE7HT@a|zOGg-d
zjPmN~(N#Je1C=GT1U+f3)nSs3F2_jlkqiecfx~oQv^U;pZ@kgM1e;!ULZuEfvZZ+|
zYMFIlq>N^<LQvwdyA0SMeS}=1fII*Ripd7S$wr+i79DqrS0<DxmK89XpJu>pvyPRW
zZ9w>B!glJ(83xfAI=XDL4O)c5^ld<K>A<IBQanf_IGY(zPs>-gK_quWuc=D54ytsN
zc}Cm!7*+3qCO@Y*RludE4CKWYz0%@J1J>#=-?C-9qO4kf#2~r6L@!<LQ&8Ts9b7z`
z;4j&(Rfi;IPMb0%*Ye1s<&U~7`STyKJn-OhOWvYI4_FpH_`sr=c5M2iiymEMS@OWb
zMQ+QIM=Z-9e9)4&WHAc-(|2q4#KaWiKhBysV<KW~{KCyySd9a|?IOU!Z=YH$Yu?s+
zMPxZuI$}kGkzcjto#t$_>#&}kjal*?t&7KDpdYW$tDP|E@I#vp|3|&67#?Ai-yUAv
zs{HnFr=AYh|H#(5yn~TGUZV1E&#u+WjkKrBr}0L{Ssk8?GSUV^RkeEh=WGRU&#uwa
zr*uYcA7W#siL=rt=ceZvvQgz`hf~KNpx29dPw#j{uw%cfc0A}=l|qd8r9p=$4S3bm
zIvuR|i@`upB17irctHjS81;Xy)AJ2RBi=i!r%xF9s$CBQ10__z7+3#>M^vjc@)coZ
z#!^9e#0iT54aTYrc-%_)_$k=jp&(to_!e|gzn4;-TB;p>d%RtT2~HitYdTM8UD`R!
zM!K<ddL$(FRs%ClPM?`Gd)f@##|i$zgCdUz_V~DsiSgMj%7c&1P|L~0GFAP;&0$gW
z5FYWikG0L7Ho-A5XQp0cluxCeki_0T%tB!bcj(38<|)?+1NmoJn+ci00_0a2`3<b?
zgv^;a=@T53Vf;|OmL9_+-Z8P;CQO@>J!E|Dq)8KJG?(iFiFhZLwa-qUG<n*jAu~NW
z=`(V43=qHxvLaw-?d%iNvxlIKU@7v=lWUCfd}dPR6Q{P4*yK${c`*x{l#$cAI@MP#
zfx!yaZpO4JlV%PX?@6C|Q_q1AX%MJpw@u7W&z>=4O8Om{6DSiu49OV<Bi^ZF;d*)I
zl=LApGw)I~P;M}A+{D_9pOHRwg5G0uW>5!XS=)r>0uYlW?`mzsQgpI!V_JS!>q;N*
zBQYFzGHr6E;+fKByV3e_FKd%AEhkeKKk~O5_*<ElksH(y<S#VxD_O|2S;2uo{$L}&
znuTN=REYi^4SK%kcr6Rbm@&<ugn}xgLL<JcJUhKP-x%-{W+u{t<4lAM(>Z~U49rNQ
zy7UV-Pr9sN#0hBf3>!Vu5BU`eMx2<#LT6-W-fierxOrlNQQ%^s856T}lsKt^(X$i9
zkObw&7=$baJ}wH(xLE;oP8<1$rTG*D>^71$j1Qtm^$Ry=1o>-Vd`K`G&1D$;ois77
z{A&>3VB;kAE+@~lXHHUM1$+x3gh!mTf{hmW6VB=Ro|D<EO?u0Mtwx1>rlsH1>2UJ|
zonXXCFB8*R2zY|oz{iNsxmgfy9&hyXWF_M^LQy~D2kBQc4pDiU3+B=zIIU%3g3ZWA
zkH^Ov`Hjd|!c}Q=x*?%=G2*jZ;HMwf@!!RW&u)odVB}-OC*Q<h7H&>gLm3|N?i>`f
ztkB-5;9_FV%?jaW+gT&O82K&mZHDf@>tpS6r>0NNykqLbj3GhRP%lSjzpq7lf=nUD
zklnjyTh<6N7j7OG>`G&+a-&U@J9SQ~@wu54dQ?B;htLD&1uMP^cC#Sdto|2Ya<kRh
zOeC}@NX<4X<l_#3BBIjf)F2@Ydcw_uaC3?=xYb)>ozpU==~a;LGU!yoNT!W53c}4v
zQAU0>zJrr7ZSpkTpu^3HRYpNAYnw4`P_Te9@k4n(1tY2(seJOp^jSAuq$;=8>E)-Q
z@EQ7P<NgC7+?;Ai@RXH>Oq`<}SVvVcwb-aQM^>K3Oqgad(pa7%?Mb#7=@J$)1s;o1
z#8A>&1tU(Ohcj*#gqz1y8Tshpl$!;}w;K7iz@L;kc`_wIXLPNC5vLkio4Y1V%bjZ2
z>!>P~?}>QN%);z2%$qKq@=;Nb0vS`PgQ0vc7SSW{R58j&Rw%rP_p({L36RIsA<d;!
zf7Aw}JRcJq(a%XAKl!FmQLa>hVgacA5d25D`i~km{*&o|L7;;1gkW(C#ti(3_h8^R
ztG6uYM*TX*N8GBuKqe{a`zFRm-U>m}3A`W6_^4Zz8%q1WopB|7h0`oKW-{vMLvnqG
z8+~X|4$;CbfdLB4`;Pc6g2f<ELFJPsDf%sYXh`UN=mM4N7|jg?g5`A>0#zQwQFLjD
z(LPSsgNUb1Ftb~6+D>QWbOIB@f}uf6MhsD(hPe-$t+Uxuhj4h0UwFi64D~QwGbs%Q
zsD1hwqC8y!ggJUvD*}cnPgkOR>i?y@hJ{R+XefV627~n*m^N%ea6Uuu;&Bo&aAv@h
zY7oM22B069QDJtA3PF4?s-fO*@NK}Kd<%Tvt?@k{xKLrvEh<#qy21xO;7`2;e(it3
zuVLDR^x%x&9AST8QTU#SlLXO|V95P9#<bbDs*tVY{RTe)5!<csz5fN@iTV2`zNZC8
zmH(we3Dc(Dtk43#_P^lcY<fcaaHGrrhqSkWkE%HL$Ios8*@Up1>_P|uVR;cF0)`i9
ziik^iF+hMAKvT6E5HwngDI!LT?CQ_j)S^u-GF<=Gre5n!t@WnVYO2=eQp9MvHbtrt
z5mw5zDOH<mElt(h|957dXU@slb6W4c=kwW2<~z^(JTqs`oO5;^deg;{jUATb|K&a_
z_hLVWv?la={HuhOTkS{R8bDuT<<|MpchdOJQjoTCSNbtz0u<mJv9M}Et#;Y*_*asg
zJw^E|oEzlmaM8)}hlb99gxwJ>P%j7_fhL3{9{O@EIEy}`>Gpf+@dJ_4;MHpW!8l!B
zuL&tDO)_@3Xu*7$X6Q&TCvA5JF59F)<(eb!Wn0TNbQ#bg0)~#q|I6J234bkT!c}Wl
zNfZ$>20l-tpqo6}*QwfL&sXSje~&J?owowmfM1tek=3}sSzNn7&4V=m{c{DZ=!FO=
zk_EbMUkjZr`w4H+B^zWE;~aCoxl%IvQfBjFU!7#cK?+zQ3pj{Ldd*tC{51m1p29xz
z+|Vbj+?m-5V@#(@oc|3&qm?_$hvAnc(kgh`r^|m<H}YDoK{L%YpkweaD_ru_`QHsd
zkrB`b0p^;}5x^T<Tr&MD7zMLF1-+XO{U43Jf+=z3Qk7ZKQzzLH+EO=zqTh{CfhAY1
zY<AI`{h@ZvXAJAIa%xwph2H>r<cJ>s&nGkkXE)c409*u5GZK6ZqzEz}%VGXQ6^Nv{
zigxi=sQiz{4pj{_fa^v;6Ozf#09H)pq2_^d*bv5zybde3b`{nMdi*&San>KSwIDMp
z%60t^jSe1OFZFAjXSjV8G#ooL9wdhiOR=Z_Ob}cC8%)jU3bVdnUau7e8qSgB2(bey
z-J&Toe*dXQt)I>#&Vf(o5XS#+I<1_UW-G<%3J#Gs<g9=V=8_}yD%J}#%@$0yJeI3U
zIsStb7=alnFe%-~@ec$xsCF~Mv0?v6z8e3pVd6O7>`LL9EmsSA4Xfdqywr0kHld}y
zWkX+UvvStXJX<p3a11r{^$Ir=+-p5nDs1Te7@7t$^hB)iJlEy?auT@TV@MD71LnIn
z!3>?pfF7*>bLP)qAhqCdEZ*-`j7_hlE3uzPSFbFPx8(PCDt_ZxPdjE*pBb;mOP9*v
ztX8|$Ty}deK3~UhTe6^<HcXvME2$0!$6m*^p>fpZ04FIP+ER4fMXy(3r^GNsZFBd;
zFw}b(nh<i=jtG1HdYz{0YV**yf!?Kn>G_s`hdvd1y$5~eqkt{<FvJc=tekRVk<(>-
z@_D^uph1T#Bt2W?rN{Vxz1PFgfIT3lcZJj_AkR6Zhp{18ZanZRh{g_=c;w@3xRxEj
z_&2B9*PAtAmdE{I@KMlJ?@#|mnKk(0rE98|stZ*|KF<R@Rm=J&nM7=%IoXiKd?)Pn
z3i6;qm)!S;o=#R-bRN&&s1xPKTzBluydcHGjyFg?NA`_AY_6LL$Z_Pg4o%NXxvnN%
z=aV2$d`!nPF3C;Bj+9%uYZvj%;|Mm4y;|V&WYE4AS;uj{{DZ6RDk|G_$qHU0K6c<p
zvvj~aAtLAguZns+kv-C94PLqU0=j|dIK(;2qgzEto^#m3H|wzbU8yf`;F-xq&Jhl+
z>FS8~_{|1g8aX)WtyoYeK^%^pgK1Td@o1KE^qPkRv1Q&h=9@j}A|ug9V7(UXH7rQp
z(J~mQM}*X$Eifyo|A~P|F)^<7IXUhx*M@Oqj&@mL-VD%smH*h#?AL_etM8+IU@*5r
z977Ggr|*v?aF*7W)B_yj>lCm2W2qW2_$V+8UIo|=SbWi9HJi92cTC!kTrwv?HA<Y^
zI@XRma@g@*q|(cAq?X4mTgH9HAv@M<<*c5+NQrkV^d=?KXA+|2x2}1mr&Aloql}Z)
z@V8NW4V4L9s?p&Z92sn!EHb0RalpuF(tMPI=vT^_OoMJP26kBC6+T_Wj<caGnCl!M
zgOkBL^Ygr;<zQa%dhnKIg%|lLuFwX)W$Tg!u|hWdEhPCOpHyK7-)eR_D(98A;OUez
zBq$FjWb6@p!t)B_N0N#@#)g<-%?46Ly#^aYkus^ZD|kFQig^a)>l`zclR|Fq>eL3j
z)vwF0KDv<V)phUubi5v2%IdVEYF>%)jJLm&7%9~3>6@*DQ(toZc;i5vBV-~G(d`_1
z_WXD^wxm_W^}J%Ha8~%KL*7FMP^jM^!}qso+!#_$bkuI<r4$izAM)9Ae+e;=$87m;
z>#V_RSDd|Kl^W?zm;JLY`Yjpg?V=R-5f3X?bi%d<uU>I>?cx>65ECJuhd5GPX1d5=
zQuJo4uAfK{PL6oG$Ql1U;cz58gqB5u3|&CoIM8GbUg8(2PBKV!1;)QO`B*V~cA{A`
zu;+)HNC0`XzlGZCWQn6({)xtpQOS{I$9TR_xLQ|G$e4h;ggyB$?8L0)E_cljJPcU@
zhno4`wya#k=Hg?=GB6PF$I7ZkTl`;Dx-<eR@b#AxQiqdlZxh`sZL+~RdA;3)^@7e!
ziJP2Zdaq+|w^^w{Q;dlY16z1JqZI@i*n^qVSm^M--K+V$2L7(Z%DcF7b&d11iuS}<
z%H#f*Jz4<wEr<A*)c5=AbvsAucU2;D(sed9a{2@0>?YhR2hTv&Rl5yTbXoQtNDzOE
zF3G;pv0rvjL%lAIf&HT84>`qimlOUwqT@*aj&P1N*O|W;k5jt&du=V>@UuKhC6;ga
z@zTjVt^j%YdmBg|@pIkqW3gU&@v>Fk>oe0Kx+7ye@iO1<len&{Hhd`)$zO601TkXz
zsB{<&-|xvlcHGnn|9!J|#2A1D-Nltls`XZ}>(&`Zn7S^;f(&Cn9@e>-8J*nb$QnM6
z!jt9Tt1})O!&PR;>Bf5@#tKh1ScB`TvlW`IN@&kcHVyRfBpza_HXb^Lau>3paz9s3
zHzeryogP6w2$hfJ98wc<@|bhgYtSF?m{Xlk<a#^QWt8(sCGRk^g?}g?XwV-JkxD;<
z$Z%s2*C_|G3_=dnsR$*N0@EiP+LOHsH~YF=&l1!x(tmV~q5~Pt$EO-TwJ^@-N}k5J
ztKUglp{0^l9Zr{VM0pj$fni69KNWjtw-s8({H~ea2;fn|WrHMkBF_T73cPh=Fj8af
zN`3;!HHv~1@-_@BVnOd>FYm1JY`Nq4K{Ax@1#%?Wp#6Q?0VPL{qIX+x#~KfhYEe=9
z+zp!G-5x7v6+iajiVW}b_zINra0R=HE*IVB&euz{TsNN@MeNagxJaMJ50beQzEGhV
z`BcO!#I%H=FlYmd=t7DNbi5KZ`s(EdbW%6FEoDXKHfoQgar&G?YXo5tKGUZwSPpj`
zhn~B-y9EAA!Q8+C|ESLHasuPM8AWGC+p&Jl*QE@@|4Chcr%jg}v6B%GPPuU)t??IA
zHeKg*640#6KQ>r-ddmJ^8qlESoJ{J{7?#%c1FgDDy%=ObFAPu<&HvGWUacs=fK)8V
zfIdV(&vgGw19p?*h{u3-T|dw%ODx(04L}6+-2Z<w;15k&p^1Ro0JUfj=z{;25m0B*
z|C<3PNui$sdi)0&&}-$IX9+PMe1@|3{RV4LW%YuU%cWzkd4lH!zP@^&Jm*pMep)_t
z&ySz08B<<4%cmHWB>EGLWifV$@>4ijE$#5o^;rcADp%F6nScl1_3dye&-T*&sRVb-
z7p&3Grn?M&o^piehd)uS@chE~^IcLe?v@&YJ_W>HY||xADBgC)`ErG?vp6DuN?L=~
zRMoE156!vGA-0yguTGXY>g69Kt5MJ+0nCWKR8rTNb~4ZykRZAWD%+_fkD1OG)?*D)
zk(Fc|F`2Bq+xRC^%nTpk@r{Y*T@0rS^yD9neb8!!&6^q!xU5V`rax%MZQzN9z~R>f
zXwO*rqOw0{__bcnKU>&dShcox;bKYa#PEY|Rd-&?p^&k~f5zEvzP<=heBPw_GhTe`
zcdd~2QpkRtB)Ke~a84TUYe3xR%%|TQaxQiMoVLQ11D=YM@^K{OA0*wM@%Tlh-&2iw
ziXe8X1Om(y;krpleS4|`PdzQDtzAraPx0KRK86y19p1)Sx^nT7#fukF3ksGa&yWQ~
zh{rG%ui)1+5NU^6GQ>`yj~BXzVOD!5?zVoeM)i}sr?SqbDmS7rHDSr5<ENfZQK-$<
zlc!5hWvoHf)zioZClyXLkORbjs%2oEQ{pcej;m`H=uDziQZwW!4kZaN3~A(^WKiLE
z6mp-N^+AbN_!m-a9O%`!k=Kriil5Tf2FUnhhV0aYzv|N^ui-c{ETA77HL!;w?-<1V
zJfj_xVj!30n0AWP3klu+VyDzE32O*w)@6SZcSURXVc={<W=dbD=}r9>T|Yt*H8UJV
z$j~J;-To9c7!TX<!0EzIp?HBu@g@I5#gZJ3r&#e{6IRah#h+6!8nUwgue<T3NQ*yr
zz9#T#@4y={3m4+u9VIxMAGh3)OXfZg%||N!%96kKTZ0$Z)hwo0WXxjpuardI_YK+b
z4@>Y)&SE~1J6**SQCFKX$a!6`Lf8MSN}O~)EYkpI^`9Gcomb6#Vew)EF;bWDxq=@)
zFnw)nI=+x$KJNRCVco9IF=~a>tbq@4N2rq559k645xu1ljeUe=`=Z4Q@rIh2Pr>MT
zd?2aid_)eh101Q3Dy*EU#dVShhvq~4@reFz1;hdwo2)^r7Oo++jzZp33gp9sDm4pu
z)^+%Pp4R#h5#9fM8s&>gV=)$~YgR2<dI8VMlF#Kak82LCm9GV7-EO5WGj!^f1}==W
ze%BJMTnq3T@-d!zSYfu79Z%Q*o_OA-zUTRbCm?P=k<jwF{lygZ{m1QivSp%dl!v3>
zqkdI4Go-gq|7PRuiB;7U<A1={qvh}h2w%ph*g_U;rbaUCZ&et#cnM3gyA9*bf0Omz
z5UU$|(b(VW6rXt};BReK$oPr#zZvHyiOABAJ2j(xkVGcw$4Omg3GBDR6J6_r<@K8G
z6XG*>E!s403|3u*@o%1L?9v3Be4k(kWa4~@$-@clD@j$4Wpxc1&Y|5;5i#;wt(>yy
zXG&%qBu|e2za<o4`k0gD%~p-`#Pms>u5<GItwYy8Y1gGugdLK#CdQ88-U!QNRpXy?
zASlFt$8#KOO^h9Ze{ax=c@zu`tt+zK0}cE;PI7B?Xyy2K1oDN%|1`9J#~QM1Eyvc8
z$C3TJj#Qj)p;M&dR#nOhO_#>0!(sfpuE$RG$$z3TUfCE%tZG*qM#C4kS~R_(!yW6j
zest88r&2)*GFEuHd$C!s1#?%ifjl}m%iWK{NDiw^^YJ}7PRhS@YCL7$j*n=7yMR4s
zPeLW=Gh>nQn3q^_i#+-t8iZGLO0;6O=u;cih6vHT=guK-mUF~Ds!@7O7il_-f1df+
z({Kd@S4m=dIGzRyZdP<2!9H?ZAlExl$??zE={$_GrdC@ih;i5Of`aD-vkXrX-ELj-
zjtEDX=YD$EKpCvYzge$$YDN=@UMqCIgw)|gg02OP$4sBI8!xPyleI(7$=BZ@1v$%o
zbN;vfx2svYMr04o`Mq2#GI*!1b8>Rzo=;HLzR{ow_NhAlPv|<|7v(jeNls6fn6)0|
zLQa>kBe|}x59!qMy4rMU^h9)>yOblv7e1bxi|6!s_$i{C<b3L&Iv#+p&<tF91jde%
zKo;O_Ki;VMIdZ%(;&Tv3@-6MSxscLVau{7qXp)cKA^4=14C4rB0rA{!D{s=uwJR$5
z>kTBCYZRJ6(x&-MBon&MgG7~bbaB^lh&d80i0d43lS8zCG0Xc-kHRKWSffjG?Mij&
zuo_*gD68+wNB~7(faU+da5k7j&m~8i%6M+CTHWFe912yI0h}9bKtda2LP|K_95YGY
z@F@*%hX3fh_+V^ME~u`iN7kKrfv*ENseYZ*f*I#|B@gq^RN15sAO1esfcIQ8s*LCL
z>pHKl<B>8eywFI<7Ql<%1N9yO&AJ|Gz_%d$BYx`h1L=YMe03d<;AB<(j|6DO7~QyV
zJYWNQ@hu7eh`(Jaj_GaxDD&g~0}044lU=~;`0NN!=*+V?d?VE4LP9H`WQ#{A`_1B+
z3^4kziC$Bk8o1dc`-m4R9C9;kNI`e2R&<Q|(45?=G|r=mhby1tyz<n8V{-hnKyxFc
zLkr^JW-RWp^03Xmbmavm&LGT=6i?B|q!>p&hdiF&t8poJG6>=YcsX$;eOH59ASsUR
zP2iUZa*NmNonL%QkM=Y^1e;y*YlM^@$B_7t5>iYhJ1_*_!m}Fh%`L2&hA$rC>65n+
zq}*?f4{e(ojSs2A*Zr(oxn^-4$yOS8(;DqfN<n-`zo;MPI*IZ9N>*5yum-JMuwt>k
zMsgy>UFz*B6EPaD@6>5WjJz7`Z!TTA+#_#vys$zWR9Np}Xce~YGLRMb+a9`ZJa~b}
z*L5s8B9cZP(fH7a6)CI5Q^*Ud`SMKS-aV}NQ0xNWYl<kg#^F>vUq>uP6IXnQHaNx$
zr3g7Nv_vU1OHR*diWju1b|a4?GqgtTaY_4BJ6|)$wY+MqHG4FpiIh&l_|T-rjbfrR
z22xiTMff@CqTG>Z)@!yX9+4?qvUKGl6_)IPL~BHQk*fo^$IYzKq~w@Y2oHXGY{KbS
zGB>JI-`T69c=07SpW@89yhh2#MTGXtxt4F#ieI79oVuFHu|}&<Ii`mS^}6ZNc%iNN
z*&#aT#)pu+H!7&TPL}dC*P;QBhsH1-JKRyxdZK4VN)WIzjq^F1OZME%S`C^`;pfR|
zh%7S`a?(YBc8&zE7P!ZURfu%l>B9K18qLR^o31QZICmLuR>XNs@&c0QWwY#}h}*dN
zFiED86ywZhd_K4|ZmS63;(#Ne6`HFajs%yiz%0olN^s2E)pmzy91aJU)ysAqYO^sK
zFDkbRmabT_c+pbK4Cm`6mtpauDv4oewdnG2lP)=MMRiub;g?P7a8k$&u^!og8(o|N
z99fE#qo_?0@)dQA&uB*BZYv@KD8C9o=~91;Lc_;BY|fmWl2C4RX-o8tC+V3MVD3M0
zI~#b4B5GE^+%qMT5i9EsU3z;Ui(dAmJQee~`duZ+S(tjel!v#uE=_7hocvsRyE=yV
z8Ef!83HlbCD>4<d6z7|!W{bZ^3+70CNFMWal0{dd>CGswQT2E%p>c2SvSWy-oFlSd
z%khSeL(hueZPkJ~2jVybtzN#g=3=#v;CRT6c^z=%N&T|V$>XdY@<!dxIlu-mJx7R#
zH|K`QfjY^LqfGvB9A!E0&S=#QW`3&Ib?!?p+0)?>QC^Z;JY~72iw~#Jlj3;1Lh~DX
zd`~Ipy$?~uN8l8uzbsMF^Qkkow_DZYBdW9<c9bvw%q<C-yfSdIz*@me|5Crgx!v`Z
z6D^9v+`Y*f6}Dz%$9XMa6!htKc5p-;zR1OVqonEj_=pCQqXLqOn#ge9^D~MsBs3wf
ztof9}bo`K~nKvlHysF~S%PGLA!gAGUP00toy2zr4F4=?P1fB#mlb6c_qT@)g0>hUH
zh03HTbr?S9xf;DXQH~?cF|Q;grFjM+KC&bfx=b-E+~fc!C-*(?Q5c-MfNrRp$Y#l}
z!;SSd>itMH%$+-TN@+AcvLh6_G~0mqNQ%^Zn$BFUjqI^PpU<W@9#e7}erF3)5A%2l
zX2SE$Q<o-W4nvQW?mF3WS2YmcLJ#iI{p>&WYMi^Iq{@m&@k^^0yRMd?CsnTq<Fw*6
z9+lv>&s^E04#%JoT5)`6y=;I%ZK~uhikEb%dc34Wm5w}It<7DzN?v}*20ENq&dm~<
z_Yyv>;8A6v(77znS*OHH>Lh3kbPVZKczmdiXevI^6RJ_^P<Y`4NhA-)b0d)F2}R=?
zzB&@IU$-hgj)Ylw@fA1^XFY6X|CcESbGGGm1~Ztms<zlfiu-m{cPPBt$6!uY9xdi%
zr}f20WuRA{<|))Mx(qXx^J$%@Sj+2ir#74y+dQ-F8;F~Q&WnuK5Fbi4{@IgKg#HpA
zPfAtDoxKP?x$(-$tYs4<IHF6IJGv?qp6(+T5mMvdoMpWsV#ORGy2<jXBjmj)GrARq
zsPHQTF>3VqHxq^Bni^&HdIgLrlUo6597_pwm?Sm3x8AiY<$y7q_ax1Z+ZgQstTErm
zoqfqYrqdd9)~A@D==5qPu6J9djlmOFiZ8*(bZbJM8h?@0b<ZASd`w#5JmHveJtl*%
zqRBRppAhsK#Pu&^_dO?1gHpr_V>BA##!x*R%@=U<#Kng5!<d|er=>;xc;~{6_a4kD
zpSx^-iFTZmnghae#wJ387RX%<N#>fL#`I}E&Q-lsjhZee`|ur`G>_0!Z6Y|fDHLA1
zL`nU}g6otbui#+0-Jx8h)=DkedBuUJ==j(QE$}oN=IrUXvQX|~{<agBr)DN@Q+(J&
z_;d!Th+@KHg~s!7^&xyoAAb+E8BK8xDbF*;u&z)ZzWLf=QLZ_BUIS^Nq#~v!yn{Ab
zu0o0b%XFO=G}QO;aoRIyo1|0G#j_&S9}2JX={h##m}J8!#IV;Bo=K7(Es%48aa#Ox
zAIHaLv;b~*d!z){=yr}!qB%4O5h9!1k)a8X&l%$yH6t%>S-|)btFU(Q>Q&VjEuOZB
zHUeGQZbpx1)Ud&(Ysc4x230P;fF7)cA-v$>zU5(S6t`k{U9iAms8<GZvYL~nC+Xtj
zwIf+wGrl`C2;XzNRP6*JiBrpi1gcyx<26v=1dRWStFVxhc4dzW(^WiwuwxS%L)eq7
z!H%=qMRxaz5)>bw(IqFHVQj;0to#mQx`tiaA?f&t#wTP%a<VhA#V7R1Hs{hcE7>Vm
zc$vWK6E>K8gs)eECPZ^(x?AZ>nVcX7&IQLHGK?LYXobT3Eza&pQffGSdXO0TJP5iv
zm15F^4I7?WO$59O@hj8(_0XS2p;4p_V26w$6e(?}T*>jdf(_we%^pvx2<7s-W^My`
zo-hiv;jAz|u|#|7op&a6ga+}~SIdcw&&pY&<we^as%W6V(<7ll&evK019{~G<sssF
zV&h~Q5E>^k?2(xtPOl3McD_LSA1JKJQV76F@}H;m#O5T;zz{kL@yiCQF_@+~F9}FN
z967Us;~gSisePd3ndJ)O{MhXCsS0Ib%)6yz2pe@fM~HDQIY%Z}SW(QpYgW~|ZOk^1
zXKcRsPI2;agE53GXPj4b#_}3%nDH=x-Ww5PaE~>3)$(a^+zbp~{{<;a9ntt1%_1`;
zSN<&dS-EF~Iz^c*dPU7yxnpC?nT%-5Y>_@o?mDY8F*iozWl1Z4b=9hi2maWG6AgZ-
zn4F52)k$7wE2FHz8nSYgSAvUQ4{csWrm_XJSwm`Yms9<i20uyf<cp#AT)LQBIMluI
zaKAQ;dx1-iVp*>>tfp4%oSIw8rzpO3#nlPzE__?d$l4mC)T8Mmu45SG3rcepbE=zc
zi0IN>V0P*{U1%=UTmFb*mLl6%K)kG+1U9QOerAnmoaUU8%;SK3%IRt&g{rskzp^+Q
z*Y}mo6><EG-9)Dx#Q*GQr^dPWv+UINU~^F`il5P;8Td{oU)SkX1lnqJI~!;s{)xu3
z6p$f*BFA}950oz-=ZTPD_CVL;XEth_yM)tVO1V`?7nsw0b}#w%Pdw}Hk9HtlL~>O+
zswpv{6}_S(VIFQVmq!h%-Av48uTJAe;b8LA<T=STk@V!K+yRrPB<=#b#CFzKd~P%f
zo3$ZlHCa&%x5c$Jcty#?z!|Z0FCjYuW!h1WI2_ieB=+3n@&Cy)=@?Jk?0|PfPi+$E
za@Qc>s~DcJX}*rrmYy@(>!c$%s7nL)kxC>{G=5f#D(Nx||3@@FRpZN@s}~|<gDK}?
zon7)P#rP!&C(@l6Etqq28lG>M;c|!<j3y<h2h5=8)BN7S#G9ksQ!IaaA~aaPzp426
zlpG&LcF<rR9iOg8pUGJxpheg-agOO06*F_k@-*t%@i!S6pWaLMb?TD$(T~Zh?BE6}
z6S_3}XN2=);pL<4G3VQKnUDoC0}&cUFL)Kzkm6=l#;5mNA@wGPth&xYyeVvVDLmHI
zCQEq-lT#_78scZ`lrhiv@pUc*)GU(D#;d*;uH~0VoQ&WUruR(E-tC`vEBX9nu71!}
zZEdQQL*sl+aH?IGe^EHzC92nTV<>sd?L2=^Q;y(;S8At-@=uJxQ9465kvu##IbT6l
z8sHQuudyO4@WWbo|H-ux4i6=nIim3yWuj$vF22^rVDcZ}_<@s)Yw?xs10?wHH;D}R
zO%BdTDt?}H%;dq7$iQ7`(5fy(4wA#1Iy~l>kMaG~vs@>-lu>v}M?Cx1YeXByv!uz@
z3XSt5z=rVPFpq~(&u}}H@fi)0ztCBU&1l^<#}yFH*%=*L4|mYaPCU=LuohRzuKsc5
zde)5(Tk)H@fHS6`Ps^nZ3T{vFjR%wKGw~jsqtE0zPs{OHT7jXTh4=8~uMaI=t#Vpw
z!D0AJkFnx`j}l!LjTg2n2J?IauiH5Svv!B@Ge#`l5zL;=(){d^V_3gv{ESb8y%Ez7
zc4VE1vjQ_4Uqmf`2+_OI!9ABHw@mq!V#7>Hw|b1Bvs<jlMGI<|x_<)56+shuuY#pI
zRamaM+^3ZUIp9jU*}bBr;?qQAx3ZiCn@1D9hM$86?iS(2X#F^e>6t)-_2dyX5ix6_
z57Gk_W+}ppzj*p|f!gtLaw|~Lvc7@x&hB^D=i!OH9tD^#n1h!<alN+I`|>DH@SKZt
zFpYiIiJ)1|n)X(FBlgn8^gi7`kI2%2hVtgSx&29JM6bQe<8!)0d9Gi|klx@h3Qc77
zB}`Uw8^=FWAv)(e4#fvX%9*V`lMY2{R;^xBvudSl9y0p4CwO`_tI;l+x6KJHq3raY
zdCl6utYvuNo+Y4M32+?L3QVq2@^gC@?pf@`KhqH!eCfgz9xG5c%pH%4scZOaJ-CZ2
zT0%LOp22t59eRo!E9NrG03!#l`<v(4ur}c3omuzt?a!=Bn<^avex-t!jr>3xFJd@?
zCiD@_$B*Ol)$Z#ReA}}@6R?G!jfBGdBQLJpGC2~s5HB0pMZ6cm^AdLv8-O!|zB2L7
z{GV;JB9)7)7F@K{{G=fyJCQP*?Viy*x6B$ezjD<g{WiKo|H~3>Sa+8$dA<2!b5a5E
zx%K$!7VyoNRhObHMiRu4n!8)r^K*+!m)9#k?{JOJ?G{P2o7K<2bD%i|a;})sc`kN@
zH)OwwX-3;e6luQP=2Z~As}}PtR#HK4XvfdR9qESujiP4duvbxlp6jCVbK67V>;E^3
zI{zn%qVahpqVxRRk@@wCEj}+TGO{{}s;#?{xy1!Dd#Tzf5=pe~q$+M8$f~|C5kJoo
z^|D&1ThB{~w5&csRs4c_5*Jr9Nc4I2){us+(>8Becf+)+H*S$cIHLBnR#nFFlZQFA
zl}TB_5w&MDsWN^Z-f69^9IsG`msb(q3H;)ugR>d<`m<X85li_V^x4l61HPBOw%TDh
zJFW5g5s5nr&ejuYe0~CWokKtU1ER;<{<Y?pHKX?QHo|Kx8xCG~{ngi8x$e4YU)=b`
z>l-agJi8#bpmMqr6OGSrum*$X%5^s=9=rSy@wQlnz;A5aux`u7X&WdykS&{WH8H<U
zL@IN~7L@O%dY34#%pI4%fvSC?PFAPt>iH!iEvcuTpn6iY$>yC@Z4mvkT1V9ukyt3H
z$56dPR4qhv2URnoQC8RJYBC~rOX?{Js+WsS*-WaEb)r{R$*^Qv*o%-8luyYvQNAd5
z+?kINZ<iI_dd=o7*IYmCsv8ivb(+hbav8PviKa!+b*8QB3vAH}_IwK3f(p?kt7&Sj
z7k!etjH0lhS(GeB{fs_pZx>0_3(t6h>OIy7@$a$d2$5Qxn^$l~gN7^dOT&td#8j4v
z4q2Z}Vk+@Hq^f>^=$k}jiEO7dsKob-qMn+32eo(M*HKqjPODnDXxh@1&ZY9?Dr)a@
z+UYky(GayK7wYzfHnlGu$bWh_wPPbt$w#}3|1A4->h6U#)=)`+OQl8A@J%C?k`D?_
zr~Y5qDEg%Xr&IqgL_S=ANnlb&(Zv^bh@`4NO!Xd7uj&-Ah4@Oy3&1~VxNcumBHCnq
z;saDqif&0ik$QDegXly1l!*~)Z?=Z6zyA6yU%cV!X&X0hzJ9ZWVc&#KRmK;!i;619
zn{XY~yG6aKPojFiXqNTy)B%eVq8;@q<EeudS6M?BS1*}Xy$b%D%lW81o;qML{FnTR
zBU;{K_`ekPCR(Wu|7CsLV^oL#s(l01;lHepEz$KQC8AZemr)%nNm)OQ(soIm$jJIQ
zN~k4GyOv3I3eS?=BC#xYY;`I1?~)E{$fm8E*L`u?hK=iQyjse{5w%ZiS7m%j#wxh!
zn#PUO6p?CF?c<tt`vsO27vD|i#l@=Sxr3sTb<9+1LZp`EPA(W{Q@u)Lpt|6+1l5t+
z%X243$F@?v)f%yJvlzBKx1=y?kIE2={#XvKQE959KV*G$i>_Bei>#M^K=mroBkN-x
zpnBu3YT2Bm>TXdc>!T=~Rh^=y8u2N~P<yXvRP|O}Um6iDs@_2LGSRN;<y5Z{-LgKi
zpXx|IRd1qtv#?jl_IXst93|_;y;ScKHL6a-X({xpI?*qKepQ#`n5vgSzpRhwpgQ!g
zz!ca>Rj8NM9;!n7N>sN{70OqFc{ugZGAKtqH9SJ?z1E<rrHjh-*(z$spV0VnJeDf)
zq^zQc<J(jjU!G9-3`0*wFR##eQj$sfTvf)G<H8kkW;1<kpTbk|<#_B&HY8;o46z-m
zj4w|s{2aruhH$*G4*GMFvMTAvs4~919Y0vSx;80m5-*}bwH#Z^z_l2OpHS`b<rzEy
zyeL(xx5Z=wd(bZ%YK><_6v1kIZ%fTZE(PRSb(#DLcL%o*Xa!gh<gTgYWkJ-ocM^`L
z!q-%;P0AWp;b^!_{uhl`H{#lUK_y9w+QZ%<yjkNM340RZtuhj;9Qtj9cW9jHhf!Bn
z<DI(IHMJM$zJ&ZjeH9X~?xhCBfrdp|&<goQc3{vUirUc!2$z@c5-0lTA;R(CzQkuH
zRo#wGCA^Aorr$t#y>+%?m_-ajpQVN-%`l4?hJHXecGoXNPFGVEIW4PqP!%aHt4FAc
z;dCJ~eCTjpUm3x#cPw6*lr@<k1@lxHUy1$$u2d;}3*kw8fzXPDwR%WI?LzW?WgT8w
zS+UUM4ZThkU)gBoE?ro;RB}r>g(a$-82fpPHDuY^6*bcqRxe$wfA3lm49O^h_{vsM
zR-1i8I`;EUQ3rfD?Uu#1YJu^Ueb#VsX>IN(yhO&Au<=#45@sF_;OnGS3He=n@;m5M
zyFG-GXH~t()FN1EZNsXjU8_-hjA}Sjtj-;mdWWhVxF}pPO}-DVq)1eHnBS(#_$vH}
zIog-hE_Q8H$o4h5y~e_q$l+@?t7H}UkVAyy?Se%M_|+)$#A%-*!+^M?rotM$$b7MY
z<7|zR<UD%8cP;4dv3X&P>E3Ns3e81cO`RxNlRGxN-1=(8np}Ja;WPNDiZyvh&lTY-
zhn^-r88&pBIIUwy>5v;HBsP3;-L$JVZ`>#@d}&Zz?CKbD_E18<xUO;9HJda(`KLop
zKf{Gzf8&-3iAh+nUpK9B-R6y(wiKLOP@YiRnF&!Y@<u*&PD@^GI0csLuGw^B)6{D=
zU9)BLhG`o&ZJ3b2b<DIY8?L`$<EF&YC5a6iue^T4MrhiS*mO;!`pBmu6Xgl{RAqrz
z!VO#2ZHDeoC*w0DWXp|Lejza}KY^nxp(G@(gZ48EuDoXR#;b2g%-=jaG2W@ndg_jQ
z^Hx`#Ns)cHO-K0Qb}Bom)MumE!x>TbM&21SDm45(E~z8GS4Vim!1Cc1QTImP6`>x{
z@kZX|;UCzd<VfCDvGUElm}otc7Zsb{%*z)~y_r`cu75KxB3?U^H!}Q#3ek5YZ(OKG
z*l(g}5#_R|7d5hI6pgY-ixyez7VWZV7u|2>jU2TbZ~l}@1L#P|G8%ileb-U6cA_;V
z5jtqVJ)RNeNArqH{~fS>3pdJ&{68A|_k^gI>`5TQBt%C<mT0aQEwZ^0&6BweB{!!<
zr)+LPbD2+btLT%>?Uq&Kwk=nZLO8CnkD<96+$ApVFg0gHjco2i^G(^!?UqO%gJ<nF
z+PC?%WBH}pVVGU)Y7c4g?G+*;#aE#jt3z{ebKN&DED>dyyiMVCZTH?hW=?ePx_%JV
z5TW!zPTe^dtXykd_oIn*U4`E+_|xT&{^-$;F`w+IzUAW!7A~BdC==7lqo;|yxANLT
z9isiMyyEbk-J<KQyd~jdi-dhV@9NMt(R4iT?9c<E?Reg-(D~xX@w{_GRifm#dH1C5
z>D1bCHek}oLkI`SdNj79LgSXi;|M^G!tE_P2uBf`=+NK9RxbiR&B5<()%1hG7y68Y
z-;`E3HsRo6XmJsDc=6Fr&0r;fU+5^lF+w<s(0WHun(>E$f5E|bl@UD@=X}$_cgqmV
zLppXt%4uk>SFmMCOTXga-yj8{*}z*IgYIUJ!4?t@y-Ad*z`yU{O>9sr@TUovH)!u=
zLCt8`=P>MSB7<<=9df^e-$Dk-*3cmbPp64K1N?-8f302PGVMZr4!*5VEq?$a6yZTm
z!%f`x*8wlGP2YdJkrbc^pXt!wnjyRz_&jvw5Lu6o1gARE_#3{!p}(V7<LH8v75<#l
z(8LPB5x(BRzl_MJLmHHJ@O$bBF9GiA<C{A*E?>b5Kj_fk)<N`Jfd4=miu{w7wh*31
z8GhDb*xpSIM}Qx2@LlZMJm9Z5_?OuMBxCru4!$Fy<qRGJycf(mLLK*}NRVs~|J7mG
z&0Vkq_$Lm&vtA3bpeSdEgWuLl_#xoq9X#DYcm}wu%Tk>hPldYCP~kA_;t)*&o^<fL
z87~2Tp@VbJSnzo81@MOEiN>j<7)6e2xQZ%`=R5)Yni%3w6HZf-7}98P_3?Jn5NZM5
z;wTn9nm!N1GRHMKwwGx<v>Ui<_}vZL)X@n1rz{5#Xxy6Cc&GvmuX95*_T^rUhZDem
z@8Ib!ja%D*pK|aN3{*$CW#zhN(r+XPuL53dMn{RVN9LdWCwGD)XcsA#9^_6zD}_{@
zv`AL&IS&0TH5v>dt8*7R_<aeDhj#+6cJOax2nT&C_hP4^nL=u{f}z1o$+5?pHG{Pg
z_$?0oJ#8A#EdhR~gKs5VDZbly+_8t{L_mL^qL=<7)JZKUv<MA9a0G2{)Oe1>pK<VQ
zq(F{>T-UJN(NFXzfS+(8x1&$v@^9{6962|aPojnd@-XH!+|r<NIe`o+6VIN^J3BSo
zX}%XdqmDYrd(y$T_7HvuY|9<|>-8EBJpg>IW7mDKpN~Ne4*m94LNTEZ+NN<tDjK^R
z_Nb!-4Lcl$o5)@Zff}^S!FRP1y~Mv`dbIc$!SW<K=uwCM9uAb0|Ad1JI#XDoC(z*P
ziEmVpBm{EM3t*sJy`FJ25BilO=-zgsmytN;MB+=igiHE&jG?i|5`=Gr|ARhu1f^?q
zLud`=om>asN%S%`1`l)aucfJ>3i#;`en&UqIJFF(<KQ=S5e~k=i(zPrC$<i1KrwiY
z!>|hq)zJd{G6(+}b&bsJ!8bVg_FhdMz61E}4&DrYb>LJnc&CG>ZieORNTA_ySVRWh
z2g~^w{EUO&J)BX?8pi7l<j~E14nD+nlHJ;*@z4p#cXioq%?d~S`?1K*I2P@WkRW8~
z;J2VyuWM~pP}AT)I0k)*>CraWHF18cj)+m_jd0}OSK-3PxK?W4<Vci(VXDK>%=p8=
z&vWowGFp(#mAuss{<SVr02}kJaLrRKghzmHAbPn{yQ_l)A>?^qa<cRXgv$vs&t>S>
z$)H>*sM%3`TQ@1#0$fjo0HU#UJK=4>A9Cn#uBY)QlPJ$MF1I6O@(6zb{1*<xPEu?&
z0Dr^5ztyV9t<XH+A2@gm8I%XdB9?>i*sbZqPhh1Mkyn3ow!WD{6hf9p&M=`XNoabt
znvb}K(|s9gfT2Tb966$d@Y!H-b=gg%*h&Le=Pu-*4AHmBG(&g|Z27w*XltLwtpi}F
za|{|!u#Ga}nqr%qr~z^!H#>6fYbP8z6uHg8x2KZSP=^NBxV*JX<DoS0e{~qXLgdyK
z;6HNk`-tA!3EZqhqOol~njuFje%Ybl1%2{JSs66A)+b+WR=B!eiJWvio<VQ|W#l7A
zP>LcHj#yT{Yqh_vlNd6<M>+IgZ6&-M_?bnBzh1PKTu3-F#maZBL%!PRVvtiNO;C3u
zsrV@P4@bc_>ouB_hMW}+ep5S9?*M)&<5;QPMIOs_MZT*qchnHW2H-a_Lp1iy7E;g&
z{Oc~9`aTDI`Tw7Trz=QKKX6x9-jxI{^G^=H{2$rIvn{#AfFj>@*{~}~IQl;S7Y_Xn
z>Py+0@0w!oV0svk|CVFWmzjPzQa}Gsj-V}_BK@bliK)R3?M(?O6~|@xbr9E5W@n3r
ztxn(xhki#p;gDTW=HT}x2!99oYzJ>?)i|aCtKeLXBPP*U6U<UaCmLLfp4-a_uK~W!
z5p;78;c%|tDhI!1x5h(Kv1^riOTP=h$DwcPR(*oTG#J{PhFeKcxD2@K#P>}yXmBg=
z{SN)Tq`+DO+%@v<=pe-(13%^ruzC$!xl(_@pPYt9-H?_=!N&&QyQoPw$N@9NwN|;0
z6;}Ws;xY(zb)<ohbnve+ehBzkke|{ca_{9dFsvjRTo-dG?t*IIs~kas@e<%`9sE{S
z0C_{McJRBpwLMlV@EeU|yHn&bCK@!jPJFlZ5<?eo*E;npRT|I1z!~x{P(V{eZV%C;
z81jgt_?v|1)&p<1l^*0=ye6aQ<(NeEC5K^mMnRS(J$v54zX3z!F$mc{q}##oO)FUK
z1`Rpp;I}3Sm-KSrQKXH-Xdd#B%i~+x9YLX7Cq#`A!cpe$gCO$QJrxuVbK#E>J&HWn
z?EUpVjfWq=6Wyc9P`M`gdXsLDEAzrhj-VSd8kc_yXE>hS*Fg9-;I3TR-l6f_8sM(Y
zns4=Ld{8-XSFU^+^mAoXxD^fcj)HG>YX*72UPu=&a-L{u*0>yIh5w(pt{>M_ZMG8-
zM4FGnA3Nf9AaL>+o&?)74t`gig00ZQz+ZImRGY@-1wi3z4t^W>)gj~bUm92Q*RAc;
z0LH=(9flnljpv|!=upSdK|6>Z#n5r4r#pV!NjTQOLtPW<?Inb706qtDlta<t*QfCO
zB?T>Y1no%^0|<wzwU4YvW6dlG1`NI2G4%h{5Pb#kM#s<{WrU*``eldy_9~6%tbzYS
zU0W)tCSt&JG1N5*ztK+&jldss1hsT%JX8<-IS1caLULMxA8_!y>j<9>{52TL*Hl~3
zhkS&b4TIg%8Fk1={LT@yt%Yz5mZAL)eg_PcM+kh;5%@!cZOc@R%fHca4t;7zS~tkA
zYL1@aG<>5$<8p5%>RQI$+(z_$z!y36ckb4B&I#bP4t_5TR|g^zz0&F8A9pDf@drV4
zlf#he(e$C6z;AZ&+Zr`)jRF332vUNh#YZ!QCx8ow{?>kt=b%06y1?Jn?4sY3G8XN<
zTwA0r;-aplOsZZp$bG`-K}W$oRU}Ay_FD)4TE>OHkMMC9+(9^sVSI%l=dY$-YG_Bp
zP)E?cWKgIaxNBK@SEHuSK@tsfb=hrYBnOIy%{Gqh{u043#Tqsbf7u{(72>atVXo!p
zw>k)fXTw|<@=PqRJceE87@DF;gbo3BUC8f*;p*rFeveTcyAerCN6H%ZZO78v7><C!
zwVwGZ8?*!XPobDR$lb>b!2i=R=xa5Ew*Wr@`H+WBiapjx_(tIB;!nARiG><MjdC;6
zHVW=`4I8`2QLqh>Q3njOT^pCTDn)2PglyN+@y?7Um#+@nOB^}(aJE~$XmDK>exrsM
zh6BIU#n3|dJm6P3_<g$xmx{mW;NNH`{4(HM9eh`}##7cLG;DVo(h1#=gCw%=bnv@c
zHEw~?c3u2!Ytp!!0qyVECUShXmaX=aj-0R7X?m+1_<z`lKlSCH1T~--)a5YT!gvW7
zTvrTtm1%mpS!2KH(BITga?-$6AIo|)c3%zQRlq-DdR$X|8AhvP12%VtaYHn=vyJfC
zz)Kwb9`ac3EEKtx6=_!70=yDJ$*~>#NDhjkiyS#$mJZ1L%k4nJMyKK43_u*=a^S8$
z+lsn6(Dy~Ih1cDUgrh8SUF4-Rgzp9}mzslQJsP`-ag3&v?Yf@WiqNQI5g7i>HXeKl
zbv}yP9YHsj5ZVX&{SN((LZ$}(Ylr^sq{hSGE7D6%>3=l#FW^<jHZ=4)^TF)|%jTlL
zI)c95q8sGOCzj*jx7H9t50;v)P>XuPCxQMnhyJDr0ChB?;Vh@&YZ1c70H5>J)NsTO
zJyn|%`FW15pDDg#!^Rt~ykgyk4V#~`^CIWuJauV7WOn$e*22h-4T*eSMA3<HKgb#T
zRHGd!&K2Jt9vL?WKHH%%R2;)c^$Mwz_+Y|w8IvXOsK|_njFkPZe*DPWTnefm<Kq=K
zmT)h<eA3`MKJ-%v_tMLi?!_`;y$a-O8)(4ApzDCW%Lw<<uO!?{Ukk^kq0LKw5#gF%
z3@VPyA9V<H(gAZs?Ht)<NpV?m<ciSe#Iwbb*GByT$V@|mf1-At496eDV<RKCPd>9;
zwgH1{A^BW}mlmFdhKV&LkqO~5%SBU3<nq!p<)D>3*P@UEJc$pEGs{F@N#tDlh)0%~
zTYx3SqEV3xmilRVgtRMbK&lRC*c)Kger466QIUzGS|u$=-$NmdArWWb8}>^h=lW@j
z$S6xIJlZ0AfceBL@}$JY&eF)l^IGvQv_)XpKy8G-k8(Udo-jsENnCtT8u@w((f5mV
z{se!k^3liYU2~7fd?cyDJznI?T=9u<{v{fZdEL&(D?}yvBT{z$qXC?c6YkZ7874FW
zjuqfz4m|IMuJE-0!SRcGfy}1|#m?gVqLf{r5)OdJ-Ga&hW@MJ1vV!da^z4jR{vJs$
zr(%znLuCAY;yFad-zSTPTnBs+<anYo<n{nLce>=P1)o0fcwlFMptl1AopcFeG04@z
zT+#VW*}sJWnO7K)d4=o!6%}3;py;6h`bQ-06WYR~0Sw3e6$~x)ryt6WdAe@sN*BG<
zuaBrbv^GG&T`mSDM+k@B6F~o50R7%<dgzCs4+9uJ$!3uB(dqv5QDm=Q@<p!=px=a(
zmM_DD0Sw%io{&Zl2hbn&H)vRt>7Do^uz0vS7QnEK8BF{&J@=)@pkdns=x_JP*ZQIO
z=>Uf3JPb-d=-&&Vf8U?pp5jlRlJA=Nb%A}kKZCtKfPPm1{rv&-FDo4WBWaui58NO0
zXDAx%ub`+PfPQ`eeWjb;^gmuPxFvvr`_j|LMUMy2?{O<&*C79-4?T7n>>}<<kAm1(
z9|q9JCip9eT@pagUFns74;GE8?>$`*yEj0=O92XWUuK=8;sIS2ce>2PA92F_DBL$5
zgW^m44T^Kuc<FBspwAj*N<S1o=g%-4R~gpl@PWn75w(X;_m9MI7~(gYhF=Em^YQV@
znXxrM5GSLj&xUu3_Q~?JIs9k<<8glrM#%jVd85E%!HCWNaz?OW9s@?Sg8mYpmBfgw
z*g_flbVNXCNA%(q<VbO<I3P)iog|Th=!n|I(vdIV<8h>TzP}^IoKqf0iW?x~K1=*&
zcBE)#alq_Ve7}D*i@QZ8oIhfgU3@Y?YrvQuIZ5=L6DgiKlCAP&?#O^lAK4&Un<XFT
zg_m!;zo8?MFF!z(M}FdOXGz$fuVhXD{oDZhO#$>ey%uK84JD5RFgzNdpi3l5^G951
zm%JUo$UWid=TW8p^rOc5D;m`(((@4MQMU*1-5J1#2i#{N(xZ+C@Uh(<`%1CpVtqL~
zpGyNWq;!eD{?az!r(5DH>3loKE<GXapG1(LrKkMODgDr2%;?KR%h%xk=ztM1`u+gE
z6QcgKNO5>fuIO7ON5+_dDRK-l*Kdj(QzzQX5x+4H`Wrmvp#Z*j5WA1E<9FHwe>ta3
z_Lp<o7T`0ic-F*n+CEW#HVixM)c}Eq0|b5yTyB|oCaSRk2{|?(A;%^m=WGi@$Sde_
ze}l%Z_cv(l9inBcJa>%cP<kejv5y2Wo`4sy+G~KkTjjTY7+35sXPi83TsquG&;ug5
z4oNre@c@B)0t6ls-T5-v#sy^gxDWjq6T?OK3@A(lBxxcbNfXtgeWX;FxYpm&1kZz>
zQJ!cPjkhC-5*%Vr=o60y7`hM9dLlbwiK7Afj|a#(2^sUPv$B@kiT6}P*8DtvjOd&U
zgU2uPS2TX5zoPLMkvxxs<1Y!&vkiD1J_Y!g1Fz{ni^>F_tRMe!fI$ZX4Ek8q+z3Y|
z@VNIFHerfC--OG6%RL~EVH3EAy>d1O$Y}>2wZw>T<=eCD344jk%e_B<yI=IpM50cF
z6@Ei)V$`2+VznqQkYjyfz$7s-V3L@)11>+8?e@e60}SA~#FOw7KZXqTgT<csP2$PH
z6M;!QEqVk^s)1sk$!AhPKTLA>!%!HZkElIqhiLq=9J`Yq^><~`<NmRn)FqO$kwKH*
z4&XcK&v$w*RKJCfCjzHW@RxHsXQ(Fvrzauf9C<^^D=46EPY>wZ)8$x$^I3B44={-P
zTp3gdMs?sjMDX1hXCW(3e>H&da6m*p5bdK8$;mN)zR8>$o(N2?06n7PHGJ~Q06De(
z`X}QYkNf-C=lIFHMa!*Ny-a>qG~OI3UN$)c0fT)Mo(fR-p})d2hVNPcf6qX!`;Fc+
z<^-_GoFA91{)}q_<nUPV#O;iSL4OwJp6QXI)EQ3)Fk`g)Ey&J546HYNj0lLq838dU
zlPCPB&rDu6-QS=xj+V!pvIfz4yPVU?ZVzC*)8CUac`msv+mkX*Qz&$fs9ko{Uyl0v
z@p*E~z%vlfjQJaMW<WllIU6$G_mOi|fE@0384>rKcIE-mw*?7y=E(rY_xwGPZ*Ey%
z%r;;O2AN-?PMH!QN3Q6qEwS+yB-oUI>1ay8bTnl*nE%Dch&=&DJQ-j_4`j4i;+zL@
zB|jw~5>o;qaaOr#`6z;<I_n~Tt!G{0ul1}};A66_KPzCEofR<5rs6CS8sn2xQv*&D
zQ@M{k!((a{jG2{f(A0o#nd<HqcT!E=Cdw-?yHDNaACal|`$uGIw`j*oYv$Cq1NgXW
zJcdsjF6{G=#M3Yg{gQ9m9DjY&YT&FKlLh#g179t7ZGfCj0dnM$=R!-|n2HpIr#&HB
zZiy7HpT^w<qnrc6_XY?#2r5bIrGJ$$uhU0G%egqyOgoPD>+tckPao{>#B@08H(O6H
z6Ww1#@TXS>@GS}8+bPl~Wd2WoG=TB(0LBwA`YZT&qCfq^06Cxd%Q;()p$+2U^CGd-
z*$AFr2Amy`0cSV*+i>=s0dnpNumO7~)&@&_?>tOnX9x8B*#SL&_Q(E4l*jyyC@=Om
zqFkO7v=On?vH;$d0ldutHar+0=b->O`+zUN*B36iJz~!+NACJ{NBLoY?iseo+$vAd
zGbZ~p&X^Lw*Z}k8$CFDlwg<?$JwQ$?WNZ-o=11Z)o(y2+>De>hW_+N=Pikh=pKm7j
zriX9lJg9s(+w_^21jxDE-}ISx0KW*^(O<+#Z04>2=KBMfu@52#|IGIS_}=&Dn^h<>
za>ky;{eto598r7L^Z>ppQJ#^L#;o=J3TIsvz$j1of5pes(X+T$yaw=C^hABOyck&`
z?)VNSjoC;xOO726?`$}wa4+vg{x;9%9`n+p$9(0(ci=d4dl~KxU_h_>8q^N_HGDil
znY}l_(EaY<x-QFRpHO?RDf^tk{+#DPgWt*H9PTbp2+z4Tfc|)Z{I?}8*D{`v%qau*
zLAHx?=K2eoGv8nFoPdzbafd|e*GJU;Os&6y&u|iW46Qf`PM@c(DloDX?xFwe<ZSuS
zAGJR_#ovR^Vo3QZ_^b@QRP0p%kA3Oku^;{1Qhuhw)0cC{`WrMC5%N<o7ZLJRaA&s1
z(&4#xv3w`~kPx-ct@LL&cL_6q%p9P<Du6y98Ru;Vv%AZ*{-`}~D>ZmRI&Ztbf_b<5
z8#M1=0R5}}^r`a(`!k$Z;LmU#C!?p!&I_24&O@jNc&wrqwa>dp;qc$%@p%E$>v_)w
z7<4i~LBJ@OKfz6J`af#VpG*xNgXRYqG(W(g^8+G!zF$P;GZp6tB+>cT`g?qSfI;U6
z7?dpb@8V=BKU3lHI2q8#$xHkVN<I{z;E@3OqlVtZAF+?x$>aVE3u1-=bbLhZ1?-u}
zfdwlA=xe?5m3|1~;pEBc1$TNGq;k-6sJ--i1L)rmFer7(pP>>{uitXE5(@p!ik0gF
z=sCAM5vqJp)2F;Ek;;bx6ucau;GjSK!k9n(!hv1J{U5a#1|;3WfTUY^e}Dq=%sa0v
zbdrt}2qk_(df{<@4;D@ESFmVu06m8qUE~~5dr`nJUi2vBq<o%>UG#W>g7*Rpdf%UZ
zF%0p`p~Z6?dX7H~j@paoqi~;{lpDY+3HKz?;_U$nZg&(Y5iAFz$@+JEoCrz%P;eJD
zcop0O+|QtU3HQ<;44{8Cfc`M_`-X^<#j60h;_(0g9C({>5B(C(6~|*mzhnyOE%Gu<
z7o962BbQ40k@$F<IhVZhHu*<<$z~-kwKYJTOhKOvToRChOP+)rpZ-|#G~r%zDPyx{
znI-QB*!y9Cf=~PvTrk(4{sPWqZ4hU9)V^SezsDCW^Ec=Mq^w_rF1Raze!m|*W|<3K
z3Si(!czX1LQ~vZ-pz|}RYEA(CwZQ#mnW})4sd^|t!6N|*4hPV?h7iXeorN#wjr#Z5
z(wKiAFGXMadAt;}lEOVnw-m|fq1Us_(&qvg0=i&nKo=~VlBGa7wrsk;{AKF{W|?JI
z1u)znpx{A&diiA`e#3HkG2!O>D^QnRuzak)g5?te6s#vfNIvI)95|p9d%9q`#{uep
zFa&vkq*L#ac@-e(6z)|JkaWwB`Z|!Zmmh~9`C^+_!P|s;6jYb`N2r=3=cSjCL;ri_
zS5KC>^xw;HNq~aO3HQ>=E;#0+Kz4z|z4Y!bp!kC-YF7tzLAC4x`T7?{XmS$&OM2M_
z5>MiT!{Dz5IKW-wG6*(85c+0-0^BH9_;JFMvJM4=%U8)g;~1?`dj+!EZ``ja6^S*t
zHM0U;WMO*tMr6gx0C}|m@-Bjm@8RP~nHA_cg}WS7c0niXLae<E_XH@o7lO`p6r}O5
z60{42#7RLK|0;ZcfCDeN<(s}nq+UjYd?MUy&_TjI9;^)eD_A+$tw33$3|d)$;*dwa
zyrNwhr3SBp`2h+l0~9QQ9Qj6<$AOj02=~ap5cg-Mht5Nzw9Fh)`@*SE;D>J#?HA+D
z)`govj9qOGxn>35E%@&z_;?Jsa692116FSqc3os-Xsf6niAOY6cZy`4Eb*&Us(eS5
zBS%STuAyeh9Y=(1&0NtcxobqXEH>!kI<--nW3Nf;`VP^$4Kmj}rts1B8qc`WK0sPV
z(T{qYl(DI*L^Ez8NG%_e__emE|D4jQicO+V)*88WyGUGudb1|ltqXi<IG&%)vDZGK
z>-$7n64|<#zDvg7qB$Z1aMWBfBZ(46C@KF&?Th9M`%*L`1Jpaa3da8td}Q+yk(A9C
zyQ-P{!KUU~(I}fALe&+}Pzg0ZDq7KuuVvSEUPJ~SQU;2zUK$xDqL)P?r5C+N0ys#G
zB%n`}Uk3RY0B-qKt8TtHD(cY;hb2|0Ty#rg*i*K(n~3KrD@NNF%j}ibvN9%EqxfaN
zOQX5pFGj!1dW$aFbn&b%;K>{Wxh^K!Kab0XQjg>e>WE^Uyl;tHW!_;?cL^|8+^i<l
zCH>{Xz8s#^qvpr9T_n-G^iDLp{is4+ayJLCJxKH%m^Pw+NVHxqop@CxOx<D84e6m=
znV-es&lT^w0<{vVO%Ua>I+d!ksb@cjpRiHXPl^`V{<M~Hg3wb+M!)EkZDA>*IDAQ=
zt_~*=mz1gcsK*Cd8LHP-Uh<qs*Go2i<08ktq+hhxBS@YYhA4)YUM@0dHr;q>T9Jo#
z3VU6oRMdv^<2m-FeWC{MX5`qHO%aXjAdF`QN{x^VB|>`HBGHOw%nUk_FWaE&4>SAY
zyVisIIS}XKqq%R}Bbg=lN!2QI+^@A?2^npF-s?$=X8-(p(E{nAEh?Cy&x=2<$}i5b
zKfhB4_w&d|gue9iCqeE?rcf)fzb_J3B5<F_Oe4kEx)?*QTwbo~qptOEw`=apH;eWw
z!F7k`YGJO2b-hC~f9PTE)XZ0eMREg}3xzF<gf6C%j4P75zC(03!oDloMEm{-`r?Ww
zG*Dl>Ya@bMO0v02y0z^3NunIhp$c8#8CF@VBiZ%W>3Uihhg4yvVj2LU42gP2H=puo
zqULpY{aDII;M8opZj!2JC0?JFwr;&hUj_0lii$dG-A*l|O|u>*O=L(|aw1XI9T)c1
z2*tV&L`I6RNaOn9x?ZLVui~(+x!123tye3>l9?2*->F&KG%KHsSaE__-xK8xP`ti>
zR|6yzs=p<q{mQAbI%+FOUFjvi*F@TU<#y32d72f^1L|)Zb3Q8)*MQYCeTS2pbwgCt
zpc!+Eq{5t{iV9-hP_3Eo0<l|f4Kd#<GLq|I&DG9a`*giWB(H_$$sXng&AbuA9nGQH
ziVD9WA&Enm=>k8$rTTf}HeG*i*B3CnHoionl;8MX7n)}_zADO9JNGHK)6}u?gqG4r
zQm@Jt^<RLp5?xGUxI)(#sk->y7b2yh2SwsK`0%7h@ow$IRh^nc=^u$-R*_;&ihHcM
zs+aZP5qAhhGOL1Tfvd}PU7sVxo7Y83M|lHJr;Dra5shDjrWPzB<l3-6n!`ubz8dFz
zG|%8^oDJ!aBxr6AVEaJSZ-QOnUGi@(S=$g3<+46TH<s%{8<}G_)ad$UI%c2WgqYo-
zp;ldV=qd7=IU;dAOr8r9Tqn$MM%#2vwWyKJ7f~|}jvSksFA-@pBRwQl(Y*tyM)r&P
z>m&F*wtAv|P$a*aKVrFk%_Bre5g6G|1fKq!lqCG=f%HZo7O#y^k6e|-MWPXfnFC08
zPQ4a#Epk{=-63r)4u4^|oJvQIT7=fu@bUE3rU!R@39TMOb7+ukdO`^)-E<tB^2DX%
za@(E={zq4CdRx?kUHx9A{IM*L@ayG0d>_0~Ua|P#U#b(G5Et5^3(S<VwoexsU3@J1
zB#4<w7Fc}9qDB{3ugO}oE^vO5wN70e(M7+=YzBzgR2JnTc>@Yt7bT)m))Kmw)CDGn
z8}Lmu4I+tGhr;$2asCaFl2DUqy#Y&z%AZ8AgxG?0VNU*t(e{=Hkl8W#HUuAYMC~n)
zF#(2vFTnvtFw4HN4s7-Kcp`bD9C<C-_||ffxDhtDh{o^8mld`?2AaLubT`RF{!bsg
zL-H4gZ#pDe$I4aEO?^sIj@=XyeeXx$ag+FYIx@1fsoq~g6BhK+f)7Z*&BH}!8WL~8
zfR%3s-XfoP@=3f~4gz;g>hilOWlG)hs%YIR`FnK!-ukhUQ@XvxU(WVDyKX`Pdqz}F
zpO&`0LzK(r`%!f%%dOGPsRu>9Y<`rQ%O#9V=jNwH%T4ehEo}|qqtoBo{*I)I+UZvb
zCqBk+&(*fyq07>*yaYP8`ZVg`|H?s;Xo9a_Iie@2uk=xgBv<F3J26K$A-Iz?{#E>n
zB%U@6H{;i5Rhdv_>TAsq=M&?vzYnt)qHU1W$4Auu`YFQYkTwVK54D?F^q&y!q2GaP
zdaDyJ3=Gb<N83B*qb4b|w(lOarRb==qf)fqj3BQMXue7{i|^bVi4=KR@7#3@+<#2e
z=gRE<wwyP9g^y=+JXjcjS1ZOG`@uW(dh)>sMEev3@WB&Qeyq#y45xAum9rIN*#3?f
z_vOgQ@OQQlencct$9X^+6t-JM3f0oqt<W#~m-A;g{)gwSO*#)AY808zVvplrV}Qrw
zLwO{rB;CIjqmVf9OH|>dDBO92=|kaTMY(+c<X^FzP9Z=4^$EaJ@bSdudpm*o<i+<M
zR*z7Jzjr{C<6YI#N6P%^{;g28hyQJ=rf<V_@HV*rkjQKYTic^xbGzMxI^1b{Ou0R?
zO-@8^^ZTj&CBivej2}>ZrQfecy2<46xbyu+x;*%PyZUFe{r!EQ@^SF{{mS6dN2P`-
z*^(aJCmQD>fIr+J>g8nh!^cG9>5<~l55*Oj>%u?m7U^jc#?MYFvJX^!{o|Do<<ozU
zFCpC1e~&K%?h3%5D%266$7=~EdV{Y~{ki_}?P&MYb35T)J$I5k%Bw*os7pO}5zcxT
z-=Xw`e}wbW^>Wt#5ng1Hj{c~J%8x}FFRor`?}>UO*P{-}dt@fNJ!>RfX0j_K2GtYJ
znaq|j{TS8dp*`aIxd{B82GtMYJxwD00PNZGfVO8(o9?GQUFw~I@E-h{vh1KAm+AH&
z&n8EH{IDkY@c~^vF<*54KM+2#M5J$%<ucKy>MKRNs@ICd9TLAtWK?|<(cez=SVf*A
z+fV57Cxuk*5J`N&Lii^;>GJ<4SSeu}A!YyMh=20_q|YCJ5;LY>vOhV2BFTN4(UE*o
zrn5W3jLW$=F4kNhi7k6l=83y^(x{`?p5#2?USM3FKNjFqfR8yqzgI?MWauRwj3*Du
z;Ef#hDoEr!ucdtVpejLqRK{{-=(q~y`X}E9iBA$gd5Ul{0yP|9$H`}a(H(^2<TJow
z!k@BK5{I4=!_GtMbVPK|bl?g>_E^Vbs)tfPjrhm+r`VA5i~CRI8qS7FPb_}g9)KSN
zt&E25r|%xD!2fXPr^gkJmj{y)u$+cd!u|>jd>RXLHTa&Mq?7pRB$b!xLGbi-dJsH~
z#ho0SPv0-P!C3nAqYxLyhXNRp)<WacI8FYWq<cpV-W>axTs>_)GXd?cbQnz2z%!Ev
z;)5Espl3WOX6UCAJt;Qy<-%@8$Jb~(pTW!P(%xrwDhEf~&pZM?pAbE>M<l+Ad^$SN
zjKT731b?1+Pjq99l|CaA$&Z}^`D~3I>(6cz_P24CeRc<WY7}@pJ^1W{z}#U_Zba>8
zrFpIqHJI@>efEB~L)4rh<@STFJzMV2JagpW8qmQ0pLym&gO_NzKdTmL-1(UKvui=_
zwyS~oHxaJv!4C~F-bnno4e^5f(vF{b9ZQn{uVajpV?Wc5g@1-0TZV({pTkhGp2f!#
zxaaDC-Ry&J1?Dzf1_zEmcMIWcIOE%t;ib<#<l);*e2<En79`Gddi@aoIZeJlKct6r
z=NdifcH%NzZP|8iQUA=cI|Bx7Cp7yF=KoluCH_Z~Dog*PHGpm((e>(bFAdSX7@{)8
z_im%1w)X*jLfYG@$L?ONAmj;b?+Ge#!jko0OjV5Qf8p)(E**kjaG&eh#Nr|Li_H`=
z4k^=f7Z7gfY32Ego!Zb}bWwSTCY^m_MDiYt*){s^#lCvR8#Up+4k`}{ThhHPGIyis
z)$Z*hcb+fQZaqImQWb}vpDr3D^*p`Ye*O}Iw`%xV9mVJ0(NW*O9ZtCic2Wmn|DB>+
zN})x`{sX$(_xI^>{z4rE{e?|ReCP#n47P<|xI^{9%opyZSWyh~q*SEk3%dxXSQ&h`
z===uMq3dLyzHo?EnO$Mg_)TnM#fXi>4ert6y1c`iaT?xTx~s!o+gM(^R?vkTM{45l
zdPyXqAoQ}xw4lf^-N&K@tMc%RwkpMw-;9jHo=-PO#W2Jr{37-}@0J98!u|}(m(UBi
z1y%ZzTx9vg^Q8$go}imaWxEdOFQcO6UMP+!aWjAE$;rGj?dUHzQvf(_jAQi49i{_g
zMg6@{e?XpQq<T&F-Gh~y|G;FO1qY^xKB!wd8?eus{XmQV7(DP;0RAM2eOif?yPxvB
ze*pUhvi#4qcJe>>ikfdh>wb@MxW<r4@t+4#xaP1tIoC=2Rl?b6#(T8WFC)cOC%#;*
zd-df8Dw|byUTMF4zejSDmi)43w&o%GGS7;vk?B3NxS^+6{AIe9c^PYVImP@6_vz%#
zlwURIQTD6j(Cf|$^5j=Iz3!BBeVVU(k{&+YOFVX?Ut~nOml4kPF^(^}*@Z0HqW$lt
ziKBZT1?bn!x<d{Y>JB+LoM!KXv(-PN?Su9HJ$&$?T@NC!4nFEp+=)62I!Kq92m4X=
zNvKx}fcrT93etWz3~tw>=aqeW^t>W7!H@i~CO@geb?7?fM(H6=C_OEF_aKG!&`XML
z*>A!garLOf>fa0|JSpo~7S_uGxYybS!lR=6KCBXc6GPo?UL&>3X-MKpS%*BvOGQ2S
z!oL|S`gUXW@|(G6_2ZY_?Z;mO+$XBPxrF3iuH>eEBklB~+Z-TwD>~b;14QzG|5!9A
zyj&ytFL2rW4!skv#}#g#^>G^Z5JM8BJHSr{D1JIX@pIsIE9SuNB|M4JDs)ABzo_{a
zETdkNOg<5LO<tk>03X@Y=7`#_%|XRI1!ZI-@cD#OMDjAIOFXHjpqa1Tg{qsckJ|4c
zocS2vEi#jkNv~l7^6P=u9`X-F4|alA$z6h;GX7_tUN!VoF;Kq?d%fYFO*%JvHmlqS
z_v{k(_a%P6NUE|`B>y1q@4n7AfM1_S5?*i6#=VXOke_j{Bc1%x<8{8Nc9<U`I9#TU
zJIoIz9IhrEha34HtQ6!k8;4sM$SC{YsL)2dfynzA@kXV;5pO&p*=HV+L)6tFrR};y
zj!YleAqFRPM*`Fx2~hWDjSAx|`^~E$*e6Bbyq54JO4pq5=CjK0nQtBj>c@AK@FYq%
zU!Mxk(RvlGS@uzkVL$$(7{dxrqIB^eZI=9E`gbEm;`;j{d18tD@9(=KdEsMs=#U>n
z()xw`*uDNC&)CYO4AvfUmdi}g8JD3P&tMYp6PMvhfX0Th6JzSF3MKBXC0g8D*e1fH
z8GfrlC(2t#w3Tli_ZR!t+x}J_U!%kxU$4a;ze<T+cKmVZy#k+^T0dKH99ApbW8Lv1
zz<p+v-(m{^r~1@y?<78tyx+<hLhA9zJ5dYFm8g*j>WIRLi##};(@tDMILR^emn$55
z9NfSR^`ib^oMQKizK0RU|JpBFP@Pfi5l^SMw@W?Z8Bgf7*4yX}DQ%^aB91*C!Lu)K
zpA`1L%emz3K2h^Mv~Crd$7TI@w@}0H(!zcO4HHD;BUncCPWEUgTYIO7R@Lqqr4eq&
z?uHc8DO#t)m){qva^~-m3Ik$ThB{*Sd!)huoW%V8r07H}N`L<zwR=MLd$=K2(<hrm
zw^Y}vi>_V&h8>bB@VtVL=gjekE>SL<+tIWzyZPPWyYQVM;ddwL;xX;OyLbi*On9<H
z6%o<>HyO6~wuwFow`r>PKGx+Q6V(34Y66Jhk3FJusXQz6>41d$lA56JGUDiaOb?#_
z#=Tm6XU>)Of6MfAr(F_tgzUfPc<?mgm=_g2hbl=p=EVVcn(#%U@%wNA(-ibAx8E-T
z?lWxOmwOyj@bQH6eR+Gy5ARh1N85io;4kol6BLU-<GwO(^vwM8SP;5B?Li%${+T^x
zj~J&dol|KNbm{>u=#;#(<Kx1qt^gbp6$~i-i#I!WYXkoBwrG3|Iq{d1qW)1y=gG!=
zo9HMT`*CX<=`q^wmkNDi)89j}>Hol=;IDX)1HF-B{}uPx@Niek{_8GKy3amj+h6Y|
zTnFd72MPZ$>`(up>^>>SL;n${4b6u6HK0N8KT@-vd^lS-<R&B3upXtWxAGeZe~56c
zz%qj5^eyQ%?#S6Q0LKseqAnG8;Oy{u{3{I>mxl8Ta_o=!D(G*+Mfnerw75x%jw$`y
zGSE1(t^6|7A>(f~nyg*4fO^yxfZ1tLWT{K4;xN9|1UqCXcZfca&yWtg9ZaKcMT<gn
z31<fx$NKJZuzBOs3UbMIEef}dj5lgF4ucM}mETKjPkPuG?@(;(_ER&lMcRq&rGa>U
zKjAMEPR1Mh!vk?ckLz5VIa1*S+JA|U><x27i^85DvAi&kS$3yeGJ)O`JVVdv$3bQK
zB-rBk#^uNHy;0$h<v=eE=cox|#OR_Nd2!&=qdAM@fF6-kluKQj+pM~FeJ&><hpP($
zU{>xP6t2E5P-Xysj&L$7!t{Fw;)WiV#R!+!+8(jz7F2;q3O`81q_m)p@K*^Z;fDT*
z5>lFb($h|SgCe5+M@Y2NfntZ(qYib0cp4?K22Uuq5T2C#AueqPVfWW(ZYmliC(kMP
zczSw}blneEb6IhC@HQ3m(M5SN5V~Vok2>tiE8g{E4B3QoE}S=2wC=%}tU;Sk59Z-1
zP;~Xoya&<l7S@Wo6y}*_3K)Nw#6KY?(Bg33J~@9Dha(Znh{$X?Hv`xw>~G>eKvBfo
zJ3U%M#M?WJ_h=3Ig`yAs%$N;w9|!Vf=lkFVHClhcJGvZ_ROR|1mw?{o=#UC+#*oWB
zc!Kavgi|jMVSKX(XE}J<S^8awt2kt6Y2jm_n~smCn+p$!`l(n46cuJL|Ki8!yae(W
zblip(G@*_j8F~@noXw2aiPoR!B@znxl~Dt@`-uB#4>#k_DsK6811`4QWHYgSIDpOI
zQJmpI%hBfXF1iz#Pp?F~{qbRS8jpDe4eQlYk<EE!?-k`gMO<y3kSPp>WU1XP`kq7>
zj>xnxE-fnbS6H-0pM#28sZ@)k;&9Q&l)o`N{V(Uh*d!Wmv3dTIVt4{j5vs)vIyCly
zKVkeNa98FHrH&gOCY(GmI35m_nKU9-m8B!3D?XVtqD*Dd=%Nve{4;696Qa8VQ-Egx
z7Pdkj5^BV&q6HBRkLXckGq|f~%4X~#$@xf<eS$)o&jBaA*b?<WMZ!g?nb|U^gRMA5
zII}T6T(eD}W?~y^qb}L_dWeI<IGlyHQL;0p;N!`=V(g}1I+|JR8RbK(NGy+X7Rxv;
z38mOA0b=h^V%HbT(c@km%DG)y`yAm~>~{|`{!##b5V$K93Tsf8a$Xh5=cM_Esh!L;
z?MDaVL)(ZiqbHk@Y1DnfG7?)!2utZmIT`u2KTGXB0qyD<qqww0`tHMDg6%DN7AV0J
zYVs^lvQLkyl0&*2MWbyLuI}VmDJ`QxRhooApLwEm4GqK5^;*K{JE&||W$9=h{**T|
z`(y-1zbq1+uwXQ9abo%nkH)&{XSl%<L9379W5xvFGVp%%N#*FwG54a~)qz91P>1?4
z_Y+PXXYdD<IWx!bdWO@zm-t@t@G*WsG(LyfY>f1xc;;!+B$wL4dd+^CoEBVow2bhX
zyX0JX+8k;ot4wo+mR_%dU0O7DH|TtNW1LtO&L0^b*Qxs;QKGC_pWrb{&J;FktqG5n
ztS-S;k{O0x@=NPI<|VL4`g6=Io|r|Gq{b67gCEdr?~_!rE?Q4)9}>>m82?zLJE6@p
zAw`=t+jw@0*%+Uy*iu)KRIM#HNgX);+5y@e95apIiE~2f06EsMB<e`437*&)yaLTO
zF5F(Niww&tnt(+ocEiQm|G=vTcm4l#y$yU+#koHoHWZSGad*We1cVh4B5y7MAp*jY
z*ATrn<$59IdhM1{NfGJlMMxFRRw+cZc1vw0wU(}k5CL^ngy^-pQiPPEtcVa1>0VzT
zwG{VSf0Dno`u{#>o;f>bILYU8GCSYrb)I=<&dfPy&o=Ky&J5lF4n4XV)Jfw@jB|YG
zH6J$qrm$W^96m9~Atry#ILF}v#xI>K!tEGvm(CLryS!1Pb|Z5i6tO?Ti%U1Nn6g$U
z)m^&PP^a+iws^lZ!sG)>5wWYk;=rXJi1ce%Twi(;n3nh#G!PHy%6rvYDaOyB)Pmvg
z<BGx`;jKK?`i5ZfjA|n}t55d{sbvU_C&DeN;~q<bisHbKdr|28t&Fc>+@d=86^^dy
z(E|tv#io*;jS_EEBf=p(hflhJ1W_PBeW~L~#$RDvhT*Y83g2zu3CVxi0+cz28hczy
zCqx*y>?S5iMGijH2Y&M2Xu;54j7xq}g1_RxQ0hnB(FEhgC~w5!($ffmAQMbQCBR9M
zg+uFtp)`JU103q10~xnaYF#jNy$rS6Fzhx1Z=_HdhDTiQEihs(;|BlOh2H%3TSYze
zk2{j%pJMxJ|0@oRJLYZR%6VXT7>6r##epjqh+3SB%dh+zG#VBLeY{V^_F~D?0g}g@
zU)3pMBXO#(`bt>)Fs`p!O&3tH)xT<o{h@#0s&;S5tL%%j;GBqWuI$60Dzi`e3nvan
z1Io^IWa3c9jmS+*fOk3$W9(0S8JLI16WeV&l@kwjV}~M3_Dwq{MePC1B@@-0!GXFU
z4PNBzM03t)WBfCe`dp&;@jNyyJtoyQPoj<QB+3AfcH8fU^zdgAZUoX|Y7(~A?FFUZ
z?`CXIdIjbw(`9p<u{~)w<FXl#9U?w7W71y66+h#Xhme_)#>vACxulevJlepO9O>8X
zD}21cpFkb<Cr@Nt*;n{98y|5_Lnc#V>jsoV2RIY24%r{d16Rku>5&mvi{FpN-I&1D
zM??laTz)l%klthd0@UH!)%bqxpOL7zH?SYYBDwFHvQ#d2ro^~>)aL592Qm~BBQ2+7
z>}^<nU`m(l|EU8+99rqhOOKLs`KPWDDKffRTATWyv@&(OErlC8bd9uT>PL|FxH>RZ
zC7<l&ybHQu0Zp0u1qwYW6%MBk6qJ^Y^LECPD?ICfZME{6a@NAy{nb+YH3Qw+9b8^)
zs+^Vu-J>I>ceBi%K2oOo^iE#x&p06bZ)3SIqZ5iKA&nr<1mua|$O>lR#u0WH<+DbD
z(ZiEjmd)5dFss#D)2ueR!k=}(Tfyw>y1~<OYcm_q0UpHYt<GbQs(08;YMe9KTX4<?
zz^TVntgG-DJvry3fyWs)rX#=NR~Zo|J}e3q|L3TvE4wxL{u^z;YR0j5H67$`X^(ah
zKMb$0?GhQP^2LwqLd^DWWs-h99+OIAacJg88(Az4TyN%w!exGlDd~dC`_(b;6qH(~
z`s+k2T`<u1?M3zl!~8(4Uv4IA>qPi1_!JcpD)3M&6){=h@h#N)wLq6gy41GXompN>
zrwlJTwhFW_rq{oC(Z7QSKxiud&UK>p5RBsLHi~}KDi3YnX=iRc#!44%zJpZ28MtQd
zI`Gp(CVTj?x6}BHXw7|uaoJ-z{3UPv2E3-=ZFsSi?p)%k{0%YidF1%KkQ~MH$VU&m
z^T-dv4ZHKI<rFk8A_w98Ab9l5q(KS4=hJMa_ngAZnh(RhM`fzijTB+37Es3EH62T3
z^<_!@?nic6{@v5i<uRKs7|9p47F2`5BiIY-WUv=3q6{c0UqCBWFFtwcrgDKX%mRM!
zqcIDN;pE`BaPSWL8gcTPfB)-I*~kC2-HuiHf1w>-v;6l4i^LJQ_dP6f^q2)KY5sd*
zd9wH(zR7z8=9U8X=+a1oh=PoJ3i4w5_a9<)GNtkYF{$qR>lv3_o5LR#X~>V+V2CAI
zY@;Ej@J&+ekRirH`1?l;F@@u4*Q4-uh@6WT&H$T7qZX=3d*Kd|BL0XhFlbS;7p5K^
z`U80_%D1RMPGyVawWR#O&A17POz_>jNW?mzZMj|8r)v*2Hy@VybMr?c1MWuEKQf>_
zuc5R<dMqZ<T(0MEI+1!@_+GpO{Q8*dU_HwimmTxi+X_ddd(5N#`>h2R{2;KHCVgG}
zIE#N`h%;VKZtMK4ww{_nxM8lozWEqJvxEMd3(L2a&Q}asg)1Lqh@2+W(+Kjg^`kKT
zki$hk2>fUvGblk;_@kQ*L4~VWDSmF$k5(A`3QveEwF--u6X^dXeMRU!REIRbk7ezW
z+YRF^w4@tlOYSuIGpHjGmfXX*im1ZxWn4MSjaahA#{WIn1&XlF5a8K!2@PoqqlE)I
z)VCE*V^i<q<0ADQ-shmYYe~v(?)MLwY@`K#(-_rzN4fEZ!Jk2$_`hV_Xy+|ec5jXi
z+|o^N-qKBP-V#GUl-d)Ms}<7REzO2GcJG#*jH|F_nBP1%D!j{fFF&yKMiGZS`{@7=
zdrQ0Va_LfA3^{}!VJ#_N3bpv1+H=;QOTV(|zFT|BXEOu0;#_+I$%g1auJTs1bGbRU
zs?JqWRd|a?Lfm{mSznv2IB@G`k;x*ZZ^dsEcH-gPTR($K9<91nb*7<y*>HoOlYiN0
z#udN9m-3KZc23ek0NJr@vmwasShkmOqq~;vH~2HCL(h-#U>D|w#=wuS^A7ZnZ|nwN
z1)RQzUqp)39~7>~XOGDIxSRa?vF+GM2q}*_1V4V06&az4_TkV(r+Hh7&N2i!G*Ojt
z%1{P;2tjm-!LM-KK(<2@J;V%3P$@iO2rB%T!Oty<o-p_o{)xe#MV%ZwL--8*Qz2l&
zZR3f6Lph}IiHw{4csvX5{m2j8hMD=i!jgrzmlz7z^V`b}1qwGq$DZH5&fr)0c6kQ4
zy;CGUz@S`BXMoE8HgmZP(rD*@Z#J|rzPxAihY+ry$Cyie%Xf${RVUkv?)<<Vc)J4X
z-(AnbDi-YW9o^*H9m<&EXP58TX*kg#5+4?n41SwqdxxE;;4xym0_jK-)r!@id91Bg
z?BOh0>GO7UWf9{RN;=(e16KCI02>R0=+0kpU?md56JOK~o`!IlSoC2*uzV%9pkA_g
ziwjL_zJ?*f|1o0RAwoMa%l#w>Q9aMtwV$Z;QL#|?T!Wuu`;!HXD}IIJ0uN&6`$-Fy
zK`5}urBMFlu(y{#`Kb9MrfBH$YQvp9MVQFget42`RS4upHQ}o6XV>qdIyF_fsBm+V
zVb|}PW$-K93_%ur$nm@8N&cW?KoMT1w%4qx@OFFE<Zke8rt4L;)Pp7Et5$U*x806$
z<Eq{4zlsC9vr5ffDh>+&+TiE-++EDLg;LAjy9apNzxxJo`SQff&VnFz@yNPTyl62>
z1zzHSVhl|Z+FrM>g*pOwH;voe`ajRXTSaU&UERI=X=acu%IjOtf-f0@3QtMvcq|G5
zYrLnM;dxIlh<hZ)J?H?B-%t<SgTQ;?jl)?F2mEjW>S$NvL>r&(WS&EyNO?>sjd9>R
za2WGKBfhRl^JJ{2UDm`@h8hNAb8Um?*o!5-^~UgmJktA9yjBcl`Mo!SkAlVaFYLl+
zG~`~HS-yJ@$U%J{PmK3%_vXJZCH&A=bKhyuJ=(Ln4{+*qqn)d(yWxLO+FhL#snhUt
zb-Q;4{%om;Tuk>*e%4?w9s37<)&h+lE&AE^=F?a(zwGVD8tOm~zt>cBgLjiKYdCIe
zj!Xa7%DDN~j-+;!_PCDW?Xnx1@N%d7$^E7WMd<IC@1BD>ZH_)thB~^VX@`BDoE~V}
zYcTX>h9ivgNI#-*H3M+o9Px_??0hH0VxO>>LuTAwtl+a!=V$yg<~Q-r>7_v!xAz+}
zh-$$7K^C+~QQl)mLR1t7?#GkRQg9&Zddn&B#4wa`i|P<mI3B<}gZ>;3ki;w;MCO3q
zF9)Kts5)Xh40Th$rSmJi#=t|UlX+Z_!m=?xaDT@BFgCDmFbMjT7MGms$WeVtQ+S0)
zW-${|g!T5ZqwBh9z`7asRnE$F*Bf%&{&jO1w@_+vSr=isB|vq1+|YH)7`IT8oWk**
zTzbZ6U7Y22gQ_>Pjo6C=>nH*BW-1(S>7iy)9_nII7Nb1W#T0&AUZ{Iuq%{9P9f$dW
zg%HsF=XgDEGvgLYt-~L{+q&R?<pcKs)#W%|58TVRg;I;x1Ki#R9s#P$aa<nQz_^7{
zi`N55+g>BRR?Q{H1CL&-X5+RV#F_C2djZ!2)QLLc`k)#(lqY1zPX+K26nfwkKc!pG
zybI46q7SZ;5q%KXChg4qc^_V5{~T|{-H8zW{1sLyP32w0q5Zk)a_MpoZ?`ozJ~Y@i
znHy6U>TvNP=}OKMg^vbV4{0^?n`2Pn3z*-QM+g)yLy23NDmFGlao`se8#16`tnie5
z6}d4!jp>G5d=}$2KMb*4`~!oZ9f+Sa_!<A@aNt^BUc`ESNe$1>^-Z2b2#dt$Shn8j
zlIuCW0CfcNm-jL*+mplJ1g;0tLY?@JF>cp$?fB&h##OtOzudmYJSD({^#i>H)(>Xf
z<X5w$VPO6B-SEeO`*0NDz*X7zzbq(RxSrBbZ<TUpw}D%zqqXbzGH%y%>9Jl#$H;>9
z*z?h|%Imuz=dtwq6@H2s-?F$i@T+oGY_#TA)V<`Og@cA9JNPRzeH6Z0-n{tLVG+jd
zt;&b7YW6bx>&f1Dvz&q}n;!vPODlf)NT7KG<FcW74xX^bXH7HBy&eH=?k0T&^@vCN
z!~i*b#L#Z&Q@X+Db%QVK24B++zSG9>r7fdF#7o@>n3-gO4;dr&GQW`-;yCbJIyw`b
z_z3vxIP5eP$NyDOR4%gJ@Z!oS?naik(Bw&pB2yb5=&v}?5|-zOmKCUabV|#ej9VzR
z<Z9WBn$B+#8Ty`P+-S>hR41xfG5>GKAJ_Ro5paIMea^<fZypAR$GCWeH0d62dOtFr
zaa&PtI6R_SqC8Oi_jJQ=w`3%UO2AfF9C$?b`#ID3BOSKKV*`(T!5WpIvh=05rQhPR
z@|So@S%xBKkHsD>_ZEA!n{oT-WE$7!yjQlA-G6kW2!D-?cr*>QH0Kx@@#txhm_SR(
z-{C5ErTxJ#A1i(0pLp%|YDiE345{C35SeeF^>>sP+B%@L7Ioys@33R0$D)3BS|kf_
z^<_hW2;m8rg&Q_9zl>F0-;Ctnp!6_aO5Q@xhOH<x{SH6%mWDh0N!xDuhBnZtUktxD
zU_<yXY<TvIEP_(A;Z3mQl4@&7J?dok7z$l|1LG%962DCM96ug){~BuZMD6`}J8a<h
zp!c{Qe1`eoTfp{s;Pp}--@TRc_kxG)t8m2d8GikK9SYqqg+FM^i_)(PE|^P0-)8P6
zroT60>hO0H)8AvWON~1qLYJc}fB%6<{+OOf`29(k(Vd}~larky^o_l#wD}VYMfgHI
z+?2SP*;SjkixW!>HSJPOVwr&}{-~{f4t0q~4=2{Mm@*S*b&nY86rPaYCPn5QBy3_2
zkLt(9gWn@H9-GE^nDpj3De%|~`@G)x*dm}F^VeglIqX-NEnggXYz6qWC_4Bm;Md?V
zQs}X6=EujjgZCy{-I)S-xC}{^A9ySyvJ-IW^RZ5F4)oBRZSIGD+UU0xoug;tXy95-
zmhpVGkpiVRK;e^V$d`_p>lW)@fjY8e;{vysgGX#JJojR6{5Cd-)ZH{IZCq`C7#rBA
z#-<8nJu5WQu}tCkWfu4`hx+o{IE?T-PSYx#c}-k3OPNW62Yx?}pD4lw<jTh_R6Y9V
zaWd=C|Btuu3GQ*40zDGzaT>0KTR61DdVDWx^z5*7q{m|!d?rWsqaa)+qJwWL0Con4
z(V$J`z<S<@e^QZ?xtk~#JPdETo^g|ZZa4f(`8MgMw20qE&jM_suF{(tMIEkh`oPej
z@Xvs2DOO(1{9hP&oy4EOQ_bHhEd72jCd)|Vl`Aquq6LQ$i6<zNJ=}VN8mb3^-FgBK
zguzVX5|DN8novh;p17THWnSSlLwRJ#6ZZo5GQWm#3ne9hG7o({&~IYz-31r)4?M96
zM34S`BGr634U{K75{WjP+nz9k<|nOi_iGf|cr9mqGm$;q-8?{qU&hS1xmxPqT+d~k
zXUfgpB=qL3P^gEqo-7mxHn+2aPA<O^@oVTR-4^OcJuob=h5FA!(UuC4##X9w3-z1U
zG5xAghoLPK8Rw31aNOR*;zVrjUFaXIo>1Jfz+mPi+Je(fK_NYfXh&hoCUUwlu;l>Q
zJ$hkFC-7}JjGSxj1I%MuXe|T&q6fd3qa2G?nwISQwH7{T(?ly}j~0ZoERl-?tq(EI
zL2&Sg?G>4?6%RU7_qJktNad4xB3g*{;*q@N)G1Gz^I(V6`{Wcuufi=6jul)aepgr+
zr1wZdS7C-lA~wkvcv5^?QCM2}<T~IU{rzM!;}*%~PO(qoTh#C=Kk#H$WGk=~*^0}?
zHn0_69s^LhwFdlJ5c+X$Z@r#zl?e)u$mQbJ2GBivZEJ#h``W<PHt+S^*4>cvXu;OK
zj9VzR7Hm@&y|#_C2Ty)r+YC7fw!stZe*mmvK%Osrfo<Y@%jvoHZFqS1PW-e-V0!^n
zdZg0!G8vWaGwi7N0^98{`?hc5C~e=NG|>6ZOT%fY;i&;E@f5Cq+BToM!CT^~<sx!E
zvIP%iQT(5J8f+f%cxor(GXBn~=PBGUwL9>stcXOZaZiW54Lu#UEi8O`Q8)Be-QbjC
zdPX#%j$!fidd5{oC>&ugwi`sFq5Nq?s>gX?HHPyud9s(D32|w0d86Hpm4Rnguzs4G
z@Mpgm33i{k2Nm*1*-a7^xM;*{PRgH2cqiI3t#Wz#%*#CKKBF>B>USdg%zmh&9<Xp|
znfFYmhzvjvC25Y;<IzcM#ermyapjl7aVNx&cnpzKZF00*ytiUgvjmGfIDQa~#OrM9
zjmgyz_ei{CYd84I-Qd(ptrca;jYEvH8xDRL_)~e}%2<JaY#@0OHIFP!o?+ZVsm1Qu
zA)KYpM&$T-cC`W?=Cpmb8%LkTGv_o@J&RYt+KK*LAC`Eo3MM>4@m#en(fHibZs<+G
zeK<HHFXDOkxprV4Q`mD98V~;GM|$%=Kf~tF?IV<d=c6*kpMTI!!Ty2g9|5P{2?eMl
zm7d=yQauVw8lT^Us>g!jc}jVYmOr2B2B*&R;{V8dY(Ad_{_p7QmkR>rJIE;y;T;3)
zFxTvu2fEgX@(Ai^#13OQ;NUlc?9r$lND2Fv>5laxi`JL#P|@L3ET?`T#rWNqzStIR
zMoqKZpQuEp8I*7qb8y_)fmjbb$c(T2HU@T34(sw|sFVCBj4OGCpGHv5{eiT=jxXJM
z%G;!#7bs;kKOCImc@5<b=O3|?;TLLAcm(<dd10?S@B(dIJytp|@cHcpd49_eywJsC
zWhY+AgR@V5U}s2<qMef!rMB7L6z;5-y|^>(ZG5Nd1fGTaw}KDO?%aSvYn_AhHS3)e
zg`02~jofKOeLw|xNZ)5DG<^=<C8A~MY?^F5_MW>)oF*N^%r47b5$6YXT`w%i_nT{|
zkD?B<yB68%X|LQsYlmG;_R#bNc8OmMDl9GErJB#lFd)ft+ojygB8<1vKyHt`GO+7&
z&<El${At6Q@Lik@+o<zz_n?>I%0cNE<J?eWffHV~8RrHEuaegY+h*_<zpYk%xKXY}
z+gfD5x9#A5Z^Mg+?2Kr`wG5h9U-a88&JVnZ^?}`%7bkP<UaX<mm6X4DJ-pEShJ*Ja
zR$S#6QT2B4Mg(5GlleGT2E?WNFB)g;0ddh#UN|VQ&R|c76x0<aSPGeh>X_#Yu68EB
z#JK7ih2#8APN{X#i&?wDV*@Ysax3azD;2#|>{jI9ei7{tMQX&nbR9?TrA0DwFR63b
zOD%M6#@7Ty{9YPtFJbpiD}|Rna9bQu%@#j#TXgW#wng)eGX1-x*#8(4ii7vGv!L>S
zO5Eo9r&*5jQR_Yj57}}xf2arD<GlBWuig6iO}BwpjDR^flCO%^`md0}1P)^myb|jM
zPXhOF;FWfJ%~SrW-<$p_UT%Xp`(CZ$%O<b33;!AHz+TPRWo4?bw_s{=H~4j|DD^PS
zj{O6vPB8AoVYKA6ki01W+C)(sf(Nfn5gEI*L<-Z!m=zGAh^v8+#b=D;*UW*S@R$_a
z>K410&pfX^&3Ks9<mEXyE-S-Y;~8L@wTolK1Z!U!c${&gUoUQu_-<;XuBVA{)!*Ej
zi)$GlF8Rf>P+{R!Q3jVuP@R1*R=5$8i(8ogPLa9{OP$?DXdL>zhQ1iftub(J-0pP-
zt{U->fvZL&aaNy=U%fkn7y13MO6JcWo9u0NeqaxNlo(s_{((K$LHz%4P>h_v;=rB;
zDX}NsJQy=TtCGXJTp<Sq9qPkr5g`t225iFX)#}6NoO62zh!i;H4262F7Y0_7x#GZH
zj<yP{gVRdFV>z{VhSGb3`Vh4Z(DR%_a3g8&MhISlgS!=<@CQSiQ4k)cy7~jY6`wW7
z26PY&_|tBDpu%^G>>!*y_8JqlLw{NL;fHT;M!MBSZk5g%Y-r;=*+*WIb@s}B_YSP@
z8waclhtV<nuCvvRxtYaO?nY53v2N0IpB*FoZipSE(jH%l3_U#6j$fp|tgtk!oM3GO
ztE9H}iEKqVr*QEqdeqmB4T-(vY+t~9%9}QpzsW6svBD$3J^HrY2>Hbs@S#=h&!NzQ
z<lsAi+h5T$qSU^Z1yqCTQ71+F8CMNb_yOS8h#^A@FTE;-kHmTgg=TXg<A3r4@4{i2
z{8N>kewBY(2O6#Fr0K0C4fqUwe|m^<X*!3?i=~Z$KT#vS1Yhb#u$ztLpFZeD&q;4R
z`-=&mfq#a_`{}$(4jCTrr_}UV&+orZ#HV9<uzwlo+JG8l%NGastEp1z%X4u1y4DW@
z`&ERL9}hwgBDa4%3f&KdQ$urhdd`fXPW+!RF74#-tlXylxeu3NF7e*0yJ#}}a{_|u
z6}b2)|B3^D&IqdyM*IO%xCDpM^#^1Z<_8XJve%rAfdij`OY6%4QPNc$IPhgRIGwt*
zCMy0ndUb=72fF^{s6+o7c9-?RXW90x1D1>U<(QsvuMEW{oQrSF0Eb5pzHyUC{0Cjb
zeq$jRjyP)Yf&QTXW)y>P$Sxuff555B372LG#2;`Y7wc9rZselE-&_ECPdrGYa#021
zO`1vc26Ic^BuDkYDV!YDaqfUO$x%&D-D=d~=$p4|{MZa{RfK~BLC7Up-k>TeaBw&a
z$VhA*z%4sCT2ll)4qhp&smP&&H-PRD`hz!$><Fx|D7|$5lv?FC_p1unL6v$3@mPg@
zmH6NeTM_Qb`#-=8e-Ibii?I$lXl5h_>Y$mCoJj}GjAT4*W+dxL4>sDZ@I`iea~F+J
z#b0qCji0C)h0I(n{Y*b<`#(02-VCx9ftzB?zm;*0fP-(BJJj?J(5bU%XgGhclcIaq
zzVu;xquTh^M9?(#Dv)nYVcZDtThk2w80v8UtyzpKeub|A?vXEVt+R14b82D0_g0+x
zsKoac-Woui^j3;H?=4*Epx!z(l(lnq)$wZY&~V0;RfTT??vYh*)9}c7({m=D@7}(d
zaj7SV%PAVYB@H|2{`Ng~`ug6E)128Dc>5)GM5RA>_uH>9&JGSx_z9OIIlX3Da=yR)
zg`r2`Uy>d%V`^cr{IJhk=izeO*UH1>n@3k49`DwzQs6LNgE+RZM63xH1{&Gk;d$Ng
zK4j>Qp^mgTydH%|zz;tHoP1Fo7sF@b-+)5rzg6N34sT|H(L;x680Z2^q`={)4SrU1
zm^zC1m7XQS8iNd*c?-+!Hs}i9%ed^|o->y+|9*pC;m3gM!HzM%yW>@+iEmXF1{SJx
zJbZ?Q&FFj%+#{{u8O;3Bxvh0E)Dg{h)Ua{%h<GJVdpt_snZ;s?tng~;_)@X2vd}+9
zVK;ZfdoSb4^lA};Y~gCa<Uy0IDzNb!u3B(4GS`vK204a0q>oVNdSuCwHyKw(IXjOW
zGWZ!kYM57N(Z-{O0Yx~v*R4q59YMF@n|SHfQR3!z@PTfAN002V=_(DkI)sI8ft!Ab
zIwH|wgx|rp+cV|0feuQIVK|CNK>Za5-tC3YS{~lS{rPS&<J|WSE-w@I54?K=Hq2Ln
z$y6x6$>a+h6W{BBP0z6z&1+}}d~B&mosaG2F&bc+LDjNjuefnF%N*P7cErKE>4Nvl
zgf$-L$qJfy#|GXz3Gv+c&l_Z+j)1-Q8RN2jIlN0Qa*vnUf$JYQPUlIFF?Ag8{-tx$
z@x%5xNt_&CSmt|Q-IacS2%n+epKPC@eDAA;$NQUXpyq@Tcol~eM&KPh>g~sgJtBg;
zB$X$qK^}2EVV)UC4+8KP{Pe&O>X^UaCkLw#u;U_pC)G23MGSTOoz4$|)#%^<#rt8f
za2gx<fO1reY~Kv(Q2fDg#yPSM9;W?$iSL7t>|OA+fe+n-W!s_{1fk$V_h8B4BSH4)
zi4P+pdKDV5l&^1mxJe|a-o{<<VamSaTmIp3$aml{TJ+&3_A0)A;KMT@9>Kw$;}iah
z10Tgjcp_#abxx|Z@oh^uk{{7IDK`t{aAc1CV;qLPk7$a|^;C|ZQq@Zj_uz0|WNcf)
zi-eE9HUt>|7#D)kML!69TmuG=F8X+Z+k-_h)X~t7Z$d%*M%R731eoU8q8RGL|FGSq
zjUQ74G&_T;nZB8E*5}}@z!Nx($b3w5gRZ9*b+SWqfacdAh3^5L$UAqj{4svub~1YG
zm|M<QhC1oXph(~_?RR<OCuyu|ewEju4m~GntZIHacwgX&yu4|qfs>TNAe@6w0j3!k
zqzudw3G9MuPF~lI+@fyqO~5^_q@PU5F?bR;)9ou!r^q1>##3{FQ;!?Derg`$vPYfV
zJ+;Ekzw}Ym5usCS-24vyAn^0W=T{eA*aNqw;7fks)D97vVvk$<;o4IvunfdubkZsN
z;aXp3PkVz>*|`ubdgvmk!*VC(tkyS!6uwm6E9=C*&o<k6SbgXc{;Akf8l63;K`Q*K
z(b*1;Ga@~p|JOPZC2`ZA78W=CQMmM{@~^M3zcS)^gEB0)mvJ?Q6fVEC=lg4xr@2q$
znfcnlC)B4N^W-NqinKnxHGw)J^$A%Zocq+lJ4M{WGoj;|%&DNd@Nd)HVh&CL(9A4~
zp$;>DTZTe2vnYl-;rR6<m>H8s&Ev}Y>56V}JW6^E#FSR$9f$Swy%5u^EmgSOH#Y`O
zp8<oGH=zjXaOd=w25v{CIPiB$LoJ^|3a1p+^%S5EJ%1l=@GE>Y;WR<WaOWw*f3FkP
zG|nF_e9IDGC4H))7S;2%Ie1ix(SY;l^uM=xpM?INrjsOoM-D#}LTBZ_XPc*E?8!4n
ze&9@*y{afbLlcjO+A}wZF!=jLK=v4;XJT||v$TibzLxOmWRarU_04rO&Oe<e{PXd$
z^*>B6EXO_L&<v0o<ZA8Hb<pS0_)i~V+(M}}{!`o=wy)xRDkrwePu~Pt?~QumFAjWq
zh;bEkg&!9gvcHM-WHG92h1rkn55B->q7lC;`h&nfXjJ)dP#)k<J?#6BC@LNi`p2EX
zbDs2^Nqq3+A2cHpE<MTNO>*J+MIC!^w%-2GKXCRDaO*)yq7F@GTkVI#!LXAVEFvH^
z6oYJx7&WUfFj#?I<iD=1m1K$oU3gU~9yRYD=o-ol77?ILF-*4oX$*AL045C<4xK@D
z5)Va3uo+y$FI${bNbT~7P}gS0jR<v7v#u7a#}@?h17FH}Dfl46gb%n#WKZZ{CfU(1
zzl4BCQ~%kEal@g1hJbr?<v)iTdJdzGko}Vys_9?Ok@}}SW71VwHsBDZuz)hG6ist0
zT6P3=GBC^FSGei{73mJ<zh2`%pSng7@T*SMNb^OUQvYlKqgP84B5ud<pF2c&4(`Iy
zNl9<vb~dzIGXy)!6%Kn|OWuFtt|vArzOO8ixtPl9?6UEzC5C>E;8)8G{R-azJeM+g
zYH#t?(~Qf&=J1!?`c+DPwb#b6a8x~^44jtJ;a6XYSPd4CDpNSnE0T~y$NZ~=^;%TV
z+vecqsA=(1gYI86M-pz~png$$2BW6)vm5^!D)9x5fFe|Y;KNab1ApaF`VWVUR9w-<
zxSfjl%<Xh=JSsuoVEUH@8ac=M@Ckp=cb&bu^8HIL6n_x-*9qX7rz>7&#t#@*1{D68
zn_p$fzrJwuEBxyM5xx!q54y!vhkdOA&K;ow__Ye41vv^V$LVVhpc6k1_}9b1rFVql
zA1(1|=Lp=+0&G~d`|A~q8}0u3LAxE!qV{X~q<DVd>$Ir-H#87pc_(og0sm$R>r)M6
z$G*9fakirx_{|zOzl!5G54rIbDb&%S-?X5>h;KZ{@J0}{j$Ouc(l=Y(xSGShp`k|n
z?2v=2p{5*FdR}qq8M{qQZr|*6D{}DtE&<G8B6NLWNs*e%zBweqn4|g!zB%Gn@M8;g
zYHEkPGV{%8d$#*_;G1r8?wc=Jfr@#?Rv>>&O>5#Zh4%sdsOb6a!ofuxSG*vMW=wj+
zaP4=oQOmm?ESjjpHrI`FcLnnzo)cy;Z@I7{xa^$QNhWc)(<NyCxQo_n+zY`Ty$m}t
zje<Q$UgPI93ic>=^E)_=tNgqXY6Ga2DZw5Tt8<qx!5-u6<x3E!m`p8JvFqISc-{&2
zQ0d88qHw%p3@7grpKqjHHu|a|f9}3C=$q%(dxx#3IOtozIO}!rg>HVw-tBIF2R{vb
zTi!WW6oUB!>||OP%wOWxsCqJAX`}!_2Tv5id}9DR{P(aP6$v?U2J^+I$fxrB_1%y+
z$pGc6;ik;V2|t*>+mKVZ8f}U{1-`uEVE%rCU*T^u&iszship7|=5z>$<#*45`R17-
z2??_F0c*6V?wm7&`8d_mk~`QlM2}0-2P6SKfg0?IEzx(76+P1;^Y2uCPRUhL{;dI|
z00(8Y^H&`F7M_EJs%wMax)G=sgVA{^O}@1Z{MxW}aQyQ8zhiXokcD)kve$U#R<Yq0
z_L}I{vRvV{cAqWmwba|IUdCLmlCjr1w>}4_KJ}Osdf{i|?nIb+b=qO*AMEv&H)C&k
zaXUZQJIt}~joaz}frjF1^O(lUd&j+}rQVzDY01|cmgd1y?@lU9>Cq&wa2L=lqRl!h
z+KI6^STLM%i|R-P{EPzB&0TSTs-Vw8p>>CY(`eR~f1w8EznSqc)${TkJSxJsViqm9
z7ohHkvZDg528Hs^oTU_hGwYFd;5S)=zZ+5H{OUPV`L)%?an6?lIl^<@2<&9s<p03M
zpKIV57k>_?j_<-zgd=Y<{iDC)U?H_M=V{*H4#p{UbJKbbpDZI-*iEDg*F#S4DUL{C
zD{zk#Eu@BPJ+U&4I{8HnC)~n;jBs%BZ+V{hkMH6!fWj<Y$iJw6u&4|uQS9cSwEv2O
zMPW+c(jGPPv7BJh^&lL<A;T%zV6BMyOZS4KP_&tG%VyoSQsH~NheOeqZapd=&Lh8i
z_QgMG*h!T0DusUm7J=hI>gAB7FYxO;)eF>1_zT79Kkz9iwBB*>YTzDGK5s5?y?q?z
z^X5t1S>>uQpGN~o7vP4Uw}f#EC3TC!m&?=jd8_TR@;pidEv-UL#16-s8Rrgg@JCsG
zJC|4-W8U$dmt}old+Y1t^VZkLFZJ{p!sR$FvEM|-TpP51Gm)G(GN#X+z&sk>N1dH5
z(6xs5X=26pMQi+AaVytxH;~pZeKK}KD*MpD^wRqo;}%Ly@A<s`IUhIQa0VM2Jbxg_
z9tzGM%(#V8S5P4xIDayiwLG(*kC~l3J3q?hYDI`MAXgN=^Z9;R@cg|ze9qqw3m(I#
zn9|e3w_-DWISY!XF~5aU^SO8yYI<5L{#p#TN#gTw7Y2RB5$R>IbiYTjy*z3xUI$Tf
z!NQ@dOnQ&h;zQudC1}r?F%l~d7E|*Gw{SqCgMUIb9Mn|O-$_Mr@B$jOJ?ZDwECMt_
z5H(FeO$8T}FfK=cGZS1eK=>n=szS66zo;>IK?V4z&y57VfMTlYU3nUHa)e?>IO}!r
zjlet_dckJKEtHT{4ZWZZHF;5OZ195JM8ct3t&Htu+%%SM{yxtB6hmE#a-Up0W=JXg
z1A`yGVuiiVTqnj~8gd+a{{rB-rsb*0#D5dx(z_hqAQG!+8R?I!4@sF!{ylQD;>S)A
zW24cZg@$=JjNto~Cn_G?f&lU9!B@EIY{k#<3zQrD3LgR-Tb~ye76u#DjKi`GAW;+p
z_o5(M77iqwgRe(Tk2<x1_#a_h^_9YRy7?RWF#k&uS3jD$%^@5Dp$87>knaNJG<7%O
z(tv{pgTQo$m_OJ}<AZ};{I_gd$x#drWrAvf!f74jakdMpp&%V~)(*iM)?=Zhp_-<m
zI2goFDlNj$iz9hUrUhwW=x%eof=@H9yim9r3(8tnL>FPnyi(Cmn)*aSr(f9X9D3SC
zA8OK@e~1)S>MvaACaZL~@Mgv>lv<ixxC}MDc|4ddyxomA6p&bP@WK_0bF&%0HhAHk
zOt4UD6W@g@-<)_58HzTdAj3xdE==+w?!pcb=`aS}g;`<UjPB`WpM|as_9Z&yoK%Dl
z^j940t6FRr?yFjC81B28`n$33I!J2)Q334x5aSj~Er5O3qo(n%q@^{PSM6426uy=D
zP5d(($6i4BOKm4bU$B5h_1qfkBCH=huB8Vrng=f3As%NJ(KM(BT;aFt{5@eHD-w&f
zl)C6%odGjUAJpO4MQa%6mN@ukgP&99qL&ODRa?()#+4q)-x$1TFB3Q-4Sp7QlW~jc
zxhe0WL#XL3=LlXz*`eX;+<Vb6#+6~E|4YKff%?Lt!4B`&%xj_4dZEN8thESM31uOj
ze59_tAr?L(NF^mGG~4PVRx*%rw(a19-TW%3B}3i(4nEw*vEWc?lLkPBN4o{o>{dd2
zx<j0oCF4cxw!)HN$wbh#hJ=!$_D3{-DZXiLdF;(&L|1{rHBPsFe6JSt8Z|+c%r)qr
zqfY*+v{eC7_yU9fwD2z>e>i<h7P{#x4hW0r>Y6~w5;uJ%z9??XcL686w;S{`A_4kD
zb+)m;Z$!M*!OkD#?nOmkZL|;(_!^O1hV^twlf5(cmEaQ5Ex6#h!Nu;ZuSzyDZlOfr
z)Viw#t8Og(#s*8a1Eyp#?e8RZ92O2eAzv2JrI;SEbivQ$<_Amrhy>MZZGHWNrFG!;
z&{tY-3yckxJ_3eZ!yJ!FRSPW8HBU=Fk_|2WoD7%v%J52?TVXJ48@x7HRt0VkgJsmQ
z9(KxZV%$Qh*(r<Cinye*Yz5GqTwdP@u@wi)?qr-tpo6a>|4JLzgRJL0pXkb(8MjbU
z92I^9wVW9z3}wd{w@_;C_4A>Y<If9q5V<(mub0HtPle<NxTA%OPriN;`^NgU!F~<k
z^tdS5&&ae(Lf|9K>rjwIZtx``d?q|jzb$~S@7K!f+I|Pr2fVS&Uh?+Ck4f7f%EvWF
z@tnqWkUWXQNV4)pBGyW(%9j%xejU_)MPRUej}pgE0@-@{_oTP2obwB&{0*sK|G`kM
z`$}zvul<LJ<ZVzqPQG$5*q>$xEsB>^FrP{m)mDW^q&yxTrY~X#`<t=iUg*D0r2ZSh
z?*E|8Z;ZygP?pVXX7g;u!CR%7og%p$b4&kM+-#SmSR5}+pw^^SYfdm<CDHM1*#!MZ
zt0~laG!%YX%HtiUXwBH*0L~qr+w(4|lkx+K4S9v*Tf>x6146cf9|Q-`Nk9*$VjSO%
zf++^Sg*qG_FpF^&euZDh2J38tjlqk{!KiHt`j0~$3N9YVxK!YC@EYKngM-VM|9ZyR
zpo7l?u8rab#ZUQRf6+|}Y;y=Vu_Eq*OIuJUhn6tT1{{1T@Gcz2NVxbR=4U;FZ8_*!
zuj!$iw+`VEL!cUUGQ5Ft)iQ;v)KdnCo%pvJ{0e`Lam63AfAAFoFBt+L*oqD@t^_h7
zyBtG5!{pBla+e6*QCNBv#R6^&R4K>Om--nmVKEg)g%59Dfk~IRwM4(v=7KhrPf8mH
zVW83NmnwWA>rwnswr=*K!q<V0G+CflMJgQzn%&sWiq=a3wHtBxRWI6(qjwemc9C9z
zFKz_~9%Di2**3LL8hFCMIZ+3G(2b#!!1aN^c{=bD=C@Gd^x)|K47Gf*s1Db_2K8iT
z29XmUqhpX7?$XJ;OEcg@rw*FP{IYe<pcym;xZZ6U)QP_qg~#9+bPsUtYo<9x#&mpX
zD=S(<0ys>=)Ni_B#s4U9FT?v;4>jy+3J-^Q(3`A?TRg;%I<?>s3NOP)M0zz=se@=$
z>0u~jr2pW0sV@{nsX6T6<)W6(6rq7``XyPGn<YZ^M6W@e{ILj!|4MJ0yaIIzKfM+l
z?0i^nOZo;sB9hqn`v$)(IR~Gy@r8pwgB}l!_RynjE+RwfuQ+(=G<+t08L4dzQKA8-
zA*x48;k9%Vk?sWItCm<9T&k`YUy9dl71Qn6OOK1#Hk<U7bZy80D#r$gn5LSfsUgag
zMRf#0;p!Uo5In<r7i>OCdin>4w1eya;V_yq1a}E=e-m%ey8zz;%@1Cd$Ct7%>%)uR
z%dltmT8my5YF=fpLgbqHvIZrH&BR>@^3b00;m6?60Z`y^jcKU5Q95)+^CMWK4yB3A
zBdSB^G9E@rP35Q#Jub4V$k6BZda8eL*hnJdFxoh52EEG$K^R8+F%O0cv=!GZD=Vl!
zbq_eG6*LzRZsE{^U9n0e??w#pyH(iFmS5fn#B;w77Q8&hp}G8F^+DcE&JSL$ZqyG~
zw~vQMMfyp~gy9=yx)0wBt-A4g@}W35VhG1~#AMVx;ydC&#jvRx26cC0L`sAk(T;XD
zJtD(?j>Hc#+>H>Atg(G*9I3j<f<_7i`!aF?YFgm#i4nOtIPxaOEvn~jbMPgodGW7c
z+(N1Ix1d&&Cw_fffj>Vu@{sLK&B!A_Jt8x*6Szk}Mpa;)H3T#xKStpPck!6+wZTzM
z-3YE{Lu$MeADTC+nQ@Eixj{Ip)sCNdJ%(%0igzbCbY~U*ayL%x22L}fv`PB$2b+5t
zm!m<#gzv}4V>k@{@=-Lc6TuWX#uo!eodA(SX)=5Q>_Z%e#!+7~Zt#!xiSP<s))`IV
z)mz$tIy@X5WL)ao)(~U7oN<flh+>Qi@DK2g%;*sCIbbomaWoD8-+DY}G<uxK45J}6
zdIryFqpt%i1=my&p^bluZ#3@3+E)TbuTrAB<!Bs@@VgpUk2;*a0+ZQ&*vn01vT7su
z@)c7IF@;}e4>|Gc`wD~n72)6&H+93?BB$~zz5?ANy~DU_Vec!$)#}3`k-)@M8K&;n
z&bULWQHRsv<0uk1j4*`Hi0IF8W)FV>nl4w1I?2)5{@m}C1jlqU0gu6!=VzE->g~dQ
z_&+~5249XOFl&#M#$Y9dj*M}-4T<72j8#(TbetnzNoPhKuVa2XGio@0?<-ijka131
zNB<JS$#X?e25vV5lz}_x3uHK*R8l8WD2(t`ZW6II$f8P2qigVG9~uiDY-5A0Up2S^
zbu@S^jR$Ig@<-tnz!EqNb7NQ7y<9%_9?*2TYSc*|PCsy?-y=*`=3-3VAVR-@w`1G+
z63AHT_MA@)erheL`;2krp2F$kqeoJV!%c^^Ft1jFN{qc5=eHkwDjzqO)v|l4+r}-h
zqn#fdccX|j;qmzm;G>92zHRrU@fmK7+sL@opTl<m_ZThXUgmoy<2t}VhY{9sS&@ak
z9{ly=;FVz!x*zo!cE0uxUP<l#@Lahoap4Hd;>s&&O4S@~^rH?(ucX09I6La#$64+q
z)473-0n|y3`a_pf_-R|N@yag^xuBFA?=$2SKGfhZV}2SxWXGa<-nK@C*Py1gM+JWT
zTpPze-oghuX>*T^pNE<*KtV=B#xFpT8=yUBasrKC#{3pa(xdoqM=h7vIsWCqsd0A4
zi9Qb$o;OAffl9zI?x?;OH7^yb`Ghe3K`;!&VI;wLJd<Ld2*zhb`~l4GQ%EfiX~1dg
z1Qj$R`z9=sbM}OnA>*;~obZvT{fbUaRg-ziRds{?d}d|UMo4%>scJLh(vs7}D*R3X
z7BTt3t139LubKf)ilNb_t8SE!G+q^DlULniuLSxBuc9z{tOTw~^0l$6J^;fdIArtj
zf&PkvSDi#bxO9p@`~m+2MXnKfL*k5|VVwCL9JkSajwlZXS&MRGNQzAy%D6>!q-KbU
z;^4$ZywaT*L)~MrPfT%4Cej(tBPJ8OI2Mx%MC2ii@&T$ooMSU-G$cJ@GwDW-&7}2U
z@QBT%X2y-!Ofu)=6!_4XNgGh)ay4&=!V?sm65nJ$yEb`<{o&f+<keUZ(Fx4x=*h6)
zwS=4u3pQ?ebhUg?DnEENzmFhzH6@!zM_j#^ajC)Sh^ytvJU=)kkN2}vR3N9wJ_2bu
z_r;VJDDmivDM@bN6#OJ*9DQ-vuJ;d4Er5VW?@smG8uNowWkm2{q)hRt7OR?iJ$K{O
zxzOR!jZ@WS`l)RqdJn=pwcXy7PVFY+r*@O^Q$G>4E!YcAH8VU5yXf7iSy8(lZBm_R
zjkK=-^bcA$g1!QW(TUblk@y$w;H@}_Kk{IZn~lbxg)?1`As!6K`5t{d@J?WNo{L{Y
z9_XE3fjV5jrkHVy>KJ_rFGsDXSiY_>xbPZtgxU!L+2O>4!@@zb3ZI6Wm#ym=w@~V~
z=8EV#g!h_xK)v)m%rn6?NicZi$~Enr5!W2IKa34dD`8bUrK@I5vzrB)g+p^;+ES6l
zYepe>2(X9m(<r@k-#AXw@dzz^_f5ZEq*2yPUtq{vs3XqPZ)V)CBUW|^d`UO>y|&&S
z)5XDc_}!A}G!N-+De>lR#1C-DrhfzmkC09OibFO-%?~r?$(GDmV7J6KV>^drW;d~%
z*-b2G4wT(FbFkqXr^n2p($LJ|wxNYHX%hBm+f3>^J>(YZ2<1!)v3CBsEX4RtjN5kd
z@*Es}OAmI=jET6wC`C4*=(pd{!W}yEO_9QdE8k39h_a=yVkD`ac42M>8>^-5S!T*B
z{CW}kEw<0I=7NvfB7NKD$jvjnsA7E!4P5EF7q}i1g|B0N)pm~ctcPq|{Oq@df$~|#
zN$4^qyn|O6v(mDyAKAIlKRCM%(p@-;a5#U(!P!v}{S9KW$_|lO_M5_s#Xr7Xc%g50
zQWEx1h)c?=XF%v09EN;#o%~irHRk6iVqF~<iASk?l<R4cw(E!O`oiijp+oQSdUB>X
zSp7BQs@06o@d2kOQ3lZ{=Z4Pdg_=h%%)xf$w^*T2qU&a&BwZYwLy4}Pyf0Ju04X-u
z5NlvDnl^PYg;z*1Gwqd=D(z*Xa?Vc?kpxm{&MZT1g3Xb<N3iFp)H8!Yspl08nyK_C
zq*?z88+X3Yly{jTw90#*bFfFEUYnEQ@-+2gX^-pdWboD0$!t0KXkouOq|2j&YVKs*
zLaB9J4W+k-uQl84by|L~1`FliVIN6t)P0Ykjvl;rJmWH^d6y}?3b;qiuEmrAb$C6s
zJqKL-vIuQJm7hKTwqL^E#<#BUe8Je@ciM0=#$6XP&%e{|jn9>jnm5j;Jk7b=b7mZM
zxI4d?af|BM@hDtnnu$*XmzN%uDki@S^9W~v{8SmB=|YRM!oRyngtyW@<hz^f4`YMh
zJ;R)wRSqW&RnlPLKo2VXKbu7Q_ZVU@<Q1v^ih!9C(wHf3!bu3TaO3w>M5MXAp%vgo
zq`qeiO$S$FkNGdlFu#gOnCdu3Waxi!@cYA2^uQtceczkG_-Gq<lHMUK#Df|MoJDQ`
z-G_tyzJvq$gT5k5WLp1uH0uXZyIJLnXa%Q>r%;DGi|{Sk$5`Bh{KJrlfsC(^!iN&y
z&DY7_(+%F-B0~4!D#gu5&=~p|7j8W%CABvnW1L&>;JC$2a*HucyyO;7^p;y(EeFEl
z8%1;@I@g#vhT3L|gNv8J5Tz%Zb?^ofEAiFWi+FFkVOEdx20n}p{^$_6weDDanp`ao
z{s;}TajD6t@Fhsg#}SZrk$oHrm*6c5RP7_Hw^WEYRaZ;&fV{(W%W0A+@hvSQE}Ew7
zVv%gp(wKdFDL=S$lc?PUa)B(uB1W}Evfyv`-1@L2;`w|c`i1`q6nHm26^rD#ZW(q+
zM10x)&4>Kpvg0C3<N}ePVzMmY1T8v#{IW<B%4?8lym>QfZ6ZQNPu6hT5ZQp+Y9*fJ
zYKMpu+Ys5z+woH;RE^rGIJ&veFTUAaSU__d;VD@lC{)9hi!I2zAqcaUcY|AG_?O2;
zjK~{Ny$y$vUduO&B*@TATs?3HkACGjct=EiXxQa%1p$xXRXkaEMWH3Nu4obAC-Iid
zl}{G>3qy>dF@$Y-vhaeUc_{|lC3ut=6O3gf)_W_k7-L<cb}NJ@0E4aSt%akDzMGP?
zl{onlO%Q*GF-v0m2#Yg@B?|GK-3kX5WEhM}aM(65+9_BZT-hYC`M_YTejAMaXPWuj
zByAV*M;J>>?9?_WzA?jKrvyv4gE1<xhCC794i9E;2jhQb8N|zH2wVxq9!b%(9bv3x
zQne%<CI0WR2Mu_pj`({&1;vW7L1Gi00%Jrm#wECz7$dB)Rbm2+zVBy6>r=26V;ZuI
z6rUx2f-pK8vLgL7uwhRFOG@k~1rnQ2Se&tt#MTlPW2{PIyMW=R{o0>K7=M^zTD_!|
zJ_CL~V=;-%CM>~Ni^NtwgNFSm#b8o`TZmCPg?pmp=ut5GmS#lfGliGpG0i^7!Yg`w
zASNdZZ&7CMw1odzaPCV&niQg$ch*VlEHFF>Snw>O!iw)~lBD_1g56^Fgv8bo7G|tX
zV!H@SFqW3ssb}H+Pf`qaO0e`f*b0e?=U~e(Nq3cr@N;l&B}giYcZDUkg)ocxswH-m
zusCD*Sxl1c{k)w<WzR!xgh_EpTKqiRSe<4NOFZHi;8$sM7w#_;wvVtF^WoP!2s=wy
zlrelwVF$2bI}q#*aZ$AcUArMAiK{}AxOPWQ$*L-e?Seqj?-R^eE5TDXsHE#9So#8S
zW|%W3!Px+Pk6EJb1=xEm%fzH4ZXt<{5e9LSggiV-;Nup9csD<Ry>|lKti*9eaVNkD
z1h%sH-MH*S;9`Kj)|6=2iD+h|mb-DSifH>t;7N|i-E|T?OW@X8=8Q^k*e-zE6laqJ
z=M%U+$(#uZt_A3OIwM+kp@GlDnV6QuQzY@MpTSNEmbMWXk>EXfBGm@hW)t{=#bB8P
zR}#1@%^+S#N}O8&`d*BRwl*|S(IS%8`$cr1!tkR2#6RIhC`pA_NnC=9i80AotHcB`
z?j{Vw>z<SZ_W|_ntrZ<FqIvtmOw2a_4>S*Z2})8DYAmp!`7c4ofe>RM8(T|k35Kd{
zXcs|QhH7o-6d*jQ+Vv7zrI=$jW%mDonRww=V~Y)~B#519Oxn;Ef|Ovp4IL#Y%7Pgi
z>isgT_(j>vuo9A#m|uimMr#&>q+%DVkeDDW!hDv*_UTxi#Lkl1lqmQ^&iPoAB+dT=
zRK!?CLSk$GfGGWMhQT%o?jpuGV`+(<BFxWNr^HHMv1f~lS76JMq@Q9EdIe2b36g5o
zPcaD*wuP`H^I;Mq>?mOzn4e-2BCPkTz=#b|{%M26CIG{HSN&=(T0g}cMC?Lm#~ei1
zKEh(G0&@^yXLUY&_bdf$SPFb;$#-vo#O4FT>Zm@2H2YhIX;qT8i}=Hg)k^FXVF||S
zC06<xuq0zKiOnV~!dQ#MRszE!q3Ja=tCmUal5~{Vm8p!xdhZ5CY>3Rg_)YoUXu<@-
z;u5>hFR{fM-+dJl6T2~d&dZ3_-DuZ&Sr(|1#Iq#8#_o$sY}g-xS<KfYvH64%1PAU*
zNNg=(NygeFwhI`Ywf~5AMVZtoNu_&o?5nYX-h(#G-h(XcpOK8KvHm7-B{9}A7M9o+
z!Xk`evq5}Efx%Yio?L3IZjhu2uY;YNwK^`b#e}iDtFh)K6+-930+_IUI@Tevv%p}g
zU@uJhr58Ud5dOVjpT8Gs<BWwQwstR?H8IN|mjA@Kix_JetCiR(U_BzDi}c2r6qBUc
z`@kMytVLog_d)OU41-AtZXw1PWB3_2vUQX&g3w(*%SfzuJ8UIISvzc5lC;JzLhWE*
z+z!37G7MtkAy9x{Ij{y34`KU=@!u39W*!31>Woo|4f_*}`9;;AU@XFVG4l}nT98y6
z)?nfxY!_i1*fnX1ogys6vY2>?uXKOTr?q(^vLD#&{mAbhW<=e7<oC@PDX=yyiCc7m
zYKa{sEXsTliS_<7umocb5}QC+nz6XV76U_vHT)UviZdxCN&ARB#8`*K&Jq@540k^d
zz~5m95W`!t5^Tb*kHGl{a`u}-5?c$bM_9BR$k}SDm84U|Zn27biIu(qjNNUDNo+P@
zVdiU**h<1`8B0oR3ovw7+Zzbs?aDP=y(8CpzX|?0^LL5No4_UzMiBDre%zlUY%yUW
z#wsKxG}-$tiR}Z1X}04{G>f=NMO2c89n86Qf0M-K6P94Ugv8b!L<sL>Kksjo;4T91
zQeawwryz~1bzKKxEF_hz!`zdGzq8X&>}L#94`C|_3p0kPhp;V#DOpTCgdGKjHgu*n
zwU~N{G~q3<M_2`>9>NwAMiAP%4pR?dg0M7Wn0g4?N0`MJrXIr1zJ>IDAR`J6!B$k#
z9>Cml2(<Z!z|T#10CNvvYYB@nAEq9{b`h3j3{wwbrwB_iRxh#Ax6!PKsCYZqtOqdl
z5c^7yl)DdL<{@kgVKG*LnTN2Wghd#`%tKi3!@w-Yuq8hXY{FqQYePm<AI{l&5L<Gh
z361|jY{?1RM;JHZL2SthJ4;wd>U|J9a>9na11!N9cI1T32ZnWB{W~xfXA(B#MA}8{
zDaNoNC+rkqX~wW0C#>`cu$aVtj{W!%V6zE}GKTFqVJnZIS^F}g=?H8Q2|fOE?8k|A
zl=wr8VLMJ(@1wvXjA1)Y*o31<<oy{2u^lIHF)=0>!*-l70SpsF>rvRMWfFGdL^@0C
z$~WxBJAe)A$k~4gyK%zi6J|--hp-zbY%O6C#;_YFY!@(Waoam!D#0Xd#)(w=F4$9y
zVKYwHY{J5fVKYwHO2XKshp-nXYztv==EGi`u%o~*WINx*Ty#9kG|W54K$~z3{C<i3
z0`m@GiwUb`4D$|Qg0KW*n0E-<2Mk%zaSVD-u-;!_;vw3w_rOo==&oO2;vsB4VF|`C
z@esC_ury<scL>`>SeP+PJA|DAhUHz?dk7b^$MZz!eUN4!2fHQN<7E<CsbgV@ZPBr6
zi5(>@#<CHK^?n~2*Od`v@52_m5sypS;`hNHXZ}`+3Bqa_OG#`WVM)e1BzBgt5M$W6
zpMdYfPM}#4QFQ_#EXYXOFR^ha+FH<5TYrg-J7K#Bi!vYf?S!2oEWsGI?Sz&7C1>lG
z*tHWj8yKe8y1$@V7PDi|PNXfw9%c+%cEXP87<TN0_0E7V&V1OgXMjy0jAhqjzfRa<
zVCb!eOwQDLY}bjjkJwXE#d_@42|G(zEo0cM6E^IBfh8EjUY)S{g!vi6R-Lf5z|g9e
z|Ai?<!bY7)r-<ERcI?v$EBydiRARrvHvI!&vk6NxhFv;gD+voRhD|zQTYzE6wtWCo
zDJEf$PNd!+YV6pf6E=acF!N!HPT1lPF%yl?Fo-=mfkGF?7M-wtz<OAs<3rd|u3^^s
z2&7>jK`&{*(0UlN4q@{N<7PdKS%<K-g!!2dvkqaqfMLkCf0XN(hcW9Asq|y8Cz&0y
z4q>wit7Qzc4q+<^Q))5m5Vl3<!>mKtQDE3UcYX|0VOG&4{HH*ga1tt_68p7ZVvA2A
zGPAM_R!C3~W1KNdV*7}3j$*8n;8`#tTm`3cUGwWENt%BOIzp@?A+fcD#TaXo*e=4t
zjHM-Zim)_eof0eUv_n|Y2~&PaYQ|Q*lR^WM3Rg3>>V$3SguB;gm=Sw*0*?}7gfZ;Z
z3G4k=U>0N8s}nW>7`m(aub3WcxyjAgtP@S>{Mf7$wvVtV>%eB6u(O0E7{g}$6JWzW
z$=MRvtP?gL7|s&)pX5?QV6RT3UBn)dDg^fGgq<QR#2EJKgq8jcSS@4Ns}nYxuoPq1
zs}r^o7#7D(f7481uTG?+e?z!#<faO2)(Px=8al$P1Do~Jz$OsJO>Mzuov_7(v8@(t
z)(I29aJi%PG;AfMiWY3uiFEcfZ2d69Aol764*NTFgc!qKov`_Y)iQ>?I$>)G^D~CM
zI$^tj^@xl1zr$97N!Y6ssq{?Fwcq5?jg=BH>r7!lHS0G>Az+QKMj-bN4!X<g{1pdZ
ztw$w?$0P}O6rbn@AoGuj5CwP)MGqW|S6ARO;Y}$1n!^dT@i+?mWxFi!LWBuPl)55?
zW25;gzI~elS+oBF-_LqA1Kdlj6Zkzi%=Tr0X?k{%pYS(TfI`zVC&IWNCHRY!q7g9>
z%i_V95gBF(Nd`r)DicZ2#nWqwdN&4BVK;R|40SSB<;L%bFmAc=sxro_-S{0OPkL(I
zxTC+0aB<!L6&96GR5~JVUU(Y)KcvEPMUT4aBkEBn8x1Hv!eN9m6$7S)(&0x)duTYg
z@CQ9{6dFDvY2zb;sTMb3WY#7GQwcXdBG&vFB0sE+$t17oTTmgwMBmlQ^pu+(#uWpi
zKdjoD0o~Q*A_aQU&ntkFzgZC<SX3gu_^i-ht~%m1qG?9|Gb=*>pmd-%K<G8UL2nne
zL?6}8^pKk#$%vSX9(L0yorwOQ+^E+qHy!Di0lo5Jk|X=IZu$al%xiUS{O8#9eGa(=
zDc~em@1}<%j7Q!07_8(VS3WYu^q8AI0#h&1RWiIrana&+1+IB~j{DEb-K3j5qD!P9
zUZY0WYbiH<Xa;q1m%^#39pPuZ!@yfa`2Qit9e1*B`W4h{(%0q2N3egp3*7h%ZIXXC
z+0*R*GQ@b98y8hJJ|eiA7&L*~lp<o#lh7|xaJc-ov@ICiUFVh?+Agx74_5Qj?glqq
z_1o^4@c)09hK7Do=r5W>y3oqqNfEyCJbcrCH(A%bxtz2R16kF)xvq-w4wO27obgUK
z|FvH+o;CQB68|F=J;doR3X8;>X9^2~e>CEIInweho}RdNwWv5-INEn@wWzbpKB9@r
znzU%M%ZEj$UEUzdx(M$ps=EpYmhZ6*;2+Oba}E<w9NbeNVqJx$mxoZ(+BfH6CRd=;
z+BZBSQebc7X6~`v<PjuATI*0~>Sj-7Jc3eFcRBG9e*+4gzYpUvlp6ntDv6ixAqO;p
zS*kf$Bh##~r`4c8Dh2l>Me33w&{GC|5!2g6sD$Vp27M&cGa_9|bm~XV{!FS<L%Kwm
zM)~X1eL6iQ>91q4T@LxzLk4{{(<?-*AJM6yx;!`hbxVZ)RfI%+z1Gbz<1{O%L#ah<
zWEtc220sM|4!<5nq4S3skD=5Yn6B_9;-`0@a3YPY#%EI0f<hCR!4Z8u0bDl_L7n)M
zD0Kc1<83H){szX|Q7Zmh@p<|ICZtj70&&JWQ7Qp^oURmQ4gOZizn2P)e;P-0Z-Iyx
z7M1kdTV~LeocQ$mqSErcVS~)=--`<emll=O?5#HFA=D9vy|pMb_ec2|kD%1tx#l?I
z^&&pAsHAZ(HAknnFg=D+*Jm*vN2&AQz&Oe2{B?{|^K^dYSJLJe-}+HepnPx2&17+(
z>}?nE1xVw)9R^)FiOZ-Pitrtgy;+0dM${=PT_W`xV%S$;FjPo}eSTrxh_LPpx#?56
z*Y**g-mFfRt1|f87`H??Li%bA`YNW^q15z^E@Qmj;IC#pDxwREN*3&k8T39(Z$hc-
zQ*teC{wW>IpD_3%BK8fI3y(6n%^)|3<Tp57Ou0d{e^WTRaSHd|zAl50dK2+(C%V?#
zSCc-%%TVZUrWp^T)cGTfSE1DTvo_v8*iP-!1$weTt*9M?Olgm}>64WMxHyueL}+ht
zGfb*w1u>BtP72}%T^VQ*$*YOp>ZVWRRBca+%uPg38T2UX6ak!gZ!0Pp-rnJ+t95UC
z2DsMZD-t5r1NtVUfRlWeL2naT(0vnzhyq{Hpznr3*5We0Q;Pkm$`H#kUhC$c)W&$7
zn?H;Tfxe>BtD2Zht<k&;lUaE8C!%ZSCx;l1i!{U=ji6m+F*%7+S69z?3Z<s5YBl5S
zD0O}^OXfRJX#C?+jAu}Se~CKFgcD52qSOT_Or)p_g>Ilt;`<9wYW!m}jQdgQ{ArQS
zN3T@kdRcza=%VTf^VNz_&!VA~V_Lah@0J@=!FUX%W~cH&(a^JK(B%mOu0<X0?k9Dc
z`JvS!)f48cBch{c(P%0Qz9q{lF6+5$;j*2}E-ov2N&dQCMT7boVO6d9bEk;+LN5QA
zqNRDO=m!eiZXp_J@RvLEutCo>_m*Cl^_JGFxoqIFmCKIaMOWZ5d#C_Y>{x0%g75|v
z9$vg*^v&3I<`22~=is$~&?kxuiweJQcs7b!LN=;UXn|I{fHy2RKDHBe;-?PMd{VoK
zH|j(h)47;cSmdv9l-IkJILf1Ld|Vmoq&$YgrCcPivJhXR0rrYobJVfX0vQc=Y$V+H
zxN6kNMiPa~2IFlgH9ccVFY%`&E~XR}735mhE>UOrMNlX1v>PASz<36w%c_VMVUaSH
ztdd+7g=XDpU6&hIt$UNiH2!g|1QZ9~^rLXuVZ02b#y^(y<`s*}&MOMkjO<{h3OAEu
zEbPYZ_bZSw3%JXeh@FQ<jUzoouSKC5b?nr+amP-?jbB-SI_Zg`aM@wJ0i~vY9O*@)
zF6yH<s>#jd7>m2{E30hb;F}4QE@L9vhZ;qC$eAPx&8X9;HaG6rNxAVW>rp2?X%sFy
zjCY{a^p7LGXw<jP*BjO8W^#;W-T0L)ws7zu6)s~Ua=x4y3KkypyM<JX4wkubW#nMU
zjbGW0I$CrvjKXDv@hUkrd~rUe21j`{h*~op<+X17$}UzCLFrO1YKzf=r;9N)MBOru
zjRrUF*oe9D@fE031L7!LHW;TUYQCze;b21I;!H872FGfvo7=IPbmQaeP$#P?6fUd6
zx}d0}QcVp9)1YhC9XlOv92Y607ZjC>U;M79*Yx1Qtf>`svexC6x{|a2CnLHQXiLM3
z#_?@TFGK0_lJO8q&Aag}j8jZCTty)rcH`<!W7-0Ku6|!IExsv0tD5~q{=p-uQRHkL
z3NPjOvdPw>i!KbNqoy{I^=mOr$J`1W#Z7J;Q3wT)Wv~3MsQ2_>IsxjrJ_gf9kMraj
zOefFL7K65$3H89K8SUNZOS|QG3J9h<+&H|;*!tqYNnaL)mw#PuxpAG6|1Bz9VH8#n
zQJT=k^fHtl`rZn;<*sZM36fKN{8rdapO8Tv{=H?PaOrEl5aAeE!Q@($nmgmOjMuqw
zb;10th#Md27h&itAC+XesGB}MD<U?X!cOkQ+;oI94*Hm?0;VTWy4+>F6{Y6qNb%`~
zxW3`IOVQKFxUL=Qi|9CRlX;CkDuX(?lXl}HJ49{YqSAi#Ozw1(N7aiM)RvF*Grh}A
zM{ANK9+Bij#O7*@$bj6~!sHN2%_(&i`%u`x6@Qf*S6zR|a^qDUsH1U*YEih%OFVd}
z4j**GT_SN&QORJw#S=V4&DZFTp{R(AEh-5fih=G@+)S4z9r3tZd<3pzgWl+<Nx11(
zRijS+CQ-Q5GTw$#b7xGJ@st}M(at!P=kkl!ONxU16c5G7#UrvM=s891bdzaLDh0Vg
zT6miZm#3l@7huIbHAMx%xBYI}5$z(Th?Q@LOd{%N``Z<6T*d0`ut>o0<rc^;gQ$~O
zH43d6BX9|;48wawhUrF6J8C0txrqhLA4Tc1Bcf$!cZSI^lx}kgm$|r`?wD(F;}fe;
zC-+-XxXd-<I&<TQE+)63beUs3<;EQ|?QVP`wT8@epm3RCJcClxKPGA8;@ACf6>($}
zGiBXONQG2CoE%?mD(ZD%@Gu3=rCMa^Qn{KT4wt#5amOq~m)h0*d${5pdTn`8DR!mx
z<wc{*)lTnl?Kx~oTa6z$T6j2e4n5;C6Lr(k2!DTUj<H*{`s?ntxcMf9MAW8}n`Ec;
z9C`wDXJ{WbdQ4ppJKPRASD08|+O5wC8}*phGY+0{<C7w&W1)WKfTBR96Vt4l$-%qa
z_$1t69-y5<-zhNYan#Z1cgj$>oEIs`6{(ZUI~5|nx~OE@J7KrHn$O>{-1x){>ZG^Y
zjpJMzx|kL|C74CtsWXUKQ43<x2tNx)ZKGn%#YO&!j-@6;sDhcPC0aNqg&4<WNX*RQ
zB$Sk^_1HVDZsrlVJA@nS&PwB*l$$;&gE}=QjlvzK=)j`V!WJfHq{EvB!j|K((Ip5$
znrx{M9VvjY=D6z0BNPP<AJNr32*FWlawH_%HGYt`fISj6WJm}6K4Qu4J5p`XiJ$0Z
zPjFC=L=1l19e@+E`;J82#F1H%9fWa>E)Hqq<w)GkHkpHUBmvwNOVr61qi>veBth2V
z;l!`ajdOs+3n82eDfXnZ-Q*D&_~=YwM>^benmcf}vgYb~md~Q}@|E;!J}F<1l9&q@
zQM&u-(EV=uM0`Ku5}bnwhPy{YZZbWC0C6WhkA~fJb<^Oe1>EJP2oFYAIA&|zat>Z+
z;G~EAh@jA#p;kXfDJ&YUa`I@@jdK@`2p(;46C8n<8%IM^aCo6Q+Z~O&=~D_&C&v;f
zw1$r5dk#lifoqOU;r=_?=H|yap%(WB?L4kL+U^z_6+)eiq}{mVREMyxKxZE91YL7N
zoyd-6dB(YvE?HJdWgS##o+)J=1#WywlKIO}x|9oR2zxxdqrxpTs+NVqZX9VGg;33u
z4AZMox|A|b@|trh0v&a39Qx9vZ>pc=qA0!eHMr%RAjI4_^o1`&eon0dj)-@(pzzX{
z0IvH-{t|zy8+U@5bmLPas1tt*#ku<PgB`eSiaEKlBMk=K5IIDG9d6t)lyT!zn@}hI
zEQ)gt1v|P7e%AjkiRI^A>fGE{2Hq_&1n^yxq4wG-Hk3LdLxRP@cdJln_SAiYcd5g*
z_E@Oe{B<ZaevAkIFtlH-O5d#qU6Z>aggV)Yx^c(N1~+bnP$zzhhszG*ag>^Vwkw_(
zRumX~1vQ3*6K*EQSgXjqKv!elZ3BZ#dvgUEVTA#ce7jrziWuW*H}2@|aO0NZ?*#5L
zgF5NYqR<+_Pi~1{S5PBjlIa)~8j~`1tUzQ&V4r!c40M-rk)=kch##wP%R73hkzRT!
zcp7eHP=~X}s!_P?FkXvN<5&BGpIwedSaD{GxS5<r)Qboni3lER0NtfrWG+V|SXuB`
zlUv?Op-xVbe$BX}x5bTLW1&v`tteb}7*C?q^r%MMF&x*nRXQ9?xtSbe?QZ;<DC%Ua
z1BJ_&NaKEYu2G$CIV;O@RBFyRcDmg7H3`Z8UI9v%9mf4AH9c0u#>EdupiwFf-V3>z
zl(F|J-1s$VTR8Y$6-t*ekwO}lt1<UpwOj6rn8<=&<LIq()2ESI1na$e6fV7tM^S2x
zz(S{XB(8<2eZ_k*lg@HYZrl=$Ba2FXBf=sH@uG=k%!Y3SVBQiZM;7@j!xn>WhHRMe
zlpBXK|0oDg8HT;cdmV0K*b){Ii|-<0r$NMdbyQL5C9L>(0mvSWKaPj<Y3p%h6m31o
z03vlfghGqRG^=^EwzNA=I(2e8>Lg~NaM=(MlA97|dM!##PA%1r*SYa4YDFA!&Q9of
zy_=5RNy??S!Jt>5PX5H)I8NnRlABJkAbJZ5m%ofBP-=d{UM&_=HB(YdPa1TK@isTE
z9-lo<@zL~+!nTMOXQN^)*Wsp*tPmNOy-qh>CHnEK8=oFQ9qoFb3Rk;?6{dLlnNFqV
z&y<vi+H{NQAvb*lo<1hJT5`Q#<))8{iF6n{0}lK9)o${XZ1Wgxc)nlfCQqm6kk|Dn
zTwXICMX7m<XQ?C5SE<$k@5kJ9wSRuU$&I7;<K)MTFmSS$K;dPt6}V<kO#|;I-8ix|
z3w_QW`h9ALCN~35V^(4=R=xGU(aSTaz2rwH3NJshZhco#+=#!+jjOZp2_kFud2c@=
zc*1WGNC6a`C^PVk$mkBAsBqI~Pyk4-3WbNmCoJHa1IpnO)oxtP<0op}c+TO7K~N4;
z#54oA%9_A+a3{hi8r<}msM-!Uq407z4qVgcINajK)!F$(!i}@TjlmNX8BLK&%@b_~
zo<W@=m_niPs}woW?#5?QgowWbg;xVI!1Kj{aYaSW(-|i^3B$pU;5xdqZhU3}b?E*J
z6)xQ(bR|v*boHz9FMbd;W$Fa+mohi5jQk}e(ht%Dd4CC;T2Uu!|9@R?1LjtBo{Nsb
zKeEOi%OkMm;l~>TMlc>*9>A6j4Z?sCP5?oicEVp|V}l@I6x)DqLYbX}&`FzsdKzXa
z2_Z_Fw38-H)N@Ig-qUlc-h10Kr?<V;Jtt|0Hfc7$nFIm~fg=9z`)bzO^L^V2&jTOp
zeZT*;_TEc-Z)vjgmzy7)&*$MxiC`W=L<zkWG=5pf>K7q(%86~<^*DcJZ5L);(Rdig
z*ZA%<#>}e<q2gG)1}XBjam_ck@ihgP#FSPFgEch1d(1j*LaJbs+p&wdY}V4P`LES%
z+s+T{B?|_SB9So0oW^%gSp5#9ieah<5<W2sV%iRm;hNz0yY(ETH1FaCp2l}KF-8M}
z41|hj@hqgsn~w>z$YV>v@_EhU)LkIIoB7jk2}1cb4e<Lfs#(4QDg3(&U*K!}(j3P0
z$NmU?cghc{8plpEu>(6pcTXy)Yd-ALl*Tuii+04<h8xsiTGN-OF=iSw5UMPTw;)w|
zrj9g5!*&G`o^7YUw#F~dP40x5o3*E?CEQ-lYGL+N0z#!>iaT+6x6Oab11-$3JF3EM
z_+7527+v#ChIL2bQ#sAMW<QnJICep8`gNC!r^b%qy$eKIr3j51^`wh{SyW_6Ts~|3
z3*g<|5POQn>#Q5(FQ2pa^$3qW8u;+dm!}$<51SmB>wLlbJ7%s;?n1`PS$<ag!%LrK
z@ZlPIig}5A^UR-hb|BQ`&Ero~2z}n+XFS*arxTjrQkcYx(R<vH^R%bwOHvpk+|y}|
zyCdW2jK=XfrU-vqH|2oSF0Xml=BL>nnWlO8x5Sb2bWzj!CdPDEhUisw1-NjBy<?kY
zxd$&#PiWrl*q^Rx+}$L2x~}mpHB)#W)^@%HoOv`N{EWq$8pqD1K|8lfo~FIX^NOss
z3m{cpCUFsF&Fxg4Zfm=dn#qA5b<_3?-3Y%S9@F@x6;p=Yem8y3aC(K^rR*c>d&blF
z6`V%mX^n?|G8)I8xpfh44Q3{DVy!<@&|19Z3V!s8Dd6;8f>2$sco|Y;$ukk{+?syI
z*StGlJ~N?l*fp7tThz})W}jyw^6vBMGt5iI#ZLcX@VgSgneVjb@%gB5F{?H{)WWA@
z&&+oBLW9o)$EY`;7d}UQrmcB*3_a6{;B6By4cGi<W12@>6T86g$pA;1&w3E5ttPh%
zY2xPspf>8({IfZziE6j7J2cO0d{55QVRzgX{K5p>xOWwvEon78BD@6N-O7KqqUk+z
z7}NU%gifwVJ2wZ<G7FKFTiMUnqqwQUZs>C2^xKH=In$(Hx5A%oYJLx!OuHG4b4}3B
zt*K{cHE%x~3_i<xM4tFmSh$oY)--VXrGLRYf6tK?xbycM*O<WJuW{+ZRq#3Q7&<_>
zA-6Mmj&m=}xh8OTboBiN;7I4WJcMey#mNgheqkAQ;Vp&dikjasX6p1i!fB%4vgX4w
zD;noziGJT-1WvmN%?~#wcZ0szrAzlBEzC*={HWU?KR2cMu#3|g-yJhm+J$YJ(Y%|j
z=UNdQ8)W7a+69`&9lAF8(7vsCTnD_%#Z~=z(6XKnBnS))K2O<WTAoj7eO%xC%NJI|
z^Jz`*>6ixTB4B#WYWf4SCO|gfp6L04<}o>mJow9F*1j0w(<TRg&j&oqmo@K>`R6Md
zztUAX0bEsS>hL#yr3ak()*!@e@ANHR*LWCbO5<0u9{QPvP;o5YgcSa5Tyy>vcn@hf
zuu3hhgd?bU1$ydRdJa<gHq|S*0$hz9ZGOeHX@U>0ygy@aMGmf)Kcl_CU5!6WY5d9t
z#;EaUX$YN%w+DG#*|dBXQuy16YZUnKUdqq%n!mDb?TV1fuf<D{!k@ba|E#R>QI}su
z<MxO(&+Um1E@zKe!-VlZfLjr3-XCARj`<R+L5MhLfA0Or`zp`!(~!OLYXTQ`VSY0j
zA8ldGIFv%)ol$-^t8shen;*R&Z*s6!+Rka6k?bVOxHg=!j;61w%$v<6AbX@fm(uz!
z^*PTZVtBGOm)1Pqj;$hIcv70nYJRk8n&d}_Bi*^Y=F!qN_&rzIR?L;a_sWaqiWXf}
z#hCtBkHB%-C|rp*^}hQ4__D#di3o}Bv@eh~O(K)VmB{33R!Gm&5WO;K0v8dln!}j-
zGaBa!3}44y=MtTb&^Uixg~o)1(2a15bjmQ_%KG5_=P`&L+59}A&90g=ExL85fS-Gs
zzdAR0HR&{9y3IsslL5ceEuWv~BK!=-v@1aLN@r~TC_<3c>pZJlf)tfuhuTDp@YChb
zS)$+zDQh<Y*((M+D)dLo#w&1%dDgD3dG3h8FT`tTzQ9^oQxl?BJk~7Y74UOXj2E_e
z_830s@@e4oI~U=x4Z245xD(-7H|%~9gXodZFYw6&XCZUXHGHX###Htobdq%h35)(k
zCc?Kcrd<xASCBk#;qR*I<h7_d3^%6f0zO57UkF#y{57nF;VKZl!uh~OIGi@BjOXU`
z7gf!34XJo_&0mwlnDH7Az2Z#+7x8e|cpsGY&1n9bf+>JssBbpHvo6M)gXk5nt@W?Q
zPFlu$f#xC~yrvo`KB4&nemQop$ma!5^VhI$<nuxXqDMY2WVJr#uMB_TntmaF3}5f^
zY2frbrg`+IrSd67_>Q$>pL*rvYyGRMCi5XNA1_oj&)0YrU)TJ#*kgka=j#RbL-hCB
z9LB7p3DGN`8Q?-6{cba!JLX@QJ%;ywo4o7KoaVWHz=!Ygy}*75|JP1njC@{<LG;My
z#e~*(7o8VV8o#D#8qC8Tr!O)e5eIxg{+a@C#>;9RSDnP~AkS-CmLG%cl}}OIx$n@u
zSkm}z*26eujpJs29dU+2J74qoq}d|xc0w;!HJ>R?j^WzM>gjz7LS<<(W3YC!@#3_$
z-jp*%ns==EOoYY>7Upqx5quHvH+~p<pBLwj3DZ_#=ub2o9}qp*h1>04vKf-kVT|;D
znb5eKykD|BsZTxXdm6_}qCVn;i}RP6WB7*RbDGDb2jKU7umPO@#~@TYEnb9_`J^pg
zisB}BooN3rE1KVlU$yJ<uAT|aBcD3>@x2~!=2M60mCqD#k<X4a#?)sW0v~a8O>5je
zB=}`h<F^0F!C%g3Vr0f-t`|q~FK0Esw}dehn1c`r?>J!bHl#>wuTAVF(n23^A2tzZ
z{zaUZ650r}-3Ga5gvlY;OP=Q4s(mS~@x4wz3tR^)+<;(wvFDtZ^4iEP#g_^iM<;w3
zh3B)EikklrhTY`K5Gt6(BTHg4i)1lAgy;}%{RD_J>h6`lRMUK}jWO-&8pk7m+>N+D
zh_^|~km1`sFR=;2KbIQ#Js)CI=qG^amG2yIVdp*;y~Owe-`1YI3E|v|dl{^xF?Sio
zvut6Gbc*2je`tz^1A{N8A$p|qaz@*^bY5l|!k@cby`0lHrmu-O;a%UC3z~Odv3z+<
z<FISPF1)P1T+;l9*be6HL-fjf0=UR;cgy%6!HKv5m}YfNf6zCLk06{|9WPT)m=^+!
zX*aF$5Be5wYJ79r1n_76eSbW5+{-P~eky*VIkAWb>F%I;c}`pWb`E1i=+@Pvpmt2_
zqo8_mp`f;>X%y5dvY;Gry3J_*nv}&O^XLj{=d}LjvB`a?2S3{pJFbmagjmn{`$RqM
z$OQd%(+2P%d)0I71U2`Gdg?F}6M%Z!NMNC!$OK)}gg)#14HMKRFZ^xB$H)C)L3V;Z
zv|kn!nV{dv!2=@vilRqBzdCk;g8d5x{mO%xNB{*TZe~Gc`h(ky=C2Jb{u?IfS2?Y}
zdBWu2FYbQH;8%8%?!H;n^sC4u{Z7*c@gaNFbj&189uOtfVWmsT9FQeN=IGi2^jYd}
zn4@1cwLg?pgujK7>@+=cK$aAlrm-BHAjm5eJxY4z*lF?(F4Xjj2Qyt$;UJ#yx@meP
zGELX8Lkt(4CNmDN8#X&Suid&?dS!l=#s^<1Y6W+ic%`KAu_nfhSAh`aoo{>liVs}m
z|KS|Q)UQGaefNUED>dN9pMn2u#J~8*UH@L0!azF0PjKHN?xemFnZyr|(HenfAbJIA
zX@6myK;s{Fh0JN(He`74m9{26%*qh>*D(kY`10w=Td^2F%zQ{^qO`?xkg`s?r+xuK
zxZ_R<{)RS{EnkEbcDM=Gz7^{zur$>KJ<>2<3BRc5u9Ls^HNVMRUBWL8d^iBi=v7T~
z7X<UsjBok6=H2IyUr%ZL!+~kg&TZj-9htSzuBq+t1Sf#qkb7GC>z3xReMsCEUvt`Z
zDd5bPv!%Laar5v4xJP;qemD`&iR&;4OMEo}72Tm0`AyAv(^oysZ%R+zj`im{^lC=a
zuEJNd8g~`Gn$x)3Z@!w>xSOC?3lV$*<Gz99;HzBdB5$;+io~uB1C=!Ij^tO%8o#cA
zF<SSk57DD_uTFGdjXUSnDtHm^x+cc7t7#ll(!L!FkoAzJd*Sx-Y2$q~zW(BthVyBw
z9zcpH*V8-Qv>~(`|D*A>S4_{-ucb8Y+`UG((%r1p&uV>s`{@q2o3b>Mmu52-FKFED
zdS4sUIC_w~18e98nj!nw$`CsHdY5M!<ZGJ0qBwacHU;1P5BwVOYs^XHf*;?`fQ(=7
za-BAHbRzm&^kHgDU6^0*O5p?u+^yT!W;O1Pyw?JaXHyt6^|^U`r#o?9&zT}YDFV3l
z_gY8eH;kDk>goRe-ktHy<M|?Z*#Ad1qG$d7M;^H7WvD-<^>0jIOh2XHpkImTXS(|4
zGl%dvGIUyxC>2cO5R$#3&jgVBZ=@3jX+emjt{_Z2fDlc%v1V}=BlU|G??4KD?5@jq
zVIgg4%=51&G>_d|9ejKwu)JsL4`NIFqr2j(@v6vV83$s~QaMQB`o?LKDZ{n90>3^M
z;c?3d=H`13@)sapXBVY4o`S);`xgbSAAFr{5UiW)*L{uOl)@NodA$nJqx{!vTK|T?
zv|W_(!PloW8%AMsMD&|j38OS2dPSK5F7(|Jf4!ygu;~GD^SO`3<D)mR5A;1p4FB5g
z$`<-0-qASD1i{BJ2@~^lhx4aWGKs_SwK3KW>yBBUK+AU@7SB048Bik9NMOo`c?m9B
zo1ErvnzeWVQip0G)H)ZcsLeJdCXc}DWzM>+X?L0GR3doIWN7E!n(DAnnQaGSR#w$`
zre=z;3%{4%sYm!C#<ZK#_(xI}pN3S`S-c4;;=B6<9nO!$OI`iz2RpMpiNVgC#&-o>
zgTYQ)<HMPG{0#~fz!Z+MK<cBAH<-BK-SoZTY5XHT#?+_Z9tFOU1up!!0^i6*@c9BS
z8GNJAlNfxXsBu@|8#I&w@Ey6kF~e@7{Kkal-95!Osv74t5OzZ!=>TUzQxLMCK2yG%
zKhDx;>X75^l=%krMf_r8-u}&)w!eJZ;;D#!%i?LR@6K~?W+M8{uD*HX9{jjUG3X8k
z-^@XZB;3{U&Ai4@Wb+<8vu<0nBBZR5W7Pg;2|~EzALzIjJ>BA4zM^@zsNS5=_zel;
z({3Nl=(nbMcP4wYuJIf4rUAQnSVm*=6F7N4e=mMG#C>P-&8D_-*YP)J=D!-TrUK<H
zEQEn)wQ`v7T=(0U<8QJdqTnz{N8@f$y%p2A+g!et(6~El-b!hFUm9cN^%mu#z6-+h
zvRfr@Wg`Z5#@;G)4MKfv1T+5|TJzAC;>(hQZxyxG{ytL#8{Ub2tE~Ajy^6;7vkay;
z0io81X~N&oDE*MHL5Q{?UR%YR(tH@Nq4E6%jOnilq2m=kj_Njl0C&FMYJpV2Fs9M0
z#`&4=<Je#pEj_2{{j7;*9S9X`9)FucgxNS|@tDTlQg}P1ad&<heB09mj=cm{@zDMz
za3t_{4nieha^&3^@@+OnB*Hu8;74;A;IuDAc!yUaIDQtLb}q5Et5F_f`m1XkPXIIb
z!Ol(E+YQa%jA7TV38Cw#!ft<9M+>~D!+lbGdsgEg;6yQxK;!NM;@jkfA3kP5obaLA
z+a1m0^+xY^vG|?+JCO-=b-k0&b~jI8j6B})Aaq?m{0;4AJ>)YGG9UbG6M1*idMBrO
zZmqzN-fZi9XAHdZk1_ogA%x%kEt9(+cCMfAlr`@@IlU8^cf7?~rk#7}_73Y3e%%)7
zovOxh{M2DLKEi%7pStG5zD;TTfQK>lry+XP)dVi$Zz*6*{TYqhbF(>r9G?lW=!@fM
z>H#*J%5ANTrdGl4Ip6~a|85MTNAPzOz(w%=RHuGQ<GA0{X1tqgmQQOQzXss>oJ88u
zKC5|`=es$LBhLcth7PoV({2nx<!O8$KLTIUW;>`x^|HqCc1;8B`0E0JkC*iECfg@5
zWo~NTt!wpz9>#RjfKX8_J`E|lvomG!rpDdUe>Xa1wXVMT<|px4)UC&NXSMN;v}qy9
z@JZjhbDGB+1D`@?4_3Oq2H&ITk?VUgZFY0V6k!*hZr)?=q84|$dC$|hd&U2~w8q_@
z<h_i>4`xggal%&?-pgtJK-ILtn}<FXU%tAaIn2KIX{^$N>>K9cy%I#P+9K2JR_S}}
ziKq#y)Q7(zcglQkLi0E^Ho)KRR_S{+&AV0lUR~pE{k%7&@mtsn<~<G3EAQsy1M!nS
zBr<d-tM^*kliPT`7ew#`#*EO`I67B<0G+$V@AApM804`TB>QMD;|EqhrSbi($<Ls1
zHoatDTGME3hP*vzCi}9Q#}CF8!MmrC$-cbiZ(+H(+u1h;(JRd&aFHe!Z<FzEsRE~6
zS@XBxhJuRcYyMUbW7^TaSG*c<5$_;=N%uh<WH-)OyD81zRI+$O<Cq4YcDJ%F#-n|&
zcr9&rYsmz#Tj*C1;h8u6wIO=>>qPYN*1+$fUoQVeG0oqEJrejZ-lCM|Z=J>%@fM{a
zdc<3l(fT-$TJSe|aMs%8G`};jcwXZ>#wI6lKHlP4dQ8*yC`c|UMev5zFKgU>C{He`
zX#A#{)%P_%oS4Uxi>eVKFij-3(7(FoG0$!Cx3=dUESiQ?eKOu>!P~t<a?y;ozcphD
z;N34pCKt_W-d@j=ivo>r@r)0<?yu$0ez*Z1^K=}ASii0j$Hg>$Q_Tcjdt3;AA2*Ex
z+QB@n)o#R}%l>`1x97R!aaqlme2i(AhtOr$X=l&J$>YYri?r+|FL_*1<6J(l8`{r2
z=(nu-TT7FFK$<LRA40mt+f3jW(v8gKZ3$~vht%m-X&3rsH>F>W8IQ9oaHQMp=2Nu%
zjOKAPx0T<>?Ao1g^0+|T@$&aM9F@0~tlti#%6A@TDl#AY%rJR;OyhXx$cI1oZM)?0
zsR*B;qk-h{Y`d&4Fahj_?5F$W@mbB|`%;O|WA)hf9AD7%rn1R>9%1df9?9d25x$Kv
z!?H{fmK$-{4Gqs&zM^@wwGMv2y(gPIzN&e*T92=3{I({>j5h_*tDUSv<iU&ELpUql
z%KT{8)O;9+c?!GR%NSFC7NS?20JzY12k-H78vh9E!p{Of@({ip!&>OG10iioruh)2
zz^1r3rRiO`9)iX*QSV`%E=r~V>9&-~#d)m`-dB7v!s8<w`0#YKn3alb>|QXrxT0|!
zC;{wt?#cm26^kbzgq=ITFRp2Pr;jo9>&E*&{<zZODb2g{_TuRXj(g};>@D%TU(2pf
zE}qe>o43U+jo)6!n9=4Sdd%D6HgK7BZSoJ%OnZ|rxrEk|&X^2&cl0btMR@!Y6M6e=
zC%Gi8dE6YTcKHS!4<wglHGg}<G{N&4(EdX#fsR!h(`tBO!23@K<1Rr<O2_a8@^;^!
zTvE|I((uW<bM}%6&0p3q4duV4dDsWaeoFIK<W1s_#F|<%t$BMJCb^^;!SQt?*tu5+
zl1n19$)9`xAGfzNl1uPOG!Z{>IJsml>Ih@@H!{6A4b}gs`&qFCKl_J+d9|epNHNWB
zH7!kP{G+TBZkJ{tdaS0US*?$gbny!~>AU5$G#}yVhyKPQcwq5j6gN%yGn>DUpSN3D
z)+E1K3)214L2{|DdAHwRI-zkcrbl4s*6h-n=Iu?s<Wd$dnuNc=?87en9I<p-^H{?T
z@Zn@FZFMKhJogAbAiEh{8fYU-P-0R#ZEGICH<O#}p8U#PHJYP=%Mw}*FILo{w%pNP
z_grKCc@hul+_Afi%@_6HX_^u3Tb9$bI}a|4%poqAnXX+L`b;G<m#)%fMeXmSO;d#3
zkUJkPi%cgft%B#NplKGibIYpQ4Nk*ttLD|v?MrjunFi823qQA-To#!YERzBh-M4p>
z%Vr`D1LM<?J2sZh&iC#IHGEmFXr0e#n>*Sjpild}CK;oeXzj)^llUTdcihJ!(}njV
za^yF%cSt_wX?tv*%3qxSqX6|Uq8CmruhnqZt_3%7`+bdMY|OO&8i&i$FX0uUqDg&e
z;qMkCW4^XUip4Ks#dH8OgX-jRJd=OqOYuST)4#^IG-GwGkCdA5$G=n1hFzFaq?>q|
z*ZVRa5C8Pb@ny%wX6N(y?JsxpDScVwvz&2t%Nj6@*;1FAEhyYP56k&{mU~(s`6M2-
ze>dULg?yGrT7>r^%a5`}HO3oAF1IcElSku;xI67FFB$JE@wFFMpwi<kx7-J=QpK3Q
zCNzHT^yF7?^4lG=G(!qA`>mPe^18;|#$kCw<2cZY@Hcu_0XV}oHSabK%Uc@fOu=rb
zoC8j~IS5sjX_I%K%eqTI=81dgkMX3Nz~iN4oYe>x$6o>L&~`Qp-s36F@5amH<hQUI
z@)^zJ644;<&c5-S=JB>j06sp_0Z#iu_bhsRGCs!NO2GjhFKUbJ6_fZX@_qNIc+Bkn
zDql+opg~(7LgdcF3Yz=NF1I>()ftRwHw7W=++iB0oxt6uH$JWL%VsC*C?RYS4pSVK
z=fqoDt=z<z;bt|CG&8Ut|5(xTZOC3}vPB{tx19TFCh)XvWq(Thu`i${`#r6HHphJf
z<H`QCCO*bQk#K(&qDMmgIp8Aj$Cx<v^BUjg@Pfv}0>+4s<3AhmFa9~){VyDq@joK)
z<<lg9S0F@STS2nFqw&L;dHod$Na4qIVns^mUy1)e%nT7=g$E%59Bx@W3n?7A3&M(=
z*2f>;%6)y|+r`Nh^eg=_QN}4k^zw%@RCnXIq6`IL=r%bkDjLTdI4uMmx@;CW9ZzU}
z`^@AY<4E{m#?m!SyO~%~*Z2{x2)b)P^vZKOqMtBD#JToJ*4oWzK8(}S_>qd$pM&fb
zr`_$xcydKY8{R|%B)F17^vMNU8PoWYDJnug1t9{tm9;V*(GM`Dehy;M3jD_|QM@AJ
ze*<Uhqky^!MF`>0t&Ei=;3Bbd!33~d=gu)JS-Id3n^oV8uZ_D;E-NQY>l^X4xvJJW
z(#Du+)imzz&aA9!e5<(&UWeSJWhJLm1pQdW)W3<<Q!W6f+otAmhH8NyJ<9HopM~gE
zYye#NJ<>LrKf#|j3#(z;l22evfB3A8Wivj&q2P~lmcS3hH15hDpuNy{aRz87@WVFF
zfTwZSt^wB7;}0Dq2Qu2=Xx%hXQ2g8?a3)qT)hT=_b%0~pkUr!6DH?jWZP>s>gfAMO
zygQr+BJ;@47UbOr+<^w{MM3znrJ&2_fHRLKgy4_h9x3uNFa2>mwrilJ$-6y_X~bC+
zMs8y=FsE^TQxwkJH)xXs9nHHB9IF6Jf9{jPs+h*zEUijtd>Fq3g*fq@c{&<MuEI|{
zVT*5;d<$<uxdVDtRvX>zlncP+4B$(A-$Dl-`#L^Kt}1FHY)Yyi!}hK!YyL3){x<k4
zb}>U{;%nY@YE@O^Zi}@lGM$^u`ai?r7ZyIH&2Y6S{29^-`DxAHoi#pq^VkFUyPU~Y
zGnx&Pnbo-a;I%4<;wE6UaC+LB$7jpLx8rN~<p87hZVSXJab}5_Hrt-J`ZN&w!(9jP
z<7ph<%PxN#=M*>FiHzpAHZW%V$b{ouREOQrJ<jhK)YQaJeus40nwKDDI(Ru0{2te}
zgs=G{&h3Q8-I1E8YWzsnRN-%fyH%B_Yu@d96I1gaGym>8{F?wpD6zK4MBkgT_za|~
z$#{Q`^P^i|iCOTXsCzTkF3@;bWIKXWkMTPicS~k9Y2n}E$0t|Ex>XFVW|xG5o8;AA
z_mI6lxti@43a;YS%v9j_Rxw5<tMd?|;(XEKV~|3>5;M8)VtU=>b#*1ed#3zdd^{{!
z^9fB~TrhQ*ho1yj<JUaDhd=VzfSQONdY{(jhZ83AJ<NkUP*=}r-feVOw>0h+&+1u?
zyT!3O(0Ikem|dCE_=w-d%_HB#8PTn{)t!hE$1onG5Us<3(?s$^m9phMNL94)8fcv}
z&uDXeJS{YEzh(>GOMna?-whVDo_lgKIHqyDYSy5gt9g)9B+_#qt_GQ&#A_yi-JTl)
z;4I6B5WIc;GdUQUYPa?WYg#{7HMzgweW!#eLk@-Z(^?Og;5zxRo|fkKW=xB`J7xw0
z&F}Ol|1-|nyp_3Yu&p_F#T;a>Wi4D!sIhy4N#Hmo7vU_tXO&FNUl||y&*I9MOlxPA
zz&gu9>UnO%S$OeF=C$4RI8*)a;BO$#WX3d)M@$9qqnl<eU(&pNUpbkKOeE}l<=5AC
z;2Y#Ov002;)jan+;N81^$z)yg6*iN0QyO;*Avvva{Qh0;@%WnM?%+(C@2!ci8BQi!
zS}&}V^~y;}m^$pkJzSD`3mz{xx5)3U07qUYPzWCHLgD$)o{tkIoq|x)WN{Btm|f5E
zsGrt&5o-kg!cD{pS<Q3LL*7m633<(<{Y~a$Up-BpFs6Ce#uG{ryn!+EDQg_%dq0r*
z_?pN0pa4ERADmFtygS}csA(L>um6MY9r6au`9}-zxa@>!trQm7)Oa`-Ga7f-uM=h?
zIQBwMpa^$|>4Z7W<D8lUKl<?iIGS)`45G&*o|phGCh_BKQ>L9O@<cDfQ=k6Q8t3MR
z`Fw);lg~qlc=%%PG~C|DG)R{;?XGJlM&|15DN}^q(0!h@^C3mLSR2*pg{$g`ktrF8
znI^-!Bjv;?Z63O9XdG_au<OoYGI?TCvsfVBU-BUqqp_Hl=G}9f69bLA6Z(mB8g~o$
z#7+dq_ka;6d?>eu%@f7n=b3=K`>?nsrFqOr;{RaNGr*DO8cH!IuIX#C+U~xbDbvn<
z##@uu{Kpd*(_ca3IFReG8`_k!d{Ofwcp-)S?v~}tn#Y%g{|jzSxwfwHHGM%5V}_m3
z_?CvnYx9q}4*nNhd)&ow&6HMl7x^_b61^P8LPGG-5zYaFG&R3v#^NoF;{w=*o%^Mm
z<eEV9_c?!U;JtcJUgYr!+9Up23V|a|;jcK?0SWL4&10_pzrukqZRs?m3TGNH=Q|4l
z-MA@So7Zmei8}FL(FV6GUOT4w-(?vLUxLv7%di`Fr?<5gZRhr-YkiHoM-*!(G#>h?
zYTPaLwKa|3$b9++b|u%=H4zp%rE&X`adK@#;~Debe~qu*e}4ur>zsiQb-KH8YiG6D
z{mhg4b6VdWVr$zG{kp0CH_XFc`hi`FLQFTNv-#if*y-WF!4t3)S&;;ve8HHL>EU+%
z=>2tC!$}rGIC0HN<unfG1=tPU9{{J_7=-rkgC7t5vboYPdq%sm#@%@=<!jt+DpM00
zcjw7eP2<-!G4309e==2v6oK8UOigKg+{2g&H6c_X7RPfB+}a#WwJ=uxOudOh$9=2!
z8)h#RnLT%qraIc+QBDBzSVtk^4EqFt#~^y-mt2<sAq>WGFW_%*{dsp5_lVYcn#A-K
z{{~+%Y5=Cw97GSN>+-;bPj?G-T|wjSe($<5jfY7Wf%ot~*!?Ig0w8Jc{|u9^Xm4C|
zAouuyyIEHudU)-=nkAiPtbQF*;KTS10{n$1s&(v!;Kys$Zd&6<8zz9=(EUxz&uAWb
zCjKw@^~Wq9K=#U$OGU=Zm@@2!+?pPux!^yJJ$aY+Nem>15}MCeOp9?{-b0?|-9>RI
zt?|1Glm9o`>Mp56SxviZ<4|NVxXa^ELF?mbO_BcG{rI7x=G|p*sH}0fxP~ekM?0JF
zH|kFTXW3PV9_<{eX}kOJj@sX%o$k6ZM0?Rrd<HI%_oso=Z!^OC#wYKd!VI-EkG0wW
z@BRj6awyPzIE`(MV;U2Ghs!L}Mc9)lL|S;GC---7dtZ(O_=M)&ES{9oIPA)>3tuZc
zDKg9W0(hNa3Da#hVxBfFhIQx1lk%GX<e0UiRNXh3|Bf%@mMl#vs@dVp${NT1xA@<Y
z?be31^EHnr^HuQSUh1T3gby%g88wY_vC!^Qp5^IZrEBqNNRcNO%M9{yi{+#l&2zDk
z|D>xki11h};KT1FoYdC5J0?%+XdEx}G-eh)e4L!nG}cN$n%SV*lRZuIO!GhRD=HOB
zXCZqOdvZ>jxs`cxLF0&4{vRmPeL3OeqUI5<4u1U8fV=7V5WV6}02j@5chyg>YTVsX
zJh`TEx5Q7bYurxGuH?y6nsD7cxuJ3Q>Eq;Sjc3e9{vMAkKAi*1wzeQd9r($d=HH_a
zpJra<+nVR*iTwTbdHxg%Q7=CFdH+xN(eIRmX0g-?U`O4@^;0~}yDiWu8I5zPz;3_0
z*q)Np{HNIzWP3_p<8BLgN<ri2q^$m!#_>K^;vaDS4&#(G|7q$oP8mXU&Fxc9sc3zy
znlk(ieR|s3Rik#M4&L1V7&a=W)U`31)uM6OtVWcd{72C4usx-zX&kosf5dMcggFPA
zciYNS<}@DmvaRtjPDkU}6vpVusT5)**dCg{{YShu=^B1&LMvr_(?${D=f6`u%|9@P
zF`Z{2dNlmh9Pnd<CQpql1bjaA|6erA9d@VEudu^+!y4q>z4uci6OT9a0`TD_;?#<^
zf1rag^PGTCd79im!S2&DmajpIxNettYCVGEbOgI0cXXc`nR~qTS10eTA*VLAJuc8K
z#&wspQ(Kz<OaWu&8$jrMGcB2K8+@;PS+B%1rU<(*-}N!gBi|}{m+$(N=8<m`eE8k3
z^=Zw2W(s5EyFLq{^0jylQsgt9G2Z`&c%MmFp7jd;0etxYeAu7$Ma@4*GsY`JsCcG9
zzvCIp`;fvf_SFIXy8DjntD1N7xxS`xzG(VCWq(+&@QeQBz`H-+nOr}u`LNEW#@+m{
zpV9b(>?7-&h0yiYnTK1i>*ur`9u~F0FZ8XW`3LJ5!>^Zs(0()jOZ3h2z>E6Ow<7or
z?tZMt{tDjp&BIgK2l#&L|H98<x~qj((8}(vh&QHjcW`?}jX#($Z3O3&BkzYu@_`a~
z7U63>oXrd1M;~liz6Pm^w0Ip-CXbgs=-0i&<ux>q?Q8Hu>~ws<4BLbd<~VmHe#G7}
z9C?P9Jf3%eA9eRfy+HG!U1TmlGi}QB>&`)5WG->ftS;l87Sn$5puhDayiZUBjI>Tm
zY5MmZo(A5dOQ&VDzB{B&%W53m$^0|Yd@v83aVSOkNTUcoeDr(Tn5q49d?R0QZqm+O
z%TM#Q9bV38gLglglsv7fdDphn*me=m9a5*&H9o<5m|p{;SH06(-yUM-Gyj6?W0>TO
zR>G2N{0q*D6BXce9zgVRJ_lSR88)-6aU5rfS<ZO^IQ(s(kajrFke{&4-atLU<Gfi0
z?|!Txxxv%?#1zK#n}O(&=Z47Sx;!`JpfBRMHMxO#NSuE0HMAv9qG@i1HjHVdiM+`?
ziKe;Zctc6^ZU#4$H9pb7n92JPDtS|dzwo5Lp$c9kg#)Px{&shM*-+Pf7>~^ncAsT&
zj5iIT;#s^2DfGi;;rGR7aR;lV=?4?mY*yo8_(0>I^)Y7nHiQW8ZqlAkT7>^B(}e!%
zDG2Dt!&fGYCiqwM=d&|bAq^=E@tGj;Z`kF|zvgs$R<rIbemc7$tlTG|(+e7hw=%qi
zTeZ`Rn&;N2%Qt{C-LmGf)oUqxU-Kg~lRu{W1YnxiG!6F|@|)V0pVB<8)J5`PGuSmz
z7Iu<V@ZlBobT&=!pPjXSDaEYtgBSg}EA#1d5xW`V{RBG%w@p92qj`6RIfL#+Ja?p>
z5!3jV8WjhUXRr@KANBc&6Yk{B@HGF~8Pg!|K6;&z(LBy*0r=71uLGz5JcO##;sr<%
z_tW_L_rHt2o>A01mj(H-p0eh*G)x_Qc!%%|U-MyqCZf1$skrQm$P3Hmr?MSWnnt@a
z;KLK<8Pl5o1GblKn1SfkhL+ZM=YTV2H6E57Xx!d$G=KY3al$;Kt(88DOCgJJC(JWJ
z%Nj9fUVszoA5=*UB+pDi^howh54h-!OZLpP#&H$$;g8?+SiU-|IW(*RZs@bjk+Jfc
z#}z05A09tvj%of60*q-_f>1e{+*9xy=2QVMaz#$%r?8ueS@Q`^yKBvvY=JOyhxwT`
zjl09}%(}*L`e-qY(5|6*ET^Zj6{I&7(bOy^BJ(tg|6IoMvyiGtiwBS*OMD!v!Y=Ms
z$(e0aKMvdIzkM3pXjj@s+6p6=;zqVa;I6cd35}z)HiCquZS*vcGoSYiXTTP>kwpl<
zD6T;Mb9LY-eq#Yb6=xdc-7U3^MexEN?>7Zqo_W!}9N}k7;#u^zVQF8}y!rer++W|e
zeDxT<41P~BuzX$fVOyp&?ry|wWL%Lh-lM5AUTD|UJo0Ig5A9o;$7@E<f&P2~Fsp4t
z=x!CsyKbFDH4z@$<|=vjsQ4`U5j<wAsq8(?<F%wVd3T;aE2DY%_nrsuZV#Q6(>#8b
zvH;%wC~NYpLWG~e7<HXBrtvUdQR88qC5?yi%NoC)(**y?vnrZE-+d%@t=l%8HKF;>
zH|7n`s%!kAqQ#pLoc>wJoN4_$zUI1gBEmQ4`E&+SP9R~}rE?HsVjh~aI2$AM^J!E6
z8J2g-(!Qp#e`tX=<B#Eyc)AKw_{^pz=P*|fGX;jMYnrE>x%uyC7NO_<o_I3d(t57f
z=~<0GjMES7!n-?ZmLS4E>|>0$XH$rh+-=pfW5A_8?(U$K;SGSZJ<YpA=Ir!uz*(p8
zcU#L8;LrWRp5)m%&AYXAc3$J?ix0b@hnv8ee;GpMZvy&tTiLUH@FK2z7;$!0<M@Vp
z?iaivkul|8-~kiO=)R%V9%7q`Piy?9Ia7yu_(10D8O`4~W$juT#|Qov!mZ0$I*8D<
z$rsr4lBGMEcDEnSAuWr{%<G?%h~Riu3V-3(+RyPc|8UGy!G{<6bLdC-t)?+X_2=Xv
zbkp0kyUFHx&X~4ylW|T_<M`gX_u_oh3y`A^+wPv@Ydv=jJ!eAW50#DIwNID^WIT*B
zWy+7??TK?5S|5`fyoheQ_RMISpVWVeG#;t~XPHb#l<ywRo)c)CKa&Kz?rYGH;ahgY
zP?Pp<8oQr!gkLv}!>NeA&2u=d@#|ufFNu#G!&yzcG>3B<chA{|^BQ+I0EY_^9A7|0
zoY5-v(T;BVB5k*(hs)XyhiH{{e;BiNY^Pc+7O!c$9oWp!&V2)8cuMo`Q|s`w#w&SK
zczJ#m`H-VKeele8R_ld$pm979Y0%C+of&Rx-ff<`_Zmd~c=IfPU3fHYV!eV#J&88_
z-f8==DW!Q=Pxn+O?6925u-osJOZVkO!C%*eAJn%gAMxi~JUWjhi;ro2Z2Mcx&(*hy
zdLoW{;cU|}^E>$~l>MI=hG|qG)byGn`5g>Lz78SW-is>}`LO(H&Eu5V1RqZ0rWwt<
zY24J(IG=0LubakAf#xwC-YeMsgwxU1yvt_<u*}yTHX|{OyXhH;Oskuo5l`#eE2R1U
zEBILGdOMPdD5Xt+B)7Vq&`3`6e^kI2O&wu#Wz)??zmBgBcL^hrsdPKek+OD&9cTI1
zSZbdLfYYrHA?C`RP)8;rIMb$nP2=tn^+;XgxKq$V99&%|U**zadNglpH9QT-fFJ)O
z$InK2jA=Kg@vxh1jfY+AXuP|RgrChZ;IfNFjDaUNCm=;1&cf|RBo<y6H+!1@LJMO$
z%t9!K#(NEKOfWv_JcMxTmfYqsjbF#Ss9)4LrptegZ7i7v<d9oxn|-Z^LnuI4_n2UF
zRnuQ^>C}O%Y%yloDF~6Kdu3^JL*u+&{s(S~vRO21YTBJwHqU6>&B|srO@w)*gfaav
zJ&7|N;9F7<J<>HxU&jwu+?TUjX-HwsXBn^abmLn-tNBNorr70cmd|T`BrsL-?n%;?
zG0o#o?>1k@o}y#TS%e6W_n_J^U+3O1-%`>1uvy>X*I5H=KB4K$@Xd}6qHmhDd`<Is
zamfcCZaKD0X+8`anYu9EbVT39X-4pz37E%72RP><GIuC5@dkFP-D?^7K-;@H-!iB1
zN9c$8^sDC9l;Lm4otQE)ZFg_o)X8u0fx|wN(mb~DE%5P2+Lp)1m+#~D*U~o^{`5++
zd!-O_^$3>Ao8mK5rl6fpHm$QFq)OJ}B}m~9Pj0L5H?*l~`HJT6Z<;3f(HqK^pU`~w
z!pq{S8t3myzKO5x;AQH!P}6rG#G5RchStF^yB0tW?aNx<P0gc0KKO9Uo|%pCKE{k4
zK!}>YfCsCv+jCvo@@>t#D@LZH@jvwD^|w+8f5;<%zwz##81c4JPw;NxY-K!w8ykOX
z4!E2P44L=V0))`7IlP4bIaYr-xwR58Z~>}O1JimNjjJ&L15HQxqQ#q#G68(g@EuHu
z+ZJtYX&&dP;yXBxB&>O$Y5X=&73TcPXp?T-fi_BY5eBEDHu&%xt)uiOdFy{P6~S}H
zdzXIObU2V4jr1FS3-2zR=0>yH9Gfej<~OpvG|y|k(lHJ4?us{B)I7dG7|?wUFwM)F
zMspJH;fpqBvDxJP2yZ8AbVB3qq&-^YpORfOI9k^{?wFO~ccGgN&DV0K4nBO8Fxrgp
z6^xnBEQDNDMT-ZJqWkW2Hae&ATGi^a`$FHY{zuO5Up@3i+naL}&{44-srIjR$N9OQ
z_TVmi=dwf6ie8ZUxf!kRF52g2H9qV=((Yd~^syOhme(|%?0bv)*X$3?$25PmVeN_<
zcZc`6C5?ZvW%VnNGHu-cL7ecqaPCCJZq78ohZA-#n<g6ir5wgAoB1fe7N3R``tC40
zx2bXWQro%ghtNOL#u)yS=du7n@LAb$Nc;#BW&(lc(ZD)*_ZKvi=hBg|4;$6d_?OD2
zMZZ@Rfy3{43C$1tlgFbUU$SA(^EB<|>%6qaUAXfy8vhc@VwgNckN%xk(E4`4Uy?j;
zOcU;lC+8J4?$+yhCEy|ee$KOvLc%8}=T)>_SctE2xA4wm15`gvVKEl$mt(+LP#r?V
z3;Q_*T-doI_`HV3!+IhM2z%tl;{NbG`15A889svtNMk%qe^&Eh`hmv7`I*!BmrEF<
zobxGqlyiOz__5`fZ!YOyy~ovXeo8C3IXU0cPTgAz=clzkZ!9dqn%v4BF_~<XpIi#s
z)pmYf)4cUf{>x3^G-pk!7E=WuerP?v0$$V<mf>qWEMr3Z%hxbwoT}DG8EwQd|Nht5
zU!7mqB)*m7EyMBZCgS|adU%vQq0=UWPTq%Icmg}W1zsg@8uS|`8$|3e?E0O95O!Qh
z^c&iBG=DvAM#aFpg|;oGdDN2wAJ(%irTItMG}N<=b?JKQv~$PBwyd^uld&zQaU2(|
z7><iJV7e`6db~Ed9EZguyF<Ddr7d34xLZ=&${KgGw5_7?M_qVUr>er3KjXKpstw$d
z-d59i7@)54uM{w50n-r221sse0vFTh?!|7KA-)3t={_Rv>%&3e#nI=lumU;^AbL5R
z11=nXA}~JeZV%_7qj|SpwgZ;_F1MZ89@F}6{cKNYe7Hde1Ig{F?iUx$^YQ*f_^EY!
zS}S9*CHiqPcU{|_)%;hctg`}Sk0Q5^X?-lFGW>;KW!qlTJPwXJ<AuqyiK0ni9=^sO
zW05SX2BGqpT!C<Ib#7<6!X3h8z=y}u_G!&O#`Nj71)<!UD*d`+X?p-(_}wvPn&jOL
z^6hQS<8exxyxU}FW14>io3xcUp>=-}y8GZzIOmU(f*g9p)|^diW87u;!Mnd{n9OE1
z9|p}waO~`9=N4L)#f!LZPO`-)ZW045#s`jOWy{C#Iq>0?GfO?;*WDA$PH5cCb+)SU
z$2ex3I)s`Oi%&rc|Gzua#m$cfus44!ZIvQ3jTZ)1VcmVTWa$=UFW<Akg>Sd8vVq32
z&WrH3(37_2vGA&l=X$yWwDjw0-x1UJS8G%pNbX2MsQgTO6;9HQW|bmMJoNMuNXM<m
z9a+uevwea5&Hy;w7a}~)P2lI(<Bnp4#3x1?SMtDVT#oP=6Og|&XZZ=u<NHgA)o{+g
z0Wh50!4gF3?jgaBdIZOhkics6s{wFEorX{yv3L_w_?v8*I_%cD8{j)Q(}Eu{|FpV)
zE$@F1Vt(A3-VvEU_b`7)M_ar3+zD8E<%tIV!bcuE6Pm||iX!;^?gfsWp61<p*cqAF
zx(_{6zcUBXqxzkk6Hy)Fv{~0k132x*G#|z(YW!;$cJ<2;Dvl{6QP)=XhyHvB5pR3l
z_~64IN!eM|d>F5$@vmh~gMQuSekb!4ez&$w0DgRX9XR7QAq4Mkj_jP#co?sx@voIJ
zrk^<oRiDM%kix&+zL>jD=wJAi#tWz`l)g4KZ+t-tQaLrP6Hwd{Iz`Y6(h$OKq%nCS
z=?P0`HO;jIKD=mMkk|azX06>Aqz+r9Uw6^Eprq~a_aB<{>(<5v70uhnV#y19jqgvJ
zHvPI=J{MFq&zGInfZq?eTW%dfmOEn#;1}v?X#VRS#%xm)Lf6xv->{w*c;T0S&w_r#
zdIHUd^~`B}f6*k?%6dAQM?E?6uAU2Hn&+cB@L@d{rZoTc35-$Cg=q*~Pm6wCJr`!R
z-TuDGlsI%R%xl_}b74W_`)e38+?dAkq%1>!?#9W5CC!KBl{M~8Q5RM;j(u+t{)WEZ
z2F`elE6Ur7mkm<=n~&RihH0kyw=9}7ZHg}#ZynIgUQ<}tzkWQcjWXO=!`W};AjI7M
zamV6gkRr&I$1Prj6#CytS=@(|`rS9a;h%E?{c*R8{{|Cb;5vjb80MJx6od>=wD>fn
z(C<D)qJ9&&)b}wa&PBVRKi=1U@<?J9gfysGgE?i;x7l@wZI}9udHwfMEClEq`74XZ
zAf^5c@$rG=`%;k7z$XFRgOCOR#>6uaQlDeuSqQ1$v3MR*=x=(};sr?a(UbaDxI63b
zD@HV@O!XwJk%<VL!<Yf95F+3=9bN}60&e~x#?+sJkoqNyHz9@oCc@O8fq;IvM!xA=
zVh&OmY_?PNzV^I<TT|bxV+=<ZB_M?U@Bxdn^D-d@q&_>jpg-O>+)W8Y4umvdKpGSw
z77Y5%dDh~rQ0V^&15$qiLh66P;*pO2Nsc(y$VClEX)s0t_%wtJz<|VOA*BAv77rk$
zJ_ABOM<MjjreESQh;eD)h;+nYuQkX(O8vm%1xOJf?OA*bQt1CF12S+0!s?F`I?J{+
z=VKrZ7?1{a2od0{0~Vixl==)v{U(Ia@4f{}d<MAG_p$!E26GXE?_f-WHiR^&&*K-f
z5*gqIizgtZJ_Ewf#VkbVcVB@fo@IP#z(h!}5@E2>9%dI8feZa92Bf|ZA@w;XJ^>;1
zvlgF%r2e?Q(X!DV1s69W21ShNs0AScoY}VcETjy;fYk3mNd3p>@m&-`e|(AoVX(`C
zkOn1-ry+&G6a!K}4<Yq!0lNxX|65e2ei=gOcfXm!dtJLKAVh#~F(3_U5rcoQcpXye
zGa&Vw5Hi4&#b+R;KI2h;4q_4K-%i094_KlNDGloL_$4t&86a=*1f<kwKm@oX4I%Yc
zSUdyi^cnwKbC#e(VQ_lO;sr=&fdBoon8izwQs18GE-6R!(^h{XqCbZ9*UhvVG00nk
zM#R9L=`NX$=ra*k+|v3R0*lW=$^saV`fbJ+6>Rv1B{~rUCIW*?6A)702EH^E(Ptvm
z&qnl5uy_u#n-KetfBvk^|H7aMAp)HCsKpsbRPb#Eq`nU!_3er1(h1;FKZh~(ry!*M
zc+3*4P#P31J_9KXyr#ujq10zU24Epl{|<{sI{IxU0{!vJScx<^W1hIogOmXn5C)g!
zAcX#U>*%sPaH-FL)GtN!?O}XbxvP)<+r#fW9sn9lK*#`eOuPyq0({5e4XuCbkFEZ6
zM4yS!4+{zXBmSv%OUy#b01QZjHbiL9*LTWyEY1q0J`;id?gWI;KlOmcQ;<@>h4DBI
zGTPu|DiY5^NQ1V;3y?BE+Tvqc|IZT^FKhji?8R(%h4DpzKhIc$sx~;KZSfkU)Gt`P
zq4iI;N5Ssth<@4X&xZQ*$6u;ti2zats9L-ODJnjR0nwq$DWpCF5>G)0{Zl3^?m<fZ
z*=~Fo<Uk06p-mXm5f_;>U?Rj>iO}!<{1Ner*8i@DG4UFN&_BuH<8=@sz;_E6(_jWd
z7<7Lnig+uc&w#|+T7PX|aV9MNPtD``6eRqI`~S7RB|J!Jz<>yl&q0WU)>SPY>Ckr>
zkoqO9pL*5eWyl5p<9*-rEJ24Nz>q!lcAt|j81#LQ0U2Og>!)%SZ$e6a2BdxfA^fjp
z2e|*w&p}Fq8i|4A6%@i?O+Wy63_|KRE$%@|{kp}|kWxRecn)%08k8)NhZF`4!VFx5
zkop;m(@yGp7WW~A{)u*Ku9yIB^}Fl8kpsX0bqHxtvG^3E3{bRq6H@A5Xz>|Hsqb4n
zfE4=pEpEm~;5i6sP{$bf9tvq-cQ|`uz@>hZiqQ8Uq`pmPPa3$?4=|>Fj`5`daT0k5
zVel6YFXDfMesY=w^h*#@-?O+6DfR7Q+%o~3`fmUK7dZ^*s16|v24^ik1t|j*E#8Eb
z`bRB311a@=iwBTGe{|5E>GsTlkOp;(k<j}ogu!6U<Tl~qOp`e1l%`idZpxc*3vBg$
zrVeQiZR%fc{$*4DS;wtjJUP<8#r)Hz{+QW5(w|=RIa3^gW@4|YcIC;Y357-9F>MZ4
zJ!`zp7+z=!n>jpc{H|PV8ifDB1QcH|i7j9UZZNqm7`|xA-QgLg&f$Hg#o@}wCo>qW
zFqsTTmzpAnkD4lnD}HF29Bwl0?(l%|wqp2Krmz)vXX?7TetQzTGBO*Fm!OAkT-l81
zf576A*?8QycmOGy+y8*Y?POf*Hb;-w=ZUK*ghBkr7LP%S*?YWcaSu}H_n%;LqnN$G
z(pgQ%E;Qv)G$nS_)JHK{Ki%5D%>46cfBLw1aq?U|qWFH^8rHO7oXY?WxT+2z^4M6i
z_%x)*V|iflCZy2+e#PPeq|oo4i}`8ss<t-R$V3qM>V!7P7cI`jj>Erpm)XZL^*sm~
zc*f#6NEx_jaTb2O*>qli|JFGR6$s&9>)PF#zj{pLxR+cwkG<<yyE3E*vE1&sudZmj
zA7rh5HKOlZyap-a|A6_hv<8ImANx)hA5UIAjsKAbOoRrr5W-;Dixv+cr9Km(eg{J8
zPtD`q_)?$opkGK)e+B+yJGE@DDWBiJ_6o)&pCP|MFaM#%vyjqX$Ksp|p^sm(Y|&l9
z(j`s1$8Lo(aN+I=&+1n+j&~+A+c015O9zDs%@5N*)2?Ye^jFvTUizp0l*ZlTyFx?b
zPp}<a>xCAisM8(<Yo4TnD5QTrz?vts5!}bPZ(z-nIS8rGf{5oMI13_PAZ}jV*&pA~
z->}#iG5l+%uz%X(__fsScs}$bn<DwZ^5qELws>VS+rQ?VCw)z?NLZRF3U@2;CiVrG
zlNFxjnX2S77OzL}oW-Yp1K!YhKg(bXSe`g-tn|A0@oS#M_jZu@(33M-VMVd4u;xj;
zFyG~8HNP@ud3?>V%g<?kh3gBRX@ehpvJ>H(ri=z`7+}Ik@LyA!U+Hkq6m}rLe@#dD
zlC{GZFuHs;!ZRNI=1il@=QTf&uzbM;UA~O5n1I!+hxQed*va@lhN6Lqg5~kEV_m);
z;XTVwnR1tBJ;Huf#q!gp4u1S!8BfNy`Ttu?<AWR{uYXJb20S0ZZJqyCir}=TpNTGx
zZKFL9VpJqC)g?lFkPRk26T$NqpNrsQ^Z1Wr5uA;NpC6|sen(&5;DjY|lIZI@(HYR8
z=+KEypS;9t7&8EQiBDU+ZVDHo<3HwD@*T^!G`=Qf@wo_|oyUJdA^fb#Tby<hAG3I-
ziw}pLT~o3I4W&WF;&_?nx3C0%!m;FQmam#J`0<}iMfhpUHzW9r#b+Zp$7tM7+7Wzi
z9{=}P1n*ef>*5PbXf1I#`uA*?2n+50=@R0F2<~A_ycEINDdJ3MG5(!jqTl}H)I9#v
zgv1y3efyIglYU?SyT=VqoAgEfmt*T)zNmj&`~;8seT%C2zUM{#_b!?+>0JMV$L&7Z
zG;;mhmv_tVTXgk=Y3KSk$A5ZhS9|GCFE#0l``_or-~LqIlrM(2pO(9P-)ViOadH3o
z{mc3+Fu2>aFYe#IsQ5&BSO4U_I~En@6&Ed=m*IbN2kzWAa@(OJNB14N`QXSccOSa>
z=xui$+I-6qt6{$SME|Mg-Bl~sn^UIyhx(6f@Mv+%;e!XwHGjV(X(p%px2&}2o%_o0
zHIHxn%l<Rh3;eFTk8beJxOv|lcZ`(x9X@#IX#9fs?|ttt`=9vUU#|G4uf@H}d_WJo
z<R*5~k6yoWePL@RlkqOO`l=7^z4)rV-ccl2KC*oI4c?^(Z`pVE9Y?*rmt5wR_uYEX
zJ968{4|=y9@y>gHd|u1jI-(8l+;`-oaZ_G0u=a`ndHqU%*+#2(`o24EyY<k)192pF
z*Uck$9=tPt;O=ra7ER2b-n{bjt0KDQ-UBONdg9v$S6;Sg={#j#y=7(2{eSk>m7f{!
zy7kiYncZ{S;iKNjh-YJsbkjXM4C3uObif<7^?5EM?}GTwZm*9X#;m~Az5@picfCMv
zy#JP4Zt;YRLw6nRy0JzkR$BRqRq?y-Ie571qZ`@m+rMnB*?h;!{&n6BVb5$*-l4nh
zjUT<+{OZ>J6Y&?47Oya$-?env>D|=l^NsJnbEJe+??Aur-B<Q7>^9AOa@W%2*<Hm0
z2k#l_rg=63gab^B4Z_}<*GenT9E_iP;P74Lc*eVI?25hdz4^<oGEe=if8FGv#VgIj
zyOu7wHMH(JK07`tr=?r!U5CB*9rnaOH?T$X3*xR@ZaH%BsCV=(?`Y|uclhAZyAL1o
z?%8+8-3Q}bzVj_T*Sq>!^B0+AYtP!t7VkTHu<Msj4j<fipgXwt@NIz02M^yFKYW*2
z^!SSP;~wThXV>k|Va!%oemoPu=+dj_lV-qsZ##70u6sxBxb3d}hrE%)m@NJi^)pY0
zUb>ZQx21bV%(rh}xnWQDSiqv`&V*f`cBCAi<<ZMoo_6C5K5+Hb1#{|0SFVeVcBkX;
z`^>hFuDsVgy=KWNn2Kdvx*2w7)UE-&qT=1~3mr9EKeg<Ho964Hm2EU_M-Enw9z1m5
z-~rFh<-%&}_5(wnRBYoo*_rOjJ*IQ!Pj6qjah<K-9qz-dB+eRG&S_7qJhbwe0iLG&
To@n2<^2H|>-~11UZu<WL&UqA6

delta 220346
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

diff --git a/roms/SLOF b/roms/SLOF
index 8ebf2f55e1..9546892a80 160000
--- a/roms/SLOF
+++ b/roms/SLOF
@@ -1 +1 @@
-Subproject commit 8ebf2f55e1ba1492b942ba4b682160e644fc0f98
+Subproject commit 9546892a80d5a4c73deea6719de46372f007f4a6
-- 
2.23.0



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

* Re: [PULL 51/88] ppc: well form kvmppc_hint_smt_possible error hint helper
  2019-12-17  4:42 ` [PULL 51/88] ppc: well form kvmppc_hint_smt_possible error hint helper David Gibson
@ 2019-12-17  6:32   ` Markus Armbruster
  2019-12-18  3:12     ` David Gibson
  0 siblings, 1 reply; 94+ messages in thread
From: Markus Armbruster @ 2019-12-17  6:32 UTC (permalink / raw)
  To: David Gibson
  Cc: lvivier, peter.maydell, Vladimir Sementsov-Ogievskiy, aik,
	qemu-devel, groug, qemu-ppc, clg, Marc-André Lureau

David Gibson <david@gibson.dropbear.id.au> writes:

> From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
>
> Make kvmppc_hint_smt_possible hint append helper well formed:
> rename errp to errp_in, as it is IN-parameter here (which is unusual
> for errp), rename function to be kvmppc_error_append_*_hint.
>
> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> Message-Id: <20191127191434.20945-1-vsementsov@virtuozzo.com>
> Reviewed-by: Greg Kurz <groug@kaod.org>
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

Review led to the commit message to be replaced for this and related
patches.  It's in my "[PULL 00/34] Error reporting patches for
2019-12-16".  No big deal, but if you respin, either steal that message
or drop this patch.



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

* Re: [PULL 00/88] ppc-for-5.0 queue 20191217
  2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
                   ` (87 preceding siblings ...)
  2019-12-17  4:43 ` [PULL 88/88] pseries: Update SLOF firmware image David Gibson
@ 2019-12-17 14:32 ` Peter Maydell
  88 siblings, 0 replies; 94+ messages in thread
From: Peter Maydell @ 2019-12-17 14:32 UTC (permalink / raw)
  To: David Gibson
  Cc: Laurent Vivier, Alexey Kardashevskiy, QEMU Developers, Greg Kurz,
	qemu-ppc, Cédric Le Goater

On Tue, 17 Dec 2019 at 04:43, David Gibson <david@gibson.dropbear.id.au> wrote:
>
> The following changes since commit cb88904a54903ef6ba21a68a61d9cd51e2166304:
>
>   Merge remote-tracking branch 'remotes/amarkovic/tags/mips-queue-dec-16-2019' into staging (2019-12-16 14:07:56 +0000)
>
> are available in the Git repository at:
>
>   git://github.com/dgibson/qemu.git tags/ppc-for-5.0-20191217
>
> for you to fetch changes up to a363e9ed8731f45674260932a340a0d81c4b0a6f:
>
>   pseries: Update SLOF firmware image (2019-12-17 11:40:23 +1100)
>
> ----------------------------------------------------------------
> ppc patch queue 2019-12-17
>
> This is the first pull request for the qemu-5.0 branch.  It has a lot
> of accumulated changes, including:
>
>     * SLOF update to support boot using the IOMMU (will become
>       necessary for secure guests)
>
>     * Clean ups to pnv handling of chip models
>
>     * A number of extensions to the powernv machine model
>
>     * TCG extensions to allow powernv emulated systems to run KVM guests
>
>     * Outline support for POWER10 chips in powernv
>
>     * Cleanups to the ibm,client-architecture-support feature negotiation path
>
>     * XIVE reworks to better handle the powernv machine
>
>     * Improvements to not waste interrupt queues and other semi-scarce
>       resources when using XIVE under KVM
>
> ----------------------------------------------------------------


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/5.0
for any user-visible changes.

-- PMM


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

* Re: [PULL 51/88] ppc: well form kvmppc_hint_smt_possible error hint helper
  2019-12-17  6:32   ` Markus Armbruster
@ 2019-12-18  3:12     ` David Gibson
  0 siblings, 0 replies; 94+ messages in thread
From: David Gibson @ 2019-12-18  3:12 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: lvivier, peter.maydell, Vladimir Sementsov-Ogievskiy, aik,
	qemu-devel, groug, qemu-ppc, clg, Marc-André Lureau

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

On Tue, Dec 17, 2019 at 07:32:15AM +0100, Markus Armbruster wrote:
> David Gibson <david@gibson.dropbear.id.au> writes:
> 
> > From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
> >
> > Make kvmppc_hint_smt_possible hint append helper well formed:
> > rename errp to errp_in, as it is IN-parameter here (which is unusual
> > for errp), rename function to be kvmppc_error_append_*_hint.
> >
> > Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
> > Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > Message-Id: <20191127191434.20945-1-vsementsov@virtuozzo.com>
> > Reviewed-by: Greg Kurz <groug@kaod.org>
> > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> 
> Review led to the commit message to be replaced for this and related
> patches.  It's in my "[PULL 00/34] Error reporting patches for
> 2019-12-16".  No big deal, but if you respin, either steal that message
> or drop this patch.

Uh, sorry.  I realized moments before sending this that this patch had
been updated.  I didn't want to re-do all my pre-pull testing, though
and it's not actually harmful, so I left it.

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

* Re: [PULL 01/88] ppc/pnv: Add a PNOR model
  2019-12-17  4:41 ` [PULL 01/88] ppc/pnv: Add a PNOR model David Gibson
@ 2020-01-07 14:43   ` Peter Maydell
  2020-01-07 16:26     ` Cédric Le Goater
  0 siblings, 1 reply; 94+ messages in thread
From: Peter Maydell @ 2020-01-07 14:43 UTC (permalink / raw)
  To: David Gibson
  Cc: Laurent Vivier, Alexey Kardashevskiy, QEMU Developers, Greg Kurz,
	Cédric Le Goater, qemu-ppc, Cédric Le Goater

On Tue, 17 Dec 2019 at 04:43, David Gibson <david@gibson.dropbear.id.au> wrote:
>
> From: Cédric Le Goater <clg@fr.ibm.com>
>
> On a POWERPC PowerNV system, the host firmware is stored in a PNOR
> flash chip which contents is mapped on the LPC bus. This model adds a
> simple dummy device to map the contents of a block device in the host
> address space.
>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> Message-Id: <20191021131215.3693-2-clg@kaod.org>
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  hw/ppc/Makefile.objs      |   4 +-
>  hw/ppc/pnv.c              |  14 ++++
>  hw/ppc/pnv_pnor.c         | 135 ++++++++++++++++++++++++++++++++++++++
>  include/hw/ppc/pnv.h      |   3 +
>  include/hw/ppc/pnv_pnor.h |  25 +++++++
>  5 files changed, 180 insertions(+), 1 deletion(-)
>  create mode 100644 hw/ppc/pnv_pnor.c
>  create mode 100644 include/hw/ppc/pnv_pnor.h

Hi; Coverity finds some issues in this patch:

> +static void pnv_pnor_update(PnvPnor *s, int offset, int size)
> +{
> +    int offset_end;
> +
> +    if (s->blk) {
> +        return;
> +    }
> +
> +    offset_end = offset + size;
> +    offset = QEMU_ALIGN_DOWN(offset, BDRV_SECTOR_SIZE);
> +    offset_end = QEMU_ALIGN_UP(offset_end, BDRV_SECTOR_SIZE);
> +
> +    blk_pwrite(s->blk, offset, s->storage + offset,
> +               offset_end - offset, 0);

Here we call blk_pwrite() but don't check whether it
succeeded or failed. (CID 1412228)

> +static void pnv_pnor_realize(DeviceState *dev, Error **errp)
> +{
> +    PnvPnor *s = PNV_PNOR(dev);
> +    int ret;
> +
> +    if (s->blk) {
> +        uint64_t perm = BLK_PERM_CONSISTENT_READ |
> +                        (blk_is_read_only(s->blk) ? 0 : BLK_PERM_WRITE);
> +        ret = blk_set_perm(s->blk, perm, BLK_PERM_ALL, errp);
> +        if (ret < 0) {
> +            return;
> +        }
> +
> +        s->size = blk_getlength(s->blk);
> +        if (s->size <= 0) {

blk_getlength() returns an int64_t, but s->size is a uint32_t.
This means that this attempt to check for <= 0 doesn't
actually catch the negative values which are errors...

> +            error_setg(errp, "failed to get flash size");
> +            return;
> +        }
> +
> +        s->storage = blk_blockalign(s->blk, s->size);

...so we'll pass a very large positive number to
blk_blockalign() (since it takse a size_t argument), which
Coverity correctly identifies as doing the wrong thing.
(CID 1412226)

Side note: the blk functions here seem a bit inconsistent:
blk_getlength() returns int64_t
blk_blockalign() takes size_t
blk_pread() takes int

> +
> +        if (blk_pread(s->blk, 0, s->storage, s->size) != s->size) {
> +            error_setg(errp, "failed to read the initial flash content");
> +            return;
> +        }
> +    } else {
> +        s->storage = blk_blockalign(NULL, s->size);
> +        memset(s->storage, 0xFF, s->size);
> +    }
> +
> +    memory_region_init_io(&s->mmio, OBJECT(s), &pnv_pnor_ops, s,
> +                          TYPE_PNV_PNOR, s->size);
> +}

thanks
-- PMM


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

* Re: [PULL 01/88] ppc/pnv: Add a PNOR model
  2020-01-07 14:43   ` Peter Maydell
@ 2020-01-07 16:26     ` Cédric Le Goater
  0 siblings, 0 replies; 94+ messages in thread
From: Cédric Le Goater @ 2020-01-07 16:26 UTC (permalink / raw)
  To: Peter Maydell, David Gibson
  Cc: Laurent Vivier, Alexey Kardashevskiy, QEMU Developers, Greg Kurz,
	Cédric Le Goater, qemu-ppc

On 1/7/20 3:43 PM, Peter Maydell wrote:
> On Tue, 17 Dec 2019 at 04:43, David Gibson <david@gibson.dropbear.id.au> wrote:
>>
>> From: Cédric Le Goater <clg@fr.ibm.com>
>>
>> On a POWERPC PowerNV system, the host firmware is stored in a PNOR
>> flash chip which contents is mapped on the LPC bus. This model adds a
>> simple dummy device to map the contents of a block device in the host
>> address space.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> Message-Id: <20191021131215.3693-2-clg@kaod.org>
>> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
>> ---
>>  hw/ppc/Makefile.objs      |   4 +-
>>  hw/ppc/pnv.c              |  14 ++++
>>  hw/ppc/pnv_pnor.c         | 135 ++++++++++++++++++++++++++++++++++++++
>>  include/hw/ppc/pnv.h      |   3 +
>>  include/hw/ppc/pnv_pnor.h |  25 +++++++
>>  5 files changed, 180 insertions(+), 1 deletion(-)
>>  create mode 100644 hw/ppc/pnv_pnor.c
>>  create mode 100644 include/hw/ppc/pnv_pnor.h
> 
> Hi; Coverity finds some issues in this patch:
> 
>> +static void pnv_pnor_update(PnvPnor *s, int offset, int size)
>> +{
>> +    int offset_end;
>> +
>> +    if (s->blk) {
>> +        return;
>> +    }
>> +
>> +    offset_end = offset + size;
>> +    offset = QEMU_ALIGN_DOWN(offset, BDRV_SECTOR_SIZE);
>> +    offset_end = QEMU_ALIGN_UP(offset_end, BDRV_SECTOR_SIZE);
>> +
>> +    blk_pwrite(s->blk, offset, s->storage + offset,
>> +               offset_end - offset, 0);
> 
> Here we call blk_pwrite() but don't check whether it
> succeeded or failed. (CID 1412228)

Yes. I will send fixes for both issues.

Thanks,

C. 

>> +static void pnv_pnor_realize(DeviceState *dev, Error **errp)
>> +{
>> +    PnvPnor *s = PNV_PNOR(dev);
>> +    int ret;
>> +
>> +    if (s->blk) {
>> +        uint64_t perm = BLK_PERM_CONSISTENT_READ |
>> +                        (blk_is_read_only(s->blk) ? 0 : BLK_PERM_WRITE);
>> +        ret = blk_set_perm(s->blk, perm, BLK_PERM_ALL, errp);
>> +        if (ret < 0) {
>> +            return;
>> +        }
>> +
>> +        s->size = blk_getlength(s->blk);
>> +        if (s->size <= 0) {
> 
> blk_getlength() returns an int64_t, but s->size is a uint32_t.
> This means that this attempt to check for <= 0 doesn't
> actually catch the negative values which are errors...
> 
>> +            error_setg(errp, "failed to get flash size");
>> +            return;
>> +        }
>> +
>> +        s->storage = blk_blockalign(s->blk, s->size);
> 
> ...so we'll pass a very large positive number to
> blk_blockalign() (since it takse a size_t argument), which
> Coverity correctly identifies as doing the wrong thing.
> (CID 1412226)
> 
> Side note: the blk functions here seem a bit inconsistent:
> blk_getlength() returns int64_t
> blk_blockalign() takes size_t
> blk_pread() takes int
> 
>> +
>> +        if (blk_pread(s->blk, 0, s->storage, s->size) != s->size) {
>> +            error_setg(errp, "failed to read the initial flash content");
>> +            return;
>> +        }
>> +    } else {
>> +        s->storage = blk_blockalign(NULL, s->size);
>> +        memset(s->storage, 0xFF, s->size);
>> +    }
>> +
>> +    memory_region_init_io(&s->mmio, OBJECT(s), &pnv_pnor_ops, s,
>> +                          TYPE_PNV_PNOR, s->size);
>> +}
> 
> thanks
> -- PMM
> 



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

end of thread, other threads:[~2020-01-07 16:27 UTC | newest]

Thread overview: 94+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-17  4:41 [PULL 00/88] ppc-for-5.0 queue 20191217 David Gibson
2019-12-17  4:41 ` [PULL 01/88] ppc/pnv: Add a PNOR model David Gibson
2020-01-07 14:43   ` Peter Maydell
2020-01-07 16:26     ` Cédric Le Goater
2019-12-17  4:41 ` [PULL 02/88] ppc/pnv: Add a "/qemu" device tree node David Gibson
2019-12-17  4:41 ` [PULL 03/88] ppc/pnv: Drop "chip" link from POWER9 PSI object David Gibson
2019-12-17  4:41 ` [PULL 04/88] xive: Link "cpu" property to XiveTCTX::cs pointer David Gibson
2019-12-17  4:41 ` [PULL 05/88] xive: Link "xive" property to XiveSource::xive pointer David Gibson
2019-12-17  4:42 ` [PULL 06/88] xive: Link "xive" property to XiveEndSource::xrtr pointer David Gibson
2019-12-17  4:42 ` [PULL 07/88] ppc/pnv: Link "psi" property to PnvLpc::psi pointer David Gibson
2019-12-17  4:42 ` [PULL 08/88] ppc/pnv: Link "psi" property to PnvOCC::psi pointer David Gibson
2019-12-17  4:42 ` [PULL 09/88] ppc/pnv: Link "chip" property to PnvHomer::chip pointer David Gibson
2019-12-17  4:42 ` [PULL 10/88] ppc/pnv: Link "chip" property to PnvCore::chip pointer David Gibson
2019-12-17  4:42 ` [PULL 11/88] ppc/pnv: Link "chip" property to PnvXive::chip pointer David Gibson
2019-12-17  4:42 ` [PULL 12/88] xics: Link ICS_PROP_XICS property to ICSState::xics pointer David Gibson
2019-12-17  4:42 ` [PULL 13/88] xics: Link ICP_PROP_XICS property to ICPState::xics pointer David Gibson
2019-12-17  4:42 ` [PULL 14/88] xics: Link ICP_PROP_CPU property to ICPState::cs pointer David Gibson
2019-12-17  4:42 ` [PULL 15/88] spapr: Abort if XICS interrupt controller cannot be initialized David Gibson
2019-12-17  4:42 ` [PULL 16/88] ppc/pnv: Add a LPC "ranges" property David Gibson
2019-12-17  4:42 ` [PULL 17/88] ppc/xive: Record the IPB in the associated NVT David Gibson
2019-12-17  4:42 ` [PULL 18/88] ppc/xive: Introduce helpers for the NVT id David Gibson
2019-12-17  4:42 ` [PULL 19/88] ppc/pnv: Remove pnv_xive_vst_size() routine David Gibson
2019-12-17  4:42 ` [PULL 20/88] xive/kvm: Trigger interrupts from userspace David Gibson
2019-12-17  4:42 ` [PULL 21/88] ppc/pnv: Quiesce some XIVE errors David Gibson
2019-12-17  4:42 ` [PULL 22/88] ppc/xive: Introduce OS CAM line helpers David Gibson
2019-12-17  4:42 ` [PULL 23/88] ppc/xive: Check V bit in TM_PULL_POOL_CTX David Gibson
2019-12-17  4:42 ` [PULL 24/88] ipmi: Add support to customize OEM functions David Gibson
2019-12-17  4:42 ` [PULL 25/88] ppc/pnv: Add HIOMAP commands David Gibson
2019-12-17  4:42 ` [PULL 26/88] ppc/pnv: Create BMC devices at machine init David Gibson
2019-12-17  4:42 ` [PULL 27/88] ppc/xive: Introduce a XivePresenter interface David Gibson
2019-12-17  4:42 ` [PULL 28/88] ppc/xive: Implement the " David Gibson
2019-12-17  4:42 ` [PULL 29/88] ppc/pnv: Instantiate cores separately David Gibson
2019-12-17  4:42 ` [PULL 30/88] ppc/pnv: Loop on the threads of the chip to find a matching NVT David Gibson
2019-12-17  4:42 ` [PULL 31/88] ppc: Introduce a ppc_cpu_pir() helper David Gibson
2019-12-17  4:42 ` [PULL 32/88] ppc/pnv: Introduce a pnv_xive_is_cpu_enabled() helper David Gibson
2019-12-17  4:42 ` [PULL 33/88] ppc/pnv: Fix TIMA indirect access David Gibson
2019-12-17  4:42 ` [PULL 34/88] ppc/xive: Introduce a XiveFabric interface David Gibson
2019-12-17  4:42 ` [PULL 35/88] ppc/pnv: Implement the " David Gibson
2019-12-17  4:42 ` [PULL 36/88] ppc/spapr: " David Gibson
2019-12-17  4:42 ` [PULL 37/88] ppc/xive: Use the XiveFabric and XivePresenter interfaces David Gibson
2019-12-17  4:42 ` [PULL 38/88] ppc/xive: Extend the TIMA operation with a XivePresenter parameter David Gibson
2019-12-17  4:42 ` [PULL 39/88] linux-headers: Update David Gibson
2019-12-17  4:42 ` [PULL 40/88] spapr: Pass the maximum number of vCPUs to the KVM interrupt controller David Gibson
2019-12-17  4:42 ` [PULL 41/88] spapr/xics: Configure number of servers in KVM David Gibson
2019-12-17  4:42 ` [PULL 42/88] spapr/xive: " David Gibson
2019-12-17  4:42 ` [PULL 43/88] ppc/pnv: Clarify how the TIMA is accessed on a multichip system David Gibson
2019-12-17  4:42 ` [PULL 44/88] ppc/xive: Move the TIMA operations to the controller model David Gibson
2019-12-17  4:42 ` [PULL 45/88] ppc/xive: Remove the get_tctx() XiveRouter handler David Gibson
2019-12-17  4:42 ` [PULL 46/88] ppc/xive: Introduce a xive_tctx_ipb_update() helper David Gibson
2019-12-17  4:42 ` [PULL 47/88] ppc/xive: Synthesize interrupt from the saved IPB in the NVT David Gibson
2019-12-17  4:42 ` [PULL 48/88] ppc/pnv: Introduce a pnv_xive_block_id() helper David Gibson
2019-12-17  4:42 ` [PULL 49/88] ppc/pnv: Extend XiveRouter with a get_block_id() handler David Gibson
2019-12-17  4:42 ` [PULL 50/88] ppc/pnv: Dump the XIVE NVT table David Gibson
2019-12-17  4:42 ` [PULL 51/88] ppc: well form kvmppc_hint_smt_possible error hint helper David Gibson
2019-12-17  6:32   ` Markus Armbruster
2019-12-18  3:12     ` David Gibson
2019-12-17  4:42 ` [PULL 52/88] spapr: Don't trigger a CAS reboot for XICS/XIVE mode changeover David Gibson
2019-12-17  4:42 ` [PULL 53/88] spapr: Improve handling of fdt buffer size David Gibson
2019-12-17  4:42 ` [PULL 54/88] spapr: Fold h_cas_compose_response() into h_client_architecture_support() David Gibson
2019-12-17  4:42 ` [PULL 55/88] spapr: Simplify ovec diff David Gibson
2019-12-17  4:42 ` [PULL 56/88] ppc: Deassert the external interrupt pin in KVM on reset David Gibson
2019-12-17  4:42 ` [PULL 57/88] xics: Don't deassert outputs David Gibson
2019-12-17  4:42 ` [PULL 58/88] ppc: Don't use CPUPPCState::irq_input_state with modern Book3s CPU models David Gibson
2019-12-17  4:42 ` [PULL 59/88] ppc: Ignore the CPU_INTERRUPT_EXITTB interrupt with KVM David Gibson
2019-12-17  4:42 ` [PULL 60/88] ppc: Make PPCVirtualHypervisor an incomplete type David Gibson
2019-12-17  4:42 ` [PULL 61/88] target/ppc: Add POWER10 DD1.0 model information David Gibson
2019-12-17  4:42 ` [PULL 62/88] ppc/pnv: Introduce a POWER10 PnvChip and a powernv10 machine David Gibson
2019-12-17  4:42 ` [PULL 63/88] ppc/psi: cleanup definitions David Gibson
2019-12-17  4:42 ` [PULL 64/88] ppc/pnv: add a PSI bridge model for POWER10 David Gibson
2019-12-17  4:42 ` [PULL 65/88] ppc/pnv: add a LPC Controller " David Gibson
2019-12-17  4:43 ` [PULL 66/88] target/ppc: Implement the VTB for HV access David Gibson
2019-12-17  4:43 ` [PULL 67/88] target/ppc: Work [S]PURR implementation and add HV support David Gibson
2019-12-17  4:43 ` [PULL 68/88] target/ppc: Add SPR ASDR David Gibson
2019-12-17  4:43 ` [PULL 69/88] target/ppc: Add SPR TBU40 David Gibson
2019-12-17  4:43 ` [PULL 70/88] ppc/pnv: Loop on the whole hierarchy to populate the DT with the XSCOM nodes David Gibson
2019-12-17  4:43 ` [PULL 71/88] ppc/pnv: populate the DT with realized XSCOM devices David Gibson
2019-12-17  4:43 ` [PULL 72/88] ppc/pnv: Make PnvXScomInterface an incomplete type David Gibson
2019-12-17  4:43 ` [PULL 73/88] ppc/pnv: Introduce PBA registers David Gibson
2019-12-17  4:43 ` [PULL 74/88] ppc/pnv: Fix OCC common area region mapping David Gibson
2019-12-17  4:43 ` [PULL 75/88] ppc: Drop useless extern annotation for functions David Gibson
2019-12-17  4:43 ` [PULL 76/88] ppc/pnv: Introduce PnvPsiClass::compat David Gibson
2019-12-17  4:43 ` [PULL 77/88] ppc/pnv: Drop PnvPsiClass::chip_type David Gibson
2019-12-17  4:43 ` [PULL 78/88] ppc/pnv: Introduce PnvMachineClass and PnvMachineClass::compat David Gibson
2019-12-17  4:43 ` [PULL 79/88] ppc/pnv: Introduce PnvMachineClass::dt_power_mgt() David Gibson
2019-12-17  4:43 ` [PULL 80/88] ppc/pnv: Drop pnv_is_power9() and pnv_is_power10() helpers David Gibson
2019-12-17  4:43 ` [PULL 81/88] ppc/pnv: Introduce PnvChipClass::intc_print_info() method David Gibson
2019-12-17  4:43 ` [PULL 82/88] ppc/pnv: Introduce PnvChipClass::xscom_core_base() method David Gibson
2019-12-17  4:43 ` [PULL 83/88] ppc/pnv: Pass XSCOM base address and address size to pnv_dt_xscom() David Gibson
2019-12-17  4:43 ` [PULL 84/88] ppc/pnv: Pass content of the "compatible" property " David Gibson
2019-12-17  4:43 ` [PULL 85/88] ppc/pnv: Drop pnv_chip_is_power9() and pnv_chip_is_power10() helpers David Gibson
2019-12-17  4:43 ` [PULL 86/88] ppc/pnv: Introduce PnvChipClass::xscom_pcba() method David Gibson
2019-12-17  4:43 ` [PULL 87/88] ppc/pnv: Drop PnvChipClass::type David Gibson
2019-12-17  4:43 ` [PULL 88/88] pseries: Update SLOF firmware image David Gibson
2019-12-17 14:32 ` [PULL 00/88] ppc-for-5.0 queue 20191217 Peter Maydell

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.