Re: [Qemu-devel] [PATCH v2 08/15] ppc/pnv: add a OCC model class

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

Applied, thanks.

> ---
> 
>  Changes in v2:
> 
>  - new attributes to define XSCOM operations per CPU family and a PSI
>IRQ number.
> 
>  include/hw/ppc/pnv_occ.h | 15 +++
>  hw/ppc/pnv.c |  2 +-
>  hw/ppc/pnv_occ.c | 55 +++-
>  3 files changed, 54 insertions(+), 18 deletions(-)
> 
> diff --git a/include/hw/ppc/pnv_occ.h b/include/hw/ppc/pnv_occ.h
> index 82f299dc76ff..dab5a05f8e99 100644
> --- a/include/hw/ppc/pnv_occ.h
> +++ b/include/hw/ppc/pnv_occ.h
> @@ -23,6 +23,8 @@
>  
>  #define TYPE_PNV_OCC "pnv-occ"
>  #define PNV_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV_OCC)
> +#define TYPE_PNV8_OCC TYPE_PNV_OCC "-POWER8"
> +#define PNV8_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV8_OCC)
>  
>  typedef struct PnvOCC {
>  DeviceState xd;
> @@ -35,4 +37,17 @@ typedef struct PnvOCC {
>  MemoryRegion xscom_regs;
>  } PnvOCC;
>  
> +#define PNV_OCC_CLASS(klass) \
> + OBJECT_CLASS_CHECK(PnvOCCClass, (klass), TYPE_PNV_OCC)
> +#define PNV_OCC_GET_CLASS(obj) \
> + OBJECT_GET_CLASS(PnvOCCClass, (obj), TYPE_PNV_OCC)
> +
> +typedef struct PnvOCCClass {
> +DeviceClass parent_class;
> +
> +int xscom_size;
> +const MemoryRegionOps *xscom_ops;
> +int psi_irq;
> +} PnvOCCClass;
> +
>  #endif /* _PPC_PNV_OCC_H */
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index 918fae057b5c..6ae9ce679505 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -790,7 +790,7 @@ static void pnv_chip_power8_instance_init(Object *obj)
> OBJECT(>psi), _abort);
>  
>  object_initialize_child(obj, "occ",  >occ, sizeof(chip8->occ),
> -TYPE_PNV_OCC, _abort, NULL);
> +TYPE_PNV8_OCC, _abort, NULL);
>  object_property_add_const_link(OBJECT(>occ), "psi",
> OBJECT(>psi), _abort);
>  }
> diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c
> index 04880f26d612..ea725647c988 100644
> --- a/hw/ppc/pnv_occ.c
> +++ b/hw/ppc/pnv_occ.c
> @@ -34,15 +34,17 @@
>  static void pnv_occ_set_misc(PnvOCC *occ, uint64_t val)
>  {
>  bool irq_state;
> +PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
>  
>  val &= 0xull;
>  
>  occ->occmisc = val;
>  irq_state = !!(val >> 63);
> -pnv_psi_irq_set(occ->psi, PSIHB_IRQ_OCC, irq_state);
> +pnv_psi_irq_set(occ->psi, poc->psi_irq, irq_state);
>  }
>  
> -static uint64_t pnv_occ_xscom_read(void *opaque, hwaddr addr, unsigned size)
> +static uint64_t pnv_occ_power8_xscom_read(void *opaque, hwaddr addr,
> +  unsigned size)
>  {
>  PnvOCC *occ = PNV_OCC(opaque);
>  uint32_t offset = addr >> 3;
> @@ -54,13 +56,13 @@ static uint64_t pnv_occ_xscom_read(void *opaque, hwaddr 
> addr, unsigned size)
>  break;
>  default:
>  qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
> -  HWADDR_PRIx "\n", addr);
> +  HWADDR_PRIx "\n", addr >> 3);
>  }
>  return val;
>  }
>  
> -static void pnv_occ_xscom_write(void *opaque, hwaddr addr,
> -uint64_t val, unsigned size)
> +static void pnv_occ_power8_xscom_write(void *opaque, hwaddr addr,
> +   uint64_t val, unsigned size)
>  {
>  PnvOCC *occ = PNV_OCC(opaque);
>  uint32_t offset = addr >> 3;
> @@ -77,13 +79,13 @@ static void pnv_occ_xscom_write(void *opaque, hwaddr addr,
>  break;
>  default:
>  qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
> -  HWADDR_PRIx "\n", addr);
> +  HWADDR_PRIx "\n", addr >> 3);
>  }
>  }
>  
> -static const MemoryRegionOps pnv_occ_xscom_ops = {
> -.read = pnv_occ_xscom_read,
> -.write = pnv_occ_xscom_write,
> +static const MemoryRegionOps pnv_occ_power8_xscom_ops = {
> +.read = pnv_occ_power8_xscom_read,
> +.write = pnv_occ_power8_xscom_write,
>  .valid.min_access_size = 8,
>  .valid.max_access_size = 8,
>  .impl.min_access_size = 8,
> @@ -91,27 +93,42 @@ static const MemoryRegionOps pnv_occ_xscom_ops = {
>  .endianness = DEVICE_BIG_ENDIAN,
>  };
>  
> +static void pnv_occ_power8_class_init(ObjectClass *klass, void *data)
> +{
> +PnvOCCClass *poc = PNV_OCC_CLASS(klass);
> +
> +poc->xscom_size = PNV_XSCOM_OCC_SIZE;
> +poc->xscom_ops = _occ_power8_xscom_ops;
> +poc->psi_irq = PSIHB_IRQ_OCC;
> +}
> +
> +static const TypeInfo pnv_occ_power8_type_info = {
> +.name  = TYPE_PNV8_OCC,
> +.parent= TYPE_PNV_OCC,
> +.instance_size = sizeof(PnvOCC),
> +.class_init= 

[Qemu-devel] [PATCH v2 08/15] ppc/pnv: add a OCC model class

2019-03-07 Thread Cédric Le Goater
To ease the introduction of the OCC model for POWER9, provide a new
class attributes to define XSCOM operations per CPU family and a PSI
IRQ number.

Signed-off-by: Cédric Le Goater 
Reviewed-by: David Gibson 
---

 Changes in v2:

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

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

diff --git a/include/hw/ppc/pnv_occ.h b/include/hw/ppc/pnv_occ.h
index 82f299dc76ff..dab5a05f8e99 100644
--- a/include/hw/ppc/pnv_occ.h
+++ b/include/hw/ppc/pnv_occ.h
@@ -23,6 +23,8 @@
 
 #define TYPE_PNV_OCC "pnv-occ"
 #define PNV_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV_OCC)
+#define TYPE_PNV8_OCC TYPE_PNV_OCC "-POWER8"
+#define PNV8_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV8_OCC)
 
 typedef struct PnvOCC {
 DeviceState xd;
@@ -35,4 +37,17 @@ typedef struct PnvOCC {
 MemoryRegion xscom_regs;
 } PnvOCC;
 
+#define PNV_OCC_CLASS(klass) \
+ OBJECT_CLASS_CHECK(PnvOCCClass, (klass), TYPE_PNV_OCC)
+#define PNV_OCC_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(PnvOCCClass, (obj), TYPE_PNV_OCC)
+
+typedef struct PnvOCCClass {
+DeviceClass parent_class;
+
+int xscom_size;
+const MemoryRegionOps *xscom_ops;
+int psi_irq;
+} PnvOCCClass;
+
 #endif /* _PPC_PNV_OCC_H */
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 918fae057b5c..6ae9ce679505 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -790,7 +790,7 @@ static void pnv_chip_power8_instance_init(Object *obj)
OBJECT(>psi), _abort);
 
 object_initialize_child(obj, "occ",  >occ, sizeof(chip8->occ),
-TYPE_PNV_OCC, _abort, NULL);
+TYPE_PNV8_OCC, _abort, NULL);
 object_property_add_const_link(OBJECT(>occ), "psi",
OBJECT(>psi), _abort);
 }
diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c
index 04880f26d612..ea725647c988 100644
--- a/hw/ppc/pnv_occ.c
+++ b/hw/ppc/pnv_occ.c
@@ -34,15 +34,17 @@
 static void pnv_occ_set_misc(PnvOCC *occ, uint64_t val)
 {
 bool irq_state;
+PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
 
 val &= 0xull;
 
 occ->occmisc = val;
 irq_state = !!(val >> 63);
-pnv_psi_irq_set(occ->psi, PSIHB_IRQ_OCC, irq_state);
+pnv_psi_irq_set(occ->psi, poc->psi_irq, irq_state);
 }
 
-static uint64_t pnv_occ_xscom_read(void *opaque, hwaddr addr, unsigned size)
+static uint64_t pnv_occ_power8_xscom_read(void *opaque, hwaddr addr,
+  unsigned size)
 {
 PnvOCC *occ = PNV_OCC(opaque);
 uint32_t offset = addr >> 3;
@@ -54,13 +56,13 @@ static uint64_t pnv_occ_xscom_read(void *opaque, hwaddr 
addr, unsigned size)
 break;
 default:
 qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
-  HWADDR_PRIx "\n", addr);
+  HWADDR_PRIx "\n", addr >> 3);
 }
 return val;
 }
 
