Message ID | 1474266577-11704-10-git-send-email-nikunj@linux.vnet.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
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 --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);
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(-)