From: Scott Wood Date: Mon, 21 Jan 2013 15:53:51 +0000 (+0000) Subject: openpic: fix remaining issues from idr-to-destmask conversion X-Git-Tag: v1.4.0-rc0~82^2~4 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=f40c360c0da020a1a478f8e60dd205d7412bc315;p=qemu.git openpic: fix remaining issues from idr-to-destmask conversion openpic_update_irq() was checking idr rather than destmask, treating it as if it were a simple bitmap of cpus. Changed to use destmask. IPI delivery was removing bits directly from .idr, without calling write_IRQreg_idr so that the change could be conveyed to destmask. Changed to use destmask directly. Save/restore destmask when serializing, as due to the IPI change it cannot be reproduced from idr. Signed-off-by: Scott Wood Signed-off-by: Alexander Graf --- diff --git a/hw/openpic.c b/hw/openpic.c index 25aa9bf45..a4488c2d4 100644 --- a/hw/openpic.c +++ b/hw/openpic.c @@ -436,13 +436,13 @@ static void openpic_update_irq(OpenPICState *opp, int n_IRQ) src->ivpr &= ~IVPR_ACTIVITY_MASK; } - if (src->idr == 0) { + if (src->destmask == 0) { /* No target */ DPRINTF("%s: IRQ %d has no target\n", __func__, n_IRQ); return; } - if (src->idr == (1 << src->last_cpu)) { + if (src->destmask == (1 << src->last_cpu)) { /* Only one CPU is allowed to receive this IRQ */ IRQ_local_pipe(opp, src->last_cpu, n_IRQ, active, was_active); } else if (!(src->ivpr & IVPR_MODE_MASK)) { @@ -1000,8 +1000,7 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr, case 0x70: idx = (addr - 0x40) >> 4; /* we use IDE as mask which CPUs to deliver the IPI to still. */ - write_IRQreg_idr(opp, opp->irq_ipi0 + idx, - opp->src[opp->irq_ipi0 + idx].idr | val); + opp->src[opp->irq_ipi0 + idx].destmask |= val; openpic_set_irq(opp, opp->irq_ipi0 + idx, 1); openpic_set_irq(opp, opp->irq_ipi0 + idx, 0); break; @@ -1101,8 +1100,8 @@ static uint32_t openpic_iack(OpenPICState *opp, IRQDest *dst, int cpu) } if ((irq >= opp->irq_ipi0) && (irq < (opp->irq_ipi0 + MAX_IPI))) { - src->idr &= ~(1 << cpu); - if (src->idr && !src->level) { + src->destmask &= ~(1 << cpu); + if (src->destmask && !src->level) { /* trigger on CPUs that didn't know about it yet */ openpic_set_irq(opp, irq, 1); openpic_set_irq(opp, irq, 0); @@ -1307,6 +1306,7 @@ static void openpic_save(QEMUFile* f, void *opaque) for (i = 0; i < opp->max_irq; i++) { qemu_put_be32s(f, &opp->src[i].ivpr); qemu_put_be32s(f, &opp->src[i].idr); + qemu_get_be32s(f, &opp->src[i].destmask); qemu_put_sbe32s(f, &opp->src[i].last_cpu); qemu_put_sbe32s(f, &opp->src[i].pending); } @@ -1372,6 +1372,7 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id) qemu_get_be32s(f, &opp->src[i].ivpr); qemu_get_be32s(f, &opp->src[i].idr); + qemu_get_be32s(f, &opp->src[i].destmask); qemu_get_sbe32s(f, &opp->src[i].last_cpu); qemu_get_sbe32s(f, &opp->src[i].pending); }