diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2018-07-03 14:59:27 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2018-07-03 14:59:27 +0100 |
| commit | b07cd3e748b3f27a17c27afeee578dc4eedb8dd5 (patch) | |
| tree | c7a6d5ea8459801bcc120b30958397824b8453f3 /hw/intc/xics.c | |
| parent | a395717cbd26e7593d3c3fe81faca121ec6d13e8 (diff) | |
| parent | 29f9cef39eb1ae55e82c6763eb22d7a1bdff7276 (diff) | |
| download | focaccia-qemu-b07cd3e748b3f27a17c27afeee578dc4eedb8dd5.tar.gz focaccia-qemu-b07cd3e748b3f27a17c27afeee578dc4eedb8dd5.zip | |
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-3.0-20180703' into staging
ppc patch queue 2018-07-03
Here's a last minue pull request before today's soft freeze. Ideally
I would have sent this earlier, but I was waiting for a couple of
extra fixes I knew were close. And the freeze crept up on me, like
always.
Most of the changes here are bugfixes in any case. There are some
cleanups as well, which have been in my staging tree for a little
while. There are a couple of truly new features (some extensions to
the sam460ex platform), but these are low risk, since they only affect
a new and not really stabilized machine type anyway.
Higlights are:
* Mac platform improvements from Mark Cave-Ayland
* Sam460ex improvements from BALATON Zoltan et al.
* XICS interrupt handler cleanups from Cédric Le Goater
* TCG improvements for atomic loads and stores from Richard
Henderson
* Assorted other bugfixes
# gpg: Signature made Tue 03 Jul 2018 06:55:22 BST
# gpg: using RSA key 6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>"
# gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>"
# gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>"
# gpg: aka "David Gibson (kernel.org) <dwg@kernel.org>"
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392
* remotes/dgibson/tags/ppc-for-3.0-20180703: (35 commits)
ppc: Include vga cirrus card into the compiling process
target/ppc: Relax reserved bitmask of indexed store instructions
target/ppc: set is_jmp on ppc_tr_breakpoint_check
spapr: compute default value of "hpt-max-page-size" later
target/ppc/kvm: don't pass cpu to kvm_get_smmu_info()
target/ppc/kvm: get rid of kvm_get_fallback_smmu_info()
ppc440_uc: Basic emulation of PPC440 DMA controller
sam460ex: Add RTC device
hw/timer: Add basic M41T80 emulation
ppc4xx_i2c: Rewrite to model hardware more closely
hw/ppc: Give sam46ex its own config option
fpu_helper.c: fix setting FPSCR[FI] bit
target/ppc: Implement the rest of gen_st_atomic
target/ppc: Implement the rest of gen_ld_atomic
target/ppc: Use atomic min/max helpers
target/ppc: Use MO_ALIGN for EXIWX and ECOWX
target/ppc: Split out gen_st_atomic
target/ppc: Split out gen_ld_atomic
target/ppc: Split out gen_load_locked
target/ppc: Tidy gen_conditional_store
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
# Conflicts:
# hw/ppc/spapr.c
Diffstat (limited to 'hw/intc/xics.c')
| -rw-r--r-- | hw/intc/xics.c | 174 |
1 files changed, 93 insertions, 81 deletions
diff --git a/hw/intc/xics.c b/hw/intc/xics.c index e73e623e3b..b9f1a3c972 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -294,7 +294,6 @@ static const VMStateDescription vmstate_icp_server = { static void icp_reset(void *dev) { ICPState *icp = ICP(dev); - ICPStateClass *icpc = ICP_GET_CLASS(icp); icp->xirr = 0; icp->pending_priority = 0xff; @@ -302,16 +301,11 @@ static void icp_reset(void *dev) /* Make all outputs are deasserted */ qemu_set_irq(icp->output, 0); - - if (icpc->reset) { - icpc->reset(icp); - } } static void icp_realize(DeviceState *dev, Error **errp) { ICPState *icp = ICP(dev); - ICPStateClass *icpc = ICP_GET_CLASS(dev); PowerPCCPU *cpu; CPUPPCState *env; Object *obj; @@ -351,10 +345,6 @@ static void icp_realize(DeviceState *dev, Error **errp) return; } - if (icpc->realize) { - icpc->realize(icp, errp); - } - qemu_register_reset(icp_reset, dev); vmstate_register(NULL, icp->cs->cpu_index, &vmstate_icp_server, icp); } @@ -547,9 +537,61 @@ static void ics_simple_eoi(ICSState *ics, uint32_t nr) } } -static void ics_simple_reset(void *dev) +static void ics_simple_reset(DeviceState *dev) +{ + ICSStateClass *icsc = ICS_BASE_GET_CLASS(dev); + + icsc->parent_reset(dev); +} + +static void ics_simple_reset_handler(void *dev) +{ + ics_simple_reset(dev); +} + +static void ics_simple_realize(DeviceState *dev, Error **errp) { ICSState *ics = ICS_SIMPLE(dev); + ICSStateClass *icsc = ICS_BASE_GET_CLASS(ics); + Error *local_err = NULL; + + icsc->parent_realize(dev, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + ics->qirqs = qemu_allocate_irqs(ics_simple_set_irq, ics, ics->nr_irqs); + + qemu_register_reset(ics_simple_reset_handler, ics); +} + +static void ics_simple_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + ICSStateClass *isc = ICS_BASE_CLASS(klass); + + device_class_set_parent_realize(dc, ics_simple_realize, + &isc->parent_realize); + device_class_set_parent_reset(dc, ics_simple_reset, + &isc->parent_reset); + + isc->reject = ics_simple_reject; + isc->resend = ics_simple_resend; + isc->eoi = ics_simple_eoi; +} + +static const TypeInfo ics_simple_info = { + .name = TYPE_ICS_SIMPLE, + .parent = TYPE_ICS_BASE, + .instance_size = sizeof(ICSState), + .class_init = ics_simple_class_init, + .class_size = sizeof(ICSStateClass), +}; + +static void ics_base_reset(DeviceState *dev) +{ + ICSState *ics = ICS_BASE(dev); int i; uint8_t flags[ics->nr_irqs]; @@ -566,7 +608,35 @@ static void ics_simple_reset(void *dev) } } -static int ics_simple_dispatch_pre_save(void *opaque) +static void ics_base_realize(DeviceState *dev, Error **errp) +{ + ICSState *ics = ICS_BASE(dev); + Object *obj; + Error *err = NULL; + + obj = object_property_get_link(OBJECT(dev), ICS_PROP_XICS, &err); + if (!obj) { + error_propagate(errp, err); + error_prepend(errp, "required link '" ICS_PROP_XICS "' not found: "); + return; + } + ics->xics = XICS_FABRIC(obj); + + if (!ics->nr_irqs) { + error_setg(errp, "Number of interrupts needs to be greater 0"); + return; + } + ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState)); +} + +static void ics_base_instance_init(Object *obj) +{ + ICSState *ics = ICS_BASE(obj); + + ics->offset = XICS_IRQ_BASE; +} + +static int ics_base_dispatch_pre_save(void *opaque) { ICSState *ics = opaque; ICSStateClass *info = ICS_BASE_GET_CLASS(ics); @@ -578,7 +648,7 @@ static int ics_simple_dispatch_pre_save(void *opaque) return 0; } -static int ics_simple_dispatch_post_load(void *opaque, int version_id) +static int ics_base_dispatch_post_load(void *opaque, int version_id) { ICSState *ics = opaque; ICSStateClass *info = ICS_BASE_GET_CLASS(ics); @@ -590,7 +660,7 @@ static int ics_simple_dispatch_post_load(void *opaque, int version_id) return 0; } -static const VMStateDescription vmstate_ics_simple_irq = { +static const VMStateDescription vmstate_ics_base_irq = { .name = "ics/irq", .version_id = 2, .minimum_version_id = 1, @@ -604,95 +674,36 @@ static const VMStateDescription vmstate_ics_simple_irq = { }, }; -static const VMStateDescription vmstate_ics_simple = { +static const VMStateDescription vmstate_ics_base = { .name = "ics", .version_id = 1, .minimum_version_id = 1, - .pre_save = ics_simple_dispatch_pre_save, - .post_load = ics_simple_dispatch_post_load, + .pre_save = ics_base_dispatch_pre_save, + .post_load = ics_base_dispatch_post_load, .fields = (VMStateField[]) { /* Sanity check */ VMSTATE_UINT32_EQUAL(nr_irqs, ICSState, NULL), VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs, ICSState, nr_irqs, - vmstate_ics_simple_irq, + vmstate_ics_base_irq, ICSIRQState), VMSTATE_END_OF_LIST() }, }; -static void ics_simple_initfn(Object *obj) -{ - ICSState *ics = ICS_SIMPLE(obj); - - ics->offset = XICS_IRQ_BASE; -} - -static void ics_simple_realize(ICSState *ics, Error **errp) -{ - if (!ics->nr_irqs) { - error_setg(errp, "Number of interrupts needs to be greater 0"); - return; - } - ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState)); - ics->qirqs = qemu_allocate_irqs(ics_simple_set_irq, ics, ics->nr_irqs); - - qemu_register_reset(ics_simple_reset, ics); -} - -static Property ics_simple_properties[] = { +static Property ics_base_properties[] = { DEFINE_PROP_UINT32("nr-irqs", ICSState, nr_irqs, 0), DEFINE_PROP_END_OF_LIST(), }; -static void ics_simple_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - ICSStateClass *isc = ICS_BASE_CLASS(klass); - - isc->realize = ics_simple_realize; - dc->props = ics_simple_properties; - dc->vmsd = &vmstate_ics_simple; - isc->reject = ics_simple_reject; - isc->resend = ics_simple_resend; - isc->eoi = ics_simple_eoi; -} - -static const TypeInfo ics_simple_info = { - .name = TYPE_ICS_SIMPLE, - .parent = TYPE_ICS_BASE, - .instance_size = sizeof(ICSState), - .class_init = ics_simple_class_init, - .class_size = sizeof(ICSStateClass), - .instance_init = ics_simple_initfn, -}; - -static void ics_base_realize(DeviceState *dev, Error **errp) -{ - ICSStateClass *icsc = ICS_BASE_GET_CLASS(dev); - ICSState *ics = ICS_BASE(dev); - Object *obj; - Error *err = NULL; - - obj = object_property_get_link(OBJECT(dev), ICS_PROP_XICS, &err); - if (!obj) { - error_propagate(errp, err); - error_prepend(errp, "required link '" ICS_PROP_XICS "' not found: "); - return; - } - ics->xics = XICS_FABRIC(obj); - - - if (icsc->realize) { - icsc->realize(ics, errp); - } -} - static void ics_base_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = ics_base_realize; + dc->props = ics_base_properties; + dc->reset = ics_base_reset; + dc->vmsd = &vmstate_ics_base; } static const TypeInfo ics_base_info = { @@ -700,6 +711,7 @@ static const TypeInfo ics_base_info = { .parent = TYPE_DEVICE, .abstract = true, .instance_size = sizeof(ICSState), + .instance_init = ics_base_instance_init, .class_init = ics_base_class_init, .class_size = sizeof(ICSStateClass), }; |