Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UUID usage on SOF #245

Merged
merged 2 commits into from
Jun 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions developer_guides/firmware/components/component-overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ uAPI to create a component of that ``type``. It also provides an entry point
to the component ops implementation.

UUIDs (Universally Unique Identifiers) provide a more scalable and
collision-free way of component identification. UUIDs are currently used by
the tracing subsystem while both the topology and driver still depend on
``type`` to define topology and create component instances. UUIDs are
expected to replace the ``type`` in these parts as well.
collision-free way of component identification. UUIDs are currently used as
the standard interface by all users of the SOF firmware, including the
tracing subsystem, the topology .m4 files, and the Linux topology driver.
Using the ``type`` to define topology and create component is still supported
today, but the ``type`` could be moved out of the IPC struct in the future,
so allocating UUID for the new added component driver is *mandatory* now.

The UUID entry declared in the FW code contains the identifier value as well
as the object which is the component name in this case. Both are
Expand Down
1 change: 1 addition & 0 deletions developer_guides/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ terminology before reading further.
firmware/index
unit_tests
topology/topology
uuid/index.rst
debugability/index
tuning/sof-ctl
rimage/index.rst
Expand Down
129 changes: 129 additions & 0 deletions developer_guides/uuid/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
.. _uuid:

UUID Usage in SOF
#################

Why UUID Needed
***************

To develop a new audio signal processing component, we traditionally
implemented the component driver with a new unique component type
introduced. The pain points with this method include how to keep the
ABI (Application Binary Interface) aligned for the topology file, the
driver, and the firmware. And if unaligned, how should we make them
backward compatible. For example, When adding a new component, we could
have 8 types of combination of topology/driver/firmware versions with
either the new component is supported or not in each
topology/driver/firmware part. Even more, if enumerated type is used
for the component type and the sequence in the enumerate list
(the value) is changed during an update, there could be component type
collision if versions are not aligned.

UUIDs (Universally Unique Identifiers) provide a more scalable and
collision-free way of component identification. UUIDs are used as the
standard interface by all users of the SOF firmware, including the
tracing subsystem, the topology .m4 files, and the Linux topology
driver.

Allocating a new UUID for the new added component is recommended, as
the component type will be replaced by UUID in the IPC structures,
in the future. For the whole SOF stack, the usage of the UUID shall
follow rules as below:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again you are using recommended and 'should' when it's now mandatory. You have to be consistent with the language used between paragraphs.


UUID Allocation
***************
The UUID allocation of a specific component shall use the version 4 in
`UUID wikipedia <https://en.wikipedia.org/wiki/Universally_unique_identifier>`__,
and the value shall be declared in the firmware component driver with
``DECLARE_SOF_RT_UUID``, for details, please refer to the API
documentation :ref:`uuid-api`.

UUID in Topology
****************
The same UUID shall be used in topology .m4 file for a new added
widget (corresponding to the new added component), since we have
implemented macro to help to handle the conversion task, just use the
exactly same macro ``DECLARE_SOF_RT_UUID`` as depicted in the firmware
source, e.g for SRC component the below shall be added to the topology
.m4 tools/topology/m4/src.m4:

.. code-block:: none

DECLARE_SOF_RT_UUID("host", host_uuid, 0x8b9d100c, 0x6d78, 0x418f,
0x90, 0xa3, 0xe0, 0xe8, 0x05, 0xd0, 0x85, 0x2b);

Linux Topology Driver
*********************
The topology driver will parse the 16-byte UUID token, append it to the
extended data of the IPC struct, and sent it to the
firmware in component creation stage, **for all components**.

keyonjie marked this conversation as resolved.
Show resolved Hide resolved
.. code-block:: none

/* Component extended tokens */
static const struct sof_topology_token comp_ext_tokens[] = {
{SOF_TKN_COMP_UUID,
SND_SOC_TPLG_TUPLE_TYPE_UUID, get_token_uuid,
offsetof(struct sof_ipc_comp_new_ext, uuid), 0},
};

.. code-block:: none

static int sof_widget_ready(struct snd_soc_component *scomp, int index,
struct snd_soc_dapm_widget *w,
struct snd_soc_tplg_dapm_widget *tw)
{
...
ret = sof_parse_tokens(scomp, &swidget->comp_ext, comp_ext_tokens,
ARRAY_SIZE(comp_ext_tokens), tw->priv.array,
le32_to_cpu(tw->priv.size));
...
}

UUID Arrays Stored Section
**************************
Only the UUID arrays for component types used in topology file are
stored to the .rodata section as static data, for limited memory
footprint purpose, e.g.
19 component types * 16 Bytes/component type = 304 Bytes.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is unclear, this implies there are built-time components so where are those UUIDs stored?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The wording 'runtime' is confused here, let me correct it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well this begs a follow-up question. how do we determine which components are used in topology files and which ones are not?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically, the macro 'DECLARE_SOF_RT_UUID' will declare the corresponding UUID static data to the .rodata section. So, if a component(or module, or a pure driver only) is declared with macro 'DECLARE_SOF_RT_UUID' in the firmware, then its UUID should be specified in the topology. Otherwise, when declared with the macro 'DECLARE_SOF_UUID' only, it will be used for the system internal only, the tracing system will use it, but since its UUID will not located in the .rodata section, this will save the memory footprint (we need only 4 Bytes offset for each of this kind of definition).

If you grep the 'DECLARE_SOF_RT_UUID' usage in the firmware source, it is about 39 for the real use at this moment, if UUID of a component is defined in the firmware with 'DECLARE_SOF_RT_UUID', it will occupy 16 Bytes
of the memory, no matter if the component will be used in your topology files or not.


UUID to Component Driver Mapping
********************************
The firmware will use UUID byte array to match the component driver, if
it is provided from the Linux driver side, otherwise, fallback to use
the traditional component type for backwards-compatible behavior.

.. code-block:: none

static const struct comp_driver *get_drv(struct sof_ipc_comp *comp)
{
...
/* validate the extended data */
...
/* use UUID to match the driver if UUID is provided */
if (comp->ext_data_offset) {
/* use component type if old tplg without UUID used */
if (sof_is_uuid_nil(comp_ext->uuid))
goto comp_type_match;

/* search driver list with UUID */
...
/* matched, return drv */
return drv;

/* not found, failed */
return NULL;
}

comp_type_match:
/* search driver list for driver type */
...
/* return the component type matched driver */
return drv;
}

ABI Alignment for UUID Support
******************************
In general, UUID will be used only all FW/tplg/driver are in ABI version
equal or greater than 3.17, otherwise component type will be used.