diff mbox series

[v3,5/8] hw/ppc/pegasos2: Fix PCI interrupt routing

Message ID eca1ecce0b814ece8d285cb869ff839130a37b70.1677445307.git.balaton@eik.bme.hu
State New
Headers show
Series Pegasos2 fixes and audio output support | expand

Commit Message

BALATON Zoltan Feb. 16, 2023, 8:27 p.m. UTC
According to the PegasosII schematics the PCI interrupt lines are
connected to both the gpp pins of the Mv64361 north bridge and the
PINT pins of the VT8231 south bridge so guests can get interrupts from
either of these. So far we only had the MV64361 connections which
worked for on board devices but for additional PCI devices (such as
network or sound card added with -device) guest OSes expect interrupt
from the ISA IRQ 9 where the firmware routes these PCI interrupts in
VT8231 ISA bridge. After the previous patches we can now model this
and also remove the board specific connection from mv64361. Also
configure routing of these lines when using Virtual Open Firmware to
match board firmware for guests that expect this.

This fixes PCI interrupts on pegasos2 under Linux, MorphOS and AmigaOS.

Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Tested-by: Rene Engel <ReneEngel80@emailn.de>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
---
 hw/pci-host/mv64361.c |  4 ----
 hw/ppc/pegasos2.c     | 26 +++++++++++++++++++++++++-
 2 files changed, 25 insertions(+), 5 deletions(-)

Comments

Bernhard Beschow Feb. 26, 2023, 10:51 p.m. UTC | #1
Am 16. Februar 2023 20:27:32 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>According to the PegasosII schematics the PCI interrupt lines are
>connected to both the gpp pins of the Mv64361 north bridge and the
>PINT pins of the VT8231 south bridge so guests can get interrupts from
>either of these. So far we only had the MV64361 connections which
>worked for on board devices but for additional PCI devices (such as
>network or sound card added with -device) guest OSes expect interrupt
>from the ISA IRQ 9 where the firmware routes these PCI interrupts in
>VT8231 ISA bridge. After the previous patches we can now model this
>and also remove the board specific connection from mv64361. Also
>configure routing of these lines when using Virtual Open Firmware to
>match board firmware for guests that expect this.
>
>This fixes PCI interrupts on pegasos2 under Linux, MorphOS and AmigaOS.
>
>Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
>Tested-by: Rene Engel <ReneEngel80@emailn.de>
>Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
>---
> hw/pci-host/mv64361.c |  4 ----
> hw/ppc/pegasos2.c     | 26 +++++++++++++++++++++++++-
> 2 files changed, 25 insertions(+), 5 deletions(-)
>
>diff --git a/hw/pci-host/mv64361.c b/hw/pci-host/mv64361.c
>index f43f33fbd9..3d9132f989 100644
>--- a/hw/pci-host/mv64361.c
>+++ b/hw/pci-host/mv64361.c
>@@ -874,10 +874,6 @@ static void mv64361_realize(DeviceState *dev, Error **errp)
>     }
>     sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cpu_irq);
>     qdev_init_gpio_in_named(dev, mv64361_gpp_irq, "gpp", 32);
>-    /* FIXME: PCI IRQ connections may be board specific */
>-    for (i = 0; i < PCI_NUM_PINS; i++) {
>-        s->pci[1].irq[i] = qdev_get_gpio_in_named(dev, "gpp", 12 + i);
>-    }
> }
> 
> static void mv64361_reset(DeviceState *dev)
>diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
>index a9563f4fb2..4e1476673b 100644
>--- a/hw/ppc/pegasos2.c
>+++ b/hw/ppc/pegasos2.c
>@@ -74,6 +74,8 @@ struct Pegasos2MachineState {
>     MachineState parent_obj;
>     PowerPCCPU *cpu;
>     DeviceState *mv;
>+    qemu_irq mv_pirq[PCI_NUM_PINS];
>+    qemu_irq via_pirq[PCI_NUM_PINS];
>     Vof *vof;
>     void *fdt_blob;
>     uint64_t kernel_addr;
>@@ -96,6 +98,15 @@ static void pegasos2_cpu_reset(void *opaque)
>     }
> }
> 
>+static void pegasos2_pci_irq(void *opaque, int n, int level)
>+{
>+    Pegasos2MachineState *pm = opaque;
>+
>+    /* PCI interrupt lines are connected to both MV64361 and VT8231 */
>+    qemu_set_irq(pm->mv_pirq[n], level);
>+    qemu_set_irq(pm->via_pirq[n], level);
>+}
>+
> static void pegasos2_init(MachineState *machine)
> {
>     Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
>@@ -107,7 +118,7 @@ static void pegasos2_init(MachineState *machine)
>     I2CBus *i2c_bus;
>     const char *fwname = machine->firmware ?: PROM_FILENAME;
>     char *filename;
>-    int sz;
>+    int i, sz;
>     uint8_t *spd_data;
> 
>     /* init CPU */
>@@ -157,11 +168,18 @@ static void pegasos2_init(MachineState *machine)
>     /* Marvell Discovery II system controller */
>     pm->mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
>                           qdev_get_gpio_in(DEVICE(pm->cpu), PPC6xx_INPUT_INT)));
>+    for (i = 0; i < PCI_NUM_PINS; i++) {
>+        pm->mv_pirq[i] = qdev_get_gpio_in_named(pm->mv, "gpp", 12 + i);
>+    }
>     pci_bus = mv64361_get_pci_bus(pm->mv, 1);
>+    pci_bus_irqs(pci_bus, pegasos2_pci_irq, pm, PCI_NUM_PINS);
> 
>     /* VIA VT8231 South Bridge (multifunction PCI device) */
>     via = OBJECT(pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0),
>                                                  true, TYPE_VT8231_ISA));
>+    for (i = 0; i < PCI_NUM_PINS; i++) {
>+        pm->via_pirq[i] = qdev_get_gpio_in_named(DEVICE(via), "pirq", i);
>+    }
>     object_property_add_alias(OBJECT(machine), "rtc-time",
>                               object_resolve_path_component(via, "rtc"),
>                               "date");
>@@ -268,6 +286,12 @@ static void pegasos2_machine_reset(MachineState *machine, ShutdownCause reason)
>                               PCI_INTERRUPT_LINE, 2, 0x9);
>     pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
>                               0x50, 1, 0x2);
>+    pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
>+                              0x55, 1, 0x90);
>+    pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
>+                              0x56, 1, 0x99);
>+    pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
>+                              0x57, 1, 0x90);

Let's not mix aspects (implement VT82XX PCI IRQ routing) with Pegasos2 aspects. IOW let's keep these additions in a separate patch to make things clearer.

> 
>     pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 1) << 8) |
>                               PCI_INTERRUPT_LINE, 2, 0x109);
BALATON Zoltan Feb. 26, 2023, 11:39 p.m. UTC | #2
On Sun, 26 Feb 2023, Bernhard Beschow wrote:
> Am 16. Februar 2023 20:27:32 UTC schrieb BALATON Zoltan <balaton@eik.bme.hu>:
>> According to the PegasosII schematics the PCI interrupt lines are
>> connected to both the gpp pins of the Mv64361 north bridge and the
>> PINT pins of the VT8231 south bridge so guests can get interrupts from
>> either of these. So far we only had the MV64361 connections which
>> worked for on board devices but for additional PCI devices (such as
>> network or sound card added with -device) guest OSes expect interrupt
>> from the ISA IRQ 9 where the firmware routes these PCI interrupts in
>> VT8231 ISA bridge. After the previous patches we can now model this
>> and also remove the board specific connection from mv64361. Also
>> configure routing of these lines when using Virtual Open Firmware to
>> match board firmware for guests that expect this.
>>
>> This fixes PCI interrupts on pegasos2 under Linux, MorphOS and AmigaOS.
>>
>> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
>> Tested-by: Rene Engel <ReneEngel80@emailn.de>
>> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
>> ---
>> hw/pci-host/mv64361.c |  4 ----
>> hw/ppc/pegasos2.c     | 26 +++++++++++++++++++++++++-
>> 2 files changed, 25 insertions(+), 5 deletions(-)
>>
>> diff --git a/hw/pci-host/mv64361.c b/hw/pci-host/mv64361.c
>> index f43f33fbd9..3d9132f989 100644
>> --- a/hw/pci-host/mv64361.c
>> +++ b/hw/pci-host/mv64361.c
>> @@ -874,10 +874,6 @@ static void mv64361_realize(DeviceState *dev, Error **errp)
>>     }
>>     sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cpu_irq);
>>     qdev_init_gpio_in_named(dev, mv64361_gpp_irq, "gpp", 32);
>> -    /* FIXME: PCI IRQ connections may be board specific */
>> -    for (i = 0; i < PCI_NUM_PINS; i++) {
>> -        s->pci[1].irq[i] = qdev_get_gpio_in_named(dev, "gpp", 12 + i);
>> -    }
>> }
>>
>> static void mv64361_reset(DeviceState *dev)
>> diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
>> index a9563f4fb2..4e1476673b 100644
>> --- a/hw/ppc/pegasos2.c
>> +++ b/hw/ppc/pegasos2.c
>> @@ -74,6 +74,8 @@ struct Pegasos2MachineState {
>>     MachineState parent_obj;
>>     PowerPCCPU *cpu;
>>     DeviceState *mv;
>> +    qemu_irq mv_pirq[PCI_NUM_PINS];
>> +    qemu_irq via_pirq[PCI_NUM_PINS];
>>     Vof *vof;
>>     void *fdt_blob;
>>     uint64_t kernel_addr;
>> @@ -96,6 +98,15 @@ static void pegasos2_cpu_reset(void *opaque)
>>     }
>> }
>>
>> +static void pegasos2_pci_irq(void *opaque, int n, int level)
>> +{
>> +    Pegasos2MachineState *pm = opaque;
>> +
>> +    /* PCI interrupt lines are connected to both MV64361 and VT8231 */
>> +    qemu_set_irq(pm->mv_pirq[n], level);
>> +    qemu_set_irq(pm->via_pirq[n], level);
>> +}
>> +
>> static void pegasos2_init(MachineState *machine)
>> {
>>     Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
>> @@ -107,7 +118,7 @@ static void pegasos2_init(MachineState *machine)
>>     I2CBus *i2c_bus;
>>     const char *fwname = machine->firmware ?: PROM_FILENAME;
>>     char *filename;
>> -    int sz;
>> +    int i, sz;
>>     uint8_t *spd_data;
>>
>>     /* init CPU */
>> @@ -157,11 +168,18 @@ static void pegasos2_init(MachineState *machine)
>>     /* Marvell Discovery II system controller */
>>     pm->mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
>>                           qdev_get_gpio_in(DEVICE(pm->cpu), PPC6xx_INPUT_INT)));
>> +    for (i = 0; i < PCI_NUM_PINS; i++) {
>> +        pm->mv_pirq[i] = qdev_get_gpio_in_named(pm->mv, "gpp", 12 + i);
>> +    }
>>     pci_bus = mv64361_get_pci_bus(pm->mv, 1);
>> +    pci_bus_irqs(pci_bus, pegasos2_pci_irq, pm, PCI_NUM_PINS);
>>
>>     /* VIA VT8231 South Bridge (multifunction PCI device) */
>>     via = OBJECT(pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0),
>>                                                  true, TYPE_VT8231_ISA));
>> +    for (i = 0; i < PCI_NUM_PINS; i++) {
>> +        pm->via_pirq[i] = qdev_get_gpio_in_named(DEVICE(via), "pirq", i);
>> +    }
>>     object_property_add_alias(OBJECT(machine), "rtc-time",
>>                               object_resolve_path_component(via, "rtc"),
>>                               "date");
>> @@ -268,6 +286,12 @@ static void pegasos2_machine_reset(MachineState *machine, ShutdownCause reason)
>>                               PCI_INTERRUPT_LINE, 2, 0x9);
>>     pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
>>                               0x50, 1, 0x2);
>> +    pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
>> +                              0x55, 1, 0x90);
>> +    pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
>> +                              0x56, 1, 0x99);
>> +    pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
>> +                              0x57, 1, 0x90);
>
> Let's not mix aspects (implement VT82XX PCI IRQ routing) with Pegasos2 aspects. IOW let's keep these additions in a separate patch to make things clearer.

I guess this one hunk could be split out but not sure what would that 
bring.

Regards,
BALATON Zoltan

>>
>>     pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 1) << 8) |
>>                               PCI_INTERRUPT_LINE, 2, 0x109);
>
>
diff mbox series

Patch

diff --git a/hw/pci-host/mv64361.c b/hw/pci-host/mv64361.c
index f43f33fbd9..3d9132f989 100644
--- a/hw/pci-host/mv64361.c
+++ b/hw/pci-host/mv64361.c
@@ -874,10 +874,6 @@  static void mv64361_realize(DeviceState *dev, Error **errp)
     }
     sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cpu_irq);
     qdev_init_gpio_in_named(dev, mv64361_gpp_irq, "gpp", 32);
-    /* FIXME: PCI IRQ connections may be board specific */
-    for (i = 0; i < PCI_NUM_PINS; i++) {
-        s->pci[1].irq[i] = qdev_get_gpio_in_named(dev, "gpp", 12 + i);
-    }
 }
 
 static void mv64361_reset(DeviceState *dev)
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index a9563f4fb2..4e1476673b 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -74,6 +74,8 @@  struct Pegasos2MachineState {
     MachineState parent_obj;
     PowerPCCPU *cpu;
     DeviceState *mv;
+    qemu_irq mv_pirq[PCI_NUM_PINS];
+    qemu_irq via_pirq[PCI_NUM_PINS];
     Vof *vof;
     void *fdt_blob;
     uint64_t kernel_addr;
@@ -96,6 +98,15 @@  static void pegasos2_cpu_reset(void *opaque)
     }
 }
 
