On Sat, May 21, 2022 at 10:27 AM Mark Cave-Ayland < mark.cave-ayl...@ilande.co.uk> wrote:
> On 13/05/2022 18:54, Bernhard Beschow wrote: > > > PCI interrupt wiring and device creation (piix4 only) were performed > > in create() functions which are obsolete. Move these tasks into QOM > > functions to modernize the code. > > > > In order to avoid duplicate checking for xen_enabled() the piix3 realize > > methods are now split. > > > > Signed-off-by: Bernhard Beschow <shen...@gmail.com> > > --- > > hw/isa/piix3.c | 67 +++++++++++++++++++++++++++++++++----------------- > > hw/isa/piix4.c | 20 +++++++++------ > > 2 files changed, 57 insertions(+), 30 deletions(-) > > > > diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c > > index 7d69420967..d15117a7c7 100644 > > --- a/hw/isa/piix3.c > > +++ b/hw/isa/piix3.c > > @@ -24,6 +24,7 @@ > > > > #include "qemu/osdep.h" > > #include "qemu/range.h" > > +#include "qapi/error.h" > > #include "hw/southbridge/piix.h" > > #include "hw/irq.h" > > #include "hw/isa/isa.h" > > @@ -280,7 +281,7 @@ static const MemoryRegionOps rcr_ops = { > > .endianness = DEVICE_LITTLE_ENDIAN > > }; > > > > -static void piix3_realize(PCIDevice *dev, Error **errp) > > +static void pci_piix3_realize(PCIDevice *dev, Error **errp) > > { > > PIIX3State *d = PIIX3_PCI_DEVICE(dev); > > > > @@ -305,7 +306,6 @@ static void pci_piix3_class_init(ObjectClass *klass, > void *data) > > dc->desc = "ISA bridge"; > > dc->vmsd = &vmstate_piix3; > > dc->hotpluggable = false; > > - k->realize = piix3_realize; > > k->vendor_id = PCI_VENDOR_ID_INTEL; > > /* 82371SB PIIX3 PCI-to-ISA bridge (Step A1) */ > > k->device_id = PCI_DEVICE_ID_INTEL_82371SB_0; > > @@ -329,11 +329,28 @@ static const TypeInfo piix3_pci_type_info = { > > }, > > }; > > > > +static void piix3_realize(PCIDevice *dev, Error **errp) > > +{ > > + ERRP_GUARD(); > > + PIIX3State *piix3 = PIIX3_PCI_DEVICE(dev); > > + PCIBus *pci_bus = pci_get_bus(dev); > > + > > + pci_piix3_realize(dev, errp); > > + if (*errp) { > > + return; > > + } > > + > > + pci_bus_irqs(pci_bus, piix3_set_irq, pci_slot_get_pirq, > > + piix3, PIIX_NUM_PIRQS); > > + pci_bus_set_route_irq_fn(pci_bus, piix3_route_intx_pin_to_irq); > > +}; > > + > > Oooof. So the reason this looks a bit odd is because we don't have an > equivalent of > device_class_set_parent_realize() for PCIDevice realize(). Having had a > look in pci.c > this looks like a similar approach for handling errors, execpt that here > errp is > accessed directly. > Yes, I was surprised by this as well. So I took inspiration from sdhci_common_realize(). > > I think this is probably the best we can do for now though. Have you tried > forcing > pci_piix3_realize() to throw an error during testing to make sure this > works as expected? > I'll post the results in the cover letter of v2. > > > static void piix3_class_init(ObjectClass *klass, void *data) > > { > > PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); > > > > k->config_write = piix3_write_config; > > + k->realize = piix3_realize; > > } > > > > static const TypeInfo piix3_info = { > > @@ -342,11 +359,33 @@ static const TypeInfo piix3_info = { > > .class_init = piix3_class_init, > > }; > > > > +static void piix3_xen_realize(PCIDevice *dev, Error **errp) > > +{ > > + ERRP_GUARD(); > > + PIIX3State *piix3 = PIIX3_PCI_DEVICE(dev); > > + PCIBus *pci_bus = pci_get_bus(dev); > > + > > + pci_piix3_realize(dev, errp); > > + if (*errp) { > > + return; > > + } > > + > > + /* > > + * Xen supports additional interrupt routes from the PCI devices to > > + * the IOAPIC: the four pins of each PCI device on the bus are also > > + * connected to the IOAPIC directly. > > + * These additional routes can be discovered through ACPI. > > + */ > > + pci_bus_irqs(pci_bus, xen_piix3_set_irq, xen_pci_slot_get_pirq, > > + piix3, XEN_PIIX_NUM_PIRQS); > > +}; > > + > > static void piix3_xen_class_init(ObjectClass *klass, void *data) > > { > > PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); > > > > k->config_write = piix3_write_config_xen; > > + k->realize = piix3_xen_realize; > > }; > > > > static const TypeInfo piix3_xen_info = { > > @@ -368,27 +407,11 @@ PIIX3State *piix3_create(PCIBus *pci_bus, ISABus > **isa_bus) > > { > > PIIX3State *piix3; > > PCIDevice *pci_dev; > > + const char *type = xen_enabled() ? TYPE_PIIX3_XEN_DEVICE > > + : TYPE_PIIX3_DEVICE; > > > > - /* > > - * Xen supports additional interrupt routes from the PCI devices to > > - * the IOAPIC: the four pins of each PCI device on the bus are also > > - * connected to the IOAPIC directly. > > - * These additional routes can be discovered through ACPI. > > - */ > > - if (xen_enabled()) { > > - pci_dev = pci_create_simple_multifunction(pci_bus, -1, true, > > - > TYPE_PIIX3_XEN_DEVICE); > > - piix3 = PIIX3_PCI_DEVICE(pci_dev); > > - pci_bus_irqs(pci_bus, xen_piix3_set_irq, xen_pci_slot_get_pirq, > > - piix3, XEN_PIIX_NUM_PIRQS); > > - } else { > > - pci_dev = pci_create_simple_multifunction(pci_bus, -1, true, > > - TYPE_PIIX3_DEVICE); > > - piix3 = PIIX3_PCI_DEVICE(pci_dev); > > - pci_bus_irqs(pci_bus, piix3_set_irq, pci_slot_get_pirq, > > - piix3, PIIX_NUM_PIRQS); > > - pci_bus_set_route_irq_fn(pci_bus, piix3_route_intx_pin_to_irq); > > - } > > + pci_dev = pci_create_simple_multifunction(pci_bus, -1, true, type); > > + piix3 = PIIX3_PCI_DEVICE(pci_dev); > > *isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix3), "isa.0")); > > > > return piix3; > > diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c > > index a223b69e24..134d23aea7 100644 > > --- a/hw/isa/piix4.c > > +++ b/hw/isa/piix4.c > > @@ -204,6 +204,8 @@ static const MemoryRegionOps piix4_rcr_ops = { > > static void piix4_realize(PCIDevice *dev, Error **errp) > > { > > PIIX4State *s = PIIX4_PCI_DEVICE(dev); > > + PCIDevice *pci; > > + PCIBus *pci_bus = pci_get_bus(dev); > > ISABus *isa_bus; > > qemu_irq *i8259_out_irq; > > > > @@ -242,6 +244,15 @@ static void piix4_realize(PCIDevice *dev, Error > **errp) > > return; > > } > > s->rtc.irq = isa_get_irq(ISA_DEVICE(&s->rtc), s->rtc.isairq); > > + > > + /* IDE */ > > + pci = pci_create_simple(pci_bus, dev->devfn + 1, "piix4-ide"); > > + pci_ide_create_devs(pci); > > + > > + /* USB */ > > + pci_create_simple(pci_bus, dev->devfn + 2, "piix4-usb-uhci"); > > + > > + pci_bus_irqs(pci_bus, piix4_set_irq, pci_slot_get_pirq, s, > PIIX_NUM_PIRQS); > > } > > > > static void piix4_init(Object *obj) > > @@ -292,7 +303,6 @@ type_init(piix4_register_types) > > > > DeviceState *piix4_create(PCIBus *pci_bus, ISABus **isa_bus, I2CBus > **smbus) > > { > > - PIIX4State *s; > > PCIDevice *pci; > > DeviceState *dev; > > int devfn = PCI_DEVFN(10, 0); > > @@ -300,22 +310,16 @@ DeviceState *piix4_create(PCIBus *pci_bus, ISABus > **isa_bus, I2CBus **smbus) > > pci = pci_create_simple_multifunction(pci_bus, devfn, true, > > TYPE_PIIX4_PCI_DEVICE); > > dev = DEVICE(pci); > > - s = PIIX4_PCI_DEVICE(pci); > > + > > if (isa_bus) { > > *isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0")); > > } > > > > - pci = pci_create_simple(pci_bus, devfn + 1, "piix4-ide"); > > - pci_ide_create_devs(pci); > > - > > - pci_create_simple(pci_bus, devfn + 2, "piix4-usb-uhci"); > > if (smbus) { > > *smbus = piix4_pm_init(pci_bus, devfn + 3, 0x1100, > > qdev_get_gpio_in_named(dev, "isa", 9), > > NULL, 0, NULL); > > } > > > > - pci_bus_irqs(pci_bus, piix4_set_irq, pci_slot_get_pirq, s, > PIIX_NUM_PIRQS); > > - > > return dev; > > } > > As long as the error handling works as required: > > Reviewed-by: Mark Cave-Ayland <mark.cave-ayl...@ilande.co.uk> > > > ATB, > > Mark. >