qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: sysbus_create_simple Vs qdev_create


From: Markus Armbruster
Subject: Re: sysbus_create_simple Vs qdev_create
Date: Wed, 15 Jul 2020 10:32:14 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)

Philippe Mathieu-Daudé <philmd@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!




reply via email to

[Prev in Thread] Current Thread [Next in Thread]