diff mbox series

[02/13] hw/ide/via: Implement ISA IRQ routing

Message ID 20230422150728.176512-3-shentey@gmail.com (mailing list archive)
State New, archived
Headers show
Series Clean up PCI IDE device models | expand

Commit Message

Bernhard Beschow April 22, 2023, 3:07 p.m. UTC
The VIA south bridge allows the legacy IDE interrupts to be routed to four
different ISA interrupts. This can be configured through the 0x4a register in
the PCI configuration space of the ISA function. The default routing matches
the legacy ISA IRQs, that is 14 and 15.

Implement this missing piece of the VIA south bridge.

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
 hw/ide/via.c      |  6 ++++--
 hw/isa/vt82c686.c | 17 +++++++++++++++++
 2 files changed, 21 insertions(+), 2 deletions(-)

Comments

BALATON Zoltan April 22, 2023, 5:23 p.m. UTC | #1
On Sat, 22 Apr 2023, Bernhard Beschow wrote:
> The VIA south bridge allows the legacy IDE interrupts to be routed to four
> different ISA interrupts. This can be configured through the 0x4a register in
> the PCI configuration space of the ISA function. The default routing matches
> the legacy ISA IRQs, that is 14 and 15.

On VT8231 0x4a is PCI Master Arbitration Control, IDE interrupt Routing is 
0x4c and only documents 14/15 as valid values. Not sure any guest would 
actually change this or 0x4a and if that could cause problems but you may 
need to handle this somehow. (Apart from testing with MorphOS with -kernel 
you should really be testing with pegasos2.rom with MorphOS and Linux, 
e.g. Debian 8.11 netinstall iso is known to boot.)

Regards,
BALATON Zoltan