+static void pegasos2_pci_irq(void *opaque, int n, int level)
+{
+    Pegasos2MachineState *pm = opaque;
+
+    /* PCI interrupt lines are connected to both MV64361 and VT8231 */
+    qemu_set_irq(pm->mv_pirq[n], level);
+    qemu_set_irq(pm->via_pirq[n], level);
+}
+
 static void pegasos2_init(MachineState *machine)
 {
     Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
@@ -107,7 +118,7 @@  static void pegasos2_init(MachineState *machine)
     I2CBus *i2c_bus;
     const char *fwname = machine->firmware ?: PROM_FILENAME;
     char *filename;
-    int sz;
+    int i, sz;
     uint8_t *spd_data;
 
     /* init CPU */
@@ -157,11 +168,18 @@  static void pegasos2_init(MachineState *machine)
     /* Marvell Discovery II system controller */
     pm->mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
                           qdev_get_gpio_in(DEVICE(pm->cpu), PPC6xx_INPUT_INT)));
+    for (i = 0; i < PCI_NUM_PINS; i++) {
+        pm->mv_pirq[i] = qdev_get_gpio_in_named(pm->mv, "gpp", 12 + i);
+    }
     pci_bus = mv64361_get_pci_bus(pm->mv, 1);
+    pci_bus_irqs(pci_bus, pegasos2_pci_irq, pm, PCI_NUM_PINS);
 
     /* VIA VT8231 South Bridge (multifunction PCI device) */
     via = OBJECT(pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0),
                                                  true, TYPE_VT8231_ISA));
+    for (i = 0; i < PCI_NUM_PINS; i++) {
+        pm->via_pirq[i] = qdev_get_gpio_in_named(DEVICE(via), "pirq", i);
+    }
     object_property_add_alias(OBJECT(machine), "rtc-time",
                               object_resolve_path_component(via, "rtc"),
                               "date");
@@ -268,6 +286,12 @@  static void pegasos2_machine_reset(MachineState *machine, ShutdownCause reason)
                               PCI_INTERRUPT_LINE, 2, 0x9);
     pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
                               0x50, 1, 0x2);
+    pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
+                              0x55, 1, 0x90);
+    pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
+                              0x56, 1, 0x99);
+    pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
+                              0x57, 1, 0x90);
 
     pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 1) << 8) |
                               PCI_INTERRUPT_LINE, 2, 0x109);