At the moment you can't really implement one sysbus device by saying that it's composed of a set of other sysbus devices. This patch adds new functions sysbus_pass_mmio() and sysbus_pass_one_irq() which allow a sysbus device to delegate an MMIO or IRQ to another sysbus device (The approach is inspired by the existing sysbus_pass_irq() which lets a sysbus device delegate all its IRQs at once).
This works; the most obvious deficiency is that the subcomponent device will still appear as its own device on the bus. So: is this a reasonable solution to the problem, or an unacceptable hack? Comments welcome :-) The patchset includes a patch from Juha which implements resizing and unmapping of sysbus MMIOs; this is sort of related but useful on its own anyway [ie you're likely to see it again even if you don't like patches 2 and 3 :-)] Here's an example device init function that uses this: static int omap3_hsusb_host_init(SysBusDevice *dev) { OMAP3HSUSBHostState *s = FROM_SYSBUS(OMAP3HSUSBHostState, dev); SysBusDevice *ohci_busdev; /* Create the OHCI device which is our subcomponent */ s->ohci_usb = qdev_create(dev->qdev.parent_bus, "sysbus-ohci"); qdev_prop_set_uint32(s->ohci_usb, "num-ports", 3); qdev_prop_set_taddr(s->ohci_usb, "dma-offset", 0); qdev_init_nofail(s->ohci_usb); ohci_busdev = sysbus_from_qdev(s->ohci_usb); /* Our IRQ 0 is delegated to the OHCI; 1 and 2 we handle ourselves */ sysbus_pass_one_irq(dev, ohci_busdev, 0); sysbus_init_irq(dev, &s->ehci_irq); sysbus_init_irq(dev, &s->tll_irq); /* MMIOs 0 and 1 created as usual and handled ourselves */ sysbus_init_mmio(dev, 0x1000, cpu_register_io_memory(omap3_hsusb_tll_readfn, omap3_hsusb_tll_writefn, s, DEVICE_NATIVE_ENDIAN)); sysbus_init_mmio(dev, 0x400, cpu_register_io_memory(omap3_hsusb_host_readfn, omap3_hsusb_host_writefn, s, DEVICE_NATIVE_ENDIAN)); /* Resize the OHCI MMIO to fit our requirements, and expose it * as our MMIO 2 */ sysbus_mmio_resize(ohci_busdev, 0, 0x400); sysbus_pass_mmio(dev, ohci_busdev, 0); /* MMIO 3 is another normal case */ sysbus_init_mmio(dev, 0x400, cpu_register_io_memory(omap3_hsusb_ehci_readfn, omap3_hsusb_ehci_writefn, s, DEVICE_NATIVE_ENDIAN)); vmstate_register(&dev->qdev, -1, &vmstate_omap3_hsusb_host, s); return 0; } Juha Riihimäki (1): sysbus: Add support for resizing and unmapping MMIOs Peter Maydell (2): sysbus: Allow sysbus MMIO passthrough sysbus: Allow passthrough of single IRQ hw/sysbus.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/sysbus.h | 6 +++++ 2 files changed, 78 insertions(+), 0 deletions(-)