-static void pnv_occ_xscom_write(void *opaque, hwaddr addr,
-uint64_t val, unsigned size)
+static void pnv_occ_power8_xscom_write(void *opaque, hwaddr addr,
+   uint64_t val, unsigned size)
 {
 PnvOCC *occ = PNV_OCC(opaque);
 uint32_t offset = addr >> 3;
@@ -77,13 +79,13 @@ static void pnv_occ_xscom_write(void *opaque, hwaddr addr,
 break;
 default:
 qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
-  HWADDR_PRIx "\n", addr);
+  HWADDR_PRIx "\n", addr >> 3);
 }
 }
 
-static const MemoryRegionOps pnv_occ_xscom_ops = {
-.read = pnv_occ_xscom_read,
-.write = pnv_occ_xscom_write,
+static const MemoryRegionOps pnv_occ_power8_xscom_ops = {
+.read = pnv_occ_power8_xscom_read,
+.write = pnv_occ_power8_xscom_write,
 .valid.min_access_size = 8,
 .valid.max_access_size = 8,
 .impl.min_access_size = 8,
@@ -91,27 +93,42 @@ static const MemoryRegionOps pnv_occ_xscom_ops = {
 .endianness = DEVICE_BIG_ENDIAN,
 };
 
+static void pnv_occ_power8_class_init(ObjectClass *klass, void *data)
+{
+PnvOCCClass *poc = PNV_OCC_CLASS(klass);
+
+poc->xscom_size = PNV_XSCOM_OCC_SIZE;
+poc->xscom_ops = _occ_power8_xscom_ops;
+poc->psi_irq = PSIHB_IRQ_OCC;
+}
+
+static const TypeInfo pnv_occ_power8_type_info = {
+.name  = TYPE_PNV8_OCC,
+.parent= TYPE_PNV_OCC,
+.instance_size = sizeof(PnvOCC),
+.class_init= pnv_occ_power8_class_init,
+};
 
 static void pnv_occ_realize(DeviceState *dev, Error **errp)
 {
 PnvOCC *occ = PNV_OCC(dev);
+PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
 Object *obj;
-Error *error = NULL;
+Error *local_err = NULL;
 
 occ->occmisc = 0;
 
-/* get PSI object from chip */
-obj = object_property_get_link(OBJECT(dev), "psi", );
+