summaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/devel/clocks.rst71
-rw-r--r--docs/system/arm/mps2.rst6
2 files changed, 67 insertions, 10 deletions
diff --git a/docs/devel/clocks.rst b/docs/devel/clocks.rst
index c54bbb8240..956bd147ea 100644
--- a/docs/devel/clocks.rst
+++ b/docs/devel/clocks.rst
@@ -80,11 +80,12 @@ 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 and an opaque parameter
-for the callback (this will be explained in a following section).
+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);
+ 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
@@ -113,7 +114,7 @@ output.
* callback for the input clock (see "Callback on input clock
* change" section below for more information).
*/
- static void clk_in_callback(void *opaque);
+ static void clk_in_callback(void *opaque, ClockEvent event);
/*
* static array describing clocks:
@@ -124,7 +125,7 @@ output.
* the clk_out field of a MyDeviceState structure.
*/
static const ClockPortInitArray mydev_clocks = {
- QDEV_CLOCK_IN(MyDeviceState, clk_in, clk_in_callback),
+ QDEV_CLOCK_IN(MyDeviceState, clk_in, clk_in_callback, ClockUpdate),
QDEV_CLOCK_OUT(MyDeviceState, clk_out),
QDEV_CLOCK_END
};
@@ -153,6 +154,47 @@ 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
-------------------------------
@@ -231,7 +273,7 @@ object during device instance init. For example:
.. code-block:: c
clk = qdev_init_clock_in(DEVICE(dev), "clk-in", clk_in_callback,
- dev);
+ dev, ClockUpdate);
/* set initial value to 10ns / 100MHz */
clock_set_ns(clk, 10);
@@ -267,11 +309,12 @@ 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:
+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) {
+ void clock_callback(void *opaque, ClockEvent event) {
MyDeviceState *s = (MyDeviceState *) opaque;
/*
* 'opaque' is the argument passed to qdev_init_clock_in();
@@ -317,6 +360,18 @@ 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
-----------------------
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
index 601ccea15c..f83b151787 100644
--- a/docs/system/arm/mps2.rst
+++ b/docs/system/arm/mps2.rst
@@ -1,5 +1,5 @@
-Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``)
-=========================================================================================================================================
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an547``)
+=========================================================================================================================================================
These board models all use Arm M-profile CPUs.
@@ -27,6 +27,8 @@ QEMU models the following FPGA images:
Dual Cortex-M33 as documented in Arm Application Note AN521
``mps3-an524``
Dual Cortex-M33 on an MPS3, as documented in Arm Application Note AN524
+``mps3-an547``
+ Cortex-M55 on an MPS3, as documented in Arm Application Note AN547
Differences between QEMU and real hardware: