Philippe Mathieu-Daudé <phi...@redhat.com> writes: > Hi Pratik, > > On 7/14/20 6:17 PM, Pratik Parvati wrote: >> Here is a brief context that might help you. >> I am referring hw/arm/versatilepb.c >> >> The ARM PrimeCell UART (PL011) device created as follows >> >> dev = qdev_create(NULL, "pl011"); >> s = SYS_BUS_DEVICE(dev); >> qdev_prop_set_chr(dev, "chardev", chr); >> qdev_init_nofail(dev); >> sysbus_mmio_map(s, 0, addr); >> sysbus_connect_irq(s, 0, irq);
This is pl011_create(). Since recent merge commit 6675a653d2e, it's dev = qdev_new("pl011"); s = SYS_BUS_DEVICE(dev); qdev_prop_set_chr(dev, "chardev", chr); sysbus_realize_and_unref(s, &error_fatal); sysbus_mmio_map(s, 0, addr); sysbus_connect_irq(s, 0, irq); >> >> Whereas the PL031 RTC device is created as >> >> /* Add PL031 Real Time Clock. */ >> sysbus_create_simple("pl031", 0x101e8000, pic[10]); >> >> What is the difference between these two devices creation? > > Both devices inherit SysBusDevice, which itself inherits QDev. Yes: TYPE_SYS_BUS_DEVICE is a subtype of TYPE_DEVICE. > You can create QDev objects with the qdev API, and > SysBusDevice objects with the sysbus API. Yes. qdev_new(), qdev_realize_and_unref(), ... work with DeviceState * (the C type of an instance of QOM TYPE_DEVICE). sysbus_realize_and_unref(), ... work with SysBusDevice * (the C type of an instance of QOM TYPE_SYS_BUS_DEVICE). Since TYPE_SYS_BUS_DEVICE is a subtype of TYPE_DEVICE, you can safely use qdev_ functions with sysbus devices. Example: pl011_create() uses qdev_new() to create a sysbus device. That's fine. > sysbus_create_simple() is a condensed helper, but only allow you > to pass qemu_irq objects, not a 'chardev' property. So for this > case you have to use the qdev API instead. Yes. It's a helper that combines creating a sysbus device, wiring up one MMIO region and one IRQ, and realizing. If you need to configure or wire up more than that, you can't use it. >> How do I know >> which method to use while creating an object? > > SysBusDevice are plugged onto a bus. QDev aren't. > The sysbus API results in smaller code, easier to review. The general pattern for a stand-alone device is dev = qdev_new(type_name); set properties and wire up stuff... qdev_realize_and_unref(dev, bus, &err); When this is to be done in device code, say to create a component device, the split between .instance_init() and .realize() complicates things. If interested, ask and I'll explain. There are quite a few wrappers around qdev_ functions for various subtypes of TYPE_DEVICE. Use them to make your code more concise and easier to understand. Example: sysbus_realize_and_unref(). There are also convenience functions that capture special cases of the entire general pattern. Example: sysbus_create_simple(). Hope this helps!