Skip to content

Commit

Permalink
hw/isa/vt82c686: Bring back via_isa_set_irq()
Browse files Browse the repository at this point in the history
The VIA integrated south bridge chips combine several functions and
allow routing their interrupts to any of the ISA IRQs also allowing
multiple sources to share the same ISA IRQ. E.g. pegasos2 firmware
configures everything to use IRQ 9 but amigaone routes them to
separate ISA IRQs so the current simplified routing does not work.
Bring back via_isa_set_irq() and change it to take the component that
wants to change an IRQ and keep track of interrupt status of each
source separately and do the mapping to ISA IRQ within the ISA bridge.

This may not handle cases when an ISA IRQ is controlled by devices
directly, not going through via_isa_set_irq() such as serial, parallel
or keyboard but these IRQs being conventionally fixed are not likely
to be change by guests or share with other devices so this does not
cause a problem in practice.

This reverts commit 4e5a20b.

Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Message-ID: <1c3902d4166234bef0a476026441eaac3dd6cda5.1701035944.git.balaton@eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
  • Loading branch information
zbalaton authored and philmd committed Nov 28, 2023
1 parent 57c3150 commit 7e01bd8
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
41 changes: 41 additions & 0 deletions hw/isa/vt82c686.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,7 @@ struct ViaISAState {
PCIDevice dev;
qemu_irq cpu_intr;
qemu_irq *isa_irqs_in;
uint16_t irq_state[ISA_NUM_IRQS];
ViaSuperIOState via_sio;
MC146818RtcState rtc;
PCIIDEState ide;
Expand Down Expand Up @@ -592,6 +593,46 @@ static const TypeInfo via_isa_info = {
},
};

void via_isa_set_irq(PCIDevice *d, int pin, int level)
{
ViaISAState *s = VIA_ISA(pci_get_function_0(d));
uint8_t irq = d->config[PCI_INTERRUPT_LINE], max_irq = 15;
int f = PCI_FUNC(d->devfn);
uint16_t mask = BIT(f);

switch (f) {
case 2: /* USB ports 0-1 */
case 3: /* USB ports 2-3 */
max_irq = 14;
break;
}

/* Keep track of the state of all sources */
if (level) {
s->irq_state[0] |= mask;
} else {
s->irq_state[0] &= ~mask;
}
if (irq == 0 || irq == 0xff) {
return; /* disabled */
}
if (unlikely(irq > max_irq || irq == 2)) {
qemu_log_mask(LOG_GUEST_ERROR, "Invalid ISA IRQ routing %d for %d",
irq, f);
return;
}
/* Record source state at mapped IRQ */
if (level) {
s->irq_state[irq] |= mask;
} else {
s->irq_state[irq] &= ~mask;
}
/* Make sure there are no stuck bits if mapping has changed */
s->irq_state[irq] &= s->irq_state[0];
/* ISA IRQ level is the OR of all sources routed to it */
qemu_set_irq(s->isa_irqs_in[irq], !!s->irq_state[irq]);
}

static void via_isa_request_i8259_irq(void *opaque, int irq, int level)
{
ViaISAState *s = opaque;
Expand Down
2 changes: 2 additions & 0 deletions include/hw/isa/vt82c686.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,6 @@ struct ViaAC97State {
uint32_t ac97_cmd;
};

void via_isa_set_irq(PCIDevice *d, int n, int level);

#endif

0 comments on commit 7e01bd8

Please sign in to comment.