On 2011-11-02 18:44, Fabien Chouteau wrote: > On 31/10/2011 14:12, Peter Maydell wrote: >> On 29 October 2011 14:52, Alexander Graf <ag...@suse.de> wrote: >>> A lot of people seem to also have code that doesn't make sense >>> upstream, for example implementing a one-off device that only >>> really matters for their own devboard which nobody else owns. >>> For such cases, having a plugin framework would be handy. I >>> interestingly enough got into the same discussion on LinuxCon >>> with some QEMU downstreams. >> >> If we get the qdev rework done then I think we're probably in >> a better position to have a plugin framework for devices. (There >> are some issues about API and ABI stability guarantees, of course.) >> > > Interesting, we have a "plug-in" implementation in our Qemu branch. It
We have a "plugin" model here as well. It's really simple: the plugin is loaded dynamically into the QEMU process and can access any global function and variable. Of course, this breaks regularly. > allows a plug-ins to register io_areas, read and write callback, trigger > interrupts, etc... > > Qemu provides this interface to the plug-in: > > struct QemuPlugin_Emulator > { > uint64_t (*get_time)(QemuPlugin_ClockType clock); > > > uint32_t (*add_event)(uint64_t expire_time, > QemuPlugin_ClockType clock, > uint32_t event_id, > EventCallback event, > void *opaque); > > uint32_t (*remove_event)(QemuPlugin_ClockType clock, > uint32_t event_id); > > uint32_t (*set_irq)(uint32_t line, uint32_t level); > > uint32_t (*dma_read)(void *dest, > target_addr_t addr, > int size); > > uint32_t (*dma_write)(void *src, > target_addr_t addr, > int size); > > uint32_t (*attach_device)(QemuPlugin_DeviceInfo *dev); > > uint32_t version; > }; > > and the plug-in provides this interface to Qemu: > > typedef uint32_t io_read_fn(void *opaque, target_addr_t addr, uint32_t size); > > typedef void io_write_fn(void *opaque, > target_addr_t addr, > uint32_t size, > uint32_t val); > > typedef void reset_fn(void *opaque); > typedef void init_fn(void *opaque); > typedef void exit_fn(void *opaque); > > typedef struct QemuPlugin_DeviceInfo > { > uint32_t version; > > uint32_t vendor_id; > uint32_t device_id; > char name[NAME_LENGTH]; > char desc[DESC_LENGTH]; > > void *opaque; > > io_read_fn *io_read; > io_write_fn *io_write; > > reset_fn *pdevice_reset; > init_fn *pdevice_init; > exit_fn *pdevice_exit; > > uint32_t nr_iomem; > struct QemuPlugin_IOMemory > { > target_addr_t base; > target_addr_t size; > } iomem[MAX_IOMEM]; > } QemuPlugin_DeviceInfo; > To implement, e.g., a custom PCI device, you still need a stub in QEMU with that model. But you want access to the PCI layer, the MSI services, etc. anyway - unless you plan to reinvent all that wheels. Another example: How do you model a USB device this way? IOW, we need a plugin model that can interact with other components at their interface level, not only through a central, naturally restricted one. Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux