All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424
@ 2017-04-24  1:58 David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 01/47] target/ppc: Improve accuracy of guest HTM availability on P8s David Gibson
                   ` (48 more replies)
  0 siblings, 49 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:58 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

The following changes since commit 32c7e0ab755745e961f1772e95cac381cc68769d:

  Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20170421' into staging (2017-04-21 15:59:27 +0100)

are available in the git repository at:

  git://github.com/dgibson/qemu.git tags/ppc-for-2.10-20170424

for you to fetch changes up to 4cab48942a1c5353f0a314fab1aa85a5f0a61461:

  target/ppc: Style fixes (2017-04-24 08:56:19 +1000)

----------------------------------------------------------------
ppc patch queue 2017-04-24

Here's my first pull request for qemu-2.10, consisting of assorted
patches which have accumulated while qemu-2.9 stabilized.  Highlights
are:
    * Rework / cleanup of the XICS interrupt controller
    * Substantial improvement to the 'powernv' machine type
        - Includes an MMIO XICS version
    * POWER9 support improvements
        - POWER9 guests with KVM
	- Partial support for POWER9 guests with TCG
    * IOMMU and VFIO improvements
    * Assorted minor changes

There are several IPMI patches here that aren't usually in my area of
maintenance, but there isn't a regular maintainer and these patches
are for the benefit of the powernv machine type.

----------------------------------------------------------------
Alexey Kardashevskiy (4):
      target-ppc: kvm: make use of KVM_CREATE_SPAPR_TCE_64
      target-ppc/kvm: Enable in-kernel TCE acceleration for multi-tce
      spapr_pci: Warn when RAM page size is not enabled in IOMMU page mask
      spapr_pci: Removed unused include

Anton Blanchard (1):
      target/ppc: Fix size of struct PPCElfPrstatus

Benjamin Herrenschmidt (2):
      ppc/pnv: Add OCC model stub with interrupt support
      ppc/pnv: Add support for POWER8+ LPC Controller

Bernhard Kaindl (1):
      e500,book3s: mfspr 259: Register mapped/aliased SPRG3 user read

Bharata B Rao (1):
      spapr-cpu-core: Release ICPState object during CPU unrealization

Cédric Le Goater (25):
      ppc/spapr: QOM'ify sPAPRRTCState
      ppc/xics: introduce an 'intc' backlink under PowerPCCPU
      spapr: move the IRQ server number mapping under the machine
      spapr: allocate the ICPState object from under sPAPRCPUCore
      ppc/xics: add a realize() handler to ICPStateClass
      ppc/pnv: add a PnvICPState object
      ppc/pnv: extend the machine with a XICSFabric interface
      ppc/pnv: extend the machine with a InterruptStatsProvider interface
      ppc/pnv: create the ICP object under PnvCore
      ppc/pnv: add a helper to calculate MMIO addresses registers
      ppc/pnv: add memory regions for the ICP registers
      ppc/pnv: Add cut down PSI bridge model and hookup external interrupt
      ppc: add IPMI support
      ipmi: use a file to load SDRs
      ipmi: provide support for FRUs
      ipmi: introduce an ipmi_bmc_sdr_find() API
      ipmi: introduce an ipmi_bmc_gen_event() API
      spapr: remove the 'nr_servers' field from the machine
      ppc/pnv: enable only one LPC bus
      ppc/pnv: scan ISA bus to populate device tree
      ppc/pnv: populate device tree for RTC devices
      ppc/pnv: populate device tree for serial devices
      ppc/pnv: populate device tree for IPMI BT devices
      ppc/pnv: add initial IPMI sensors for the BMC simulator
      ppc/pnv: generate an OEM SEL event on shutdown

David Gibson (2):
      pseries: Add pseries-2.10 machine type
      target/ppc: Style fixes

Sam Bobroff (6):
      target/ppc: Improve accuracy of guest HTM availability on P8s
      spapr: Add ibm,processor-radix-AP-encodings to the device tree
      target-ppc: support KVM_CAP_PPC_MMU_RADIX, KVM_CAP_PPC_MMU_HASH_V3
      spapr: move spapr_populate_pa_features()
      spapr: Enable ISA 3.0 MMU mode selection via CAS
      spapr: Workaround for broken radix guests

Suraj Jitindar Singh (4):
      target/ppc: Add new H-CALL shells for in memory table translation
      target/ppc: Implement H_REGISTER_PROCESS_TABLE H_CALL
      target/ppc: Add ibm,processor-radix-AP-encodings for TCG
      target/ppc: Flush TLB on write to PIDR

Thomas Huth (1):
      hw/ppc/pnv: Classify the "PowerNV Chip" devices as CPU devices

 default-configs/ppc64-softmmu.mak |   4 +
 hw/intc/Makefile.objs             |   1 +
 hw/intc/xics.c                    |  22 +-
 hw/intc/xics_pnv.c                | 192 +++++++++++++
 hw/intc/xics_spapr.c              |  25 +-
 hw/ipmi/ipmi_bmc_sim.c            | 191 ++++++++++++-
 hw/ppc/Makefile.objs              |   2 +-
 hw/ppc/pnv.c                      | 411 ++++++++++++++++++++++++---
 hw/ppc/pnv_bmc.c                  | 122 ++++++++
 hw/ppc/pnv_core.c                 |  27 +-
 hw/ppc/pnv_lpc.c                  | 106 ++++++-
 hw/ppc/pnv_occ.c                  | 136 +++++++++
 hw/ppc/pnv_psi.c                  | 571 ++++++++++++++++++++++++++++++++++++++
 hw/ppc/spapr.c                    | 371 +++++++++++++++----------
 hw/ppc/spapr_cpu_core.c           |  17 +-
 hw/ppc/spapr_events.c             |   2 +-
 hw/ppc/spapr_hcall.c              | 174 +++++++++++-
 hw/ppc/spapr_iommu.c              |   8 +-
 hw/ppc/spapr_pci.c                |   8 +-
 hw/ppc/spapr_rtc.c                |  41 +--
 include/hw/ipmi/ipmi.h            |   4 +
 include/hw/ppc/pnv.h              |  57 +++-
 include/hw/ppc/pnv_lpc.h          |   8 +
 include/hw/ppc/pnv_occ.h          |  38 +++
 include/hw/ppc/pnv_psi.h          |  67 +++++
 include/hw/ppc/pnv_xscom.h        |   6 +
 include/hw/ppc/spapr.h            |  30 +-
 include/hw/ppc/spapr_ovec.h       |   8 +
 include/hw/ppc/xics.h             |  19 +-
 include/sysemu/kvm.h              |   1 +
 qemu-options.hx                   |  15 +-
 target/ppc/arch_dump.c            |   2 +-
 target/ppc/cpu-qom.h              |   1 +
 target/ppc/cpu.h                  |   5 +
 target/ppc/helper.h               |   1 +
 target/ppc/kvm.c                  | 144 +++++++++-
 target/ppc/kvm_ppc.h              |  40 ++-
 target/ppc/misc_helper.c          |   8 +
 target/ppc/translate_init.c       | 410 ++++++++++++++-------------
 39 files changed, 2803 insertions(+), 492 deletions(-)
 create mode 100644 hw/intc/xics_pnv.c
 create mode 100644 hw/ppc/pnv_bmc.c
 create mode 100644 hw/ppc/pnv_occ.c
 create mode 100644 hw/ppc/pnv_psi.c
 create mode 100644 include/hw/ppc/pnv_occ.h
 create mode 100644 include/hw/ppc/pnv_psi.h

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

* [Qemu-devel] [PULL 01/47] target/ppc: Improve accuracy of guest HTM availability on P8s
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
@ 2017-04-24  1:58 ` David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 02/47] pseries: Add pseries-2.10 machine type David Gibson
                   ` (47 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:58 UTC (permalink / raw)
  To: peter.maydell
  Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, Sam Bobroff, David Gibson

From: Sam Bobroff <sam.bobroff@au1.ibm.com>

On Power8 hosts it is currently theoretically possible for QEMU/KVM-HV guests
to receive a ibm,pa-features property indicating that HTM support is available
when it is not.  The situation would occur if the platform firmware of
a Power8 host cleared the HTM bit of the ibm,pa-features property.
QEMU would query KVM for the availability of HTM, which will return no
support, but workaround code in kvm_arch_init_vcpu() would then
re-enable it because KVM_HV is in use and the processor is P8.

This patch adjusts the workaround in kvm_arch_init_vcpu() so that it does not
enable HTM (in the above case) unless the host kernel indicates to the QEMU
process, via the auxiliary vector, that userspace can use HTM (via the HWCAP2
bit KVM_FEATURE2_HTM).

The reason to use the value from the auxiliary vector is that it is
set based only on what the host kernel found in the ibm,pa-features
HTM bit at boot time.

Signed-off-by: Sam Bobroff <sam.bobroff@au1.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/kvm.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 64017ac..c3d4262 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -49,6 +49,7 @@
 #if defined(TARGET_PPC64)
 #include "hw/ppc/spapr_cpu_core.h"
 #endif
+#include "elf.h"
 
 //#define DEBUG_KVM
 
@@ -509,8 +510,11 @@ int kvm_arch_init_vcpu(CPUState *cs)
     case POWERPC_MMU_2_07:
         if (!cap_htm && !kvmppc_is_pr(cs->kvm_state)) {
             /* KVM-HV has transactional memory on POWER8 also without the
-             * KVM_CAP_PPC_HTM extension, so enable it here instead. */
-            cap_htm = true;
+             * KVM_CAP_PPC_HTM extension, so enable it here instead as
+             * long as it's availble to userspace on the host. */
+            if (qemu_getauxval(AT_HWCAP2) & PPC_FEATURE2_HAS_HTM) {
+                cap_htm = true;
+            }
         }
         break;
     default:
-- 
2.9.3

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

* [Qemu-devel] [PULL 02/47] pseries: Add pseries-2.10 machine type
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 01/47] target/ppc: Improve accuracy of guest HTM availability on P8s David Gibson
@ 2017-04-24  1:58 ` David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 03/47] ppc/spapr: QOM'ify sPAPRRTCState David Gibson
                   ` (46 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:58 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 35db949..de5db75 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3158,18 +3158,37 @@ static const TypeInfo spapr_machine_info = {
     type_init(spapr_machine_register_##suffix)
 
 /*
+ * pseries-2.10
+ */
+static void spapr_machine_2_10_instance_options(MachineState *machine)
+{
+}
+
+static void spapr_machine_2_10_class_options(MachineClass *mc)
+{
+    /* Defaults for the latest behaviour inherited from the base class */
+}
+
+DEFINE_SPAPR_MACHINE(2_10, "2.10", true);
+
+/*
  * pseries-2.9
  */
+#define SPAPR_COMPAT_2_9                                               \
+    HW_COMPAT_2_9
+
 static void spapr_machine_2_9_instance_options(MachineState *machine)
 {
+    spapr_machine_2_10_instance_options(machine);
 }
 
 static void spapr_machine_2_9_class_options(MachineClass *mc)
 {
-    /* Defaults for the latest behaviour inherited from the base class */
+    spapr_machine_2_10_class_options(mc);
+    SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_9);
 }
 
-DEFINE_SPAPR_MACHINE(2_9, "2.9", true);
+DEFINE_SPAPR_MACHINE(2_9, "2.9", false);
 
 /*
  * pseries-2.8
-- 
2.9.3

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

* [Qemu-devel] [PULL 03/47] ppc/spapr: QOM'ify sPAPRRTCState
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 01/47] target/ppc: Improve accuracy of guest HTM availability on P8s David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 02/47] pseries: Add pseries-2.10 machine type David Gibson
@ 2017-04-24  1:58 ` David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 04/47] hw/ppc/pnv: Classify the "PowerNV Chip" devices as CPU devices David Gibson
                   ` (45 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:58 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

Also use an 'sPAPRRTCState' attribute under the sPAPR machine to hold
the RTC object. Overall, these changes remove an unnecessary and
implicit dependency on SysBus.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr.c         | 16 ++++++++--------
 hw/ppc/spapr_events.c  |  2 +-
 hw/ppc/spapr_rtc.c     | 41 +++++++----------------------------------
 include/hw/ppc/spapr.h | 21 ++++++++++++++++-----
 include/hw/ppc/xics.h  |  2 +-
 5 files changed, 33 insertions(+), 49 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index de5db75..3edc3dd 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1333,13 +1333,13 @@ static void spapr_create_nvram(sPAPRMachineState *spapr)
 
 static void spapr_rtc_create(sPAPRMachineState *spapr)
 {
-    DeviceState *dev = qdev_create(NULL, TYPE_SPAPR_RTC);
-
-    qdev_init_nofail(dev);
-    spapr->rtc = dev;
-
-    object_property_add_alias(qdev_get_machine(), "rtc-time",
-                              OBJECT(spapr->rtc), "date", NULL);
+    object_initialize(&spapr->rtc, sizeof(spapr->rtc), TYPE_SPAPR_RTC);
+    object_property_add_child(OBJECT(spapr), "rtc", OBJECT(&spapr->rtc),
+                              &error_fatal);
+    object_property_set_bool(OBJECT(&spapr->rtc), true, "realized",
+                              &error_fatal);
+    object_property_add_alias(OBJECT(spapr), "rtc-time", OBJECT(&spapr->rtc),
+                              "date", &error_fatal);
 }
 
 /* Returns whether we want to use VGA or not */
@@ -1377,7 +1377,7 @@ static int spapr_post_load(void *opaque, int version_id)
      * So when migrating from those versions, poke the incoming offset
      * value into the RTC device */
     if (version_id < 3) {
-        err = spapr_rtc_import_offset(spapr->rtc, spapr->rtc_offset);
+        err = spapr_rtc_import_offset(&spapr->rtc, spapr->rtc_offset);
     }
 
     return err;
diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index 24a5758..f0b28d8 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -422,7 +422,7 @@ static void spapr_init_maina(struct rtas_event_log_v6_maina *maina,
     maina->hdr.section_id = cpu_to_be16(RTAS_LOG_V6_SECTION_ID_MAINA);
     maina->hdr.section_length = cpu_to_be16(sizeof(*maina));
     /* FIXME: section version, subtype and creator id? */
-    spapr_rtc_read(spapr->rtc, &tm, NULL);
+    spapr_rtc_read(&spapr->rtc, &tm, NULL);
     year = tm.tm_year + 1900;
     maina->creation_date = cpu_to_be32((to_bcd(year / 100) << 24)
                                        | (to_bcd(year % 100) << 16)
diff --git a/hw/ppc/spapr_rtc.c b/hw/ppc/spapr_rtc.c
index 3a17ac4..00a4e4c 100644
--- a/hw/ppc/spapr_rtc.c
+++ b/hw/ppc/spapr_rtc.c
@@ -33,19 +33,8 @@
 #include "qapi-event.h"
 #include "qemu/cutils.h"
 
-#define SPAPR_RTC(obj) \
-    OBJECT_CHECK(sPAPRRTCState, (obj), TYPE_SPAPR_RTC)
-
-typedef struct sPAPRRTCState sPAPRRTCState;
-struct sPAPRRTCState {
-    /*< private >*/
-    SysBusDevice parent_obj;
-    int64_t ns_offset;
-};
-
-void spapr_rtc_read(DeviceState *dev, struct tm *tm, uint32_t *ns)
+void spapr_rtc_read(sPAPRRTCState *rtc, struct tm *tm, uint32_t *ns)
 {
-    sPAPRRTCState *rtc = SPAPR_RTC(dev);
     int64_t host_ns = qemu_clock_get_ns(rtc_clock);
     int64_t guest_ns;
     time_t guest_s;
@@ -63,16 +52,12 @@ void spapr_rtc_read(DeviceState *dev, struct tm *tm, uint32_t *ns)
     }
 }
 
-int spapr_rtc_import_offset(DeviceState *dev, int64_t legacy_offset)
+int spapr_rtc_import_offset(sPAPRRTCState *rtc, int64_t legacy_offset)
 {
-    sPAPRRTCState *rtc;
-
-    if (!dev) {
+    if (!rtc) {
         return -ENODEV;
     }
 
-    rtc = SPAPR_RTC(dev);
-
     rtc->ns_offset = legacy_offset * NANOSECONDS_PER_SECOND;
 
     return 0;
@@ -91,12 +76,7 @@ static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPRMachineState *spapr,
         return;
     }
 
-    if (!spapr->rtc) {
-        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
-        return;
-    }
-
-    spapr_rtc_read(spapr->rtc, &tm, &ns);
+    spapr_rtc_read(&spapr->rtc, &tm, &ns);
 
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
     rtas_st(rets, 1, tm.tm_year + 1900);
@@ -113,7 +93,7 @@ static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                  target_ulong args,
                                  uint32_t nret, target_ulong rets)
 {
-    sPAPRRTCState *rtc;
+    sPAPRRTCState *rtc = &spapr->rtc;
     struct tm tm;
     time_t new_s;
     int64_t host_ns;
@@ -123,11 +103,6 @@ static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPRMachineState *spapr,
         return;
     }
 
-    if (!spapr->rtc) {
-        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
-        return;
-    }
-
     tm.tm_year = rtas_ld(args, 0) - 1900;
     tm.tm_mon = rtas_ld(args, 1) - 1;
     tm.tm_mday = rtas_ld(args, 2);
@@ -144,8 +119,6 @@ static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPRMachineState *spapr,
     /* Generate a monitor event for the change */
     qapi_event_send_rtc_change(qemu_timedate_diff(&tm), &error_abort);
 
-    rtc = SPAPR_RTC(spapr->rtc);
-
     host_ns = qemu_clock_get_ns(rtc_clock);
 
     rtc->ns_offset = (new_s * NANOSECONDS_PER_SECOND) - host_ns;
@@ -155,7 +128,7 @@ static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPRMachineState *spapr,
 
 static void spapr_rtc_qom_date(Object *obj, struct tm *current_tm, Error **errp)
 {
-    spapr_rtc_read(DEVICE(obj), current_tm, NULL);
+    spapr_rtc_read(SPAPR_RTC(obj), current_tm, NULL);
 }
 
 static void spapr_rtc_realize(DeviceState *dev, Error **errp)
@@ -200,7 +173,7 @@ static void spapr_rtc_class_init(ObjectClass *oc, void *data)
 
 static const TypeInfo spapr_rtc_info = {
     .name          = TYPE_SPAPR_RTC,
-    .parent        = TYPE_SYS_BUS_DEVICE,
+    .parent        = TYPE_DEVICE,
     .instance_size = sizeof(sPAPRRTCState),
     .class_init    = spapr_rtc_class_init,
 };
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 808aac8..ba9e689 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -20,6 +20,18 @@ typedef struct sPAPREventSource sPAPREventSource;
 
 #define SPAPR_TIMEBASE_FREQ     512000000ULL
 
+#define TYPE_SPAPR_RTC "spapr-rtc"
+
+#define SPAPR_RTC(obj)                                  \
+    OBJECT_CHECK(sPAPRRTCState, (obj), TYPE_SPAPR_RTC)
+
+typedef struct sPAPRRTCState sPAPRRTCState;
+struct sPAPRRTCState {
+    /*< private >*/
+    DeviceState parent_obj;
+    int64_t ns_offset;
+};
+
 typedef struct sPAPRMachineClass sPAPRMachineClass;
 
 #define TYPE_SPAPR_MACHINE      "spapr-machine"
@@ -58,7 +70,7 @@ struct sPAPRMachineState {
     QLIST_HEAD(, sPAPRPHBState) phbs;
     struct sPAPRNVRAM *nvram;
     ICSState *ics;
-    DeviceState *rtc;
+    sPAPRRTCState rtc;
 
     void *htab;
     uint32_t htab_shift;
@@ -629,11 +641,10 @@ struct sPAPRConfigureConnectorState {
 
 void spapr_ccs_reset_hook(void *opaque);
 
-#define TYPE_SPAPR_RTC "spapr-rtc"
-#define TYPE_SPAPR_RNG "spapr-rng"
+void spapr_rtc_read(sPAPRRTCState *rtc, struct tm *tm, uint32_t *ns);
+int spapr_rtc_import_offset(sPAPRRTCState *rtc, int64_t legacy_offset);
 
-void spapr_rtc_read(DeviceState *dev, struct tm *tm, uint32_t *ns);
-int spapr_rtc_import_offset(DeviceState *dev, int64_t legacy_offset);
+#define TYPE_SPAPR_RNG "spapr-rng"
 
 int spapr_rng_populate_dt(void *fdt);
 
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 9a5e715..ce23018 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -28,7 +28,7 @@
 #ifndef XICS_H
 #define XICS_H
 
-#include "hw/sysbus.h"
+#include "hw/qdev.h"
 
 #define XICS_IPI        0x2
 #define XICS_BUID       0x1
-- 
2.9.3

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

* [Qemu-devel] [PULL 04/47] hw/ppc/pnv: Classify the "PowerNV Chip" devices as CPU devices
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (2 preceding siblings ...)
  2017-04-24  1:58 ` [Qemu-devel] [PULL 03/47] ppc/spapr: QOM'ify sPAPRRTCState David Gibson
@ 2017-04-24  1:58 ` David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 05/47] target-ppc: kvm: make use of KVM_CREATE_SPAPR_TCE_64 David Gibson
                   ` (44 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:58 UTC (permalink / raw)
  To: peter.maydell
  Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, Thomas Huth, David Gibson

From: Thomas Huth <thuth@redhat.com>

The devices that are derived from TYPE_PNV_CHIP currently show up
as "uncategorized" devices in the help text of "-device ?". Since
they obviously are related to the CPU, let's put them into the
CPU category instead.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 3fa722a..aad7917 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -723,6 +723,7 @@ static void pnv_chip_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
 
+    set_bit(DEVICE_CATEGORY_CPU, dc->categories);
     dc->realize = pnv_chip_realize;
     dc->props = pnv_chip_properties;
     dc->desc = "PowerNV Chip";
-- 
2.9.3

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

* [Qemu-devel] [PULL 05/47] target-ppc: kvm: make use of KVM_CREATE_SPAPR_TCE_64
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (3 preceding siblings ...)
  2017-04-24  1:58 ` [Qemu-devel] [PULL 04/47] hw/ppc/pnv: Classify the "PowerNV Chip" devices as CPU devices David Gibson
@ 2017-04-24  1:58 ` David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 06/47] spapr: Add ibm, processor-radix-AP-encodings to the device tree David Gibson
                   ` (43 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:58 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

From: Alexey Kardashevskiy <aik@ozlabs.ru>

KVM_CAP_SPAPR_TCE capability allows creating TCE tables in KVM which
allows having in-kernel acceleration for H_PUT_TCE_xxx hypercalls.
However it only supports 32bit DMA windows at zero bus offset.

There is a new KVM_CAP_SPAPR_TCE_64 capability which supports 64bit
window size, variable page size and bus offset.

This makes use of the new capability. The kernel headers are already
updated as the kernel support went in to v4.6.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_iommu.c |  8 +++++---
 target/ppc/kvm.c     | 48 +++++++++++++++++++++++++++++++++++++-----------
 target/ppc/kvm_ppc.h | 12 +++++++-----
 3 files changed, 49 insertions(+), 19 deletions(-)

diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index ae30bbe..29c80bb 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -79,15 +79,16 @@ static IOMMUAccessFlags spapr_tce_iommu_access_flags(uint64_t tce)
 
 static uint64_t *spapr_tce_alloc_table(uint32_t liobn,
                                        uint32_t page_shift,
+                                       uint64_t bus_offset,
                                        uint32_t nb_table,
                                        int *fd,
                                        bool need_vfio)
 {
     uint64_t *table = NULL;
-    uint64_t window_size = (uint64_t)nb_table << page_shift;
 
-    if (kvm_enabled() && !(window_size >> 32)) {
-        table = kvmppc_create_spapr_tce(liobn, window_size, fd, need_vfio);
+    if (kvm_enabled()) {
+        table = kvmppc_create_spapr_tce(liobn, page_shift, bus_offset, nb_table,
+                                        fd, need_vfio);
     }
 
     if (!table) {
@@ -342,6 +343,7 @@ void spapr_tce_table_enable(sPAPRTCETable *tcet,
     tcet->nb_table = nb_table;
     tcet->table = spapr_tce_alloc_table(tcet->liobn,
                                         tcet->page_shift,
+                                        tcet->bus_offset,
                                         tcet->nb_table,
                                         &tcet->fd,
                                         tcet->need_vfio);
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index c3d4262..79b90a6 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -74,6 +74,7 @@ static int cap_booke_sregs;
 static int cap_ppc_smt;
 static int cap_ppc_rma;
 static int cap_spapr_tce;
+static int cap_spapr_tce_64;
 static int cap_spapr_multitce;
 static int cap_spapr_vfio;
 static int cap_hior;
@@ -126,6 +127,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
     cap_ppc_smt = kvm_check_extension(s, KVM_CAP_PPC_SMT);
     cap_ppc_rma = kvm_check_extension(s, KVM_CAP_PPC_RMA);
     cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE);
+    cap_spapr_tce_64 = kvm_check_extension(s, KVM_CAP_SPAPR_TCE_64);
     cap_spapr_multitce = kvm_check_extension(s, KVM_CAP_SPAPR_MULTITCE);
     cap_spapr_vfio = false;
     cap_one_reg = kvm_check_extension(s, KVM_CAP_ONE_REG);
@@ -2136,13 +2138,10 @@ bool kvmppc_spapr_use_multitce(void)
     return cap_spapr_multitce;
 }
 
-void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd,
-                              bool need_vfio)
+void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t page_shift,
+                              uint64_t bus_offset, uint32_t nb_table,
+                              int *pfd, bool need_vfio)
 {
-    struct kvm_create_spapr_tce args = {
-        .liobn = liobn,
-        .window_size = window_size,
-    };
     long len;
     int fd;
     void *table;
@@ -2155,14 +2154,41 @@ void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd,
         return NULL;
     }
 
-    fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE, &args);
-    if (fd < 0) {
-        fprintf(stderr, "KVM: Failed to create TCE table for liobn 0x%x\n",
-                liobn);
+    if (cap_spapr_tce_64) {
+        struct kvm_create_spapr_tce_64 args = {
+            .liobn = liobn,
+            .page_shift = page_shift,
+            .offset = bus_offset >> page_shift,
+            .size = nb_table,
+            .flags = 0
+        };
+        fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE_64, &args);
+        if (fd < 0) {
+            fprintf(stderr,
+                    "KVM: Failed to create TCE64 table for liobn 0x%x\n",
+                    liobn);
+            return NULL;
+        }
+    } else if (cap_spapr_tce) {
+        uint64_t window_size = (uint64_t) nb_table << page_shift;
+        struct kvm_create_spapr_tce args = {
+            .liobn = liobn,
+            .window_size = window_size,
+        };
+        if ((window_size != args.window_size) || bus_offset) {
+            return NULL;
+        }
+        fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE, &args);
+        if (fd < 0) {
+            fprintf(stderr, "KVM: Failed to create TCE table for liobn 0x%x\n",
+                    liobn);
+            return NULL;
+        }
+    } else {
         return NULL;
     }
 
-    len = (window_size / SPAPR_TCE_PAGE_SIZE) * sizeof(uint64_t);
+    len = nb_table * sizeof(uint64_t);
     /* FIXME: round this up to page size */
 
     table = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
index 8e9f42d..08ecf75 100644
--- a/target/ppc/kvm_ppc.h
+++ b/target/ppc/kvm_ppc.h
@@ -36,8 +36,9 @@ int kvmppc_booke_watchdog_enable(PowerPCCPU *cpu);
 #ifndef CONFIG_USER_ONLY
 off_t kvmppc_alloc_rma(void **rma);
 bool kvmppc_spapr_use_multitce(void);
-void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd,
-                              bool need_vfio);
+void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t page_shift,
+                              uint64_t bus_offset, uint32_t nb_table,
+                              int *pfd, bool need_vfio);
 int kvmppc_remove_spapr_tce(void *table, int pfd, uint32_t window_size);
 int kvmppc_reset_htab(int shift_hint);
 uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift);
@@ -167,9 +168,10 @@ static inline bool kvmppc_spapr_use_multitce(void)
     return false;
 }
 
-static inline void *kvmppc_create_spapr_tce(uint32_t liobn,
-                                            uint32_t window_size, int *fd,
-                                            bool need_vfio)
+static inline void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t page_shift,
+                                            uint64_t bus_offset,
+                                            uint32_t nb_table,
+                                            int *pfd, bool need_vfio)
 {
     return NULL;
 }
-- 
2.9.3

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

* [Qemu-devel] [PULL 06/47] spapr: Add ibm, processor-radix-AP-encodings to the device tree
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (4 preceding siblings ...)
  2017-04-24  1:58 ` [Qemu-devel] [PULL 05/47] target-ppc: kvm: make use of KVM_CREATE_SPAPR_TCE_64 David Gibson
@ 2017-04-24  1:58 ` David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 07/47] target-ppc: support KVM_CAP_PPC_MMU_RADIX, KVM_CAP_PPC_MMU_HASH_V3 David Gibson
                   ` (42 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:58 UTC (permalink / raw)
  To: peter.maydell
  Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, Sam Bobroff, David Gibson

From: Sam Bobroff <sam.bobroff@au1.ibm.com>

Use the new ioctl, KVM_PPC_GET_RMMU_INFO, to fetch radix MMU
information from KVM and present the page encodings in the device tree
under ibm,processor-radix-AP-encodings. This provides page size
information to the guest which is necessary for it to use radix mode.

Signed-off-by: Sam Bobroff <sam.bobroff@au1.ibm.com>
[dwg: Compile fix for 32-bit targets, style nit fix]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr.c       | 13 +++++++++++++
 include/sysemu/kvm.h |  1 +
 target/ppc/cpu-qom.h |  1 +
 target/ppc/cpu.h     |  4 ++++
 target/ppc/kvm.c     | 29 +++++++++++++++++++++++++++++
 5 files changed, 48 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 3edc3dd..ea247e6 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -459,6 +459,8 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
     sPAPRDRConnector *drc;
     sPAPRDRConnectorClass *drck;
     int drc_index;
+    uint32_t radix_AP_encodings[PPC_PAGE_SIZES_MAX_SZ];
+    int i;
 
     drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, index);
     if (drc) {
@@ -544,6 +546,17 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
     _FDT(spapr_fixup_cpu_numa_dt(fdt, offset, cs));
 
     _FDT(spapr_fixup_cpu_smt_dt(fdt, offset, cpu, compat_smt));
+
+    if (pcc->radix_page_info) {
+        for (i = 0; i < pcc->radix_page_info->count; i++) {
+            radix_AP_encodings[i] =
+                cpu_to_be32(pcc->radix_page_info->entries[i]);
+        }
+        _FDT((fdt_setprop(fdt, offset, "ibm,processor-radix-AP-encodings",
+                          radix_AP_encodings,
+                          pcc->radix_page_info->count *
+                          sizeof(radix_AP_encodings[0]))));
+    }
 }
 
 static void spapr_populate_cpus_dt_node(void *fdt, sPAPRMachineState *spapr)
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 24281fc..5cc83f2 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -527,5 +527,6 @@ int kvm_set_one_reg(CPUState *cs, uint64_t id, void *source);
  * Returns: 0 on success, or a negative errno on failure.
  */
 int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target);
+struct ppc_radix_page_info *kvm_get_radix_page_info(void);
 int kvm_get_max_memslots(void);
 #endif
diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h
index 81500e5..d0cf6ca 100644
--- a/target/ppc/cpu-qom.h
+++ b/target/ppc/cpu-qom.h
@@ -197,6 +197,7 @@ typedef struct PowerPCCPUClass {
     int bfd_mach;
     uint32_t l1_dcache_size, l1_icache_size;
     const struct ppc_segment_page_sizes *sps;
+    struct ppc_radix_page_info *radix_page_info;
     void (*init_proc)(CPUPPCState *env);
     int  (*check_pow)(CPUPPCState *env);
     int (*handle_mmu_fault)(PowerPCCPU *cpu, vaddr eaddr, int rwx, int mmu_idx);
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 5ee33b3..cacdd0a 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -943,6 +943,10 @@ struct ppc_segment_page_sizes {
     struct ppc_one_seg_page_size sps[PPC_PAGE_SIZES_MAX_SZ];
 };
 
+struct ppc_radix_page_info {
+    uint32_t count;
+    uint32_t entries[PPC_PAGE_SIZES_MAX_SZ];
+};
 
 /*****************************************************************************/
 /* The whole PowerPC CPU context */
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 79b90a6..9dc2f7f 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -50,6 +50,7 @@
 #include "hw/ppc/spapr_cpu_core.h"
 #endif
 #include "elf.h"
+#include "sysemu/kvm_int.h"
 
 //#define DEBUG_KVM
 
@@ -333,6 +334,30 @@ static void kvm_get_smmu_info(PowerPCCPU *cpu, struct kvm_ppc_smmu_info *info)
     kvm_get_fallback_smmu_info(cpu, info);
 }
 
+struct ppc_radix_page_info *kvm_get_radix_page_info(void)
+{
+    KVMState *s = KVM_STATE(current_machine->accelerator);
+    struct ppc_radix_page_info *radix_page_info;
+    struct kvm_ppc_rmmu_info rmmu_info;
+    int i;
+
+    if (!kvm_check_extension(s, KVM_CAP_PPC_MMU_RADIX)) {
+        return NULL;
+    }
+    if (kvm_vm_ioctl(s, KVM_PPC_GET_RMMU_INFO, &rmmu_info)) {
+        return NULL;
+    }
+    radix_page_info = g_malloc0(sizeof(*radix_page_info));
+    radix_page_info->count = 0;
+    for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) {
+        if (rmmu_info.ap_encodings[i]) {
+            radix_page_info->entries[i] = rmmu_info.ap_encodings[i];
+            radix_page_info->count++;
+        }
+    }
+    return radix_page_info;
+}
+
 static bool kvm_valid_page_size(uint32_t flags, long rampgsize, uint32_t shift)
 {
     if (!(flags & KVM_PPC_PAGE_SIZES_REAL)) {
@@ -2303,6 +2328,10 @@ static void kvmppc_host_cpu_class_init(ObjectClass *oc, void *data)
     if (icache_size != -1) {
         pcc->l1_icache_size = icache_size;
     }
+
+#if defined(TARGET_PPC64)
+    pcc->radix_page_info = kvm_get_radix_page_info();
+#endif /* defined(TARGET_PPC64) */
 }
 
 bool kvmppc_has_cap_epr(void)
-- 
2.9.3

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

* [Qemu-devel] [PULL 07/47] target-ppc: support KVM_CAP_PPC_MMU_RADIX, KVM_CAP_PPC_MMU_HASH_V3
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (5 preceding siblings ...)
  2017-04-24  1:58 ` [Qemu-devel] [PULL 06/47] spapr: Add ibm, processor-radix-AP-encodings to the device tree David Gibson
@ 2017-04-24  1:58 ` David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 08/47] target/ppc: Add new H-CALL shells for in memory table translation David Gibson
                   ` (41 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:58 UTC (permalink / raw)
  To: peter.maydell
  Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, Sam Bobroff, David Gibson

From: Sam Bobroff <sam.bobroff@au1.ibm.com>

Query and cache the value of two new KVM capabilities that indicate
KVM's support for new radix and hash modes of the MMU.

Signed-off-by: Sam Bobroff <sam.bobroff@au1.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/kvm.c     | 14 ++++++++++++++
 target/ppc/kvm_ppc.h | 12 ++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 9dc2f7f..38db27b 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -86,6 +86,8 @@ static int cap_papr;
 static int cap_htab_fd;
 static int cap_fixup_hcalls;
 static int cap_htm;             /* Hardware transactional memory support */
+static int cap_mmu_radix;
+static int cap_mmu_hash_v3;
 
 static uint32_t debug_inst_opcode;
 
@@ -140,6 +142,8 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
     cap_htab_fd = kvm_check_extension(s, KVM_CAP_PPC_HTAB_FD);
     cap_fixup_hcalls = kvm_check_extension(s, KVM_CAP_PPC_FIXUP_HCALL);
     cap_htm = kvm_vm_check_extension(s, KVM_CAP_PPC_HTM);
+    cap_mmu_radix = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_RADIX);
+    cap_mmu_hash_v3 = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_HASH_V3);
 
     if (!cap_interrupt_level) {
         fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the "
@@ -2354,6 +2358,16 @@ bool kvmppc_has_cap_htm(void)
     return cap_htm;
 }
 
+bool kvmppc_has_cap_mmu_radix(void)
+{
+    return cap_mmu_radix;
+}
+
+bool kvmppc_has_cap_mmu_hash_v3(void)
+{
+    return cap_mmu_hash_v3;
+}
+
 static PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc)
 {
     ObjectClass *oc = OBJECT_CLASS(pcc);
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
index 08ecf75..64189a4 100644
--- a/target/ppc/kvm_ppc.h
+++ b/target/ppc/kvm_ppc.h
@@ -54,6 +54,8 @@ void kvmppc_read_hptes(ppc_hash_pte64_t *hptes, hwaddr ptex, int n);
 void kvmppc_write_hpte(hwaddr ptex, uint64_t pte0, uint64_t pte1);
 bool kvmppc_has_cap_fixup_hcalls(void);
 bool kvmppc_has_cap_htm(void);
+bool kvmppc_has_cap_mmu_radix(void);
+bool kvmppc_has_cap_mmu_hash_v3(void);
 int kvmppc_enable_hwrng(void);
 int kvmppc_put_books_sregs(PowerPCCPU *cpu);
 PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void);
@@ -254,6 +256,16 @@ static inline bool kvmppc_has_cap_htm(void)
     return false;
 }
 
+static inline bool kvmppc_has_cap_mmu_radix(void)
+{
+    return false;
+}
+
+static inline bool kvmppc_has_cap_mmu_hash_v3(void)
+{
+    return false;
+}
+
 static inline int kvmppc_enable_hwrng(void)
 {
     return -1;
-- 
2.9.3

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

* [Qemu-devel] [PULL 08/47] target/ppc: Add new H-CALL shells for in memory table translation
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (6 preceding siblings ...)
  2017-04-24  1:58 ` [Qemu-devel] [PULL 07/47] target-ppc: support KVM_CAP_PPC_MMU_RADIX, KVM_CAP_PPC_MMU_HASH_V3 David Gibson
@ 2017-04-24  1:58 ` David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 09/47] target/ppc: Implement H_REGISTER_PROCESS_TABLE H_CALL David Gibson
                   ` (40 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:58 UTC (permalink / raw)
  To: peter.maydell
  Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg,
	Suraj Jitindar Singh, David Gibson

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

The use of the new in memory tables introduced in ISAv3.00 for translation,
also referred to as process tables, requires the introduction of 3 new
H-CALLs; H_REGISTER_PROCESS_TABLE, H_CLEAN_SLB, and H_INVALIDATE_PID.

Add shells for each of these and register them as the hypercall handlers.
Currently they all log an unimplemented hypercall and return H_FUNCTION.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
[dwg: Fix style nits]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_hcall.c   | 31 +++++++++++++++++++++++++++++++
 include/hw/ppc/spapr.h |  3 +++
 2 files changed, 34 insertions(+)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index f05a90e..7952129 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -878,6 +878,32 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPRMachineState *spapr,
     return ret;
 }
 
+static target_ulong h_clean_slb(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+                                target_ulong opcode, target_ulong *args)
+{
+    qemu_log_mask(LOG_UNIMP, "Unimplemented SPAPR hcall 0x"TARGET_FMT_lx"%s\n",
+                  opcode, " (H_CLEAN_SLB)");
+    return H_FUNCTION;
+}
+
+static target_ulong h_invalidate_pid(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+                                     target_ulong opcode, target_ulong *args)
+{
+    qemu_log_mask(LOG_UNIMP, "Unimplemented SPAPR hcall 0x"TARGET_FMT_lx"%s\n",
+                  opcode, " (H_INVALIDATE_PID)");
+    return H_FUNCTION;
+}
+
+static target_ulong h_register_process_table(PowerPCCPU *cpu,
+                                             sPAPRMachineState *spapr,
+                                             target_ulong opcode,
+                                             target_ulong *args)
+{
+    qemu_log_mask(LOG_UNIMP, "Unimplemented SPAPR hcall 0x"TARGET_FMT_lx"%s\n",
+                  opcode, " (H_REGISTER_PROC_TBL)");
+    return H_FUNCTION;
+}
+
 #define H_SIGNAL_SYS_RESET_ALL         -1
 #define H_SIGNAL_SYS_RESET_ALLBUTSELF  -2
 
@@ -1084,6 +1110,11 @@ static void hypercall_register_types(void)
     spapr_register_hypercall(H_PAGE_INIT, h_page_init);
     spapr_register_hypercall(H_SET_MODE, h_set_mode);
 
+    /* In Memory Table MMU h-calls */
+    spapr_register_hypercall(H_CLEAN_SLB, h_clean_slb);
+    spapr_register_hypercall(H_INVALIDATE_PID, h_invalidate_pid);
+    spapr_register_hypercall(H_REGISTER_PROC_TBL, h_register_process_table);
+
     /* "debugger" hcalls (also used by SLOF). Note: We do -not- differenciate
      * here between the "CI" and the "CACHE" variants, they will use whatever
      * mapping attributes qemu is using. When using KVM, the kernel will
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index ba9e689..342f7a6 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -361,6 +361,9 @@ struct sPAPRMachineState {
 #define H_XIRR_X                0x2FC
 #define H_RANDOM                0x300
 #define H_SET_MODE              0x31C
+#define H_CLEAN_SLB             0x374
+#define H_INVALIDATE_PID        0x378
+#define H_REGISTER_PROC_TBL     0x37C
 #define H_SIGNAL_SYS_RESET      0x380
 #define MAX_HCALL_OPCODE        H_SIGNAL_SYS_RESET
 
-- 
2.9.3

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

* [Qemu-devel] [PULL 09/47] target/ppc: Implement H_REGISTER_PROCESS_TABLE H_CALL
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (7 preceding siblings ...)
  2017-04-24  1:58 ` [Qemu-devel] [PULL 08/47] target/ppc: Add new H-CALL shells for in memory table translation David Gibson
@ 2017-04-24  1:58 ` David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 10/47] spapr: move spapr_populate_pa_features() David Gibson
                   ` (39 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:58 UTC (permalink / raw)
  To: peter.maydell
  Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg,
	Suraj Jitindar Singh, Sam Bobroff, David Gibson

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

The H_REGISTER_PROCESS_TABLE H_CALL is used by a guest to indicate to the
hypervisor where in memory its process table is and how translation should
be performed using this process table.

Provide the implementation of this H_CALL for a guest.

We first check for invalid flags, then parse the flags to determine the
operation, and then check the other parameters for valid values based on
the operation (register new table/deregister table/maintain registration).
The process table is then stored in the appropriate location and registered
with the hypervisor (if running under KVM), and the LPCR_[UPRT/GTSE] bits
are updated as required.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Signed-off-by: Sam Bobroff <sam.bobroff@au1.ibm.com>
[dwg: Correct missing prototype and uninitialized variable]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr.c         |  35 +++++++++------
 hw/ppc/spapr_hcall.c   | 113 +++++++++++++++++++++++++++++++++++++++++++++++--
 include/hw/ppc/spapr.h |   2 +
 target/ppc/kvm.c       |  31 ++++++++++++++
 target/ppc/kvm_ppc.h   |  10 +++++
 5 files changed, 176 insertions(+), 15 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index ea247e6..54391a1 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -40,6 +40,7 @@
 #include "kvm_ppc.h"
 #include "migration/migration.h"
 #include "mmu-hash64.h"
+#include "mmu-book3s-v3.h"
 #include "qom/cpu.h"
 
 #include "hw/boards.h"
@@ -1113,7 +1114,7 @@ static int get_htab_fd(sPAPRMachineState *spapr)
     return spapr->htab_fd;
 }
 
-static void close_htab_fd(sPAPRMachineState *spapr)
+void close_htab_fd(sPAPRMachineState *spapr)
 {
     if (spapr->htab_fd >= 0) {
         close(spapr->htab_fd);
@@ -1240,6 +1241,19 @@ static void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift,
     }
 }
 
+void spapr_setup_hpt_and_vrma(sPAPRMachineState *spapr)
+{
+    spapr_reallocate_hpt(spapr,
+                     spapr_hpt_shift_for_ramsize(MACHINE(spapr)->maxram_size),
+                     &error_fatal);
+    if (spapr->vrma_adjust) {
+        spapr->rma_size = kvmppc_rma_size(spapr_node0_size(),
+                                          spapr->htab_shift);
+    }
+    /* We're setting up a hash table, so that means we're not radix */
+    spapr->patb_entry = 0;
+}
+
 static void find_unknown_sysbus_device(SysBusDevice *sbdev, void *opaque)
 {
     bool matched = false;
@@ -1268,17 +1282,14 @@ static void ppc_spapr_reset(void)
     /* Check for unknown sysbus devices */
     foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL);
 
-    spapr->patb_entry = 0;
-
-    /* Allocate and/or reset the hash page table */
-    spapr_reallocate_hpt(spapr,
-                         spapr_hpt_shift_for_ramsize(machine->maxram_size),
-                         &error_fatal);
-
-    /* Update the RMA size if necessary */
-    if (spapr->vrma_adjust) {
-        spapr->rma_size = kvmppc_rma_size(spapr_node0_size(),
-                                          spapr->htab_shift);
+    if (kvm_enabled() && kvmppc_has_cap_mmu_radix()) {
+        /* If using KVM with radix mode available, VCPUs can be started
+         * without a HPT because KVM will start them in radix mode.
+         * Set the GR bit in PATB so that we know there is no HPT. */
+        spapr->patb_entry = PATBE1_GR;
+    } else {
+        spapr->patb_entry = 0;
+        spapr_setup_hpt_and_vrma(spapr);
     }
 
     qemu_devices_reset();
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 7952129..a958fee 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -12,6 +12,8 @@
 #include "trace.h"
 #include "kvm_ppc.h"
 #include "hw/ppc/spapr_ovec.h"
+#include "qemu/error-report.h"
+#include "mmu-book3s-v3.h"
 
 struct SPRSyncState {
     int spr;
@@ -894,14 +896,119 @@ static target_ulong h_invalidate_pid(PowerPCCPU *cpu, sPAPRMachineState *spapr,
     return H_FUNCTION;
 }
 
+static void spapr_check_setup_free_hpt(sPAPRMachineState *spapr,
+                                       uint64_t patbe_old, uint64_t patbe_new)
+{
+    /*
+     * We have 4 Options:
+     * HASH->HASH || RADIX->RADIX || NOTHING->RADIX : Do Nothing
+     * HASH->RADIX                                  : Free HPT
+     * RADIX->HASH                                  : Allocate HPT
+     * NOTHING->HASH                                : Allocate HPT
+     * Note: NOTHING implies the case where we said the guest could choose
+     *       later and so assumed radix and now it's called H_REG_PROC_TBL
+     */
+
+    if ((patbe_old & PATBE1_GR) == (patbe_new & PATBE1_GR)) {
+        /* We assume RADIX, so this catches all the "Do Nothing" cases */
+    } else if (!(patbe_old & PATBE1_GR)) {
+        /* HASH->RADIX : Free HPT */
+        g_free(spapr->htab);
+        spapr->htab = NULL;
+        spapr->htab_shift = 0;
+        close_htab_fd(spapr);
+    } else if (!(patbe_new & PATBE1_GR)) {
+        /* RADIX->HASH || NOTHING->HASH : Allocate HPT */
+        spapr_setup_hpt_and_vrma(spapr);
+    }
+    return;
+}
+
+#define FLAGS_MASK              0x01FULL
+#define FLAG_MODIFY             0x10
+#define FLAG_REGISTER           0x08
+#define FLAG_RADIX              0x04
+#define FLAG_HASH_PROC_TBL      0x02
+#define FLAG_GTSE               0x01
+
 static target_ulong h_register_process_table(PowerPCCPU *cpu,
                                              sPAPRMachineState *spapr,
                                              target_ulong opcode,
                                              target_ulong *args)
 {
-    qemu_log_mask(LOG_UNIMP, "Unimplemented SPAPR hcall 0x"TARGET_FMT_lx"%s\n",
-                  opcode, " (H_REGISTER_PROC_TBL)");
-    return H_FUNCTION;
+    CPUPPCState *env = &cpu->env;
+    target_ulong flags = args[0];
+    target_ulong proc_tbl = args[1];
+    target_ulong page_size = args[2];
+    target_ulong table_size = args[3];
+    uint64_t cproc;
+
+    if (flags & ~FLAGS_MASK) { /* Check no reserved bits are set */
+        return H_PARAMETER;
+    }
+    if (flags & FLAG_MODIFY) {
+        if (flags & FLAG_REGISTER) {
+            if (flags & FLAG_RADIX) { /* Register new RADIX process table */
+                if (proc_tbl & 0xfff || proc_tbl >> 60) {
+                    return H_P2;
+                } else if (page_size) {
+                    return H_P3;
+                } else if (table_size > 24) {
+                    return H_P4;
+                }
+                cproc = PATBE1_GR | proc_tbl | table_size;
+            } else { /* Register new HPT process table */
+                if (flags & FLAG_HASH_PROC_TBL) { /* Hash with Segment Tables */
+                    /* TODO - Not Supported */
+                    /* Technically caused by flag bits => H_PARAMETER */
+                    return H_PARAMETER;
+                } else { /* Hash with SLB */
+                    if (proc_tbl >> 38) {
+                        return H_P2;
+                    } else if (page_size & ~0x7) {
+                        return H_P3;
+                    } else if (table_size > 24) {
+                        return H_P4;
+                    }
+                }
+                cproc = (proc_tbl << 25) | page_size << 5 | table_size;
+            }
+
+        } else { /* Deregister current process table */
+            /* Set to benign value: (current GR) | 0. This allows
+             * deregistration in KVM to succeed even if the radix bit in flags
+             * doesn't match the radix bit in the old PATB. */
+            cproc = spapr->patb_entry & PATBE1_GR;
+        }
+    } else { /* Maintain current registration */
+        if (!(flags & FLAG_RADIX) != !(spapr->patb_entry & PATBE1_GR)) {
+            /* Technically caused by flag bits => H_PARAMETER */
+            return H_PARAMETER; /* Existing Process Table Mismatch */
+        }
+        cproc = spapr->patb_entry;
+    }
+
+    /* Check if we need to setup OR free the hpt */
+    spapr_check_setup_free_hpt(spapr, spapr->patb_entry, cproc);
+
+    spapr->patb_entry = cproc; /* Save new process table */
+    if ((flags & FLAG_RADIX) || (flags & FLAG_HASH_PROC_TBL)) {
+        /* Use Process TBL */
+        env->spr[SPR_LPCR] |= LPCR_UPRT;
+    } else {
+        env->spr[SPR_LPCR] &= ~LPCR_UPRT;
+    }
+    if (flags & FLAG_GTSE) { /* Partition Uses Guest Translation Shootdwn */
+        env->spr[SPR_LPCR] |= LPCR_GTSE;
+    } else {
+        env->spr[SPR_LPCR] &= ~LPCR_GTSE;
+    }
+
+    if (kvm_enabled()) {
+        return kvmppc_configure_v3_mmu(cpu, flags & FLAG_RADIX,
+                                       flags & FLAG_GTSE, cproc);
+    }
+    return H_SUCCESS;
 }
 
 #define H_SIGNAL_SYS_RESET_ALL         -1
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 342f7a6..d234efc 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -608,6 +608,8 @@ 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);
 sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn);
 void spapr_tce_table_enable(sPAPRTCETable *tcet,
                             uint32_t page_shift, uint64_t bus_offset,
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 38db27b..c959b90 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -362,6 +362,37 @@ struct ppc_radix_page_info *kvm_get_radix_page_info(void)
     return radix_page_info;
 }
 
+target_ulong kvmppc_configure_v3_mmu(PowerPCCPU *cpu,
+                                     bool radix, bool gtse,
+                                     uint64_t proc_tbl)
+{
+    CPUState *cs = CPU(cpu);
+    int ret;
+    uint64_t flags = 0;
+    struct kvm_ppc_mmuv3_cfg cfg = {
+        .process_table = proc_tbl,
+    };
+
+    if (radix) {
+        flags |= KVM_PPC_MMUV3_RADIX;
+    }
+    if (gtse) {
+        flags |= KVM_PPC_MMUV3_GTSE;
+    }
+    cfg.flags = flags;
+    ret = kvm_vm_ioctl(cs->kvm_state, KVM_PPC_CONFIGURE_V3_MMU, &cfg);
+    switch (ret) {
+    case 0:
+        return H_SUCCESS;
+    case -EINVAL:
+        return H_PARAMETER;
+    case -ENODEV:
+        return H_NOT_AVAILABLE;
+    default:
+        return H_HARDWARE;
+    }
+}
+
 static bool kvm_valid_page_size(uint32_t flags, long rampgsize, uint32_t shift)
 {
     if (!(flags & KVM_PPC_PAGE_SIZES_REAL)) {
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
index 64189a4..4b2fd9a 100644
--- a/target/ppc/kvm_ppc.h
+++ b/target/ppc/kvm_ppc.h
@@ -33,6 +33,9 @@ int kvmppc_clear_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits);
 int kvmppc_or_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits);
 int kvmppc_set_tcr(PowerPCCPU *cpu);
 int kvmppc_booke_watchdog_enable(PowerPCCPU *cpu);
+target_ulong kvmppc_configure_v3_mmu(PowerPCCPU *cpu,
+                                     bool radix, bool gtse,
+                                     uint64_t proc_tbl);
 #ifndef CONFIG_USER_ONLY
 off_t kvmppc_alloc_rma(void **rma);
 bool kvmppc_spapr_use_multitce(void);
@@ -159,6 +162,13 @@ static inline int kvmppc_booke_watchdog_enable(PowerPCCPU *cpu)
     return -1;
 }
 
+static inline target_ulong kvmppc_configure_v3_mmu(PowerPCCPU *cpu,
+                                     bool radix, bool gtse,
+                                     uint64_t proc_tbl)
+{
+    return 0;
+}
+
 #ifndef CONFIG_USER_ONLY
 static inline off_t kvmppc_alloc_rma(void **rma)
 {
-- 
2.9.3

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

* [Qemu-devel] [PULL 10/47] spapr: move spapr_populate_pa_features()
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (8 preceding siblings ...)
  2017-04-24  1:58 ` [Qemu-devel] [PULL 09/47] target/ppc: Implement H_REGISTER_PROCESS_TABLE H_CALL David Gibson
@ 2017-04-24  1:58 ` David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 11/47] spapr: Enable ISA 3.0 MMU mode selection via CAS David Gibson
                   ` (38 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:58 UTC (permalink / raw)
  To: peter.maydell
  Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, Sam Bobroff, David Gibson

From: Sam Bobroff <sam.bobroff@au1.ibm.com>

In the next patch, spapr_fixup_cpu_dt() will need to call
spapr_populate_pa_features() so move it's definition up without making
any other changes.

Signed-off-by: Sam Bobroff <sam.bobroff@au1.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr.c | 122 ++++++++++++++++++++++++++++-----------------------------
 1 file changed, 61 insertions(+), 61 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 54391a1..21da9a1 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -227,6 +227,67 @@ static int spapr_fixup_cpu_numa_dt(void *fdt, int offset, CPUState *cs)
     return ret;
 }
 
+/* Populate the "ibm,pa-features" property */
+static void spapr_populate_pa_features(CPUPPCState *env, void *fdt, int offset)
+{
+    uint8_t pa_features_206[] = { 6, 0,
+        0xf6, 0x1f, 0xc7, 0x00, 0x80, 0xc0 };
+    uint8_t pa_features_207[] = { 24, 0,
+        0xf6, 0x1f, 0xc7, 0xc0, 0x80, 0xf0,
+        0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+        0x80, 0x00, 0x80, 0x00, 0x00, 0x00 };
+    /* Currently we don't advertise any of the "new" ISAv3.00 functionality */
+    uint8_t pa_features_300[] = { 64, 0,
+        0xf6, 0x1f, 0xc7, 0xc0, 0x80, 0xf0, /*  0 -  5 */
+        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /*  6 - 11 */
+        0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 12 - 17 */
+        0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 18 - 23 */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 24 - 29 */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 - 35 */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 36 - 41 */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 42 - 47 */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 48 - 53 */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 54 - 59 */
+        0x00, 0x00, 0x00, 0x00           }; /* 60 - 63 */
+
+    uint8_t *pa_features;
+    size_t pa_size;
+
+    switch (POWERPC_MMU_VER(env->mmu_model)) {
+    case POWERPC_MMU_VER_2_06:
+        pa_features = pa_features_206;
+        pa_size = sizeof(pa_features_206);
+        break;
+    case POWERPC_MMU_VER_2_07:
+        pa_features = pa_features_207;
+        pa_size = sizeof(pa_features_207);
+        break;
+    case POWERPC_MMU_VER_3_00:
+        pa_features = pa_features_300;
+        pa_size = sizeof(pa_features_300);
+        break;
+    default:
+        return;
+    }
+
+    if (env->ci_large_pages) {
+        /*
+         * Note: we keep CI large pages off by default because a 64K capable
+         * guest provisioned with large pages might otherwise try to map a qemu
+         * framebuffer (or other kind of memory mapped PCI BAR) using 64K pages
+         * even if that qemu runs on a 4k host.
+         * We dd this bit back here if we are confident this is not an issue
+         */
+        pa_features[3] |= 0x20;
+    }
+    if (kvmppc_has_cap_htm() && pa_size > 24) {
+        pa_features[24] |= 0x80;    /* Transactional memory support */
+    }
+
+    _FDT((fdt_setprop(fdt, offset, "ibm,pa-features", pa_features, pa_size)));
+}
+
 static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
 {
     int ret = 0, offset, cpus_offset;
@@ -379,67 +440,6 @@ static int spapr_populate_memory(sPAPRMachineState *spapr, void *fdt)
     return 0;
 }
 
-/* Populate the "ibm,pa-features" property */
-static void spapr_populate_pa_features(CPUPPCState *env, void *fdt, int offset)
-{
-    uint8_t pa_features_206[] = { 6, 0,
-        0xf6, 0x1f, 0xc7, 0x00, 0x80, 0xc0 };
-    uint8_t pa_features_207[] = { 24, 0,
-        0xf6, 0x1f, 0xc7, 0xc0, 0x80, 0xf0,
-        0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
-        0x80, 0x00, 0x80, 0x00, 0x00, 0x00 };
-    /* Currently we don't advertise any of the "new" ISAv3.00 functionality */
-    uint8_t pa_features_300[] = { 64, 0,
-        0xf6, 0x1f, 0xc7, 0xc0, 0x80, 0xf0, /*  0 -  5 */
-        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /*  6 - 11 */
-        0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 12 - 17 */
-        0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 18 - 23 */
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 24 - 29 */
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 - 35 */
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 36 - 41 */
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 42 - 47 */
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 48 - 53 */
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 54 - 59 */
-        0x00, 0x00, 0x00, 0x00           }; /* 60 - 63 */
-
-    uint8_t *pa_features;
-    size_t pa_size;
-
-    switch (POWERPC_MMU_VER(env->mmu_model)) {
-    case POWERPC_MMU_VER_2_06:
-        pa_features = pa_features_206;
-        pa_size = sizeof(pa_features_206);
-        break;
-    case POWERPC_MMU_VER_2_07:
-        pa_features = pa_features_207;
-        pa_size = sizeof(pa_features_207);
-        break;
-    case POWERPC_MMU_VER_3_00:
-        pa_features = pa_features_300;
-        pa_size = sizeof(pa_features_300);
-        break;
-    default:
-        return;
-    }
-
-    if (env->ci_large_pages) {
-        /*
-         * Note: we keep CI large pages off by default because a 64K capable
-         * guest provisioned with large pages might otherwise try to map a qemu
-         * framebuffer (or other kind of memory mapped PCI BAR) using 64K pages
-         * even if that qemu runs on a 4k host.
-         * We dd this bit back here if we are confident this is not an issue
-         */
-        pa_features[3] |= 0x20;
-    }
-    if (kvmppc_has_cap_htm() && pa_size > 24) {
-        pa_features[24] |= 0x80;    /* Transactional memory support */
-    }
-
-    _FDT((fdt_setprop(fdt, offset, "ibm,pa-features", pa_features, pa_size)));
-}
-
 static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
                                   sPAPRMachineState *spapr)
 {
-- 
2.9.3

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

* [Qemu-devel] [PULL 11/47] spapr: Enable ISA 3.0 MMU mode selection via CAS
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (9 preceding siblings ...)
  2017-04-24  1:58 ` [Qemu-devel] [PULL 10/47] spapr: move spapr_populate_pa_features() David Gibson
@ 2017-04-24  1:58 ` David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 12/47] spapr: Workaround for broken radix guests David Gibson
                   ` (37 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:58 UTC (permalink / raw)
  To: peter.maydell
  Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, Sam Bobroff, David Gibson

From: Sam Bobroff <sam.bobroff@au1.ibm.com>

Add the new node, /chosen/ibm,arch-vec-5-platform-support to the
device tree. This allows the guest to determine which modes are
supported by the hypervisor.

Update the option vector processing in h_client_architecture_support()
to handle the new MMU bits. This allows guests to request hash or
radix mode and QEMU to create the guest's HPT at this time if it is
necessary but hasn't yet been done.  QEMU will terminate the guest if
it requests an unavailable mode, as required by the architecture.

Extend the ibm,pa-features node with the new ISA 3.0 values
and set the radix bit if KVM supports radix mode. This probably won't
be used directly by guests to determine the availability of radix mode
(that is indicated by the new node added above) but the architecture
requires that it be set when the hardware supports it.

If QEMU is using KVM, and KVM is capable of running in radix mode,
guests can be run in real-mode without allocating a HPT (because KVM
will use a minimal RPT). So in this case, we avoid creating the HPT
at reset time and later (during CAS) create it if it is necessary.

ISA 3.0 guests will now begin to call h_register_process_table(),
which has been added previously.

Signed-off-by: Sam Bobroff <sam.bobroff@au1.ibm.com>
[dwg: Strip some unneeded prefix from error messages]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr.c              | 71 ++++++++++++++++++++++++++++++++++++---------
 hw/ppc/spapr_hcall.c        | 30 +++++++++++++++++++
 include/hw/ppc/spapr_ovec.h |  5 ++++
 3 files changed, 93 insertions(+), 13 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 21da9a1..d967ec3 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -237,20 +237,31 @@ static void spapr_populate_pa_features(CPUPPCState *env, void *fdt, int offset)
         0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
         0x80, 0x00, 0x80, 0x00, 0x00, 0x00 };
-    /* Currently we don't advertise any of the "new" ISAv3.00 functionality */
-    uint8_t pa_features_300[] = { 64, 0,
-        0xf6, 0x1f, 0xc7, 0xc0, 0x80, 0xf0, /*  0 -  5 */
-        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /*  6 - 11 */
+    uint8_t pa_features_300[] = { 66, 0,
+        /* 0: MMU|FPU|SLB|RUN|DABR|NX, 1: fri[nzpm]|DABRX|SPRG3|SLB0|PP110 */
+        /* 2: VPM|DS205|PPR|DS202|DS206, 3: LSD|URG, SSO, 5: LE|CFAR|EB|LSQ */
+        0xf6, 0x1f, 0xc7, 0xc0, 0x80, 0xf0, /* 0 - 5 */
+        /* 6: DS207 */
+        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 6 - 11 */
+        /* 16: Vector */
         0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 12 - 17 */
-        0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 18 - 23 */
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 24 - 29 */
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 - 35 */
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 36 - 41 */
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 42 - 47 */
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 48 - 53 */
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 54 - 59 */
-        0x00, 0x00, 0x00, 0x00           }; /* 60 - 63 */
-
+        /* 18: Vec. Scalar, 20: Vec. XOR, 22: HTM */
+        0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 18 - 23 */
+        /* 24: Ext. Dec, 26: 64 bit ftrs, 28: PM ftrs */
+        0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 24 - 29 */
+        /* 30: MMR, 32: LE atomic, 34: EBB + ext EBB */
+        0x80, 0x00, 0x80, 0x00, 0xC0, 0x00, /* 30 - 35 */
+        /* 36: SPR SO, 38: Copy/Paste, 40: Radix MMU */
+        0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 36 - 41 */
+        /* 42: PM, 44: PC RA, 46: SC vec'd */
+        0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 42 - 47 */
+        /* 48: SIMD, 50: QP BFP, 52: String */
+        0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 48 - 53 */
+        /* 54: DecFP, 56: DecI, 58: SHA */
+        0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 54 - 59 */
+        /* 60: NM atomic, 62: RNG */
+        0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 60 - 65 */
+    };
     uint8_t *pa_features;
     size_t pa_size;
 
@@ -856,6 +867,33 @@ static void spapr_dt_rtas(sPAPRMachineState *spapr, void *fdt)
     spapr_dt_rtas_tokens(fdt, rtas);
 }
 
+/* Prepare ibm,arch-vec-5-platform-support, which indicates the MMU features
+ * that the guest may request and thus the valid values for bytes 24..26 of
+ * option vector 5: */
+static void spapr_dt_ov5_platform_support(void *fdt, int chosen)
+{
+    char val[2 * 3] = {
+        24, 0x00, /* Hash/Radix, filled in below. */
+        25, 0x00, /* Hash options: Segment Tables == no, GTSE == no. */
+        26, 0x40, /* Radix options: GTSE == yes. */
+    };
+
+    if (kvm_enabled()) {
+        if (kvmppc_has_cap_mmu_radix() && kvmppc_has_cap_mmu_hash_v3()) {
+            val[1] = 0x80; /* OV5_MMU_BOTH */
+        } else if (kvmppc_has_cap_mmu_radix()) {
+            val[1] = 0x40; /* OV5_MMU_RADIX_300 */
+        } else {
+            val[1] = 0x00; /* Hash */
+        }
+    } else {
+        /* TODO: TCG case, hash */
+        val[1] = 0x00;
+    }
+    _FDT(fdt_setprop(fdt, chosen, "ibm,arch-vec-5-platform-support",
+                     val, sizeof(val)));
+}
+
 static void spapr_dt_chosen(sPAPRMachineState *spapr, void *fdt)
 {
     MachineState *machine = MACHINE(spapr);
@@ -909,6 +947,8 @@ static void spapr_dt_chosen(sPAPRMachineState *spapr, void *fdt)
         _FDT(fdt_setprop_string(fdt, chosen, "linux,stdout-path", stdout_path));
     }
 
+    spapr_dt_ov5_platform_support(fdt, chosen);
+
     g_free(stdout_path);
     g_free(bootlist);
 }
@@ -2078,6 +2118,11 @@ static void ppc_spapr_init(MachineState *machine)
     }
 
     spapr_ovec_set(spapr->ov5, OV5_FORM1_AFFINITY);
+    if (kvmppc_has_cap_mmu_radix()) {
+        /* KVM always allows GTSE with radix... */
+        spapr_ovec_set(spapr->ov5, OV5_MMU_RADIX_GTSE);
+    }
+    /* ... but not with hash (currently). */
 
     /* advertise support for dedicated HP event source to guests */
     if (spapr->use_hotplug_event_source) {
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index a958fee..cbd1f29 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1063,6 +1063,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
     uint32_t best_compat = 0;
     int i;
     sPAPROptionVector *ov5_guest, *ov5_cas_old, *ov5_updates;
+    bool guest_radix;
 
     /*
      * We scan the supplied table of PVRs looking for two things
@@ -1114,6 +1115,13 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
     ov_table = list;
 
     ov5_guest = spapr_ovec_parse_vector(ov_table, 5);
+    if (spapr_ovec_test(ov5_guest, OV5_MMU_BOTH)) {
+        error_report("guest requested hash and radix MMU, which is invalid.");
+        exit(EXIT_FAILURE);
+    }
+    /* The radix/hash bit in byte 24 requires special handling: */
+    guest_radix = spapr_ovec_test(ov5_guest, OV5_MMU_RADIX_300);
+    spapr_ovec_clear(ov5_guest, OV5_MMU_RADIX_300);
 
     /* NOTE: there are actually a number of ov5 bits where input from the
      * guest is always zero, and the platform/QEMU enables them independently
@@ -1132,6 +1140,21 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
     ov5_updates = spapr_ovec_new();
     spapr->cas_reboot = spapr_ovec_diff(ov5_updates,
                                         ov5_cas_old, spapr->ov5_cas);
+    /* Now that processing is finished, set the radix/hash bit for the
+     * guest if it requested a valid mode; otherwise terminate the boot. */
+    if (guest_radix) {
+        if (kvm_enabled() && !kvmppc_has_cap_mmu_radix()) {
+            error_report("Guest requested unavailable MMU mode (radix).");
+            exit(EXIT_FAILURE);
+        }
+        spapr_ovec_set(spapr->ov5_cas, OV5_MMU_RADIX_300);
+    } else {
+        if (kvm_enabled() && kvmppc_has_cap_mmu_radix()
+            && !kvmppc_has_cap_mmu_hash_v3()) {
+            error_report("Guest requested unavailable MMU mode (hash).");
+            exit(EXIT_FAILURE);
+        }
+    }
 
     if (!spapr->cas_reboot) {
         spapr->cas_reboot =
@@ -1142,6 +1165,13 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
 
     if (spapr->cas_reboot) {
         qemu_system_reset_request();
+    } else {
+        /* If ppc_spapr_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 & PATBE1_GR) && !guest_radix) {
+            /* legacy hash or new hash: */
+            spapr_setup_hpt_and_vrma(spapr);
+        }
     }
 
     return H_SUCCESS;
diff --git a/include/hw/ppc/spapr_ovec.h b/include/hw/ppc/spapr_ovec.h
index 355a344..f7f2abe 100644
--- a/include/hw/ppc/spapr_ovec.h
+++ b/include/hw/ppc/spapr_ovec.h
@@ -48,6 +48,11 @@ typedef struct sPAPROptionVector sPAPROptionVector;
 #define OV5_FORM1_AFFINITY      OV_BIT(5, 0)
 #define OV5_HP_EVT              OV_BIT(6, 5)
 
+/* ISA 3.00 MMU features: */
+#define OV5_MMU_BOTH            OV_BIT(24, 0) /* Radix and hash */
+#define OV5_MMU_RADIX_300       OV_BIT(24, 1) /* 1=Radix only, 0=Hash only */
+#define OV5_MMU_RADIX_GTSE      OV_BIT(26, 1) /* Radix GTSE */
+
 /* interfaces */
 sPAPROptionVector *spapr_ovec_new(void);
 sPAPROptionVector *spapr_ovec_clone(sPAPROptionVector *ov_orig);
-- 
2.9.3

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

* [Qemu-devel] [PULL 12/47] spapr: Workaround for broken radix guests
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (10 preceding siblings ...)
  2017-04-24  1:58 ` [Qemu-devel] [PULL 11/47] spapr: Enable ISA 3.0 MMU mode selection via CAS David Gibson
@ 2017-04-24  1:58 ` David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 13/47] target-ppc/kvm: Enable in-kernel TCE acceleration for multi-tce David Gibson
                   ` (36 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:58 UTC (permalink / raw)
  To: peter.maydell
  Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, Sam Bobroff, David Gibson

From: Sam Bobroff <sam.bobroff@au1.ibm.com>

For a little while around 4.9, Linux kernels that saw the radix bit in
ibm,pa-features would attempt to set up the MMU as if they were a
hypervisor, even if they were a guest, which would cause them to
crash.

Work around this by detecting pre-ISA 3.0 guests by their lack of that
bit in option vector 1, and then removing the radix bit from
ibm,pa-features. Note: This now requires regeneration of that node
after CAS negotiation.

Signed-off-by: Sam Bobroff <sam.bobroff@au1.ibm.com>
[dwg: Fix style nits]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr.c              | 15 +++++++++++++--
 hw/ppc/spapr_hcall.c        |  6 ++++--
 include/hw/ppc/spapr.h      |  1 +
 include/hw/ppc/spapr_ovec.h |  3 +++
 4 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index d967ec3..a355512 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -228,7 +228,8 @@ static int spapr_fixup_cpu_numa_dt(void *fdt, int offset, CPUState *cs)
 }
 
 /* Populate the "ibm,pa-features" property */
-static void spapr_populate_pa_features(CPUPPCState *env, void *fdt, int offset)
+static void spapr_populate_pa_features(CPUPPCState *env, void *fdt, int offset,
+                                      bool legacy_guest)
 {
     uint8_t pa_features_206[] = { 6, 0,
         0xf6, 0x1f, 0xc7, 0x00, 0x80, 0xc0 };
@@ -295,6 +296,12 @@ static void spapr_populate_pa_features(CPUPPCState *env, void *fdt, int offset)
     if (kvmppc_has_cap_htm() && pa_size > 24) {
         pa_features[24] |= 0x80;    /* Transactional memory support */
     }
+    if (legacy_guest && pa_size > 40) {
+        /* Workaround for broken kernels that attempt (guest) radix
+         * mode when they can't handle it, if they see the radix bit set
+         * in pa-features. So hide it from them. */
+        pa_features[40 + 2] &= ~0x80; /* Radix MMU */
+    }
 
     _FDT((fdt_setprop(fdt, offset, "ibm,pa-features", pa_features, pa_size)));
 }
@@ -309,6 +316,7 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
 
     CPU_FOREACH(cs) {
         PowerPCCPU *cpu = POWERPC_CPU(cs);
+        CPUPPCState *env = &cpu->env;
         DeviceClass *dc = DEVICE_GET_CLASS(cs);
         int index = ppc_get_vcpu_dt_id(cpu);
         int compat_smt = MIN(smp_threads, ppc_compat_max_threads(cpu));
@@ -350,6 +358,9 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
         if (ret < 0) {
             return ret;
         }
+
+        spapr_populate_pa_features(env, fdt, offset,
+                                         spapr->cas_legacy_guest_workaround);
     }
     return ret;
 }
@@ -547,7 +558,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
                           page_sizes_prop, page_sizes_prop_size)));
     }
 
-    spapr_populate_pa_features(env, fdt, offset);
+    spapr_populate_pa_features(env, fdt, offset, false);
 
     _FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id",
                            cs->cpu_index / vcpus_per_socket)));
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index cbd1f29..9f18f75 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1062,7 +1062,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
     uint32_t max_compat = cpu->max_compat;
     uint32_t best_compat = 0;
     int i;
-    sPAPROptionVector *ov5_guest, *ov5_cas_old, *ov5_updates;
+    sPAPROptionVector *ov1_guest, *ov5_guest, *ov5_cas_old, *ov5_updates;
     bool guest_radix;
 
     /*
@@ -1114,6 +1114,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
     /* For the future use: here @ov_table points to the first option vector */
     ov_table = list;
 
+    ov1_guest = spapr_ovec_parse_vector(ov_table, 1);
     ov5_guest = spapr_ovec_parse_vector(ov_table, 5);
     if (spapr_ovec_test(ov5_guest, OV5_MMU_BOTH)) {
         error_report("guest requested hash and radix MMU, which is invalid.");
@@ -1155,7 +1156,8 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
             exit(EXIT_FAILURE);
         }
     }
-
+    spapr->cas_legacy_guest_workaround = !spapr_ovec_test(ov1_guest,
+                                                          OV1_PPC_3_00);
     if (!spapr->cas_reboot) {
         spapr->cas_reboot =
             (spapr_h_cas_compose_response(spapr, args[1], args[2],
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index d234efc..e27de64 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -89,6 +89,7 @@ struct sPAPRMachineState {
     sPAPROptionVector *ov5;         /* QEMU-supported option vectors */
     sPAPROptionVector *ov5_cas;     /* negotiated (via CAS) option vectors */
     bool cas_reboot;
+    bool cas_legacy_guest_workaround;
 
     Notifier epow_notifier;
     QTAILQ_HEAD(, sPAPREventLogEntry) pending_events;
diff --git a/include/hw/ppc/spapr_ovec.h b/include/hw/ppc/spapr_ovec.h
index f7f2abe..f088833 100644
--- a/include/hw/ppc/spapr_ovec.h
+++ b/include/hw/ppc/spapr_ovec.h
@@ -43,6 +43,9 @@ typedef struct sPAPROptionVector sPAPROptionVector;
 
 #define OV_BIT(byte, bit) ((byte - 1) * BITS_PER_BYTE + bit)
 
+/* option vector 1 */
+#define OV1_PPC_3_00            OV_BIT(3, 0) /* guest supports PowerPC 3.00? */
+
 /* option vector 5 */
 #define OV5_DRCONF_MEMORY       OV_BIT(2, 2)
 #define OV5_FORM1_AFFINITY      OV_BIT(5, 0)
-- 
2.9.3

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

* [Qemu-devel] [PULL 13/47] target-ppc/kvm: Enable in-kernel TCE acceleration for multi-tce
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (11 preceding siblings ...)
  2017-04-24  1:58 ` [Qemu-devel] [PULL 12/47] spapr: Workaround for broken radix guests David Gibson
@ 2017-04-24  1:58 ` David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 14/47] spapr_pci: Warn when RAM page size is not enabled in IOMMU page mask David Gibson
                   ` (35 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:58 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

From: Alexey Kardashevskiy <aik@ozlabs.ru>

This enables in-kernel handling of H_PUT_TCE_INDIRECT and
H_STUFF_TCE hypercalls. The host kernel support is there since v4.6,
in particular d3695aa4f452
("KVM: PPC: Add support for multiple-TCE hcalls").

H_PUT_TCE is already accelerated and does not need any special enablement.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr.c       |  4 +++-
 target/ppc/kvm.c     | 14 ++++++++++++++
 target/ppc/kvm_ppc.h |  6 ++++++
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index a355512..8749f1b 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2361,10 +2361,12 @@ static void ppc_spapr_init(MachineState *machine)
 
     qemu_register_boot_set(spapr_boot_set, spapr);
 
-    /* to stop and start vmclock */
     if (kvm_enabled()) {
+        /* to stop and start vmclock */
         qemu_add_vm_change_state_handler(cpu_ppc_clock_vm_state_change,
                                          &spapr->tb);
+
+        kvmppc_spapr_enable_inkernel_multitce();
     }
 }
 
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index c959b90..8574c36 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -2198,6 +2198,20 @@ bool kvmppc_spapr_use_multitce(void)
     return cap_spapr_multitce;
 }
 
+int kvmppc_spapr_enable_inkernel_multitce(void)
+{
+    int ret;
+
+    ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_PPC_ENABLE_HCALL, 0,
+                            H_PUT_TCE_INDIRECT, 1);
+    if (!ret) {
+        ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_PPC_ENABLE_HCALL, 0,
+                                H_STUFF_TCE, 1);
+    }
+
+    return ret;
+}
+
 void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t page_shift,
                               uint64_t bus_offset, uint32_t nb_table,
                               int *pfd, bool need_vfio)
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
index 4b2fd9a..f48243d 100644
--- a/target/ppc/kvm_ppc.h
+++ b/target/ppc/kvm_ppc.h
@@ -39,6 +39,7 @@ target_ulong kvmppc_configure_v3_mmu(PowerPCCPU *cpu,
 #ifndef CONFIG_USER_ONLY
 off_t kvmppc_alloc_rma(void **rma);
 bool kvmppc_spapr_use_multitce(void);
+int kvmppc_spapr_enable_inkernel_multitce(void);
 void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t page_shift,
                               uint64_t bus_offset, uint32_t nb_table,
                               int *pfd, bool need_vfio);
@@ -180,6 +181,11 @@ static inline bool kvmppc_spapr_use_multitce(void)
     return false;
 }
 
+static inline int kvmppc_spapr_enable_inkernel_multitce(void)
+{
+    return -1;
+}
+
 static inline void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t page_shift,
                                             uint64_t bus_offset,
                                             uint32_t nb_table,
-- 
2.9.3

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

* [Qemu-devel] [PULL 14/47] spapr_pci: Warn when RAM page size is not enabled in IOMMU page mask
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (12 preceding siblings ...)
  2017-04-24  1:58 ` [Qemu-devel] [PULL 13/47] target-ppc/kvm: Enable in-kernel TCE acceleration for multi-tce David Gibson
@ 2017-04-24  1:58 ` David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 15/47] spapr_pci: Removed unused include David Gibson
                   ` (34 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:58 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

From: Alexey Kardashevskiy <aik@ozlabs.ru>

If a page size used by QEMU is not enabled in the PHB IOMMU page mask,
in-kernel acceleration of TCE handling won't be enabled and performance
might be slower than expected.

This prints a warning if system page size is not enabled. This should
print a warning if huge pages are enabled but sphb.pgsz still uses
the default value of 4K|64K.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_pci.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 98c52e4..097ebdd 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1771,6 +1771,12 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
     }
 
     /* DMA setup */
+    if ((sphb->page_size_mask & qemu_getrampagesize()) == 0) {
+        error_report("System page size 0x%lx is not enabled in page_size_mask "
+                     "(0x%"PRIx64"). Performance may be slow",
+                     qemu_getrampagesize(), sphb->page_size_mask);
+    }
+
     for (i = 0; i < windows_supported; ++i) {
         tcet = spapr_tce_new_table(DEVICE(sphb), sphb->dma_liobn[i]);
         if (!tcet) {
-- 
2.9.3

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

* [Qemu-devel] [PULL 15/47] spapr_pci: Removed unused include
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (13 preceding siblings ...)
  2017-04-24  1:58 ` [Qemu-devel] [PULL 14/47] spapr_pci: Warn when RAM page size is not enabled in IOMMU page mask David Gibson
@ 2017-04-24  1:58 ` David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 16/47] target/ppc: Add ibm, processor-radix-AP-encodings for TCG David Gibson
                   ` (33 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:58 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

From: Alexey Kardashevskiy <aik@ozlabs.ru>

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_pci.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 097ebdd..e7567e2 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -50,8 +50,6 @@
 #include "sysemu/hostmem.h"
 #include "sysemu/numa.h"
 
-#include "hw/vfio/vfio.h"
-
 /* Copied from the kernel arch/powerpc/platforms/pseries/msi.c */
 #define RTAS_QUERY_FN           0
 #define RTAS_CHANGE_FN          1
-- 
2.9.3

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

* [Qemu-devel] [PULL 16/47] target/ppc: Add ibm, processor-radix-AP-encodings for TCG
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (14 preceding siblings ...)
  2017-04-24  1:58 ` [Qemu-devel] [PULL 15/47] spapr_pci: Removed unused include David Gibson
@ 2017-04-24  1:58 ` David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 17/47] ppc/xics: introduce an 'intc' backlink under PowerPCCPU David Gibson
                   ` (32 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:58 UTC (permalink / raw)
  To: peter.maydell
  Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg,
	Suraj Jitindar Singh, David Gibson

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

The ibm,processor-radix-AP-encodings device tree property of the cpu node
is used to specify the radix mode supported page sizes of the processor
to the guest os. Contained in the top 3 bits of the msb is the actual
page size (AP) encoding associated with the corresponding radix mode
supported page size. Add this property for a TCG guest, note the TCG code
is capable of translating any format so just add the 4 default page sizes.

The ibm,processor-radix-AP-encodings device tree property is defined as:
One to n cells in ascending order of radix mode supported page sizes
encoded as BE ints (32bit on ppc) in the form:
0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
- 0bxxx -> AP encoding
- 0byyyyyyyyyyyyyyyyyyyyyyyyyyyyy -> supported page size encoded as a shift

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/translate_init.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index c1a9014..aa0c44d 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -8808,6 +8808,25 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
     pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
 }
 
+#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 POWER9_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_POWER9(CPUPPCState *env)
 {
     /* Common Registers */
@@ -8959,6 +8978,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
     pcc->handle_mmu_fault = ppc64_v3_handle_mmu_fault;
     /* segment page size remain the same */
     pcc->sps = &POWER7_POWER8_sps;
+    pcc->radix_page_info = &POWER9_radix_page_info;
 #endif
     pcc->excp_model = POWERPC_EXCP_POWER8;
     pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
-- 
2.9.3

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

* [Qemu-devel] [PULL 17/47] ppc/xics: introduce an 'intc' backlink under PowerPCCPU
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (15 preceding siblings ...)
  2017-04-24  1:58 ` [Qemu-devel] [PULL 16/47] target/ppc: Add ibm, processor-radix-AP-encodings for TCG David Gibson
@ 2017-04-24  1:58 ` David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 18/47] spapr: move the IRQ server number mapping under the machine David Gibson
                   ` (31 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:58 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

Today, the ICPState array of the sPAPR machine is indexed with
'cpu_index' of the CPUState. This numbering of CPUs is internal to
QEMU and the guest only knows about what is exposed in the device
tree, that is the 'cpu_dt_id'. This is why sPAPR uses the helper
xics_get_cpu_index_by_dt_id() to do the mapping in a couple of places.

To provide a more generic XICS layer, we need to abstract the IRQ
'server' number and remove any assumption made on its nature. It
should not be used as a 'cpu_index' for lookups like xics_cpu_setup()
and xics_cpu_destroy() do.

To reach that goal, we choose to introduce a generic 'intc' backlink
under PowerPCCPU, and let the machine core init routine do the
ICPState lookup. The resulting object is passed on to xics_cpu_setup()
which does the store under PowerPCCPU. The IRQ 'server' number in XICS
is now generic. sPAPR uses 'cpu_dt_id' and PowerNV will use 'PIR'
number.

This also has the benefit of simplifying the sPAPR hcall routines
which do not need to do any ICPState lookups anymore.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/xics.c          |  6 +++---
 hw/intc/xics_spapr.c    | 20 +++++---------------
 hw/ppc/spapr_cpu_core.c |  4 +++-
 include/hw/ppc/xics.h   |  2 +-
 target/ppc/cpu.h        |  1 +
 5 files changed, 13 insertions(+), 20 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index e740989..56fe70c 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -52,7 +52,7 @@ int xics_get_cpu_index_by_dt_id(int cpu_dt_id)
 void xics_cpu_destroy(XICSFabric *xi, PowerPCCPU *cpu)
 {
     CPUState *cs = CPU(cpu);
-    ICPState *icp = xics_icp_get(xi, cs->cpu_index);
+    ICPState *icp = ICP(cpu->intc);
 
     assert(icp);
     assert(cs == icp->cs);
@@ -61,15 +61,15 @@ void xics_cpu_destroy(XICSFabric *xi, PowerPCCPU *cpu)
     icp->cs = NULL;
 }
 
-void xics_cpu_setup(XICSFabric *xi, PowerPCCPU *cpu)
+void xics_cpu_setup(XICSFabric *xi, PowerPCCPU *cpu, ICPState *icp)
 {
     CPUState *cs = CPU(cpu);
     CPUPPCState *env = &cpu->env;
-    ICPState *icp = xics_icp_get(xi, cs->cpu_index);
     ICPStateClass *icpc;
 
     assert(icp);
 
+    cpu->intc = OBJECT(icp);
     icp->cs = cs;
 
     icpc = ICP_GET_CLASS(icp);
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 84d24b2..58f100d 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -43,11 +43,9 @@
 static target_ulong h_cppr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                            target_ulong opcode, target_ulong *args)
 {
-    CPUState *cs = CPU(cpu);
-    ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), cs->cpu_index);
     target_ulong cppr = args[0];
 
-    icp_set_cppr(icp, cppr);
+    icp_set_cppr(ICP(cpu->intc), cppr);
     return H_SUCCESS;
 }
 
@@ -69,9 +67,7 @@ static target_ulong h_ipi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
 static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                            target_ulong opcode, target_ulong *args)
 {
-    CPUState *cs = CPU(cpu);
-    ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), cs->cpu_index);
-    uint32_t xirr = icp_accept(icp);
+    uint32_t xirr = icp_accept(ICP(cpu->intc));
 
     args[0] = xirr;
     return H_SUCCESS;
@@ -80,9 +76,7 @@ static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
 static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                              target_ulong opcode, target_ulong *args)
 {
-    CPUState *cs = CPU(cpu);
-    ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), cs->cpu_index);
-    uint32_t xirr = icp_accept(icp);
+    uint32_t xirr = icp_accept(ICP(cpu->intc));
 
     args[0] = xirr;
     args[1] = cpu_get_host_ticks();
@@ -92,21 +86,17 @@ static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPRMachineState *spapr,
 static target_ulong h_eoi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                           target_ulong opcode, target_ulong *args)
 {
-    CPUState *cs = CPU(cpu);
-    ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), cs->cpu_index);
     target_ulong xirr = args[0];
 
-    icp_eoi(icp, xirr);
+    icp_eoi(ICP(cpu->intc), xirr);
     return H_SUCCESS;
 }
 
 static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                             target_ulong opcode, target_ulong *args)
 {
-    CPUState *cs = CPU(cpu);
-    ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), cs->cpu_index);
     uint32_t mfrr;
-    uint32_t xirr = icp_ipoll(icp, &mfrr);
+    uint32_t xirr = icp_ipoll(ICP(cpu->intc), &mfrr);
 
     args[0] = xirr;
     args[1] = mfrr;
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 6883f09..7db61bd 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -63,6 +63,8 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu,
                            Error **errp)
 {
     CPUPPCState *env = &cpu->env;
+    XICSFabric *xi = XICS_FABRIC(spapr);
+    ICPState *icp = xics_icp_get(xi, CPU(cpu)->cpu_index);
 
     /* Set time-base frequency to 512 MHz */
     cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ);
@@ -80,7 +82,7 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu,
         }
     }
 
-    xics_cpu_setup(XICS_FABRIC(spapr), cpu);
+    xics_cpu_setup(xi, cpu, icp);
 
     qemu_register_reset(spapr_cpu_reset, cpu);
     spapr_cpu_reset(cpu);
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index ce23018..b97d30b 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -168,7 +168,7 @@ void spapr_dt_xics(int nr_servers, void *fdt, uint32_t phandle);
 
 qemu_irq xics_get_qirq(XICSFabric *xi, int irq);
 ICPState *xics_icp_get(XICSFabric *xi, int server);
-void xics_cpu_setup(XICSFabric *xi, PowerPCCPU *cpu);
+void xics_cpu_setup(XICSFabric *xi, PowerPCCPU *cpu, ICPState *icp);
 void xics_cpu_destroy(XICSFabric *xi, PowerPCCPU *cpu);
 
 /* Internal XICS interfaces */
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index cacdd0a..e0ff041 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1200,6 +1200,7 @@ struct PowerPCCPU {
     uint32_t max_compat;
     uint32_t compat_pvr;
     PPCVirtualHypervisor *vhyp;
+    Object *intc;
 
     /* Fields related to migration compatibility hacks */
     bool pre_2_8_migration;
-- 
2.9.3

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

* [Qemu-devel] [PULL 18/47] spapr: move the IRQ server number mapping under the machine
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (16 preceding siblings ...)
  2017-04-24  1:58 ` [Qemu-devel] [PULL 17/47] ppc/xics: introduce an 'intc' backlink under PowerPCCPU David Gibson
@ 2017-04-24  1:58 ` David Gibson
  2017-04-24  1:58 ` [Qemu-devel] [PULL 19/47] spapr: allocate the ICPState object from under sPAPRCPUCore David Gibson
                   ` (30 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:58 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

This is the second step to abstract the IRQ 'server' number of the
XICS layer. Now that the prereq cleanups have been done in the
previous patch, we can move down the 'cpu_dt_id' to 'cpu_index'
mapping in the sPAPR machine handler.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/xics_spapr.c    | 5 ++---
 hw/ppc/spapr.c          | 3 ++-
 hw/ppc/spapr_cpu_core.c | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 58f100d..f05308b8 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -52,9 +52,8 @@ static target_ulong h_cppr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
 static target_ulong h_ipi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                           target_ulong opcode, target_ulong *args)
 {
-    target_ulong server = xics_get_cpu_index_by_dt_id(args[0]);
     target_ulong mfrr = args[1];
-    ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), server);
+    ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), args[0]);
 
     if (!icp) {
         return H_PARAMETER;
@@ -122,7 +121,7 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
     }
 
     nr = rtas_ld(args, 0);
-    server = xics_get_cpu_index_by_dt_id(rtas_ld(args, 1));
+    server = rtas_ld(args, 1);
     priority = rtas_ld(args, 2);
 
     if (!ics_valid_irq(ics, nr) || !xics_icp_get(XICS_FABRIC(spapr), server)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 8749f1b..08f8615 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3112,9 +3112,10 @@ static void spapr_ics_resend(XICSFabric *dev)
     ics_resend(spapr->ics);
 }
 
-static ICPState *spapr_icp_get(XICSFabric *xi, int server)
+static ICPState *spapr_icp_get(XICSFabric *xi, int cpu_dt_id)
 {
     sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
+    int server = xics_get_cpu_index_by_dt_id(cpu_dt_id);
 
     return (server < spapr->nr_servers) ? &spapr->icps[server] : NULL;
 }
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 7db61bd..4e1a995 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -64,7 +64,7 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu,
 {
     CPUPPCState *env = &cpu->env;
     XICSFabric *xi = XICS_FABRIC(spapr);
-    ICPState *icp = xics_icp_get(xi, CPU(cpu)->cpu_index);
+    ICPState *icp = xics_icp_get(xi, cpu->cpu_dt_id);
 
     /* Set time-base frequency to 512 MHz */
     cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ);
-- 
2.9.3

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

* [Qemu-devel] [PULL 19/47] spapr: allocate the ICPState object from under sPAPRCPUCore
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (17 preceding siblings ...)
  2017-04-24  1:58 ` [Qemu-devel] [PULL 18/47] spapr: move the IRQ server number mapping under the machine David Gibson
@ 2017-04-24  1:58 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 20/47] ppc/xics: add a realize() handler to ICPStateClass David Gibson
                   ` (29 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:58 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

Today, all the ICPs are created before the CPUs, stored in an array
under the sPAPR machine and linked to the CPU when the core threads
are realized. This modeling brings some complexity when a lookup in
the array is required and it can be simplified by allocating the ICPs
when the CPUs are.

This is the purpose of this proposal which introduces a new 'icp_type'
field under the machine and creates the ICP objects of the right type
(KVM or not) before the PowerPCCPU object are.

This change allows more cleanups : the removal of the icps array under
the sPAPR machine and the removal of the xics_get_cpu_index_by_dt_id()
helper.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/xics.c          | 11 -----------
 hw/ppc/spapr.c          | 47 ++++++++++++++---------------------------------
 hw/ppc/spapr_cpu_core.c | 18 ++++++++++++++----
 include/hw/ppc/spapr.h  |  2 +-
 include/hw/ppc/xics.h   |  2 --
 5 files changed, 29 insertions(+), 51 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 56fe70c..d4428b4 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -38,17 +38,6 @@
 #include "monitor/monitor.h"
 #include "hw/intc/intc.h"
 
-int xics_get_cpu_index_by_dt_id(int cpu_dt_id)
-{
-    PowerPCCPU *cpu = ppc_get_vcpu_by_dt_id(cpu_dt_id);
-
-    if (cpu) {
-        return cpu->parent_obj.cpu_index;
-    }
-
-    return -1;
-}
-
 void xics_cpu_destroy(XICSFabric *xi, PowerPCCPU *cpu)
 {
     CPUState *cs = CPU(cpu);
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 08f8615..703b14a 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -104,7 +104,6 @@ static int try_create_xics(sPAPRMachineState *spapr, const char *type_ics,
     XICSFabric *xi = XICS_FABRIC(spapr);
     Error *err = NULL, *local_err = NULL;
     ICSState *ics = NULL;
-    int i;
 
     ics = ICS_SIMPLE(object_new(type_ics));
     object_property_add_child(OBJECT(spapr), "ics", OBJECT(ics), NULL);
@@ -113,34 +112,14 @@ static int try_create_xics(sPAPRMachineState *spapr, const char *type_ics,
     object_property_set_bool(OBJECT(ics), true, "realized", &local_err);
     error_propagate(&err, local_err);
     if (err) {
-        goto error;
+        error_propagate(errp, err);
+        return -1;
     }
 
-    spapr->icps = g_malloc0(nr_servers * sizeof(ICPState));
     spapr->nr_servers = nr_servers;
-
-    for (i = 0; i < nr_servers; i++) {
-        ICPState *icp = &spapr->icps[i];
-
-        object_initialize(icp, sizeof(*icp), type_icp);
-        object_property_add_child(OBJECT(spapr), "icp[*]", OBJECT(icp), NULL);
-        object_property_add_const_link(OBJECT(icp), "xics", OBJECT(xi), NULL);
-        object_property_set_bool(OBJECT(icp), true, "realized", &err);
-        if (err) {
-            goto error;
-        }
-        object_unref(OBJECT(icp));
-    }
-
     spapr->ics = ics;
+    spapr->icp_type = type_icp;
     return 0;
-
-error:
-    error_propagate(errp, err);
-    if (ics) {
-        object_unparent(OBJECT(ics));
-    }
-    return -1;
 }
 
 static int xics_system_init(MachineState *machine,
@@ -1441,9 +1420,10 @@ static int spapr_post_load(void *opaque, int version_id)
     int err = 0;
 
     if (!object_dynamic_cast(OBJECT(spapr->ics), TYPE_ICS_KVM)) {
-        int i;
-        for (i = 0; i < spapr->nr_servers; i++) {
-            icp_resend(&spapr->icps[i]);
+        CPUState *cs;
+        CPU_FOREACH(cs) {
+            PowerPCCPU *cpu = POWERPC_CPU(cs);
+            icp_resend(ICP(cpu->intc));
         }
     }
 
@@ -3114,20 +3094,21 @@ static void spapr_ics_resend(XICSFabric *dev)
 
 static ICPState *spapr_icp_get(XICSFabric *xi, int cpu_dt_id)
 {
-    sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
-    int server = xics_get_cpu_index_by_dt_id(cpu_dt_id);
+    PowerPCCPU *cpu = ppc_get_vcpu_by_dt_id(cpu_dt_id);
 
-    return (server < spapr->nr_servers) ? &spapr->icps[server] : NULL;
+    return cpu ? ICP(cpu->intc) : NULL;
 }
 
 static void spapr_pic_print_info(InterruptStatsProvider *obj,
                                  Monitor *mon)
 {
     sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
-    int i;
+    CPUState *cs;
+
+    CPU_FOREACH(cs) {
+        PowerPCCPU *cpu = POWERPC_CPU(cs);
 
-    for (i = 0; i < spapr->nr_servers; i++) {
-        icp_pic_print_info(&spapr->icps[i], mon);
+        icp_pic_print_info(ICP(cpu->intc), mon);
     }
 
     ics_pic_print_info(spapr->ics, mon);
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 4e1a995..2e689b5 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -63,8 +63,6 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu,
                            Error **errp)
 {
     CPUPPCState *env = &cpu->env;
-    XICSFabric *xi = XICS_FABRIC(spapr);
-    ICPState *icp = xics_icp_get(xi, cpu->cpu_dt_id);
 
     /* Set time-base frequency to 512 MHz */
     cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ);
@@ -82,8 +80,6 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu,
         }
     }
 
-    xics_cpu_setup(xi, cpu, icp);
-
     qemu_register_reset(spapr_cpu_reset, cpu);
     spapr_cpu_reset(cpu);
 }
@@ -143,18 +139,32 @@ static void spapr_cpu_core_realize_child(Object *child, Error **errp)
     sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
     CPUState *cs = CPU(child);
     PowerPCCPU *cpu = POWERPC_CPU(cs);
+    Object *obj;
+
+    obj = object_new(spapr->icp_type);
+    object_property_add_child(OBJECT(cpu), "icp", obj, NULL);
+    object_property_add_const_link(obj, "xics", OBJECT(spapr), &error_abort);
+    object_property_set_bool(obj, true, "realized", &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
 
     object_property_set_bool(child, true, "realized", &local_err);
     if (local_err) {
+        object_unparent(obj);
         error_propagate(errp, local_err);
         return;
     }
 
     spapr_cpu_init(spapr, cpu, &local_err);
     if (local_err) {
+        object_unparent(obj);
         error_propagate(errp, local_err);
         return;
     }
+
+    xics_cpu_setup(XICS_FABRIC(spapr), cpu, ICP(obj));
 }
 
 static void spapr_cpu_core_realize(DeviceState *dev, Error **errp)
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index e27de64..7dbba57 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -109,7 +109,7 @@ struct sPAPRMachineState {
     MemoryHotplugState hotplug_memory;
 
     uint32_t nr_servers;
-    ICPState *icps;
+    const char *icp_type;
 };
 
 #define H_SUCCESS         0
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index b97d30b..b07f56f 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -172,8 +172,6 @@ void xics_cpu_setup(XICSFabric *xi, PowerPCCPU *cpu, ICPState *icp);
 void xics_cpu_destroy(XICSFabric *xi, PowerPCCPU *cpu);
 
 /* Internal XICS interfaces */
-int xics_get_cpu_index_by_dt_id(int cpu_dt_id);
-
 void icp_set_cppr(ICPState *icp, uint8_t cppr);
 void icp_set_mfrr(ICPState *icp, uint8_t mfrr);
 uint32_t icp_accept(ICPState *ss);
-- 
2.9.3

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

* [Qemu-devel] [PULL 20/47] ppc/xics: add a realize() handler to ICPStateClass
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (18 preceding siblings ...)
  2017-04-24  1:58 ` [Qemu-devel] [PULL 19/47] spapr: allocate the ICPState object from under sPAPRCPUCore David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 21/47] ppc/pnv: add a PnvICPState object David Gibson
                   ` (28 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

It will be used by derived classes in PowerNV for customization.

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

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index d4428b4..292fffe 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -337,6 +337,7 @@ static void icp_reset(void *dev)
 static void icp_realize(DeviceState *dev, Error **errp)
 {
     ICPState *icp = ICP(dev);
+    ICPStateClass *icpc = ICP_GET_CLASS(dev);
     Object *obj;
     Error *err = NULL;
 
@@ -349,6 +350,10 @@ static void icp_realize(DeviceState *dev, Error **errp)
 
     icp->xics = XICS_FABRIC(obj);
 
+    if (icpc->realize) {
+        icpc->realize(dev, errp);
+    }
+
     qemu_register_reset(icp_reset, dev);
 }
 
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index b07f56f..731e177 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -60,6 +60,7 @@ typedef struct XICSFabric XICSFabric;
 struct ICPStateClass {
     DeviceClass parent_class;
 
+    void (*realize)(DeviceState *dev, Error **errp);
     void (*pre_save)(ICPState *s);
     int (*post_load)(ICPState *s, int version_id);
     void (*cpu_setup)(ICPState *icp, PowerPCCPU *cpu);
-- 
2.9.3

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

* [Qemu-devel] [PULL 21/47] ppc/pnv: add a PnvICPState object
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (19 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 20/47] ppc/xics: add a realize() handler to ICPStateClass David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 22/47] ppc/pnv: extend the machine with a XICSFabric interface David Gibson
                   ` (27 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

This provides a new ICPState object for the PowerNV machine (POWER8).
Access to the Interrupt Management area is done though a memory
region. It contains the registers of the Interrupt Control Presenters
of each thread which are used to accept, return, forward interrupts in
the system.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intc/Makefile.objs |   1 +
 hw/intc/xics_pnv.c    | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/xics.h |  12 ++++
 3 files changed, 205 insertions(+)
 create mode 100644 hw/intc/xics_pnv.c

diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index adedd0d..78426a7 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -35,6 +35,7 @@ obj-$(CONFIG_SH4) += sh_intc.o
 obj-$(CONFIG_XICS) += xics.o
 obj-$(CONFIG_XICS_SPAPR) += xics_spapr.o
 obj-$(CONFIG_XICS_KVM) += xics_kvm.o
+obj-$(CONFIG_POWERNV) += xics_pnv.o
 obj-$(CONFIG_ALLWINNER_A10_PIC) += allwinner-a10-pic.o
 obj-$(CONFIG_S390_FLIC) += s390_flic.o
 obj-$(CONFIG_S390_FLIC_KVM) += s390_flic_kvm.o
diff --git a/hw/intc/xics_pnv.c b/hw/intc/xics_pnv.c
new file mode 100644
index 0000000..12ae605
--- /dev/null
+++ b/hw/intc/xics_pnv.c
@@ -0,0 +1,192 @@
+/*
+ * QEMU PowerPC PowerNV Interrupt Control Presenter (ICP) model
+ *
+ * Copyright (c) 2017, IBM Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "sysemu/sysemu.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "hw/ppc/xics.h"
+
+#define ICP_XIRR_POLL    0 /* 1 byte (CPRR) or 4 bytes */
+#define ICP_XIRR         4 /* 1 byte (CPRR) or 4 bytes */
+#define ICP_MFRR        12 /* 1 byte access only */
+
+#define ICP_LINKA       16 /* unused */
+#define ICP_LINKB       20 /* unused */
+#define ICP_LINKC       24 /* unused */
+
+static uint64_t pnv_icp_read(void *opaque, hwaddr addr, unsigned width)
+{
+    ICPState *icp = ICP(opaque);
+    PnvICPState *picp = PNV_ICP(opaque);
+    bool byte0 = (width == 1 && (addr & 0x3) == 0);
+    uint64_t val = 0xffffffff;
+
+    switch (addr & 0xffc) {
+    case ICP_XIRR_POLL:
+        val = icp_ipoll(icp, NULL);
+        if (byte0) {
+            val >>= 24;
+        } else if (width != 4) {
+            goto bad_access;
+        }
+        break;
+    case ICP_XIRR:
+        if (byte0) {
+            val = icp_ipoll(icp, NULL) >> 24;
+        } else if (width == 4) {
+            val = icp_accept(icp);
+        } else {
+            goto bad_access;
+        }
+        break;
+    case ICP_MFRR:
+        if (byte0) {
+            val = icp->mfrr;
+        } else {
+            goto bad_access;
+        }
+        break;
+    case ICP_LINKA:
+        if (width == 4) {
+            val = picp->links[0];
+        } else {
+            goto bad_access;
+        }
+        break;
+    case ICP_LINKB:
+        if (width == 4) {
+            val = picp->links[1];
+        } else {
+            goto bad_access;
+        }
+        break;
+    case ICP_LINKC:
+        if (width == 4) {
+            val = picp->links[2];
+        } else {
+            goto bad_access;
+        }
+        break;
+    default:
+bad_access:
+        qemu_log_mask(LOG_GUEST_ERROR, "XICS: Bad ICP access 0x%"
+                      HWADDR_PRIx"/%d\n", addr, width);
+    }
+
+    return val;
+}
+
+static void pnv_icp_write(void *opaque, hwaddr addr, uint64_t val,
+                              unsigned width)
+{
+    ICPState *icp = ICP(opaque);
+    PnvICPState *picp = PNV_ICP(opaque);
+    bool byte0 = (width == 1 && (addr & 0x3) == 0);
+
+    switch (addr & 0xffc) {
+    case ICP_XIRR:
+        if (byte0) {
+            icp_set_cppr(icp, val);
+        } else if (width == 4) {
+            icp_eoi(icp, val);
+        } else {
+            goto bad_access;
+        }
+        break;
+    case ICP_MFRR:
+        if (byte0) {
+            icp_set_mfrr(icp, val);
+        } else {
+            goto bad_access;
+        }
+        break;
+    case ICP_LINKA:
+        if (width == 4) {
+            picp->links[0] = val;
+        } else {
+            goto bad_access;
+        }
+        break;
+    case ICP_LINKB:
+        if (width == 4) {
+            picp->links[1] = val;
+        } else {
+            goto bad_access;
+        }
+        break;
+    case ICP_LINKC:
+        if (width == 4) {
+            picp->links[2] = val;
+        } else {
+            goto bad_access;
+        }
+        break;
+    default:
+bad_access:
+        qemu_log_mask(LOG_GUEST_ERROR, "XICS: Bad ICP access 0x%"
+                      HWADDR_PRIx"/%d\n", addr, width);
+    }
+}
+
+static const MemoryRegionOps pnv_icp_ops = {
+    .read = pnv_icp_read,
+    .write = pnv_icp_write,
+    .endianness = DEVICE_BIG_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 4,
+    },
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 4,
+    },
+};
+
+static void pnv_icp_realize(DeviceState *dev, Error **errp)
+{
+    PnvICPState *icp = PNV_ICP(dev);
+
+    memory_region_init_io(&icp->mmio, OBJECT(dev), &pnv_icp_ops,
+                          icp, "icp-thread", 0x1000);
+}
+
+static void pnv_icp_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    ICPStateClass *icpc = ICP_CLASS(klass);
+
+    icpc->realize = pnv_icp_realize;
+    dc->desc = "PowerNV ICP";
+}
+
+static const TypeInfo pnv_icp_info = {
+    .name          = TYPE_PNV_ICP,
+    .parent        = TYPE_ICP,
+    .instance_size = sizeof(PnvICPState),
+    .class_init    = pnv_icp_class_init,
+    .class_size    = sizeof(ICPStateClass),
+};
+
+static void pnv_icp_register_types(void)
+{
+    type_register_static(&pnv_icp_info);
+}
+
+type_init(pnv_icp_register_types)
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 731e177..c215dc7 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -41,10 +41,12 @@
  */
 typedef struct ICPStateClass ICPStateClass;
 typedef struct ICPState ICPState;
+typedef struct PnvICPState PnvICPState;
 typedef struct ICSStateClass ICSStateClass;
 typedef struct ICSState ICSState;
 typedef struct ICSIRQState ICSIRQState;
 typedef struct XICSFabric XICSFabric;
+typedef struct PowerPCCPU PowerPCCPU;
 
 #define TYPE_ICP "icp"
 #define ICP(obj) OBJECT_CHECK(ICPState, (obj), TYPE_ICP)
@@ -52,6 +54,9 @@ typedef struct XICSFabric XICSFabric;
 #define TYPE_KVM_ICP "icp-kvm"
 #define KVM_ICP(obj) OBJECT_CHECK(ICPState, (obj), TYPE_KVM_ICP)
 
+#define TYPE_PNV_ICP "pnv-icp"
+#define PNV_ICP(obj) OBJECT_CHECK(PnvICPState, (obj), TYPE_PNV_ICP)
+
 #define ICP_CLASS(klass) \
      OBJECT_CLASS_CHECK(ICPStateClass, (klass), TYPE_ICP)
 #define ICP_GET_CLASS(obj) \
@@ -81,6 +86,13 @@ struct ICPState {
     XICSFabric *xics;
 };
 
+struct PnvICPState {
+    ICPState parent_obj;
+
+    MemoryRegion mmio;
+    uint32_t links[3];
+};
+
 #define TYPE_ICS_BASE "ics-base"
 #define ICS_BASE(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_BASE)
 
-- 
2.9.3

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

* [Qemu-devel] [PULL 22/47] ppc/pnv: extend the machine with a XICSFabric interface
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (20 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 21/47] ppc/pnv: add a PnvICPState object David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 23/47] ppc/pnv: extend the machine with a InterruptStatsProvider interface David Gibson
                   ` (26 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

A XICSFabric QOM interface is used by the XICS layer to manipulate the
ICP and ICS objects. Let's define the associated handlers for the
PowerNV machine. All handlers should be defined even if there is no
ICS under the PowerNV machine yet.

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

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index aad7917..0a0cfe3 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -34,6 +34,7 @@
 #include "qemu/cutils.h"
 #include "qapi/visitor.h"
 
+#include "hw/ppc/xics.h"
 #include "hw/ppc/pnv_xscom.h"
 
 #include "hw/isa/isa.h"
@@ -738,6 +739,29 @@ static const TypeInfo pnv_chip_info = {
     .abstract      = true,
 };
 
+static 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) {
+            return cpu;
+        }
+    }
+
+    return NULL;
+}
+
+static ICPState *pnv_icp_get(XICSFabric *xi, int pir)
+{
+    PowerPCCPU *cpu = ppc_get_vcpu_by_pir(pir);
+
+    return cpu ? ICP(cpu->intc) : NULL;
+}
+
 static void pnv_get_num_chips(Object *obj, Visitor *v, const char *name,
                               void *opaque, Error **errp)
 {
@@ -788,6 +812,7 @@ static void powernv_machine_class_props_init(ObjectClass *oc)
 static void powernv_machine_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
+    XICSFabricClass *xic = XICS_FABRIC_CLASS(oc);
 
     mc->desc = "IBM PowerNV (Non-Virtualized)";
     mc->init = ppc_powernv_init;
@@ -798,6 +823,7 @@ static void powernv_machine_class_init(ObjectClass *oc, void *data)
     mc->no_parallel = 1;
     mc->default_boot_order = NULL;
     mc->default_ram_size = 1 * G_BYTE;
+    xic->icp_get = pnv_icp_get;
 
     powernv_machine_class_props_init(oc);
 }
@@ -808,6 +834,10 @@ static const TypeInfo powernv_machine_info = {
     .instance_size = sizeof(PnvMachineState),
     .instance_init = powernv_machine_initfn,
     .class_init    = powernv_machine_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_XICS_FABRIC },
+        { },
+    },
 };
 
 static void powernv_machine_register_types(void)
-- 
2.9.3

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

* [Qemu-devel] [PULL 23/47] ppc/pnv: extend the machine with a InterruptStatsProvider interface
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (21 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 22/47] ppc/pnv: extend the machine with a XICSFabric interface David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 24/47] ppc/pnv: create the ICP object under PnvCore David Gibson
                   ` (25 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

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

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 0a0cfe3..f3623ee 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -33,6 +33,8 @@
 #include "exec/address-spaces.h"
 #include "qemu/cutils.h"
 #include "qapi/visitor.h"
+#include "monitor/monitor.h"
+#include "hw/intc/intc.h"
 
 #include "hw/ppc/xics.h"
 #include "hw/ppc/pnv_xscom.h"
@@ -762,6 +764,18 @@ static ICPState *pnv_icp_get(XICSFabric *xi, int pir)
     return cpu ? ICP(cpu->intc) : NULL;
 }
 
+static void pnv_pic_print_info(InterruptStatsProvider *obj,
+                               Monitor *mon)
+{
+    CPUState *cs;
+
+    CPU_FOREACH(cs) {
+        PowerPCCPU *cpu = POWERPC_CPU(cs);
+
+        icp_pic_print_info(ICP(cpu->intc), mon);
+    }
+}
+
 static void pnv_get_num_chips(Object *obj, Visitor *v, const char *name,
                               void *opaque, Error **errp)
 {
@@ -813,6 +827,7 @@ static void powernv_machine_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
     XICSFabricClass *xic = XICS_FABRIC_CLASS(oc);
+    InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc);
 
     mc->desc = "IBM PowerNV (Non-Virtualized)";
     mc->init = ppc_powernv_init;
@@ -824,6 +839,7 @@ static void powernv_machine_class_init(ObjectClass *oc, void *data)
     mc->default_boot_order = NULL;
     mc->default_ram_size = 1 * G_BYTE;
     xic->icp_get = pnv_icp_get;
+    ispc->print_info = pnv_pic_print_info;
 
     powernv_machine_class_props_init(oc);
 }
@@ -836,6 +852,7 @@ static const TypeInfo powernv_machine_info = {
     .class_init    = powernv_machine_class_init,
     .interfaces = (InterfaceInfo[]) {
         { TYPE_XICS_FABRIC },
+        { TYPE_INTERRUPT_STATS_PROVIDER },
         { },
     },
 };
-- 
2.9.3

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

* [Qemu-devel] [PULL 24/47] ppc/pnv: create the ICP object under PnvCore
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (22 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 23/47] ppc/pnv: extend the machine with a InterruptStatsProvider interface David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 25/47] ppc/pnv: add a helper to calculate MMIO addresses registers David Gibson
                   ` (24 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

Each thread of a core is linked to an ICP. This allocates a PnvICPState
object before the PowerPCCPU object is realized and lets the XICSFabric
do the store under the 'intc' backlink when xics_cpu_setup() is
called.

This modeling removes the need of maintaining an array of ICP objects
under the PowerNV machine and also simplifies the XICSFabric icp_get()
handler.

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

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index f3623ee..2add2ad 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -694,6 +694,8 @@ static void pnv_chip_realize(DeviceState *dev, Error **errp)
         object_property_set_int(OBJECT(pnv_core),
                                 pcc->core_pir(chip, core_hwid),
                                 "pir", &error_fatal);
+        object_property_add_const_link(OBJECT(pnv_core), "xics",
+                                       qdev_get_machine(), &error_fatal);
         object_property_set_bool(OBJECT(pnv_core), true, "realized",
                                  &error_fatal);
         object_unref(OBJECT(pnv_core));
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index d79d530..1b7ec70 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -25,6 +25,7 @@
 #include "hw/ppc/pnv.h"
 #include "hw/ppc/pnv_core.h"
 #include "hw/ppc/pnv_xscom.h"
+#include "hw/ppc/xics.h"
 
 static void powernv_cpu_reset(void *opaque)
 {
@@ -110,23 +111,37 @@ static const MemoryRegionOps pnv_core_xscom_ops = {
     .endianness = DEVICE_BIG_ENDIAN,
 };
 
-static void pnv_core_realize_child(Object *child, Error **errp)
+static void pnv_core_realize_child(Object *child, XICSFabric *xi, Error **errp)
 {
     Error *local_err = NULL;
     CPUState *cs = CPU(child);
     PowerPCCPU *cpu = POWERPC_CPU(cs);
+    Object *obj;
+
+    obj = object_new(TYPE_PNV_ICP);
+    object_property_add_child(OBJECT(cpu), "icp", obj, NULL);
+    object_property_add_const_link(obj, "xics", OBJECT(xi), &error_abort);
+    object_property_set_bool(obj, true, "realized", &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
 
     object_property_set_bool(child, true, "realized", &local_err);
     if (local_err) {
+        object_unparent(obj);
         error_propagate(errp, local_err);
         return;
     }
 
     powernv_cpu_init(cpu, &local_err);
     if (local_err) {
+        object_unparent(obj);
         error_propagate(errp, local_err);
         return;
     }
+
+    xics_cpu_setup(xi, cpu, ICP(obj));
 }
 
 static void pnv_core_realize(DeviceState *dev, Error **errp)
@@ -140,6 +155,14 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
     void *obj;
     int i, j;
     char name[32];
+    Object *xi;
+
+    xi = object_property_get_link(OBJECT(dev), "xics", &local_err);
+    if (!xi) {
+        error_setg(errp, "%s: required link 'xics' not found: %s",
+                   __func__, error_get_pretty(local_err));
+        return;
+    }
 
     pc->threads = g_malloc0(size * cc->nr_threads);
     for (i = 0; i < cc->nr_threads; i++) {
@@ -160,7 +183,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
     for (j = 0; j < cc->nr_threads; j++) {
         obj = pc->threads + j * size;
 
-        pnv_core_realize_child(obj, &local_err);
+        pnv_core_realize_child(obj, XICS_FABRIC(xi), &local_err);
         if (local_err) {
             goto err;
         }
-- 
2.9.3

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

* [Qemu-devel] [PULL 25/47] ppc/pnv: add a helper to calculate MMIO addresses registers
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (23 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 24/47] ppc/pnv: create the ICP object under PnvCore David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 26/47] ppc/pnv: add memory regions for the ICP registers David Gibson
                   ` (23 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

Some controllers (ICP, PSI) have a base register address which is
calculated using the chip id.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 include/hw/ppc/pnv.h | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index df98a72..5693ba1 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -91,14 +91,24 @@ typedef struct PnvChipClass {
     OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP_POWER9)
 
 /*
- * This generates a HW chip id depending on an index:
+ * This generates a HW chip id depending on an index, as found on a
+ * two socket system with dual chip modules :
  *
  *    0x0, 0x1, 0x10, 0x11
  *
  * 4 chips should be the maximum
+ *
+ * TODO: use a machine property to define the chip ids
  */
 #define PNV_CHIP_HWID(i) ((((i) & 0x3e) << 3) | ((i) & 0x1))
 
+/*
+ * Converts back a HW chip id to an index. This is useful to calculate
+ * the MMIO addresses of some controllers which depend on the chip id.
+ */
+#define PNV_CHIP_INDEX(chip)                                    \
+    (((chip)->chip_id >> 2) * 2 + ((chip)->chip_id & 0x3))
+
 #define TYPE_POWERNV_MACHINE       MACHINE_TYPE_NAME("powernv")
 #define POWERNV_MACHINE(obj) \
     OBJECT_CHECK(PnvMachineState, (obj), TYPE_POWERNV_MACHINE)
-- 
2.9.3

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

* [Qemu-devel] [PULL 26/47] ppc/pnv: add memory regions for the ICP registers
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (24 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 25/47] ppc/pnv: add a helper to calculate MMIO addresses registers David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 27/47] ppc/pnv: Add cut down PSI bridge model and hookup external interrupt David Gibson
                   ` (22 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

This provides to a PowerNV chip (POWER8) access to the Interrupt
Management area, which contains the registers of the Interrupt Control
Presenters of each thread. These are used to accept, return, forward
interrupts in the system.

This area is modeled with a per-chip container memory region holding
all the ICP registers. Each thread of a chip is then associated with
its ICP registers using a memory subregion indexed by its PIR number
in the overall region.

The device tree is populated accordingly.

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

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 2add2ad..1fa90d6 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -218,6 +218,43 @@ static void powernv_create_core_node(PnvChip *chip, PnvCore *pc, void *fdt)
                        servers_prop, sizeof(servers_prop))));
 }
 
+static void powernv_populate_icp(PnvChip *chip, void *fdt, uint32_t pir,
+                                 uint32_t nr_threads)
+{
+    uint64_t addr = PNV_ICP_BASE(chip) | (pir << 12);
+    char *name;
+    const char compat[] = "IBM,power8-icp\0IBM,ppc-xicp";
+    uint32_t irange[2], i, rsize;
+    uint64_t *reg;
+    int offset;
+
+    irange[0] = cpu_to_be32(pir);
+    irange[1] = cpu_to_be32(nr_threads);
+
+    rsize = sizeof(uint64_t) * 2 * nr_threads;
+    reg = g_malloc(rsize);
+    for (i = 0; i < nr_threads; i++) {
+        reg[i * 2] = cpu_to_be64(addr | ((pir + i) * 0x1000));
+        reg[i * 2 + 1] = cpu_to_be64(0x1000);
+    }
+
+    name = g_strdup_printf("interrupt-controller@%"PRIX64, addr);
+    offset = fdt_add_subnode(fdt, 0, name);
+    _FDT(offset);
+    g_free(name);
+
+    _FDT((fdt_setprop(fdt, offset, "compatible", compat, sizeof(compat))));
+    _FDT((fdt_setprop(fdt, offset, "reg", reg, rsize)));
+    _FDT((fdt_setprop_string(fdt, offset, "device_type",
+                              "PowerPC-External-Interrupt-Presentation")));
+    _FDT((fdt_setprop(fdt, offset, "interrupt-controller", NULL, 0)));
+    _FDT((fdt_setprop(fdt, offset, "ibm,interrupt-server-ranges",
+                       irange, sizeof(irange))));
+    _FDT((fdt_setprop_cell(fdt, offset, "#interrupt-cells", 1)));
+    _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 0)));
+    g_free(reg);
+}
+
 static void powernv_populate_chip(PnvChip *chip, void *fdt)
 {
     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
@@ -231,6 +268,10 @@ static void powernv_populate_chip(PnvChip *chip, void *fdt)
         PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
 
         powernv_create_core_node(chip, pnv_core, fdt);
+
+        /* Interrupt Control Presenters (ICP). One per core. */
+        powernv_populate_icp(chip, fdt, pnv_core->pir,
+                             CPU_CORE(pnv_core)->nr_threads);
     }
 
     if (chip->ram_size) {
@@ -643,6 +684,38 @@ static void pnv_chip_init(Object *obj)
     object_property_add_child(obj, "lpc", OBJECT(&chip->lpc), NULL);
 }
 
+static void pnv_chip_icp_realize(PnvChip *chip, Error **errp)
+{
+    PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
+    char *typename = pnv_core_typename(pcc->cpu_model);
+    size_t typesize = object_type_get_instance_size(typename);
+    int i, j;
+    char *name;
+    XICSFabric *xi = XICS_FABRIC(qdev_get_machine());
+
+    name = g_strdup_printf("icp-%x", chip->chip_id);
+    memory_region_init(&chip->icp_mmio, OBJECT(chip), name, PNV_ICP_SIZE);
+    sysbus_init_mmio(SYS_BUS_DEVICE(chip), &chip->icp_mmio);
+    g_free(name);
+
+    sysbus_mmio_map(SYS_BUS_DEVICE(chip), 1, PNV_ICP_BASE(chip));
+
+    /* Map the ICP registers for each thread */
+    for (i = 0; i < chip->nr_cores; i++) {
+        PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
+        int core_hwid = CPU_CORE(pnv_core)->core_id;
+
+        for (j = 0; j < CPU_CORE(pnv_core)->nr_threads; j++) {
+            uint32_t pir = pcc->core_pir(chip, core_hwid) + j;
+            PnvICPState *icp = PNV_ICP(xics_icp_get(xi, pir));
+
+            memory_region_add_subregion(&chip->icp_mmio, pir << 12, &icp->mmio);
+        }
+    }
+
+    g_free(typename);
+}
+
 static void pnv_chip_realize(DeviceState *dev, Error **errp)
 {
     PnvChip *chip = PNV_CHIP(dev);
@@ -713,6 +786,14 @@ static void pnv_chip_realize(DeviceState *dev, Error **errp)
     object_property_set_bool(OBJECT(&chip->lpc), true, "realized",
                              &error_fatal);
     pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip->lpc.xscom_regs);
+
+    /* Interrupt Management Area. This is the memory region holding
+     * all the Interrupt Control Presenter (ICP) registers */
+    pnv_chip_icp_realize(chip, &error);
+    if (error) {
+        error_propagate(errp, error);
+        return;
+    }
 }
 
 static Property pnv_chip_properties[] = {
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 5693ba1..96231c1 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -54,6 +54,7 @@ typedef struct PnvChip {
     MemoryRegion xscom_mmio;
     MemoryRegion xscom;
     AddressSpace xscom_as;
+    MemoryRegion icp_mmio;
 
     PnvLpcController lpc;
 } PnvChip;
@@ -136,4 +137,22 @@ typedef struct PnvMachineState {
 #define PNV_XSCOM_BASE(chip)                                            \
     (chip->xscom_base + ((uint64_t)(chip)->chip_id) * PNV_XSCOM_SIZE)
 
+/*
+ * XSCOM 0x20109CA defines the ICP BAR:
+ *
+ * 0:29   : bits 14 to 43 of address to define 1 MB region.
+ * 30     : 1 to enable ICP to receive loads/stores against its BAR region
+ * 31:63  : Constant 0
+ *
+ * Usually defined as :
+ *
+ *      0xffffe00200000000 -> 0x0003ffff80000000
+ *      0xffffe00600000000 -> 0x0003ffff80100000
+ *      0xffffe02200000000 -> 0x0003ffff80800000
+ *      0xffffe02600000000 -> 0x0003ffff80900000
+ */
+#define PNV_ICP_SIZE         0x0000000000100000ull
+#define PNV_ICP_BASE(chip)                                              \
+    (0x0003ffff80000000ull + (uint64_t) PNV_CHIP_INDEX(chip) * PNV_ICP_SIZE)
+
 #endif /* _PPC_PNV_H */
-- 
2.9.3

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

* [Qemu-devel] [PULL 27/47] ppc/pnv: Add cut down PSI bridge model and hookup external interrupt
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (25 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 26/47] ppc/pnv: add memory regions for the ICP registers David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 28/47] ppc/pnv: Add OCC model stub with interrupt support David Gibson
                   ` (21 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

The Processor Service Interface (PSI) Controller is one of the engines
of the "Bridge" unit which connects the different interfaces to the
Power Processor.

This adds just enough of the PSI bridge to handle various on-chip and
the one external interrupt. The rest of PSI has to do with the link to
the IBM FSP service processor which we don't plan to emulate (not used
on OpenPower machines).

The ics_get() and ics_resend() handlers of the XICSFabric interface of
the PowerNV machine are now defined to handle the Interrupt Control
Source of PSI. The InterruptStatsProvider interface is also modified
to dump the new ICS.

Originally from Benjamin Herrenschmidt <benh@kernel.crashing.org>

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/Makefile.objs       |   2 +-
 hw/ppc/pnv.c               |  65 +++++-
 hw/ppc/pnv_psi.c           | 571 +++++++++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/pnv.h       |  13 ++
 include/hw/ppc/pnv_psi.h   |  67 ++++++
 include/hw/ppc/pnv_xscom.h |   3 +
 6 files changed, 714 insertions(+), 7 deletions(-)
 create mode 100644 hw/ppc/pnv_psi.c
 create mode 100644 include/hw/ppc/pnv_psi.h

diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index 0012934..dc19ee1 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -6,7 +6,7 @@ obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o
 obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o spapr_rng.o
 obj-$(CONFIG_PSERIES) += spapr_cpu_core.o spapr_ovec.o
 # IBM PowerNV
-obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_core.o pnv_lpc.o
+obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_core.o pnv_lpc.o pnv_psi.o
 ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy)
 obj-y += spapr_pci_vfio.o
 endif
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 1fa90d6..a516acb 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -353,15 +353,22 @@ static void ppc_powernv_reset(void)
  * have a CPLD that will collect the SerIRQ and shoot them as a
  * single level interrupt to the P8 chip. So let's setup a hook
  * for doing just that.
- *
- * Note: The actual interrupt input isn't emulated yet, this will
- * come with the PSI bridge model.
  */
 static void pnv_lpc_isa_irq_handler_cpld(void *opaque, int n, int level)
 {
-    /* We don't yet emulate the PSI bridge which provides the external
-     * interrupt, so just drop interrupts on the floor
-     */
+    PnvMachineState *pnv = POWERNV_MACHINE(qdev_get_machine());
+    uint32_t old_state = pnv->cpld_irqstate;
+    PnvChip *chip = opaque;
+
+    if (level) {
+        pnv->cpld_irqstate |= 1u << n;
+    } else {
+        pnv->cpld_irqstate &= ~(1u << n);
+    }
+    if (pnv->cpld_irqstate != old_state) {
+        pnv_psi_irq_set(&chip->psi, PSIHB_IRQ_EXTERNAL,
+                        pnv->cpld_irqstate != 0);
+    }
 }
 
 static void pnv_lpc_isa_irq_handler(void *opaque, int n, int level)
@@ -682,6 +689,11 @@ static void pnv_chip_init(Object *obj)
 
     object_initialize(&chip->lpc, sizeof(chip->lpc), TYPE_PNV_LPC);
     object_property_add_child(obj, "lpc", OBJECT(&chip->lpc), NULL);
+
+    object_initialize(&chip->psi, sizeof(chip->psi), TYPE_PNV_PSI);
+    object_property_add_child(obj, "psi", OBJECT(&chip->psi), NULL);
+    object_property_add_const_link(OBJECT(&chip->psi), "xics",
+                                   OBJECT(qdev_get_machine()), &error_abort);
 }
 
 static void pnv_chip_icp_realize(PnvChip *chip, Error **errp)
@@ -794,6 +806,16 @@ static void pnv_chip_realize(DeviceState *dev, Error **errp)
         error_propagate(errp, error);
         return;
     }
+
+    /* Processor Service Interface (PSI) Host Bridge */
+    object_property_set_int(OBJECT(&chip->psi), PNV_PSIHB_BASE(chip),
+                            "bar", &error_fatal);
+    object_property_set_bool(OBJECT(&chip->psi), true, "realized", &error);
+    if (error) {
+        error_propagate(errp, error);
+        return;
+    }
+    pnv_xscom_add_subregion(chip, PNV_XSCOM_PSIHB_BASE, &chip->psi.xscom_regs);
 }
 
 static Property pnv_chip_properties[] = {
@@ -824,6 +846,29 @@ static const TypeInfo pnv_chip_info = {
     .abstract      = true,
 };
 
+static ICSState *pnv_ics_get(XICSFabric *xi, int irq)
+{
+    PnvMachineState *pnv = POWERNV_MACHINE(xi);
+    int i;
+
+    for (i = 0; i < pnv->num_chips; i++) {
+        if (ics_valid_irq(&pnv->chips[i]->psi.ics, irq)) {
+            return &pnv->chips[i]->psi.ics;
+        }
+    }
+    return NULL;
+}
+
+static void pnv_ics_resend(XICSFabric *xi)
+{
+    PnvMachineState *pnv = POWERNV_MACHINE(xi);
+    int i;
+
+    for (i = 0; i < pnv->num_chips; i++) {
+        ics_resend(&pnv->chips[i]->psi.ics);
+    }
+}
+
 static PowerPCCPU *ppc_get_vcpu_by_pir(int pir)
 {
     CPUState *cs;
@@ -850,6 +895,8 @@ static ICPState *pnv_icp_get(XICSFabric *xi, int pir)
 static void pnv_pic_print_info(InterruptStatsProvider *obj,
                                Monitor *mon)
 {
+    PnvMachineState *pnv = POWERNV_MACHINE(obj);
+    int i;
     CPUState *cs;
 
     CPU_FOREACH(cs) {
@@ -857,6 +904,10 @@ static void pnv_pic_print_info(InterruptStatsProvider *obj,
 
         icp_pic_print_info(ICP(cpu->intc), mon);
     }
+
+    for (i = 0; i < pnv->num_chips; i++) {
+        ics_pic_print_info(&pnv->chips[i]->psi.ics, mon);
+    }
 }
 
 static void pnv_get_num_chips(Object *obj, Visitor *v, const char *name,
@@ -922,6 +973,8 @@ static void powernv_machine_class_init(ObjectClass *oc, void *data)
     mc->default_boot_order = NULL;
     mc->default_ram_size = 1 * G_BYTE;
     xic->icp_get = pnv_icp_get;
+    xic->ics_get = pnv_ics_get;
+    xic->ics_resend = pnv_ics_resend;
     ispc->print_info = pnv_pic_print_info;
 
     powernv_machine_class_props_init(oc);
diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
new file mode 100644
index 0000000..2bf5bfe
--- /dev/null
+++ b/hw/ppc/pnv_psi.c
@@ -0,0 +1,571 @@
+/*
+ * QEMU PowerPC PowerNV Processor Service Interface (PSI) model
+ *
+ * Copyright (c) 2015-2017, IBM Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "target/ppc/cpu.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+
+#include "exec/address-spaces.h"
+
+#include "hw/ppc/fdt.h"
+#include "hw/ppc/pnv.h"
+#include "hw/ppc/pnv_xscom.h"
+#include "hw/ppc/pnv_psi.h"
+
+#include <libfdt.h>
+
+#define PSIHB_XSCOM_FIR_RW      0x00
+#define PSIHB_XSCOM_FIR_AND     0x01
+#define PSIHB_XSCOM_FIR_OR      0x02
+#define PSIHB_XSCOM_FIRMASK_RW  0x03
+#define PSIHB_XSCOM_FIRMASK_AND 0x04
+#define PSIHB_XSCOM_FIRMASK_OR  0x05
+#define PSIHB_XSCOM_FIRACT0     0x06
+#define PSIHB_XSCOM_FIRACT1     0x07
+
+/* Host Bridge Base Address Register */
+#define PSIHB_XSCOM_BAR         0x0a
+#define   PSIHB_BAR_EN                  0x0000000000000001ull
+
+/* FSP Base Address Register */
+#define PSIHB_XSCOM_FSPBAR      0x0b
+
+/* PSI Host Bridge Control/Status Register */
+#define PSIHB_XSCOM_CR          0x0e
+#define   PSIHB_CR_FSP_CMD_ENABLE       0x8000000000000000ull
+#define   PSIHB_CR_FSP_MMIO_ENABLE      0x4000000000000000ull
+#define   PSIHB_CR_FSP_IRQ_ENABLE       0x1000000000000000ull
+#define   PSIHB_CR_FSP_ERR_RSP_ENABLE   0x0800000000000000ull
+#define   PSIHB_CR_PSI_LINK_ENABLE      0x0400000000000000ull
+#define   PSIHB_CR_FSP_RESET            0x0200000000000000ull
+#define   PSIHB_CR_PSIHB_RESET          0x0100000000000000ull
+#define   PSIHB_CR_PSI_IRQ              0x0000800000000000ull
+#define   PSIHB_CR_FSP_IRQ              0x0000400000000000ull
+#define   PSIHB_CR_FSP_LINK_ACTIVE      0x0000200000000000ull
+#define   PSIHB_CR_IRQ_CMD_EXPECT       0x0000010000000000ull
+          /* and more ... */
+
+/* PSIHB Status / Error Mask Register */
+#define PSIHB_XSCOM_SEMR        0x0f
+
+/* XIVR, to signal interrupts to the CEC firmware. more XIVR below. */
+#define PSIHB_XSCOM_XIVR_FSP    0x10
+#define   PSIHB_XIVR_SERVER_SH          40
+#define   PSIHB_XIVR_SERVER_MSK         (0xffffull << PSIHB_XIVR_SERVER_SH)
+#define   PSIHB_XIVR_PRIO_SH            32
+#define   PSIHB_XIVR_PRIO_MSK           (0xffull << PSIHB_XIVR_PRIO_SH)
+#define   PSIHB_XIVR_SRC_SH             29
+#define   PSIHB_XIVR_SRC_MSK            (0x7ull << PSIHB_XIVR_SRC_SH)
+#define   PSIHB_XIVR_PENDING            0x01000000ull
+
+/* PSI Host Bridge Set Control/ Status Register */
+#define PSIHB_XSCOM_SCR         0x12
+
+/* PSI Host Bridge Clear Control/ Status Register */
+#define PSIHB_XSCOM_CCR         0x13
+
+/* DMA Upper Address Register */
+#define PSIHB_XSCOM_DMA_UPADD   0x14
+
+/* Interrupt Status */
+#define PSIHB_XSCOM_IRQ_STAT    0x15
+#define   PSIHB_IRQ_STAT_OCC            0x0000001000000000ull
+#define   PSIHB_IRQ_STAT_FSI            0x0000000800000000ull
+#define   PSIHB_IRQ_STAT_LPCI2C         0x0000000400000000ull
+#define   PSIHB_IRQ_STAT_LOCERR         0x0000000200000000ull
+#define   PSIHB_IRQ_STAT_EXT            0x0000000100000000ull
+
+/* remaining XIVR */
+#define PSIHB_XSCOM_XIVR_OCC    0x16
+#define PSIHB_XSCOM_XIVR_FSI    0x17
+#define PSIHB_XSCOM_XIVR_LPCI2C 0x18
+#define PSIHB_XSCOM_XIVR_LOCERR 0x19
+#define PSIHB_XSCOM_XIVR_EXT    0x1a
+
+/* Interrupt Requester Source Compare Register */
+#define PSIHB_XSCOM_IRSN        0x1b
+#define   PSIHB_IRSN_COMP_SH            45
+#define   PSIHB_IRSN_COMP_MSK           (0x7ffffull << PSIHB_IRSN_COMP_SH)
+#define   PSIHB_IRSN_IRQ_MUX            0x0000000800000000ull
+#define   PSIHB_IRSN_IRQ_RESET          0x0000000400000000ull
+#define   PSIHB_IRSN_DOWNSTREAM_EN      0x0000000200000000ull
+#define   PSIHB_IRSN_UPSTREAM_EN        0x0000000100000000ull
+#define   PSIHB_IRSN_COMPMASK_SH        13
+#define   PSIHB_IRSN_COMPMASK_MSK       (0x7ffffull << PSIHB_IRSN_COMPMASK_SH)
+
+#define PSIHB_BAR_MASK                  0x0003fffffff00000ull
+#define PSIHB_FSPBAR_MASK               0x0003ffff00000000ull
+
+static void pnv_psi_set_bar(PnvPsi *psi, uint64_t bar)
+{
+    MemoryRegion *sysmem = get_system_memory();
+    uint64_t old = psi->regs[PSIHB_XSCOM_BAR];
+
+    psi->regs[PSIHB_XSCOM_BAR] = bar & (PSIHB_BAR_MASK | PSIHB_BAR_EN);
+
+    /* Update MR, always remove it first */
+    if (old & PSIHB_BAR_EN) {
+        memory_region_del_subregion(sysmem, &psi->regs_mr);
+    }
+
+    /* Then add it back if needed */
+    if (bar & PSIHB_BAR_EN) {
+        uint64_t addr = bar & PSIHB_BAR_MASK;
+        memory_region_add_subregion(sysmem, addr, &psi->regs_mr);
+    }
+}
+
+static void pnv_psi_update_fsp_mr(PnvPsi *psi)
+{
+    /* TODO: Update FSP MR if/when we support FSP BAR */
+}
+
+static void pnv_psi_set_cr(PnvPsi *psi, uint64_t cr)
+{
+    uint64_t old = psi->regs[PSIHB_XSCOM_CR];
+
+    psi->regs[PSIHB_XSCOM_CR] = cr;
+
+    /* Check some bit changes */
+    if ((old ^ psi->regs[PSIHB_XSCOM_CR]) & PSIHB_CR_FSP_MMIO_ENABLE) {
+        pnv_psi_update_fsp_mr(psi);
+    }
+}
+
+static void pnv_psi_set_irsn(PnvPsi *psi, uint64_t val)
+{
+    ICSState *ics = &psi->ics;
+
+    /* In this model we ignore the up/down enable bits for now
+     * as SW doesn't use them (other than setting them at boot).
+     * We ignore IRQ_MUX, its meaning isn't clear and we don't use
+     * it and finally we ignore reset (XXX fix that ?)
+     */
+    psi->regs[PSIHB_XSCOM_IRSN] = val & (PSIHB_IRSN_COMP_MSK |
+                                         PSIHB_IRSN_IRQ_MUX |
+                                         PSIHB_IRSN_IRQ_RESET |
+                                         PSIHB_IRSN_DOWNSTREAM_EN |
+                                         PSIHB_IRSN_UPSTREAM_EN);
+
+    /* We ignore the compare mask as well, our ICS emulation is too
+     * simplistic to make any use if it, and we extract the offset
+     * from the compare value
+     */
+    ics->offset = (val & PSIHB_IRSN_COMP_MSK) >> PSIHB_IRSN_COMP_SH;
+}
+
+/*
+ * FSP and PSI interrupts are muxed under the same number.
+ */
+static const uint32_t xivr_regs[] = {
+    [PSIHB_IRQ_PSI]       = PSIHB_XSCOM_XIVR_FSP,
+    [PSIHB_IRQ_FSP]       = PSIHB_XSCOM_XIVR_FSP,
+    [PSIHB_IRQ_OCC]       = PSIHB_XSCOM_XIVR_OCC,
+    [PSIHB_IRQ_FSI]       = PSIHB_XSCOM_XIVR_FSI,
+    [PSIHB_IRQ_LPC_I2C]   = PSIHB_XSCOM_XIVR_LPCI2C,
+    [PSIHB_IRQ_LOCAL_ERR] = PSIHB_XSCOM_XIVR_LOCERR,
+    [PSIHB_IRQ_EXTERNAL]  = PSIHB_XSCOM_XIVR_EXT,
+};
+
+static const uint32_t stat_regs[] = {
+    [PSIHB_IRQ_PSI]       = PSIHB_XSCOM_CR,
+    [PSIHB_IRQ_FSP]       = PSIHB_XSCOM_CR,
+    [PSIHB_IRQ_OCC]       = PSIHB_XSCOM_IRQ_STAT,
+    [PSIHB_IRQ_FSI]       = PSIHB_XSCOM_IRQ_STAT,
+    [PSIHB_IRQ_LPC_I2C]   = PSIHB_XSCOM_IRQ_STAT,
+    [PSIHB_IRQ_LOCAL_ERR] = PSIHB_XSCOM_IRQ_STAT,
+    [PSIHB_IRQ_EXTERNAL]  = PSIHB_XSCOM_IRQ_STAT,
+};
+
+static const uint64_t stat_bits[] = {
+    [PSIHB_IRQ_PSI]       = PSIHB_CR_PSI_IRQ,
+    [PSIHB_IRQ_FSP]       = PSIHB_CR_FSP_IRQ,
+    [PSIHB_IRQ_OCC]       = PSIHB_IRQ_STAT_OCC,
+    [PSIHB_IRQ_FSI]       = PSIHB_IRQ_STAT_FSI,
+    [PSIHB_IRQ_LPC_I2C]   = PSIHB_IRQ_STAT_LPCI2C,
+    [PSIHB_IRQ_LOCAL_ERR] = PSIHB_IRQ_STAT_LOCERR,
+    [PSIHB_IRQ_EXTERNAL]  = PSIHB_IRQ_STAT_EXT,
+};
+
+void pnv_psi_irq_set(PnvPsi *psi, PnvPsiIrq irq, bool state)
+{
+    ICSState *ics = &psi->ics;
+    uint32_t xivr_reg;
+    uint32_t stat_reg;
+    uint32_t src;
+    bool masked;
+
+    if (irq > PSIHB_IRQ_EXTERNAL) {
+        qemu_log_mask(LOG_GUEST_ERROR, "PSI: Unsupported irq %d\n", irq);
+        return;
+    }
+
+    xivr_reg = xivr_regs[irq];
+    stat_reg = stat_regs[irq];
+
+    src = (psi->regs[xivr_reg] & PSIHB_XIVR_SRC_MSK) >> PSIHB_XIVR_SRC_SH;
+    if (state) {
+        psi->regs[stat_reg] |= stat_bits[irq];
+        /* TODO: optimization, check mask here. That means
+         * re-evaluating when unmasking
+         */
+        qemu_irq_raise(ics->qirqs[src]);
+    } else {
+        psi->regs[stat_reg] &= ~stat_bits[irq];
+
+        /* FSP and PSI are muxed so don't lower if either is still set */
+        if (stat_reg != PSIHB_XSCOM_CR ||
+            !(psi->regs[stat_reg] & (PSIHB_CR_PSI_IRQ | PSIHB_CR_FSP_IRQ))) {
+            qemu_irq_lower(ics->qirqs[src]);
+        } else {
+            state = true;
+        }
+    }
+
+    /* Note about the emulation of the pending bit: This isn't
+     * entirely correct. The pending bit should be cleared when the
+     * EOI has been received. However, we don't have callbacks on EOI
+     * (especially not under KVM) so no way to emulate that properly,
+     * so instead we just set that bit as the logical "output" of the
+     * XIVR (ie pending & !masked)
+     *
+     * CLG: We could define a new ICS object with a custom eoi()
+     * handler to clear the pending bit. But I am not sure this would
+     * be useful for the software anyhow.
+     */
+    masked = (psi->regs[xivr_reg] & PSIHB_XIVR_PRIO_MSK) == PSIHB_XIVR_PRIO_MSK;
+    if (state && !masked) {
+        psi->regs[xivr_reg] |= PSIHB_XIVR_PENDING;
+    } else {
+        psi->regs[xivr_reg] &= ~PSIHB_XIVR_PENDING;
+    }
+}
+
+static void pnv_psi_set_xivr(PnvPsi *psi, uint32_t reg, uint64_t val)
+{
+    ICSState *ics = &psi->ics;
+    uint16_t server;
+    uint8_t prio;
+    uint8_t src;
+
+    psi->regs[reg] = (psi->regs[reg] & PSIHB_XIVR_PENDING) |
+            (val & (PSIHB_XIVR_SERVER_MSK |
+                    PSIHB_XIVR_PRIO_MSK |
+                    PSIHB_XIVR_SRC_MSK));
+    val = psi->regs[reg];
+    server = (val & PSIHB_XIVR_SERVER_MSK) >> PSIHB_XIVR_SERVER_SH;
+    prio = (val & PSIHB_XIVR_PRIO_MSK) >> PSIHB_XIVR_PRIO_SH;
+    src = (val & PSIHB_XIVR_SRC_MSK) >> PSIHB_XIVR_SRC_SH;
+
+    if (src >= PSI_NUM_INTERRUPTS) {
+        qemu_log_mask(LOG_GUEST_ERROR, "PSI: Unsupported irq %d\n", src);
+        return;
+    }
+
+    /* Remove pending bit if the IRQ is masked */
+    if ((psi->regs[reg] & PSIHB_XIVR_PRIO_MSK) == PSIHB_XIVR_PRIO_MSK) {
+        psi->regs[reg] &= ~PSIHB_XIVR_PENDING;
+    }
+
+    /* The low order 2 bits are the link pointer (Type II interrupts).
+     * Shift back to get a valid IRQ server.
+     */
+    server >>= 2;
+
+    /* Now because of source remapping, weird things can happen
+     * if you change the source number dynamically, our simple ICS
+     * doesn't deal with remapping. So we just poke a different
+     * ICS entry based on what source number was written. This will
+     * do for now but a more accurate implementation would instead
+     * use a fixed server/prio and a remapper of the generated irq.
+     */
+    ics_simple_write_xive(ics, src, server, prio, prio);
+}
+
+static uint64_t pnv_psi_reg_read(PnvPsi *psi, uint32_t offset, bool mmio)
+{
+    uint64_t val = 0xffffffffffffffffull;
+
+    switch (offset) {
+    case PSIHB_XSCOM_FIR_RW:
+    case PSIHB_XSCOM_FIRACT0:
+    case PSIHB_XSCOM_FIRACT1:
+    case PSIHB_XSCOM_BAR:
+    case PSIHB_XSCOM_FSPBAR:
+    case PSIHB_XSCOM_CR:
+    case PSIHB_XSCOM_XIVR_FSP:
+    case PSIHB_XSCOM_XIVR_OCC:
+    case PSIHB_XSCOM_XIVR_FSI:
+    case PSIHB_XSCOM_XIVR_LPCI2C:
+    case PSIHB_XSCOM_XIVR_LOCERR:
+    case PSIHB_XSCOM_XIVR_EXT:
+    case PSIHB_XSCOM_IRQ_STAT:
+    case PSIHB_XSCOM_SEMR:
+    case PSIHB_XSCOM_DMA_UPADD:
+    case PSIHB_XSCOM_IRSN:
+        val = psi->regs[offset];
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "PSI: read at Ox%" PRIx32 "\n", offset);
+    }
+    return val;
+}
+
+static void pnv_psi_reg_write(PnvPsi *psi, uint32_t offset, uint64_t val,
+                              bool mmio)
+{
+    switch (offset) {
+    case PSIHB_XSCOM_FIR_RW:
+    case PSIHB_XSCOM_FIRACT0:
+    case PSIHB_XSCOM_FIRACT1:
+    case PSIHB_XSCOM_SEMR:
+    case PSIHB_XSCOM_DMA_UPADD:
+        psi->regs[offset] = val;
+        break;
+    case PSIHB_XSCOM_FIR_OR:
+        psi->regs[PSIHB_XSCOM_FIR_RW] |= val;
+        break;
+    case PSIHB_XSCOM_FIR_AND:
+        psi->regs[PSIHB_XSCOM_FIR_RW] &= val;
+        break;
+    case PSIHB_XSCOM_BAR:
+        /* Only XSCOM can write this one */
+        if (!mmio) {
+            pnv_psi_set_bar(psi, val);
+        } else {
+            qemu_log_mask(LOG_GUEST_ERROR, "PSI: invalid write of BAR\n");
+        }
+        break;
+    case PSIHB_XSCOM_FSPBAR:
+        psi->regs[PSIHB_XSCOM_FSPBAR] = val & PSIHB_FSPBAR_MASK;
+        pnv_psi_update_fsp_mr(psi);
+        break;
+    case PSIHB_XSCOM_CR:
+        pnv_psi_set_cr(psi, val);
+        break;
+    case PSIHB_XSCOM_SCR:
+        pnv_psi_set_cr(psi, psi->regs[PSIHB_XSCOM_CR] | val);
+        break;
+    case PSIHB_XSCOM_CCR:
+        pnv_psi_set_cr(psi, psi->regs[PSIHB_XSCOM_CR] & ~val);
+        break;
+    case PSIHB_XSCOM_XIVR_FSP:
+    case PSIHB_XSCOM_XIVR_OCC:
+    case PSIHB_XSCOM_XIVR_FSI:
+    case PSIHB_XSCOM_XIVR_LPCI2C:
+    case PSIHB_XSCOM_XIVR_LOCERR:
+    case PSIHB_XSCOM_XIVR_EXT:
+        pnv_psi_set_xivr(psi, offset, val);
+        break;
+    case PSIHB_XSCOM_IRQ_STAT:
+        /* Read only */
+        qemu_log_mask(LOG_GUEST_ERROR, "PSI: invalid write of IRQ_STAT\n");
+        break;
+    case PSIHB_XSCOM_IRSN:
+        pnv_psi_set_irsn(psi, val);
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "PSI: write at Ox%" PRIx32 "\n", offset);
+    }
+}
+
+/*
+ * The values of the registers when accessed through the MMIO region
+ * follow the relation : xscom = (mmio + 0x50) >> 3
+ */
+static uint64_t pnv_psi_mmio_read(void *opaque, hwaddr addr, unsigned size)
+{
+    return pnv_psi_reg_read(opaque, (addr >> 3) + PSIHB_XSCOM_BAR, true);
+}
+
+static void pnv_psi_mmio_write(void *opaque, hwaddr addr,
+                              uint64_t val, unsigned size)
+{
+    pnv_psi_reg_write(opaque, (addr >> 3) + PSIHB_XSCOM_BAR, val, true);
+}
+
+static const MemoryRegionOps psi_mmio_ops = {
+    .read = pnv_psi_mmio_read,
+    .write = pnv_psi_mmio_write,
+    .endianness = DEVICE_BIG_ENDIAN,
+    .valid = {
+        .min_access_size = 8,
+        .max_access_size = 8,
+    },
+    .impl = {
+        .min_access_size = 8,
+        .max_access_size = 8,
+    },
+};
+
+static uint64_t pnv_psi_xscom_read(void *opaque, hwaddr addr, unsigned size)
+{
+    return pnv_psi_reg_read(opaque, addr >> 3, false);
+}
+
+static void pnv_psi_xscom_write(void *opaque, hwaddr addr,
+                                uint64_t val, unsigned size)
+{
+    pnv_psi_reg_write(opaque, addr >> 3, val, false);
+}
+
+static const MemoryRegionOps pnv_psi_xscom_ops = {
+    .read = pnv_psi_xscom_read,
+    .write = pnv_psi_xscom_write,
+    .endianness = DEVICE_BIG_ENDIAN,
+    .valid = {
+        .min_access_size = 8,
+        .max_access_size = 8,
+    },
+    .impl = {
+        .min_access_size = 8,
+        .max_access_size = 8,
+    }
+};
+
+static void pnv_psi_init(Object *obj)
+{
+    PnvPsi *psi = PNV_PSI(obj);
+
+    object_initialize(&psi->ics, sizeof(psi->ics), TYPE_ICS_SIMPLE);
+    object_property_add_child(obj, "ics-psi", OBJECT(&psi->ics), NULL);
+}
+
+static const uint8_t irq_to_xivr[] = {
+    PSIHB_XSCOM_XIVR_FSP,
+    PSIHB_XSCOM_XIVR_OCC,
+    PSIHB_XSCOM_XIVR_FSI,
+    PSIHB_XSCOM_XIVR_LPCI2C,
+    PSIHB_XSCOM_XIVR_LOCERR,
+    PSIHB_XSCOM_XIVR_EXT,
+};
+
+static void pnv_psi_realize(DeviceState *dev, Error **errp)
+{
+    PnvPsi *psi = PNV_PSI(dev);
+    ICSState *ics = &psi->ics;
+    Object *obj;
+    Error *err = NULL;
+    unsigned int i;
+
+    obj = object_property_get_link(OBJECT(dev), "xics", &err);
+    if (!obj) {
+        error_setg(errp, "%s: required link 'xics' not found: %s",
+                   __func__, error_get_pretty(err));
+        return;
+    }
+
+    /* Create PSI interrupt control source */
+    object_property_add_const_link(OBJECT(ics), "xics", obj,  &error_abort);
+    object_property_set_int(OBJECT(ics), PSI_NUM_INTERRUPTS, "nr-irqs", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    object_property_set_bool(OBJECT(ics), true, "realized",  &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    for (i = 0; i < ics->nr_irqs; i++) {
+        ics_set_irq_type(ics, i, true);
+    }
+
+    /* XSCOM region for PSI registers */
+    pnv_xscom_region_init(&psi->xscom_regs, OBJECT(dev), &pnv_psi_xscom_ops,
+                psi, "xscom-psi", PNV_XSCOM_PSIHB_SIZE);
+
+    /* Initialize MMIO region */
+    memory_region_init_io(&psi->regs_mr, OBJECT(dev), &psi_mmio_ops, psi,
+                          "psihb", PNV_PSIHB_SIZE);
+
+    /* Default BAR for MMIO region */
+    pnv_psi_set_bar(psi, psi->bar | PSIHB_BAR_EN);
+
+    /* Default sources in XIVR */
+    for (i = 0; i < PSI_NUM_INTERRUPTS; i++) {
+        uint8_t xivr = irq_to_xivr[i];
+        psi->regs[xivr] = PSIHB_XIVR_PRIO_MSK |
+            ((uint64_t) i << PSIHB_XIVR_SRC_SH);
+    }
+}
+
+static int pnv_psi_populate(PnvXScomInterface *dev, void *fdt, int xscom_offset)
+{
+    const char compat[] = "ibm,power8-psihb-x\0ibm,psihb-x";
+    char *name;
+    int offset;
+    uint32_t lpc_pcba = PNV_XSCOM_PSIHB_BASE;
+    uint32_t reg[] = {
+        cpu_to_be32(lpc_pcba),
+        cpu_to_be32(PNV_XSCOM_PSIHB_SIZE)
+    };
+
+    name = g_strdup_printf("psihb@%x", lpc_pcba);
+    offset = fdt_add_subnode(fdt, xscom_offset, name);
+    _FDT(offset);
+    g_free(name);
+
+    _FDT((fdt_setprop(fdt, offset, "reg", reg, sizeof(reg))));
+
+    _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 2)));
+    _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 1)));
+    _FDT((fdt_setprop(fdt, offset, "compatible", compat,
+                      sizeof(compat))));
+    return 0;
+}
+
+static Property pnv_psi_properties[] = {
+    DEFINE_PROP_UINT64("bar", PnvPsi, bar, 0),
+    DEFINE_PROP_UINT64("fsp-bar", PnvPsi, fsp_bar, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void pnv_psi_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass);
+
+    xdc->populate = pnv_psi_populate;
+
+    dc->realize = pnv_psi_realize;
+    dc->props = pnv_psi_properties;
+}
+
+static const TypeInfo pnv_psi_info = {
+    .name          = TYPE_PNV_PSI,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PnvPsi),
+    .instance_init = pnv_psi_init,
+    .class_init    = pnv_psi_class_init,
+    .interfaces    = (InterfaceInfo[]) {
+        { TYPE_PNV_XSCOM_INTERFACE },
+        { }
+    }
+};
+
+static void pnv_psi_register_types(void)
+{
+    type_register_static(&pnv_psi_info);
+}
+
+type_init(pnv_psi_register_types)
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 96231c1..a3ed2ee 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -22,6 +22,7 @@
 #include "hw/boards.h"
 #include "hw/sysbus.h"
 #include "hw/ppc/pnv_lpc.h"
+#include "hw/ppc/pnv_psi.h"
 
 #define TYPE_PNV_CHIP "powernv-chip"
 #define PNV_CHIP(obj) OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP)
@@ -57,6 +58,7 @@ typedef struct PnvChip {
     MemoryRegion icp_mmio;
 
     PnvLpcController lpc;
+    PnvPsi       psi;
 } PnvChip;
 
 typedef struct PnvChipClass {
@@ -125,6 +127,7 @@ typedef struct PnvMachineState {
     PnvChip      **chips;
 
     ISABus       *isa_bus;
+    uint32_t     cpld_irqstate;
 } PnvMachineState;
 
 #define PNV_FDT_ADDR          0x01000000
@@ -155,4 +158,14 @@ typedef struct PnvMachineState {
 #define PNV_ICP_BASE(chip)                                              \
     (0x0003ffff80000000ull + (uint64_t) PNV_CHIP_INDEX(chip) * PNV_ICP_SIZE)
 
+
+#define PNV_PSIHB_SIZE       0x0000000000100000ull
+#define PNV_PSIHB_BASE(chip) \
+    (0x0003fffe80000000ull + (uint64_t)PNV_CHIP_INDEX(chip) * PNV_PSIHB_SIZE)
+
+#define PNV_PSIHB_FSP_SIZE   0x0000000100000000ull
+#define PNV_PSIHB_FSP_BASE(chip) \
+    (0x0003ffe000000000ull + (uint64_t)PNV_CHIP_INDEX(chip) * \
+     PNV_PSIHB_FSP_SIZE)
+
 #endif /* _PPC_PNV_H */
diff --git a/include/hw/ppc/pnv_psi.h b/include/hw/ppc/pnv_psi.h
new file mode 100644
index 0000000..11d83e4
--- /dev/null
+++ b/include/hw/ppc/pnv_psi.h
@@ -0,0 +1,67 @@
+/*
+ * QEMU PowerPC PowerNV Processor Service Interface (PSI) model
+ *
+ * Copyright (c) 2015-2017, IBM Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _PPC_PNV_PSI_H
+#define _PPC_PNV_PSI_H
+
+#include "hw/sysbus.h"
+#include "hw/ppc/xics.h"
+
+#define TYPE_PNV_PSI "pnv-psi"
+#define PNV_PSI(obj) \
+     OBJECT_CHECK(PnvPsi, (obj), TYPE_PNV_PSI)
+
+#define PSIHB_XSCOM_MAX         0x20
+
+typedef struct XICSState XICSState;
+
+typedef struct PnvPsi {
+    SysBusDevice parent;
+
+    MemoryRegion regs_mr;
+    uint64_t bar;
+
+    /* FSP region not supported */
+    /* MemoryRegion fsp_mr; */
+    uint64_t fsp_bar;
+
+    /* Interrupt generation */
+    ICSState ics;
+
+    /* Registers */
+    uint64_t regs[PSIHB_XSCOM_MAX];
+
+    MemoryRegion xscom_regs;
+} PnvPsi;
+
+/* The PSI and FSP interrupts are muxed on the same IRQ number */
+typedef enum PnvPsiIrq {
+    PSIHB_IRQ_PSI, /* internal use only */
+    PSIHB_IRQ_FSP, /* internal use only */
+    PSIHB_IRQ_OCC,
+    PSIHB_IRQ_FSI,
+    PSIHB_IRQ_LPC_I2C,
+    PSIHB_IRQ_LOCAL_ERR,
+    PSIHB_IRQ_EXTERNAL,
+} PnvPsiIrq;
+
+#define PSI_NUM_INTERRUPTS 6
+
+extern void pnv_psi_irq_set(PnvPsi *psi, PnvPsiIrq irq, bool state);
+
+#endif /* _PPC_PNV_PSI_H */
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index 0faa184..15f7fdb 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -60,6 +60,9 @@ typedef struct PnvXScomInterfaceClass {
 #define PNV_XSCOM_LPC_BASE        0xb0020
 #define PNV_XSCOM_LPC_SIZE        0x4
 
+#define PNV_XSCOM_PSIHB_BASE      0x2010900
+#define PNV_XSCOM_PSIHB_SIZE      0x20
+
 extern void pnv_xscom_realize(PnvChip *chip, Error **errp);
 extern int pnv_xscom_populate(PnvChip *chip, void *fdt, int offset);
 
-- 
2.9.3

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

* [Qemu-devel] [PULL 28/47] ppc/pnv: Add OCC model stub with interrupt support
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (26 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 27/47] ppc/pnv: Add cut down PSI bridge model and hookup external interrupt David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 29/47] ppc: add IPMI support David Gibson
                   ` (20 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell
  Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg,
	Benjamin Herrenschmidt, David Gibson

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

The OCC is an on-chip microcontroller based on a ppc405 core used
for various power management tasks. It comes with a pile of additional
hardware sitting on the PIB (aka XSCOM bus). At this point we don't
emulate it (nor plan to do so). However there is one facility which
is provided by the surrounding hardware that we do need, which is the
interrupt generation facility. OPAL uses it to send itself interrupts
under some circumstances and there are other uses around the corner.

So this implement just enough to support this.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
[clg: - updated for qemu-2.9
      - changed the XSCOM interface to fit new model
      - QOMified the model ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/Makefile.objs       |   2 +-
 hw/ppc/pnv.c               |  13 +++++
 hw/ppc/pnv_occ.c           | 136 +++++++++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/pnv.h       |   2 +
 include/hw/ppc/pnv_occ.h   |  38 +++++++++++++
 include/hw/ppc/pnv_xscom.h |   3 +
 6 files changed, 193 insertions(+), 1 deletion(-)
 create mode 100644 hw/ppc/pnv_occ.c
 create mode 100644 include/hw/ppc/pnv_occ.h

diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index dc19ee1..ef67ea8 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -6,7 +6,7 @@ obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o
 obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o spapr_rng.o
 obj-$(CONFIG_PSERIES) += spapr_cpu_core.o spapr_ovec.o
 # IBM PowerNV
-obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_core.o pnv_lpc.o pnv_psi.o
+obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_core.o pnv_lpc.o pnv_psi.o pnv_occ.o
 ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy)
 obj-y += spapr_pci_vfio.o
 endif
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index a516acb..16f32c9 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -694,6 +694,11 @@ static void pnv_chip_init(Object *obj)
     object_property_add_child(obj, "psi", OBJECT(&chip->psi), NULL);
     object_property_add_const_link(OBJECT(&chip->psi), "xics",
                                    OBJECT(qdev_get_machine()), &error_abort);
+
+    object_initialize(&chip->occ, sizeof(chip->occ), TYPE_PNV_OCC);
+    object_property_add_child(obj, "occ", OBJECT(&chip->occ), NULL);
+    object_property_add_const_link(OBJECT(&chip->occ), "psi",
+                                   OBJECT(&chip->psi), &error_abort);
 }
 
 static void pnv_chip_icp_realize(PnvChip *chip, Error **errp)
@@ -816,6 +821,14 @@ static void pnv_chip_realize(DeviceState *dev, Error **errp)
         return;
     }
     pnv_xscom_add_subregion(chip, PNV_XSCOM_PSIHB_BASE, &chip->psi.xscom_regs);
+
+    /* Create the simplified OCC model */
+    object_property_set_bool(OBJECT(&chip->occ), true, "realized", &error);
+    if (error) {
+        error_propagate(errp, error);
+        return;
+    }
+    pnv_xscom_add_subregion(chip, PNV_XSCOM_OCC_BASE, &chip->occ.xscom_regs);
 }
 
 static Property pnv_chip_properties[] = {
diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c
new file mode 100644
index 0000000..04880f2
--- /dev/null
+++ b/hw/ppc/pnv_occ.c
@@ -0,0 +1,136 @@
+/*
+ * QEMU PowerPC PowerNV Emulation of a few OCC related registers
+ *
+ * Copyright (c) 2015-2017, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "sysemu/sysemu.h"
+#include "target/ppc/cpu.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+
+#include "hw/ppc/pnv.h"
+#include "hw/ppc/pnv_xscom.h"
+#include "hw/ppc/pnv_occ.h"
+
+#define OCB_OCI_OCCMISC         0x4020
+#define OCB_OCI_OCCMISC_AND     0x4021
+#define OCB_OCI_OCCMISC_OR      0x4022
+
+static void pnv_occ_set_misc(PnvOCC *occ, uint64_t val)
+{
+    bool irq_state;
+
+    val &= 0xffff000000000000ull;
+
+    occ->occmisc = val;
+    irq_state = !!(val >> 63);
+    pnv_psi_irq_set(occ->psi, PSIHB_IRQ_OCC, irq_state);
+}
+
+static uint64_t pnv_occ_xscom_read(void *opaque, hwaddr addr, unsigned size)
+{
+    PnvOCC *occ = PNV_OCC(opaque);
+    uint32_t offset = addr >> 3;
+    uint64_t val = 0;
+
+    switch (offset) {
+    case OCB_OCI_OCCMISC:
+        val = occ->occmisc;
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
+                      HWADDR_PRIx "\n", addr);
+    }
+    return val;
+}
+
+static void pnv_occ_xscom_write(void *opaque, hwaddr addr,
+                                uint64_t val, unsigned size)
+{
+    PnvOCC *occ = PNV_OCC(opaque);
+    uint32_t offset = addr >> 3;
+
+    switch (offset) {
+    case OCB_OCI_OCCMISC_AND:
+        pnv_occ_set_misc(occ, occ->occmisc & val);
+        break;
+    case OCB_OCI_OCCMISC_OR:
+        pnv_occ_set_misc(occ, occ->occmisc | val);
+        break;
+    case OCB_OCI_OCCMISC:
+        pnv_occ_set_misc(occ, val);
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
+                      HWADDR_PRIx "\n", addr);
+    }
+}
+
+static const MemoryRegionOps pnv_occ_xscom_ops = {
+    .read = pnv_occ_xscom_read,
+    .write = pnv_occ_xscom_write,
+    .valid.min_access_size = 8,
+    .valid.max_access_size = 8,
+    .impl.min_access_size = 8,
+    .impl.max_access_size = 8,
+    .endianness = DEVICE_BIG_ENDIAN,
+};
+
+
+static void pnv_occ_realize(DeviceState *dev, Error **errp)
+{
+    PnvOCC *occ = PNV_OCC(dev);
+    Object *obj;
+    Error *error = NULL;
+
+    occ->occmisc = 0;
+
+    /* get PSI object from chip */
+    obj = object_property_get_link(OBJECT(dev), "psi", &error);
+    if (!obj) {
+        error_setg(errp, "%s: required link 'psi' not found: %s",
+                   __func__, error_get_pretty(error));
+        return;
+    }
+    occ->psi = PNV_PSI(obj);
+
+    /* XScom region for OCC registers */
+    pnv_xscom_region_init(&occ->xscom_regs, OBJECT(dev), &pnv_occ_xscom_ops,
+                  occ, "xscom-occ", PNV_XSCOM_OCC_SIZE);
+}
+
+static void pnv_occ_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = pnv_occ_realize;
+}
+
+static const TypeInfo pnv_occ_type_info = {
+    .name          = TYPE_PNV_OCC,
+    .parent        = TYPE_DEVICE,
+    .instance_size = sizeof(PnvOCC),
+    .class_init    = pnv_occ_class_init,
+};
+
+static void pnv_occ_register_types(void)
+{
+    type_register_static(&pnv_occ_type_info);
+}
+
+type_init(pnv_occ_register_types)
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index a3ed2ee..b45a0d9 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -23,6 +23,7 @@
 #include "hw/sysbus.h"
 #include "hw/ppc/pnv_lpc.h"
 #include "hw/ppc/pnv_psi.h"
+#include "hw/ppc/pnv_occ.h"
 
 #define TYPE_PNV_CHIP "powernv-chip"
 #define PNV_CHIP(obj) OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP)
@@ -59,6 +60,7 @@ typedef struct PnvChip {
 
     PnvLpcController lpc;
     PnvPsi       psi;
+    PnvOCC       occ;
 } PnvChip;
 
 typedef struct PnvChipClass {
diff --git a/include/hw/ppc/pnv_occ.h b/include/hw/ppc/pnv_occ.h
new file mode 100644
index 0000000..f8ec330
--- /dev/null
+++ b/include/hw/ppc/pnv_occ.h
@@ -0,0 +1,38 @@
+/*
+ * QEMU PowerPC PowerNV Emulation of a few OCC related registers
+ *
+ * Copyright (c) 2015-2017, IBM Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _PPC_PNV_OCC_H
+#define _PPC_PNV_OCC_H
+
+#define TYPE_PNV_OCC "pnv-occ"
+#define PNV_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV_OCC)
+
+typedef struct PnvPsi PnvPsi;
+
+typedef struct PnvOCC {
+    DeviceState xd;
+
+    /* OCC Misc interrupt */
+    uint64_t occmisc;
+
+    PnvPsi *psi;
+
+    MemoryRegion xscom_regs;
+} PnvOCC;
+
+#endif /* _PPC_PNV_OCC_H */
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index 15f7fdb..3757b2c 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -63,6 +63,9 @@ typedef struct PnvXScomInterfaceClass {
 #define PNV_XSCOM_PSIHB_BASE      0x2010900
 #define PNV_XSCOM_PSIHB_SIZE      0x20
 
+#define PNV_XSCOM_OCC_BASE        0x0066000
+#define PNV_XSCOM_OCC_SIZE        0x6000
+
 extern void pnv_xscom_realize(PnvChip *chip, Error **errp);
 extern int pnv_xscom_populate(PnvChip *chip, void *fdt, int offset);
 
-- 
2.9.3

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

* [Qemu-devel] [PULL 29/47] ppc: add IPMI support
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (27 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 28/47] ppc/pnv: Add OCC model stub with interrupt support David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 30/47] ipmi: use a file to load SDRs David Gibson
                   ` (19 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

OpenPOWER systems use a BT device to communicate with the BMC.
Provide support for it.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 default-configs/ppc64-softmmu.mak | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
index 05c8335..7f5b56c 100644
--- a/default-configs/ppc64-softmmu.mak
+++ b/default-configs/ppc64-softmmu.mak
@@ -6,6 +6,10 @@ include usb.mak
 CONFIG_VIRTIO_VGA=y
 CONFIG_ESCC=y
 CONFIG_M48T59=y
+CONFIG_IPMI=y
+CONFIG_IPMI_LOCAL=y
+CONFIG_IPMI_EXTERN=y
+CONFIG_ISA_IPMI_BT=y
 CONFIG_SERIAL=y
 CONFIG_PARALLEL=y
 CONFIG_I8254=y
-- 
2.9.3

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

* [Qemu-devel] [PULL 30/47] ipmi: use a file to load SDRs
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (28 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 29/47] ppc: add IPMI support David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 31/47] ipmi: provide support for FRUs David Gibson
                   ` (18 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

The IPMI BMC simulator populates the sdr/sensor tables with a minimal
set of entries (Watchdog). But some qemu platforms might want to use
extra entries for their custom needs.

This patch modifies slighty the initializing routine to take into
account a larger set read from a file. The name of the file to use is
defined through a new 'sdr' property of the simulator device.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Acked-by: Corey Minyard <cminyard@mvista.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ipmi/ipmi_bmc_sim.c | 23 +++++++++++++++++++++--
 qemu-options.hx        | 11 ++++++++++-
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
index c7883d6..1142c0c 100644
--- a/hw/ipmi/ipmi_bmc_sim.c
+++ b/hw/ipmi/ipmi_bmc_sim.c
@@ -27,6 +27,7 @@
 #include "qemu/timer.h"
 #include "hw/ipmi/ipmi.h"
 #include "qemu/error-report.h"
+#include "hw/loader.h"
 
 #define IPMI_NETFN_CHASSIS            0x00
 
@@ -213,6 +214,7 @@ struct IPMIBmcSim {
     IPMISel sel;
     IPMISdr sdr;
     IPMISensor sensors[MAX_SENSORS];
+    char *sdr_filename;
 
     /* Odd netfns are for responses, so we only need the even ones. */
     const IPMINetfn *netfns[MAX_NETFNS / 2];
@@ -1696,22 +1698,33 @@ static void ipmi_sdr_init(IPMIBmcSim *ibs)
 
     sdrs_size = sizeof(init_sdrs);
     sdrs = init_sdrs;
+    if (ibs->sdr_filename &&
+        !g_file_get_contents(ibs->sdr_filename, (gchar **) &sdrs, &sdrs_size,
+                             NULL)) {
+        error_report("failed to load sdr file '%s'", ibs->sdr_filename);
+        sdrs_size = sizeof(init_sdrs);
+        sdrs = init_sdrs;
+    }
 
     for (i = 0; i < sdrs_size; i += len) {
         struct ipmi_sdr_header *sdrh;
 
         if (i + IPMI_SDR_HEADER_SIZE > sdrs_size) {
             error_report("Problem with recid 0x%4.4x", i);
-            return;
+            break;
         }
         sdrh = (struct ipmi_sdr_header *) &sdrs[i];
         len = ipmi_sdr_length(sdrh);
         if (i + len > sdrs_size) {
             error_report("Problem with recid 0x%4.4x", i);
-            return;
+            break;
         }
         sdr_add_entry(ibs, sdrh, len, NULL);
     }
+
+    if (sdrs != init_sdrs) {
+        g_free(sdrs);
+    }
 }
 
 static const VMStateDescription vmstate_ipmi_sim = {
@@ -1780,6 +1793,11 @@ static void ipmi_sim_realize(DeviceState *dev, Error **errp)
     vmstate_register(NULL, 0, &vmstate_ipmi_sim, ibs);
 }
 
+static Property ipmi_sim_properties[] = {
+    DEFINE_PROP_STRING("sdrfile", IPMIBmcSim, sdr_filename),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void ipmi_sim_class_init(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
@@ -1787,6 +1805,7 @@ static void ipmi_sim_class_init(ObjectClass *oc, void *data)
 
     dc->hotpluggable = false;
     dc->realize = ipmi_sim_realize;
+    dc->props = ipmi_sim_properties;
     bk->handle_command = ipmi_sim_handle_command;
 }
 
diff --git a/qemu-options.hx b/qemu-options.hx
index 9171bd5..366b088 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -425,7 +425,7 @@ possible drivers and properties, use @code{-device help} and
 @code{-device @var{driver},help}.
 
 Some drivers are:
-@item -device ipmi-bmc-sim,id=@var{id}[,slave_addr=@var{val}]
+@item -device ipmi-bmc-sim,id=@var{id}[,slave_addr=@var{val}][,sdrfile=@var{file}]
 
 Add an IPMI BMC.  This is a simulation of a hardware management
 interface processor that normally sits on a system.  It provides
@@ -437,6 +437,15 @@ This address is the BMC's address on the I2C network of management
 controllers.  If you don't know what this means, it is safe to ignore
 it.
 
+@table @option
+@item bmc=@var{id}
+The BMC to connect to, one of ipmi-bmc-sim or ipmi-bmc-extern above.
+@item slave_addr=@var{val}
+Define slave address to use for the BMC.  The default is 0x20.
+@item sdrfile=@var{file}
+file containing raw Sensor Data Records (SDR) data.  The default is none.
+@end table
+
 @item -device ipmi-bmc-extern,id=@var{id},chardev=@var{id}[,slave_addr=@var{val}]
 
 Add a connection to an external IPMI BMC simulator.  Instead of
-- 
2.9.3

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

* [Qemu-devel] [PULL 31/47] ipmi: provide support for FRUs
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (29 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 30/47] ipmi: use a file to load SDRs David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 32/47] ipmi: introduce an ipmi_bmc_sdr_find() API David Gibson
                   ` (17 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

This patch provides a simple FRU support for the BMC simulator. FRUs
are loaded from a file which name is specified in the object
properties, each entry having a fixed size, also specified in the
properties. If the file is unknown or not accessible for some reason,
a unique entry of 1024 bytes is created as a default. Just enough to
start some simulation.

These commands complies with the IPMI spec : "34. FRU Inventory Device
Commands".

Signed-off-by: Cédric Le Goater <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 | 128 +++++++++++++++++++++++++++++++++++++++++++++++++
 qemu-options.hx        |   8 +++-
 2 files changed, 134 insertions(+), 2 deletions(-)

diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
index 1142c0c..eae7b2d 100644
--- a/hw/ipmi/ipmi_bmc_sim.c
+++ b/hw/ipmi/ipmi_bmc_sim.c
@@ -80,6 +80,9 @@
 #define IPMI_CMD_ENTER_SDR_REP_UPD_MODE   0x2A
 #define IPMI_CMD_EXIT_SDR_REP_UPD_MODE    0x2B
 #define IPMI_CMD_RUN_INIT_AGENT           0x2C
+#define IPMI_CMD_GET_FRU_AREA_INFO        0x10
+#define IPMI_CMD_READ_FRU_DATA            0x11
+#define IPMI_CMD_WRITE_FRU_DATA           0x12
 #define IPMI_CMD_GET_SEL_INFO             0x40
 #define IPMI_CMD_GET_SEL_ALLOC_INFO       0x41
 #define IPMI_CMD_RESERVE_SEL              0x42
@@ -122,6 +125,13 @@ typedef struct IPMISdr {
     uint8_t overflow;
 } IPMISdr;
 
+typedef struct IPMIFru {
+    char *filename;
+    unsigned int nentries;
+    uint16_t areasize;
+    uint8_t *data;
+} IPMIFru;
+
 typedef struct IPMISensor {
     uint8_t status;
     uint8_t reading;
@@ -213,6 +223,7 @@ struct IPMIBmcSim {
 
     IPMISel sel;
     IPMISdr sdr;
+    IPMIFru fru;
     IPMISensor sensors[MAX_SENSORS];
     char *sdr_filename;
 
@@ -1317,6 +1328,91 @@ static void get_sel_info(IPMIBmcSim *ibs,
     rsp_buffer_push(rsp, (ibs->sel.overflow << 7) | 0x02);
 }
 
+static void get_fru_area_info(IPMIBmcSim *ibs,
+                         uint8_t *cmd, unsigned int cmd_len,
+                         RspBuffer *rsp)
+{
+    uint8_t fruid;
+    uint16_t fru_entry_size;
+
+    fruid = cmd[2];
+
+    if (fruid >= ibs->fru.nentries) {
+        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
+        return;
+    }
+
+    fru_entry_size = ibs->fru.areasize;
+
+    rsp_buffer_push(rsp, fru_entry_size & 0xff);
+    rsp_buffer_push(rsp, fru_entry_size >> 8 & 0xff);
+    rsp_buffer_push(rsp, 0x0);
+}
+
+static void read_fru_data(IPMIBmcSim *ibs,
+                         uint8_t *cmd, unsigned int cmd_len,
+                         RspBuffer *rsp)
+{
+    uint8_t fruid;
+    uint16_t offset;
+    int i;
+    uint8_t *fru_entry;
+    unsigned int count;
+
+    fruid = cmd[2];
+    offset = (cmd[3] | cmd[4] << 8);
+
+    if (fruid >= ibs->fru.nentries) {
+        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
+        return;
+    }
+
+    if (offset >= ibs->fru.areasize - 1) {
+        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
+        return;
+    }
+
+    fru_entry = &ibs->fru.data[fruid * ibs->fru.areasize];
+
+    count = MIN(cmd[5], ibs->fru.areasize - offset);
+
+    rsp_buffer_push(rsp, count & 0xff);
+    for (i = 0; i < count; i++) {
+        rsp_buffer_push(rsp, fru_entry[offset + i]);
+    }
+}
+
+static void write_fru_data(IPMIBmcSim *ibs,
+                         uint8_t *cmd, unsigned int cmd_len,
+                         RspBuffer *rsp)
+{
+    uint8_t fruid;
+    uint16_t offset;
+    uint8_t *fru_entry;
+    unsigned int count;
+
+    fruid = cmd[2];
+    offset = (cmd[3] | cmd[4] << 8);
+
+    if (fruid >= ibs->fru.nentries) {
+        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
+        return;
+    }
+
+    if (offset >= ibs->fru.areasize - 1) {
+        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
+        return;
+    }
+
+    fru_entry = &ibs->fru.data[fruid * ibs->fru.areasize];
+
+    count = MIN(cmd_len - 5, ibs->fru.areasize - offset);
+
+    memcpy(fru_entry + offset, cmd + 5, count);
+
+    rsp_buffer_push(rsp, count & 0xff);
+}
+
 static void reserve_sel(IPMIBmcSim *ibs,
                         uint8_t *cmd, unsigned int cmd_len,
                         RspBuffer *rsp)
@@ -1653,6 +1749,9 @@ static const IPMINetfn app_netfn = {
 };
 
 static const IPMICmdHandler storage_cmds[] = {
+    [IPMI_CMD_GET_FRU_AREA_INFO] = { get_fru_area_info, 3 },
+    [IPMI_CMD_READ_FRU_DATA] = { read_fru_data, 5 },
+    [IPMI_CMD_WRITE_FRU_DATA] = { write_fru_data, 5 },
     [IPMI_CMD_GET_SDR_REP_INFO] = { get_sdr_rep_info },
     [IPMI_CMD_RESERVE_SDR_REP] = { reserve_sdr_rep },
     [IPMI_CMD_GET_SDR] = { get_sdr, 8 },
@@ -1755,6 +1854,31 @@ static const VMStateDescription vmstate_ipmi_sim = {
     }
 };
 
+static void ipmi_fru_init(IPMIFru *fru)
+{
+    int fsize;
+    int size = 0;
+
+    fsize = get_image_size(fru->filename);
+    if (fsize > 0) {
+        size = QEMU_ALIGN_UP(fsize, fru->areasize);
+        fru->data = g_malloc0(size);
+        if (load_image_size(fru->filename, fru->data, fsize) != fsize) {
+            error_report("Could not load file '%s'", fru->filename);
+            g_free(fru->data);
+            fru->data = NULL;
+        }
+    }
+
+    if (!fru->data) {
+        /* give one default FRU */
+        size = fru->areasize;
+        fru->data = g_malloc0(size);
+    }
+
+    fru->nentries = size / fru->areasize;
+}
+
 static void ipmi_sim_realize(DeviceState *dev, Error **errp)
 {
     IPMIBmc *b = IPMI_BMC(dev);
@@ -1776,6 +1900,8 @@ static void ipmi_sim_realize(DeviceState *dev, Error **errp)
 
     ipmi_sdr_init(ibs);
 
+    ipmi_fru_init(&ibs->fru);
+
     ibs->acpi_power_state[0] = 0;
     ibs->acpi_power_state[1] = 0;
 
@@ -1794,6 +1920,8 @@ static void ipmi_sim_realize(DeviceState *dev, Error **errp)
 }
 
 static Property ipmi_sim_properties[] = {
+    DEFINE_PROP_UINT16("fruareasize", IPMIBmcSim, fru.areasize, 1024),
+    DEFINE_PROP_STRING("frudatafile", IPMIBmcSim, fru.filename),
     DEFINE_PROP_STRING("sdrfile", IPMIBmcSim, sdr_filename),
     DEFINE_PROP_END_OF_LIST(),
 };
diff --git a/qemu-options.hx b/qemu-options.hx
index 366b088..39770c1 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -425,7 +425,7 @@ possible drivers and properties, use @code{-device help} and
 @code{-device @var{driver},help}.
 
 Some drivers are:
-@item -device ipmi-bmc-sim,id=@var{id}[,slave_addr=@var{val}][,sdrfile=@var{file}]
+@item -device ipmi-bmc-sim,id=@var{id}[,slave_addr=@var{val}][,sdrfile=@var{file}][,furareasize=@var{val}][,furdatafile=@var{file}]
 
 Add an IPMI BMC.  This is a simulation of a hardware management
 interface processor that normally sits on a system.  It provides
@@ -443,7 +443,11 @@ The BMC to connect to, one of ipmi-bmc-sim or ipmi-bmc-extern above.
 @item slave_addr=@var{val}
 Define slave address to use for the BMC.  The default is 0x20.
 @item sdrfile=@var{file}
-file containing raw Sensor Data Records (SDR) data.  The default is none.
+file containing raw Sensor Data Records (SDR) data. The default is none.
+@item fruareasize=@var{val}
+size of a Field Replaceable Unit (FRU) area.  The default is 1024.
+@item frudatafile=@var{file}
+file containing raw Field Replaceable Unit (FRU) inventory data. The default is none.
 @end table
 
 @item -device ipmi-bmc-extern,id=@var{id},chardev=@var{id}[,slave_addr=@var{val}]
-- 
2.9.3

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

* [Qemu-devel] [PULL 32/47] ipmi: introduce an ipmi_bmc_sdr_find() API
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (30 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 31/47] ipmi: provide support for FRUs David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 33/47] ipmi: introduce an ipmi_bmc_gen_event() API David Gibson
                   ` (16 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

This patch exposes a new IPMI routine to query a sdr entry from the
sdr table maintained by the IPMI BMC simulator. The API is very
similar to the internal sdr_find_entry() routine and should be used
the same way to query one or all sdrs.

A typical use would be to loop on the sdrs to build nodes of a device
tree.

Signed-off-by: Cédric Le Goater <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 | 16 ++++++++++++++++
 include/hw/ipmi/ipmi.h |  2 ++
 2 files changed, 18 insertions(+)

diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
index eae7b2d..8185a84 100644
--- a/hw/ipmi/ipmi_bmc_sim.c
+++ b/hw/ipmi/ipmi_bmc_sim.c
@@ -416,6 +416,22 @@ static int sdr_find_entry(IPMISdr *sdr, uint16_t recid,
     return 1;
 }
 
+int ipmi_bmc_sdr_find(IPMIBmc *b, uint16_t recid,
+                      const struct ipmi_sdr_compact **sdr, uint16_t *nextrec)
+
+{
+    IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b);
+    unsigned int pos;
+
+    pos = 0;
+    if (sdr_find_entry(&ibs->sdr, recid, &pos, nextrec)) {
+        return -1;
+    }
+
+    *sdr = (const struct ipmi_sdr_compact *) &ibs->sdr.sdr[pos];
+    return 0;
+}
+
 static void sel_inc_reservation(IPMISel *sel)
 {
     sel->reservation++;
diff --git a/include/hw/ipmi/ipmi.h b/include/hw/ipmi/ipmi.h
index 91b83b5..0d36cfc 100644
--- a/include/hw/ipmi/ipmi.h
+++ b/include/hw/ipmi/ipmi.h
@@ -259,4 +259,6 @@ struct ipmi_sdr_compact {
 
 typedef uint8_t ipmi_sdr_compact_buffer[sizeof(struct ipmi_sdr_compact)];
 
+int ipmi_bmc_sdr_find(IPMIBmc *b, uint16_t recid,
+                      const struct ipmi_sdr_compact **sdr, uint16_t *nextrec);
 #endif
-- 
2.9.3

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

* [Qemu-devel] [PULL 33/47] ipmi: introduce an ipmi_bmc_gen_event() API
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (31 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 32/47] ipmi: introduce an ipmi_bmc_sdr_find() API David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 34/47] target/ppc: Fix size of struct PPCElfPrstatus David Gibson
                   ` (15 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

It will be used to fill the message buffer with custom events expected
by some systems. Typically, an Open PowerNV platform guest is notified
with an OEM SEL message before a shutdown or a reboot.

Signed-off-by: Cédric Le Goater <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 | 24 ++++++++++++++++++++++++
 include/hw/ipmi/ipmi.h |  2 ++
 2 files changed, 26 insertions(+)

diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
index 8185a84..155561d 100644
--- a/hw/ipmi/ipmi_bmc_sim.c
+++ b/hw/ipmi/ipmi_bmc_sim.c
@@ -473,6 +473,30 @@ static int attn_irq_enabled(IPMIBmcSim *ibs)
             IPMI_BMC_MSG_FLAG_EVT_BUF_FULL_SET(ibs));
 }
 
+void ipmi_bmc_gen_event(IPMIBmc *b, uint8_t *evt, bool log)
+{
+    IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b);
+    IPMIInterface *s = ibs->parent.intf;
+    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
+
+    if (!IPMI_BMC_EVENT_MSG_BUF_ENABLED(ibs)) {
+        return;
+    }
+
+    if (log && IPMI_BMC_EVENT_LOG_ENABLED(ibs)) {
+        sel_add_event(ibs, evt);
+    }
+
+    if (ibs->msg_flags & IPMI_BMC_MSG_FLAG_EVT_BUF_FULL) {
+        goto out;
+    }
+
+    memcpy(ibs->evtbuf, evt, 16);
+    ibs->msg_flags |= IPMI_BMC_MSG_FLAG_EVT_BUF_FULL;
+    k->set_atn(s, 1, attn_irq_enabled(ibs));
+ out:
+    return;
+}
 static void gen_event(IPMIBmcSim *ibs, unsigned int sens_num, uint8_t deassert,
                       uint8_t evd1, uint8_t evd2, uint8_t evd3)
 {
diff --git a/include/hw/ipmi/ipmi.h b/include/hw/ipmi/ipmi.h
index 0d36cfc..0affe5a 100644
--- a/include/hw/ipmi/ipmi.h
+++ b/include/hw/ipmi/ipmi.h
@@ -261,4 +261,6 @@ typedef uint8_t ipmi_sdr_compact_buffer[sizeof(struct ipmi_sdr_compact)];
 
 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);
+
 #endif
-- 
2.9.3

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

* [Qemu-devel] [PULL 34/47] target/ppc: Fix size of struct PPCElfPrstatus
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (32 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 33/47] ipmi: introduce an ipmi_bmc_gen_event() API David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 35/47] spapr: remove the 'nr_servers' field from the machine David Gibson
                   ` (14 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell
  Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, Anton Blanchard,
	David Gibson

From: Anton Blanchard <anton@samba.org>

gdb refuses to parse QEMU memory dumps because struct PPCElfPrstatus
is the wrong size. Fix it.

Signed-off-by: Anton Blanchard <anton@samba.org>
Fixes: e62fbc54d459 ("target-ppc: dump-guest-memory support")
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/arch_dump.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/ppc/arch_dump.c b/target/ppc/arch_dump.c
index 28d9cc7..8e9397a 100644
--- a/target/ppc/arch_dump.c
+++ b/target/ppc/arch_dump.c
@@ -50,7 +50,7 @@ struct PPCUserRegStruct {
 struct PPCElfPrstatus {
     char pad1[112];
     struct PPCUserRegStruct pr_reg;
-    reg_t pad2[4];
+    char pad2[40];
 } QEMU_PACKED;
 
 
-- 
2.9.3

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

* [Qemu-devel] [PULL 35/47] spapr: remove the 'nr_servers' field from the machine
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (33 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 34/47] target/ppc: Fix size of struct PPCElfPrstatus David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 36/47] ppc/pnv: Add support for POWER8+ LPC Controller David Gibson
                   ` (13 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

xics_system_init() does not need 'nr_servers' anymore as it is only
used to define the 'interrupt-controller' node in the device tree. So
let's just compute the value when calling spapr_dt_xics().

This also gives us an opportunity to simplify the xics_system_init()
routine and introduce a specific spapr_ics_create() helper to create
the sPAPR ICS object.

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

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 703b14a..80d12d0 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -97,45 +97,40 @@
 
 #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
 
-static int try_create_xics(sPAPRMachineState *spapr, const char *type_ics,
-                           const char *type_icp, int nr_servers,
-                           int nr_irqs, Error **errp)
+static ICSState *spapr_ics_create(sPAPRMachineState *spapr,
+                                  const char *type_ics,
+                                  int nr_irqs, Error **errp)
 {
-    XICSFabric *xi = XICS_FABRIC(spapr);
     Error *err = NULL, *local_err = NULL;
-    ICSState *ics = NULL;
+    Object *obj;
 
-    ics = ICS_SIMPLE(object_new(type_ics));
-    object_property_add_child(OBJECT(spapr), "ics", OBJECT(ics), NULL);
-    object_property_set_int(OBJECT(ics), nr_irqs, "nr-irqs", &err);
-    object_property_add_const_link(OBJECT(ics), "xics", OBJECT(xi), NULL);
-    object_property_set_bool(OBJECT(ics), true, "realized", &local_err);
+    obj = object_new(type_ics);
+    object_property_add_child(OBJECT(spapr), "ics", obj, NULL);
+    object_property_add_const_link(obj, "xics", OBJECT(spapr), &error_abort);
+    object_property_set_int(obj, nr_irqs, "nr-irqs", &err);
+    object_property_set_bool(obj, true, "realized", &local_err);
     error_propagate(&err, local_err);
     if (err) {
         error_propagate(errp, err);
-        return -1;
+        return NULL;
     }
 
-    spapr->nr_servers = nr_servers;
-    spapr->ics = ics;
-    spapr->icp_type = type_icp;
-    return 0;
+    return ICS_SIMPLE(obj);
 }
 
-static int xics_system_init(MachineState *machine,
-                            int nr_servers, int nr_irqs, Error **errp)
+static void xics_system_init(MachineState *machine, int nr_irqs, Error **errp)
 {
-    int rc = -1;
+    sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
 
     if (kvm_enabled()) {
         Error *err = NULL;
 
         if (machine_kernel_irqchip_allowed(machine) &&
-            !xics_kvm_init(SPAPR_MACHINE(machine), errp)) {
-            rc = try_create_xics(SPAPR_MACHINE(machine), TYPE_ICS_KVM,
-                                 TYPE_KVM_ICP, nr_servers, nr_irqs, &err);
+            !xics_kvm_init(spapr, errp)) {
+            spapr->icp_type = TYPE_KVM_ICP;
+            spapr->ics = spapr_ics_create(spapr, TYPE_ICS_KVM, nr_irqs, &err);
         }
-        if (machine_kernel_irqchip_required(machine) && rc < 0) {
+        if (machine_kernel_irqchip_required(machine) && !spapr->ics) {
             error_reportf_err(err,
                               "kernel_irqchip requested but unavailable: ");
         } else {
@@ -143,13 +138,11 @@ static int xics_system_init(MachineState *machine,
         }
     }
 
-    if (rc < 0) {
-        xics_spapr_init(SPAPR_MACHINE(machine), errp);
-        rc = try_create_xics(SPAPR_MACHINE(machine), TYPE_ICS_SIMPLE,
-                               TYPE_ICP, nr_servers, nr_irqs, errp);
+    if (!spapr->ics) {
+        xics_spapr_init(spapr, errp);
+        spapr->icp_type = TYPE_ICP;
+        spapr->ics = spapr_ics_create(spapr, TYPE_ICS_SIMPLE, nr_irqs, errp);
     }
-
-    return rc;
 }
 
 static int spapr_fixup_cpu_smt_dt(void *fdt, int offset, PowerPCCPU *cpu,
@@ -977,6 +970,7 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr,
     void *fdt;
     sPAPRPHBState *phb;
     char *buf;
+    int smt = kvmppc_smt_threads();
 
     fdt = g_malloc0(FDT_MAX_SIZE);
     _FDT((fdt_create_empty_tree(fdt, FDT_MAX_SIZE)));
@@ -1016,7 +1010,7 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr,
     _FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2));
 
     /* /interrupt controller */
-    spapr_dt_xics(spapr->nr_servers, fdt, PHANDLE_XICP);
+    spapr_dt_xics(DIV_ROUND_UP(max_cpus * smt, smp_threads), fdt, PHANDLE_XICP);
 
     ret = spapr_populate_memory(spapr, fdt);
     if (ret < 0) {
@@ -2045,7 +2039,6 @@ static void ppc_spapr_init(MachineState *machine)
     hwaddr node0_size = spapr_node0_size();
     long load_limit, fw_size;
     char *filename;
-    int smt = kvmppc_smt_threads();
 
     msi_nonbroken = true;
 
@@ -2096,8 +2089,7 @@ static void ppc_spapr_init(MachineState *machine)
     load_limit = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FW_OVERHEAD;
 
     /* Set up Interrupt Controller before we create the VCPUs */
-    xics_system_init(machine, DIV_ROUND_UP(max_cpus * smt, smp_threads),
-                     XICS_IRQS_SPAPR, &error_fatal);
+    xics_system_init(machine, XICS_IRQS_SPAPR, &error_fatal);
 
     /* Set up containers for ibm,client-set-architecture negotiated options */
     spapr->ov5 = spapr_ovec_new();
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 7dbba57..5802f88 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -108,7 +108,6 @@ struct sPAPRMachineState {
     char *kvm_type;
     MemoryHotplugState hotplug_memory;
 
-    uint32_t nr_servers;
     const char *icp_type;
 };
 
-- 
2.9.3

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

* [Qemu-devel] [PULL 36/47] ppc/pnv: Add support for POWER8+ LPC Controller
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (34 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 35/47] spapr: remove the 'nr_servers' field from the machine David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 37/47] ppc/pnv: enable only one LPC bus David Gibson
                   ` (12 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell
  Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg,
	Benjamin Herrenschmidt, David Gibson

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

It adds the Naples chip which supports proper LPC interrupts via the
LPC controller rather than via an external CPLD.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
[clg: - updated for qemu-2.9
      - ported on latest PowerNV patchset
      - moved the IRQ handler in pnv_lpc.c
      - introduced pnv_lpc_isa_irq_create() to create the ISA IRQs ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/pnv.c             | 45 +++-------------------
 hw/ppc/pnv_lpc.c         | 97 +++++++++++++++++++++++++++++++++++++++++++++++-
 include/hw/ppc/pnv_lpc.h |  8 ++++
 3 files changed, 108 insertions(+), 42 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 16f32c9..27589b9 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -346,36 +346,6 @@ static void ppc_powernv_reset(void)
     cpu_physical_memory_write(PNV_FDT_ADDR, fdt, fdt_totalsize(fdt));
 }
 
-/* If we don't use the built-in LPC interrupt deserializer, we need
- * to provide a set of qirqs for the ISA bus or things will go bad.
- *
- * Most machines using pre-Naples chips (without said deserializer)
- * have a CPLD that will collect the SerIRQ and shoot them as a
- * single level interrupt to the P8 chip. So let's setup a hook
- * for doing just that.
- */
-static void pnv_lpc_isa_irq_handler_cpld(void *opaque, int n, int level)
-{
-    PnvMachineState *pnv = POWERNV_MACHINE(qdev_get_machine());
-    uint32_t old_state = pnv->cpld_irqstate;
-    PnvChip *chip = opaque;
-
-    if (level) {
-        pnv->cpld_irqstate |= 1u << n;
-    } else {
-        pnv->cpld_irqstate &= ~(1u << n);
-    }
-    if (pnv->cpld_irqstate != old_state) {
-        pnv_psi_irq_set(&chip->psi, PSIHB_IRQ_EXTERNAL,
-                        pnv->cpld_irqstate != 0);
-    }
-}
-
-static void pnv_lpc_isa_irq_handler(void *opaque, int n, int level)
-{
-     /* XXX TODO */
-}
-
 static ISABus *pnv_isa_create(PnvChip *chip)
 {
     PnvLpcController *lpc = &chip->lpc;
@@ -390,16 +360,7 @@ static ISABus *pnv_isa_create(PnvChip *chip)
     isa_bus = isa_bus_new(NULL, &lpc->isa_mem, &lpc->isa_io,
                           &error_fatal);
 
-    /* Not all variants have a working serial irq decoder. If not,
-     * handling of LPC interrupts becomes a platform issue (some
-     * platforms have a CPLD to do it).
-     */
-    if (pcc->chip_type == PNV_CHIP_POWER8NVL) {
-        irqs = qemu_allocate_irqs(pnv_lpc_isa_irq_handler, chip, ISA_NUM_IRQS);
-    } else {
-        irqs = qemu_allocate_irqs(pnv_lpc_isa_irq_handler_cpld, chip,
-                                  ISA_NUM_IRQS);
-    }
+    irqs = pnv_lpc_isa_irq_create(lpc, pcc->chip_type, ISA_NUM_IRQS);
 
     isa_bus_irqs(isa_bus, irqs);
     return isa_bus;
@@ -699,6 +660,10 @@ static void pnv_chip_init(Object *obj)
     object_property_add_child(obj, "occ", OBJECT(&chip->occ), NULL);
     object_property_add_const_link(OBJECT(&chip->occ), "psi",
                                    OBJECT(&chip->psi), &error_abort);
+
+    /* The LPC controller needs PSI to generate interrupts */
+    object_property_add_const_link(OBJECT(&chip->lpc), "psi",
+                                   OBJECT(&chip->psi), &error_abort);
 }
 
 static void pnv_chip_icp_realize(PnvChip *chip, Error **errp)
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index 78db524..5d20c15 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -250,6 +250,34 @@ static const MemoryRegionOps pnv_lpc_xscom_ops = {
     .endianness = DEVICE_BIG_ENDIAN,
 };
 
+static void pnv_lpc_eval_irqs(PnvLpcController *lpc)
+{
+    bool lpc_to_opb_irq = false;
+
+    /* Update LPC controller to OPB line */
+    if (lpc->lpc_hc_irqser_ctrl & LPC_HC_IRQSER_EN) {
+        uint32_t irqs;
+
+        irqs = lpc->lpc_hc_irqstat & lpc->lpc_hc_irqmask;
+        lpc_to_opb_irq = (irqs != 0);
+    }
+
+    /* We don't honor the polarity register, it's pointless and unused
+     * anyway
+     */
+    if (lpc_to_opb_irq) {
+        lpc->opb_irq_input |= OPB_MASTER_IRQ_LPC;
+    } else {
+        lpc->opb_irq_input &= ~OPB_MASTER_IRQ_LPC;
+    }
+
+    /* Update OPB internal latch */
+    lpc->opb_irq_stat |= lpc->opb_irq_input & lpc->opb_irq_mask;
+
+    /* Reflect the interrupt */
+    pnv_psi_irq_set(lpc->psi, PSIHB_IRQ_LPC_I2C, lpc->opb_irq_stat != 0);
+}
+
 static uint64_t lpc_hc_read(void *opaque, hwaddr addr, unsigned size)
 {
     PnvLpcController *lpc = opaque;
@@ -300,12 +328,15 @@ static void lpc_hc_write(void *opaque, hwaddr addr, uint64_t val,
         break;
     case LPC_HC_IRQSER_CTRL:
         lpc->lpc_hc_irqser_ctrl = val;
+        pnv_lpc_eval_irqs(lpc);
         break;
     case LPC_HC_IRQMASK:
         lpc->lpc_hc_irqmask = val;
+        pnv_lpc_eval_irqs(lpc);
         break;
     case LPC_HC_IRQSTAT:
         lpc->lpc_hc_irqstat &= ~val;
+        pnv_lpc_eval_irqs(lpc);
         break;
     case LPC_HC_ERROR_ADDRESS:
         break;
@@ -363,14 +394,15 @@ static void opb_master_write(void *opaque, hwaddr addr,
     switch (addr) {
     case OPB_MASTER_LS_IRQ_STAT:
         lpc->opb_irq_stat &= ~val;
+        pnv_lpc_eval_irqs(lpc);
         break;
     case OPB_MASTER_LS_IRQ_MASK:
-        /* XXX Filter out reserved bits */
         lpc->opb_irq_mask = val;
+        pnv_lpc_eval_irqs(lpc);
         break;
     case OPB_MASTER_LS_IRQ_POL:
-        /* XXX Filter out reserved bits */
         lpc->opb_irq_pol = val;
+        pnv_lpc_eval_irqs(lpc);
         break;
     case OPB_MASTER_LS_IRQ_INPUT:
         /* Read only */
@@ -398,6 +430,8 @@ static const MemoryRegionOps opb_master_ops = {
 static void pnv_lpc_realize(DeviceState *dev, Error **errp)
 {
     PnvLpcController *lpc = PNV_LPC(dev);
+    Object *obj;
+    Error *error = NULL;
 
     /* Reg inits */
     lpc->lpc_hc_fw_rd_acc_size = LPC_HC_FW_RD_4B;
@@ -441,6 +475,15 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
     pnv_xscom_region_init(&lpc->xscom_regs, OBJECT(dev),
                           &pnv_lpc_xscom_ops, lpc, "xscom-lpc",
                           PNV_XSCOM_LPC_SIZE);
+
+    /* get PSI object from chip */
+    obj = object_property_get_link(OBJECT(dev), "psi", &error);
+    if (!obj) {
+        error_setg(errp, "%s: required link 'psi' not found: %s",
+                   __func__, error_get_pretty(error));
+        return;
+    }
+    lpc->psi = PNV_PSI(obj);
 }
 
 static void pnv_lpc_class_init(ObjectClass *klass, void *data)
@@ -470,3 +513,53 @@ static void pnv_lpc_register_types(void)
 }
 
 type_init(pnv_lpc_register_types)
+
+/* If we don't use the built-in LPC interrupt deserializer, we need
+ * to provide a set of qirqs for the ISA bus or things will go bad.
+ *
+ * Most machines using pre-Naples chips (without said deserializer)
+ * have a CPLD that will collect the SerIRQ and shoot them as a
+ * single level interrupt to the P8 chip. So let's setup a hook
+ * for doing just that.
+ */
+static void pnv_lpc_isa_irq_handler_cpld(void *opaque, int n, int level)
+{
+    PnvMachineState *pnv = POWERNV_MACHINE(qdev_get_machine());
+    uint32_t old_state = pnv->cpld_irqstate;
+    PnvLpcController *lpc = PNV_LPC(opaque);
+
+    if (level) {
+        pnv->cpld_irqstate |= 1u << n;
+    } else {
+        pnv->cpld_irqstate &= ~(1u << n);
+    }
+
+    if (pnv->cpld_irqstate != old_state) {
+        pnv_psi_irq_set(lpc->psi, PSIHB_IRQ_EXTERNAL, pnv->cpld_irqstate != 0);
+    }
+}
+
+static void pnv_lpc_isa_irq_handler(void *opaque, int n, int level)
+{
+    PnvLpcController *lpc = PNV_LPC(opaque);
+
+    /* The Naples HW latches the 1 levels, clearing is done by SW */
+    if (level) {
+        lpc->lpc_hc_irqstat |= LPC_HC_IRQ_SERIRQ0 >> n;
+        pnv_lpc_eval_irqs(lpc);
+    }
+}
+
+qemu_irq *pnv_lpc_isa_irq_create(PnvLpcController *lpc, int chip_type,
+                                 int nirqs)
+{
+    /* Not all variants have a working serial irq decoder. If not,
+     * handling of LPC interrupts becomes a platform issue (some
+     * platforms have a CPLD to do it).
+     */
+    if (chip_type == PNV_CHIP_POWER8NVL) {
+        return qemu_allocate_irqs(pnv_lpc_isa_irq_handler, lpc, nirqs);
+    } else {
+        return qemu_allocate_irqs(pnv_lpc_isa_irq_handler_cpld, lpc, nirqs);
+    }
+}
diff --git a/include/hw/ppc/pnv_lpc.h b/include/hw/ppc/pnv_lpc.h
index 38e5506..ccf969a 100644
--- a/include/hw/ppc/pnv_lpc.h
+++ b/include/hw/ppc/pnv_lpc.h
@@ -23,6 +23,8 @@
 #define PNV_LPC(obj) \
      OBJECT_CHECK(PnvLpcController, (obj), TYPE_PNV_LPC)
 
+typedef struct PnvPsi PnvPsi;
+
 typedef struct PnvLpcController {
     DeviceState parent;
 
@@ -62,6 +64,12 @@ typedef struct PnvLpcController {
 
     /* XSCOM registers */
     MemoryRegion xscom_regs;
+
+    /* PSI to generate interrupts */
+    PnvPsi *psi;
 } PnvLpcController;
 
+qemu_irq *pnv_lpc_isa_irq_create(PnvLpcController *lpc, int chip_type,
+                                 int nirqs);
+
 #endif /* _PPC_PNV_LPC_H */
-- 
2.9.3

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

* [Qemu-devel] [PULL 37/47] ppc/pnv: enable only one LPC bus
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (35 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 36/47] ppc/pnv: Add support for POWER8+ LPC Controller David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 38/47] ppc/pnv: scan ISA bus to populate device tree David Gibson
                   ` (11 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

The default LPC bus of a multichip system is on chip 0. It's
recognized by the firmware (skiboot) using a "primary" property in the
device tree.

We introduce a pnv_chip_lpc_offset() routine to locate the LPC node of
a chip and set the property directly from the machine level.

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

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 27589b9..9468e99 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -255,6 +255,18 @@ static void powernv_populate_icp(PnvChip *chip, void *fdt, uint32_t pir,
     g_free(reg);
 }
 
+static int pnv_chip_lpc_offset(PnvChip *chip, void *fdt)
+{
+    char *name;
+    int offset;
+
+    name = g_strdup_printf("/xscom@%" PRIx64 "/isa@%x",
+                           (uint64_t) PNV_XSCOM_BASE(chip), PNV_XSCOM_LPC_BASE);
+    offset = fdt_path_offset(fdt, name);
+    g_free(name);
+    return offset;
+}
+
 static void powernv_populate_chip(PnvChip *chip, void *fdt)
 {
     PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
@@ -264,6 +276,16 @@ static void powernv_populate_chip(PnvChip *chip, void *fdt)
 
     pnv_xscom_populate(chip, fdt, 0);
 
+    /* The default LPC bus of a multichip system is on chip 0. It's
+     * recognized by the firmware (skiboot) using a "primary"
+     * property.
+     */
+    if (chip->chip_id == 0x0) {
+        int lpc_offset = pnv_chip_lpc_offset(chip, fdt);
+
+        _FDT((fdt_setprop(fdt, lpc_offset, "primary", NULL, 0)));
+    }
+
     for (i = 0; i < chip->nr_cores; i++) {
         PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
 
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index 5d20c15..f03a80a 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -92,14 +92,6 @@ enum {
 #define LPC_HC_REGS_OPB_SIZE    0x00001000
 
 
-/*
- * TODO: the "primary" cell should only be added on chip 0. This is
- * how skiboot chooses the default LPC controller on multichip
- * systems.
- *
- * It would be easly done if we can change the populate() interface to
- * replace the PnvXScomInterface parameter by a PnvChip one
- */
 static int pnv_lpc_populate(PnvXScomInterface *dev, void *fdt, int xscom_offset)
 {
     const char compat[] = "ibm,power8-lpc\0ibm,lpc";
@@ -119,7 +111,6 @@ static int pnv_lpc_populate(PnvXScomInterface *dev, void *fdt, int xscom_offset)
     _FDT((fdt_setprop(fdt, offset, "reg", reg, sizeof(reg))));
     _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 2)));
     _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 1)));
-    _FDT((fdt_setprop(fdt, offset, "primary", NULL, 0)));
     _FDT((fdt_setprop(fdt, offset, "compatible", compat, sizeof(compat))));
     return 0;
 }
-- 
2.9.3

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

* [Qemu-devel] [PULL 38/47] ppc/pnv: scan ISA bus to populate device tree
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (36 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 37/47] ppc/pnv: enable only one LPC bus David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 39/47] ppc/pnv: populate device tree for RTC devices David Gibson
                   ` (10 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

This is an empty shell that we will use to include nodes in the device
tree for ISA devices. We expect RTC, UART and IPMI BT devices.

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

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 9468e99..c445906 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -303,6 +303,29 @@ static void powernv_populate_chip(PnvChip *chip, void *fdt)
     g_free(typename);
 }
 
+typedef struct ForeachPopulateArgs {
+    void *fdt;
+    int offset;
+} ForeachPopulateArgs;
+
+static int powernv_populate_isa_device(DeviceState *dev, void *opaque)
+{
+    return 0;
+}
+
+static void powernv_populate_isa(ISABus *bus, void *fdt, int lpc_offset)
+{
+    ForeachPopulateArgs args = {
+        .fdt = fdt,
+        .offset = lpc_offset,
+    };
+
+    /* ISA devices are not necessarily parented to the ISA bus so we
+     * can not use object_child_foreach() */
+    qbus_walk_children(BUS(bus), powernv_populate_isa_device,
+                       NULL, NULL, NULL, &args);
+}
+
 static void *powernv_create_fdt(MachineState *machine)
 {
     const char plat_compat[] = "qemu,powernv\0ibm,powernv";
@@ -311,6 +334,7 @@ static void *powernv_create_fdt(MachineState *machine)
     char *buf;
     int off;
     int i;
+    int lpc_offset;
 
     fdt = g_malloc0(FDT_MAX_SIZE);
     _FDT((fdt_create_empty_tree(fdt, FDT_MAX_SIZE)));
@@ -350,6 +374,10 @@ static void *powernv_create_fdt(MachineState *machine)
     for (i = 0; i < pnv->num_chips; i++) {
         powernv_populate_chip(pnv->chips[i], fdt);
     }
+
+    /* Populate ISA devices on chip 0 */
+    lpc_offset = pnv_chip_lpc_offset(pnv->chips[0], fdt);
+    powernv_populate_isa(pnv->isa_bus, fdt, lpc_offset);
     return fdt;
 }
 
-- 
2.9.3

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

* [Qemu-devel] [PULL 39/47] ppc/pnv: populate device tree for RTC devices
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (37 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 38/47] ppc/pnv: scan ISA bus to populate device tree David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 40/47] ppc/pnv: populate device tree for serial devices David Gibson
                   ` (9 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

The code could be common to any ISA device but we are missing the IO
length.

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

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index c445906..8ab5bb1 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -303,6 +303,26 @@ static void powernv_populate_chip(PnvChip *chip, void *fdt)
     g_free(typename);
 }
 
+static void powernv_populate_rtc(ISADevice *d, void *fdt, int lpc_off)
+{
+    uint32_t io_base = d->ioport_id;
+    uint32_t io_regs[] = {
+        cpu_to_be32(1),
+        cpu_to_be32(io_base),
+        cpu_to_be32(2)
+    };
+    char *name;
+    int node;
+
+    name = g_strdup_printf("%s@i%x", qdev_fw_name(DEVICE(d)), io_base);
+    node = fdt_add_subnode(fdt, lpc_off, name);
+    _FDT(node);
+    g_free(name);
+
+    _FDT((fdt_setprop(fdt, node, "reg", io_regs, sizeof(io_regs))));
+    _FDT((fdt_setprop_string(fdt, node, "compatible", "pnpPNP,b00")));
+}
+
 typedef struct ForeachPopulateArgs {
     void *fdt;
     int offset;
@@ -310,6 +330,16 @@ typedef struct ForeachPopulateArgs {
 
 static int powernv_populate_isa_device(DeviceState *dev, void *opaque)
 {
+    ForeachPopulateArgs *args = opaque;
+    ISADevice *d = ISA_DEVICE(dev);
+
+    if (object_dynamic_cast(OBJECT(dev), TYPE_MC146818_RTC)) {
+        powernv_populate_rtc(d, args->fdt, args->offset);
+    } else {
+        error_report("unknown isa device %s@i%x", qdev_fw_name(dev),
+                     d->ioport_id);
+    }
+
     return 0;
 }
 
-- 
2.9.3

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

* [Qemu-devel] [PULL 40/47] ppc/pnv: populate device tree for serial devices
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (38 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 39/47] ppc/pnv: populate device tree for RTC devices David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 41/47] ppc/pnv: populate device tree for IPMI BT devices David Gibson
                   ` (8 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

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

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 8ab5bb1..dfa21e4 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -323,6 +323,37 @@ static void powernv_populate_rtc(ISADevice *d, void *fdt, int lpc_off)
     _FDT((fdt_setprop_string(fdt, node, "compatible", "pnpPNP,b00")));
 }
 
+static void powernv_populate_serial(ISADevice *d, void *fdt, int lpc_off)
+{
+    const char compatible[] = "ns16550\0pnpPNP,501";
+    uint32_t io_base = d->ioport_id;
+    uint32_t io_regs[] = {
+        cpu_to_be32(1),
+        cpu_to_be32(io_base),
+        cpu_to_be32(8)
+    };
+    char *name;
+    int node;
+
+    name = g_strdup_printf("%s@i%x", qdev_fw_name(DEVICE(d)), io_base);
+    node = fdt_add_subnode(fdt, lpc_off, name);
+    _FDT(node);
+    g_free(name);
+
+    _FDT((fdt_setprop(fdt, node, "reg", io_regs, sizeof(io_regs))));
+    _FDT((fdt_setprop(fdt, node, "compatible", compatible,
+                      sizeof(compatible))));
+
+    _FDT((fdt_setprop_cell(fdt, node, "clock-frequency", 1843200)));
+    _FDT((fdt_setprop_cell(fdt, node, "current-speed", 115200)));
+    _FDT((fdt_setprop_cell(fdt, node, "interrupts", d->isairq[0])));
+    _FDT((fdt_setprop_cell(fdt, node, "interrupt-parent",
+                           fdt_get_phandle(fdt, lpc_off))));
+
+    /* This is needed by Linux */
+    _FDT((fdt_setprop_string(fdt, node, "device_type", "serial")));
+}
+
 typedef struct ForeachPopulateArgs {
     void *fdt;
     int offset;
@@ -335,6 +366,8 @@ static int powernv_populate_isa_device(DeviceState *dev, void *opaque)
 
     if (object_dynamic_cast(OBJECT(dev), TYPE_MC146818_RTC)) {
         powernv_populate_rtc(d, args->fdt, args->offset);
+    } else if (object_dynamic_cast(OBJECT(dev), TYPE_ISA_SERIAL)) {
+        powernv_populate_serial(d, args->fdt, args->offset);
     } else {
         error_report("unknown isa device %s@i%x", qdev_fw_name(dev),
                      d->ioport_id);
-- 
2.9.3

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

* [Qemu-devel] [PULL 41/47] ppc/pnv: populate device tree for IPMI BT devices
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (39 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 40/47] ppc/pnv: populate device tree for serial devices David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-06-05 14:33   ` Peter Maydell
  2017-04-24  1:59 ` [Qemu-devel] [PULL 42/47] ppc/pnv: add initial IPMI sensors for the BMC simulator David Gibson
                   ` (7 subsequent siblings)
  48 siblings, 1 reply; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

When an ipmi-bt device [1] is defined on the ISA bus, we need to
populate the device tree with the object properties. Such devices are
created with the command line options :

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

[1] https://lists.gnu.org/archive/html/qemu-devel/2015-11/msg03168.html

Signed-off-by: Cédric Le Goater <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 dfa21e4..977e126 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -354,6 +354,39 @@ static void powernv_populate_serial(ISADevice *d, void *fdt, int lpc_off)
     _FDT((fdt_setprop_string(fdt, node, "device_type", "serial")));
 }
 
+static void powernv_populate_ipmi_bt(ISADevice *d, void *fdt, int lpc_off)
+{
+    const char compatible[] = "bt\0ipmi-bt";
+    uint32_t io_base;
+    uint32_t io_regs[] = {
+        cpu_to_be32(1),
+        0, /* 'io_base' retrieved from the 'ioport' property of 'isa-ipmi-bt' */
+        cpu_to_be32(3)
+    };
+    uint32_t irq;
+    char *name;
+    int node;
+
+    io_base = object_property_get_int(OBJECT(d), "ioport", &error_fatal);
+    io_regs[1] = cpu_to_be32(io_base);
+
+    irq = object_property_get_int(OBJECT(d), "irq", &error_fatal);
+
+    name = g_strdup_printf("%s@i%x", qdev_fw_name(DEVICE(d)), io_base);
+    node = fdt_add_subnode(fdt, lpc_off, name);
+    _FDT(node);
+    g_free(name);
+
+    fdt_setprop(fdt, node, "reg", io_regs, sizeof(io_regs));
+    fdt_setprop(fdt, node, "compatible", compatible, sizeof(compatible));
+
+    /* Mark it as reserved to avoid Linux trying to claim it */
+    _FDT((fdt_setprop_string(fdt, node, "status", "reserved")));
+    _FDT((fdt_setprop_cell(fdt, node, "interrupts", irq)));
+    _FDT((fdt_setprop_cell(fdt, node, "interrupt-parent",
+                           fdt_get_phandle(fdt, lpc_off))));
+}
+
 typedef struct ForeachPopulateArgs {
     void *fdt;
     int offset;
@@ -368,6 +401,8 @@ static int powernv_populate_isa_device(DeviceState *dev, void *opaque)
         powernv_populate_rtc(d, args->fdt, args->offset);
     } else if (object_dynamic_cast(OBJECT(dev), TYPE_ISA_SERIAL)) {
         powernv_populate_serial(d, args->fdt, args->offset);
+    } else if (object_dynamic_cast(OBJECT(dev), "isa-ipmi-bt")) {
+        powernv_populate_ipmi_bt(d, args->fdt, args->offset);
     } else {
         error_report("unknown isa device %s@i%x", qdev_fw_name(dev),
                      d->ioport_id);
-- 
2.9.3

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

* [Qemu-devel] [PULL 42/47] ppc/pnv: add initial IPMI sensors for the BMC simulator
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (40 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 41/47] ppc/pnv: populate device tree for IPMI BT devices David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 43/47] ppc/pnv: generate an OEM SEL event on shutdown David Gibson
                   ` (6 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

Skiboot, the firmware for the PowerNV platform, expects the BMC to
provide some specific IPMI sensors. These sensors are exposed in the
device tree and their values are updated by the firmware at boot time.

Sensors of interest are :

	"FW Boot Progress"
	"Boot Count"

As such a device is defined on the command line, we can only detect
its presence at reset time.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/Makefile.objs |  2 +-
 hw/ppc/pnv.c         | 21 ++++++++++++++
 hw/ppc/pnv_bmc.c     | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/pnv.h |  9 ++++++
 4 files changed, 112 insertions(+), 1 deletion(-)
 create mode 100644 hw/ppc/pnv_bmc.c

diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index ef67ea8..7efc686 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -6,7 +6,7 @@ obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o
 obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o spapr_rng.o
 obj-$(CONFIG_PSERIES) += spapr_cpu_core.o spapr_ovec.o
 # IBM PowerNV
-obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_core.o pnv_lpc.o pnv_psi.o pnv_occ.o
+obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_core.o pnv_lpc.o pnv_psi.o pnv_occ.o pnv_bmc.o
 ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy)
 obj-y += spapr_pci_vfio.o
 endif
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 977e126..685eb12 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -35,6 +35,7 @@
 #include "qapi/visitor.h"
 #include "monitor/monitor.h"
 #include "hw/intc/intc.h"
+#include "hw/ipmi/ipmi.h"
 
 #include "hw/ppc/xics.h"
 #include "hw/ppc/pnv_xscom.h"
@@ -476,16 +477,36 @@ static void *powernv_create_fdt(MachineState *machine)
     /* Populate ISA devices on chip 0 */
     lpc_offset = pnv_chip_lpc_offset(pnv->chips[0], fdt);
     powernv_populate_isa(pnv->isa_bus, fdt, lpc_offset);
+
+    if (pnv->bmc) {
+        pnv_bmc_populate_sensors(pnv->bmc, fdt);
+    }
+
     return fdt;
 }
 
 static void ppc_powernv_reset(void)
 {
     MachineState *machine = MACHINE(qdev_get_machine());
+    PnvMachineState *pnv = POWERNV_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("", TYPE_IPMI_BMC, NULL);
+    if (obj) {
+        pnv->bmc = IPMI_BMC(obj);
+    }
+
     fdt = powernv_create_fdt(machine);
 
     /* Pack resulting tree */
diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c
new file mode 100644
index 0000000..a0820dc
--- /dev/null
+++ b/hw/ppc/pnv_bmc.c
@@ -0,0 +1,81 @@
+/*
+ * QEMU PowerNV, BMC related functions
+ *
+ * Copyright (c) 2016-2017, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "sysemu/sysemu.h"
+#include "target/ppc/cpu.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "hw/ipmi/ipmi.h"
+#include "hw/ppc/fdt.h"
+
+#include "hw/ppc/pnv.h"
+
+#include <libfdt.h>
+
+/* TODO: include definition in ipmi.h */
+#define IPMI_SDR_FULL_TYPE 1
+
+void pnv_bmc_populate_sensors(IPMIBmc *bmc, void *fdt)
+{
+    int offset;
+    int i;
+    const struct ipmi_sdr_compact *sdr;
+    uint16_t nextrec;
+
+    offset = fdt_add_subnode(fdt, 0, "/bmc");
+    _FDT(offset);
+
+    _FDT((fdt_setprop_string(fdt, offset, "name", "bmc")));
+    _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 0x1)));
+    _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 0x0)));
+
+    offset = fdt_add_subnode(fdt, offset, "sensors");
+    _FDT(offset);
+
+    _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 0x1)));
+    _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 0x0)));
+
+    for (i = 0; !ipmi_bmc_sdr_find(bmc, i, &sdr, &nextrec); i++) {
+        int off;
+        char *name;
+
+        if (sdr->header.rec_type != IPMI_SDR_COMPACT_TYPE &&
+            sdr->header.rec_type != IPMI_SDR_FULL_TYPE) {
+            continue;
+        }
+
+        name = g_strdup_printf("sensor@%x", sdr->sensor_owner_number);
+        off = fdt_add_subnode(fdt, offset, name);
+        _FDT(off);
+        g_free(name);
+
+        _FDT((fdt_setprop_cell(fdt, off, "reg", sdr->sensor_owner_number)));
+        _FDT((fdt_setprop_string(fdt, off, "name", "sensor")));
+        _FDT((fdt_setprop_string(fdt, off, "compatible", "ibm,ipmi-sensor")));
+        _FDT((fdt_setprop_cell(fdt, off, "ipmi-sensor-reading-type",
+                               sdr->reading_type)));
+        _FDT((fdt_setprop_cell(fdt, off, "ipmi-entity-id",
+                               sdr->entity_id)));
+        _FDT((fdt_setprop_cell(fdt, off, "ipmi-entity-instance",
+                               sdr->entity_instance)));
+        _FDT((fdt_setprop_cell(fdt, off, "ipmi-sensor-type",
+                               sdr->sensor_type)));
+    }
+}
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index b45a0d9..02f6cf5 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -118,6 +118,8 @@ typedef struct PnvChipClass {
 #define POWERNV_MACHINE(obj) \
     OBJECT_CHECK(PnvMachineState, (obj), TYPE_POWERNV_MACHINE)
 
+typedef struct IPMIBmc IPMIBmc;
+
 typedef struct PnvMachineState {
     /*< private >*/
     MachineState parent_obj;
@@ -130,12 +132,19 @@ typedef struct PnvMachineState {
 
     ISABus       *isa_bus;
     uint32_t     cpld_irqstate;
+
+    IPMIBmc      *bmc;
 } PnvMachineState;
 
 #define PNV_FDT_ADDR          0x01000000
 #define PNV_TIMEBASE_FREQ     512000000ULL
 
 /*
+ * BMC helpers
+ */
+void pnv_bmc_populate_sensors(IPMIBmc *bmc, void *fdt);
+
+/*
  * POWER8 MMIO base addresses
  */
 #define PNV_XSCOM_SIZE        0x800000000ull
-- 
2.9.3

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

* [Qemu-devel] [PULL 43/47] ppc/pnv: generate an OEM SEL event on shutdown
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (41 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 42/47] ppc/pnv: add initial IPMI sensors for the BMC simulator David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 44/47] spapr-cpu-core: Release ICPState object during CPU unrealization David Gibson
                   ` (5 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

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

OpenPOWER systems expect to be notified with such an event before a
shutdown or a reboot. An OEM SEL message is sent with specific
identifiers and a user data containing the request : OFF or REBOOT.

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

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 685eb12..d4bcdb0 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -485,6 +485,15 @@ static void *powernv_create_fdt(MachineState *machine)
     return fdt;
 }
 
+static void pnv_powerdown_notify(Notifier *n, void *opaque)
+{
+    PnvMachineState *pnv = POWERNV_MACHINE(qdev_get_machine());
+
+    if (pnv->bmc) {
+        pnv_bmc_powerdown(pnv->bmc);
+    }
+}
+
 static void ppc_powernv_reset(void)
 {
     MachineState *machine = MACHINE(qdev_get_machine());
@@ -638,6 +647,11 @@ static void ppc_powernv_init(MachineState *machine)
 
     /* Create an RTC ISA device too */
     rtc_init(pnv->isa_bus, 2000, NULL);
+
+    /* OpenPOWER systems use a IPMI SEL Event message to notify the
+     * host to powerdown */
+    pnv->powerdown_notifier.notify = pnv_powerdown_notify;
+    qemu_register_powerdown_notifier(&pnv->powerdown_notifier);
 }
 
 /*
diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c
index a0820dc..7b60b4c 100644
--- a/hw/ppc/pnv_bmc.c
+++ b/hw/ppc/pnv_bmc.c
@@ -32,6 +32,47 @@
 /* TODO: include definition in ipmi.h */
 #define IPMI_SDR_FULL_TYPE 1
 
+/*
+ * OEM SEL Event data packet sent by BMC in response of a Read Event
+ * Message Buffer command
+ */
+typedef struct OemSel {
+    /* SEL header */
+    uint8_t id[2];
+    uint8_t type;
+    uint8_t timestamp[4];
+    uint8_t manuf_id[3];
+
+    /* OEM SEL data (6 bytes) follows */
+    uint8_t netfun;
+    uint8_t cmd;
+    uint8_t data[4];
+} OemSel;
+
+#define SOFT_OFF        0x00
+#define SOFT_REBOOT     0x01
+
+static void pnv_gen_oem_sel(IPMIBmc *bmc, uint8_t reboot)
+{
+    /* IPMI SEL Event are 16 bytes long */
+    OemSel sel = {
+        .id        = { 0x55 , 0x55 },
+        .type      = 0xC0, /* OEM */
+        .manuf_id  = { 0x0, 0x0, 0x0 },
+        .timestamp = { 0x0, 0x0, 0x0, 0x0 },
+        .netfun    = 0x3A, /* IBM */
+        .cmd       = 0x04, /* AMI OEM SEL Power Notification */
+        .data      = { reboot, 0xFF, 0xFF, 0xFF },
+    };
+
+    ipmi_bmc_gen_event(bmc, (uint8_t *) &sel, 0 /* do not log the event */);
+}
+
+void pnv_bmc_powerdown(IPMIBmc *bmc)
+{
+    pnv_gen_oem_sel(bmc, SOFT_OFF);
+}
+
 void pnv_bmc_populate_sensors(IPMIBmc *bmc, void *fdt)
 {
     int offset;
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 02f6cf5..c1288f9 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -134,6 +134,7 @@ typedef struct PnvMachineState {
     uint32_t     cpld_irqstate;
 
     IPMIBmc      *bmc;
+    Notifier     powerdown_notifier;
 } PnvMachineState;
 
 #define PNV_FDT_ADDR          0x01000000
@@ -143,6 +144,7 @@ typedef struct PnvMachineState {
  * BMC helpers
  */
 void pnv_bmc_populate_sensors(IPMIBmc *bmc, void *fdt);
+void pnv_bmc_powerdown(IPMIBmc *bmc);
 
 /*
  * POWER8 MMIO base addresses
-- 
2.9.3

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

* [Qemu-devel] [PULL 44/47] spapr-cpu-core: Release ICPState object during CPU unrealization
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (42 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 43/47] ppc/pnv: generate an OEM SEL event on shutdown David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 45/47] target/ppc: Flush TLB on write to PIDR David Gibson
                   ` (4 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell
  Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, Bharata B Rao,
	David Gibson

From: Bharata B Rao <bharata@linux.vnet.ibm.com>

Recent commits that re-organized ICPState object missed to destroy
the object when CPU is unrealized. Fix this so that CPU unplug
doesn't abort QEMU.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_cpu_core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 2e689b5..4389ef4 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -127,6 +127,7 @@ static void spapr_cpu_core_unrealizefn(DeviceState *dev, Error **errp)
         PowerPCCPU *cpu = POWERPC_CPU(cs);
 
         spapr_cpu_destroy(cpu);
+        object_unparent(cpu->intc);
         cpu_remove_sync(cs);
         object_unparent(obj);
     }
-- 
2.9.3

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

* [Qemu-devel] [PULL 45/47] target/ppc: Flush TLB on write to PIDR
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (43 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 44/47] spapr-cpu-core: Release ICPState object during CPU unrealization David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 46/47] e500, book3s: mfspr 259: Register mapped/aliased SPRG3 user read David Gibson
                   ` (3 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell
  Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg,
	Suraj Jitindar Singh, David Gibson

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

The PIDR (process id register) is used to store the id of the currently
running process, which is used to select the process table entry used to
perform address translation. This means that when we write to this register
all the translations in the TLB become outdated as they are for a
previously running process. Thus when this register is written to we need
to invalidate the TLB entries to ensure stale entries aren't used to
to perform translation for the new process, which would result in at best
segfaults or alternatively just random memory being accessed.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
[dwg: Fixed compile error for 32-bit targets]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/helper.h         |  1 +
 target/ppc/misc_helper.c    |  8 ++++++++
 target/ppc/translate_init.c | 10 ++++++++--
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 6d77661..bb6a94a 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -709,6 +709,7 @@ DEF_HELPER_FLAGS_1(load_601_rtcu, TCG_CALL_NO_RWG, tl, env)
 DEF_HELPER_FLAGS_1(load_purr, TCG_CALL_NO_RWG, tl, env)
 #endif
 DEF_HELPER_2(store_sdr1, void, env, tl)
+DEF_HELPER_2(store_pidr, void, env, tl)
 DEF_HELPER_FLAGS_2(store_tbl, TCG_CALL_NO_RWG, void, env, tl)
 DEF_HELPER_FLAGS_2(store_tbu, TCG_CALL_NO_RWG, void, env, tl)
 DEF_HELPER_FLAGS_2(store_atbl, TCG_CALL_NO_RWG, void, env, tl)
diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c
index fa573dd..0e42178 100644
--- a/target/ppc/misc_helper.c
+++ b/target/ppc/misc_helper.c
@@ -88,6 +88,14 @@ void helper_store_sdr1(CPUPPCState *env, target_ulong val)
     }
 }
 
+void helper_store_pidr(CPUPPCState *env, target_ulong val)
+{
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
+
+    env->spr[SPR_BOOKS_PID] = val;
+    tlb_flush(CPU(cpu));
+}
+
 void helper_store_hid0_601(CPUPPCState *env, target_ulong val)
 {
     target_ulong hid0;
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index aa0c44d..77e5463 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -394,8 +394,14 @@ static void spr_write_sdr1 (DisasContext *ctx, int sprn, int gprn)
     gen_helper_store_sdr1(cpu_env, cpu_gpr[gprn]);
 }
 
-/* 64 bits PowerPC specific SPRs */
 #if defined(TARGET_PPC64)
+/* 64 bits PowerPC specific SPRs */
+/* PIDR */
+static void spr_write_pidr(DisasContext *ctx, int sprn, int gprn)
+{
+    gen_helper_store_pidr(cpu_env, cpu_gpr[gprn]);
+}
+
 static void spr_read_hior (DisasContext *ctx, int gprn, int sprn)
 {
     tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, excp_prefix));
@@ -8200,7 +8206,7 @@ static void gen_spr_power8_book4(CPUPPCState *env)
                      KVM_REG_PPC_ACOP, 0);
     spr_register_kvm(env, SPR_BOOKS_PID, "PID",
                      SPR_NOACCESS, SPR_NOACCESS,
-                     &spr_read_generic, &spr_write_generic,
+                     &spr_read_generic, &spr_write_pidr,
                      KVM_REG_PPC_PID, 0);
     spr_register_kvm(env, SPR_WORT, "WORT",
                      SPR_NOACCESS, SPR_NOACCESS,
-- 
2.9.3

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

* [Qemu-devel] [PULL 46/47] e500, book3s: mfspr 259: Register mapped/aliased SPRG3 user read
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (44 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 45/47] target/ppc: Flush TLB on write to PIDR David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  1:59 ` [Qemu-devel] [PULL 47/47] target/ppc: Style fixes David Gibson
                   ` (2 subsequent siblings)
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell
  Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, Bernhard Kaindl,
	David Gibson

From: Bernhard Kaindl <bernhard.kaindl@thalesgroup.com>

This patch registers mfspr 259 for Book3S and e500 family cores
following this research:

mfspr 259 provides read-only mapped user access to SPRG3(SPR 275) according to:

- PowerISA 2.02, Book III (documents implementation starting with POWER4+ @ p20)
- IBM PowerPC 970MP RISC Microprocessor User's Manual v2.1, page 48
- Amit Singh: "Mac OS X Internals: A Systems Approach" on 970 and 970FX cores:
  He demonstrates mfspr 259 reading TLS data from Mac OS X on G5 on page 588
- NXP documents it in the Core Reference Manuals of: e500, e500mc and e5500
- getcpu() of the 32 & 64-bit Book3S Linux vDSOs use it to read the core number

mfspr 259 does not appear to be implemented in these cores according to:

- 74xx series: MPC7410/MPC7400 and MPC7450 RISC Microprocessor Reference Manuals
- 4xx series:  PPC440 Processor User's Manual, Revision 1.09 by AMCC
- 750 series:  IBM PowerPC 750CL RISC Microprocessor User's Manual
- e200 series: e200z4 Power Architectureâ Core Reference Manual

Implementation: gen_spr_usprg3() is called from init_proc_book3s_common()
(covers the 970 and POWER cores) and init_proc_e500() (covers the e500 family)
to register spr_read_ureg() in the same way which it already provides
the mapped SPR access for SPR_USPRG4-7 in gen_spr_usprgh() for cores
which have the same read-only mapped SPRG register access for SPRG4-7.

Verified using Linux by pinning a thread to a core and checking sched_getcpu()
using qemu-system-ppc64 -M pseries -cpu POWER8 using MTTCG on a x86_64 host.

Signed-off-by: Bernhard Kaindl <bernhard.kaindl@thalesgroup.com>
Reviewed-by: Stefan Resch <stefan.resch@thalesgroup.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/translate_init.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index 77e5463..0ecf541 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -1640,6 +1640,14 @@ static void spr_write_booke_pid (DisasContext *ctx, int sprn, int gprn)
 }
 #endif
 
+static void gen_spr_usprg3 (CPUPPCState *env)
+{
+    spr_register(env, SPR_USPRG3, "USPRG3",
+                 &spr_read_ureg, SPR_NOACCESS,
+                 &spr_read_ureg, SPR_NOACCESS,
+                 0x00000000);
+}
+
 static void gen_spr_usprgh (CPUPPCState *env)
 {
     spr_register(env, SPR_USPRG4, "USPRG4",
@@ -4914,6 +4922,7 @@ static void init_proc_e500 (CPUPPCState *env, int version)
             break;
     }
     gen_spr_BookE(env, ivor_mask);
+    gen_spr_usprg3(env);
     /* Processor identification */
     spr_register(env, SPR_BOOKE_PIR, "PIR",
                  SPR_NOACCESS, SPR_NOACCESS,
@@ -8245,6 +8254,7 @@ static void init_proc_book3s_common(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_tbl(env);
+    gen_spr_usprg3(env);
     gen_spr_book3s_altivec(env);
     gen_spr_book3s_pmu_sup(env);
     gen_spr_book3s_pmu_user(env);
-- 
2.9.3

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

* [Qemu-devel] [PULL 47/47] target/ppc: Style fixes
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (45 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 46/47] e500, book3s: mfspr 259: Register mapped/aliased SPRG3 user read David Gibson
@ 2017-04-24  1:59 ` David Gibson
  2017-04-24  3:08 ` [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 no-reply
  2017-04-24 13:12 ` [Qemu-devel] " Peter Maydell
  48 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  1:59 UTC (permalink / raw)
  To: peter.maydell; +Cc: agraf, mdroth, aik, qemu-devel, qemu-ppc, clg, David Gibson

This makes a small step fixing one of many style problems that exist in
the older ppc code.  This removes spaces between function (or macro) name
and the following '('.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/translate_init.c | 372 ++++++++++++++++++++++----------------------
 1 file changed, 186 insertions(+), 186 deletions(-)

diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index 0ecf541..e82e3e6 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -66,7 +66,7 @@ static void spr_store_dump_spr(int sprn)
 #endif
 }
 
-static void spr_write_generic (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_generic(DisasContext *ctx, int sprn, int gprn)
 {
     gen_store_spr(sprn, cpu_gpr[gprn]);
     spr_store_dump_spr(sprn);
@@ -86,7 +86,7 @@ static void spr_write_generic32(DisasContext *ctx, int sprn, int gprn)
 #endif
 }
 
-static void spr_write_clear (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_clear(DisasContext *ctx, int sprn, int gprn)
 {
     TCGv t0 = tcg_temp_new();
     TCGv t1 = tcg_temp_new();
@@ -106,47 +106,47 @@ static void spr_access_nop(DisasContext *ctx, int sprn, int gprn)
 
 /* SPR common to all PowerPC */
 /* XER */
-static void spr_read_xer (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_xer(DisasContext *ctx, int gprn, int sprn)
 {
     gen_read_xer(ctx, cpu_gpr[gprn]);
 }
 
-static void spr_write_xer (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_xer(DisasContext *ctx, int sprn, int gprn)
 {
     gen_write_xer(cpu_gpr[gprn]);
 }
 
 /* LR */
-static void spr_read_lr (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_lr(DisasContext *ctx, int gprn, int sprn)
 {
     tcg_gen_mov_tl(cpu_gpr[gprn], cpu_lr);
 }
 
-static void spr_write_lr (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_lr(DisasContext *ctx, int sprn, int gprn)
 {
     tcg_gen_mov_tl(cpu_lr, cpu_gpr[gprn]);
 }
 
 /* CFAR */
 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
-static void spr_read_cfar (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_cfar(DisasContext *ctx, int gprn, int sprn)
 {
     tcg_gen_mov_tl(cpu_gpr[gprn], cpu_cfar);
 }
 
-static void spr_write_cfar (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_cfar(DisasContext *ctx, int sprn, int gprn)
 {
     tcg_gen_mov_tl(cpu_cfar, cpu_gpr[gprn]);
 }
 #endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
 
 /* CTR */
-static void spr_read_ctr (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_ctr(DisasContext *ctx, int gprn, int sprn)
 {
     tcg_gen_mov_tl(cpu_gpr[gprn], cpu_ctr);
 }
 
-static void spr_write_ctr (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_ctr(DisasContext *ctx, int sprn, int gprn)
 {
     tcg_gen_mov_tl(cpu_ctr, cpu_gpr[gprn]);
 }
@@ -157,7 +157,7 @@ static void spr_write_ctr (DisasContext *ctx, int sprn, int gprn)
 /* UPMCx */
 /* USIA */
 /* UDECR */
-static void spr_read_ureg (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_ureg(DisasContext *ctx, int gprn, int sprn)
 {
     gen_load_spr(cpu_gpr[gprn], sprn + 0x10);
 }
@@ -172,7 +172,7 @@ static void spr_write_ureg(DisasContext *ctx, int sprn, int gprn)
 /* SPR common to all non-embedded PowerPC */
 /* DECR */
 #if !defined(CONFIG_USER_ONLY)
-static void spr_read_decr (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_decr(DisasContext *ctx, int gprn, int sprn)
 {
     if (ctx->tb->cflags & CF_USE_ICOUNT) {
         gen_io_start();
@@ -184,7 +184,7 @@ static void spr_read_decr (DisasContext *ctx, int gprn, int sprn)
     }
 }
 
-static void spr_write_decr (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_decr(DisasContext *ctx, int sprn, int gprn)
 {
     if (ctx->tb->cflags & CF_USE_ICOUNT) {
         gen_io_start();
@@ -199,7 +199,7 @@ static void spr_write_decr (DisasContext *ctx, int sprn, int gprn)
 
 /* SPR common to all non-embedded PowerPC, except 601 */
 /* Time base */
-static void spr_read_tbl (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_tbl(DisasContext *ctx, int gprn, int sprn)
 {
     if (ctx->tb->cflags & CF_USE_ICOUNT) {
         gen_io_start();
@@ -211,7 +211,7 @@ static void spr_read_tbl (DisasContext *ctx, int gprn, int sprn)
     }
 }
 
-static void spr_read_tbu (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_tbu(DisasContext *ctx, int gprn, int sprn)
 {
     if (ctx->tb->cflags & CF_USE_ICOUNT) {
         gen_io_start();
@@ -224,19 +224,19 @@ static void spr_read_tbu (DisasContext *ctx, int gprn, int sprn)
 }
 
 __attribute__ (( unused ))
-static void spr_read_atbl (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_atbl(DisasContext *ctx, int gprn, int sprn)
 {
     gen_helper_load_atbl(cpu_gpr[gprn], cpu_env);
 }
 
 __attribute__ (( unused ))
-static void spr_read_atbu (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_atbu(DisasContext *ctx, int gprn, int sprn)
 {
     gen_helper_load_atbu(cpu_gpr[gprn], cpu_env);
 }
 
 #if !defined(CONFIG_USER_ONLY)
-static void spr_write_tbl (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_tbl(DisasContext *ctx, int sprn, int gprn)
 {
     if (ctx->tb->cflags & CF_USE_ICOUNT) {
         gen_io_start();
@@ -248,7 +248,7 @@ static void spr_write_tbl (DisasContext *ctx, int sprn, int gprn)
     }
 }
 
-static void spr_write_tbu (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_tbu(DisasContext *ctx, int sprn, int gprn)
 {
     if (ctx->tb->cflags & CF_USE_ICOUNT) {
         gen_io_start();
@@ -261,20 +261,20 @@ static void spr_write_tbu (DisasContext *ctx, int sprn, int gprn)
 }
 
 __attribute__ (( unused ))
-static void spr_write_atbl (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_atbl(DisasContext *ctx, int sprn, int gprn)
 {
     gen_helper_store_atbl(cpu_env, cpu_gpr[gprn]);
 }
 
 __attribute__ (( unused ))
-static void spr_write_atbu (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_atbu(DisasContext *ctx, int sprn, int gprn)
 {
     gen_helper_store_atbu(cpu_env, cpu_gpr[gprn]);
 }
 
 #if defined(TARGET_PPC64)
 __attribute__ (( unused ))
-static void spr_read_purr (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_purr(DisasContext *ctx, int gprn, int sprn)
 {
     gen_helper_load_purr(cpu_gpr[gprn], cpu_env);
 }
@@ -310,38 +310,38 @@ static void spr_write_hdecr(DisasContext *ctx, int sprn, int gprn)
 #if !defined(CONFIG_USER_ONLY)
 /* IBAT0U...IBAT0U */
 /* IBAT0L...IBAT7L */
-static void spr_read_ibat (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_ibat(DisasContext *ctx, int gprn, int sprn)
 {
     tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2]));
 }
 
-static void spr_read_ibat_h (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_ibat_h(DisasContext *ctx, int gprn, int sprn)
 {
     tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, IBAT[sprn & 1][((sprn - SPR_IBAT4U) / 2) + 4]));
 }
 
-static void spr_write_ibatu (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_ibatu(DisasContext *ctx, int sprn, int gprn)
 {
     TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
     gen_helper_store_ibatu(cpu_env, t0, cpu_gpr[gprn]);
     tcg_temp_free_i32(t0);
 }
 
-static void spr_write_ibatu_h (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_ibatu_h(DisasContext *ctx, int sprn, int gprn)
 {
     TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_IBAT4U) / 2) + 4);
     gen_helper_store_ibatu(cpu_env, t0, cpu_gpr[gprn]);
     tcg_temp_free_i32(t0);
 }
 
-static void spr_write_ibatl (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_ibatl(DisasContext *ctx, int sprn, int gprn)
 {
     TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0L) / 2);
     gen_helper_store_ibatl(cpu_env, t0, cpu_gpr[gprn]);
     tcg_temp_free_i32(t0);
 }
 
-static void spr_write_ibatl_h (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_ibatl_h(DisasContext *ctx, int sprn, int gprn)
 {
     TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_IBAT4L) / 2) + 4);
     gen_helper_store_ibatl(cpu_env, t0, cpu_gpr[gprn]);
@@ -350,38 +350,38 @@ static void spr_write_ibatl_h (DisasContext *ctx, int sprn, int gprn)
 
 /* DBAT0U...DBAT7U */
 /* DBAT0L...DBAT7L */
-static void spr_read_dbat (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_dbat(DisasContext *ctx, int gprn, int sprn)
 {
     tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, DBAT[sprn & 1][(sprn - SPR_DBAT0U) / 2]));
 }
 
-static void spr_read_dbat_h (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_dbat_h(DisasContext *ctx, int gprn, int sprn)
 {
     tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, DBAT[sprn & 1][((sprn - SPR_DBAT4U) / 2) + 4]));
 }
 
-static void spr_write_dbatu (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_dbatu(DisasContext *ctx, int sprn, int gprn)
 {
     TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0U) / 2);
     gen_helper_store_dbatu(cpu_env, t0, cpu_gpr[gprn]);
     tcg_temp_free_i32(t0);
 }
 
-static void spr_write_dbatu_h (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_dbatu_h(DisasContext *ctx, int sprn, int gprn)
 {
     TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4U) / 2) + 4);
     gen_helper_store_dbatu(cpu_env, t0, cpu_gpr[gprn]);
     tcg_temp_free_i32(t0);
 }
 
-static void spr_write_dbatl (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_dbatl(DisasContext *ctx, int sprn, int gprn)
 {
     TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0L) / 2);
     gen_helper_store_dbatl(cpu_env, t0, cpu_gpr[gprn]);
     tcg_temp_free_i32(t0);
 }
 
-static void spr_write_dbatl_h (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_dbatl_h(DisasContext *ctx, int sprn, int gprn)
 {
     TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4L) / 2) + 4);
     gen_helper_store_dbatl(cpu_env, t0, cpu_gpr[gprn]);
@@ -389,7 +389,7 @@ static void spr_write_dbatl_h (DisasContext *ctx, int sprn, int gprn)
 }
 
 /* SDR1 */
-static void spr_write_sdr1 (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_sdr1(DisasContext *ctx, int sprn, int gprn)
 {
     gen_helper_store_sdr1(cpu_env, cpu_gpr[gprn]);
 }
@@ -402,12 +402,12 @@ static void spr_write_pidr(DisasContext *ctx, int sprn, int gprn)
     gen_helper_store_pidr(cpu_env, cpu_gpr[gprn]);
 }
 
-static void spr_read_hior (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_hior(DisasContext *ctx, int gprn, int sprn)
 {
     tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, excp_prefix));
 }
 
-static void spr_write_hior (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_hior(DisasContext *ctx, int sprn, int gprn)
 {
     TCGv t0 = tcg_temp_new();
     tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0x3FFFFF00000ULL);
@@ -419,28 +419,28 @@ static void spr_write_hior (DisasContext *ctx, int sprn, int gprn)
 
 /* PowerPC 601 specific registers */
 /* RTC */
-static void spr_read_601_rtcl (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_601_rtcl(DisasContext *ctx, int gprn, int sprn)
 {
     gen_helper_load_601_rtcl(cpu_gpr[gprn], cpu_env);
 }
 
-static void spr_read_601_rtcu (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_601_rtcu(DisasContext *ctx, int gprn, int sprn)
 {
     gen_helper_load_601_rtcu(cpu_gpr[gprn], cpu_env);
 }
 
 #if !defined(CONFIG_USER_ONLY)
-static void spr_write_601_rtcu (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_601_rtcu(DisasContext *ctx, int sprn, int gprn)
 {
     gen_helper_store_601_rtcu(cpu_env, cpu_gpr[gprn]);
 }
 
-static void spr_write_601_rtcl (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_601_rtcl(DisasContext *ctx, int sprn, int gprn)
 {
     gen_helper_store_601_rtcl(cpu_env, cpu_gpr[gprn]);
 }
 
-static void spr_write_hid0_601 (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_hid0_601(DisasContext *ctx, int sprn, int gprn)
 {
     gen_helper_store_hid0_601(cpu_env, cpu_gpr[gprn]);
     /* Must stop the translation as endianness may have changed */
@@ -450,19 +450,19 @@ static void spr_write_hid0_601 (DisasContext *ctx, int sprn, int gprn)
 
 /* Unified bats */
 #if !defined(CONFIG_USER_ONLY)
-static void spr_read_601_ubat (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_601_ubat(DisasContext *ctx, int gprn, int sprn)
 {
     tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2]));
 }
 
-static void spr_write_601_ubatu (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_601_ubatu(DisasContext *ctx, int sprn, int gprn)
 {
     TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
     gen_helper_store_601_batl(cpu_env, t0, cpu_gpr[gprn]);
     tcg_temp_free_i32(t0);
 }
 
-static void spr_write_601_ubatl (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_601_ubatl(DisasContext *ctx, int sprn, int gprn)
 {
     TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
     gen_helper_store_601_batu(cpu_env, t0, cpu_gpr[gprn]);
@@ -472,34 +472,34 @@ static void spr_write_601_ubatl (DisasContext *ctx, int sprn, int gprn)
 
 /* PowerPC 40x specific registers */
 #if !defined(CONFIG_USER_ONLY)
-static void spr_read_40x_pit (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_40x_pit(DisasContext *ctx, int gprn, int sprn)
 {
     gen_helper_load_40x_pit(cpu_gpr[gprn], cpu_env);
 }
 
-static void spr_write_40x_pit (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_40x_pit(DisasContext *ctx, int sprn, int gprn)
 {
     gen_helper_store_40x_pit(cpu_env, cpu_gpr[gprn]);
 }
 
-static void spr_write_40x_dbcr0 (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_40x_dbcr0(DisasContext *ctx, int sprn, int gprn)
 {
     gen_helper_store_40x_dbcr0(cpu_env, cpu_gpr[gprn]);
     /* We must stop translation as we may have rebooted */
     gen_stop_exception(ctx);
 }
 
-static void spr_write_40x_sler (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_40x_sler(DisasContext *ctx, int sprn, int gprn)
 {
     gen_helper_store_40x_sler(cpu_env, cpu_gpr[gprn]);
 }
 
-static void spr_write_booke_tcr (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_booke_tcr(DisasContext *ctx, int sprn, int gprn)
 {
     gen_helper_store_booke_tcr(cpu_env, cpu_gpr[gprn]);
 }
 
-static void spr_write_booke_tsr (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_booke_tsr(DisasContext *ctx, int sprn, int gprn)
 {
     gen_helper_store_booke_tsr(cpu_env, cpu_gpr[gprn]);
 }
@@ -508,19 +508,19 @@ static void spr_write_booke_tsr (DisasContext *ctx, int sprn, int gprn)
 /* PowerPC 403 specific registers */
 /* PBL1 / PBU1 / PBL2 / PBU2 */
 #if !defined(CONFIG_USER_ONLY)
-static void spr_read_403_pbr (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_403_pbr(DisasContext *ctx, int gprn, int sprn)
 {
     tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, pb[sprn - SPR_403_PBL1]));
 }
 
-static void spr_write_403_pbr (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_403_pbr(DisasContext *ctx, int sprn, int gprn)
 {
     TCGv_i32 t0 = tcg_const_i32(sprn - SPR_403_PBL1);
     gen_helper_store_403_pbr(cpu_env, t0, cpu_gpr[gprn]);
     tcg_temp_free_i32(t0);
 }
 
-static void spr_write_pir (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_pir(DisasContext *ctx, int sprn, int gprn)
 {
     TCGv t0 = tcg_temp_new();
     tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0xF);
@@ -530,7 +530,7 @@ static void spr_write_pir (DisasContext *ctx, int sprn, int gprn)
 #endif
 
 /* SPE specific registers */
-static void spr_read_spefscr (DisasContext *ctx, int gprn, int sprn)
+static void spr_read_spefscr(DisasContext *ctx, int gprn, int sprn)
 {
     TCGv_i32 t0 = tcg_temp_new_i32();
     tcg_gen_ld_i32(t0, cpu_env, offsetof(CPUPPCState, spe_fscr));
@@ -538,7 +538,7 @@ static void spr_read_spefscr (DisasContext *ctx, int gprn, int sprn)
     tcg_temp_free_i32(t0);
 }
 
-static void spr_write_spefscr (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_spefscr(DisasContext *ctx, int sprn, int gprn)
 {
     TCGv_i32 t0 = tcg_temp_new_i32();
     tcg_gen_trunc_tl_i32(t0, cpu_gpr[gprn]);
@@ -548,7 +548,7 @@ static void spr_write_spefscr (DisasContext *ctx, int sprn, int gprn)
 
 #if !defined(CONFIG_USER_ONLY)
 /* Callback used to write the exception vector base */
-static void spr_write_excp_prefix (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_excp_prefix(DisasContext *ctx, int sprn, int gprn)
 {
     TCGv t0 = tcg_temp_new();
     tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUPPCState, ivpr_mask));
@@ -558,7 +558,7 @@ static void spr_write_excp_prefix (DisasContext *ctx, int sprn, int gprn)
     tcg_temp_free(t0);
 }
 
-static void spr_write_excp_vector (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_excp_vector(DisasContext *ctx, int sprn, int gprn)
 {
     int sprn_offs;
 
@@ -584,7 +584,7 @@ static void spr_write_excp_vector (DisasContext *ctx, int sprn, int gprn)
 }
 #endif
 
-static inline void vscr_init (CPUPPCState *env, uint32_t val)
+static inline void vscr_init(CPUPPCState *env, uint32_t val)
 {
     env->vscr = val;
     /* Altivec always uses round-to-nearest */
@@ -685,7 +685,7 @@ static inline void _spr_register(CPUPPCState *env, int num,
 }
 
 /* Generic PowerPC SPRs */
-static void gen_spr_generic (CPUPPCState *env)
+static void gen_spr_generic(CPUPPCState *env)
 {
     /* Integer processing */
     spr_register(env, SPR_XER, "XER",
@@ -770,7 +770,7 @@ static void gen_spr_sdr1(CPUPPCState *env)
 }
 
 /* BATs 0-3 */
-static void gen_low_BATs (CPUPPCState *env)
+static void gen_low_BATs(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     spr_register(env, SPR_IBAT0U, "IBAT0U",
@@ -842,7 +842,7 @@ static void gen_low_BATs (CPUPPCState *env)
 }
 
 /* BATs 4-7 */
-static void gen_high_BATs (CPUPPCState *env)
+static void gen_high_BATs(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     spr_register(env, SPR_IBAT4U, "IBAT4U",
@@ -914,7 +914,7 @@ static void gen_high_BATs (CPUPPCState *env)
 }
 
 /* Generic PowerPC time base */
-static void gen_tbl (CPUPPCState *env)
+static void gen_tbl(CPUPPCState *env)
 {
     spr_register(env, SPR_VTBL,  "TBL",
                  &spr_read_tbl, SPR_NOACCESS,
@@ -935,7 +935,7 @@ static void gen_tbl (CPUPPCState *env)
 }
 
 /* Softare table search registers */
-static void gen_6xx_7xx_soft_tlb (CPUPPCState *env, int nb_tlbs, int nb_ways)
+static void gen_6xx_7xx_soft_tlb(CPUPPCState *env, int nb_tlbs, int nb_ways)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->nb_tlb = nb_tlbs;
@@ -974,7 +974,7 @@ static void gen_6xx_7xx_soft_tlb (CPUPPCState *env, int nb_tlbs, int nb_ways)
 }
 
 /* SPR common to MPC755 and G2 */
-static void gen_spr_G2_755 (CPUPPCState *env)
+static void gen_spr_G2_755(CPUPPCState *env)
 {
     /* SGPRs */
     spr_register(env, SPR_SPRG4, "SPRG4",
@@ -996,7 +996,7 @@ static void gen_spr_G2_755 (CPUPPCState *env)
 }
 
 /* SPR common to all 7xx PowerPC implementations */
-static void gen_spr_7xx (CPUPPCState *env)
+static void gen_spr_7xx(CPUPPCState *env)
 {
     /* Breakpoints */
     /* XXX : not implemented */
@@ -1241,7 +1241,7 @@ static void spr_read_thrm(DisasContext *ctx, int gprn, int sprn)
 }
 #endif /* !CONFIG_USER_ONLY */
 
-static void gen_spr_thrm (CPUPPCState *env)
+static void gen_spr_thrm(CPUPPCState *env)
 {
     /* Thermal management */
     /* XXX : not implemented */
@@ -1262,7 +1262,7 @@ static void gen_spr_thrm (CPUPPCState *env)
 }
 
 /* SPR specific to PowerPC 604 implementation */
-static void gen_spr_604 (CPUPPCState *env)
+static void gen_spr_604(CPUPPCState *env)
 {
     /* Processor identification */
     spr_register(env, SPR_PIR, "PIR",
@@ -1315,7 +1315,7 @@ static void gen_spr_604 (CPUPPCState *env)
 }
 
 /* SPR specific to PowerPC 603 implementation */
-static void gen_spr_603 (CPUPPCState *env)
+static void gen_spr_603(CPUPPCState *env)
 {
     /* External access control */
     /* XXX : not implemented */
@@ -1333,7 +1333,7 @@ static void gen_spr_603 (CPUPPCState *env)
 }
 
 /* SPR specific to PowerPC G2 implementation */
-static void gen_spr_G2 (CPUPPCState *env)
+static void gen_spr_G2(CPUPPCState *env)
 {
     /* Memory base address */
     /* MBAR */
@@ -1385,7 +1385,7 @@ static void gen_spr_G2 (CPUPPCState *env)
 }
 
 /* SPR specific to PowerPC 602 implementation */
-static void gen_spr_602 (CPUPPCState *env)
+static void gen_spr_602(CPUPPCState *env)
 {
     /* ESA registers */
     /* XXX : not implemented */
@@ -1433,7 +1433,7 @@ static void gen_spr_602 (CPUPPCState *env)
 }
 
 /* SPR specific to PowerPC 601 implementation */
-static void gen_spr_601 (CPUPPCState *env)
+static void gen_spr_601(CPUPPCState *env)
 {
     /* Multiplication/division register */
     /* MQ */
@@ -1509,7 +1509,7 @@ static void gen_spr_601 (CPUPPCState *env)
 #endif
 }
 
-static void gen_spr_74xx (CPUPPCState *env)
+static void gen_spr_74xx(CPUPPCState *env)
 {
     /* Processor identification */
     spr_register(env, SPR_PIR, "PIR",
@@ -1561,7 +1561,7 @@ static void gen_spr_74xx (CPUPPCState *env)
     vscr_init(env, 0x00010000);
 }
 
-static void gen_l3_ctrl (CPUPPCState *env)
+static void gen_l3_ctrl(CPUPPCState *env)
 {
     /* L3CR */
     /* XXX : not implemented */
@@ -1583,7 +1583,7 @@ static void gen_l3_ctrl (CPUPPCState *env)
                  0x00000000);
 }
 
-static void gen_74xx_soft_tlb (CPUPPCState *env, int nb_tlbs, int nb_ways)
+static void gen_74xx_soft_tlb(CPUPPCState *env, int nb_tlbs, int nb_ways)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->nb_tlb = nb_tlbs;
@@ -1609,7 +1609,7 @@ static void gen_74xx_soft_tlb (CPUPPCState *env, int nb_tlbs, int nb_ways)
 }
 
 #if !defined(CONFIG_USER_ONLY)
-static void spr_write_e500_l1csr0 (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_e500_l1csr0(DisasContext *ctx, int sprn, int gprn)
 {
     TCGv t0 = tcg_temp_new();
 
@@ -1627,12 +1627,12 @@ static void spr_write_e500_l1csr1(DisasContext *ctx, int sprn, int gprn)
     tcg_temp_free(t0);
 }
 
-static void spr_write_booke206_mmucsr0 (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_booke206_mmucsr0(DisasContext *ctx, int sprn, int gprn)
 {
     gen_helper_booke206_tlbflush(cpu_env, cpu_gpr[gprn]);
 }
 
-static void spr_write_booke_pid (DisasContext *ctx, int sprn, int gprn)
+static void spr_write_booke_pid(DisasContext *ctx, int sprn, int gprn)
 {
     TCGv_i32 t0 = tcg_const_i32(sprn);
     gen_helper_booke_setpid(cpu_env, t0, cpu_gpr[gprn]);
@@ -1640,7 +1640,7 @@ static void spr_write_booke_pid (DisasContext *ctx, int sprn, int gprn)
 }
 #endif
 
-static void gen_spr_usprg3 (CPUPPCState *env)
+static void gen_spr_usprg3(CPUPPCState *env)
 {
     spr_register(env, SPR_USPRG3, "USPRG3",
                  &spr_read_ureg, SPR_NOACCESS,
@@ -1648,7 +1648,7 @@ static void gen_spr_usprg3 (CPUPPCState *env)
                  0x00000000);
 }
 
-static void gen_spr_usprgh (CPUPPCState *env)
+static void gen_spr_usprgh(CPUPPCState *env)
 {
     spr_register(env, SPR_USPRG4, "USPRG4",
                  &spr_read_ureg, SPR_NOACCESS,
@@ -1669,7 +1669,7 @@ static void gen_spr_usprgh (CPUPPCState *env)
 }
 
 /* PowerPC BookE SPR */
-static void gen_spr_BookE (CPUPPCState *env, uint64_t ivor_mask)
+static void gen_spr_BookE(CPUPPCState *env, uint64_t ivor_mask)
 {
     const char *ivor_names[64] = {
         "IVOR0",  "IVOR1",  "IVOR2",  "IVOR3",
@@ -1921,7 +1921,7 @@ static void gen_spr_BookE206(CPUPPCState *env, uint32_t mas_mask,
 }
 
 /* SPR specific to PowerPC 440 implementation */
-static void gen_spr_440 (CPUPPCState *env)
+static void gen_spr_440(CPUPPCState *env)
 {
     /* Cache control */
     /* XXX : not implemented */
@@ -2062,7 +2062,7 @@ static void gen_spr_440 (CPUPPCState *env)
 }
 
 /* SPR shared between PowerPC 40x implementations */
-static void gen_spr_40x (CPUPPCState *env)
+static void gen_spr_40x(CPUPPCState *env)
 {
     /* Cache */
     /* not emulated, as QEMU do not emulate caches */
@@ -2117,7 +2117,7 @@ static void gen_spr_40x (CPUPPCState *env)
 }
 
 /* SPR specific to PowerPC 405 implementation */
-static void gen_spr_405 (CPUPPCState *env)
+static void gen_spr_405(CPUPPCState *env)
 {
     /* MMU */
     spr_register(env, SPR_40x_PID, "PID",
@@ -2223,7 +2223,7 @@ static void gen_spr_405 (CPUPPCState *env)
 }
 
 /* SPR shared between PowerPC 401 & 403 implementations */
-static void gen_spr_401_403 (CPUPPCState *env)
+static void gen_spr_401_403(CPUPPCState *env)
 {
     /* Time base */
     spr_register(env, SPR_403_VTBL,  "TBL",
@@ -2251,7 +2251,7 @@ static void gen_spr_401_403 (CPUPPCState *env)
 }
 
 /* SPR specific to PowerPC 401 implementation */
-static void gen_spr_401 (CPUPPCState *env)
+static void gen_spr_401(CPUPPCState *env)
 {
     /* Debug interface */
     /* XXX : not implemented */
@@ -2293,7 +2293,7 @@ static void gen_spr_401 (CPUPPCState *env)
                  0x00000000);
 }
 
-static void gen_spr_401x2 (CPUPPCState *env)
+static void gen_spr_401x2(CPUPPCState *env)
 {
     gen_spr_401(env);
     spr_register(env, SPR_40x_PID, "PID",
@@ -2307,7 +2307,7 @@ static void gen_spr_401x2 (CPUPPCState *env)
 }
 
 /* SPR specific to PowerPC 403 implementation */
-static void gen_spr_403 (CPUPPCState *env)
+static void gen_spr_403(CPUPPCState *env)
 {
     /* Debug interface */
     /* XXX : not implemented */
@@ -2343,7 +2343,7 @@ static void gen_spr_403 (CPUPPCState *env)
                  0x00000000);
 }
 
-static void gen_spr_403_real (CPUPPCState *env)
+static void gen_spr_403_real(CPUPPCState *env)
 {
     spr_register(env, SPR_403_PBL1,  "PBL1",
                  SPR_NOACCESS, SPR_NOACCESS,
@@ -2363,7 +2363,7 @@ static void gen_spr_403_real (CPUPPCState *env)
                  0x00000000);
 }
 
-static void gen_spr_403_mmu (CPUPPCState *env)
+static void gen_spr_403_mmu(CPUPPCState *env)
 {
     /* MMU */
     spr_register(env, SPR_40x_PID, "PID",
@@ -2377,7 +2377,7 @@ static void gen_spr_403_mmu (CPUPPCState *env)
 }
 
 /* SPR specific to PowerPC compression coprocessor extension */
-static void gen_spr_compress (CPUPPCState *env)
+static void gen_spr_compress(CPUPPCState *env)
 {
     /* XXX : not implemented */
     spr_register(env, SPR_401_SKR, "SKR",
@@ -2386,7 +2386,7 @@ static void gen_spr_compress (CPUPPCState *env)
                  0x00000000);
 }
 
-static void gen_spr_5xx_8xx (CPUPPCState *env)
+static void gen_spr_5xx_8xx(CPUPPCState *env)
 {
     /* Exception processing */
     spr_register_kvm(env, SPR_DSISR, "DSISR",
@@ -2504,7 +2504,7 @@ static void gen_spr_5xx_8xx (CPUPPCState *env)
                  0x00000000);
 }
 
-static void gen_spr_5xx (CPUPPCState *env)
+static void gen_spr_5xx(CPUPPCState *env)
 {
     /* XXX : not implemented */
     spr_register(env, SPR_RCPU_MI_GRA, "MI_GRA",
@@ -2613,7 +2613,7 @@ static void gen_spr_5xx (CPUPPCState *env)
                  0x00000000);
 }
 
-static void gen_spr_8xx (CPUPPCState *env)
+static void gen_spr_8xx(CPUPPCState *env)
 {
     /* XXX : not implemented */
     spr_register(env, SPR_MPC_IC_CST, "IC_CST",
@@ -2775,7 +2775,7 @@ static void gen_spr_8xx (CPUPPCState *env)
 
 /*****************************************************************************/
 /* Exception vectors models                                                  */
-static void init_excp_4xx_real (CPUPPCState *env)
+static void init_excp_4xx_real(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100;
@@ -2795,7 +2795,7 @@ static void init_excp_4xx_real (CPUPPCState *env)
 #endif
 }
 
-static void init_excp_4xx_softmmu (CPUPPCState *env)
+static void init_excp_4xx_softmmu(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100;
@@ -2819,7 +2819,7 @@ static void init_excp_4xx_softmmu (CPUPPCState *env)
 #endif
 }
 
-static void init_excp_MPC5xx (CPUPPCState *env)
+static void init_excp_MPC5xx(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000100;
@@ -2844,7 +2844,7 @@ static void init_excp_MPC5xx (CPUPPCState *env)
 #endif
 }
 
-static void init_excp_MPC8xx (CPUPPCState *env)
+static void init_excp_MPC8xx(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000100;
@@ -2875,7 +2875,7 @@ static void init_excp_MPC8xx (CPUPPCState *env)
 #endif
 }
 
-static void init_excp_G2 (CPUPPCState *env)
+static void init_excp_G2(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000100;
@@ -2930,7 +2930,7 @@ static void init_excp_e200(CPUPPCState *env, target_ulong ivpr_mask)
 #endif
 }
 
-static void init_excp_BookE (CPUPPCState *env)
+static void init_excp_BookE(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000;
@@ -2956,7 +2956,7 @@ static void init_excp_BookE (CPUPPCState *env)
 #endif
 }
 
-static void init_excp_601 (CPUPPCState *env)
+static void init_excp_601(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000100;
@@ -2976,7 +2976,7 @@ static void init_excp_601 (CPUPPCState *env)
 #endif
 }
 
-static void init_excp_602 (CPUPPCState *env)
+static void init_excp_602(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     /* XXX: exception prefix has a special behavior on 602 */
@@ -3003,7 +3003,7 @@ static void init_excp_602 (CPUPPCState *env)
 #endif
 }
 
-static void init_excp_603 (CPUPPCState *env)
+static void init_excp_603(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000100;
@@ -3027,7 +3027,7 @@ static void init_excp_603 (CPUPPCState *env)
 #endif
 }
 
-static void init_excp_604 (CPUPPCState *env)
+static void init_excp_604(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000100;
@@ -3049,7 +3049,7 @@ static void init_excp_604 (CPUPPCState *env)
 #endif
 }
 
-static void init_excp_7x0 (CPUPPCState *env)
+static void init_excp_7x0(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000100;
@@ -3072,7 +3072,7 @@ static void init_excp_7x0 (CPUPPCState *env)
 #endif
 }
 
-static void init_excp_750cl (CPUPPCState *env)
+static void init_excp_750cl(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000100;
@@ -3094,7 +3094,7 @@ static void init_excp_750cl (CPUPPCState *env)
 #endif
 }
 
-static void init_excp_750cx (CPUPPCState *env)
+static void init_excp_750cx(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000100;
@@ -3117,7 +3117,7 @@ static void init_excp_750cx (CPUPPCState *env)
 }
 
 /* XXX: Check if this is correct */
-static void init_excp_7x5 (CPUPPCState *env)
+static void init_excp_7x5(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000100;
@@ -3143,7 +3143,7 @@ static void init_excp_7x5 (CPUPPCState *env)
 #endif
 }
 
-static void init_excp_7400 (CPUPPCState *env)
+static void init_excp_7400(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000100;
@@ -3168,7 +3168,7 @@ static void init_excp_7400 (CPUPPCState *env)
 #endif
 }
 
-static void init_excp_7450 (CPUPPCState *env)
+static void init_excp_7450(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000100;
@@ -3195,8 +3195,8 @@ static void init_excp_7450 (CPUPPCState *env)
 #endif
 }
 
-#if defined (TARGET_PPC64)
-static void init_excp_970 (CPUPPCState *env)
+#if defined(TARGET_PPC64)
+static void init_excp_970(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000100;
@@ -3224,7 +3224,7 @@ static void init_excp_970 (CPUPPCState *env)
 #endif
 }
 
-static void init_excp_POWER7 (CPUPPCState *env)
+static void init_excp_POWER7(CPUPPCState *env)
 {
 #if !defined(CONFIG_USER_ONLY)
     env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000100;
@@ -3269,17 +3269,17 @@ static void init_excp_POWER8(CPUPPCState *env)
 
 /*****************************************************************************/
 /* Power management enable checks                                            */
-static int check_pow_none (CPUPPCState *env)
+static int check_pow_none(CPUPPCState *env)
 {
     return 0;
 }
 
-static int check_pow_nocheck (CPUPPCState *env)
+static int check_pow_nocheck(CPUPPCState *env)
 {
     return 1;
 }
 
-static int check_pow_hid0 (CPUPPCState *env)
+static int check_pow_hid0(CPUPPCState *env)
 {
     if (env->spr[SPR_HID0] & 0x00E00000)
         return 1;
@@ -3287,7 +3287,7 @@ static int check_pow_hid0 (CPUPPCState *env)
     return 0;
 }
 
-static int check_pow_hid0_74xx (CPUPPCState *env)
+static int check_pow_hid0_74xx(CPUPPCState *env)
 {
     if (env->spr[SPR_HID0] & 0x00600000)
         return 1;
@@ -3332,7 +3332,7 @@ static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU *cpu)
                                                                             \
     static void glue(glue(ppc_, _name), _cpu_family_class_init)
 
-static void init_proc_401 (CPUPPCState *env)
+static void init_proc_401(CPUPPCState *env)
 {
     gen_spr_40x(env);
     gen_spr_401_403(env);
@@ -3378,7 +3378,7 @@ POWERPC_FAMILY(401)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_401x2 (CPUPPCState *env)
+static void init_proc_401x2(CPUPPCState *env)
 {
     gen_spr_40x(env);
     gen_spr_401_403(env);
@@ -3436,7 +3436,7 @@ POWERPC_FAMILY(401x2)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_401x3 (CPUPPCState *env)
+static void init_proc_401x3(CPUPPCState *env)
 {
     gen_spr_40x(env);
     gen_spr_401_403(env);
@@ -3489,7 +3489,7 @@ POWERPC_FAMILY(401x3)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_IOP480 (CPUPPCState *env)
+static void init_proc_IOP480(CPUPPCState *env)
 {
     gen_spr_40x(env);
     gen_spr_401_403(env);
@@ -3547,7 +3547,7 @@ POWERPC_FAMILY(IOP480)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_403 (CPUPPCState *env)
+static void init_proc_403(CPUPPCState *env)
 {
     gen_spr_40x(env);
     gen_spr_401_403(env);
@@ -3594,7 +3594,7 @@ POWERPC_FAMILY(403)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_403GCX (CPUPPCState *env)
+static void init_proc_403GCX(CPUPPCState *env)
 {
     gen_spr_40x(env);
     gen_spr_401_403(env);
@@ -3661,7 +3661,7 @@ POWERPC_FAMILY(403GCX)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_405 (CPUPPCState *env)
+static void init_proc_405(CPUPPCState *env)
 {
     /* Time base */
     gen_tbl(env);
@@ -3727,7 +3727,7 @@ POWERPC_FAMILY(405)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_440EP (CPUPPCState *env)
+static void init_proc_440EP(CPUPPCState *env)
 {
     /* Time base */
     gen_tbl(env);
@@ -3831,7 +3831,7 @@ POWERPC_FAMILY(440EP)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_440GP (CPUPPCState *env)
+static void init_proc_440GP(CPUPPCState *env)
 {
     /* Time base */
     gen_tbl(env);
@@ -3914,7 +3914,7 @@ POWERPC_FAMILY(440GP)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_440x4 (CPUPPCState *env)
+static void init_proc_440x4(CPUPPCState *env)
 {
     /* Time base */
     gen_tbl(env);
@@ -3997,7 +3997,7 @@ POWERPC_FAMILY(440x4)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_440x5 (CPUPPCState *env)
+static void init_proc_440x5(CPUPPCState *env)
 {
     /* Time base */
     gen_tbl(env);
@@ -4243,7 +4243,7 @@ POWERPC_FAMILY(460)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_460F (CPUPPCState *env)
+static void init_proc_460F(CPUPPCState *env)
 {
     /* Time base */
     gen_tbl(env);
@@ -4353,7 +4353,7 @@ POWERPC_FAMILY(460F)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_MPC5xx (CPUPPCState *env)
+static void init_proc_MPC5xx(CPUPPCState *env)
 {
     /* Time base */
     gen_tbl(env);
@@ -4397,7 +4397,7 @@ POWERPC_FAMILY(MPC5xx)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_MPC8xx (CPUPPCState *env)
+static void init_proc_MPC8xx(CPUPPCState *env)
 {
     /* Time base */
     gen_tbl(env);
@@ -4442,7 +4442,7 @@ POWERPC_FAMILY(MPC8xx)(ObjectClass *oc, void *data)
 
 /* Freescale 82xx cores (aka PowerQUICC-II)                                  */
 
-static void init_proc_G2 (CPUPPCState *env)
+static void init_proc_G2(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -4521,7 +4521,7 @@ POWERPC_FAMILY(G2)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_G2LE (CPUPPCState *env)
+static void init_proc_G2LE(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -4603,7 +4603,7 @@ POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_e200 (CPUPPCState *env)
+static void init_proc_e200(CPUPPCState *env)
 {
     /* Time base */
     gen_tbl(env);
@@ -4757,7 +4757,7 @@ POWERPC_FAMILY(e200)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_e300 (CPUPPCState *env)
+static void init_proc_e300(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -4889,7 +4889,7 @@ enum fsl_e500_version {
     fsl_e5500,
 };
 
-static void init_proc_e500 (CPUPPCState *env, int version)
+static void init_proc_e500(CPUPPCState *env, int version)
 {
     PowerPCCPU *cpu = ppc_env_get_cpu(env);
     uint32_t tlbncfg[2];
@@ -5258,7 +5258,7 @@ POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data)
 
 #define POWERPC_MSRR_601     (0x0000000000001040ULL)
 
-static void init_proc_601 (CPUPPCState *env)
+static void init_proc_601(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -5331,7 +5331,7 @@ POWERPC_FAMILY(601)(ObjectClass *oc, void *data)
 
 #define POWERPC_MSRR_601v    (0x0000000000001040ULL)
 
-static void init_proc_601v (CPUPPCState *env)
+static void init_proc_601v(CPUPPCState *env)
 {
     init_proc_601(env);
     /* XXX : not implemented */
@@ -5373,7 +5373,7 @@ POWERPC_FAMILY(601v)(ObjectClass *oc, void *data)
     pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK;
 }
 
-static void init_proc_602 (CPUPPCState *env)
+static void init_proc_602(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -5443,7 +5443,7 @@ POWERPC_FAMILY(602)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_603 (CPUPPCState *env)
+static void init_proc_603(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -5510,7 +5510,7 @@ POWERPC_FAMILY(603)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_603E (CPUPPCState *env)
+static void init_proc_603E(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -5577,7 +5577,7 @@ POWERPC_FAMILY(603E)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_604 (CPUPPCState *env)
+static void init_proc_604(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -5641,7 +5641,7 @@ POWERPC_FAMILY(604)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_604E (CPUPPCState *env)
+static void init_proc_604E(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -5725,7 +5725,7 @@ POWERPC_FAMILY(604E)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_740 (CPUPPCState *env)
+static void init_proc_740(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -5796,7 +5796,7 @@ POWERPC_FAMILY(740)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_750 (CPUPPCState *env)
+static void init_proc_750(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -5875,7 +5875,7 @@ POWERPC_FAMILY(750)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_750cl (CPUPPCState *env)
+static void init_proc_750cl(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -6077,7 +6077,7 @@ POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_750cx (CPUPPCState *env)
+static void init_proc_750cx(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -6160,7 +6160,7 @@ POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_750fx (CPUPPCState *env)
+static void init_proc_750fx(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -6248,7 +6248,7 @@ POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_750gx (CPUPPCState *env)
+static void init_proc_750gx(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -6336,7 +6336,7 @@ POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_745 (CPUPPCState *env)
+static void init_proc_745(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -6412,7 +6412,7 @@ POWERPC_FAMILY(745)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_755 (CPUPPCState *env)
+static void init_proc_755(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -6499,7 +6499,7 @@ POWERPC_FAMILY(755)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_7400 (CPUPPCState *env)
+static void init_proc_7400(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -6578,7 +6578,7 @@ POWERPC_FAMILY(7400)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_7410 (CPUPPCState *env)
+static void init_proc_7410(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -6663,7 +6663,7 @@ POWERPC_FAMILY(7410)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_7440 (CPUPPCState *env)
+static void init_proc_7440(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -6771,7 +6771,7 @@ POWERPC_FAMILY(7440)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_7450 (CPUPPCState *env)
+static void init_proc_7450(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -6905,7 +6905,7 @@ POWERPC_FAMILY(7450)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_7445 (CPUPPCState *env)
+static void init_proc_7445(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -7042,7 +7042,7 @@ POWERPC_FAMILY(7445)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_7455 (CPUPPCState *env)
+static void init_proc_7455(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -7181,7 +7181,7 @@ POWERPC_FAMILY(7455)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_7457 (CPUPPCState *env)
+static void init_proc_7457(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -7344,7 +7344,7 @@ POWERPC_FAMILY(7457)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BUS_CLK;
 }
 
-static void init_proc_e600 (CPUPPCState *env)
+static void init_proc_e600(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
     gen_spr_sdr1(env);
@@ -7486,7 +7486,7 @@ POWERPC_FAMILY(e600)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BUS_CLK;
 }
 
-#if defined (TARGET_PPC64)
+#if defined(TARGET_PPC64)
 #if defined(CONFIG_USER_ONLY)
 #define POWERPC970_HID5_INIT 0x00000080
 #else
@@ -7545,7 +7545,7 @@ static void spr_write_prev_upper32(DisasContext *ctx, int sprn, int gprn)
     tcg_temp_free(spr);
 }
 
-static int check_pow_970 (CPUPPCState *env)
+static int check_pow_970(CPUPPCState *env)
 {
     if (env->spr[SPR_HID0] & (HID0_DEEPNAP | HID0_DOZE | HID0_NAP)) {
         return 1;
@@ -8513,7 +8513,7 @@ static const struct ppc_segment_page_sizes POWER7_POWER8_sps = {
 };
 #endif /* CONFIG_SOFTMMU */
 
-static void init_proc_POWER7 (CPUPPCState *env)
+static void init_proc_POWER7(CPUPPCState *env)
 {
     /* Common Registers */
     init_proc_book3s_common(env);
@@ -9079,7 +9079,7 @@ void cpu_ppc_set_papr(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp)
 
 #endif /* !defined(CONFIG_USER_ONLY) */
 
-#endif /* defined (TARGET_PPC64) */
+#endif /* defined(TARGET_PPC64) */
 
 /*****************************************************************************/
 /* Generic CPU instantiation routine                                         */
@@ -9250,7 +9250,7 @@ static void init_ppc_proc(PowerPCCPU *cpu)
 }
 
 #if defined(PPC_DUMP_CPU)
-static void dump_ppc_sprs (CPUPPCState *env)
+static void dump_ppc_sprs(CPUPPCState *env)
 {
     ppc_spr_t *spr;
 #if !defined(CONFIG_USER_ONLY)
@@ -9299,7 +9299,7 @@ enum {
 
 #define PPC_OPCODE_MASK 0x3
 
-static inline int is_indirect_opcode (void *handler)
+static inline int is_indirect_opcode(void *handler)
 {
     return ((uintptr_t)handler & PPC_OPCODE_MASK) == PPC_INDIRECT;
 }
@@ -9311,7 +9311,7 @@ static inline opc_handler_t **ind_table(void *handler)
 
 /* Instruction table creation */
 /* Opcodes tables creation */
-static void fill_new_table (opc_handler_t **table, int len)
+static void fill_new_table(opc_handler_t **table, int len)
 {
     int i;
 
@@ -9319,7 +9319,7 @@ static void fill_new_table (opc_handler_t **table, int len)
         table[i] = &invalid_handler;
 }
 
-static int create_new_table (opc_handler_t **table, unsigned char idx)
+static int create_new_table(opc_handler_t **table, unsigned char idx)
 {
     opc_handler_t **tmp;
 
@@ -9330,7 +9330,7 @@ static int create_new_table (opc_handler_t **table, unsigned char idx)
     return 0;
 }
 
-static int insert_in_table (opc_handler_t **table, unsigned char idx,
+static int insert_in_table(opc_handler_t **table, unsigned char idx,
                             opc_handler_t *handler)
 {
     if (table[idx] != &invalid_handler)
@@ -9340,8 +9340,8 @@ static int insert_in_table (opc_handler_t **table, unsigned char idx,
     return 0;
 }
 
-static int register_direct_insn (opc_handler_t **ppc_opcodes,
-                                 unsigned char idx, opc_handler_t *handler)
+static int register_direct_insn(opc_handler_t **ppc_opcodes,
+                                unsigned char idx, opc_handler_t *handler)
 {
     if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
         printf("*** ERROR: opcode %02x already assigned in main "
@@ -9356,9 +9356,9 @@ static int register_direct_insn (opc_handler_t **ppc_opcodes,
     return 0;
 }
 
-static int register_ind_in_table (opc_handler_t **table,
-                                  unsigned char idx1, unsigned char idx2,
-                                  opc_handler_t *handler)
+static int register_ind_in_table(opc_handler_t **table,
+                                 unsigned char idx1, unsigned char idx2,
+                                 opc_handler_t *handler)
 {
     if (table[idx1] == &invalid_handler) {
         if (create_new_table(table, idx1) < 0) {
@@ -9391,16 +9391,16 @@ static int register_ind_in_table (opc_handler_t **table,
     return 0;
 }
 
-static int register_ind_insn (opc_handler_t **ppc_opcodes,
-                              unsigned char idx1, unsigned char idx2,
-                              opc_handler_t *handler)
+static int register_ind_insn(opc_handler_t **ppc_opcodes,
+                             unsigned char idx1, unsigned char idx2,
+                             opc_handler_t *handler)
 {
     return register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
 }
 
-static int register_dblind_insn (opc_handler_t **ppc_opcodes,
-                                 unsigned char idx1, unsigned char idx2,
-                                 unsigned char idx3, opc_handler_t *handler)
+static int register_dblind_insn(opc_handler_t **ppc_opcodes,
+                                unsigned char idx1, unsigned char idx2,
+                                unsigned char idx3, opc_handler_t *handler)
 {
     if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
         printf("*** ERROR: unable to join indirect table idx "
@@ -9443,7 +9443,7 @@ static int register_trplind_insn(opc_handler_t **ppc_opcodes,
     }
     return 0;
 }
-static int register_insn (opc_handler_t **ppc_opcodes, opcode_t *insn)
+static int register_insn(opc_handler_t **ppc_opcodes, opcode_t *insn)
 {
     if (insn->opc2 != 0xFF) {
         if (insn->opc3 != 0xFF) {
@@ -9471,7 +9471,7 @@ static int register_insn (opc_handler_t **ppc_opcodes, opcode_t *insn)
     return 0;
 }
 
-static int test_opcode_table (opc_handler_t **table, int len)
+static int test_opcode_table(opc_handler_t **table, int len)
 {
     int i, count, tmp;
 
@@ -9498,7 +9498,7 @@ static int test_opcode_table (opc_handler_t **table, int len)
     return count;
 }
 
-static void fix_opcode_tables (opc_handler_t **ppc_opcodes)
+static void fix_opcode_tables(opc_handler_t **ppc_opcodes)
 {
     if (test_opcode_table(ppc_opcodes, PPC_CPU_OPCODES_LEN) == 0)
         printf("*** WARNING: no opcode defined !\n");
@@ -9529,7 +9529,7 @@ static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp)
 }
 
 #if defined(PPC_DUMP_CPU)
-static void dump_ppc_insns (CPUPPCState *env)
+static void dump_ppc_insns(CPUPPCState *env)
 {
     opc_handler_t **table, *handler;
     const char *p, *q;
@@ -9943,7 +9943,7 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
         case POWERPC_MMU_601:
             mmu_model = "PowerPC 601";
             break;
-#if defined (TARGET_PPC64)
+#if defined(TARGET_PPC64)
         case POWERPC_MMU_64B:
             mmu_model = "PowerPC 64";
             break;
@@ -9986,7 +9986,7 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
         case POWERPC_EXCP_BOOKE:
             excp_model = "PowerPC BookE";
             break;
-#if defined (TARGET_PPC64)
+#if defined(TARGET_PPC64)
         case POWERPC_EXCP_970:
             excp_model = "PowerPC 970";
             break;
@@ -10011,7 +10011,7 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
         case PPC_FLAGS_INPUT_RCPU:
             bus_model = "RCPU / MPC8xx";
             break;
-#if defined (TARGET_PPC64)
+#if defined(TARGET_PPC64)
         case PPC_FLAGS_INPUT_970:
             bus_model = "PowerPC 970";
             break;
-- 
2.9.3

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

* Re: [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (46 preceding siblings ...)
  2017-04-24  1:59 ` [Qemu-devel] [PULL 47/47] target/ppc: Style fixes David Gibson
@ 2017-04-24  3:08 ` no-reply
  2017-04-24  4:25   ` [Qemu-devel] [Qemu-ppc] " David Gibson
  2017-04-24 13:12 ` [Qemu-devel] " Peter Maydell
  48 siblings, 1 reply; 61+ messages in thread
From: no-reply @ 2017-04-24  3:08 UTC (permalink / raw)
  To: david; +Cc: famz, peter.maydell, mdroth, aik, qemu-devel, agraf, qemu-ppc, clg

Hi,

This series seems to have some coding style problems. See output below for
more information:

Message-id: 20170424015927.8933-1-david@gibson.dropbear.id.au
Subject: [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

# Useful git options
git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
94bea6a target/ppc: Style fixes
d23eac0 e500, book3s: mfspr 259: Register mapped/aliased SPRG3 user read
3a5bd96 target/ppc: Flush TLB on write to PIDR
3240e33 spapr-cpu-core: Release ICPState object during CPU unrealization
ea6341d ppc/pnv: generate an OEM SEL event on shutdown
130cf1f ppc/pnv: add initial IPMI sensors for the BMC simulator
7e24b32 ppc/pnv: populate device tree for IPMI BT devices
6575717 ppc/pnv: populate device tree for serial devices
836d562 ppc/pnv: populate device tree for RTC devices
dca8231 ppc/pnv: scan ISA bus to populate device tree
4d631b7 ppc/pnv: enable only one LPC bus
af22372 ppc/pnv: Add support for POWER8+ LPC Controller
2d79b40 spapr: remove the 'nr_servers' field from the machine
8fa3c09 target/ppc: Fix size of struct PPCElfPrstatus
212f4d7 ipmi: introduce an ipmi_bmc_gen_event() API
240da02 ipmi: introduce an ipmi_bmc_sdr_find() API
3607ef7 ipmi: provide support for FRUs
aa873a2 ipmi: use a file to load SDRs
ef1ce62 ppc: add IPMI support
1a8fffd ppc/pnv: Add OCC model stub with interrupt support
828bcfa ppc/pnv: Add cut down PSI bridge model and hookup external interrupt
ac8392a ppc/pnv: add memory regions for the ICP registers
d90ca95 ppc/pnv: add a helper to calculate MMIO addresses registers
a5a614b ppc/pnv: create the ICP object under PnvCore
5f43b5e ppc/pnv: extend the machine with a InterruptStatsProvider interface
04dfecf ppc/pnv: extend the machine with a XICSFabric interface
5b94a0f ppc/pnv: add a PnvICPState object
96c645e ppc/xics: add a realize() handler to ICPStateClass
4569615 spapr: allocate the ICPState object from under sPAPRCPUCore
8257d1e spapr: move the IRQ server number mapping under the machine
56d6f91 ppc/xics: introduce an 'intc' backlink under PowerPCCPU
f024a9a target/ppc: Add ibm, processor-radix-AP-encodings for TCG
a0d8df3 spapr_pci: Removed unused include
7cc7952 spapr_pci: Warn when RAM page size is not enabled in IOMMU page mask
2093121 target-ppc/kvm: Enable in-kernel TCE acceleration for multi-tce
26538ee spapr: Workaround for broken radix guests
d2da420 spapr: Enable ISA 3.0 MMU mode selection via CAS
50fe08d spapr: move spapr_populate_pa_features()
d667f21 target/ppc: Implement H_REGISTER_PROCESS_TABLE H_CALL
129c199 target/ppc: Add new H-CALL shells for in memory table translation
d033285 target-ppc: support KVM_CAP_PPC_MMU_RADIX, KVM_CAP_PPC_MMU_HASH_V3
38c395b spapr: Add ibm, processor-radix-AP-encodings to the device tree
4fe232c target-ppc: kvm: make use of KVM_CREATE_SPAPR_TCE_64
90f87ad hw/ppc/pnv: Classify the "PowerNV Chip" devices as CPU devices
c98837a ppc/spapr: QOM'ify sPAPRRTCState
1bc37a7 pseries: Add pseries-2.10 machine type
40a726e target/ppc: Improve accuracy of guest HTM availability on P8s

=== OUTPUT BEGIN ===
Checking PATCH 1/47: target/ppc: Improve accuracy of guest HTM availability on P8s...
Checking PATCH 2/47: pseries: Add pseries-2.10 machine type...
Checking PATCH 3/47: ppc/spapr: QOM'ify sPAPRRTCState...
Checking PATCH 4/47: hw/ppc/pnv: Classify the "PowerNV Chip" devices as CPU devices...
Checking PATCH 5/47: target-ppc: kvm: make use of KVM_CREATE_SPAPR_TCE_64...
Checking PATCH 6/47: spapr: Add ibm, processor-radix-AP-encodings to the device tree...
Checking PATCH 7/47: target-ppc: support KVM_CAP_PPC_MMU_RADIX, KVM_CAP_PPC_MMU_HASH_V3...
Checking PATCH 8/47: target/ppc: Add new H-CALL shells for in memory table translation...
Checking PATCH 9/47: target/ppc: Implement H_REGISTER_PROCESS_TABLE H_CALL...
Checking PATCH 10/47: spapr: move spapr_populate_pa_features()...
Checking PATCH 11/47: spapr: Enable ISA 3.0 MMU mode selection via CAS...
Checking PATCH 12/47: spapr: Workaround for broken radix guests...
Checking PATCH 13/47: target-ppc/kvm: Enable in-kernel TCE acceleration for multi-tce...
Checking PATCH 14/47: spapr_pci: Warn when RAM page size is not enabled in IOMMU page mask...
Checking PATCH 15/47: spapr_pci: Removed unused include...
Checking PATCH 16/47: target/ppc: Add ibm, processor-radix-AP-encodings for TCG...
Checking PATCH 17/47: ppc/xics: introduce an 'intc' backlink under PowerPCCPU...
Checking PATCH 18/47: spapr: move the IRQ server number mapping under the machine...
Checking PATCH 19/47: spapr: allocate the ICPState object from under sPAPRCPUCore...
Checking PATCH 20/47: ppc/xics: add a realize() handler to ICPStateClass...
Checking PATCH 21/47: ppc/pnv: add a PnvICPState object...
Checking PATCH 22/47: ppc/pnv: extend the machine with a XICSFabric interface...
Checking PATCH 23/47: ppc/pnv: extend the machine with a InterruptStatsProvider interface...
Checking PATCH 24/47: ppc/pnv: create the ICP object under PnvCore...
Checking PATCH 25/47: ppc/pnv: add a helper to calculate MMIO addresses registers...
Checking PATCH 26/47: ppc/pnv: add memory regions for the ICP registers...
Checking PATCH 27/47: ppc/pnv: Add cut down PSI bridge model and hookup external interrupt...
Checking PATCH 28/47: ppc/pnv: Add OCC model stub with interrupt support...
Checking PATCH 29/47: ppc: add IPMI support...
Checking PATCH 30/47: ipmi: use a file to load SDRs...
Checking PATCH 31/47: ipmi: provide support for FRUs...
Checking PATCH 32/47: ipmi: introduce an ipmi_bmc_sdr_find() API...
Checking PATCH 33/47: ipmi: introduce an ipmi_bmc_gen_event() API...
Checking PATCH 34/47: target/ppc: Fix size of struct PPCElfPrstatus...
Checking PATCH 35/47: spapr: remove the 'nr_servers' field from the machine...
Checking PATCH 36/47: ppc/pnv: Add support for POWER8+ LPC Controller...
Checking PATCH 37/47: ppc/pnv: enable only one LPC bus...
Checking PATCH 38/47: ppc/pnv: scan ISA bus to populate device tree...
Checking PATCH 39/47: ppc/pnv: populate device tree for RTC devices...
Checking PATCH 40/47: ppc/pnv: populate device tree for serial devices...
Checking PATCH 41/47: ppc/pnv: populate device tree for IPMI BT devices...
Checking PATCH 42/47: ppc/pnv: add initial IPMI sensors for the BMC simulator...
Checking PATCH 43/47: ppc/pnv: generate an OEM SEL event on shutdown...
Checking PATCH 44/47: spapr-cpu-core: Release ICPState object during CPU unrealization...
Checking PATCH 45/47: target/ppc: Flush TLB on write to PIDR...
Checking PATCH 46/47: e500, book3s: mfspr 259: Register mapped/aliased SPRG3 user read...
ERROR: space prohibited between function name and open parenthesis '('
#51: FILE: target/ppc/translate_init.c:1643:
+static void gen_spr_usprg3 (CPUPPCState *env)

total: 1 errors, 0 warnings, 28 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 47/47: target/ppc: Style fixes...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

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

* Re: [Qemu-devel] [Qemu-ppc] [PULL 00/47] ppc-for-2.10 queue 20170424
  2017-04-24  3:08 ` [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 no-reply
@ 2017-04-24  4:25   ` David Gibson
  0 siblings, 0 replies; 61+ messages in thread
From: David Gibson @ 2017-04-24  4:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, famz, mdroth, qemu-ppc, clg

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

On Sun, Apr 23, 2017 at 08:08:23PM -0700, no-reply@patchew.org wrote:
> Hi,
> 
> This series seems to have some coding style problems. See output below for
> more information:
> 
> Message-id: 20170424015927.8933-1-david@gibson.dropbear.id.au
> Subject: [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424
> Type: series
> 
> === TEST SCRIPT BEGIN ===
> #!/bin/bash
> 
> BASE=base
> n=1
> total=$(git log --oneline $BASE.. | wc -l)
> failed=0
> 
> # Useful git options
> git config --local diff.renamelimit 0
> git config --local diff.renames True
> 
> commits="$(git log --format=%H --reverse $BASE..)"
> for c in $commits; do
>     echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
>     if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
>         failed=1
>         echo
>     fi
>     n=$((n+1))
> done
> 
> exit $failed
> === TEST SCRIPT END ===
> 
> Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
> Switched to a new branch 'test'
> 94bea6a target/ppc: Style fixes
> d23eac0 e500, book3s: mfspr 259: Register mapped/aliased SPRG3 user read
> 3a5bd96 target/ppc: Flush TLB on write to PIDR
> 3240e33 spapr-cpu-core: Release ICPState object during CPU unrealization
> ea6341d ppc/pnv: generate an OEM SEL event on shutdown
> 130cf1f ppc/pnv: add initial IPMI sensors for the BMC simulator
> 7e24b32 ppc/pnv: populate device tree for IPMI BT devices
> 6575717 ppc/pnv: populate device tree for serial devices
> 836d562 ppc/pnv: populate device tree for RTC devices
> dca8231 ppc/pnv: scan ISA bus to populate device tree
> 4d631b7 ppc/pnv: enable only one LPC bus
> af22372 ppc/pnv: Add support for POWER8+ LPC Controller
> 2d79b40 spapr: remove the 'nr_servers' field from the machine
> 8fa3c09 target/ppc: Fix size of struct PPCElfPrstatus
> 212f4d7 ipmi: introduce an ipmi_bmc_gen_event() API
> 240da02 ipmi: introduce an ipmi_bmc_sdr_find() API
> 3607ef7 ipmi: provide support for FRUs
> aa873a2 ipmi: use a file to load SDRs
> ef1ce62 ppc: add IPMI support
> 1a8fffd ppc/pnv: Add OCC model stub with interrupt support
> 828bcfa ppc/pnv: Add cut down PSI bridge model and hookup external interrupt
> ac8392a ppc/pnv: add memory regions for the ICP registers
> d90ca95 ppc/pnv: add a helper to calculate MMIO addresses registers
> a5a614b ppc/pnv: create the ICP object under PnvCore
> 5f43b5e ppc/pnv: extend the machine with a InterruptStatsProvider interface
> 04dfecf ppc/pnv: extend the machine with a XICSFabric interface
> 5b94a0f ppc/pnv: add a PnvICPState object
> 96c645e ppc/xics: add a realize() handler to ICPStateClass
> 4569615 spapr: allocate the ICPState object from under sPAPRCPUCore
> 8257d1e spapr: move the IRQ server number mapping under the machine
> 56d6f91 ppc/xics: introduce an 'intc' backlink under PowerPCCPU
> f024a9a target/ppc: Add ibm, processor-radix-AP-encodings for TCG
> a0d8df3 spapr_pci: Removed unused include
> 7cc7952 spapr_pci: Warn when RAM page size is not enabled in IOMMU page mask
> 2093121 target-ppc/kvm: Enable in-kernel TCE acceleration for multi-tce
> 26538ee spapr: Workaround for broken radix guests
> d2da420 spapr: Enable ISA 3.0 MMU mode selection via CAS
> 50fe08d spapr: move spapr_populate_pa_features()
> d667f21 target/ppc: Implement H_REGISTER_PROCESS_TABLE H_CALL
> 129c199 target/ppc: Add new H-CALL shells for in memory table translation
> d033285 target-ppc: support KVM_CAP_PPC_MMU_RADIX, KVM_CAP_PPC_MMU_HASH_V3
> 38c395b spapr: Add ibm, processor-radix-AP-encodings to the device tree
> 4fe232c target-ppc: kvm: make use of KVM_CREATE_SPAPR_TCE_64
> 90f87ad hw/ppc/pnv: Classify the "PowerNV Chip" devices as CPU devices
> c98837a ppc/spapr: QOM'ify sPAPRRTCState
> 1bc37a7 pseries: Add pseries-2.10 machine type
> 40a726e target/ppc: Improve accuracy of guest HTM availability on P8s
> 
> === OUTPUT BEGIN ===
> Checking PATCH 1/47: target/ppc: Improve accuracy of guest HTM availability on P8s...
> Checking PATCH 2/47: pseries: Add pseries-2.10 machine type...
> Checking PATCH 3/47: ppc/spapr: QOM'ify sPAPRRTCState...
> Checking PATCH 4/47: hw/ppc/pnv: Classify the "PowerNV Chip" devices as CPU devices...
> Checking PATCH 5/47: target-ppc: kvm: make use of KVM_CREATE_SPAPR_TCE_64...
> Checking PATCH 6/47: spapr: Add ibm, processor-radix-AP-encodings to the device tree...
> Checking PATCH 7/47: target-ppc: support KVM_CAP_PPC_MMU_RADIX, KVM_CAP_PPC_MMU_HASH_V3...
> Checking PATCH 8/47: target/ppc: Add new H-CALL shells for in memory table translation...
> Checking PATCH 9/47: target/ppc: Implement H_REGISTER_PROCESS_TABLE H_CALL...
> Checking PATCH 10/47: spapr: move spapr_populate_pa_features()...
> Checking PATCH 11/47: spapr: Enable ISA 3.0 MMU mode selection via CAS...
> Checking PATCH 12/47: spapr: Workaround for broken radix guests...
> Checking PATCH 13/47: target-ppc/kvm: Enable in-kernel TCE acceleration for multi-tce...
> Checking PATCH 14/47: spapr_pci: Warn when RAM page size is not enabled in IOMMU page mask...
> Checking PATCH 15/47: spapr_pci: Removed unused include...
> Checking PATCH 16/47: target/ppc: Add ibm, processor-radix-AP-encodings for TCG...
> Checking PATCH 17/47: ppc/xics: introduce an 'intc' backlink under PowerPCCPU...
> Checking PATCH 18/47: spapr: move the IRQ server number mapping under the machine...
> Checking PATCH 19/47: spapr: allocate the ICPState object from under sPAPRCPUCore...
> Checking PATCH 20/47: ppc/xics: add a realize() handler to ICPStateClass...
> Checking PATCH 21/47: ppc/pnv: add a PnvICPState object...
> Checking PATCH 22/47: ppc/pnv: extend the machine with a XICSFabric interface...
> Checking PATCH 23/47: ppc/pnv: extend the machine with a InterruptStatsProvider interface...
> Checking PATCH 24/47: ppc/pnv: create the ICP object under PnvCore...
> Checking PATCH 25/47: ppc/pnv: add a helper to calculate MMIO addresses registers...
> Checking PATCH 26/47: ppc/pnv: add memory regions for the ICP registers...
> Checking PATCH 27/47: ppc/pnv: Add cut down PSI bridge model and hookup external interrupt...
> Checking PATCH 28/47: ppc/pnv: Add OCC model stub with interrupt support...
> Checking PATCH 29/47: ppc: add IPMI support...
> Checking PATCH 30/47: ipmi: use a file to load SDRs...
> Checking PATCH 31/47: ipmi: provide support for FRUs...
> Checking PATCH 32/47: ipmi: introduce an ipmi_bmc_sdr_find() API...
> Checking PATCH 33/47: ipmi: introduce an ipmi_bmc_gen_event() API...
> Checking PATCH 34/47: target/ppc: Fix size of struct PPCElfPrstatus...
> Checking PATCH 35/47: spapr: remove the 'nr_servers' field from the machine...
> Checking PATCH 36/47: ppc/pnv: Add support for POWER8+ LPC Controller...
> Checking PATCH 37/47: ppc/pnv: enable only one LPC bus...
> Checking PATCH 38/47: ppc/pnv: scan ISA bus to populate device tree...
> Checking PATCH 39/47: ppc/pnv: populate device tree for RTC devices...
> Checking PATCH 40/47: ppc/pnv: populate device tree for serial devices...
> Checking PATCH 41/47: ppc/pnv: populate device tree for IPMI BT devices...
> Checking PATCH 42/47: ppc/pnv: add initial IPMI sensors for the BMC simulator...
> Checking PATCH 43/47: ppc/pnv: generate an OEM SEL event on shutdown...
> Checking PATCH 44/47: spapr-cpu-core: Release ICPState object during CPU unrealization...
> Checking PATCH 45/47: target/ppc: Flush TLB on write to PIDR...
> Checking PATCH 46/47: e500, book3s: mfspr 259: Register mapped/aliased SPRG3 user read...
> ERROR: space prohibited between function name and open parenthesis '('
> #51: FILE: target/ppc/translate_init.c:1643:
> +static void gen_spr_usprg3 (CPUPPCState *env)
> 
> total: 1 errors, 0 warnings, 28 lines checked

This style error is a case of matching the surrounding style instead
of the official style.  In any case I fixed this instance - along with
the rest of that particular style violation - in 47/47.

> 
> Your patch has style problems, please review.  If any of these errors
> are false positives report them to the maintainer, see
> CHECKPATCH in MAINTAINERS.
> 
> Checking PATCH 47/47: target/ppc: Style fixes...
> === OUTPUT END ===
> 
> Test command exited with code: 1
> 
> 
> ---
> Email generated automatically by Patchew [http://patchew.org/].
> Please send your feedback to patchew-devel@freelists.org

-- 
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: 819 bytes --]

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

* Re: [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424
  2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
                   ` (47 preceding siblings ...)
  2017-04-24  3:08 ` [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 no-reply
@ 2017-04-24 13:12 ` Peter Maydell
  2017-04-24 14:38   ` Cédric Le Goater
  2017-04-26  2:38   ` David Gibson
  48 siblings, 2 replies; 61+ messages in thread
From: Peter Maydell @ 2017-04-24 13:12 UTC (permalink / raw)
  To: David Gibson
  Cc: Alexander Graf, Michael Roth, Alexey Kardashevskiy,
	QEMU Developers, qemu-ppc, Cédric Le Goater

On 24 April 2017 at 02:58, David Gibson <david@gibson.dropbear.id.au> wrote:
> The following changes since commit 32c7e0ab755745e961f1772e95cac381cc68769d:
>
>   Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20170421' into staging (2017-04-21 15:59:27 +0100)
>
> are available in the git repository at:
>
>   git://github.com/dgibson/qemu.git tags/ppc-for-2.10-20170424
>
> for you to fetch changes up to 4cab48942a1c5353f0a314fab1aa85a5f0a61461:
>
>   target/ppc: Style fixes (2017-04-24 08:56:19 +1000)
>
> ----------------------------------------------------------------
> ppc patch queue 2017-04-24
>
> Here's my first pull request for qemu-2.10, consisting of assorted
> patches which have accumulated while qemu-2.9 stabilized.  Highlights
> are:
>     * Rework / cleanup of the XICS interrupt controller
>     * Substantial improvement to the 'powernv' machine type
>         - Includes an MMIO XICS version
>     * POWER9 support improvements
>         - POWER9 guests with KVM
>         - Partial support for POWER9 guests with TCG
>     * IOMMU and VFIO improvements
>     * Assorted minor changes
>
> There are several IPMI patches here that aren't usually in my area of
> maintenance, but there isn't a regular maintainer and these patches
> are for the benefit of the powernv machine type.


Hi -- I'm afraid this pullreq generates a new clang sanitizer warning
running 'make check':

/home/petmay01/linaro/qemu-for-merges/hw/core/loader.c:67:15: runtime
error: null pointer passed as argument 1, which is declared to never
be null

It looks like we try to call open(NULL, ...).

Affected tests are in check-qtest-i386:
tests/bios-tables-test
  /i386/acpi/piix4/ipmi
  /i386/acpi/q35/ipmi
tests/ipmi-kcs-test

Here's a backtrace:

#0  0x00005555567e6197 in get_image_size (filename=0x0) at
/home/petmay01/linaro/qemu-for-merges/hw/core/loader.c:67
#1  0x00005555568ead3c in ipmi_fru_init (fru=0x55555ab98588)
    at /home/petmay01/linaro/qemu-for-merges/hw/ipmi/ipmi_bmc_sim.c:1902
#2  0x00005555568e91ac in ipmi_sim_realize (dev=<optimised out>,
errp=<optimised out>)
    at /home/petmay01/linaro/qemu-for-merges/hw/ipmi/ipmi_bmc_sim.c:1943
#3  0x00005555567d6df6 in device_set_realized (obj=<optimised out>,
value=<optimised out>, errp=<optimised out>)
    at /home/petmay01/linaro/qemu-for-merges/hw/core/qdev.c:905
#4  0x0000555556d7b1f8 in property_set_bool (obj=0x55555ab93c90,
v=<optimised out>, name=<optimised out>, opaque=<optimised out>,
errp=0x7fffffffde90) at
/home/petmay01/linaro/qemu-for-merges/qom/object.c:1860
#5  0x0000555556d7dd1d in object_property_set_qobject (obj=0x0,
value=<optimised out>, name=0x58fdf801 <error: Cannot access memory at
address 0x58fdf801>, errp=0x1) at
/home/petmay01/linaro/qemu-for-merges/qom/qom-qobject.c:27
#6  0x0000555556d78cb2 in object_property_set_bool
(obj=0x55555ab93c90, value=<optimised out>, name=0x55555710e087
"realized", errp=0x7fffffffde90) at
/home/petmay01/linaro/qemu-for-merges/qom/object.c:1163
#7  0x000055555661d80d in qdev_device_add (opts=<optimised out>,
errp=<optimised out>)
    at /home/petmay01/linaro/qemu-for-merges/qdev-monitor.c:630
#8  0x00005555566374cb in device_init_func (opaque=<optimised out>,
opts=0x0, errp=0x58fdf801)
    at /home/petmay01/linaro/qemu-for-merges/vl.c:2305
#9  0x000055555701dc81 in qemu_opts_foreach (list=<optimised out>,
func=<optimised out>, opaque=<optimised out>, errp=<optimised out>) at
/home/petmay01/linaro/qemu-for-merges/util/qemu-option.c:1114
#10 0x0000555556633289 in main (argc=<optimised out>, argv=<optimised
out>, envp=<optimised out>)
    at /home/petmay01/linaro/qemu-for-merges/vl.c:4583

It looks like the device doesn't handle not having its fru.filename
property set -- this should either cause an error in realize or the
rest of the device code should handle NULL.

thanks
-- PMM

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

* Re: [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424
  2017-04-24 13:12 ` [Qemu-devel] " Peter Maydell
@ 2017-04-24 14:38   ` Cédric Le Goater
  2017-04-25  6:55     ` Cédric Le Goater
  2017-04-26  2:38   ` David Gibson
  1 sibling, 1 reply; 61+ messages in thread
From: Cédric Le Goater @ 2017-04-24 14:38 UTC (permalink / raw)
  To: Peter Maydell, David Gibson
  Cc: Alexander Graf, Michael Roth, Alexey Kardashevskiy,
	QEMU Developers, qemu-ppc

On 04/24/2017 03:12 PM, Peter Maydell wrote:
> On 24 April 2017 at 02:58, David Gibson <david@gibson.dropbear.id.au> wrote:
>> The following changes since commit 32c7e0ab755745e961f1772e95cac381cc68769d:
>>
>>   Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20170421' into staging (2017-04-21 15:59:27 +0100)
>>
>> are available in the git repository at:
>>
>>   git://github.com/dgibson/qemu.git tags/ppc-for-2.10-20170424
>>
>> for you to fetch changes up to 4cab48942a1c5353f0a314fab1aa85a5f0a61461:
>>
>>   target/ppc: Style fixes (2017-04-24 08:56:19 +1000)
>>
>> ----------------------------------------------------------------
>> ppc patch queue 2017-04-24
>>
>> Here's my first pull request for qemu-2.10, consisting of assorted
>> patches which have accumulated while qemu-2.9 stabilized.  Highlights
>> are:
>>     * Rework / cleanup of the XICS interrupt controller
>>     * Substantial improvement to the 'powernv' machine type
>>         - Includes an MMIO XICS version
>>     * POWER9 support improvements
>>         - POWER9 guests with KVM
>>         - Partial support for POWER9 guests with TCG
>>     * IOMMU and VFIO improvements
>>     * Assorted minor changes
>>
>> There are several IPMI patches here that aren't usually in my area of
>> maintenance, but there isn't a regular maintainer and these patches
>> are for the benefit of the powernv machine type.
> 
> 
> Hi -- I'm afraid this pullreq generates a new clang sanitizer warning
> running 'make check':
> 
> /home/petmay01/linaro/qemu-for-merges/hw/core/loader.c:67:15: runtime
> error: null pointer passed as argument 1, which is declared to never
> be null
> 
> It looks like we try to call open(NULL, ...).
> 
> Affected tests are in check-qtest-i386:
> tests/bios-tables-test
>   /i386/acpi/piix4/ipmi
>   /i386/acpi/q35/ipmi
> tests/ipmi-kcs-test
> 
> Here's a backtrace:
> 
> #0  0x00005555567e6197 in get_image_size (filename=0x0) at
> /home/petmay01/linaro/qemu-for-merges/hw/core/loader.c:67
> #1  0x00005555568ead3c in ipmi_fru_init (fru=0x55555ab98588)
>     at /home/petmay01/linaro/qemu-for-merges/hw/ipmi/ipmi_bmc_sim.c:1902
> #2  0x00005555568e91ac in ipmi_sim_realize (dev=<optimised out>,
> errp=<optimised out>)
>     at /home/petmay01/linaro/qemu-for-merges/hw/ipmi/ipmi_bmc_sim.c:1943
> #3  0x00005555567d6df6 in device_set_realized (obj=<optimised out>,
> value=<optimised out>, errp=<optimised out>)
>     at /home/petmay01/linaro/qemu-for-merges/hw/core/qdev.c:905
> #4  0x0000555556d7b1f8 in property_set_bool (obj=0x55555ab93c90,
> v=<optimised out>, name=<optimised out>, opaque=<optimised out>,
> errp=0x7fffffffde90) at
> /home/petmay01/linaro/qemu-for-merges/qom/object.c:1860
> #5  0x0000555556d7dd1d in object_property_set_qobject (obj=0x0,
> value=<optimised out>, name=0x58fdf801 <error: Cannot access memory at
> address 0x58fdf801>, errp=0x1) at
> /home/petmay01/linaro/qemu-for-merges/qom/qom-qobject.c:27
> #6  0x0000555556d78cb2 in object_property_set_bool
> (obj=0x55555ab93c90, value=<optimised out>, name=0x55555710e087
> "realized", errp=0x7fffffffde90) at
> /home/petmay01/linaro/qemu-for-merges/qom/object.c:1163
> #7  0x000055555661d80d in qdev_device_add (opts=<optimised out>,
> errp=<optimised out>)
>     at /home/petmay01/linaro/qemu-for-merges/qdev-monitor.c:630
> #8  0x00005555566374cb in device_init_func (opaque=<optimised out>,
> opts=0x0, errp=0x58fdf801)
>     at /home/petmay01/linaro/qemu-for-merges/vl.c:2305
> #9  0x000055555701dc81 in qemu_opts_foreach (list=<optimised out>,
> func=<optimised out>, opaque=<optimised out>, errp=<optimised out>) at
> /home/petmay01/linaro/qemu-for-merges/util/qemu-option.c:1114
> #10 0x0000555556633289 in main (argc=<optimised out>, argv=<optimised
> out>, envp=<optimised out>)
>     at /home/petmay01/linaro/qemu-for-merges/vl.c:4583
> 
> It looks like the device doesn't handle not having its fru.filename
> property set -- this should either cause an error in realize or the
> rest of the device code should handle NULL.

I missed that one beacause the IPMI tests are not run on ppc64. I will 
work on a fix and include the IPMI tests under ppc64 also.

Thanks, 

C.

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

* Re: [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424
  2017-04-24 14:38   ` Cédric Le Goater
@ 2017-04-25  6:55     ` Cédric Le Goater
  0 siblings, 0 replies; 61+ messages in thread
From: Cédric Le Goater @ 2017-04-25  6:55 UTC (permalink / raw)
  To: Peter Maydell, David Gibson
  Cc: Alexander Graf, Michael Roth, Alexey Kardashevskiy,
	QEMU Developers, qemu-ppc

On 04/24/2017 04:38 PM, Cédric Le Goater wrote:
> On 04/24/2017 03:12 PM, Peter Maydell wrote:
>> On 24 April 2017 at 02:58, David Gibson <david@gibson.dropbear.id.au> wrote:
>>> The following changes since commit 32c7e0ab755745e961f1772e95cac381cc68769d:
>>>
>>>   Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20170421' into staging (2017-04-21 15:59:27 +0100)
>>>
>>> are available in the git repository at:
>>>
>>>   git://github.com/dgibson/qemu.git tags/ppc-for-2.10-20170424
>>>
>>> for you to fetch changes up to 4cab48942a1c5353f0a314fab1aa85a5f0a61461:
>>>
>>>   target/ppc: Style fixes (2017-04-24 08:56:19 +1000)
>>>
>>> ----------------------------------------------------------------
>>> ppc patch queue 2017-04-24
>>>
>>> Here's my first pull request for qemu-2.10, consisting of assorted
>>> patches which have accumulated while qemu-2.9 stabilized.  Highlights
>>> are:
>>>     * Rework / cleanup of the XICS interrupt controller
>>>     * Substantial improvement to the 'powernv' machine type
>>>         - Includes an MMIO XICS version
>>>     * POWER9 support improvements
>>>         - POWER9 guests with KVM
>>>         - Partial support for POWER9 guests with TCG
>>>     * IOMMU and VFIO improvements
>>>     * Assorted minor changes
>>>
>>> There are several IPMI patches here that aren't usually in my area of
>>> maintenance, but there isn't a regular maintainer and these patches
>>> are for the benefit of the powernv machine type.
>>
>>
>> Hi -- I'm afraid this pullreq generates a new clang sanitizer warning
>> running 'make check':
>>
>> /home/petmay01/linaro/qemu-for-merges/hw/core/loader.c:67:15: runtime
>> error: null pointer passed as argument 1, which is declared to never
>> be null
>>
>> It looks like we try to call open(NULL, ...).
>>
>> Affected tests are in check-qtest-i386:
>> tests/bios-tables-test
>>   /i386/acpi/piix4/ipmi
>>   /i386/acpi/q35/ipmi
>> tests/ipmi-kcs-test
>>
>> Here's a backtrace:
>>
>> #0  0x00005555567e6197 in get_image_size (filename=0x0) at
>> /home/petmay01/linaro/qemu-for-merges/hw/core/loader.c:67
>> #1  0x00005555568ead3c in ipmi_fru_init (fru=0x55555ab98588)
>>     at /home/petmay01/linaro/qemu-for-merges/hw/ipmi/ipmi_bmc_sim.c:1902
>> #2  0x00005555568e91ac in ipmi_sim_realize (dev=<optimised out>,
>> errp=<optimised out>)
>>     at /home/petmay01/linaro/qemu-for-merges/hw/ipmi/ipmi_bmc_sim.c:1943
>> #3  0x00005555567d6df6 in device_set_realized (obj=<optimised out>,
>> value=<optimised out>, errp=<optimised out>)
>>     at /home/petmay01/linaro/qemu-for-merges/hw/core/qdev.c:905
>> #4  0x0000555556d7b1f8 in property_set_bool (obj=0x55555ab93c90,
>> v=<optimised out>, name=<optimised out>, opaque=<optimised out>,
>> errp=0x7fffffffde90) at
>> /home/petmay01/linaro/qemu-for-merges/qom/object.c:1860
>> #5  0x0000555556d7dd1d in object_property_set_qobject (obj=0x0,
>> value=<optimised out>, name=0x58fdf801 <error: Cannot access memory at
>> address 0x58fdf801>, errp=0x1) at
>> /home/petmay01/linaro/qemu-for-merges/qom/qom-qobject.c:27
>> #6  0x0000555556d78cb2 in object_property_set_bool
>> (obj=0x55555ab93c90, value=<optimised out>, name=0x55555710e087
>> "realized", errp=0x7fffffffde90) at
>> /home/petmay01/linaro/qemu-for-merges/qom/object.c:1163
>> #7  0x000055555661d80d in qdev_device_add (opts=<optimised out>,
>> errp=<optimised out>)
>>     at /home/petmay01/linaro/qemu-for-merges/qdev-monitor.c:630
>> #8  0x00005555566374cb in device_init_func (opaque=<optimised out>,
>> opts=0x0, errp=0x58fdf801)
>>     at /home/petmay01/linaro/qemu-for-merges/vl.c:2305
>> #9  0x000055555701dc81 in qemu_opts_foreach (list=<optimised out>,
>> func=<optimised out>, opaque=<optimised out>, errp=<optimised out>) at
>> /home/petmay01/linaro/qemu-for-merges/util/qemu-option.c:1114
>> #10 0x0000555556633289 in main (argc=<optimised out>, argv=<optimised
>> out>, envp=<optimised out>)
>>     at /home/petmay01/linaro/qemu-for-merges/vl.c:4583
>>
>> It looks like the device doesn't handle not having its fru.filename
>> property set -- this should either cause an error in realize or the
>> rest of the device code should handle NULL.
> 
> I missed that one beacause the IPMI tests are not run on ppc64. I will 
> work on a fix and include the IPMI tests under ppc64 also.

I could not reproduce the error with the clang environment I am 
using (f24). Nevertheless, I have sent a couple of patches which 
should fix the problem.

Thanks,

C.  

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

* Re: [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424
  2017-04-24 13:12 ` [Qemu-devel] " Peter Maydell
  2017-04-24 14:38   ` Cédric Le Goater
@ 2017-04-26  2:38   ` David Gibson
  2017-04-26  6:11     ` Cédric Le Goater
  1 sibling, 1 reply; 61+ messages in thread
From: David Gibson @ 2017-04-26  2:38 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Alexander Graf, Michael Roth, Alexey Kardashevskiy,
	QEMU Developers, qemu-ppc, Cédric Le Goater

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

On Mon, Apr 24, 2017 at 02:12:19PM +0100, Peter Maydell wrote:
> On 24 April 2017 at 02:58, David Gibson <david@gibson.dropbear.id.au> wrote:
> > The following changes since commit 32c7e0ab755745e961f1772e95cac381cc68769d:
> >
> >   Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20170421' into staging (2017-04-21 15:59:27 +0100)
> >
> > are available in the git repository at:
> >
> >   git://github.com/dgibson/qemu.git tags/ppc-for-2.10-20170424
> >
> > for you to fetch changes up to 4cab48942a1c5353f0a314fab1aa85a5f0a61461:
> >
> >   target/ppc: Style fixes (2017-04-24 08:56:19 +1000)
> >
> > ----------------------------------------------------------------
> > ppc patch queue 2017-04-24
> >
> > Here's my first pull request for qemu-2.10, consisting of assorted
> > patches which have accumulated while qemu-2.9 stabilized.  Highlights
> > are:
> >     * Rework / cleanup of the XICS interrupt controller
> >     * Substantial improvement to the 'powernv' machine type
> >         - Includes an MMIO XICS version
> >     * POWER9 support improvements
> >         - POWER9 guests with KVM
> >         - Partial support for POWER9 guests with TCG
> >     * IOMMU and VFIO improvements
> >     * Assorted minor changes
> >
> > There are several IPMI patches here that aren't usually in my area of
> > maintenance, but there isn't a regular maintainer and these patches
> > are for the benefit of the powernv machine type.
> 
> 
> Hi -- I'm afraid this pullreq generates a new clang sanitizer warning
> running 'make check':

Drat.  What do I need to do to see these warnings?  Sounds like I
should add that to my pre-pull-request testing sequence.  Just
building with clang (on Fedora 25) and running make check doesn't seem
to be sufficient.

> /home/petmay01/linaro/qemu-for-merges/hw/core/loader.c:67:15: runtime
> error: null pointer passed as argument 1, which is declared to never
> be null
> 
> It looks like we try to call open(NULL, ...).
> 
> Affected tests are in check-qtest-i386:
> tests/bios-tables-test
>   /i386/acpi/piix4/ipmi
>   /i386/acpi/q35/ipmi
> tests/ipmi-kcs-test
> 
> Here's a backtrace:
> 
> #0  0x00005555567e6197 in get_image_size (filename=0x0) at
> /home/petmay01/linaro/qemu-for-merges/hw/core/loader.c:67
> #1  0x00005555568ead3c in ipmi_fru_init (fru=0x55555ab98588)
>     at /home/petmay01/linaro/qemu-for-merges/hw/ipmi/ipmi_bmc_sim.c:1902
> #2  0x00005555568e91ac in ipmi_sim_realize (dev=<optimised out>,
> errp=<optimised out>)
>     at /home/petmay01/linaro/qemu-for-merges/hw/ipmi/ipmi_bmc_sim.c:1943
> #3  0x00005555567d6df6 in device_set_realized (obj=<optimised out>,
> value=<optimised out>, errp=<optimised out>)
>     at /home/petmay01/linaro/qemu-for-merges/hw/core/qdev.c:905
> #4  0x0000555556d7b1f8 in property_set_bool (obj=0x55555ab93c90,
> v=<optimised out>, name=<optimised out>, opaque=<optimised out>,
> errp=0x7fffffffde90) at
> /home/petmay01/linaro/qemu-for-merges/qom/object.c:1860
> #5  0x0000555556d7dd1d in object_property_set_qobject (obj=0x0,
> value=<optimised out>, name=0x58fdf801 <error: Cannot access memory at
> address 0x58fdf801>, errp=0x1) at
> /home/petmay01/linaro/qemu-for-merges/qom/qom-qobject.c:27
> #6  0x0000555556d78cb2 in object_property_set_bool
> (obj=0x55555ab93c90, value=<optimised out>, name=0x55555710e087
> "realized", errp=0x7fffffffde90) at
> /home/petmay01/linaro/qemu-for-merges/qom/object.c:1163
> #7  0x000055555661d80d in qdev_device_add (opts=<optimised out>,
> errp=<optimised out>)
>     at /home/petmay01/linaro/qemu-for-merges/qdev-monitor.c:630
> #8  0x00005555566374cb in device_init_func (opaque=<optimised out>,
> opts=0x0, errp=0x58fdf801)
>     at /home/petmay01/linaro/qemu-for-merges/vl.c:2305
> #9  0x000055555701dc81 in qemu_opts_foreach (list=<optimised out>,
> func=<optimised out>, opaque=<optimised out>, errp=<optimised out>) at
> /home/petmay01/linaro/qemu-for-merges/util/qemu-option.c:1114
> #10 0x0000555556633289 in main (argc=<optimised out>, argv=<optimised
> out>, envp=<optimised out>)
>     at /home/petmay01/linaro/qemu-for-merges/vl.c:4583
> 
> It looks like the device doesn't handle not having its fru.filename
> property set -- this should either cause an error in realize or the
> rest of the device code should handle NULL.
> 
> thanks
> -- PMM
> 

-- 
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: 819 bytes --]

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

* Re: [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424
  2017-04-26  2:38   ` David Gibson
@ 2017-04-26  6:11     ` Cédric Le Goater
  2017-04-26 10:46       ` Peter Maydell
  0 siblings, 1 reply; 61+ messages in thread
From: Cédric Le Goater @ 2017-04-26  6:11 UTC (permalink / raw)
  To: David Gibson, Peter Maydell
  Cc: Alexander Graf, Michael Roth, Alexey Kardashevskiy,
	QEMU Developers, qemu-ppc

On 04/26/2017 04:38 AM, David Gibson wrote:
> On Mon, Apr 24, 2017 at 02:12:19PM +0100, Peter Maydell wrote:
>> On 24 April 2017 at 02:58, David Gibson <david@gibson.dropbear.id.au> wrote:
>>> The following changes since commit 32c7e0ab755745e961f1772e95cac381cc68769d:
>>>
>>>   Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20170421' into staging (2017-04-21 15:59:27 +0100)
>>>
>>> are available in the git repository at:
>>>
>>>   git://github.com/dgibson/qemu.git tags/ppc-for-2.10-20170424
>>>
>>> for you to fetch changes up to 4cab48942a1c5353f0a314fab1aa85a5f0a61461:
>>>
>>>   target/ppc: Style fixes (2017-04-24 08:56:19 +1000)
>>>
>>> ----------------------------------------------------------------
>>> ppc patch queue 2017-04-24
>>>
>>> Here's my first pull request for qemu-2.10, consisting of assorted
>>> patches which have accumulated while qemu-2.9 stabilized.  Highlights
>>> are:
>>>     * Rework / cleanup of the XICS interrupt controller
>>>     * Substantial improvement to the 'powernv' machine type
>>>         - Includes an MMIO XICS version
>>>     * POWER9 support improvements
>>>         - POWER9 guests with KVM
>>>         - Partial support for POWER9 guests with TCG
>>>     * IOMMU and VFIO improvements
>>>     * Assorted minor changes
>>>
>>> There are several IPMI patches here that aren't usually in my area of
>>> maintenance, but there isn't a regular maintainer and these patches
>>> are for the benefit of the powernv machine type.
>>
>>
>> Hi -- I'm afraid this pullreq generates a new clang sanitizer warning
>> running 'make check':
> 
> Drat.  What do I need to do to see these warnings?  Sounds like I
> should add that to my pre-pull-request testing sequence.  Just
> building with clang (on Fedora 25) and running make check doesn't seem
> to be sufficient.

yes. May be we could add this flag : 

	--extra-cflags=-fsanitize=undefined

to the travis builds using clang ? It is reporting a couple of errors on ppc64

target/ppc/translate.c:980:56: runtime error: left shift of negative value -32768
target/ppc/translate.c:983:56: runtime error: left shift of negative value -16
hw/usb/hcd-ohci.c:1122:9: runtime error: left shift of 15 by 28 places cannot be represented in type 'int'
hw/usb/hcd-ohci.c:1122:9: runtime error: left shift of 15 by 28 places cannot be represented in type 'int'
hw/usb/hcd-ohci.c:1179:12: runtime error: left shift of 15 by 28 places cannot be represented in type 'int'
target/ppc/translate.c:980:56: runtime error: left shift of negative value -32768
target/ppc/translate.c:983:56: runtime error: left shift of negative value -16
target/ppc/translate.c:983:56: runtime error: left shift of negative value -1
target/ppc/translate.c:980:56: runtime error: left shift of negative value -28672
target/ppc/translate.c:980:56: runtime error: left shift of negative value -28672
target/ppc/translate.c:980:56: runtime error: left shift of negative value -28672
target/ppc/translate.c:980:56: runtime error: left shift of negative value -28672
target/ppc/translate.c:983:56: runtime error: left shift of negative value -1
target/ppc/translate.c:980:56: runtime error: left shift of negative value -1
hw/usb/hcd-xhci.c:3005:19: runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
hw/usb/hcd-xhci.c:2417:29: runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
hw/usb/hcd-xhci.c:2420:29: runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
hw/usb/hcd-xhci.c:2447:38: runtime error: left shift of 31 by 27 places cannot be represented in type 'int'
hw/usb/hcd-xhci.c:2449:48: runtime error: left shift of 31 by 27 places cannot be represented in type 'int'
hw/usb/hcd-xhci.c:2450:62: runtime error: left shift of 31 by 27 places cannot be represented in type 'int'
/target/ppc/translate.c:980:56: runtime error: left shift of negative value -1
/target/ppc/mmu_helper.c:2599:38: runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
/target/ppc/mmu_helper.c:2599:53: runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
/target/ppc/translate.c:983:56: runtime error: left shift of negative value -240
/target/ppc/translate.c:980:56: runtime error: left shift of negative value -128
/target/ppc/translate.c:983:56: runtime error: left shift of negative value -32768
target/ppc/translate.c:983:56: runtime error: left shift of negative value -1
target/ppc/translate.c:980:56: runtime error: left shift of negative value -28672
target/ppc/translate.c:983:56: runtime error: left shift of negative value -1
target/ppc/translate.c:983:56: runtime error: left shift of negative value -1
target/ppc/translate.c:980:56: runtime error: left shift of negative value -13108
target/ppc/translate.c:983:56: runtime error: left shift of negative value -1
target/ppc/translate.c:980:56: runtime error: left shift of negative value -32768


Thanks,

C. 


>> /home/petmay01/linaro/qemu-for-merges/hw/core/loader.c:67:15: runtime
>> error: null pointer passed as argument 1, which is declared to never
>> be null
>>
>> It looks like we try to call open(NULL, ...).
>>
>> Affected tests are in check-qtest-i386:
>> tests/bios-tables-test
>>   /i386/acpi/piix4/ipmi
>>   /i386/acpi/q35/ipmi
>> tests/ipmi-kcs-test
>>
>> Here's a backtrace:
>>
>> #0  0x00005555567e6197 in get_image_size (filename=0x0) at
>> /home/petmay01/linaro/qemu-for-merges/hw/core/loader.c:67
>> #1  0x00005555568ead3c in ipmi_fru_init (fru=0x55555ab98588)
>>     at /home/petmay01/linaro/qemu-for-merges/hw/ipmi/ipmi_bmc_sim.c:1902
>> #2  0x00005555568e91ac in ipmi_sim_realize (dev=<optimised out>,
>> errp=<optimised out>)
>>     at /home/petmay01/linaro/qemu-for-merges/hw/ipmi/ipmi_bmc_sim.c:1943
>> #3  0x00005555567d6df6 in device_set_realized (obj=<optimised out>,
>> value=<optimised out>, errp=<optimised out>)
>>     at /home/petmay01/linaro/qemu-for-merges/hw/core/qdev.c:905
>> #4  0x0000555556d7b1f8 in property_set_bool (obj=0x55555ab93c90,
>> v=<optimised out>, name=<optimised out>, opaque=<optimised out>,
>> errp=0x7fffffffde90) at
>> /home/petmay01/linaro/qemu-for-merges/qom/object.c:1860
>> #5  0x0000555556d7dd1d in object_property_set_qobject (obj=0x0,
>> value=<optimised out>, name=0x58fdf801 <error: Cannot access memory at
>> address 0x58fdf801>, errp=0x1) at
>> /home/petmay01/linaro/qemu-for-merges/qom/qom-qobject.c:27
>> #6  0x0000555556d78cb2 in object_property_set_bool
>> (obj=0x55555ab93c90, value=<optimised out>, name=0x55555710e087
>> "realized", errp=0x7fffffffde90) at
>> /home/petmay01/linaro/qemu-for-merges/qom/object.c:1163
>> #7  0x000055555661d80d in qdev_device_add (opts=<optimised out>,
>> errp=<optimised out>)
>>     at /home/petmay01/linaro/qemu-for-merges/qdev-monitor.c:630
>> #8  0x00005555566374cb in device_init_func (opaque=<optimised out>,
>> opts=0x0, errp=0x58fdf801)
>>     at /home/petmay01/linaro/qemu-for-merges/vl.c:2305
>> #9  0x000055555701dc81 in qemu_opts_foreach (list=<optimised out>,
>> func=<optimised out>, opaque=<optimised out>, errp=<optimised out>) at
>> /home/petmay01/linaro/qemu-for-merges/util/qemu-option.c:1114
>> #10 0x0000555556633289 in main (argc=<optimised out>, argv=<optimised
>> out>, envp=<optimised out>)
>>     at /home/petmay01/linaro/qemu-for-merges/vl.c:4583
>>
>> It looks like the device doesn't handle not having its fru.filename
>> property set -- this should either cause an error in realize or the
>> rest of the device code should handle NULL.
>>
>> thanks
>> -- PMM
>>
> 

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

* Re: [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424
  2017-04-26  6:11     ` Cédric Le Goater
@ 2017-04-26 10:46       ` Peter Maydell
  2017-04-26 13:15         ` Peter Maydell
  0 siblings, 1 reply; 61+ messages in thread
From: Peter Maydell @ 2017-04-26 10:46 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: David Gibson, Alexander Graf, Michael Roth, Alexey Kardashevskiy,
	QEMU Developers, qemu-ppc

On 26 April 2017 at 07:11, Cédric Le Goater <clg@kaod.org> wrote:
> yes. May be we could add this flag :
>
>         --extra-cflags=-fsanitize=undefined
>
> to the travis builds using clang ? It is reporting a couple of errors on ppc64
>
> target/ppc/translate.c:980:56: runtime error: left shift of negative value -32768
> target/ppc/translate.c:983:56: runtime error: left shift of negative value -16
> hw/usb/hcd-ohci.c:1122:9: runtime error: left shift of 15 by 28 places cannot be represented in type 'int'
> hw/usb/hcd-ohci.c:1122:9: runtime error: left shift of 15 by 28 places cannot be represented in type 'int'
> hw/usb/hcd-ohci.c:1179:12: runtime error: left shift of 15 by 28 places cannot be represented in type 'int'

All the stuff about shifts is false positives, because the sanitizer
doesn't know that -fwrapv makes these operations defined behaviour.

Newer versions of clang I think get this correct, and less new
but not ancient clang has a flag that says "don't report that
particular set of shift errors". For my pullreq tests at the moment
I just use grep to filter them out:
 https://git.linaro.org/people/peter.maydell/misc-scripts.git/tree/greplogs
but as the TODO note says I should find out what the right ubsan
flag is to suppress them at source.

thanks
-- PMM

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

* Re: [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424
  2017-04-26 10:46       ` Peter Maydell
@ 2017-04-26 13:15         ` Peter Maydell
  2017-04-26 13:32           ` Cédric Le Goater
  0 siblings, 1 reply; 61+ messages in thread
From: Peter Maydell @ 2017-04-26 13:15 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: David Gibson, Alexander Graf, Michael Roth, Alexey Kardashevskiy,
	QEMU Developers, qemu-ppc

On 26 April 2017 at 11:46, Peter Maydell <peter.maydell@linaro.org> wrote:
> All the stuff about shifts is false positives, because the sanitizer
> doesn't know that -fwrapv makes these operations defined behaviour.
>
> Newer versions of clang I think get this correct, and less new
> but not ancient clang has a flag that says "don't report that
> particular set of shift errors".

I just looked into this, and I think the best set of configure options is:
'--cc=clang' '--cxx=clang++' '--extra-cflags=-fsanitize=undefined
-fno-sanitize=shift-base -Werror'

Works with clang-3.8.0 at least.

thanks
-- PMM

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

* Re: [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424
  2017-04-26 13:15         ` Peter Maydell
@ 2017-04-26 13:32           ` Cédric Le Goater
  2017-04-26 13:56             ` Peter Maydell
  0 siblings, 1 reply; 61+ messages in thread
From: Cédric Le Goater @ 2017-04-26 13:32 UTC (permalink / raw)
  To: Peter Maydell
  Cc: David Gibson, Alexander Graf, Michael Roth, Alexey Kardashevskiy,
	QEMU Developers, qemu-ppc

On 04/26/2017 03:15 PM, Peter Maydell wrote:
> On 26 April 2017 at 11:46, Peter Maydell <peter.maydell@linaro.org> wrote:
>> All the stuff about shifts is false positives, because the sanitizer
>> doesn't know that -fwrapv makes these operations defined behaviour.
>>
>> Newer versions of clang I think get this correct, and less new
>> but not ancient clang has a flag that says "don't report that
>> particular set of shift errors".
> 
> I just looked into this, and I think the best set of configure options is:
> '--cc=clang' '--cxx=clang++' '--extra-cflags=-fsanitize=undefined
> -fno-sanitize=shift-base -Werror'

Ah ! Too fast you are for me :) you beat me to it. 

> Works with clang-3.8.0 at least.

Yes. confirmed.

Thanks,

C. 

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

* Re: [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424
  2017-04-26 13:32           ` Cédric Le Goater
@ 2017-04-26 13:56             ` Peter Maydell
  0 siblings, 0 replies; 61+ messages in thread
From: Peter Maydell @ 2017-04-26 13:56 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: David Gibson, Alexander Graf, Michael Roth, Alexey Kardashevskiy,
	QEMU Developers, qemu-ppc

On 26 April 2017 at 14:32, Cédric Le Goater <clg@kaod.org> wrote:
> On 04/26/2017 03:15 PM, Peter Maydell wrote:
>> I just looked into this, and I think the best set of configure options is:
>> '--cc=clang' '--cxx=clang++' '--extra-cflags=-fsanitize=undefined
>> -fno-sanitize=shift-base -Werror'
>
> Ah ! Too fast you are for me :) you beat me to it.
>
>> Works with clang-3.8.0 at least.
>
> Yes. confirmed.

I've added info on how to use clang ubsan to
 http://wiki.qemu.org/Testing#clang_UBSan

thanks
-- PMM

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

* Re: [Qemu-devel] [PULL 41/47] ppc/pnv: populate device tree for IPMI BT devices
  2017-04-24  1:59 ` [Qemu-devel] [PULL 41/47] ppc/pnv: populate device tree for IPMI BT devices David Gibson
@ 2017-06-05 14:33   ` Peter Maydell
  2017-06-05 15:36     ` Cédric Le Goater
  0 siblings, 1 reply; 61+ messages in thread
From: Peter Maydell @ 2017-06-05 14:33 UTC (permalink / raw)
  To: David Gibson
  Cc: Alexander Graf, Michael Roth, Alexey Kardashevskiy,
	QEMU Developers, qemu-ppc, Cédric Le Goater

On 24 April 2017 at 02:59, David Gibson <david@gibson.dropbear.id.au> wrote:
> From: Cédric Le Goater <clg@kaod.org>
>
> When an ipmi-bt device [1] is defined on the ISA bus, we need to
> populate the device tree with the object properties. Such devices are
> created with the command line options :
>
>    -device ipmi-bmc-sim,id=bmc0 -device isa-ipmi-bt,bmc=bmc0,irq=10
>
> [1] https://lists.gnu.org/archive/html/qemu-devel/2015-11/msg03168.html
>
> Signed-off-by: Cédric Le Goater <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 dfa21e4..977e126 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -354,6 +354,39 @@ static void powernv_populate_serial(ISADevice *d, void *fdt, int lpc_off)
>      _FDT((fdt_setprop_string(fdt, node, "device_type", "serial")));
>  }
>
> +static void powernv_populate_ipmi_bt(ISADevice *d, void *fdt, int lpc_off)
> +{
> +    const char compatible[] = "bt\0ipmi-bt";
> +    uint32_t io_base;
> +    uint32_t io_regs[] = {
> +        cpu_to_be32(1),
> +        0, /* 'io_base' retrieved from the 'ioport' property of 'isa-ipmi-bt' */
> +        cpu_to_be32(3)
> +    };
> +    uint32_t irq;
> +    char *name;
> +    int node;
> +
> +    io_base = object_property_get_int(OBJECT(d), "ioport", &error_fatal);
> +    io_regs[1] = cpu_to_be32(io_base);
> +
> +    irq = object_property_get_int(OBJECT(d), "irq", &error_fatal);
> +
> +    name = g_strdup_printf("%s@i%x", qdev_fw_name(DEVICE(d)), io_base);
> +    node = fdt_add_subnode(fdt, lpc_off, name);
> +    _FDT(node);
> +    g_free(name);
> +
> +    fdt_setprop(fdt, node, "reg", io_regs, sizeof(io_regs));
> +    fdt_setprop(fdt, node, "compatible", compatible, sizeof(compatible));
> +
> +    /* Mark it as reserved to avoid Linux trying to claim it */
> +    _FDT((fdt_setprop_string(fdt, node, "status", "reserved")));
> +    _FDT((fdt_setprop_cell(fdt, node, "interrupts", irq)));
> +    _FDT((fdt_setprop_cell(fdt, node, "interrupt-parent",
> +                           fdt_get_phandle(fdt, lpc_off))));
> +}

Hi -- Coverity points out (CID 1374832) that the fdt_setprop() calls
in this function to set "reg" and "compatible" don't check whether the
function returns an error. Is there any reason why these calls
haven't been wrapped with the barf-on-errors _FDT() macro like the
other fdt_setprop* calls in the function?

thanks
-- PMM

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

* Re: [Qemu-devel] [PULL 41/47] ppc/pnv: populate device tree for IPMI BT devices
  2017-06-05 14:33   ` Peter Maydell
@ 2017-06-05 15:36     ` Cédric Le Goater
  0 siblings, 0 replies; 61+ messages in thread
From: Cédric Le Goater @ 2017-06-05 15:36 UTC (permalink / raw)
  To: Peter Maydell, David Gibson
  Cc: Alexander Graf, Michael Roth, Alexey Kardashevskiy,
	QEMU Developers, qemu-ppc

On 06/05/2017 04:33 PM, Peter Maydell wrote:
> On 24 April 2017 at 02:59, David Gibson <david@gibson.dropbear.id.au> wrote:
>> From: Cédric Le Goater <clg@kaod.org>
>>
>> When an ipmi-bt device [1] is defined on the ISA bus, we need to
>> populate the device tree with the object properties. Such devices are
>> created with the command line options :
>>
>>    -device ipmi-bmc-sim,id=bmc0 -device isa-ipmi-bt,bmc=bmc0,irq=10
>>
>> [1] https://lists.gnu.org/archive/html/qemu-devel/2015-11/msg03168.html
>>
>> Signed-off-by: Cédric Le Goater <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 dfa21e4..977e126 100644
>> --- a/hw/ppc/pnv.c
>> +++ b/hw/ppc/pnv.c
>> @@ -354,6 +354,39 @@ static void powernv_populate_serial(ISADevice *d, void *fdt, int lpc_off)
>>      _FDT((fdt_setprop_string(fdt, node, "device_type", "serial")));
>>  }
>>
>> +static void powernv_populate_ipmi_bt(ISADevice *d, void *fdt, int lpc_off)
>> +{
>> +    const char compatible[] = "bt\0ipmi-bt";
>> +    uint32_t io_base;
>> +    uint32_t io_regs[] = {
>> +        cpu_to_be32(1),
>> +        0, /* 'io_base' retrieved from the 'ioport' property of 'isa-ipmi-bt' */
>> +        cpu_to_be32(3)
>> +    };
>> +    uint32_t irq;
>> +    char *name;
>> +    int node;
>> +
>> +    io_base = object_property_get_int(OBJECT(d), "ioport", &error_fatal);
>> +    io_regs[1] = cpu_to_be32(io_base);
>> +
>> +    irq = object_property_get_int(OBJECT(d), "irq", &error_fatal);
>> +
>> +    name = g_strdup_printf("%s@i%x", qdev_fw_name(DEVICE(d)), io_base);
>> +    node = fdt_add_subnode(fdt, lpc_off, name);
>> +    _FDT(node);
>> +    g_free(name);
>> +
>> +    fdt_setprop(fdt, node, "reg", io_regs, sizeof(io_regs));
>> +    fdt_setprop(fdt, node, "compatible", compatible, sizeof(compatible));
>> +
>> +    /* Mark it as reserved to avoid Linux trying to claim it */
>> +    _FDT((fdt_setprop_string(fdt, node, "status", "reserved")));
>> +    _FDT((fdt_setprop_cell(fdt, node, "interrupts", irq)));
>> +    _FDT((fdt_setprop_cell(fdt, node, "interrupt-parent",
>> +                           fdt_get_phandle(fdt, lpc_off))));
>> +}
> 
> Hi -- Coverity points out (CID 1374832) that the fdt_setprop() calls
> in this function to set "reg" and "compatible" don't check whether the
> function returns an error. Is there any reason why these calls
> haven't been wrapped with the barf-on-errors _FDT() macro like the
> other fdt_setprop* calls in the function?

none. I will send a fix for it. 

Thanks,

C. 

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

end of thread, other threads:[~2017-06-05 15:36 UTC | newest]

Thread overview: 61+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-24  1:58 [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 David Gibson
2017-04-24  1:58 ` [Qemu-devel] [PULL 01/47] target/ppc: Improve accuracy of guest HTM availability on P8s David Gibson
2017-04-24  1:58 ` [Qemu-devel] [PULL 02/47] pseries: Add pseries-2.10 machine type David Gibson
2017-04-24  1:58 ` [Qemu-devel] [PULL 03/47] ppc/spapr: QOM'ify sPAPRRTCState David Gibson
2017-04-24  1:58 ` [Qemu-devel] [PULL 04/47] hw/ppc/pnv: Classify the "PowerNV Chip" devices as CPU devices David Gibson
2017-04-24  1:58 ` [Qemu-devel] [PULL 05/47] target-ppc: kvm: make use of KVM_CREATE_SPAPR_TCE_64 David Gibson
2017-04-24  1:58 ` [Qemu-devel] [PULL 06/47] spapr: Add ibm, processor-radix-AP-encodings to the device tree David Gibson
2017-04-24  1:58 ` [Qemu-devel] [PULL 07/47] target-ppc: support KVM_CAP_PPC_MMU_RADIX, KVM_CAP_PPC_MMU_HASH_V3 David Gibson
2017-04-24  1:58 ` [Qemu-devel] [PULL 08/47] target/ppc: Add new H-CALL shells for in memory table translation David Gibson
2017-04-24  1:58 ` [Qemu-devel] [PULL 09/47] target/ppc: Implement H_REGISTER_PROCESS_TABLE H_CALL David Gibson
2017-04-24  1:58 ` [Qemu-devel] [PULL 10/47] spapr: move spapr_populate_pa_features() David Gibson
2017-04-24  1:58 ` [Qemu-devel] [PULL 11/47] spapr: Enable ISA 3.0 MMU mode selection via CAS David Gibson
2017-04-24  1:58 ` [Qemu-devel] [PULL 12/47] spapr: Workaround for broken radix guests David Gibson
2017-04-24  1:58 ` [Qemu-devel] [PULL 13/47] target-ppc/kvm: Enable in-kernel TCE acceleration for multi-tce David Gibson
2017-04-24  1:58 ` [Qemu-devel] [PULL 14/47] spapr_pci: Warn when RAM page size is not enabled in IOMMU page mask David Gibson
2017-04-24  1:58 ` [Qemu-devel] [PULL 15/47] spapr_pci: Removed unused include David Gibson
2017-04-24  1:58 ` [Qemu-devel] [PULL 16/47] target/ppc: Add ibm, processor-radix-AP-encodings for TCG David Gibson
2017-04-24  1:58 ` [Qemu-devel] [PULL 17/47] ppc/xics: introduce an 'intc' backlink under PowerPCCPU David Gibson
2017-04-24  1:58 ` [Qemu-devel] [PULL 18/47] spapr: move the IRQ server number mapping under the machine David Gibson
2017-04-24  1:58 ` [Qemu-devel] [PULL 19/47] spapr: allocate the ICPState object from under sPAPRCPUCore David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 20/47] ppc/xics: add a realize() handler to ICPStateClass David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 21/47] ppc/pnv: add a PnvICPState object David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 22/47] ppc/pnv: extend the machine with a XICSFabric interface David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 23/47] ppc/pnv: extend the machine with a InterruptStatsProvider interface David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 24/47] ppc/pnv: create the ICP object under PnvCore David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 25/47] ppc/pnv: add a helper to calculate MMIO addresses registers David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 26/47] ppc/pnv: add memory regions for the ICP registers David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 27/47] ppc/pnv: Add cut down PSI bridge model and hookup external interrupt David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 28/47] ppc/pnv: Add OCC model stub with interrupt support David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 29/47] ppc: add IPMI support David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 30/47] ipmi: use a file to load SDRs David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 31/47] ipmi: provide support for FRUs David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 32/47] ipmi: introduce an ipmi_bmc_sdr_find() API David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 33/47] ipmi: introduce an ipmi_bmc_gen_event() API David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 34/47] target/ppc: Fix size of struct PPCElfPrstatus David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 35/47] spapr: remove the 'nr_servers' field from the machine David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 36/47] ppc/pnv: Add support for POWER8+ LPC Controller David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 37/47] ppc/pnv: enable only one LPC bus David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 38/47] ppc/pnv: scan ISA bus to populate device tree David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 39/47] ppc/pnv: populate device tree for RTC devices David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 40/47] ppc/pnv: populate device tree for serial devices David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 41/47] ppc/pnv: populate device tree for IPMI BT devices David Gibson
2017-06-05 14:33   ` Peter Maydell
2017-06-05 15:36     ` Cédric Le Goater
2017-04-24  1:59 ` [Qemu-devel] [PULL 42/47] ppc/pnv: add initial IPMI sensors for the BMC simulator David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 43/47] ppc/pnv: generate an OEM SEL event on shutdown David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 44/47] spapr-cpu-core: Release ICPState object during CPU unrealization David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 45/47] target/ppc: Flush TLB on write to PIDR David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 46/47] e500, book3s: mfspr 259: Register mapped/aliased SPRG3 user read David Gibson
2017-04-24  1:59 ` [Qemu-devel] [PULL 47/47] target/ppc: Style fixes David Gibson
2017-04-24  3:08 ` [Qemu-devel] [PULL 00/47] ppc-for-2.10 queue 20170424 no-reply
2017-04-24  4:25   ` [Qemu-devel] [Qemu-ppc] " David Gibson
2017-04-24 13:12 ` [Qemu-devel] " Peter Maydell
2017-04-24 14:38   ` Cédric Le Goater
2017-04-25  6:55     ` Cédric Le Goater
2017-04-26  2:38   ` David Gibson
2017-04-26  6:11     ` Cédric Le Goater
2017-04-26 10:46       ` Peter Maydell
2017-04-26 13:15         ` Peter Maydell
2017-04-26 13:32           ` Cédric Le Goater
2017-04-26 13:56             ` 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.