diff mbox series

[v2] hw/ppc/pegasos2: Fix IRQ routing from pci.0

Message ID 20241102121711.26F054E6013@zero.eik.bme.hu (mailing list archive)
State New
Headers show
Series [v2] hw/ppc/pegasos2: Fix IRQ routing from pci.0 | expand

Commit Message

BALATON Zoltan Nov. 2, 2024, 12:17 p.m. UTC
The MV64361 has two PCI buses one of which is used for AGP on
PegasosII. So far we only emulated the PCI bus on pci.1 but some
graphics cards are only recognised by some guests when connected to
pci.0 corresponding to the AGP port. So far the interrupts were not
routed from pci.0 so this patch fixes that allowing the use of both
PCI buses. On real board only INTA and INTB are connected for AGP but
to avoid surprises we connect all 4 PCI interrupt lines so pci.0 can
be used for all PCI cards as well.

Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
 hw/pci-host/mv64361.c |  1 +
 hw/ppc/pegasos2.c     | 30 +++++++++++++++++++++++++++++-
 2 files changed, 30 insertions(+), 1 deletion(-)

Comments

BALATON Zoltan Nov. 15, 2024, 4:01 p.m. UTC | #1
On Sat, 2 Nov 2024, BALATON Zoltan wrote:
> The MV64361 has two PCI buses one of which is used for AGP on
> PegasosII. So far we only emulated the PCI bus on pci.1 but some
> graphics cards are only recognised by some guests when connected to
> pci.0 corresponding to the AGP port. So far the interrupts were not
> routed from pci.0 so this patch fixes that allowing the use of both
> PCI buses. On real board only INTA and INTB are connected for AGP but
> to avoid surprises we connect all 4 PCI interrupt lines so pci.0 can
> be used for all PCI cards as well.

Ping? As this is a bug fix it's still not too late to merge I think.

Regards,
BALATON Zoltan

> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
> hw/pci-host/mv64361.c |  1 +
> hw/ppc/pegasos2.c     | 30 +++++++++++++++++++++++++++++-
> 2 files changed, 30 insertions(+), 1 deletion(-)
>
> diff --git a/hw/pci-host/mv64361.c b/hw/pci-host/mv64361.c
> index 1036d8600d..421c287eb0 100644
> --- a/hw/pci-host/mv64361.c
> +++ b/hw/pci-host/mv64361.c
> @@ -95,6 +95,7 @@ static void mv64361_pcihost_realize(DeviceState *dev, Error **errp)
>                                    &s->mem, &s->io, 0, 4, TYPE_PCI_BUS);
>     g_free(name);
>     pci_create_simple(h->bus, 0, TYPE_MV64361_PCI_BRIDGE);
> +    qdev_init_gpio_out(dev, s->irq, ARRAY_SIZE(s->irq));
> }
>
> static Property mv64361_pcihost_props[] = {
> diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
> index 8ff4a00c34..16abeaac82 100644
> --- a/hw/ppc/pegasos2.c
> +++ b/hw/ppc/pegasos2.c
> @@ -14,6 +14,7 @@
> #include "hw/sysbus.h"
> #include "hw/pci/pci_host.h"
> #include "hw/irq.h"
> +#include "hw/or-irq.h"
> #include "hw/pci-host/mv64361.h"
> #include "hw/isa/vt82c686.h"
> #include "hw/ide/pci.h"
> @@ -73,8 +74,11 @@ OBJECT_DECLARE_TYPE(Pegasos2MachineState, MachineClass, PEGASOS2_MACHINE)
>
> struct Pegasos2MachineState {
>     MachineState parent_obj;
> +
>     PowerPCCPU *cpu;
>     DeviceState *mv;
> +    IRQState pci_irqs[PCI_NUM_PINS];
> +    OrIRQState orirq[PCI_NUM_PINS];
>     qemu_irq mv_pirq[PCI_NUM_PINS];
>     qemu_irq via_pirq[PCI_NUM_PINS];
>     Vof *vof;
> @@ -177,7 +181,6 @@ static void pegasos2_init(MachineState *machine)
>         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_new_multifunction(PCI_DEVFN(12, 0), TYPE_VT8231_ISA));
> @@ -209,6 +212,31 @@ static void pegasos2_init(MachineState *machine)
>     /* other PC hardware */
>     pci_vga_init(pci_bus);
>
> +    /* PCI interrupt routing: lines from pci.0 and pci.1 are ORed */
> +    for (int h = 0; h < 2; h++) {
> +        DeviceState *pd;
> +        g_autofree const char *pn = g_strdup_printf("pcihost%d", h);
> +
> +        pd = DEVICE(object_resolve_path_component(OBJECT(pm->mv), pn));
> +        assert(pd);
> +        for (i = 0; i < PCI_NUM_PINS; i++) {
> +            OrIRQState *ori = &pm->orirq[i];
> +
> +            if (h == 0) {
> +                g_autofree const char *n = g_strdup_printf("pci-orirq[%d]", i);
> +
> +                object_initialize_child_with_props(OBJECT(pm), n,
> +                                                   ori, sizeof(*ori),
> +                                                   TYPE_OR_IRQ, &error_fatal,
> +                                                   "num-lines", "2", NULL);
> +                qdev_realize(DEVICE(ori), NULL, &error_fatal);
> +                qemu_init_irq(&pm->pci_irqs[i], pegasos2_pci_irq, pm, i);
> +                qdev_connect_gpio_out(DEVICE(ori), 0, &pm->pci_irqs[i]);
> +            }
> +            qdev_connect_gpio_out(pd, i, qdev_get_gpio_in(DEVICE(ori), h));
> +        }
> +    }
> +
>     if (machine->kernel_filename) {
>         sz = load_elf(machine->kernel_filename, NULL, NULL, NULL,
>                       &pm->kernel_entry, &pm->kernel_addr, NULL, NULL, 1,
>
diff mbox series

Patch

diff --git a/hw/pci-host/mv64361.c b/hw/pci-host/mv64361.c
index 1036d8600d..421c287eb0 100644
--- a/hw/pci-host/mv64361.c
+++ b/hw/pci-host/mv64361.c
@@ -95,6 +95,7 @@  static void mv64361_pcihost_realize(DeviceState *dev, Error **errp)
                                    &s->mem, &s->io, 0, 4, TYPE_PCI_BUS);
     g_free(name);
     pci_create_simple(h->bus, 0, TYPE_MV64361_PCI_BRIDGE);
+    qdev_init_gpio_out(dev, s->irq, ARRAY_SIZE(s->irq));
 }
 
 static Property mv64361_pcihost_props[] = {
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 8ff4a00c34..16abeaac82 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -14,6 +14,7 @@ 
 #include "hw/sysbus.h"
 #include "hw/pci/pci_host.h"
 #include "hw/irq.h"
+#include "hw/or-irq.h"
 #include "hw/pci-host/mv64361.h"
 #include "hw/isa/vt82c686.h"
 #include "hw/ide/pci.h"
@@ -73,8 +74,11 @@  OBJECT_DECLARE_TYPE(Pegasos2MachineState, MachineClass, PEGASOS2_MACHINE)
 
 struct Pegasos2MachineState {
     MachineState parent_obj;
+
     PowerPCCPU *cpu;
     DeviceState *mv;
+    IRQState pci_irqs[PCI_NUM_PINS];
+    OrIRQState orirq[PCI_NUM_PINS];
     qemu_irq mv_pirq[PCI_NUM_PINS];
     qemu_irq via_pirq[PCI_NUM_PINS];
     Vof *vof;
@@ -177,7 +181,6 @@  static void pegasos2_init(MachineState *machine)
         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_new_multifunction(PCI_DEVFN(12, 0), TYPE_VT8231_ISA));
@@ -209,6 +212,31 @@  static void pegasos2_init(MachineState *machine)
     /* other PC hardware */
     pci_vga_init(pci_bus);
 
+    /* PCI interrupt routing: lines from pci.0 and pci.1 are ORed */
+    for (int h = 0; h < 2; h++) {
+        DeviceState *pd;
+        g_autofree const char *pn = g_strdup_printf("pcihost%d", h);
+
+        pd = DEVICE(object_resolve_path_component(OBJECT(pm->mv), pn));
+        assert(pd);
+        for (i = 0; i < PCI_NUM_PINS; i++) {
+            OrIRQState *ori = &pm->orirq[i];
+
+            if (h == 0) {
+                g_autofree const char *n = g_strdup_printf("pci-orirq[%d]", i);
+
+                object_initialize_child_with_props(OBJECT(pm), n,
+                                                   ori, sizeof(*ori),
+                                                   TYPE_OR_IRQ, &error_fatal,
+                                                   "num-lines", "2", NULL);
+                qdev_realize(DEVICE(ori), NULL, &error_fatal);
+                qemu_init_irq(&pm->pci_irqs[i], pegasos2_pci_irq, pm, i);
+                qdev_connect_gpio_out(DEVICE(ori), 0, &pm->pci_irqs[i]);
+            }
+            qdev_connect_gpio_out(pd, i, qdev_get_gpio_in(DEVICE(ori), h));
+        }
+    }
+
     if (machine->kernel_filename) {
         sz = load_elf(machine->kernel_filename, NULL, NULL, NULL,
                       &pm->kernel_entry, &pm->kernel_addr, NULL, NULL, 1,