| Modelling a clock tree in QEMU | |
| ============================== | |
| What are clocks? | |
| ---------------- | |
| Clocks are QOM objects developed for the purpose of modelling the | |
| distribution of clocks in QEMU. | |
| They allow us to model the clock distribution of a platform and detect | |
| configuration errors in the clock tree such as badly configured PLL, clock | |
| source selection or disabled clock. | |
| The object is *Clock* and its QOM name is ``clock`` (in C code, the macro | |
| ``TYPE_CLOCK``). | |
| Clocks are typically used with devices where they are used to model inputs | |
| and outputs. They are created in a similar way to GPIOs. Inputs and outputs | |
| of different devices can be connected together. | |
| In these cases a Clock object is a child of a Device object, but this | |
| is not a requirement. Clocks can be independent of devices. For | |
| example it is possible to create a clock outside of any device to | |
| model the main clock source of a machine. | |
| Here is an example of clocks:: | |
| +---------+ +----------------------+ +--------------+ | |
| | Clock 1 | | Device B | | Device C | | |
| | | | +-------+ +-------+ | | +-------+ | | |
| | |>>-+-->>|Clock 2| |Clock 3|>>--->>|Clock 6| | | |
| +---------+ | | | (in) | | (out) | | | | (in) | | | |
| | | +-------+ +-------+ | | +-------+ | | |
| | | +-------+ | +--------------+ | |
| | | |Clock 4|>> | |
| | | | (out) | | +--------------+ | |
| | | +-------+ | | Device D | | |
| | | +-------+ | | +-------+ | | |
| | | |Clock 5|>>--->>|Clock 7| | | |
| | | | (out) | | | | (in) | | | |
| | | +-------+ | | +-------+ | | |
| | +----------------------+ | | | |
| | | +-------+ | | |
| +----------------------------->>|Clock 8| | | |
| | | (in) | | | |
| | +-------+ | | |
| +--------------+ | |
| Clocks are defined in the ``include/hw/clock.h`` header and device | |
| related functions are defined in the ``include/hw/qdev-clock.h`` | |
| header. | |
| The clock state | |
| --------------- | |
| The state of a clock is its period; it is stored as an integer | |
| representing it in units of 2 :sup:`-32` ns. The special value of 0 is used to | |
| represent the clock being inactive or gated. The clocks do not model | |
| the signal itself (pin toggling) or other properties such as the duty | |
| cycle. | |
| All clocks contain this state: outputs as well as inputs. This allows | |
| the current period of a clock to be fetched at any time. When a clock | |
| is updated, the value is immediately propagated to all connected | |
| clocks in the tree. | |
| To ease interaction with clocks, helpers with a unit suffix are defined for | |
| every clock state setter or getter. The suffixes are: | |
| - ``_ns`` for handling periods in nanoseconds | |
| - ``_hz`` for handling frequencies in hertz | |
| The 0 period value is converted to 0 in hertz and vice versa. 0 always means | |
| that the clock is disabled. | |
| Adding a new clock | |
| ------------------ | |
| Adding clocks to a device must be done during the init method of the Device | |
| instance. | |
| To add an input clock to a device, the function ``qdev_init_clock_in()`` | |
| must be used. It takes the name, a callback, an opaque parameter | |
| for the callback and a mask of events when the callback should be | |
| called (this will be explained in a following section). | |
| Output is simpler; only the name is required. Typically:: | |
| qdev_init_clock_in(DEVICE(dev), "clk_in", clk_in_callback, dev, ClockUpdate); | |
| qdev_init_clock_out(DEVICE(dev), "clk_out"); | |
| Both functions return the created Clock pointer, which should be saved in the | |
| device's state structure for further use. | |
| These objects will be automatically deleted by the QOM reference mechanism. | |
| Note that it is possible to create a static array describing clock inputs and | |
| outputs. The function ``qdev_init_clocks()`` must be called with the array as | |
| parameter to initialize the clocks: it has the same behaviour as calling the | |
| ``qdev_init_clock_in/out()`` for each clock in the array. To ease the array | |
| construction, some macros are defined in ``include/hw/qdev-clock.h``. | |
| As an example, the following creates 2 clocks to a device: one input and one | |
| output. | |
| .. code-block:: c | |
| /* device structure containing pointers to the clock objects */ | |
| typedef struct MyDeviceState { | |
| DeviceState parent_obj; | |
| Clock *clk_in; | |
| Clock *clk_out; | |
| } MyDeviceState; | |
| /* | |
| * callback for the input clock (see "Callback on input clock | |
| * change" section below for more information). | |
| */ | |
| static void clk_in_callback(void *opaque, ClockEvent event); | |
| /* | |
| * static array describing clocks: | |
| * + a clock input named "clk_in", whose pointer is stored in | |
| * the clk_in field of a MyDeviceState structure with callback | |
| * clk_in_callback. | |
| * + a clock output named "clk_out" whose pointer is stored in | |
| * the clk_out field of a MyDeviceState structure. | |
| */ | |
| static const ClockPortInitArray mydev_clocks = { | |
| QDEV_CLOCK_IN(MyDeviceState, clk_in, clk_in_callback, ClockUpdate), | |
| QDEV_CLOCK_OUT(MyDeviceState, clk_out), | |
| QDEV_CLOCK_END | |
| }; | |
| /* device initialization function */ | |
| static void mydev_init(Object *obj) | |
| { | |
| /* cast to MyDeviceState */ | |
| MyDeviceState *mydev = MYDEVICE(obj); | |
| /* create and fill the pointer fields in the MyDeviceState */ | |
| qdev_init_clocks(mydev, mydev_clocks); | |
| [...] | |
| } | |
| An alternative way to create a clock is to simply call | |
| ``object_new(TYPE_CLOCK)``. In that case the clock will neither be an | |
| input nor an output of a device. After the whole QOM hierarchy of the | |
| clock has been set ``clock_setup_canonical_path()`` should be called. | |
| At creation, the period of the clock is 0: the clock is disabled. You can | |
| change it using ``clock_set_ns()`` or ``clock_set_hz()``. | |
| Note that if you are creating a clock with a fixed period which will never | |
| change (for example the main clock source of a board), then you'll have | |
| nothing else to do. This value will be propagated to other clocks when | |
| connecting the clocks together and devices will fetch the right value during | |
| the first reset. | |
| Clock callbacks | |
| --------------- | |
| You can give a clock a callback function in several ways: | |
| * by passing it as an argument to ``qdev_init_clock_in()`` | |
| * as an argument to the ``QDEV_CLOCK_IN()`` macro initializing an | |
| array to be passed to ``qdev_init_clocks()`` | |
| * by directly calling the ``clock_set_callback()`` function | |
| The callback function must be of this type: | |
| .. code-block:: c | |
| typedef void ClockCallback(void *opaque, ClockEvent event); | |
| The ``opaque`` argument is the pointer passed to ``qdev_init_clock_in()`` | |
| or ``clock_set_callback()``; for ``qdev_init_clocks()`` it is the | |
| ``dev`` device pointer. | |
| The ``event`` argument specifies why the callback has been called. | |
| When you register the callback you specify a mask of ClockEvent values | |
| that you are interested in. The callback will only be called for those | |
| events. | |
| The events currently supported are: | |
| * ``ClockPreUpdate`` : called when the input clock's period is about to | |
| update. This is useful if the device needs to do some action for | |
| which it needs to know the old value of the clock period. During | |
| this callback, Clock API functions like ``clock_get()`` or | |
| ``clock_ticks_to_ns()`` will use the old period. | |
| * ``ClockUpdate`` : called after the input clock's period has changed. | |
| During this callback, Clock API functions like ``clock_ticks_to_ns()`` | |
| will use the new period. | |
| Note that a clock only has one callback: it is not possible to register | |
| different functions for different events. You must register a single | |
| callback which listens for all of the events you are interested in, | |
| and use the ``event`` argument to identify which event has happened. | |
| Retrieving clocks from a device | |
| ------------------------------- | |
| ``qdev_get_clock_in()`` and ``dev_get_clock_out()`` are available to | |
| get the clock inputs or outputs of a device. For example: | |
| .. code-block:: c | |
| Clock *clk = qdev_get_clock_in(DEVICE(mydev), "clk_in"); | |
| or: | |
| .. code-block:: c | |
| Clock *clk = qdev_get_clock_out(DEVICE(mydev), "clk_out"); | |
| Connecting two clocks together | |
| ------------------------------ | |
| To connect two clocks together, use the ``clock_set_source()`` function. | |
| Given two clocks ``clk1``, and ``clk2``, ``clock_set_source(clk2, clk1);`` | |
| configures ``clk2`` to follow the ``clk1`` period changes. Every time ``clk1`` | |
| is updated, ``clk2`` will be updated too. | |
| When connecting clock between devices, prefer using the | |
| ``qdev_connect_clock_in()`` function to set the source of an input | |
| device clock. For example, to connect the input clock ``clk2`` of | |
| ``devB`` to the output clock ``clk1`` of ``devA``, do: | |
| .. code-block:: c | |
| qdev_connect_clock_in(devB, "clk2", qdev_get_clock_out(devA, "clk1")) | |
| We used ``qdev_get_clock_out()`` above, but any clock can drive an | |
| input clock, even another input clock. The following diagram shows | |
| some examples of connections. Note also that a clock can drive several | |
| other clocks. | |
| :: | |
| +------------+ +--------------------------------------------------+ | |
| | Device A | | Device B | | |
| | | | +---------------------+ | | |
| | | | | Device C | | | |
| | +-------+ | | +-------+ | +-------+ +-------+ | +-------+ | | |
| | |Clock 1|>>-->>|Clock 2|>>+-->>|Clock 3| |Clock 5|>>>>|Clock 6|>> | |
| | | (out) | | | | (in) | | | | (in) | | (out) | | | (out) | | | |
| | +-------+ | | +-------+ | | +-------+ +-------+ | +-------+ | | |
| +------------+ | | +---------------------+ | | |
| | | | | |
| | | +--------------+ | | |
| | | | Device D | | | |
| | | | +-------+ | | | |
| | +-->>|Clock 4| | | | |
| | | | (in) | | | | |
| | | +-------+ | | | |
| | +--------------+ | | |
| +--------------------------------------------------+ | |
| In the above example, when *Clock 1* is updated by *Device A*, three | |
| clocks get the new clock period value: *Clock 2*, *Clock 3* and *Clock 4*. | |
| It is not possible to disconnect a clock or to change the clock connection | |
| after it is connected. | |
| Clock multiplier and divider settings | |
| ------------------------------------- | |
| By default, when clocks are connected together, the child | |
| clocks run with the same period as their source (parent) clock. | |
| The Clock API supports a built-in period multiplier/divider | |
| mechanism so you can configure a clock to make its children | |
| run at a different period from its own. If you call the | |
| ``clock_set_mul_div()`` function you can specify the clock's | |
| multiplier and divider values. The children of that clock | |
| will all run with a period of ``parent_period * multiplier / divider``. | |
| For instance, if the clock has a frequency of 8MHz and you set its | |
| multiplier to 2 and its divider to 3, the child clocks will run | |
| at 12MHz. | |
| You can change the multiplier and divider of a clock at runtime, | |
| so you can use this to model clock controller devices which | |
| have guest-programmable frequency multipliers or dividers. | |
| Note that ``clock_set_mul_div()`` does not automatically call | |
| ``clock_propagate()``. If you make a runtime change to the | |
| multiplier or divider you must call clock_propagate() yourself. | |
| Unconnected input clocks | |
| ------------------------ | |
| A newly created input clock is disabled (period of 0). This means the | |
| clock will be considered as disabled until the period is updated. If | |
| the clock remains unconnected it will always keep its initial value | |
| of 0. If this is not the desired behaviour, ``clock_set()``, | |
| ``clock_set_ns()`` or ``clock_set_hz()`` should be called on the Clock | |
| object during device instance init. For example: | |
| .. code-block:: c | |
| clk = qdev_init_clock_in(DEVICE(dev), "clk-in", clk_in_callback, | |
| dev, ClockUpdate); | |
| /* set initial value to 10ns / 100MHz */ | |
| clock_set_ns(clk, 10); | |
| To enforce that the clock is wired up by the board code, you can | |
| call ``clock_has_source()`` in your device's realize method: | |
| .. code-block:: c | |
| if (!clock_has_source(s->clk)) { | |
| error_setg(errp, "MyDevice: clk input must be connected"); | |
| return; | |
| } | |
| Note that this only checks that the clock has been wired up; it is | |
| still possible that the output clock connected to it is disabled | |
| or has not yet been configured, in which case the period will be | |
| zero. You should use the clock callback to find out when the clock | |
| period changes. | |
| Fetching clock frequency/period | |
| ------------------------------- | |
| To get the current state of a clock, use the functions ``clock_get()`` | |
| or ``clock_get_hz()``. | |
| ``clock_get()`` returns the period of the clock in its fully precise | |
| internal representation, as an unsigned 64-bit integer in units of | |
| 2^-32 nanoseconds. (For many purposes ``clock_ticks_to_ns()`` will | |
| be more convenient; see the section below on expiry deadlines.) | |
| ``clock_get_hz()`` returns the frequency of the clock, rounded to the | |
| next lowest integer. This implies some inaccuracy due to the rounding, | |
| so be cautious about using it in calculations. | |
| It is also possible to register a callback on clock frequency changes. | |
| Here is an example, which assumes that ``clock_callback`` has been | |
| specified as the callback for the ``ClockUpdate`` event: | |
| .. code-block:: c | |
| void clock_callback(void *opaque, ClockEvent event) { | |
| MyDeviceState *s = (MyDeviceState *) opaque; | |
| /* | |
| * 'opaque' is the argument passed to qdev_init_clock_in(); | |
| * usually this will be the device state pointer. | |
| */ | |
| /* do something with the new period */ | |
| fprintf(stdout, "device new period is %" PRIu64 "* 2^-32 ns\n", | |
| clock_get(dev->my_clk_input)); | |
| } | |
| If you are only interested in the frequency for displaying it to | |
| humans (for instance in debugging), use ``clock_display_freq()``, | |
| which returns a prettified string-representation, e.g. "33.3 MHz". | |
| The caller must free the string with g_free() after use. | |
| Calculating expiry deadlines | |
| ---------------------------- | |
| A commonly required operation for a clock is to calculate how long | |
| it will take for the clock to tick N times; this can then be used | |
| to set a timer expiry deadline. Use the function ``clock_ticks_to_ns()``, | |
| which takes an unsigned 64-bit count of ticks and returns the length | |
| of time in nanoseconds required for the clock to tick that many times. | |
| It is important not to try to calculate expiry deadlines using a | |
| shortcut like multiplying a "period of clock in nanoseconds" value | |
| by the tick count, because clocks can have periods which are not a | |
| whole number of nanoseconds, and the accumulated error in the | |
| multiplication can be significant. | |
| For a clock with a very long period and a large number of ticks, | |
| the result of this function could in theory be too large to fit in | |
| a 64-bit value. To avoid overflow in this case, ``clock_ticks_to_ns()`` | |
| saturates the result to INT64_MAX (because this is the largest valid | |
| input to the QEMUTimer APIs). Since INT64_MAX nanoseconds is almost | |
| 300 years, anything with an expiry later than that is in the "will | |
| never happen" category. Callers of ``clock_ticks_to_ns()`` should | |
| therefore generally not special-case the possibility of a saturated | |
| result but just allow the timer to be set to that far-future value. | |
| (If you are performing further calculations on the returned value | |
| rather than simply passing it to a QEMUTimer function like | |
| ``timer_mod_ns()`` then you should be careful to avoid overflow | |
| in those calculations, of course.) | |
| Obtaining tick counts | |
| --------------------- | |
| For calculations where you need to know the number of ticks in | |
| a given duration, use ``clock_ns_to_ticks()``. This function handles | |
| possible non-whole-number-of-nanoseconds periods and avoids | |
| potential rounding errors. It will return '0' if the clock is stopped | |
| (i.e. it has period zero). If the inputs imply a tick count that | |
| overflows a 64-bit value (a very long duration for a clock with a | |
| very short period) the output value is truncated, so effectively | |
| the 64-bit output wraps around. | |
| Changing a clock period | |
| ----------------------- | |
| A device can change its outputs using the ``clock_update()``, | |
| ``clock_update_ns()`` or ``clock_update_hz()`` function. It will trigger | |
| updates on every connected input. | |
| For example, let's say that we have an output clock *clkout* and we | |
| have a pointer to it in the device state because we did the following | |
| in init phase: | |
| .. code-block:: c | |
| dev->clkout = qdev_init_clock_out(DEVICE(dev), "clkout"); | |
| Then at any time (apart from the cases listed below), it is possible to | |
| change the clock value by doing: | |
| .. code-block:: c | |
| clock_update_hz(dev->clkout, 1000 * 1000 * 1000); /* 1GHz */ | |
| Because updating a clock may trigger any side effects through | |
| connected clocks and their callbacks, this operation must be done | |
| while holding the qemu io lock. | |
| For the same reason, one can update clocks only when it is allowed to have | |
| side effects on other objects. In consequence, it is forbidden: | |
| * during migration, | |
| * and in the enter phase of reset. | |
| Note that calling ``clock_update[_ns|_hz]()`` is equivalent to calling | |
| ``clock_set[_ns|_hz]()`` (with the same arguments) then | |
| ``clock_propagate()`` on the clock. Thus, setting the clock value can | |
| be separated from triggering the side-effects. This is often required | |
| to factorize code to handle reset and migration in devices. | |
| Aliasing clocks | |
| --------------- | |
| Sometimes, one needs to forward, or inherit, a clock from another | |
| device. Typically, when doing device composition, a device might | |
| expose a sub-device's clock without interfering with it. The function | |
| ``qdev_alias_clock()`` can be used to achieve this behaviour. Note | |
| that it is possible to expose the clock under a different name. | |
| ``qdev_alias_clock()`` works for both input and output clocks. | |
| For example, if device B is a child of device A, | |
| ``device_a_instance_init()`` may do something like this: | |
| .. code-block:: c | |
| void device_a_instance_init(Object *obj) | |
| { | |
| AState *A = DEVICE_A(obj); | |
| BState *B; | |
| /* create object B as child of A */ | |
| [...] | |
| qdev_alias_clock(B, "clk", A, "b_clk"); | |
| /* | |
| * Now A has a clock "b_clk" which is an alias to | |
| * the clock "clk" of its child B. | |
| */ | |
| } | |
| This function does not return any clock object. The new clock has the | |
| same direction (input or output) as the original one. This function | |
| only adds a link to the existing clock. In the above example, object B | |
| remains the only object allowed to use the clock and device A must not | |
| try to change the clock period or set a callback to the clock. This | |
| diagram describes the example with an input clock:: | |
| +--------------------------+ | |
| | Device A | | |
| | +--------------+ | | |
| | | Device B | | | |
| | | +-------+ | | | |
| >>"b_clk">>>| "clk" | | | | |
| | (in) | | (in) | | | | |
| | | +-------+ | | | |
| | +--------------+ | | |
| +--------------------------+ | |
| Migration | |
| --------- | |
| Clock state is not migrated automatically. Every device must handle its | |
| clock migration. Alias clocks must not be migrated. | |
| To ensure clock states are restored correctly during migration, there | |
| are two solutions. | |
| Clock states can be migrated by adding an entry into the device | |
| vmstate description. You should use the ``VMSTATE_CLOCK`` macro for this. | |
| This is typically used to migrate an input clock state. For example: | |
| .. code-block:: c | |
| MyDeviceState { | |
| DeviceState parent_obj; | |
| [...] /* some fields */ | |
| Clock *clk; | |
| }; | |
| VMStateDescription my_device_vmstate = { | |
| .name = "my_device", | |
| .fields = (VMStateField[]) { | |
| [...], /* other migrated fields */ | |
| VMSTATE_CLOCK(clk, MyDeviceState), | |
| VMSTATE_END_OF_LIST() | |
| } | |
| }; | |
| The second solution is to restore the clock state using information already | |
| at our disposal. This can be used to restore output clock states using the | |
| device state. The functions ``clock_set[_ns|_hz]()`` can be used during the | |
| ``post_load()`` migration callback. | |
| When adding clock support to an existing device, if you care about | |
| migration compatibility you will need to be careful, as simply adding | |
| a ``VMSTATE_CLOCK()`` line will break compatibility. Instead, you can | |
| put the ``VMSTATE_CLOCK()`` line into a vmstate subsection with a | |
| suitable ``needed`` function, and use ``clock_set()`` in a | |
| ``pre_load()`` function to set the default value that will be used if | |
| the source virtual machine in the migration does not send the clock | |
| state. | |
| Care should be taken not to use ``clock_update[_ns|_hz]()`` or | |
| ``clock_propagate()`` during the whole migration procedure because it | |
| will trigger side effects to other devices in an unknown state. |