Re: [Qemu-devel] [PATCH v4 18/20] ppc/pnv: Add OCC model stub with interrupt support

2016-10-14 Thread David Gibson
On Mon, Oct 03, 2016 at 09:24:54AM +0200, Cédric Le Goater wrote:
> From: Benjamin Herrenschmidt 
> 
> 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 
> [clg: - updated for qemu-2.7
>   - changed the XSCOM interface to fit new model
>   - QOMified the model ]
> Signed-off-by: Cédric Le Goater 

Reviewed-by: David Gibson 

> ---
>  hw/ppc/Makefile.objs   |   2 +-
>  hw/ppc/pnv.c   |  11 
>  hw/ppc/pnv_occ.c   | 135 
> +
>  include/hw/ppc/pnv.h   |   2 +
>  include/hw/ppc/pnv_occ.h   |  38 +
>  include/hw/ppc/pnv_xscom.h |   3 +
>  6 files changed, 190 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 4feb15b360c8..35b11cf887d5 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
>  # 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 b17e205c74db..e805e97d4d87 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -651,6 +651,11 @@ static void pnv_chip_init(Object *obj)
>  
>  object_initialize(>psi, sizeof(chip->psi), TYPE_PNV_PSI);
>  object_property_add_child(obj, "psi", OBJECT(>psi), NULL);
> +
> +object_initialize(>occ, sizeof(chip->occ), TYPE_PNV_OCC);
> +object_property_add_child(obj, "occ", OBJECT(>occ), NULL);
> +object_property_add_const_link(OBJECT(>occ), "psi",
> +   OBJECT(>psi), _abort);
>  }
>  
>  static void pnv_chip_realize(DeviceState *dev, Error **errp)
> @@ -740,6 +745,12 @@ static void pnv_chip_realize(DeviceState *dev, Error 
> **errp)
>   _fatal);
>  memory_region_add_subregion(>xscom, PNV_XSCOM_LPC_BASE << 3,
>  >lpc.xscom_regs);
> +
> +/* Create the simplified OCC model */
> +object_property_set_bool(OBJECT(>occ), true, "realized",
> + _fatal);
> +memory_region_add_subregion(>xscom, PNV_XSCOM_OCC_BASE << 3,
> +>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 ..250517cca0ef
> --- /dev/null
> +++ b/hw/ppc/pnv_occ.c
> @@ -0,0 +1,135 @@
> +/*
> + * QEMU PowerNV Emulation of a few OCC related registers
> + *
> + * Copyright (c) 2016, 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 .
> + */
> +
> +#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_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 &= 0xull;
> +
> +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;
> +

[Qemu-devel] [PATCH v4 18/20] ppc/pnv: Add OCC model stub with interrupt support

2016-10-03 Thread Cédric Le Goater
From: Benjamin Herrenschmidt 

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 
[clg: - updated for qemu-2.7
  - changed the XSCOM interface to fit new model
  - QOMified the model ]
Signed-off-by: Cédric Le Goater 
---
 hw/ppc/Makefile.objs   |   2 +-
 hw/ppc/pnv.c   |  11 
 hw/ppc/pnv_occ.c   | 135 +
 include/hw/ppc/pnv.h   |   2 +
 include/hw/ppc/pnv_occ.h   |  38 +
 include/hw/ppc/pnv_xscom.h |   3 +
 6 files changed, 190 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 4feb15b360c8..35b11cf887d5 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
 # 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 b17e205c74db..e805e97d4d87 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -651,6 +651,11 @@ static void pnv_chip_init(Object *obj)
 
 object_initialize(>psi, sizeof(chip->psi), TYPE_PNV_PSI);
 object_property_add_child(obj, "psi", OBJECT(>psi), NULL);
+
+object_initialize(>occ, sizeof(chip->occ), TYPE_PNV_OCC);
+object_property_add_child(obj, "occ", OBJECT(>occ), NULL);
+object_property_add_const_link(OBJECT(>occ), "psi",
+   OBJECT(>psi), _abort);
 }
 
 static void pnv_chip_realize(DeviceState *dev, Error **errp)
@@ -740,6 +745,12 @@ static void pnv_chip_realize(DeviceState *dev, Error 
**errp)
  _fatal);
 memory_region_add_subregion(>xscom, PNV_XSCOM_LPC_BASE << 3,
 >lpc.xscom_regs);
+
+/* Create the simplified OCC model */
+object_property_set_bool(OBJECT(>occ), true, "realized",
+ _fatal);
+memory_region_add_subregion(>xscom, PNV_XSCOM_OCC_BASE << 3,
+>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 ..250517cca0ef
--- /dev/null
+++ b/hw/ppc/pnv_occ.c
@@ -0,0 +1,135 @@
+/*
+ * QEMU PowerNV Emulation of a few OCC related registers
+ *
+ * Copyright (c) 2016, 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 .
+ */
+
+#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_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 &= 0xull;
+
+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,