Re: [Qemu-devel] [PATCH v2 09/15] ppc/pnv: add a OCC model for POWER9

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

Applied, thanks.

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

[Qemu-devel] [PATCH v2 09/15] ppc/pnv: add a OCC model for POWER9

2019-03-07 Thread Cédric Le Goater
The OCC on POWER9 is very similar to the one found on POWER8. Provide
the same routines with P9 values for the registers and IRQ number.

Signed-off-by: Cédric Le Goater 
---

 Changes in v2 :

 - made use of the new class attributes for POWER9

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

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