Message ID | a51b8b647d3b297c794739a862d3565e3e5ed882.1677628524.git.balaton@eik.bme.hu |
---|---|
State | New |
Headers | show |
Series | Pegasos2 fixes and audio output support | expand |
Hi, It seems that I can't pick this patch standalone. It will break pegasos2 boot without patches 2 and 3 that comes beforehand. Phil, this patch already has my ack, so feel free to slide it together with patches 2 and 3 in your PR. Thanks, Daniel On 2/28/23 21:17, BALATON Zoltan wrote: > 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> > 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 298564f1f5..19e8031a3f 100644 > --- a/hw/pci-host/mv64361.c > +++ b/hw/pci-host/mv64361.c > @@ -873,10 +873,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 7cc375df05..f1650be5ee 100644 > --- a/hw/ppc/pegasos2.c > +++ b/hw/ppc/pegasos2.c > @@ -73,6 +73,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; > @@ -95,6 +97,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); > @@ -106,7 +117,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 */ > @@ -156,11 +167,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"); > @@ -267,6 +285,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);
diff --git a/hw/pci-host/mv64361.c b/hw/pci-host/mv64361.c index 298564f1f5..19e8031a3f 100644 --- a/hw/pci-host/mv64361.c +++ b/hw/pci-host/mv64361.c @@ -873,10 +873,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 7cc375df05..f1650be5ee 100644 --- a/hw/ppc/pegasos2.c +++ b/hw/ppc/pegasos2.c @@ -73,6 +73,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; @@ -95,6 +97,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); @@ -106,7 +117,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 */ @@ -156,11 +167,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"); @@ -267,6 +285,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);