> Implement this missing piece of the VIA south bridge.
>
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
> hw/ide/via.c      |  6 ++++--
> hw/isa/vt82c686.c | 17 +++++++++++++++++
> 2 files changed, 21 insertions(+), 2 deletions(-)
>
> diff --git a/hw/ide/via.c b/hw/ide/via.c
> index 177baea9a7..0caae52276 100644
> --- a/hw/ide/via.c
> +++ b/hw/ide/via.c
> @@ -31,6 +31,7 @@
> #include "sysemu/dma.h"
> #include "hw/isa/vt82c686.h"
> #include "hw/ide/pci.h"
> +#include "hw/irq.h"
> #include "trace.h"
>
> static uint64_t bmdma_read(void *opaque, hwaddr addr,
> @@ -104,7 +105,8 @@ static void bmdma_setup_bar(PCIIDEState *d)
>
> static void via_ide_set_irq(void *opaque, int n, int level)
> {
> -    PCIDevice *d = PCI_DEVICE(opaque);
> +    PCIIDEState *s = opaque;
> +    PCIDevice *d = PCI_DEVICE(s);
>
>     if (level) {
>         d->config[0x70 + n * 8] |= 0x80;
> @@ -112,7 +114,7 @@ static void via_ide_set_irq(void *opaque, int n, int level)
>         d->config[0x70 + n * 8] &= ~0x80;
>     }
>
> -    via_isa_set_irq(pci_get_function_0(d), 14 + n, level);
> +    qemu_set_irq(s->isa_irq[n], level);
> }
>
> static void via_ide_reset(DeviceState *dev)
> diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
> index ca89119ce0..c7e29bb46a 100644
> --- a/hw/isa/vt82c686.c
> +++ b/hw/isa/vt82c686.c
> @@ -568,9 +568,19 @@ static const VMStateDescription vmstate_via = {
>     }
> };
>
> +static void via_isa_set_ide_irq(void *opaque, int n, int level)
> +{
> +    static const uint8_t irqs[] = { 14, 15, 10, 11 };
> +    ViaISAState *s = opaque;
> +    uint8_t irq = irqs[(s->dev.config[0x4a] >> (n * 2)) & 0x3];
> +
> +    qemu_set_irq(s->isa_irqs_in[irq], level);
> +}
> +
> static void via_isa_init(Object *obj)
> {
>     ViaISAState *s = VIA_ISA(obj);
> +    DeviceState *dev = DEVICE(s);
>
>     object_initialize_child(obj, "rtc", &s->rtc, TYPE_MC146818_RTC);
>     object_initialize_child(obj, "ide", &s->ide, TYPE_VIA_IDE);
> @@ -578,6 +588,8 @@ static void via_isa_init(Object *obj)
>     object_initialize_child(obj, "uhci2", &s->uhci[1], TYPE_VT82C686B_USB_UHCI);
>     object_initialize_child(obj, "ac97", &s->ac97, TYPE_VIA_AC97);
>     object_initialize_child(obj, "mc97", &s->mc97, TYPE_VIA_MC97);
> +
> +    qdev_init_gpio_in_named(dev, via_isa_set_ide_irq, "ide", ARRAY_SIZE(s->ide.isa_irq));
> }
>
> static const TypeInfo via_isa_info = {
> @@ -692,6 +704,10 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
>     if (!qdev_realize(DEVICE(&s->ide), BUS(pci_bus), errp)) {
>         return;
>     }
> +    for (i = 0; i < 2; i++) {
> +        qdev_connect_gpio_out(DEVICE(&s->ide), i,
> +                              qdev_get_gpio_in_named(DEVICE(s), "ide", i));
> +    }
>
>     /* Functions 2-3: USB Ports */
>     for (i = 0; i < ARRAY_SIZE(s->uhci); i++) {
> @@ -814,6 +830,7 @@ static void vt8231_isa_reset(DeviceState *dev)
>                  PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL);
>     pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
>
> +    pci_conf[0x4a] = 0x04; /* IDE interrupt Routing */
>     pci_conf[0x58] = 0x40; /* Miscellaneous Control 0 */
>     pci_conf[0x67] = 0x08; /* Fast IR Config */
>     pci_conf[0x6b] = 0x01; /* Fast IR I/O Base */
>
Bernhard Beschow April 22, 2023, 6:47 p.m. UTC | #2
Am 22. April 2023 17:23:56 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>On Sat, 22 Apr 2023, Bernhard Beschow wrote:
>> The VIA south bridge allows the legacy IDE interrupts to be routed to four
>> different ISA interrupts. This can be configured through the 0x4a register in
>> the PCI configuration space of the ISA function. The default routing matches
>> the legacy ISA IRQs, that is 14 and 15.
>
>On VT8231 0x4a is PCI Master Arbitration Control, IDE interrupt Routing is 0x4c and only documents 14/15 as valid values.

In the datasheet titled "VT8231 South Bridge", preliminary revision 0.8, Oct. 29, 1999, page 60, the "IDE Interrupt Routing" register is located at offset 0x4a and offers the same four interrupts in the same order as in the code. Are we looking at the same datasheet?

>Not sure any guest would actually change this or 0x4a and if that could cause problems but you may need to handle this somehow. (Apart from testing with MorphOS with -kernel you should really be testing with pegasos2.rom with MorphOS and Linux, e.g. Debian 8.11 netinstall iso is known to boot.)

I've tested extensively with an x86 Linux guest on my pc-via branch which worked flawlessly.

As mentioned in the commit message the default routing of the chipset matches legacy behavior, that is interrupts 14 and 15. This is reflected by assigning [0x4a] = 4 in the code and that is how the code behaved before.

Best regards,
Bernhard

>
>Regards,
>BALATON Zoltan
>
>> Implement this missing piece of the VIA south bridge.
>> 
>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>> ---
>> hw/ide/via.c      |  6 ++++--
>> hw/isa/vt82c686.c | 17 +++++++++++++++++
>> 2 files changed, 21 insertions(+), 2 deletions(-)
>> 
>> diff --git a/hw/ide/via.c b/hw/ide/via.c
>> index 177baea9a7..0caae52276 100644
>> --- a/hw/ide/via.c
>> +++ b/hw/ide/via.c
>> @@ -31,6 +31,7 @@
>> #include "sysemu/dma.h"
>> #include "hw/isa/vt82c686.h"
>> #include "hw/ide/pci.h"
>> +#include "hw/irq.h"
>> #include "trace.h"
>> 
>> static uint64_t bmdma_read(void *opaque, hwaddr addr,
>> @@ -104,7 +105,8 @@ static void bmdma_setup_bar(PCIIDEState *d)
>> 
>> static void via_ide_set_irq(void *opaque, int n, int level)
>> {
>> -    PCIDevice *d = PCI_DEVICE(opaque);
>> +    PCIIDEState *s = opaque;
>> +    PCIDevice *d = PCI_DEVICE(s);
>> 
>>     if (level) {
>>         d->config[0x70 + n * 8] |= 0x80;
>> @@ -112,7 +114,7 @@ static void via_ide_set_irq(void *opaque, int n, int level)
>>         d->config[0x70 + n * 8] &= ~0x80;
>>     }
>> 
>> -    via_isa_set_irq(pci_get_function_0(d), 14 + n, level);
>> +    qemu_set_irq(s->isa_irq[n], level);
>> }
>> 
>> static void via_ide_reset(DeviceState *dev)
>> diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
>> index ca89119ce0..c7e29bb46a 100644
>> --- a/hw/isa/vt82c686.c
>> +++ b/hw/isa/vt82c686.c
>> @@ -568,9 +568,19 @@ static const VMStateDescription vmstate_via = {
>>     }
>> };
>> 
>> +static void via_isa_set_ide_irq(void *opaque, int n, int level)
>> +{
>> +    static const uint8_t irqs[] = { 14, 15, 10, 11 };
>> +    ViaISAState *s = opaque;
>> +    uint8_t irq = irqs[(s->dev.config[0x4a] >> (n * 2)) & 0x3];
>> +
>> +    qemu_set_irq(s->isa_irqs_in[irq], level);
>> +}
>> +
>> static void via_isa_init(Object *obj)
>> {
>>     ViaISAState *s = VIA_ISA(obj);
>> +    DeviceState *dev = DEVICE(s);
>> 
>>     object_initialize_child(obj, "rtc", &s->rtc, TYPE_MC146818_RTC);
>>     object_initialize_child(obj, "ide", &s->ide, TYPE_VIA_IDE);
>> @@ -578,6 +588,8 @@ static void via_isa_init(Object *obj)
>>     object_initialize_child(obj, "uhci2", &s->uhci[1], TYPE_VT82C686B_USB_UHCI);
>>     object_initialize_child(obj, "ac97", &s->ac97, TYPE_VIA_AC97);
>>     object_initialize_child(obj, "mc97", &s->mc97, TYPE_VIA_MC97);
>> +
>> +    qdev_init_gpio_in_named(dev, via_isa_set_ide_irq, "ide", ARRAY_SIZE(s->ide.isa_irq));
>> }
>> 
>> static const TypeInfo via_isa_info = {
>> @@ -692,6 +704,10 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
>>     if (!qdev_realize(DEVICE(&s->ide), BUS(pci_bus), errp)) {
>>         return;
>>     }
>> +    for (i = 0; i < 2; i++) {
>> +        qdev_connect_gpio_out(DEVICE(&s->ide), i,
>> +                              qdev_get_gpio_in_named(DEVICE(s), "ide", i));
>> +    }
>> 
>>     /* Functions 2-3: USB Ports */
>>     for (i = 0; i < ARRAY_SIZE(s->uhci); i++) {
>> @@ -814,6 +830,7 @@ static void vt8231_isa_reset(DeviceState *dev)
>>                  PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL);
>>     pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
>> 
>> +    pci_conf[0x4a] = 0x04; /* IDE interrupt Routing */
>>     pci_conf[0x58] = 0x40; /* Miscellaneous Control 0 */
>>     pci_conf[0x67] = 0x08; /* Fast IR Config */
>>     pci_conf[0x6b] = 0x01; /* Fast IR I/O Base */
>>
BALATON Zoltan April 22, 2023, 7:21 p.m. UTC | #3
On Sat, 22 Apr 2023, Bernhard Beschow wrote:
> Am 22. April 2023 17:23:56 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>> On Sat, 22 Apr 2023, Bernhard Beschow wrote:
>>> The VIA south bridge allows the legacy IDE interrupts to be routed to four
>>> different ISA interrupts. This can be configured through the 0x4a register in
>>> the PCI configuration space of the ISA function. The default routing matches
>>> the legacy ISA IRQs, that is 14 and 15.
>>
>> On VT8231 0x4a is PCI Master Arbitration Control, IDE interrupt Routing is 0x4c and only documents 14/15 as valid values.
>
> In the datasheet titled "VT8231 South Bridge", preliminary revision 0.8, 
> Oct. 29, 1999, page 60, the "IDE Interrupt Routing" register is located 
> at offset 0x4a and offers the same four interrupts in the same order as 
> in the code. Are we looking at the same datasheet?

Apparently not. The one I have says: Revision 2.32, May 10, 2004. Looks 
more authorative than a preliminary one.

>> Not sure any guest would actually change this or 0x4a and if that could cause problems but you may need to handle this somehow. (Apart from testing with MorphOS with -kernel you should really be testing with pegasos2.rom with MorphOS and Linux, e.g. Debian 8.11 netinstall iso is known to boot.)
>
> I've tested extensively with an x86 Linux guest on my pc-via branch which worked flawlessly.

That does not substitute testing Linux on pegasos2 though becuase there 
are some hacks in Linux kernel to handle some pecularities of the pegasos2 
including via ide on that machine and that can only be fully tested with 
pegasos2.rom and PPC Linux.

> As mentioned in the commit message the default routing of the chipset 
> matches legacy behavior, that is interrupts 14 and 15. This is reflected 
> by assigning [0x4a] = 4 in the code and that is how the code behaved 
> before.

And that's the only allowed value on VT8231, other bits are listed as 
reserved so I wonder if we want to model this at all if no guest is 
touching it anyway. So you could also just drop that part and keep it hard 
mapped to 14-15 as it is now, mentioning the config reg in a comment if we 
ever find a guest that needs it.

Regards,
BALATON Zoltan
Bernhard Beschow April 24, 2023, 7:50 a.m. UTC | #4
Am 22. April 2023 19:21:12 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>On Sat, 22 Apr 2023, Bernhard Beschow wrote:
>> Am 22. April 2023 17:23:56 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>>> On Sat, 22 Apr 2023, Bernhard Beschow wrote:
>>>> The VIA south bridge allows the legacy IDE interrupts to be routed to four
>>>> different ISA interrupts. This can be configured through the 0x4a register in
>>>> the PCI configuration space of the ISA function. The default routing matches
>>>> the legacy ISA IRQs, that is 14 and 15.
>>> 
>>> On VT8231 0x4a is PCI Master Arbitration Control, IDE interrupt Routing is 0x4c and only documents 14/15 as valid values.
>> 
>> In the datasheet titled "VT8231 South Bridge", preliminary revision 0.8, Oct. 29, 1999, page 60, the "IDE Interrupt Routing" register is located at offset 0x4a and offers the same four interrupts in the same order as in the code. Are we looking at the same datasheet?
>
>Apparently not. The one I have says: Revision 2.32, May 10, 2004. Looks more authorative than a preliminary one.

Indeed. I've updated my copy of the datasheet.

>
>>> Not sure any guest would actually change this or 0x4a and if that could cause problems but you may need to handle this somehow. (Apart from testing with MorphOS with -kernel you should really be testing with pegasos2.rom with MorphOS and Linux, e.g. Debian 8.11 netinstall iso is known to boot.)
>> 
>> I've tested extensively with an x86 Linux guest on my pc-via branch which worked flawlessly.
>
>That does not substitute testing Linux on pegasos2 though becuase there are some hacks in Linux kernel to handle some pecularities of the pegasos2 including via ide on that machine and that can only be fully tested with pegasos2.rom and PPC Linux.

I'll try to find the Debian ISO to test with pegasos2.rom.

>
>> As mentioned in the commit message the default routing of the chipset matches legacy behavior, that is interrupts 14 and 15. This is reflected by assigning [0x4a] = 4 in the code and that is how the code behaved before.
>
>And that's the only allowed value on VT8231, other bits are listed as reserved so I wonder if we want to model this at all if no guest is touching it anyway. So you could also just drop that part and keep it hard mapped to 14-15 as it is now, mentioning the config reg in a comment if we ever find a guest that needs it.

I see it now. I'll use hardcoded IRQs 14 and 15 then.

Best regards,
Bernhard

>
>Regards,
>BALATON Zoltan
BALATON Zoltan April 24, 2023, 10:10 a.m. UTC | #5
On Mon, 24 Apr 2023, Bernhard Beschow wrote:
> Am 22. April 2023 19:21:12 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>> On Sat, 22 Apr 2023, Bernhard Beschow wrote:
>>> Am 22. April 2023 17:23:56 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>>>> On Sat, 22 Apr 2023, Bernhard Beschow wrote:
>>>>> The VIA south bridge allows the legacy IDE interrupts to be routed to four
>>>>> different ISA interrupts. This can be configured through the 0x4a register in
>>>>> the PCI configuration space of the ISA function. The default routing matches
>>>>> the legacy ISA IRQs, that is 14 and 15.
>>>>
>>>> On VT8231 0x4a is PCI Master Arbitration Control, IDE interrupt Routing is 0x4c and only documents 14/15 as valid values.
>>>
>>> In the datasheet titled "VT8231 South Bridge", preliminary revision 0.8, Oct. 29, 1999, page 60, the "IDE Interrupt Routing" register is located at offset 0x4a and offers the same four interrupts in the same order as in the code. Are we looking at the same datasheet?
>>
>> Apparently not. The one I have says: Revision 2.32, May 10, 2004. Looks more authorative than a preliminary one.
>
> Indeed. I've updated my copy of the datasheet.
>
>>
>>>> Not sure any guest would actually change this or 0x4a and if that could cause problems but you may need to handle this somehow. (Apart from testing with MorphOS with -kernel you should really be testing with pegasos2.rom with MorphOS and Linux, e.g. Debian 8.11 netinstall iso is known to boot.)
>>>
>>> I've tested extensively with an x86 Linux guest on my pc-via branch which worked flawlessly.
>>
>> That does not substitute testing Linux on pegasos2 though becuase there are some hacks in Linux kernel to handle some pecularities of the pegasos2 including via ide on that machine and that can only be fully tested with pegasos2.rom and PPC Linux.
>
> I'll try to find the Debian ISO to test with pegasos2.rom.

It should be here I think:
https://www.debian.org/releases/jessie/debian-installer/

Regards,
BALATON Zoltan

>>
>>> As mentioned in the commit message the default routing of the chipset matches legacy behavior, that is interrupts 14 and 15. This is reflected by assigning [0x4a] = 4 in the code and that is how the code behaved before.
>>
>> And that's the only allowed value on VT8231, other bits are listed as reserved so I wonder if we want to model this at all if no guest is touching it anyway. So you could also just drop that part and keep it hard mapped to 14-15 as it is now, mentioning the config reg in a comment if we ever find a guest that needs it.
>
> I see it now. I'll use hardcoded IRQs 14 and 15 then.
>
> Best regards,
> Bernhard
>
>>
>> Regards,
>> BALATON Zoltan
>
>
Mark Cave-Ayland April 26, 2023, 10:55 a.m. UTC | #6
On 22/04/2023 16:07, Bernhard Beschow wrote:

> The VIA south bridge allows the legacy IDE interrupts to be routed to four
> different ISA interrupts. This can be configured through the 0x4a register in
> the PCI configuration space of the ISA function. The default routing matches
> the legacy ISA IRQs, that is 14 and 15.
> 
> Implement this missing piece of the VIA south bridge.
> 
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
>   hw/ide/via.c      |  6 ++++--
>   hw/isa/vt82c686.c | 17 +++++++++++++++++
>   2 files changed, 21 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/ide/via.c b/hw/ide/via.c
> index 177baea9a7..0caae52276 100644
> --- a/hw/ide/via.c
> +++ b/hw/ide/via.c
> @@ -31,6 +31,7 @@
>   #include "sysemu/dma.h"
>   #include "hw/isa/vt82c686.h"
>   #include "hw/ide/pci.h"
> +#include "hw/irq.h"
>   #include "trace.h"
>   
>   static uint64_t bmdma_read(void *opaque, hwaddr addr,
> @@ -104,7 +105,8 @@ static void bmdma_setup_bar(PCIIDEState *d)
>   
>   static void via_ide_set_irq(void *opaque, int n, int level)
>   {
> -    PCIDevice *d = PCI_DEVICE(opaque);
> +    PCIIDEState *s = opaque;
> +    PCIDevice *d = PCI_DEVICE(s);
>   
>       if (level) {
>           d->config[0x70 + n * 8] |= 0x80;
> @@ -112,7 +114,7 @@ static void via_ide_set_irq(void *opaque, int n, int level)
>           d->config[0x70 + n * 8] &= ~0x80;
>       }
>   
> -    via_isa_set_irq(pci_get_function_0(d), 14 + n, level);
> +    qemu_set_irq(s->isa_irq[n], level);
>   }
>   
>   static void via_ide_reset(DeviceState *dev)
> diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
> index ca89119ce0..c7e29bb46a 100644
> --- a/hw/isa/vt82c686.c
> +++ b/hw/isa/vt82c686.c
> @@ -568,9 +568,19 @@ static const VMStateDescription vmstate_via = {
>       }
>   };
>   
> +static void via_isa_set_ide_irq(void *opaque, int n, int level)
> +{
> +    static const uint8_t irqs[] = { 14, 15, 10, 11 };
> +    ViaISAState *s = opaque;
> +    uint8_t irq = irqs[(s->dev.config[0x4a] >> (n * 2)) & 0x3];
> +
> +    qemu_set_irq(s->isa_irqs_in[irq], level);
> +}
> +
>   static void via_isa_init(Object *obj)
>   {
>       ViaISAState *s = VIA_ISA(obj);
> +    DeviceState *dev = DEVICE(s);
>   
>       object_initialize_child(obj, "rtc", &s->rtc, TYPE_MC146818_RTC);
>       object_initialize_child(obj, "ide", &s->ide, TYPE_VIA_IDE);
> @@ -578,6 +588,8 @@ static void via_isa_init(Object *obj)
>       object_initialize_child(obj, "uhci2", &s->uhci[1], TYPE_VT82C686B_USB_UHCI);
>       object_initialize_child(obj, "ac97", &s->ac97, TYPE_VIA_AC97);
>       object_initialize_child(obj, "mc97", &s->mc97, TYPE_VIA_MC97);
> +
> +    qdev_init_gpio_in_named(dev, via_isa_set_ide_irq, "ide", ARRAY_SIZE(s->ide.isa_irq));
>   }
>   
>   static const TypeInfo via_isa_info = {
> @@ -692,6 +704,10 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
>       if (!qdev_realize(DEVICE(&s->ide), BUS(pci_bus), errp)) {
>           return;
>       }
> +    for (i = 0; i < 2; i++) {
> +        qdev_connect_gpio_out(DEVICE(&s->ide), i,
> +                              qdev_get_gpio_in_named(DEVICE(s), "ide", i));
> +    }
>   
>       /* Functions 2-3: USB Ports */
>       for (i = 0; i < ARRAY_SIZE(s->uhci); i++) {
> @@ -814,6 +830,7 @@ static void vt8231_isa_reset(DeviceState *dev)
>                    PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL);
>       pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
>   
> +    pci_conf[0x4a] = 0x04; /* IDE interrupt Routing */
>       pci_conf[0x58] = 0x40; /* Miscellaneous Control 0 */
>       pci_conf[0x67] = 0x08; /* Fast IR Config */
>       pci_conf[0x6b] = 0x01; /* Fast IR I/O Base */

I see there is still some further discussion on the exact datasheet being used, 
however the basic mechanism of wiring up the IDE IRQs using 
qdev_connect_gpio_out{_named}() in via_isa_realize():

Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>


ATB,

Mark.
diff mbox series

Patch

diff --git a/hw/ide/via.c b/hw/ide/via.c
index 177baea9a7..0caae52276 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -31,6 +31,7 @@ 
 #include "sysemu/dma.h"
 #include "hw/isa/vt82c686.h"
 #include "hw/ide/pci.h"
+#include "hw/irq.h"
 #include "trace.h"
 
 static uint64_t bmdma_read(void *opaque, hwaddr addr,
@@ -104,7 +105,8 @@  static void bmdma_setup_bar(PCIIDEState *d)
 
 static void via_ide_set_irq(void *opaque, int n, int level)
 {
-    PCIDevice *d = PCI_DEVICE(opaque);
+    PCIIDEState *s = opaque;
+    PCIDevice *d = PCI_DEVICE(s);
 
     if (level) {
         d->config[0x70 + n * 8] |= 0x80;
@@ -112,7 +114,7 @@  static void via_ide_set_irq(void *opaque, int n, int level)
         d->config[0x70 + n * 8] &= ~0x80;
     }
 
-    via_isa_set_irq(pci_get_function_0(d), 14 + n, level);
+    qemu_set_irq(s->isa_irq[n], level);
 }
 
 static void via_ide_reset(DeviceState *dev)
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index ca89119ce0..c7e29bb46a 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -568,9 +568,19 @@  static const VMStateDescription vmstate_via = {
     }
 };
 
+static void via_isa_set_ide_irq(void *opaque, int n, int level)
+{
+    static const uint8_t irqs[] = { 14, 15, 10, 11 };
+    ViaISAState *s = opaque;
+    uint8_t irq = irqs[(s->dev.config[0x4a] >> (n * 2)) & 0x3];
+
+    qemu_set_irq(s->isa_irqs_in[irq], level);
+}
+
 static void via_isa_init(Object *obj)
 {
     ViaISAState *s = VIA_ISA(obj);
+    DeviceState *dev = DEVICE(s);
 
     object_initialize_child(obj, "rtc", &s->rtc, TYPE_MC146818_RTC);
     object_initialize_child(obj, "ide", &s->ide, TYPE_VIA_IDE);
@@ -578,6 +588,8 @@  static void via_isa_init(Object *obj)
     object_initialize_child(obj, "uhci2", &s->uhci[1], TYPE_VT82C686B_USB_UHCI);
     object_initialize_child(obj, "ac97", &s->ac97, TYPE_VIA_AC97);
     object_initialize_child(obj, "mc97", &s->mc97, TYPE_VIA_MC97);
+
+    qdev_init_gpio_in_named(dev, via_isa_set_ide_irq, "ide", ARRAY_SIZE(s->ide.isa_irq));
 }
 
 static const TypeInfo via_isa_info = {
@@ -692,6 +704,10 @@  static void via_isa_realize(PCIDevice *d, Error **errp)
     if (!qdev_realize(DEVICE(&s->ide), BUS(pci_bus), errp)) {
         return;
     }
+    for (i = 0; i < 2; i++) {
+        qdev_connect_gpio_out(DEVICE(&s->ide), i,
+                              qdev_get_gpio_in_named(DEVICE(s), "ide", i));
+    }
 
     /* Functions 2-3: USB Ports */
     for (i = 0; i < ARRAY_SIZE(s->uhci); i++) {
@@ -814,6 +830,7 @@  static void vt8231_isa_reset(DeviceState *dev)
                  PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL);
     pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
 
+    pci_conf[0x4a] = 0x04; /* IDE interrupt Routing */
     pci_conf[0x58] = 0x40; /* Miscellaneous Control 0 */
     pci_conf[0x67] = 0x08; /* Fast IR Config */
     pci_conf[0x6b] = 0x01; /* Fast IR I/O Base */