[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2 1/2] pci: Add pci_device_route_intx_to_irq
From: |
Michael S. Tsirkin |
Subject: |
Re: [Qemu-devel] [PATCH v2 1/2] pci: Add pci_device_route_intx_to_irq |
Date: |
Thu, 19 Jul 2012 17:09:49 +0300 |
On Mon, Jul 02, 2012 at 02:38:46PM +0200, Jan Kiszka wrote:
> Add a PCI IRQ path discovery function that walks from a given device to
> the host bridge, returning the mode (enabled/inverted/disabled) and the
> IRQ number that is reported to the attached interrupt controller. For
> this purpose, another host bridge callback function is introduced:
> route_intx_to_irq. It is so far only implemented by the PIIX3, other
> host bridges can be added later on as required.
>
> Will be used for KVM PCI device assignment and VFIO.
>
> Signed-off-by: Jan Kiszka <address@hidden>
I strongly suspect what we'll end up with is reworking
this in some way, so IMO touching all architectures
is premature and will just cause churn: this is
stubbed out even on piix xen.
So I just added an extra API instead, and applied.
> ---
> hw/alpha_typhoon.c | 2 +-
> hw/apb_pci.c | 2 +-
> hw/bonito.c | 2 +-
> hw/grackle_pci.c | 1 +
> hw/gt64xxx.c | 1 +
> hw/pci.c | 18 +++++++++++++++++-
> hw/pci.h | 13 +++++++++++++
> hw/pci_internals.h | 1 +
> hw/piix_pci.c | 23 ++++++++++++++++++++---
> hw/ppc4xx_pci.c | 2 +-
> hw/ppce500_pci.c | 2 +-
> hw/prep_pci.c | 2 +-
> hw/sh_pci.c | 2 +-
> hw/spapr_pci.c | 2 +-
> hw/unin_pci.c | 4 ++--
> hw/versatile_pci.c | 2 +-
> 16 files changed, 64 insertions(+), 15 deletions(-)
>
> diff --git a/hw/alpha_typhoon.c b/hw/alpha_typhoon.c
> index 872e112..fc2e4b3 100644
> --- a/hw/alpha_typhoon.c
> +++ b/hw/alpha_typhoon.c
> @@ -764,7 +764,7 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus
> **isa_bus,
> &s->pchip.reg_io);
>
> b = pci_register_bus(&s->host.busdev.qdev, "pci",
> - typhoon_set_irq, sys_map_irq, s,
> + typhoon_set_irq, sys_map_irq, NULL, s,
> &s->pchip.reg_mem, addr_space_io, 0, 64);
> s->host.bus = b;
>
> diff --git a/hw/apb_pci.c b/hw/apb_pci.c
> index c28411a..d36cbb9 100644
> --- a/hw/apb_pci.c
> +++ b/hw/apb_pci.c
> @@ -378,7 +378,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
> memory_region_add_subregion(get_system_memory(), mem_base, &d->pci_mmio);
>
> d->bus = pci_register_bus(&d->busdev.qdev, "pci",
> - pci_apb_set_irq, pci_pbm_map_irq, d,
> + pci_apb_set_irq, pci_pbm_map_irq, NULL, d,
> &d->pci_mmio,
> get_system_io(),
> 0, 32);
> diff --git a/hw/bonito.c b/hw/bonito.c
> index 77786f8..7ce5993 100644
> --- a/hw/bonito.c
> +++ b/hw/bonito.c
> @@ -750,7 +750,7 @@ PCIBus *bonito_init(qemu_irq *pic)
> dev = qdev_create(NULL, "Bonito-pcihost");
> pcihost = FROM_SYSBUS(BonitoState, sysbus_from_qdev(dev));
> b = pci_register_bus(&pcihost->busdev.qdev, "pci", pci_bonito_set_irq,
> - pci_bonito_map_irq, pic, get_system_memory(),
> + pci_bonito_map_irq, NULL, pic, get_system_memory(),
> get_system_io(),
> 0x28, 32);
> pcihost->bus = b;
> diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
> index 81ff3a3..f47d9fe 100644
> --- a/hw/grackle_pci.c
> +++ b/hw/grackle_pci.c
> @@ -85,6 +85,7 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
> d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
> pci_grackle_set_irq,
> pci_grackle_map_irq,
> + NULL,
> pic,
> &d->pci_mmio,
> address_space_io,
> diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c
> index a2d0e5a..2418238 100644
> --- a/hw/gt64xxx.c
> +++ b/hw/gt64xxx.c
> @@ -1093,6 +1093,7 @@ PCIBus *gt64120_register(qemu_irq *pic)
> d = FROM_SYSBUS(GT64120State, s);
> d->pci.bus = pci_register_bus(&d->busdev.qdev, "pci",
> gt64120_pci_set_irq, gt64120_pci_map_irq,
> + NULL,
> pic,
> get_system_memory(),
> get_system_io(),
> diff --git a/hw/pci.c b/hw/pci.c
> index 99a4304..311ba09 100644
> --- a/hw/pci.c
> +++ b/hw/pci.c
> @@ -307,10 +307,12 @@ PCIBus *pci_bus_new(DeviceState *parent, const char
> *name,
> }
>
> void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn
> map_irq,
> + pci_route_irq_fn route_intx_to_irq,
> void *irq_opaque, int nirq)
> {
> bus->set_irq = set_irq;
> bus->map_irq = map_irq;
> + bus->route_intx_to_irq = route_intx_to_irq;
> bus->irq_opaque = irq_opaque;
> bus->nirq = nirq;
> bus->irq_count = g_malloc0(nirq * sizeof(bus->irq_count[0]));
> @@ -325,6 +327,7 @@ void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug,
> DeviceState *qdev)
>
> PCIBus *pci_register_bus(DeviceState *parent, const char *name,
> pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
> + pci_route_irq_fn route_intx_to_irq,
> void *irq_opaque,
> MemoryRegion *address_space_mem,
> MemoryRegion *address_space_io,
> @@ -334,7 +337,7 @@ PCIBus *pci_register_bus(DeviceState *parent, const char
> *name,
>
> bus = pci_bus_new(parent, name, address_space_mem,
> address_space_io, devfn_min);
> - pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq);
> + pci_bus_irqs(bus, set_irq, map_irq, route_intx_to_irq, irq_opaque, nirq);
> return bus;
> }
>
> @@ -1079,6 +1082,19 @@ static void pci_set_irq(void *opaque, int irq_num, int
> level)
> pci_change_irq_level(pci_dev, irq_num, change);
> }
>
> +PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)
> +{
> + PCIBus *bus;
> +
> + do {
> + bus = dev->bus;
> + pin = bus->map_irq(dev, pin);
> + dev = bus->parent_dev;
> + } while (dev);
> + assert(bus->route_intx_to_irq);
> + return bus->route_intx_to_irq(bus->irq_opaque, pin);
> +}
> +
> /***********************************************************/
> /* monitor info on PCI */
>
> diff --git a/hw/pci.h b/hw/pci.h
> index 79d38fd..387111b 100644
> --- a/hw/pci.h
> +++ b/hw/pci.h
> @@ -141,6 +141,15 @@ enum {
> #define PCI_DEVICE_GET_CLASS(obj) \
> OBJECT_GET_CLASS(PCIDeviceClass, (obj), TYPE_PCI_DEVICE)
>
> +typedef struct PCIINTxRoute {
> + enum {
> + PCI_INTX_ENABLED,
> + PCI_INTX_INVERTED,
> + PCI_INTX_DISABLED,
> + } mode;
> + int irq;
> +} PCIINTxRoute;
> +
> typedef struct PCIDeviceClass {
> DeviceClass parent_class;
>
> @@ -278,6 +287,7 @@ MemoryRegion *pci_address_space_io(PCIDevice *dev);
>
> typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level);
> typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
> +typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin);
>
> typedef enum {
> PCI_HOTPLUG_DISABLED,
> @@ -297,15 +307,18 @@ PCIBus *pci_bus_new(DeviceState *parent, const char
> *name,
> MemoryRegion *address_space_io,
> uint8_t devfn_min);
> void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn
> map_irq,
> + pci_route_irq_fn route_intx_to_irq,
> void *irq_opaque, int nirq);
> int pci_bus_get_irq_level(PCIBus *bus, int irq_num);
> void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *dev);
> PCIBus *pci_register_bus(DeviceState *parent, const char *name,
> pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
> + pci_route_irq_fn route_intx_to_irq,
> void *irq_opaque,
> MemoryRegion *address_space_mem,
> MemoryRegion *address_space_io,
> uint8_t devfn_min, int nirq);
> +PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin);
> void pci_device_reset(PCIDevice *dev);
> void pci_bus_reset(PCIBus *bus);
>
> diff --git a/hw/pci_internals.h b/hw/pci_internals.h
> index e8bc9f6..c931b64 100644
> --- a/hw/pci_internals.h
> +++ b/hw/pci_internals.h
> @@ -22,6 +22,7 @@ struct PCIBus {
> uint8_t devfn_min;
> pci_set_irq_fn set_irq;
> pci_map_irq_fn map_irq;
> + pci_route_irq_fn route_intx_to_irq;
> pci_hotplug_fn hotplug;
> DeviceState *hotplug_qdev;
> void *irq_opaque;
> diff --git a/hw/piix_pci.c b/hw/piix_pci.c
> index 09e84f5..347177f 100644
> --- a/hw/piix_pci.c
> +++ b/hw/piix_pci.c
> @@ -89,6 +89,7 @@ struct PCII440FXState {
> #define I440FX_SMRAM 0x72
>
> static void piix3_set_irq(void *opaque, int pirq, int level);
> +static PCIINTxRoute piix3_route_intx_pin_to_irq(void *opaque, int pci_intx);
> static void piix3_write_config_xen(PCIDevice *dev,
> uint32_t address, uint32_t val, int len);
>
> @@ -308,13 +309,13 @@ static PCIBus *i440fx_common_init(const char
> *device_name,
> if (xen_enabled()) {
> piix3 = DO_UPCAST(PIIX3State, dev,
> pci_create_simple_multifunction(b, -1, true, "PIIX3-xen"));
> - pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq,
> + pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq, NULL,
> piix3, XEN_PIIX_NUM_PIRQS);
> } else {
> piix3 = DO_UPCAST(PIIX3State, dev,
> pci_create_simple_multifunction(b, -1, true, "PIIX3"));
> - pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3,
> - PIIX_NUM_PIRQS);
> + pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq,
> + piix3_route_intx_pin_to_irq, piix3, PIIX_NUM_PIRQS);
> }
> piix3->pic = pic;
> *isa_bus = DO_UPCAST(ISABus, qbus,
> @@ -386,6 +387,22 @@ static void piix3_set_irq(void *opaque, int pirq, int
> level)
> piix3_set_irq_level(piix3, pirq, level);
> }
>
> +static PCIINTxRoute piix3_route_intx_pin_to_irq(void *opaque, int pin)
> +{
> + PIIX3State *piix3 = opaque;
> + int irq = piix3->dev.config[PIIX_PIRQC + pin];
> + PCIINTxRoute route;
> +
> + if (irq < PIIX_NUM_PIC_IRQS) {
> + route.mode = PCI_INTX_ENABLED;
> + route.irq = irq;
> + } else {
> + route.mode = PCI_INTX_DISABLED;
> + route.irq = -1;
> + }
> + return route;
> +}
> +
> /* irq routing is changed. so rebuild bitmap */
> static void piix3_update_irq_levels(PIIX3State *piix3)
> {
> diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
> index 203c3cd..224c4a0 100644
> --- a/hw/ppc4xx_pci.c
> +++ b/hw/ppc4xx_pci.c
> @@ -343,7 +343,7 @@ static int ppc4xx_pcihost_initfn(SysBusDevice *dev)
> }
>
> b = pci_register_bus(&s->pci_state.busdev.qdev, NULL, ppc4xx_pci_set_irq,
> - ppc4xx_pci_map_irq, s->irq, get_system_memory(),
> + ppc4xx_pci_map_irq, NULL, s->irq,
> get_system_memory(),
> get_system_io(), 0, 4);
> s->pci_state.bus = b;
>
> diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
> index 0f60b24..dd924ae 100644
> --- a/hw/ppce500_pci.c
> +++ b/hw/ppce500_pci.c
> @@ -318,7 +318,7 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
> }
>
> b = pci_register_bus(&s->pci_state.busdev.qdev, NULL,
> mpc85xx_pci_set_irq,
> - mpc85xx_pci_map_irq, s->irq, address_space_mem,
> + mpc85xx_pci_map_irq, NULL, s->irq,
> address_space_mem,
> address_space_io, PCI_DEVFN(0x11, 0), 4);
> s->pci_state.bus = b;
>
> diff --git a/hw/prep_pci.c b/hw/prep_pci.c
> index 38dbff4..9d7bec7 100644
> --- a/hw/prep_pci.c
> +++ b/hw/prep_pci.c
> @@ -108,7 +108,7 @@ static int raven_pcihost_init(SysBusDevice *dev)
> }
>
> bus = pci_register_bus(&h->busdev.qdev, NULL,
> - prep_set_irq, prep_map_irq, s->irq,
> + prep_set_irq, prep_map_irq, NULL, s->irq,
> address_space_mem, address_space_io, 0, 4);
> h->bus = bus;
>
> diff --git a/hw/sh_pci.c b/hw/sh_pci.c
> index 0cfac46..1cea12b 100644
> --- a/hw/sh_pci.c
> +++ b/hw/sh_pci.c
> @@ -120,7 +120,7 @@ static int sh_pci_device_init(SysBusDevice *dev)
> sysbus_init_irq(dev, &s->irq[i]);
> }
> s->bus = pci_register_bus(&s->busdev.qdev, "pci",
> - sh_pci_set_irq, sh_pci_map_irq,
> + sh_pci_set_irq, sh_pci_map_irq, NULL,
> s->irq,
> get_system_memory(),
> get_system_io(),
> diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c
> index 47ba5ff..ffede69 100644
> --- a/hw/spapr_pci.c
> +++ b/hw/spapr_pci.c
> @@ -316,7 +316,7 @@ static int spapr_phb_init(SysBusDevice *s)
>
> bus = pci_register_bus(&phb->busdev.qdev,
> phb->busname ? phb->busname : phb->dtbusname,
> - pci_spapr_set_irq, pci_spapr_map_irq, phb,
> + pci_spapr_set_irq, pci_spapr_map_irq, NULL, phb,
> &phb->memspace, &phb->iospace,
> PCI_DEVFN(0, 0), PCI_NUM_PINS);
> phb->host_state.bus = bus;
> diff --git a/hw/unin_pci.c b/hw/unin_pci.c
> index 409bcd4..056e3bc 100644
> --- a/hw/unin_pci.c
> +++ b/hw/unin_pci.c
> @@ -227,7 +227,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic,
>
> d->host_state.bus = pci_register_bus(dev, "pci",
> pci_unin_set_irq, pci_unin_map_irq,
> - pic,
> + NULL, pic,
> &d->pci_mmio,
> address_space_io,
> PCI_DEVFN(11, 0), 4);
> @@ -293,7 +293,7 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
>
> d->host_state.bus = pci_register_bus(dev, "pci",
> pci_unin_set_irq, pci_unin_map_irq,
> - pic,
> + NULL, pic,
> &d->pci_mmio,
> address_space_io,
> PCI_DEVFN(11, 0), 4);
> diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c
> index ae53a8b..90c400e 100644
> --- a/hw/versatile_pci.c
> +++ b/hw/versatile_pci.c
> @@ -68,7 +68,7 @@ static int pci_vpb_init(SysBusDevice *dev)
> sysbus_init_irq(dev, &s->irq[i]);
> }
> bus = pci_register_bus(&dev->qdev, "pci",
> - pci_vpb_set_irq, pci_vpb_map_irq, s->irq,
> + pci_vpb_set_irq, pci_vpb_map_irq, NULL, s->irq,
> get_system_memory(), get_system_io(),
> PCI_DEVFN(11, 0), 4);
>
> --
> 1.7.3.4