]>
Commit | Line | Data |
---|---|---|
31e5784a PM |
1 | Modelling a clock tree in QEMU |
2 | ============================== | |
3 | ||
4 | What are clocks? | |
5 | ---------------- | |
6 | ||
7 | Clocks are QOM objects developed for the purpose of modelling the | |
8 | distribution of clocks in QEMU. | |
9 | ||
10 | They allow us to model the clock distribution of a platform and detect | |
11 | configuration errors in the clock tree such as badly configured PLL, clock | |
12 | source selection or disabled clock. | |
13 | ||
14 | The object is *Clock* and its QOM name is ``clock`` (in C code, the macro | |
15 | ``TYPE_CLOCK``). | |
16 | ||
17 | Clocks are typically used with devices where they are used to model inputs | |
18 | and outputs. They are created in a similar way to GPIOs. Inputs and outputs | |
19 | of different devices can be connected together. | |
20 | ||
21 | In these cases a Clock object is a child of a Device object, but this | |
22 | is not a requirement. Clocks can be independent of devices. For | |
23 | example it is possible to create a clock outside of any device to | |
24 | model the main clock source of a machine. | |
25 | ||
26 | Here is an example of clocks:: | |
27 | ||
28 | +---------+ +----------------------+ +--------------+ | |
29 | | Clock 1 | | Device B | | Device C | | |
30 | | | | +-------+ +-------+ | | +-------+ | | |
31 | | |>>-+-->>|Clock 2| |Clock 3|>>--->>|Clock 6| | | |
32 | +---------+ | | | (in) | | (out) | | | | (in) | | | |
33 | | | +-------+ +-------+ | | +-------+ | | |
34 | | | +-------+ | +--------------+ | |
35 | | | |Clock 4|>> | |
36 | | | | (out) | | +--------------+ | |
37 | | | +-------+ | | Device D | | |
38 | | | +-------+ | | +-------+ | | |
39 | | | |Clock 5|>>--->>|Clock 7| | | |
40 | | | | (out) | | | | (in) | | | |
41 | | | +-------+ | | +-------+ | | |
42 | | +----------------------+ | | | |
43 | | | +-------+ | | |
44 | +----------------------------->>|Clock 8| | | |
45 | | | (in) | | | |
46 | | +-------+ | | |
47 | +--------------+ | |
48 | ||
49 | Clocks are defined in the ``include/hw/clock.h`` header and device | |
50 | related functions are defined in the ``include/hw/qdev-clock.h`` | |
51 | header. | |
52 | ||
53 | The clock state | |
54 | --------------- | |
55 | ||
56 | The state of a clock is its period; it is stored as an integer | |
57 | representing it in units of 2 :sup:`-32` ns. The special value of 0 is used to | |
58 | represent the clock being inactive or gated. The clocks do not model | |
59 | the signal itself (pin toggling) or other properties such as the duty | |
60 | cycle. | |
61 | ||
62 | All clocks contain this state: outputs as well as inputs. This allows | |
63 | the current period of a clock to be fetched at any time. When a clock | |
64 | is updated, the value is immediately propagated to all connected | |
65 | clocks in the tree. | |
66 | ||
67 | To ease interaction with clocks, helpers with a unit suffix are defined for | |
68 | every clock state setter or getter. The suffixes are: | |
69 | ||
70 | - ``_ns`` for handling periods in nanoseconds | |
71 | - ``_hz`` for handling frequencies in hertz | |
72 | ||
73 | The 0 period value is converted to 0 in hertz and vice versa. 0 always means | |
74 | that the clock is disabled. | |
75 | ||
76 | Adding a new clock | |
77 | ------------------ | |
78 | ||
79 | Adding clocks to a device must be done during the init method of the Device | |
80 | instance. | |
81 | ||
82 | To add an input clock to a device, the function ``qdev_init_clock_in()`` | |
83 | must be used. It takes the name, a callback and an opaque parameter | |
84 | for the callback (this will be explained in a following section). | |
85 | Output is simpler; only the name is required. Typically:: | |
86 | ||
87 | qdev_init_clock_in(DEVICE(dev), "clk_in", clk_in_callback, dev); | |
88 | qdev_init_clock_out(DEVICE(dev), "clk_out"); | |
89 | ||
90 | Both functions return the created Clock pointer, which should be saved in the | |
91 | device's state structure for further use. | |
92 | ||
93 | These objects will be automatically deleted by the QOM reference mechanism. | |
94 | ||
95 | Note that it is possible to create a static array describing clock inputs and | |
96 | outputs. The function ``qdev_init_clocks()`` must be called with the array as | |
97 | parameter to initialize the clocks: it has the same behaviour as calling the | |
98 | ``qdev_init_clock_in/out()`` for each clock in the array. To ease the array | |
99 | construction, some macros are defined in ``include/hw/qdev-clock.h``. | |
100 | As an example, the following creates 2 clocks to a device: one input and one | |
101 | output. | |
102 | ||
103 | .. code-block:: c | |
104 | ||
105 | /* device structure containing pointers to the clock objects */ | |
106 | typedef struct MyDeviceState { | |
107 | DeviceState parent_obj; | |
108 | Clock *clk_in; | |
109 | Clock *clk_out; | |
110 | } MyDeviceState; | |
111 | ||
112 | /* | |
113 | * callback for the input clock (see "Callback on input clock | |
114 | * change" section below for more information). | |
115 | */ | |
116 | static void clk_in_callback(void *opaque); | |
117 | ||
118 | /* | |
119 | * static array describing clocks: | |
120 | * + a clock input named "clk_in", whose pointer is stored in | |
121 | * the clk_in field of a MyDeviceState structure with callback | |
122 | * clk_in_callback. | |
123 | * + a clock output named "clk_out" whose pointer is stored in | |
124 | * the clk_out field of a MyDeviceState structure. | |
125 | */ | |
126 | static const ClockPortInitArray mydev_clocks = { | |
127 | QDEV_CLOCK_IN(MyDeviceState, clk_in, clk_in_callback), | |
128 | QDEV_CLOCK_OUT(MyDeviceState, clk_out), | |
129 | QDEV_CLOCK_END | |
130 | }; | |
131 | ||
132 | /* device initialization function */ | |
133 | static void mydev_init(Object *obj) | |
134 | { | |
135 | /* cast to MyDeviceState */ | |
136 | MyDeviceState *mydev = MYDEVICE(obj); | |
137 | /* create and fill the pointer fields in the MyDeviceState */ | |
138 | qdev_init_clocks(mydev, mydev_clocks); | |
139 | [...] | |
140 | } | |
141 | ||
142 | An alternative way to create a clock is to simply call | |
143 | ``object_new(TYPE_CLOCK)``. In that case the clock will neither be an | |
144 | input nor an output of a device. After the whole QOM hierarchy of the | |
145 | clock has been set ``clock_setup_canonical_path()`` should be called. | |
146 | ||
147 | At creation, the period of the clock is 0: the clock is disabled. You can | |
148 | change it using ``clock_set_ns()`` or ``clock_set_hz()``. | |
149 | ||
150 | Note that if you are creating a clock with a fixed period which will never | |
151 | change (for example the main clock source of a board), then you'll have | |
152 | nothing else to do. This value will be propagated to other clocks when | |
153 | connecting the clocks together and devices will fetch the right value during | |
154 | the first reset. | |
155 | ||
156 | Retrieving clocks from a device | |
157 | ------------------------------- | |
158 | ||
159 | ``qdev_get_clock_in()`` and ``dev_get_clock_out()`` are available to | |
160 | get the clock inputs or outputs of a device. For example: | |
161 | ||
162 | .. code-block:: c | |
163 | ||
164 | Clock *clk = qdev_get_clock_in(DEVICE(mydev), "clk_in"); | |
165 | ||
166 | or: | |
167 | ||
168 | .. code-block:: c | |
169 | ||
170 | Clock *clk = qdev_get_clock_out(DEVICE(mydev), "clk_out"); | |
171 | ||
172 | Connecting two clocks together | |
173 | ------------------------------ | |
174 | ||
175 | To connect two clocks together, use the ``clock_set_source()`` function. | |
176 | Given two clocks ``clk1``, and ``clk2``, ``clock_set_source(clk2, clk1);`` | |
177 | configures ``clk2`` to follow the ``clk1`` period changes. Every time ``clk1`` | |
178 | is updated, ``clk2`` will be updated too. | |
179 | ||
180 | When connecting clock between devices, prefer using the | |
181 | ``qdev_connect_clock_in()`` function to set the source of an input | |
182 | device clock. For example, to connect the input clock ``clk2`` of | |
183 | ``devB`` to the output clock ``clk1`` of ``devA``, do: | |
184 | ||
185 | .. code-block:: c | |
186 | ||
187 | qdev_connect_clock_in(devB, "clk2", qdev_get_clock_out(devA, "clk1")) | |
188 | ||
189 | We used ``qdev_get_clock_out()`` above, but any clock can drive an | |
190 | input clock, even another input clock. The following diagram shows | |
191 | some examples of connections. Note also that a clock can drive several | |
192 | other clocks. | |
193 | ||
194 | :: | |
195 | ||
196 | +------------+ +--------------------------------------------------+ | |
197 | | Device A | | Device B | | |
198 | | | | +---------------------+ | | |
199 | | | | | Device C | | | |
200 | | +-------+ | | +-------+ | +-------+ +-------+ | +-------+ | | |
201 | | |Clock 1|>>-->>|Clock 2|>>+-->>|Clock 3| |Clock 5|>>>>|Clock 6|>> | |
202 | | | (out) | | | | (in) | | | | (in) | | (out) | | | (out) | | | |
203 | | +-------+ | | +-------+ | | +-------+ +-------+ | +-------+ | | |
204 | +------------+ | | +---------------------+ | | |
205 | | | | | |
206 | | | +--------------+ | | |
207 | | | | Device D | | | |
208 | | | | +-------+ | | | |
209 | | +-->>|Clock 4| | | | |
210 | | | | (in) | | | | |
211 | | | +-------+ | | | |
212 | | +--------------+ | | |
213 | +--------------------------------------------------+ | |
214 | ||
215 | In the above example, when *Clock 1* is updated by *Device A*, three | |
216 | clocks get the new clock period value: *Clock 2*, *Clock 3* and *Clock 4*. | |
217 | ||
218 | It is not possible to disconnect a clock or to change the clock connection | |
219 | after it is connected. | |
220 | ||
221 | Unconnected input clocks | |
222 | ------------------------ | |
223 | ||
224 | A newly created input clock is disabled (period of 0). This means the | |
225 | clock will be considered as disabled until the period is updated. If | |
226 | the clock remains unconnected it will always keep its initial value | |
227 | of 0. If this is not the desired behaviour, ``clock_set()``, | |
228 | ``clock_set_ns()`` or ``clock_set_hz()`` should be called on the Clock | |
229 | object during device instance init. For example: | |
230 | ||
231 | .. code-block:: c | |
232 | ||
233 | clk = qdev_init_clock_in(DEVICE(dev), "clk-in", clk_in_callback, | |
234 | dev); | |
235 | /* set initial value to 10ns / 100MHz */ | |
236 | clock_set_ns(clk, 10); | |
237 | ||
238 | Fetching clock frequency/period | |
239 | ------------------------------- | |
240 | ||
241 | To get the current state of a clock, use the functions ``clock_get()``, | |
242 | ``clock_get_ns()`` or ``clock_get_hz()``. | |
243 | ||
244 | It is also possible to register a callback on clock frequency changes. | |
245 | Here is an example: | |
246 | ||
247 | .. code-block:: c | |
248 | ||
249 | void clock_callback(void *opaque) { | |
250 | MyDeviceState *s = (MyDeviceState *) opaque; | |
251 | /* | |
252 | * 'opaque' is the argument passed to qdev_init_clock_in(); | |
253 | * usually this will be the device state pointer. | |
254 | */ | |
255 | ||
256 | /* do something with the new period */ | |
257 | fprintf(stdout, "device new period is %" PRIu64 "ns\n", | |
258 | clock_get_ns(dev->my_clk_input)); | |
259 | } | |
260 | ||
261 | Changing a clock period | |
262 | ----------------------- | |
263 | ||
264 | A device can change its outputs using the ``clock_update()``, | |
265 | ``clock_update_ns()`` or ``clock_update_hz()`` function. It will trigger | |
266 | updates on every connected input. | |
267 | ||
268 | For example, let's say that we have an output clock *clkout* and we | |
269 | have a pointer to it in the device state because we did the following | |
270 | in init phase: | |
271 | ||
272 | .. code-block:: c | |
273 | ||
274 | dev->clkout = qdev_init_clock_out(DEVICE(dev), "clkout"); | |
275 | ||
276 | Then at any time (apart from the cases listed below), it is possible to | |
277 | change the clock value by doing: | |
278 | ||
279 | .. code-block:: c | |
280 | ||
281 | clock_update_hz(dev->clkout, 1000 * 1000 * 1000); /* 1GHz */ | |
282 | ||
283 | Because updating a clock may trigger any side effects through | |
284 | connected clocks and their callbacks, this operation must be done | |
285 | while holding the qemu io lock. | |
286 | ||
287 | For the same reason, one can update clocks only when it is allowed to have | |
288 | side effects on other objects. In consequence, it is forbidden: | |
289 | ||
290 | * during migration, | |
291 | * and in the enter phase of reset. | |
292 | ||
293 | Note that calling ``clock_update[_ns|_hz]()`` is equivalent to calling | |
294 | ``clock_set[_ns|_hz]()`` (with the same arguments) then | |
295 | ``clock_propagate()`` on the clock. Thus, setting the clock value can | |
296 | be separated from triggering the side-effects. This is often required | |
297 | to factorize code to handle reset and migration in devices. | |
298 | ||
299 | Aliasing clocks | |
300 | --------------- | |
301 | ||
302 | Sometimes, one needs to forward, or inherit, a clock from another | |
303 | device. Typically, when doing device composition, a device might | |
304 | expose a sub-device's clock without interfering with it. The function | |
305 | ``qdev_alias_clock()`` can be used to achieve this behaviour. Note | |
306 | that it is possible to expose the clock under a different name. | |
307 | ``qdev_alias_clock()`` works for both input and output clocks. | |
308 | ||
309 | For example, if device B is a child of device A, | |
310 | ``device_a_instance_init()`` may do something like this: | |
311 | ||
312 | .. code-block:: c | |
313 | ||
314 | void device_a_instance_init(Object *obj) | |
315 | { | |
316 | AState *A = DEVICE_A(obj); | |
317 | BState *B; | |
318 | /* create object B as child of A */ | |
319 | [...] | |
320 | qdev_alias_clock(B, "clk", A, "b_clk"); | |
321 | /* | |
322 | * Now A has a clock "b_clk" which is an alias to | |
323 | * the clock "clk" of its child B. | |
324 | */ | |
325 | } | |
326 | ||
327 | This function does not return any clock object. The new clock has the | |
328 | same direction (input or output) as the original one. This function | |
329 | only adds a link to the existing clock. In the above example, object B | |
330 | remains the only object allowed to use the clock and device A must not | |
331 | try to change the clock period or set a callback to the clock. This | |
332 | diagram describes the example with an input clock:: | |
333 | ||
334 | +--------------------------+ | |
335 | | Device A | | |
336 | | +--------------+ | | |
337 | | | Device B | | | |
338 | | | +-------+ | | | |
339 | >>"b_clk">>>| "clk" | | | | |
340 | | (in) | | (in) | | | | |
341 | | | +-------+ | | | |
342 | | +--------------+ | | |
343 | +--------------------------+ | |
344 | ||
345 | Migration | |
346 | --------- | |
347 | ||
348 | Clock state is not migrated automatically. Every device must handle its | |
349 | clock migration. Alias clocks must not be migrated. | |
350 | ||
351 | To ensure clock states are restored correctly during migration, there | |
352 | are two solutions. | |
353 | ||
354 | Clock states can be migrated by adding an entry into the device | |
355 | vmstate description. You should use the ``VMSTATE_CLOCK`` macro for this. | |
356 | This is typically used to migrate an input clock state. For example: | |
357 | ||
358 | .. code-block:: c | |
359 | ||
360 | MyDeviceState { | |
361 | DeviceState parent_obj; | |
362 | [...] /* some fields */ | |
363 | Clock *clk; | |
364 | }; | |
365 | ||
366 | VMStateDescription my_device_vmstate = { | |
367 | .name = "my_device", | |
368 | .fields = (VMStateField[]) { | |
369 | [...], /* other migrated fields */ | |
370 | VMSTATE_CLOCK(clk, MyDeviceState), | |
371 | VMSTATE_END_OF_LIST() | |
372 | } | |
373 | }; | |
374 | ||
375 | The second solution is to restore the clock state using information already | |
376 | at our disposal. This can be used to restore output clock states using the | |
377 | device state. The functions ``clock_set[_ns|_hz]()`` can be used during the | |
378 | ``post_load()`` migration callback. | |
379 | ||
380 | When adding clock support to an existing device, if you care about | |
381 | migration compatibility you will need to be careful, as simply adding | |
382 | a ``VMSTATE_CLOCK()`` line will break compatibility. Instead, you can | |
383 | put the ``VMSTATE_CLOCK()`` line into a vmstate subsection with a | |
384 | suitable ``needed`` function, and use ``clock_set()`` in a | |
385 | ``pre_load()`` function to set the default value that will be used if | |
386 | the source virtual machine in the migration does not send the clock | |
387 | state. | |
388 | ||
389 | Care should be taken not to use ``clock_update[_ns|_hz]()`` or | |
390 | ``clock_propagate()`` during the whole migration procedure because it | |
391 | will trigger side effects to other devices in an unknown state. |