mirror of https://github.com/xemu-project/xemu.git
hw/isa/vt82c686: Route PIRQ inputs using via_isa_set_irq()
The chip has 4 pins (called PIRQA-D in VT82C686B and PINTA-D in
VT8231) that are meant to be connected to PCI IRQ lines and allow
routing PCI interrupts to the ISA PIC. Route these in
via_isa_set_irq() to make it possible to share them with internal
functions that can also be routed to the same ISA IRQs.
Fixes: 2fdadd02e6
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Message-ID: <8c4513d8b78fac40e6d4e65a0a4b3a7f2f278a4b.1701035944.git.balaton@eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
This commit is contained in:
parent
032a443be6
commit
01f13ee245
|
@ -593,6 +593,21 @@ static const TypeInfo via_isa_info = {
|
|||
},
|
||||
};
|
||||
|
||||
static int via_isa_get_pci_irq(const ViaISAState *s, int pin)
|
||||
{
|
||||
switch (pin) {
|
||||
case 0:
|
||||
return s->dev.config[0x55] >> 4;
|
||||
case 1:
|
||||
return s->dev.config[0x56] & 0xf;
|
||||
case 2:
|
||||
return s->dev.config[0x56] >> 4;
|
||||
case 3:
|
||||
return s->dev.config[0x57] >> 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void via_isa_set_irq(PCIDevice *d, int pin, int level)
|
||||
{
|
||||
ViaISAState *s = VIA_ISA(pci_get_function_0(d));
|
||||
|
@ -601,6 +616,10 @@ void via_isa_set_irq(PCIDevice *d, int pin, int level)
|
|||
uint16_t mask = BIT(f);
|
||||
|
||||
switch (f) {
|
||||
case 0: /* PIRQ/PINT inputs */
|
||||
irq = via_isa_get_pci_irq(s, pin);
|
||||
f = 8 + pin; /* Use function 8-11 for PCI interrupt inputs */
|
||||
break;
|
||||
case 2: /* USB ports 0-1 */
|
||||
case 3: /* USB ports 2-3 */
|
||||
max_irq = 14;
|
||||
|
@ -633,52 +652,17 @@ void via_isa_set_irq(PCIDevice *d, int pin, int level)
|
|||
qemu_set_irq(s->isa_irqs_in[irq], !!s->irq_state[irq]);
|
||||
}
|
||||
|
||||
static void via_isa_pirq(void *opaque, int pin, int level)
|
||||
{
|
||||
via_isa_set_irq(opaque, pin, level);
|
||||
}
|
||||
|
||||
static void via_isa_request_i8259_irq(void *opaque, int irq, int level)
|
||||
{
|
||||
ViaISAState *s = opaque;
|
||||
qemu_set_irq(s->cpu_intr, level);
|
||||
}
|
||||
|
||||
static int via_isa_get_pci_irq(const ViaISAState *s, int irq_num)
|
||||
{
|
||||
switch (irq_num) {
|
||||
case 0:
|
||||
return s->dev.config[0x55] >> 4;
|
||||
case 1:
|
||||
return s->dev.config[0x56] & 0xf;
|
||||
case 2:
|
||||
return s->dev.config[0x56] >> 4;
|
||||
case 3:
|
||||
return s->dev.config[0x57] >> 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void via_isa_set_pci_irq(void *opaque, int irq_num, int level)
|
||||
{
|
||||
ViaISAState *s = opaque;
|
||||
PCIBus *bus = pci_get_bus(&s->dev);
|
||||
int i, pic_level, pic_irq = via_isa_get_pci_irq(s, irq_num);
|
||||
|
||||
/* IRQ 0: disabled, IRQ 2,8,13: reserved */
|
||||
if (!pic_irq) {
|
||||
return;
|
||||
}
|
||||
if (unlikely(pic_irq == 2 || pic_irq == 8 || pic_irq == 13)) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "Invalid ISA IRQ routing");
|
||||
}
|
||||
|
||||
/* The pic level is the logical OR of all the PCI irqs mapped to it. */
|
||||
pic_level = 0;
|
||||
for (i = 0; i < PCI_NUM_PINS; i++) {
|
||||
if (pic_irq == via_isa_get_pci_irq(s, i)) {
|
||||
pic_level |= pci_bus_get_irq_level(bus, i);
|
||||
}
|
||||
}
|
||||
/* Now we change the pic irq level according to the via irq mappings. */
|
||||
qemu_set_irq(s->isa_irqs_in[pic_irq], pic_level);
|
||||
}
|
||||
|
||||
static void via_isa_realize(PCIDevice *d, Error **errp)
|
||||
{
|
||||
ViaISAState *s = VIA_ISA(d);
|
||||
|
@ -689,6 +673,7 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
|
|||
int i;
|
||||
|
||||
qdev_init_gpio_out(dev, &s->cpu_intr, 1);
|
||||
qdev_init_gpio_in_named(dev, via_isa_pirq, "pirq", PCI_NUM_PINS);
|
||||
isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
|
||||
isa_bus = isa_bus_new(dev, pci_address_space(d), pci_address_space_io(d),
|
||||
errp);
|
||||
|
@ -702,8 +687,6 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
|
|||
i8254_pit_init(isa_bus, 0x40, 0, NULL);
|
||||
i8257_dma_init(isa_bus, 0);
|
||||
|
||||
qdev_init_gpio_in_named(dev, via_isa_set_pci_irq, "pirq", PCI_NUM_PINS);
|
||||
|
||||
/* RTC */
|
||||
qdev_prop_set_int32(DEVICE(&s->rtc), "base_year", 2000);
|
||||
if (!qdev_realize(DEVICE(&s->rtc), BUS(isa_bus), errp)) {
|
||||
|
|
Loading…
Reference in New Issue