Get this duplicate code in the base implementation. Signed-off-by: Nikunj A Dadhania <nik...@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; +} + +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); -- 2.7.4