qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v2 3/3] 40p: add fixed IRQ routing for LSI SCSI


From: Artyom Tarasenko
Subject: Re: [Qemu-devel] [PATCH v2 3/3] 40p: add fixed IRQ routing for LSI SCSI device
Date: Thu, 13 Sep 2018 16:21:30 +0200

On Sat, Sep 8, 2018 at 11:11 AM Mark Cave-Ayland
<address@hidden> wrote:
>
> Whilst the PReP specification describes how all PCI IRQs are routed via IRQ
> 15 on the interrupt controller, the real 40p machine has routing quirk in
> that the LSI SCSI device is routed to IRQ 13.

Is it a routing quirk or does 40p use both 15 and 13?
I used both in my AIX experiments and AIX seemed to be happy about it.
But maybe AIX simply doesn't care as long as the residual data is correct.

Artyom

> This is implemented using a little hack: the existing IRQ routing code uses
> (irq_num + (pci_dev->devfn >> 3)) & 1 to give the PCI interrupt pin, where
> the "& 1" ensures that the only pins A and B (0 and 1) will ever be used.
>
> Rather than fix the mask to "& 3" we leave the existing routing above as-is
> and then force the LSI SCSI device to use pin C (2). This enables us to
> route pin 2 permanantly to IRQ 13 since the LSI SCSI device will be its
> only user.
>
> Signed-off-by: Mark Cave-Ayland <address@hidden>
> ---
>  hw/pci-host/prep.c | 35 +++++++++++++++++++++++++++++++++--
>  hw/ppc/prep.c      | 10 +++++++---
>  2 files changed, 40 insertions(+), 5 deletions(-)
>
> diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
> index b1b6b16bad..87270605b5 100644
> --- a/hw/pci-host/prep.c
> +++ b/hw/pci-host/prep.c
> @@ -58,6 +58,7 @@ typedef struct PRePPCIState {
>
>      qemu_or_irq *or_irq;
>      qemu_irq pci_irqs[PCI_NUM_PINS];
> +    qemu_irq scsi_irq;
>      PCIBus pci_bus;
>      AddressSpace pci_io_as;
>      MemoryRegion pci_io;
> @@ -192,14 +193,41 @@ static const MemoryRegionOps raven_io_ops = {
>
>  static int raven_map_irq(PCIDevice *pci_dev, int irq_num)
>  {
> -    return (irq_num + (pci_dev->devfn >> 3)) & 1;
> +    switch (pci_dev->devfn) {
> +    case PCI_DEVFN(1, 0):
> +        /* Whilst legacy PReP machine exists we need to make
> +         * sure that this fixed interrupt routing is 40p only */
> +        if (strcmp(object_get_typename(OBJECT(pci_dev)),
> +                                       "lsi53c810") == 0) {
> +            /* LSI SCSI */
> +            return 2;
> +        } else {
> +            /* Normal PCI IRQ mapping */
> +            return (irq_num + (pci_dev->devfn >> 3)) & 1;
> +        }
> +    default:
> +        /* Normal PCI IRQ mapping */
> +        return (irq_num + (pci_dev->devfn >> 3)) & 1;
> +    }
>  }
>
>  static void raven_set_irq(void *opaque, int irq_num, int level)
>  {
>      PREPPCIState *s = opaque;
>
> -    qemu_set_irq(s->pci_irqs[irq_num], level);
> +    if (s->is_legacy_prep) {
> +        qemu_set_irq(s->pci_irqs[irq_num], level);
> +    } else {
> +        switch (irq_num) {
> +        case 2:
> +            /* LSI SCSI */
> +            qemu_set_irq(s->scsi_irq, level);
> +            break;
> +        default:
> +            /* Normal PCI IRQ mapping */
> +            qemu_set_irq(s->pci_irqs[irq_num], level);
> +        }
> +    }
>  }
>
>  static AddressSpace *raven_pcihost_set_iommu(PCIBus *bus, void *opaque,
> @@ -242,6 +270,9 @@ static void raven_pcihost_realizefn(DeviceState *d, Error 
> **errp)
>          for (i = 0; i < PCI_NUM_PINS; i++) {
>              s->pci_irqs[i] = qdev_get_gpio_in(DEVICE(s->or_irq), i);
>          }
> +
> +        /* 40p LSI SCSI has fixed routing via IRQ 13 */
> +        sysbus_init_irq(dev, &s->scsi_irq);
>      }
>
>      qdev_init_gpio_in(d, raven_change_gpio, 1);
> diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
> index 615865e46c..0412a56d98 100644
> --- a/hw/ppc/prep.c
> +++ b/hw/ppc/prep.c
> @@ -626,6 +626,7 @@ static void ibm_40p_init(MachineState *machine)
>      Nvram *m48t59 = NULL;
>      PCIBus *pci_bus;
>      ISABus *isa_bus;
> +    PCIDevice *pci;
>      void *fw_cfg;
>      int i;
>      uint32_t kernel_base = 0, initrd_base = 0;
> @@ -670,6 +671,7 @@ static void ibm_40p_init(MachineState *machine)
>      qdev_connect_gpio_out(dev, 0,
>                            cpu->env.irq_inputs[PPC6xx_INPUT_INT]);
>      sysbus_connect_irq(pcihost, 0, qdev_get_gpio_in(dev, 15));
> +    sysbus_connect_irq(pcihost, 1, qdev_get_gpio_in(dev, 13));
>      isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
>
>      /* Memory controller */
> @@ -700,9 +702,11 @@ static void ibm_40p_init(MachineState *machine)
>          qdev_prop_set_uint32(dev, "equipment", 0xc0);
>          qdev_init_nofail(dev);
>
> -        dev = DEVICE(pci_create_simple(pci_bus, PCI_DEVFN(1, 0),
> -                                       "lsi53c810"));
> -        lsi53c8xx_handle_legacy_cmdline(dev);
> +        pci = PCI_DEVICE(pci_create_simple(pci_bus, PCI_DEVFN(1, 0),
> +                                           "lsi53c810"));
> +        /* Interrupt pin C for fixed LSI SCSI IRQ routing */
> +        pci->config[PCI_INTERRUPT_PIN] = 0x3;
> +        lsi53c8xx_handle_legacy_cmdline(DEVICE(pci));
>
>          /* XXX: s3-trio at PCI_DEVFN(2, 0) */
>          pci_vga_init(pci_bus);
> --
> 2.11.0
>
>


-- 
Regards,
Artyom Tarasenko

SPARC and PPC PReP under qemu blog: http://tyom.blogspot.com/search/label/qemu



reply via email to

[Prev in Thread] Current Thread [Next in Thread]