Message ID | 4D591085.9020906@redhat.com |
---|---|
State | New |
Headers | show |
Gerd Hoffmann wrote: > On 02/08/11 00:26, Alexander Graf wrote: >> The new ISA infrastructure checks for potential irq sharing bugs on >> interrupt lines, because usually irq lines on isa can't be shared. >> >> The PREP spec however mandates that the irq lines for both IDE ports >> are shared and according to Aurelien this also used to work just fine. >> >> So let's add a way to enable this sharing again, so we don't introduce >> unnecessary regressions over older versions of Qemu. > > Had a patch for that, got shoot down for reasons I don't remember, > attached for reference. It basically allows IRQ sharing in case the > two devices sharing the IRQ are of the same kind. In that case you > usually have a single guest driver handling both devices and IRQ > sharing works most of the time. > > I don't mind much which approach we take ... I'm very indifferent myself :). This is not an issue we should waste too much time/effort on. Alex
On 2011-02-14 12:22, Gerd Hoffmann wrote: > On 02/08/11 00:26, Alexander Graf wrote: >> The new ISA infrastructure checks for potential irq sharing bugs on >> interrupt lines, because usually irq lines on isa can't be shared. >> >> The PREP spec however mandates that the irq lines for both IDE ports >> are shared and according to Aurelien this also used to work just fine. >> >> So let's add a way to enable this sharing again, so we don't introduce >> unnecessary regressions over older versions of Qemu. > > Had a patch for that, got shoot down for reasons I don't remember, > attached for reference. It basically allows IRQ sharing in case the two > devices sharing the IRQ are of the same kind. In that case you usually > have a single guest driver handling both devices and IRQ sharing works > most of the time. Yeah, 3x -serial XXX is also broken for x86 targets as the third device shares its IRQ with the first - like on real HW... Jan
diff --git a/hw/isa-bus.c b/hw/isa-bus.c index 4e306de..a99e793 100644 --- a/hw/isa-bus.c +++ b/hw/isa-bus.c @@ -26,6 +26,7 @@ struct ISABus { BusState qbus; qemu_irq *irqs; uint32_t assigned; + DeviceInfo *irq_owner[16]; }; static ISABus *isabus; target_phys_addr_t isa_mem_base = 0; @@ -72,7 +73,9 @@ qemu_irq isa_reserve_irq(int isairq) exit(1); } if (isabus->assigned & (1 << isairq)) { - fprintf(stderr, "isa irq %d already assigned\n", isairq); + DeviceInfo *owner = isabus->irq_owner[isairq]; + fprintf(stderr, "isa irq %d already assigned (%s)\n", + isairq, owner ? owner->name : "unknown"); exit(1); } isabus->assigned |= (1 << isairq); @@ -83,10 +86,17 @@ void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq) { assert(dev->nirqs < ARRAY_SIZE(dev->isairq)); if (isabus->assigned & (1 << isairq)) { - fprintf(stderr, "isa irq %d already assigned\n", isairq); - exit(1); + DeviceInfo *owner = isabus->irq_owner[isairq]; + if (owner == dev->qdev.info) { + /* irq sharing is ok in case the same driver handles both */; + } else { + fprintf(stderr, "isa irq %d already assigned (%s)\n", + isairq, owner ? owner->name : "unknown"); + exit(1); + } } isabus->assigned |= (1 << isairq); + isabus->irq_owner[isairq] = dev->qdev.info; dev->isairq[dev->nirqs] = isairq; *p = isabus->irqs[isairq]; dev->nirqs++;