diff mbox

[v4,9/9] ppc/xics: move set_nr_{irqs, servers} to xics.c

Message ID 1474266577-11704-10-git-send-email-nikunj@linux.vnet.ibm.com
State New
Headers show

Commit Message

Nikunj A Dadhania Sept. 19, 2016, 6:29 a.m. UTC
Get this duplicate code in the base implementation.

Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
---
 hw/intc/xics.c        | 74 ++++++++++++++++++++++++++++++++++++++++++++-------
 hw/intc/xics_kvm.c    | 34 +++--------------------
 hw/intc/xics_native.c | 51 +++++++++++++++++++++--------------
 hw/intc/xics_spapr.c  | 49 +++++++++-------------------------
 include/hw/ppc/xics.h | 19 ++++++++++---
 5 files changed, 126 insertions(+), 101 deletions(-)

Comments

David Gibson Sept. 22, 2016, 12:14 a.m. UTC | #1
On Mon, Sep 19, 2016 at 11:59:37AM +0530, Nikunj A Dadhania wrote:
> Get this duplicate code in the base implementation.
> 
> Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
> ---
>  hw/intc/xics.c        | 74 ++++++++++++++++++++++++++++++++++++++++++++-------
>  hw/intc/xics_kvm.c    | 34 +++--------------------
>  hw/intc/xics_native.c | 51 +++++++++++++++++++++--------------
>  hw/intc/xics_spapr.c  | 49 +++++++++-------------------------
>  include/hw/ppc/xics.h | 19 ++++++++++---
>  5 files changed, 126 insertions(+), 101 deletions(-)
> 
> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> index 4ac2d00..9fbf962 100644
> --- a/hw/intc/xics.c
> +++ b/hw/intc/xics.c
> @@ -54,8 +54,9 @@ int xics_get_cpu_index_by_dt_id(int cpu_dt_id)
>  void xics_cpu_destroy(XICSState *xics, PowerPCCPU *cpu)
>  {
>      CPUState *cs = CPU(cpu);
> -    ICPState *ss = &xics->ss[cs->cpu_index];
> +    ICPState *ss;
>  
> +    ss = xics->ss + sizeof(ICPState) * cs->cpu_index;
>      assert(cs->cpu_index < xics->nr_servers);
>      assert(cs == ss->cs);
>  
> @@ -67,9 +68,10 @@ void xics_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
>  {
>      CPUState *cs = CPU(cpu);
>      CPUPPCState *env = &cpu->env;
> -    ICPState *ss = &xics->ss[cs->cpu_index];
> +    ICPState *ss;
>      XICSStateClass *info = XICS_COMMON_GET_CLASS(xics);
>  
> +    ss = xics->ss + sizeof(ICPState) * cs->cpu_index;
>      assert(cs->cpu_index < xics->nr_servers);
>  
>      ss->cs = cs;
> @@ -101,10 +103,12 @@ static void xics_common_reset(DeviceState *d)
>  {
>      XICSState *xics = XICS_COMMON(d);
>      ICSState *ics;
> +    ICPState *ss;
>      int i;
>  
>      for (i = 0; i < xics->nr_servers; i++) {
> -        device_reset(DEVICE(&xics->ss[i]));
> +        ss = xics->ss + sizeof(ICPState) * i;
> +        device_reset(DEVICE(ss));
>      }
>  
>      QLIST_FOREACH(ics, &xics->ics, list) {
> @@ -193,6 +197,7 @@ static void xics_common_initfn(Object *obj)
>      XICSState *xics = XICS_COMMON(obj);
>  
>      QLIST_INIT(&xics->ics);
> +    xics->ss_class = object_class_by_name(TYPE_ICP);
>      object_property_add(obj, "nr_irqs", "int",
>                          xics_prop_get_nr_irqs, xics_prop_set_nr_irqs,
>                          NULL, NULL, NULL);
> @@ -201,7 +206,15 @@ static void xics_common_initfn(Object *obj)
>                          NULL, NULL, NULL);
>  
>      /* For exclusive use of monitor command */
> -    g_xics = XICS_COMMON(obj);
> +    g_xics = xics;

Looks like this change should be folded into the patch introducing g_xics.

> +}
> +
> +static void xics_common_realize(DeviceState *dev, Error **errp)
> +{
> +    XICSState *xics = XICS_COMMON(dev);
> +    XICSStateClass *xsc = XICS_COMMON_GET_CLASS(xics);
> +
> +    xsc->realize(dev, errp);
>  }
>  
>  static void xics_common_class_init(ObjectClass *oc, void *data)
> @@ -209,6 +222,7 @@ static void xics_common_class_init(ObjectClass *oc, void *data)
>      DeviceClass *dc = DEVICE_CLASS(oc);
>  
>      dc->reset = xics_common_reset;
> +    dc->realize = xics_common_realize;
>  }
>  
>  static const TypeInfo xics_common_info = {
> @@ -277,7 +291,7 @@ static void icp_check_ipi(ICPState *ss)
>  
>  static void icp_resend(XICSState *xics, int server)
>  {
> -    ICPState *ss = xics->ss + server;
> +    ICPState *ss = xics->ss + server * sizeof(ICPState);
>      ICSState *ics;
>  
>      if (ss->mfrr < CPPR(ss)) {
> @@ -290,7 +304,7 @@ static void icp_resend(XICSState *xics, int server)
>  
>  void icp_set_cppr(XICSState *xics, int server, uint8_t cppr)
>  {
> -    ICPState *ss = xics->ss + server;
> +    ICPState *ss = xics->ss + server * sizeof(ICPState);
>      uint8_t old_cppr;
>      uint32_t old_xisr;
>  
> @@ -317,7 +331,7 @@ void icp_set_cppr(XICSState *xics, int server, uint8_t cppr)
>  
>  void icp_set_mfrr(XICSState *xics, int server, uint8_t mfrr)
>  {
> -    ICPState *ss = xics->ss + server;
> +    ICPState *ss = xics->ss + server * sizeof(ICPState);
>  
>      ss->mfrr = mfrr;
>      if (mfrr < CPPR(ss)) {
> @@ -349,7 +363,7 @@ uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr)
>  
>  void icp_eoi(XICSState *xics, int server, uint32_t xirr)
>  {
> -    ICPState *ss = xics->ss + server;
> +    ICPState *ss = xics->ss + server * sizeof(ICPState);
>      ICSState *ics;
>      uint32_t irq;
>  
> @@ -370,7 +384,7 @@ void icp_eoi(XICSState *xics, int server, uint32_t xirr)
>  static void icp_irq(ICSState *ics, int server, int nr, uint8_t priority)
>  {
>      XICSState *xics = ics->xics;
> -    ICPState *ss = xics->ss + server;
> +    ICPState *ss = xics->ss + server * sizeof(ICPState);
>  
>      trace_xics_icp_irq(server, nr, priority);
>  
> @@ -488,6 +502,14 @@ static const TypeInfo icp_info = {
>      .class_size = sizeof(ICPStateClass),
>  };
>  
> +static const TypeInfo icp_native_info = {
> +    .name = TYPE_NATIVE_ICP,
> +    .parent = TYPE_ICP,
> +    .instance_size = sizeof(ICPNative),
> +    .class_init = icp_class_init,
> +    .class_size = sizeof(ICPStateClass),
> +};
> +

Introducing a whole new subclass doesn't seem to be covered by the
commit message...

>  /*
>   * ICS: Source layer
>   */
> @@ -689,7 +711,7 @@ void xics_hmp_info_pic(Monitor *mon, const QDict *qdict)
>      uint32_t i;
>  
>      for (i = 0; i < g_xics->nr_servers; i++) {
> -        ICPState *icp = &g_xics->ss[i];
> +        ICPState *icp = g_xics->ss + i * sizeof(ICPState);
>  
>          if (!icp->output) {
>              continue;
> @@ -829,12 +851,44 @@ void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)
>          lsi ? XICS_FLAGS_IRQ_LSI : XICS_FLAGS_IRQ_MSI;
>  }
>  
> +void xics_set_nr_irqs(XICSState *xics, uint32_t nr_irqs, Error **errp)
> +{
> +    ICSState *ics = QLIST_FIRST(&xics->ics);
> +
> +    /* This needs to be deprecated ... */

Could you actually deprecate this, instead of moving it around?

> +    xics->nr_irqs = nr_irqs;
> +    if (ics) {
> +        ics->nr_irqs = nr_irqs;
> +    }
> +}
> +
> +void xics_set_nr_servers(XICSState *xics, uint32_t nr_servers, Error **errp)
> +{
> +    int i;
> +    const char *typename = object_class_get_name(xics->ss_class);
> +    size_t size = object_type_get_instance_size(typename);
> +
> +    xics->nr_servers = nr_servers;
> +
> +    xics->ss = g_malloc0(xics->nr_servers * size);
> +    for (i = 0; i < xics->nr_servers; i++) {
> +        char buffer[32];
> +        void *obj;
> +
> +        obj = xics->ss + size * i;
> +        object_initialize(obj, size, typename);
> +        snprintf(buffer, sizeof(buffer), "icp[%d]", i);
> +        object_property_add_child(OBJECT(xics), buffer, obj, errp);
> +    }
> +}
> +
>  static void xics_register_types(void)
>  {
>      type_register_static(&xics_common_info);
>      type_register_static(&ics_simple_info);
>      type_register_static(&ics_base_info);
>      type_register_static(&icp_info);
> +    type_register_static(&icp_native_info);
>  }
>  
>  type_init(xics_register_types)
> diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
> index 89862df..b095b9e 100644
> --- a/hw/intc/xics_kvm.c
> +++ b/hw/intc/xics_kvm.c
> @@ -362,35 +362,6 @@ static void xics_kvm_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
>      }
>  }
>  
> -static void xics_kvm_set_nr_irqs(XICSState *xics, uint32_t nr_irqs,
> -                                 Error **errp)
> -{
> -    ICSState *ics = QLIST_FIRST(&xics->ics);
> -
> -    /* This needs to be deprecated ... */
> -    xics->nr_irqs = nr_irqs;
> -    if (ics) {
> -        ics->nr_irqs = nr_irqs;
> -    }
> -}
> -
> -static void xics_kvm_set_nr_servers(XICSState *xics, uint32_t nr_servers,
> -                                    Error **errp)
> -{
> -    int i;
> -
> -    xics->nr_servers = nr_servers;
> -
> -    xics->ss = g_malloc0(xics->nr_servers * sizeof(ICPState));
> -    for (i = 0; i < xics->nr_servers; i++) {
> -        char buffer[32];
> -        object_initialize(&xics->ss[i], sizeof(xics->ss[i]), TYPE_KVM_ICP);
> -        snprintf(buffer, sizeof(buffer), "icp[%d]", i);
> -        object_property_add_child(OBJECT(xics), buffer, OBJECT(&xics->ss[i]),
> -                                  errp);
> -    }
> -}
> -
>  static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>                         uint32_t token,
>                         uint32_t nargs, target_ulong args,
> @@ -492,6 +463,7 @@ static void xics_kvm_initfn(Object *obj)
>      XICSState *xics = XICS_COMMON(obj);
>      ICSState *ics;
>  
> +    xics->ss_class = object_class_by_name(TYPE_KVM_ICP);
>      ics = ICS_SIMPLE(object_new(TYPE_ICS_KVM));
>      object_property_add_child(obj, "ics", OBJECT(ics), NULL);
>      ics->xics = xics;
> @@ -505,8 +477,8 @@ static void xics_kvm_class_init(ObjectClass *oc, void *data)
>  
>      dc->realize = xics_kvm_realize;
>      xsc->cpu_setup = xics_kvm_cpu_setup;
> -    xsc->set_nr_irqs = xics_kvm_set_nr_irqs;
> -    xsc->set_nr_servers = xics_kvm_set_nr_servers;
> +    xsc->set_nr_irqs = xics_set_nr_irqs;
> +    xsc->set_nr_servers = xics_set_nr_servers;
>  }
>  
>  static const TypeInfo xics_spapr_kvm_info = {
> diff --git a/hw/intc/xics_native.c b/hw/intc/xics_native.c
> index 26e45cc..db2fd4d 100644
> --- a/hw/intc/xics_native.c
> +++ b/hw/intc/xics_native.c
> @@ -38,11 +38,19 @@
>  /* #define DEBUG_MM(fmt...)      printf(fmt) */
>  #define DEBUG_MM(fmt...)        do { } while (0)
>  
> +typedef struct XICSNative {
> +    /*< private >*/
> +    XICSState xics;
> +
> +    /*< public >*/
> +    MemoryRegion icp_mmio;
> +} XICSNative;
> +
>  static void xics_native_initfn(Object *obj)
>  {
> -    XICSState *xics = XICS_NATIVE(obj);
> +    XICSState *xics = XICS_COMMON(obj);
>  
> -    QLIST_INIT(&xics->ics);
> +    xics->ss_class = object_class_by_name(TYPE_NATIVE_ICP);

ss_class should be a class field, not an instance field.

>  }
>  
>  static uint64_t icp_mm_read(void *opaque, hwaddr addr, unsigned width)
> @@ -51,6 +59,7 @@ static uint64_t icp_mm_read(void *opaque, hwaddr addr, unsigned width)
>      int32_t cpu_id, server;
>      uint32_t val;
>      ICPState *ss;
> +    ICPNative *icpn;
>      bool byte0 = (width == 1 && (addr & 0x3) == 0);
>  
>      cpu_id = (addr & (ICP_MM_SIZE - 1)) >> 12;
> @@ -59,7 +68,8 @@ static uint64_t icp_mm_read(void *opaque, hwaddr addr, unsigned width)
>          fprintf(stderr, "XICS: Bad ICP server %d\n", server);
>          goto bad_access;
>      }
> -    ss = &s->ss[server];
> +    icpn = s->ss + server * sizeof(ICPNative);
> +    ss = &icpn->icp;
>  
>      switch (addr & 0xffc) {
>      case 0: /* poll */
> @@ -88,21 +98,21 @@ static uint64_t icp_mm_read(void *opaque, hwaddr addr, unsigned width)
>          break;
>      case 16:
>          if (width == 4) {
> -            val = ss->links[0];
> +            val = icpn->links[0];
>          } else {
>              goto bad_access;
>          }
>          break;
>      case 20:
>          if (width == 4) {
> -            val = ss->links[1];
> +            val = icpn->links[1];
>          } else {
>              goto bad_access;
>          }
>          break;
>      case 24:
>          if (width == 4) {
> -            val = ss->links[2];
> +            val = icpn->links[2];
>          } else {
>              goto bad_access;
>          }
> @@ -125,7 +135,7 @@ static void icp_mm_write(void *opaque, hwaddr addr, uint64_t val,
>  {
>      XICSState *s = opaque;
>      int32_t cpu_id, server;
> -    ICPState *ss;
> +    ICPNative *icpn;
>      bool byte0 = (width == 1 && (addr & 0x3) == 0);
>  
>      cpu_id = (addr & (ICP_MM_SIZE - 1)) >> 12;
> @@ -134,7 +144,8 @@ static void icp_mm_write(void *opaque, hwaddr addr, uint64_t val,
>          fprintf(stderr, "XICS: Bad ICP server %d\n", server);
>          goto bad_access;
>      }
> -    ss = &s->ss[server];
> +    icpn = s->ss + server * sizeof(ICPNative);
> +    ss = &icpn->icp;
>  
>      DEBUG_MM("icp_mm_write(addr=%016llx,serv=0x%x/%d,off=%d,w=%d,val=0x%08x)\n",
>               (unsigned long long)addr, cpu_id, server,
> @@ -159,21 +170,21 @@ static void icp_mm_write(void *opaque, hwaddr addr, uint64_t val,
>          break;
>      case 16:
>          if (width == 4) {
> -            ss->links[0] = val;
> +            icpn->links[0] = val;
>          } else {
>              goto bad_access;
>          }
>          break;
>      case 20:
>          if (width == 4) {
> -            ss->links[1] = val;
> +            icpn->links[1] = val;
>          } else {
>              goto bad_access;
>          }
>          break;
>      case 24:
>          if (width == 4) {
> -            ss->links[2] = val;
> +            icpn->links[2] = val;
>          } else {
>              goto bad_access;
>          }
> @@ -245,8 +256,9 @@ void xics_create_native_icp_node(XICSState *s, void *fdt,
>  
>  static void xics_native_realize(DeviceState *dev, Error **errp)
>  {
> -    XICSState *s = XICS_NATIVE(dev);
> -    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
> +    XICSNative *n = XICS_NATIVE(dev);
> +    XICSState *s = XICS_COMMON(dev);
> +    SysBusDevice *sbd = SYS_BUS_DEVICE(s);
>      Error *error = NULL;
>      int i;
>  
> @@ -256,13 +268,14 @@ static void xics_native_realize(DeviceState *dev, Error **errp)
>      }
>  
>      /* Register MMIO regions */
> -    memory_region_init_io(&s->icp_mmio, OBJECT(s), &icp_mm_ops, s, "icp",
> +    memory_region_init_io(&n->icp_mmio, OBJECT(s), &icp_mm_ops, s, "icp",
>                            ICP_MM_SIZE);
> -    sysbus_init_mmio(sbd, &s->icp_mmio);
> +    sysbus_init_mmio(sbd, &n->icp_mmio);
>      sysbus_mmio_map(sbd, 0, ICP_MM_BASE);
>  
>      for (i = 0; i < s->nr_servers; i++) {
> -        object_property_set_bool(OBJECT(&s->ss[i]), true, "realized", &error);
> +        ICPNative *icpn = s->ss + i * sizeof(ICPNative);
> +        object_property_set_bool(OBJECT(icpn), true, "realized", &error);
>          if (error) {
>              error_propagate(errp, error);
>              return;
> @@ -272,20 +285,18 @@ static void xics_native_realize(DeviceState *dev, Error **errp)
>  
>  static void xics_native_class_init(ObjectClass *oc, void *data)
>  {
> -    DeviceClass *dc = DEVICE_CLASS(oc);
>      XICSStateClass *xsc = XICS_NATIVE_CLASS(oc);
>  
> -    dc->realize = xics_native_realize;
> +    xsc->realize = xics_native_realize;
>      xsc->set_nr_servers = xics_set_nr_servers;
>  }
>  
>  static const TypeInfo xics_native_info = {
>      .name          = TYPE_XICS_NATIVE,
>      .parent        = TYPE_XICS_COMMON,
> -    .instance_size = sizeof(XICSState),
> +    .instance_size = sizeof(XICSNative),
>      .class_size = sizeof(XICSStateClass),
>      .class_init    = xics_native_class_init,
> -    .instance_init = xics_native_initfn,
>  };
>  
>  static void xics_native_register_types(void)
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index 4dd1399..0644942 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -67,7 +67,8 @@ static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>                             target_ulong opcode, target_ulong *args)
>  {
>      CPUState *cs = CPU(cpu);
> -    uint32_t xirr = icp_accept(spapr->xics->ss + cs->cpu_index);
> +    uint32_t xirr = icp_accept(spapr->xics->ss +
> +                               cs->cpu_index * sizeof(ICPState));
>  
>      args[0] = xirr;
>      return H_SUCCESS;
> @@ -77,9 +78,11 @@ static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>                               target_ulong opcode, target_ulong *args)
>  {
>      CPUState *cs = CPU(cpu);
> -    ICPState *ss = &spapr->xics->ss[cs->cpu_index];
> -    uint32_t xirr = icp_accept(ss);
> +    ICPState *ss;
> +    uint32_t xirr;
>  
> +    ss = spapr->xics->ss + cs->cpu_index * sizeof(ICPState);
> +    xirr = icp_accept(ss);
>      args[0] = xirr;
>      args[1] = cpu_get_host_ticks();
>      return H_SUCCESS;
> @@ -100,7 +103,8 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>  {
>      CPUState *cs = CPU(cpu);
>      uint32_t mfrr;
> -    uint32_t xirr = icp_ipoll(spapr->xics->ss + cs->cpu_index, &mfrr);
> +    uint32_t xirr = icp_ipoll(spapr->xics->ss +
> +                              cs->cpu_index * sizeof(ICPState), &mfrr);
>  
>      args[0] = xirr;
>      args[1] = mfrr;
> @@ -234,35 +238,6 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>      rtas_st(rets, 0, RTAS_OUT_SUCCESS);
>  }
>  
> -static void xics_spapr_set_nr_irqs(XICSState *xics, uint32_t nr_irqs,
> -                                   Error **errp)
> -{
> -    ICSState *ics = QLIST_FIRST(&xics->ics);
> -
> -    /* This needs to be deprecated ... */
> -    xics->nr_irqs = nr_irqs;
> -    if (ics) {
> -        ics->nr_irqs = nr_irqs;
> -    }
> -}
> -
> -static void xics_spapr_set_nr_servers(XICSState *xics, uint32_t nr_servers,
> -                                      Error **errp)
> -{
> -    int i;
> -
> -    xics->nr_servers = nr_servers;
> -
> -    xics->ss = g_malloc0(xics->nr_servers * sizeof(ICPState));
> -    for (i = 0; i < xics->nr_servers; i++) {
> -        char buffer[32];
> -        object_initialize(&xics->ss[i], sizeof(xics->ss[i]), TYPE_ICP);
> -        snprintf(buffer, sizeof(buffer), "icp[%d]", i);
> -        object_property_add_child(OBJECT(xics), buffer, OBJECT(&xics->ss[i]),
> -                                  errp);
> -    }
> -}
> -
>  static void xics_spapr_realize(DeviceState *dev, Error **errp)
>  {
>      XICSState *xics = XICS_SPAPR(dev);
> @@ -297,8 +272,8 @@ static void xics_spapr_realize(DeviceState *dev, Error **errp)
>      }
>  
>      for (i = 0; i < xics->nr_servers; i++) {
> -        object_property_set_bool(OBJECT(&xics->ss[i]), true, "realized",
> -                                 &error);
> +        ICPState *ss = xics->ss + i * sizeof(ICPState);
> +        object_property_set_bool(OBJECT(ss), true, "realized", &error);
>          if (error) {
>              error_propagate(errp, error);
>              return;
> @@ -319,8 +294,8 @@ static void xics_spapr_class_init(ObjectClass *oc, void *data)
>      XICSStateClass *xsc = XICS_SPAPR_CLASS(oc);
>  
>      dc->realize = xics_spapr_realize;
> -    xsc->set_nr_irqs = xics_spapr_set_nr_irqs;
> -    xsc->set_nr_servers = xics_spapr_set_nr_servers;
> +    xsc->set_nr_irqs = xics_set_nr_irqs;
> +    xsc->set_nr_servers = xics_set_nr_servers;
>  }
>  
>  static const TypeInfo xics_spapr_info = {
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index 58bb7c6..0a427d7 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -45,7 +45,7 @@
>       OBJECT_CHECK(KVMXICSState, (obj), TYPE_XICS_SPAPR_KVM)
>  
>  #define TYPE_XICS_NATIVE "xics-native"
> -#define XICS_NATIVE(obj) OBJECT_CHECK(XICSState, (obj), TYPE_XICS_NATIVE)
> +#define XICS_NATIVE(obj) OBJECT_CHECK(XICSNative, (obj), TYPE_XICS_NATIVE)
>  
>  #define XICS_COMMON_CLASS(klass) \
>       OBJECT_CLASS_CHECK(XICSStateClass, (klass), TYPE_XICS_COMMON)
> @@ -71,6 +71,7 @@ typedef struct XICSStateClass XICSStateClass;
>  typedef struct XICSState XICSState;
>  typedef struct ICPStateClass ICPStateClass;
>  typedef struct ICPState ICPState;
> +typedef struct ICPNative ICPNative;
>  typedef struct ICSStateClass ICSStateClass;
>  typedef struct ICSState ICSState;
>  typedef struct ICSIRQState ICSIRQState;
> @@ -78,6 +79,7 @@ typedef struct ICSIRQState ICSIRQState;
>  struct XICSStateClass {
>      DeviceClass parent_class;
>  
> +    DeviceRealize realize;
>      void (*cpu_setup)(XICSState *icp, PowerPCCPU *cpu);
>      void (*set_nr_irqs)(XICSState *icp, uint32_t nr_irqs, Error **errp);
>      void (*set_nr_servers)(XICSState *icp, uint32_t nr_servers, Error **errp);
> @@ -89,9 +91,9 @@ struct XICSState {
>      /*< public >*/
>      uint32_t nr_servers;
>      uint32_t nr_irqs;
> -    ICPState *ss;
> +    void *ss;
> +    ObjectClass *ss_class;
>      QLIST_HEAD(, ICSState) ics;
> -    MemoryRegion icp_mmio;
>  };
>  
>  #define TYPE_ICP "icp"
> @@ -100,6 +102,9 @@ struct XICSState {
>  #define TYPE_KVM_ICP "icp-kvm"
>  #define KVM_ICP(obj) OBJECT_CHECK(ICPState, (obj), TYPE_KVM_ICP)
>  
> +#define TYPE_NATIVE_ICP "icp-native"
> +#define NATIVE_ICP(obj) OBJECT_CHECK(ICPNative, (obj), TYPE_NATIVE_ICP)
> +
>  #define ICP_CLASS(klass) \
>       OBJECT_CLASS_CHECK(ICPStateClass, (klass), TYPE_ICP)
>  #define ICP_GET_CLASS(obj) \
> @@ -123,6 +128,12 @@ struct ICPState {
>      uint8_t mfrr;
>      qemu_irq output;
>      bool cap_irq_xics_enabled;
> +};
> +
> +struct ICPNative {
> +    /*<private>*/
> +    ICPState icp;
> +    /*<public>*/
>      uint32_t links[3];
>  };
>  
> @@ -199,6 +210,8 @@ void xics_spapr_free(XICSState *icp, int irq, int num);
>  
>  void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu);
>  void xics_cpu_destroy(XICSState *icp, PowerPCCPU *cpu);
> +void xics_set_nr_irqs(XICSState *xics, uint32_t nr_irqs, Error **errp);
> +void xics_set_nr_servers(XICSState *xics, uint32_t nr_servers, Error **errp);
>  
>  void xics_create_native_icp_node(XICSState *s, void *fdt,
>                                   uint32_t base, uint32_t count);
diff mbox

Patch

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 4ac2d00..9fbf962 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -54,8 +54,9 @@  int xics_get_cpu_index_by_dt_id(int cpu_dt_id)
 void xics_cpu_destroy(XICSState *xics, PowerPCCPU *cpu)
 {
     CPUState *cs = CPU(cpu);
-    ICPState *ss = &xics->ss[cs->cpu_index];
+    ICPState *ss;
 
+    ss = xics->ss + sizeof(ICPState) * cs->cpu_index;
     assert(cs->cpu_index < xics->nr_servers);
     assert(cs == ss->cs);
 
@@ -67,9 +68,10 @@  void xics_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
 {
     CPUState *cs = CPU(cpu);
     CPUPPCState *env = &cpu->env;
-    ICPState *ss = &xics->ss[cs->cpu_index];
+    ICPState *ss;
     XICSStateClass *info = XICS_COMMON_GET_CLASS(xics);
 
+    ss = xics->ss + sizeof(ICPState) * cs->cpu_index;
     assert(cs->cpu_index < xics->nr_servers);
 
     ss->cs = cs;
@@ -101,10 +103,12 @@  static void xics_common_reset(DeviceState *d)
 {
     XICSState *xics = XICS_COMMON(d);
     ICSState *ics;
+    ICPState *ss;
     int i;
 
     for (i = 0; i < xics->nr_servers; i++) {
-        device_reset(DEVICE(&xics->ss[i]));
+        ss = xics->ss + sizeof(ICPState) * i;
+        device_reset(DEVICE(ss));
     }
 
     QLIST_FOREACH(ics, &xics->ics, list) {
@@ -193,6 +197,7 @@  static void xics_common_initfn(Object *obj)
     XICSState *xics = XICS_COMMON(obj);
 
     QLIST_INIT(&xics->ics);
+    xics->ss_class = object_class_by_name(TYPE_ICP);
     object_property_add(obj, "nr_irqs", "int",
                         xics_prop_get_nr_irqs, xics_prop_set_nr_irqs,
                         NULL, NULL, NULL);
@@ -201,7 +206,15 @@  static void xics_common_initfn(Object *obj)
                         NULL, NULL, NULL);
 
     /* For exclusive use of monitor command */
-    g_xics = XICS_COMMON(obj);
+    g_xics = xics;
+}
+
+static void xics_common_realize(DeviceState *dev, Error **errp)
+{
+    XICSState *xics = XICS_COMMON(dev);
+    XICSStateClass *xsc = XICS_COMMON_GET_CLASS(xics);
+
+    xsc->realize(dev, errp);
 }
 
 static void xics_common_class_init(ObjectClass *oc, void *data)
@@ -209,6 +222,7 @@  static void xics_common_class_init(ObjectClass *oc, void *data)
     DeviceClass *dc = DEVICE_CLASS(oc);
 
     dc->reset = xics_common_reset;
+    dc->realize = xics_common_realize;
 }
 
 static const TypeInfo xics_common_info = {
@@ -277,7 +291,7 @@  static void icp_check_ipi(ICPState *ss)
 
 static void icp_resend(XICSState *xics, int server)
 {
-    ICPState *ss = xics->ss + server;
+    ICPState *ss = xics->ss + server * sizeof(ICPState);
     ICSState *ics;
 
     if (ss->mfrr < CPPR(ss)) {
@@ -290,7 +304,7 @@  static void icp_resend(XICSState *xics, int server)
 
 void icp_set_cppr(XICSState *xics, int server, uint8_t cppr)
 {
-    ICPState *ss = xics->ss + server;
+    ICPState *ss = xics->ss + server * sizeof(ICPState);
     uint8_t old_cppr;
     uint32_t old_xisr;
 
@@ -317,7 +331,7 @@  void icp_set_cppr(XICSState *xics, int server, uint8_t cppr)
 
 void icp_set_mfrr(XICSState *xics, int server, uint8_t mfrr)
 {
-    ICPState *ss = xics->ss + server;
+    ICPState *ss = xics->ss + server * sizeof(ICPState);
 
     ss->mfrr = mfrr;
     if (mfrr < CPPR(ss)) {
@@ -349,7 +363,7 @@  uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr)
 
 void icp_eoi(XICSState *xics, int server, uint32_t xirr)
 {
-    ICPState *ss = xics->ss + server;
+    ICPState *ss = xics->ss + server * sizeof(ICPState);
     ICSState *ics;
     uint32_t irq;
 
@@ -370,7 +384,7 @@  void icp_eoi(XICSState *xics, int server, uint32_t xirr)
 static void icp_irq(ICSState *ics, int server, int nr, uint8_t priority)
 {
     XICSState *xics = ics->xics;
-    ICPState *ss = xics->ss + server;
+    ICPState *ss = xics->ss + server * sizeof(ICPState);
 
     trace_xics_icp_irq(server, nr, priority);
 
@@ -488,6 +502,14 @@  static const TypeInfo icp_info = {
     .class_size = sizeof(ICPStateClass),
 };
 
+static const TypeInfo icp_native_info = {
+    .name = TYPE_NATIVE_ICP,
+    .parent = TYPE_ICP,
+    .instance_size = sizeof(ICPNative),
+    .class_init = icp_class_init,
+    .class_size = sizeof(ICPStateClass),
+};
+
 /*
  * ICS: Source layer
  */
@@ -689,7 +711,7 @@  void xics_hmp_info_pic(Monitor *mon, const QDict *qdict)
     uint32_t i;
 
     for (i = 0; i < g_xics->nr_servers; i++) {
-        ICPState *icp = &g_xics->ss[i];
+        ICPState *icp = g_xics->ss + i * sizeof(ICPState);
 
         if (!icp->output) {
             continue;
@@ -829,12 +851,44 @@  void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)
         lsi ? XICS_FLAGS_IRQ_LSI : XICS_FLAGS_IRQ_MSI;
 }
 
+void xics_set_nr_irqs(XICSState *xics, uint32_t nr_irqs, Error **errp)
+{
+    ICSState *ics = QLIST_FIRST(&xics->ics);
+
+    /* This needs to be deprecated ... */
+    xics->nr_irqs = nr_irqs;
+    if (ics) {
+        ics->nr_irqs = nr_irqs;
+    }
+}
+
+void xics_set_nr_servers(XICSState *xics, uint32_t nr_servers, Error **errp)
+{
+    int i;
+    const char *typename = object_class_get_name(xics->ss_class);
+    size_t size = object_type_get_instance_size(typename);
+
+    xics->nr_servers = nr_servers;
+
+    xics->ss = g_malloc0(xics->nr_servers * size);
+    for (i = 0; i < xics->nr_servers; i++) {
+        char buffer[32];
+        void *obj;
+
+        obj = xics->ss + size * i;
+        object_initialize(obj, size, typename);
+        snprintf(buffer, sizeof(buffer), "icp[%d]", i);
+        object_property_add_child(OBJECT(xics), buffer, obj, errp);
+    }
+}
+
 static void xics_register_types(void)
 {
     type_register_static(&xics_common_info);
     type_register_static(&ics_simple_info);
     type_register_static(&ics_base_info);
     type_register_static(&icp_info);
+    type_register_static(&icp_native_info);
 }
 
 type_init(xics_register_types)
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 89862df..b095b9e 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -362,35 +362,6 @@  static void xics_kvm_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
     }
 }
 
-static void xics_kvm_set_nr_irqs(XICSState *xics, uint32_t nr_irqs,
-                                 Error **errp)
-{
-    ICSState *ics = QLIST_FIRST(&xics->ics);
-
-    /* This needs to be deprecated ... */
-    xics->nr_irqs = nr_irqs;
-    if (ics) {
-        ics->nr_irqs = nr_irqs;
-    }
-}
-
-static void xics_kvm_set_nr_servers(XICSState *xics, uint32_t nr_servers,
-                                    Error **errp)
-{
-    int i;
-
-    xics->nr_servers = nr_servers;
-
-    xics->ss = g_malloc0(xics->nr_servers * sizeof(ICPState));
-    for (i = 0; i < xics->nr_servers; i++) {
-        char buffer[32];
-        object_initialize(&xics->ss[i], sizeof(xics->ss[i]), TYPE_KVM_ICP);
-        snprintf(buffer, sizeof(buffer), "icp[%d]", i);
-        object_property_add_child(OBJECT(xics), buffer, OBJECT(&xics->ss[i]),
-                                  errp);
-    }
-}
-
 static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                        uint32_t token,
                        uint32_t nargs, target_ulong args,
@@ -492,6 +463,7 @@  static void xics_kvm_initfn(Object *obj)
     XICSState *xics = XICS_COMMON(obj);
     ICSState *ics;
 
+    xics->ss_class = object_class_by_name(TYPE_KVM_ICP);
     ics = ICS_SIMPLE(object_new(TYPE_ICS_KVM));
     object_property_add_child(obj, "ics", OBJECT(ics), NULL);
     ics->xics = xics;
@@ -505,8 +477,8 @@  static void xics_kvm_class_init(ObjectClass *oc, void *data)
 
     dc->realize = xics_kvm_realize;
     xsc->cpu_setup = xics_kvm_cpu_setup;
-    xsc->set_nr_irqs = xics_kvm_set_nr_irqs;
-    xsc->set_nr_servers = xics_kvm_set_nr_servers;
+    xsc->set_nr_irqs = xics_set_nr_irqs;
+    xsc->set_nr_servers = xics_set_nr_servers;
 }
 
 static const TypeInfo xics_spapr_kvm_info = {
diff --git a/hw/intc/xics_native.c b/hw/intc/xics_native.c
index 26e45cc..db2fd4d 100644
--- a/hw/intc/xics_native.c
+++ b/hw/intc/xics_native.c
@@ -38,11 +38,19 @@ 
 /* #define DEBUG_MM(fmt...)      printf(fmt) */
 #define DEBUG_MM(fmt...)        do { } while (0)
 
+typedef struct XICSNative {
+    /*< private >*/
+    XICSState xics;
+
+    /*< public >*/
+    MemoryRegion icp_mmio;
+} XICSNative;
+
 static void xics_native_initfn(Object *obj)
 {
-    XICSState *xics = XICS_NATIVE(obj);
+    XICSState *xics = XICS_COMMON(obj);
 
-    QLIST_INIT(&xics->ics);
+    xics->ss_class = object_class_by_name(TYPE_NATIVE_ICP);
 }
 
 static uint64_t icp_mm_read(void *opaque, hwaddr addr, unsigned width)
@@ -51,6 +59,7 @@  static uint64_t icp_mm_read(void *opaque, hwaddr addr, unsigned width)
     int32_t cpu_id, server;
     uint32_t val;
     ICPState *ss;
+    ICPNative *icpn;
     bool byte0 = (width == 1 && (addr & 0x3) == 0);
 
     cpu_id = (addr & (ICP_MM_SIZE - 1)) >> 12;
@@ -59,7 +68,8 @@  static uint64_t icp_mm_read(void *opaque, hwaddr addr, unsigned width)
         fprintf(stderr, "XICS: Bad ICP server %d\n", server);
         goto bad_access;
     }
-    ss = &s->ss[server];
+    icpn = s->ss + server * sizeof(ICPNative);
+    ss = &icpn->icp;
 
     switch (addr & 0xffc) {
     case 0: /* poll */
@@ -88,21 +98,21 @@  static uint64_t icp_mm_read(void *opaque, hwaddr addr, unsigned width)
         break;
     case 16:
         if (width == 4) {
-            val = ss->links[0];
+            val = icpn->links[0];
         } else {
             goto bad_access;
         }
         break;
     case 20:
         if (width == 4) {
-            val = ss->links[1];
+            val = icpn->links[1];
         } else {
             goto bad_access;
         }
         break;
     case 24:
         if (width == 4) {
-            val = ss->links[2];
+            val = icpn->links[2];
         } else {
             goto bad_access;
         }
@@ -125,7 +135,7 @@  static void icp_mm_write(void *opaque, hwaddr addr, uint64_t val,
 {
     XICSState *s = opaque;
     int32_t cpu_id, server;
-    ICPState *ss;
+    ICPNative *icpn;
     bool byte0 = (width == 1 && (addr & 0x3) == 0);
 
     cpu_id = (addr & (ICP_MM_SIZE - 1)) >> 12;
@@ -134,7 +144,8 @@  static void icp_mm_write(void *opaque, hwaddr addr, uint64_t val,
         fprintf(stderr, "XICS: Bad ICP server %d\n", server);
         goto bad_access;
     }
-    ss = &s->ss[server];
+    icpn = s->ss + server * sizeof(ICPNative);
+    ss = &icpn->icp;
 
     DEBUG_MM("icp_mm_write(addr=%016llx,serv=0x%x/%d,off=%d,w=%d,val=0x%08x)\n",
              (unsigned long long)addr, cpu_id, server,
@@ -159,21 +170,21 @@  static void icp_mm_write(void *opaque, hwaddr addr, uint64_t val,
         break;
     case 16:
         if (width == 4) {
-            ss->links[0] = val;
+            icpn->links[0] = val;
         } else {
             goto bad_access;
         }
         break;
     case 20:
         if (width == 4) {
-            ss->links[1] = val;
+            icpn->links[1] = val;
         } else {
             goto bad_access;
         }
         break;
     case 24:
         if (width == 4) {
-            ss->links[2] = val;
+            icpn->links[2] = val;
         } else {
             goto bad_access;
         }
@@ -245,8 +256,9 @@  void xics_create_native_icp_node(XICSState *s, void *fdt,
 
 static void xics_native_realize(DeviceState *dev, Error **errp)
 {
-    XICSState *s = XICS_NATIVE(dev);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    XICSNative *n = XICS_NATIVE(dev);
+    XICSState *s = XICS_COMMON(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(s);
     Error *error = NULL;
     int i;
 
@@ -256,13 +268,14 @@  static void xics_native_realize(DeviceState *dev, Error **errp)
     }
 
     /* Register MMIO regions */
-    memory_region_init_io(&s->icp_mmio, OBJECT(s), &icp_mm_ops, s, "icp",
+    memory_region_init_io(&n->icp_mmio, OBJECT(s), &icp_mm_ops, s, "icp",
                           ICP_MM_SIZE);
-    sysbus_init_mmio(sbd, &s->icp_mmio);
+    sysbus_init_mmio(sbd, &n->icp_mmio);
     sysbus_mmio_map(sbd, 0, ICP_MM_BASE);
 
     for (i = 0; i < s->nr_servers; i++) {
-        object_property_set_bool(OBJECT(&s->ss[i]), true, "realized", &error);
+        ICPNative *icpn = s->ss + i * sizeof(ICPNative);
+        object_property_set_bool(OBJECT(icpn), true, "realized", &error);
         if (error) {
             error_propagate(errp, error);
             return;
@@ -272,20 +285,18 @@  static void xics_native_realize(DeviceState *dev, Error **errp)
 
 static void xics_native_class_init(ObjectClass *oc, void *data)
 {
-    DeviceClass *dc = DEVICE_CLASS(oc);
     XICSStateClass *xsc = XICS_NATIVE_CLASS(oc);
 
-    dc->realize = xics_native_realize;
+    xsc->realize = xics_native_realize;
     xsc->set_nr_servers = xics_set_nr_servers;
 }
 
 static const TypeInfo xics_native_info = {
     .name          = TYPE_XICS_NATIVE,
     .parent        = TYPE_XICS_COMMON,
-    .instance_size = sizeof(XICSState),
+    .instance_size = sizeof(XICSNative),
     .class_size = sizeof(XICSStateClass),
     .class_init    = xics_native_class_init,
-    .instance_init = xics_native_initfn,
 };
 
 static void xics_native_register_types(void)
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 4dd1399..0644942 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -67,7 +67,8 @@  static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                            target_ulong opcode, target_ulong *args)
 {
     CPUState *cs = CPU(cpu);
-    uint32_t xirr = icp_accept(spapr->xics->ss + cs->cpu_index);
+    uint32_t xirr = icp_accept(spapr->xics->ss +
+                               cs->cpu_index * sizeof(ICPState));
 
     args[0] = xirr;
     return H_SUCCESS;
@@ -77,9 +78,11 @@  static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                              target_ulong opcode, target_ulong *args)
 {
     CPUState *cs = CPU(cpu);
-    ICPState *ss = &spapr->xics->ss[cs->cpu_index];
-    uint32_t xirr = icp_accept(ss);
+    ICPState *ss;
+    uint32_t xirr;
 
+    ss = spapr->xics->ss + cs->cpu_index * sizeof(ICPState);
+    xirr = icp_accept(ss);
     args[0] = xirr;
     args[1] = cpu_get_host_ticks();
     return H_SUCCESS;
@@ -100,7 +103,8 @@  static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPRMachineState *spapr,
 {
     CPUState *cs = CPU(cpu);
     uint32_t mfrr;
-    uint32_t xirr = icp_ipoll(spapr->xics->ss + cs->cpu_index, &mfrr);
+    uint32_t xirr = icp_ipoll(spapr->xics->ss +
+                              cs->cpu_index * sizeof(ICPState), &mfrr);
 
     args[0] = xirr;
     args[1] = mfrr;
@@ -234,35 +238,6 @@  static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
 
-static void xics_spapr_set_nr_irqs(XICSState *xics, uint32_t nr_irqs,
-                                   Error **errp)
-{
-    ICSState *ics = QLIST_FIRST(&xics->ics);
-
-    /* This needs to be deprecated ... */
-    xics->nr_irqs = nr_irqs;
-    if (ics) {
-        ics->nr_irqs = nr_irqs;
-    }
-}
-
-static void xics_spapr_set_nr_servers(XICSState *xics, uint32_t nr_servers,
-                                      Error **errp)
-{
-    int i;
-
-    xics->nr_servers = nr_servers;
-
-    xics->ss = g_malloc0(xics->nr_servers * sizeof(ICPState));
-    for (i = 0; i < xics->nr_servers; i++) {
-        char buffer[32];
-        object_initialize(&xics->ss[i], sizeof(xics->ss[i]), TYPE_ICP);
-        snprintf(buffer, sizeof(buffer), "icp[%d]", i);
-        object_property_add_child(OBJECT(xics), buffer, OBJECT(&xics->ss[i]),
-                                  errp);
-    }
-}
-
 static void xics_spapr_realize(DeviceState *dev, Error **errp)
 {
     XICSState *xics = XICS_SPAPR(dev);
@@ -297,8 +272,8 @@  static void xics_spapr_realize(DeviceState *dev, Error **errp)
     }
 
     for (i = 0; i < xics->nr_servers; i++) {
-        object_property_set_bool(OBJECT(&xics->ss[i]), true, "realized",
-                                 &error);
+        ICPState *ss = xics->ss + i * sizeof(ICPState);
+        object_property_set_bool(OBJECT(ss), true, "realized", &error);
         if (error) {
             error_propagate(errp, error);
             return;
@@ -319,8 +294,8 @@  static void xics_spapr_class_init(ObjectClass *oc, void *data)
     XICSStateClass *xsc = XICS_SPAPR_CLASS(oc);
 
     dc->realize = xics_spapr_realize;
-    xsc->set_nr_irqs = xics_spapr_set_nr_irqs;
-    xsc->set_nr_servers = xics_spapr_set_nr_servers;
+    xsc->set_nr_irqs = xics_set_nr_irqs;
+    xsc->set_nr_servers = xics_set_nr_servers;
 }
 
 static const TypeInfo xics_spapr_info = {
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 58bb7c6..0a427d7 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -45,7 +45,7 @@ 
      OBJECT_CHECK(KVMXICSState, (obj), TYPE_XICS_SPAPR_KVM)
 
 #define TYPE_XICS_NATIVE "xics-native"
-#define XICS_NATIVE(obj) OBJECT_CHECK(XICSState, (obj), TYPE_XICS_NATIVE)
+#define XICS_NATIVE(obj) OBJECT_CHECK(XICSNative, (obj), TYPE_XICS_NATIVE)
 
 #define XICS_COMMON_CLASS(klass) \
      OBJECT_CLASS_CHECK(XICSStateClass, (klass), TYPE_XICS_COMMON)
@@ -71,6 +71,7 @@  typedef struct XICSStateClass XICSStateClass;
 typedef struct XICSState XICSState;
 typedef struct ICPStateClass ICPStateClass;
 typedef struct ICPState ICPState;
+typedef struct ICPNative ICPNative;
 typedef struct ICSStateClass ICSStateClass;
 typedef struct ICSState ICSState;
 typedef struct ICSIRQState ICSIRQState;
@@ -78,6 +79,7 @@  typedef struct ICSIRQState ICSIRQState;
 struct XICSStateClass {
     DeviceClass parent_class;
 
+    DeviceRealize realize;
     void (*cpu_setup)(XICSState *icp, PowerPCCPU *cpu);
     void (*set_nr_irqs)(XICSState *icp, uint32_t nr_irqs, Error **errp);
     void (*set_nr_servers)(XICSState *icp, uint32_t nr_servers, Error **errp);
@@ -89,9 +91,9 @@  struct XICSState {
     /*< public >*/
     uint32_t nr_servers;
     uint32_t nr_irqs;
-    ICPState *ss;
+    void *ss;
+    ObjectClass *ss_class;
     QLIST_HEAD(, ICSState) ics;
-    MemoryRegion icp_mmio;
 };
 
 #define TYPE_ICP "icp"
@@ -100,6 +102,9 @@  struct XICSState {
 #define TYPE_KVM_ICP "icp-kvm"
 #define KVM_ICP(obj) OBJECT_CHECK(ICPState, (obj), TYPE_KVM_ICP)
 
+#define TYPE_NATIVE_ICP "icp-native"
+#define NATIVE_ICP(obj) OBJECT_CHECK(ICPNative, (obj), TYPE_NATIVE_ICP)
+
 #define ICP_CLASS(klass) \
      OBJECT_CLASS_CHECK(ICPStateClass, (klass), TYPE_ICP)
 #define ICP_GET_CLASS(obj) \
@@ -123,6 +128,12 @@  struct ICPState {
     uint8_t mfrr;
     qemu_irq output;
     bool cap_irq_xics_enabled;
+};
+
+struct ICPNative {
+    /*<private>*/
+    ICPState icp;
+    /*<public>*/
     uint32_t links[3];
 };
 
@@ -199,6 +210,8 @@  void xics_spapr_free(XICSState *icp, int irq, int num);
 
 void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu);
 void xics_cpu_destroy(XICSState *icp, PowerPCCPU *cpu);
+void xics_set_nr_irqs(XICSState *xics, uint32_t nr_irqs, Error **errp);
+void xics_set_nr_servers(XICSState *xics, uint32_t nr_servers, Error **errp);
 
 void xics_create_native_icp_node(XICSState *s, void *fdt,
                                  uint32_t base, uint32_t count);