From 4a4312d9f4ae33791d5cf58693ad36d28712b9fd Mon Sep 17 00:00:00 2001 From: Anton Bobkov Date: Tue, 7 Dec 2021 16:23:03 +0300 Subject: [PATCH 001/150] Edit: Topology 2.0 - Grammar and style nitpicks - Delete numbers from section names - Add links to sections that were previously referred to by their numbers --- developer_guides/topology2/topology2.rst | 460 +++++++++++++---------- 1 file changed, 260 insertions(+), 200 deletions(-) diff --git a/developer_guides/topology2/topology2.rst b/developer_guides/topology2/topology2.rst index 26958c6f..f2d66f19 100644 --- a/developer_guides/topology2/topology2.rst +++ b/developer_guides/topology2/topology2.rst @@ -6,10 +6,10 @@ Topology 2.0 This is a high-level keyword extension on top of the existing ALSA conf topology format designed to: -* Simplify the ALSA conf topology definitions by providing high level "classes" so topology +* Simplify the ALSA conf topology definitions by providing high level "classes". Topology designers need to write less config for commonly defined objects. -* Allow simple reuse of objects. Define once and reuse (like M4) with the ability to alter objects +* Allow simple reuse of objects. Define once and reuse (like M4) with the ability to alter object configuration attributes from defaults. * Allow data type and value verification. This is not done today and frequently crops up in FW bug @@ -17,44 +17,44 @@ to: .. contents:: -1. Ingredients -************** +Ingredients +*********** -A typical 2.0 configuration file consists of the following: +A typical 2.0 configuration file consists of the following components: * Classes * Objects * Arguments * Conditional includes -1.1 Classes ------------ +Classes +------- -Topology today has some common definitions that are often reused throughout with slightly altered -configurations such as widgets (components), pipelines, dais, pcm and controls. Topology 2.0 -introduces the concept of reusable "class" like definitions that can be used to create commonly -used topology objects. Classes are defined with a new keyword “Class”. +Topology today has some common definitions that are often reused with slightly altered +configurations, such as widgets (components), pipelines, dais, pcm, and controls. Topology 2.0 +introduces the concept of reusable class-like definitions that you can use to create commonly +used topology objects. Classes are defined with a new keyword ``Class``. -A class definition always starts with the "Class" keyword followed by 2 nodes. The first node contains -the class group and the second node contains the class name. For example: +A class definition always starts with the ``Class`` keyword followed by two nodes. The first node contains +the class group, and the second node contains the class name. For example: .. code-block:: bash Class.Base.data {} -Note that '.' is the node separator in the alsaconf syntax. In the above line, "Base" is the class -group and "data" is the class name. Currently, the alsatplg compiler supports the following class groups: +Note that '.' is the node separator in the alsaconf syntax. In the above line, ``Base`` is the class +group and ``data`` is the class name. Currently, the alsatplg compiler supports the following class groups: widget, pipeline, DAI, control and base. Most of the commonly used topology objects can be classified into -one of these groups. If there's need for a new class group, the alsatplg compiler should be updated to add +one of these groups. If a new class group is required, the alsatplg compiler should be updated to add support for it. -1.1.1 Class Ingredients -''''''''''''''''''''''' +Class Ingredients +''''''''''''''''' A minimalistic class definition should consist of the following: -* One or more attributes declared with the keyword "DefineAttribute". Attributes are parameters that - are used to describe the object. For ex: +* One or more attributes declared with the keyword ``DefineAttribute``. Attributes are parameters that + are used to describe the object. For example: .. code-block:: bash @@ -62,11 +62,11 @@ A minimalistic class definition should consist of the following: type "string" } -"name" is an attribute of type string. + "name" is an attribute of type string. * Basic attribute qualifiers with the constructor array and unique attribute name. Attribute qualifiers - should be declared within the "attributes {}" node in the class definition. + should be declared within the ``attributes {}`` node in the class definition. .. code-block:: bash @@ -87,10 +87,10 @@ A minimalistic class definition should consist of the following: unique "name" } -1.1.2 A Simple Class -'''''''''''''''''''' +A Simple Class +'''''''''''''' -An example of a simple class definition with 2 attributes and qualifiers is as follows: +The following example demonstrates a simple class definition with two attributes and qualifiers: .. code-block:: bash @@ -124,27 +124,27 @@ An example of a simple class definition with 2 attributes and qualifiers is as f } } -The "data" class definition belonging to the "base" class group, contains 2 attributes namely, -name and bytes, both of type "string". By default, all attributes are give the type "integer" unless -specified otherwise like above. Currently, topology 2.0 supports only "integer" and "string" types for -attributes. +The ``data`` class definition belonging to the ``base`` class group contains two attributes, +name and bytes, both of type ``string``. By default, all attributes have the ``integer`` type, unless +specified otherwise, like in the example above. Currently, topology 2.0 supports only ``integer`` and +``string`` types for attributes. The attribute qualifiers are used to describe how to instantiate an object from the class definition and validate the attribute values. -In the above definition, the "constructor" array tells the compiler how to build the object's name. -A data object instantiated with the name "EQIIR-Coefficients" will be given the name, -"data.EQIIR-Coefficients" i.e. the class name followed by '.' followed by the constructor attribute +In the above definition, the ``constructor`` array tells the compiler how to build the object's name. +A data object instantiated with the name ``EQIIR-Coefficients`` will be given the name +``data.EQIIR-Coefficients``, that is the class name followed by '.' followed by the constructor attribute values separated by '.'. -The "unique" qualifier indicates that two data objects instantiated within the same alsaconf node should -have unique values for their "name" attribute. If two data objects are instantiated within the same alsaconf -node with the same "name" attribute, there be no errors but the two object instances with be merged -with the second instance overriding the attribute values in the first one. Therefore, it is the topology -writer's responbility to ensure that two instances within the same parent node have different unique attribute +The ``unique`` qualifier indicates that multiple data objects instantiated within the same alsaconf node should +have unique values for their ``name`` attribute. If two data objects are instantiated within the same alsaconf +node with the same ``name`` attribute, there will be no errors. But the two object instances will be merged, +And the attribute values in the second instance will override the attribute values in the first one. Therefore, it is the topology +writer's responbility to ensure that multiple instances within the same parent node have different unique attribute values. -Let's consider another class definition example for the "pga" widget belonging to the class group "Widget". +Let's consider another class definition example for the ``pga`` widget belonging to the class group ``Widget``: .. code-block:: bash @@ -178,16 +178,18 @@ Let's consider another class definition example for the "pga" widget belonging t } } -Note that the pga object names are constructed with the class name "pga" followed by 2 attribute values, index -and instance, ex: pga.1.1. Also note that both the attributes wil be given the type "integer" by default because -the definitions do not specify the type. Also, note that in practice, the unique instance attribute should also be -part of the constructor. +Note that the pga object names are constructed with the class name +``pga`` followed by two attribute values, index and instance. For +example, ``pga.1.1``. Both attributes will have the ``integer`` type +by default because the definitions do not specify the type. In +practice, the unique instance attribute should also be part of the +constructor. -1.1.3 Attribute default values -'''''''''''''''''''''''''''''' +Attribute default values +'''''''''''''''''''''''' Optionally, class definitions can be extended to give default values for their attributes. Let's add a -"uuid" attribute of type string to the pga class above and give it a default value. +``uuid`` attribute of type ``string`` to the ``pga`` class and give it a default value: .. code-block:: bash @@ -231,14 +233,14 @@ Optionally, class definitions can be extended to give default values for their a All pga objects will automatically be given the default uuid as specified above in the class definition. -1.1.4 Advanced attribute qualifiers -''''''''''''''''''''''''''''''''''' +Advanced attribute qualifiers +''''''''''''''''''''''''''''' -Apart from the mandatory basic attribute qualifiers, attributes in the class definition can be qualified +Apart from the mandatory basic attribute qualifiers, you can qualify attributes in the class definition using the following advanced keywords: * **Mandatory:** Attributes qualified as mandatory should be provided with a value in the object - instance, failing which the alsatplg compiler will emit and error. Objects with default values in the class + instance, failing which the alsatplg compiler will emit an error. Objects with default values in the class definition need not be qualified as mandatory. Also, note that attributes in the constructor array are mandatory by default as they are required for building the object's name. @@ -247,7 +249,7 @@ using the following advanced keywords: * **Deprecated:** Attributes that have been deprecated and should not be set in the object instance. -* **Automatic:** Attributes whose values are computed by the alsatplg compiler. +* **Automatic:** Attributes which values are computed by the alsatplg compiler. Let's add some extra attributes and advanced qualifers into the pga class definition: @@ -307,11 +309,13 @@ Let's add some extra attributes and advanced qualifers into the pga class defini uuid "7e:67:7e:b7:f4:5f:88:41:af:14:fb:a8:bd:bf:86:82" } -1.1.5 Automatic attributes -'''''''''''''''''''''''''' -In some cases, an attribute's value depends on other attribute values and need to be computed during -build time. Such attributes are qualified with the "automatic" keyword in the class definition. Please -refer to buffer_ for the complete class definition. +Automatic attributes +'''''''''''''''''''' + +In some cases, an attribute value depends on other attribute values +and need to be computed during build time. Such attributes are +qualified with the ``automatic`` keyword in the class definition. +Refer to buffer_ for the complete class definition. .. code-block:: bash @@ -337,15 +341,19 @@ refer to buffer_ for the complete class definition. } } -In the above, case the buffer's size attribute value will be computed based on the pipeline parameters to which the buffer -belongs. Currently, the alsatplg compiler only has support for computing the automatic attribute "size" for the buffer objects. -If needed, support for automatic attributes in new class definitions should be added in the alsatplg compiler. +In the example above, the ``size`` attribute value of ``buffer`` is +computed based on the pipeline parameters, to which the buffer +belongs. Currently, the alsatplg compiler only has support for +computing the automatic attribute ``size`` for the buffer objects. +Support for automatic attributes in new class definitions +should be added in the alsatplg compiler if necessary. + +Attribute Constraints +''''''''''''''''''''' -1.1.6 Attribute Constraints -''''''''''''''''''''''''''' One of the key features of Topology 2.0 is validation of the values provided for objects. This is achieved with the help of constraints added to the attribute definition. Constraints can be added to an attribute using -the "constraints" keyword as follows: +the ``constraints`` keyword: .. code-block:: bash @@ -353,12 +361,12 @@ the "constraints" keyword as follows: constraints {} } -Currently, 3 types of constraints are supported: +Currently, three types of constraints are supported: -* min: min value for attribute, applicable only to integer type attributes -* max: max value for attribute, applicable only to integer type attributes +* **min:** The minimum value for an attribute, applicable only to integer type attributes. +* **max:** The maximum value for an attribute, applicable only to integer type attributes. - For example, the pga class definition can be expanded with an attribute for "ramp_step_ms" with min and + For example, the pga class definition can be expanded with an attribute for ``ramp_step_ms`` with min and max values as follows: .. code-block:: bash @@ -370,9 +378,9 @@ Currently, 3 types of constraints are supported: } } -* valid values: an array of acceptable human-readable values, applicable only to string type attributes. +* **valid values:** an array of acceptable human-readable values, applicable only to string type attributes. - For example, the pga class can have an attribue for "ramp_step_type" with pre-defined values as follows: + For example, the pga class can have an attribue for ``ramp_step_type`` with pre-defined values as follows: .. code-block:: bash @@ -388,17 +396,23 @@ Currently, 3 types of constraints are supported: } } -When the pga is class is instantiated with a value that doesn't belong in the valid_values array for ramp_step_type, -the alsatplg compiler will emit an error along with the list of permitted values. +When the pga class is instantiated with a value that does not belong in +the ``valid_values`` array for ``ramp_step_type``, the alsatplg compiler emits +an error along with the list of valid values. -1.1.7 Attributes with token references -'''''''''''''''''''''''''''''''''''''' -Typically, a lot of objects contain a private data section that is composed of sets of tuple arrays. Some of the attributes in -a class definition may need to be packed into the tuple array. Such attributes are identified with the "token_ref" node -which contains the name of the tuple array that the attribute should be built into. For example, both the ramp_step_ms and -ramp_step_type attributes in the pga class need to be added to the tuple array. So, they are contain the token_ref node -with the value "sof_tkn_volume.word" indicating that the attributes should be packed with the "sof_tkn_volume tuple" array -of type "word" as shown below. +Attributes with token references +'''''''''''''''''''''''''''''''' + +Typically, a lot of objects contain a private data section that is +composed of sets of tuple arrays. Some of the attributes in a class +definition may need to be packed into the tuple array. Such attributes +are identified with the ``token_ref`` node which contains the name of +the tuple array that the attribute should be built into. For example, +both the ``ramp_step_ms`` and ``ramp_step_type`` attributes in the pga +class need to be added to the tuple array. So, they contain the +token_ref node with the value ``sof_tkn_volume.word`` indicating that +the attributes should be packed with the ``sof_tkn_volume tuple`` +array of type ``word``: .. code-block:: bash @@ -427,10 +441,12 @@ of type "word" as shown below. } } -Sometimes, valid_values for attributes might need to be translated from the human readable values to integer tuple values so -that it can be parsed correctly by the kernel driver. In the example above, valid values for ramp_step_type are defined -as human readable string values such as linear, log etc. which are translated to tuple values 0, 1, etc respectively before -getting added to the tuple array. +Sometimes, ``valid_values`` for attributes might need to be translated +from the human readable values to integer tuple values so that it can +be parsed correctly by the kernel driver. In the example above, valid +values for ``ramp_step_type`` are defined as human readable string +values, such as linear and log. These values are translated to tuple +values (0, 1, etc) before getting added to the tuple array. .. code-block:: bash @@ -454,10 +470,12 @@ getting added to the tuple array. } } -1.1.8 A complete class definition -''''''''''''''''''''''''''''''''' +.. _complete_class_definition: + +A complete class definition +''''''''''''''''''''''''''' -Puting it all together, the complete defintiion for the pga widget class is as follows: +Putting it all together, the following example demonstrates the complete definition for the pga widget class: .. code-block:: bash @@ -549,24 +567,27 @@ Puting it all together, the complete defintiion for the pga widget class is as f ramp_step_ms 200 } -1.2 Objects ------------ +Objects +------- + Objects are used to instantiate multiple instances of the same class to avoid duplicating -common attribute definitions. Objects are instantiated with the new keyword "Object" followed by -3 nodes in order as follows: +common attribute definitions. Objects are instantiated with the new keyword ``Object`` followed by +three nodes: .. code-block:: bash Object.Widget.pga."1" {} -The nodes refer to the following: +The nodes refer to the following elements: -* Class group to which the object's class belongs i.e. "Widget" -* Class name i.e. "pga" -* Unique attribute value: This is the value for the attribute that is qualified as "unique" in the - class definition i.e. "instance" +* Class group to which the object class belongs. In this case, the class belongs to ``Widget``. +* Class name. That is ``pga``. +* Unique attribute value. This is the value for the attribute that is qualified as ``unique`` in the + class definition. That is ``instance``. -Using the pga class definition in section 1.1.8, a pga widget object can be instantiated as follows: +Using the pga class definition as described in +:ref:`complete_class_definition`, you can instantiate a pga widget +object in the following way: .. code-block:: bash @@ -574,16 +595,21 @@ Using the pga class definition in section 1.1.8, a pga widget object can be inst index 5 } -where 1 is the value for the unique attribute ("instance") in the pga class definition and the -"index" attribute is given the value 5. Since, there are no other mandatory attributes in the -class defintion, the above instance is fully valid. The key thing to notice in the instantiation -is that there is no need to duplicate commonly used attribute values in the object instantiation. -Objects automatically inherit the default values for attributes from their class definition. +where ``1`` is the value for the unique attribute ``instance`` in the pga class definition and the +``index`` attribute is given the value of 5. As the class definition contains no other mandatory +attributes, the above instance is fully valid. + +.. important:: + + You do not need to duplicate commonly used attribute values in the + object instantiation. Objects automatically inherit the default + values for attributes from their class definition. + +Modifying default attributes +'''''''''''''''''''''''''''' -1.2.1 Modifying default attributes -'''''''''''''''''''''''''''''''''' Attributes that have default values in the class definition can be overwritten by specifying the -new value in the object instance as follows: +new value in the object instance: .. code-block:: bash @@ -592,11 +618,12 @@ new value in the object instance as follows: ramp_step_ms 300 } -The above object overrides the ramp_step_ms default value of 200ms set in the class definition with the -new value of 300ms. +The above object overrides the ``ramp_step_ms`` default value of 200 |_| ms set in the class definition with the +new value of 300 |_| ms. + +Objects within classes +'''''''''''''''''''''' -1.2.2 Objects within classes -'''''''''''''''''''''''''''' Class definitions can optionally also include child objects that need to be instantiated for every instance of the class object. For example, a pga widget typically always contains a volume mixer control. The mixer control class definition is as follows: @@ -695,13 +722,13 @@ The mixer control class definition is as follows: mute_led_direction 0 } -A mixer conrol object can be added to the pga widget class definition as below: +You can add a mixer control object to the pga widget class definition: .. code-block:: bash Class.Widget."pga" { # Attributes, qualifiers and default values are skipped for simplicity. - # Please refer to the complete class definition in Section 1.1.8 above for details + # Refer to the complete class definition in "Complete Class Definition" for details # volume control for pga widget Object.Control.mixer."1" { @@ -711,14 +738,15 @@ A mixer conrol object can be added to the pga widget class definition as below: } } -The mixer control "My Volume Control" will be programmatically added to all pga objects. +The mixer control ``My Volume Control`` will be programmatically added to all pga objects. + +Object attribute inheritance +'''''''''''''''''''''''''''' -1.2.3 Object attribute inheritance -'''''''''''''''''''''''''''''''''' -One thing to note in the above object instantiation is that the mixer object has 2 mandatory attributes, -index and instance but the index attribute value is missing in the instance. This is because the mixer control -object inherits the index attribute value from it's parent pga object when it gets instantiated. For ex, lets take -a pga object instance. +One thing to note in the above object instantiation is that the mixer object has two mandatory attributes, +index and instance. But the index attribute value is missing in the instance. This is because the mixer control +object inherits the index attribute value from its parent pga object when it gets instantiated. For example, +consider the following pga object instance: .. code-block:: bash @@ -726,12 +754,15 @@ a pga object instance. index 5 } -The index value "5" will be inherited by the mixer control object in the pga class definition. Inheritance is -implied only when a child object's class definition shares an attribute of the same name with its parent class -definition. In the case of mixer control class and pga widget class, the shared attribute is "index". +The mixer control object in the pga class definition inherits the index value of ``5``. Inheritance occurs +only when a child object's class definition shares an attribute of the same name with its parent class +definition. In the case of mixer control class and pga widget class, the shared attribute is ``index``. + +.. _setting_child_object_attributes: + +Setting child object attributes +''''''''''''''''''''''''''''''' -1.2.4 Setting child object attributes -''''''''''''''''''''''''''''''''''''' Let's consider the pga class definition with the mixer control object again: .. code-block:: bash @@ -748,8 +779,8 @@ Let's consider the pga class definition with the mixer control object again: } } -Note that the mixer control object has it's name set in the pga widget class definition. But, ideally we want to -give the mixer control a new name whenever a new pga widget object is instantiated. This can be achieved as follows: +Note that the mixer control object has its name set in the pga widget class definition. But, ideally, we want to +give the mixer control a new name whenever a new pga widget object is instantiated. You can do it like this: .. code-block:: bash @@ -763,13 +794,14 @@ give the mixer control a new name whenever a new pga widget object is instantiat } } -Now, the mixer control object is assigned the name "My Control Volume 5". +Now, the mixer control object is assigned the name ``My Control Volume 5``. -1.2.5 Nested Objects -'''''''''''''''''''' +Nested Objects +'''''''''''''' + Objects can also be instantiated as child objects within other object instances. For example, a -switch control can be added to pga widget objects during instantiation as follows: +switch control can be added to pga widget objects during instantiation: .. code-block:: bash @@ -790,12 +822,13 @@ switch control can be added to pga widget objects during instantiation as follow } } -Note how the "unique" attribute for the two mixer control objects differ to keep the mixer instances unique. +Note how the ``unique`` attribute for the two mixer control objects differs to keep the mixer instances unique. + +Recursive object attribute inheritance +'''''''''''''''''''''''''''''''''''''' -1.2.6 Recursive object attribute inheritance -'''''''''''''''''''''''''''''''''''''''''''' Objects can be nested within objects that are nested within other objects themselves. In this case, the attribute -values cam be inherited all the way from the top-level parent object. For example, consider the following class +values can be inherited all the way from the top-level parent object. For example, consider the following class definition for volume-playback pipeline: .. code-block:: bash @@ -827,14 +860,15 @@ class is instantiated as: } This ensures that all child objects within the volume-playback object will inherit the -index attribute value from it. So the pga widget object will have the same index and by the same +index attribute value from it. So the pga widget object will have the same index. And by the same rule, the mixer control object within the pga widget object will also have the same index attribute -value of "1". +value of 1. -1.2.7 Setting child object attributes deep down in the parent object tree -''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' -In section 1.2.4, we saw that we can set child attribute values from its parent object instance. -For example, the mixer control object's name can be set from the pga widget object instace. This +Setting child object attributes deep down in the parent object tree +''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +In :ref:`setting_child_object_attributes`, we saw that we can set child attribute values from its parent object instance. +For example, you can set the mixer control object's name from the pga widget object instance. This can be extended further and it is possible to set the mixer control name from the parent object of the pga object. Consider the volume playback object instance in the previous section. We can set the mixer control name for the pga object as follows: @@ -852,11 +886,12 @@ mixer control name for the pga object as follows: } -1.3. Arguments in top-level configuration files ------------------------------------------------ +Arguments in top-level configuration files +------------------------------------------ + Arguments are used to pass build-time parameters that can be used for building multiple binaries from the same configuration file. Consider the following top-level topology configuration file -with 2 pipelines: +with two pipelines: .. code-block:: bash @@ -902,19 +937,24 @@ with 2 pipelines: } } -The value for the "dynamic_pipeline" attribute in the volume-playback objects in the above example -will be expanded from the provided value for the DYNAMIC_PIPELINE argument when building the -topology binary with the -DDYNAMIC_PIPELINE=1 or -DDYNAMIC_PIPELINE=0 option. +In this example, the value for the ``dynamic_pipeline`` attribute in the volume-playback objects +is expanded from the provided value for the ``DYNAMIC_PIPELINE`` argument when building the +topology binary with the ``-DDYNAMIC_PIPELINE=1`` or ``-DDYNAMIC_PIPELINE=0`` option. + +.. note:: -Note that the alsatplg compiler only parses the arguments that are defined at the top-level node in the -machine topology file. + The alsatplg compiler only parses the arguments that are defined at + the top-level node in the machine topology file. -1.4 Includes ------------- -When building a top-level configuration file, it should include all the class definitions for the objects -being instantiated, failing which the compiler will emit errors calling out missing class definitions. The -include paths for searching for dependencies can be specified as below. All paths are relative to the -directory specified by the environment variable "ALSA_CONFIG_DIR". +Includes +-------- + +When building a top-level configuration file, it should include all +class definitions for the objects being instantiated, failing which +the compiler will emit errors calling out missing class definitions. +All paths are relative to the directory specified by the environment +variable ``ALSA_CONFIG_DIR``. You can specify the include paths for +dependencies as follows: .. code-block:: bash @@ -922,7 +962,7 @@ directory specified by the environment variable "ALSA_CONFIG_DIR". -and the class definitions can be included as follows: +Include the class definitions as follows: .. code-block:: bash @@ -931,8 +971,11 @@ and the class definitions can be included as follows: -3. Simple machine topology -************************** +.. _simple_machine_topology: + +Simple machine topology +*********************** + A machine topology typically consists of the following: * Include paths pointing to the search directory for class definitions includes @@ -943,8 +986,8 @@ A machine topology typically consists of the following: * PCM objects * Top-level pipeline connections -Let's look at a simple machine topology configuration file that includes a volume-playback pipeline, -a HDA type DAI link, a playback PCM and the top-level connection. +Let's consider a simple machine topology configuration file that includes a volume-playback pipeline, +a HDA type DAI link, a playback PCM, and the top-level connection: .. code-block:: bash @@ -1038,11 +1081,11 @@ a HDA type DAI link, a playback PCM and the top-level connection. } Note that the above configuration file only includes the top-level route between the buffer widget -"buffer.1.1" in the volume-playback pipeline and the dai widget "dai.HDA.1.playback". The connections +``buffer.1.1`` in the volume-playback pipeline and the dai widget ``dai.HDA.1.playback``. The connections between the widgets in the volume-playback pipeline are defined in the class definition. Let's peek into the volume-playback pipeline class definition to look at the route objects contained within -the class definition. Please refer to volume-playback_ for the complete class definition. +the class definition. Refer to volume-playback_ for the complete class definition. .. code-block:: bash @@ -1126,7 +1169,7 @@ the class definition. Please refer to volume-playback_ for the complete class de mips 5000 } -The pipeline class definition is fairly straight-forward to follow except for the route object instances. +The pipeline class definition is fairly easy to follow except for the route object instances. Let's analyze it a bit further. The route class definition is defined as follows: .. code-block:: bash @@ -1171,9 +1214,9 @@ Let's analyze it a bit further. The route class definition is defined as follows } } -Note that a route object is expected to have instance, source and sink attributes. +Note that a route object is expected to have instance, source, and sink attributes. -Let's look at the route objects in the volume-playback class again: +Let's consider the route objects in the volume-playback class again: .. code-block:: bash @@ -1194,14 +1237,14 @@ Let's look at the route objects in the volume-playback class again: } } -Notice that the source and sink attributes are defined for all of the routes. For ex: the second route object, -"Object.Base.route.2" has a sink attribute value of "pga..1". Referring back to the pga widget class definition -in Section 1.1.8, we know that a pga widget object's constructor has 2 attributes, namely, index and instance. +Notice that the source and sink attributes are defined for all of the routes. For example, the second route object +``Object.Base.route.2`` has a sink attribute value of ``pga..1``. Referring back to the pga widget class definition +in :ref:`complete_class_definition`, we know that a pga widget object's constructor has two attributes, ``index`` and ``instance``. We know the instance of the pga widget in the volume-playback class is 1 by looking at the list of widgets. But the index attribute value for the pga widget in the pipeline is unknown. It will only be set from a top-level -topology config file as in Section 3. Therefore, the index attribute is left empty in the class definition -and it will populated with the appropriate value by the alsatplg compiler when the route object is built. For the -machine topology above, the route object "Object.base.route.2" will be built with the right pipeline ID's as follows: +topology config file as in :ref:`simple_machine_topology`. Therefore, the index attribute is left empty in the class definition. +The alsatplg compiler will populate the index attribute with the appropriate value when the route object is built. For the +machine topology above, the route object ``Object.base.route.2`` will be built with the right pipeline IDs as follows: .. code-block:: bash @@ -1210,13 +1253,14 @@ machine topology above, the route object "Object.base.route.2" will be built wit sink "pga.1.1" } -Currently, the alsatplg supports the feature of filling in attribute values only for the route object source +Currently, alsatplg can fill in attribute values only for the route object source and sink attributes. If needed, this feature can be extended for other types of objects. -4. Conditional includes -*********************** +Conditional includes +******************** + Conditional includes allow building multiple topology binaries from the same input configuration file. -For example, let's consider the HDA generic machine topology. The number of DMIC's determines wether +For example, let's consider the HDA generic machine topology. The number of DMICs determines whether the DMIC configuration file should be included or not. This can be achieved as follows: .. code-block:: bash @@ -1231,19 +1275,23 @@ the DMIC configuration file should be included or not. This can be achieved as f "[1-4]" "include/platform/intel/dmic-generic.conf" } -The regular expression "[1-4]" indicates that the dmic-generic.conf file should be included if +The regular expression ``[1-4]`` indicates that the dmic-generic.conf file should be included if the DMIC_COUNT argument value is between 1 and 4. Assuming the top-level file is called -"sof-hda-generic.conf", two separate topology binaries can be built as follows: +``sof-hda-generic.conf``, you can build two separate topology binaries with the following commands: -**`alsatplg -p -c sof-hda-generic.conf -o sof-hda-generic.tplg`** for machines with no DMIC's +* For machines with no DMICs: -**`alsatplg -D DMIC_COUNT=2 -p -c sof-hda-generic.conf -o sof-hda-generic-2ch.tplg`** for machines with 2 DMIC's. + ``alsatplg -p -c sof-hda-generic.conf -o sof-hda-generic.tplg`` -Conditional includes are not limited to top-level configuration files. They can be added to any node -in the configuration file to include the configuration at the specified node. For example, we conditionally -include the right filter coefficients for the byte controls in a EQIIR widget as follows: +* For machines with two DMICs: -Define the argument for the coefficients in the top-level topology file as follows: + ``alsatplg -D DMIC_COUNT=2 -p -c sof-hda-generic.conf -o sof-hda-generic-2ch.tplg`` + +Conditional includes are not limited to top-level configuration files. You can add them to any node +in the configuration file to include the configuration at the specified node. For example, we can conditionally +include the right filter coefficients for the byte controls in the EQIIR widget. + +Define the argument for the coefficients in the top-level topology file: .. code-block:: bash @@ -1252,7 +1300,7 @@ Define the argument for the coefficients in the top-level topology file as follo default "highpass_40hz_0db_48khz" } -And then the coefficients can be included as follows: +And then include the coefficients: .. code-block:: bash @@ -1267,49 +1315,61 @@ And then the coefficients can be included as follows: } } -5. Building 2.0 configuration files -*********************************** -Topology 2.0 configuration files can be compiled to produce the topology binary files using the -alsatplg compiler as follows: +Building 2.0 configuration files +******************************** -alsatplg <-D args=values> -p -c input.conf -o output.tplg +You can use alsatplg to compile Topology 2.0 configuration files and produce the topology binary files: -The -D switch is used to pass comma-separated argument values to the top-level configuration file. +.. code-block:: bash -The -P switch can be used to convert a 2.0 configuration file to the 1.0 configuration file as -follows: + alsatplg <-D args=values> -p -c input.conf -o output.tplg -alsatplg <-D args=values> -P input.conf -o output.conf +The ``-D`` switch is used to pass comma-separated argument values to the top-level configuration file. -6. Topology reminders -********************* +You can use the ``-P`` switch to convert a 2.0 configuration file to the 1.0 configuration file: -1. "index" refers to the pipeline ID in pipeline, widget and control class groups +.. code-block:: bash -2. "id" in the DAI class group objects refers to the link ID as defined in the machine driver in the kernel + alsatplg <-D args=values> -P input.conf -o output.conf -7. Alsaconf reminders -********************* +Topology reminders +****************** -1. "." refers to a node separator. "foo.bar value" is quivalent to +Review the following topology considerations: -.. code-block:: bash +- "index" refers to the pipeline ID in pipeline, widget, and control class groups. + +- "id" in the DAI class group objects refers to the link ID as defined in the machine driver in the kernel. + +Alsaconf reminders +****************** + +Review the following alsaconf considerations: + +- "." refers to a node separator. "foo.bar value" is quivalent to the following: + + .. code-block:: bash foo { bar value } -2. Arrays are defined with [] as below +- Arrays are defined with []. For example: -.. code-block:: bash + .. code-block:: bash !constructor [ "foo" "bar" ] -It is recommended to use the "!" in the array definitions in the class definition. This is to ensure that if the class -configuration file is included more than once from different sources, the array items will not be duplicated. + We recommend to use the exclamation mark (!) in array definitions + within the class definition. Use it to ensure that the array items + are not duplicated if the class configuration file is included more + than once from different sources. .. _volume-playback: https://github.com/thesofproject/sof/blob/main/tools/topology/topology2/include/pipelines/volume-playback.conf .. _buffer: https://github.com/thesofproject/sof/blob/main/tools/topology/topology2/include/components/buffer.conf + +.. |_| unicode:: 0xA0 + :trim: From 19acef8d6b28b13abd154a8bebc04f5194f33802 Mon Sep 17 00:00:00 2001 From: Anton Bobkov Date: Tue, 7 Dec 2021 18:12:58 +0300 Subject: [PATCH 002/150] Edits from Deb --- developer_guides/topology2/topology2.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/developer_guides/topology2/topology2.rst b/developer_guides/topology2/topology2.rst index f2d66f19..0d3538b1 100644 --- a/developer_guides/topology2/topology2.rst +++ b/developer_guides/topology2/topology2.rst @@ -6,8 +6,8 @@ Topology 2.0 This is a high-level keyword extension on top of the existing ALSA conf topology format designed to: -* Simplify the ALSA conf topology definitions by providing high level "classes". Topology - designers need to write less config for commonly defined objects. +* Simplify the ALSA conf topology definitions by providing high level "classes". In this way, topology + designers can write less configurations for commonly defined objects. * Allow simple reuse of objects. Define once and reuse (like M4) with the ability to alter object configuration attributes from defaults. @@ -139,10 +139,10 @@ values separated by '.'. The ``unique`` qualifier indicates that multiple data objects instantiated within the same alsaconf node should have unique values for their ``name`` attribute. If two data objects are instantiated within the same alsaconf -node with the same ``name`` attribute, there will be no errors. But the two object instances will be merged, -And the attribute values in the second instance will override the attribute values in the first one. Therefore, it is the topology -writer's responbility to ensure that multiple instances within the same parent node have different unique attribute -values. +node with the same ``name`` attribute, errors will not occur, but the two object instances will be merged. +Additionally, the attribute values in the second instance will override the attribute values in the first one. +Therefore, it is the topology writer's responsibility to ensure that multiple instances within the same parent +node have different unique attribute values. Let's consider another class definition example for the ``pga`` widget belonging to the class group ``Widget``: @@ -249,7 +249,7 @@ using the following advanced keywords: * **Deprecated:** Attributes that have been deprecated and should not be set in the object instance. -* **Automatic:** Attributes which values are computed by the alsatplg compiler. +* **Automatic:** Attributes whose values are computed by the alsatplg compiler. Let's add some extra attributes and advanced qualifers into the pga class definition: @@ -860,7 +860,7 @@ class is instantiated as: } This ensures that all child objects within the volume-playback object will inherit the -index attribute value from it. So the pga widget object will have the same index. And by the same +index attribute value from it. So the pga widget object will have the same index. By the same rule, the mixer control object within the pga widget object will also have the same index attribute value of 1. From fa06975747dc9ff04bf2644156e3d5d7a3da56e8 Mon Sep 17 00:00:00 2001 From: Anton Bobkov Date: Mon, 13 Dec 2021 17:32:13 +0300 Subject: [PATCH 003/150] Change the release version to 2.0 for the SOF 2.0 release Please merge after the SOF 2.0 release occurs. --- conf.py | 2 +- release.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/conf.py b/conf.py index 574a1455..4e7b7b53 100755 --- a/conf.py +++ b/conf.py @@ -70,7 +70,7 @@ # |version| and |release|, also used in various other places throughout the # built documents. -version = release = "0.1" +version = release = "2.0" # # The short X.Y version. diff --git a/release.rst b/release.rst index 0ff6939e..2d1f65d3 100755 --- a/release.rst +++ b/release.rst @@ -26,7 +26,7 @@ kernel, and documentation. Download the source code as a zip or tar.gz file: Source and Binary Releases -------------------------- -The latest SOF release is v1.9 (October 2021). +The latest SOF release is v2.0 (December 2021). View new feature information and release downloads for the latest and previous releases on GitHub. Firmware and SDK tool source code and binary From 984ca7a8036c4426fd76c3b03e1066ac74208274 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 9 Dec 2021 17:24:27 +0200 Subject: [PATCH 004/150] build-from-scratch: Minor fix to local alsa-utils install command Do not mess with the host systemd or udev conf if making a local installation to a home directory. Signed-off-by: Jyri Sarha --- getting_started/build-guide/build-from-scratch.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/getting_started/build-guide/build-from-scratch.rst b/getting_started/build-guide/build-from-scratch.rst index 286d4f4f..c2cda4dd 100755 --- a/getting_started/build-guide/build-from-scratch.rst +++ b/getting_started/build-guide/build-from-scratch.rst @@ -157,7 +157,9 @@ Clone, build, and install alsa-utils. # To install alsa-utils locally ./gitcompile --prefix=$HOME/local \ --with-alsa-inc-prefix=$HOME/local/include \ - --with-alsa-prefix=$HOME/local/lib + --with-alsa-prefix=$HOME/local/lib \ + --with-systemdsystemunitdir=$HOME/local/lib/systemd \ + --with-udev-rules-dir=$HOME/local/lib/udev sudo make install If you run into alsa-lib linking errors, try to re-build it with the libdir From 758e01e4bff1f096583fd2b745bfeeba00da4376 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Thu, 9 Dec 2021 13:07:03 +0200 Subject: [PATCH 005/150] developer_guides: add coredump-reader example usage on Linux Add documentation and practical example how to extract the DSP coredump via Linux SOF driver debugfs interface and how to parse the result with coredump-reader. v2: update text with corrections from Anton Bobkov Signed-off-by: Kai Vehmanen --- .../debugability/coredump-reader/index.rst | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/developer_guides/debugability/coredump-reader/index.rst b/developer_guides/debugability/coredump-reader/index.rst index 1400a073..71661c82 100644 --- a/developer_guides/debugability/coredump-reader/index.rst +++ b/developer_guides/debugability/coredump-reader/index.rst @@ -30,3 +30,53 @@ We read from dump file into sof-coredump-reader.py, then we pipe its output to x .. code-block:: bash ./sof-coredump-to-gdb.sh sof-apl dump_file + +Usage with Linux SOF Driver +*************************** + +If a core dump occurs after a DSP error, the Linux SOF driver allows +accessing the dump via debugfs. Consider the following example of capturing +the dump file and processing it with coredump-reader: + +.. code-block:: bash + + dut> cat /sys/kernel/debug/sof/exception >dsp-coredump + # transfer file to host + host> sof/tools/coredumper/sof-coredump-reader.py -v -l 4 -i dsp-coredump -o dsp-coredump.gdb + host> xt-gdb sof/build_tlg_xcc/sof --command=dsp-coredump.gdb + [cut] + $1 = "Exception location:" + 0xbe02fb29 is in ipc_glb_debug_message (/home/user/sof/src/ipc/handler-ipc3.c:1371). + [cut] + $2 = "backtrace" + #0 0xbe051b00 in literals () + #1 0xbe04e277 in dump_stack (p=3187705884, addr=0x1cc6c29b, offset=3270769662, limit=380, stack_ptr=0x1) at /home/user//sof/src/arch/xtensa/include/arch/lib/cache.h:79 + #2 0xbe04e2f7 in panic_dump (p=233492486, panic_info=0x0, data=0xbe0a4130) at /home/user/sof/src/arch/xtensa/include/arch/debug/panic.h:45 + #3 0xbe02dfd9 in exception () at /home/user/sof/src/arch/xtensa/init.c:115 + #4 0xbe050a28 in _GeneralException () + #5 0xbe02fb29 in ipc_glb_debug_message (header=394016) at /home/user/sof/src/ipc/handler-ipc3.c:1373 + [cut] + (xt-gdb) info all-registers + pc 0xbe051b00 0xbe051b00 + ar0 0x0 0 + ar1 0xbe00a044 -1107255228 + ar2 0x10000 65536 + +Notes: + +- Coredump-reader only works with the xcc toolchain. + +- If the Linux kernel fails to probe, the exception file cannot be read. + +- To prevent runtime suspend from powering off the DSP and erasing + the exception data, perform one of the following steps: + + - Set the ``CONFIG_SND_SOC_SOF_DEBUG_RETAIN_DSP_CONTEXT`` option in the + kernel to ensure DSP is left powered on if a DSP crash occurs. + + - Disable runtime power management (PM) with a module parameter. + For example, for PCI devices:: + options sof_pci_dev sof_pci_debug=1 + +- The DSP core dump information is also printed to kernel dmesg, but + sof-coredump-reader.py cannot parse this core dump format. From 44344d27bf6004556a34ae387c420e453dfc826f Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Tue, 21 Dec 2021 01:45:23 +0000 Subject: [PATCH 006/150] unit_tests: add workaround for uintptr_t redefinition Also regroup -DTOOLCHAIN=xt closer to the other flags, stop hiding it after the example. Signed-off-by: Marc Herbert --- developer_guides/unit_tests.rst | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/developer_guides/unit_tests.rst b/developer_guides/unit_tests.rst index 3b1008dd..93e0e0e7 100644 --- a/developer_guides/unit_tests.rst +++ b/developer_guides/unit_tests.rst @@ -35,6 +35,28 @@ and re-use to build unit tests. Like this: ``-DINIT_CONFIG`` and a new build directory - Build and run the tests with ``make test`` or ``ninja test``. +.. note:: + + Use -DTOOLCHAIN=xt option. + + As of December 2021, -DTOOLCHAIN=xtensa--elf is not + supported. You can use a native toolchain, see below. + +If you get this double ``uintptr_t`` definition error: + +.. code-block:: bash + + [ 2%] Building C object test/cmocka/CMakeFiles/common_mock.dir/src/common_mocks.c.o + In file included from sof/test/cmocka/src/common_mocks.c:29: + sof/but/cmocka_git/src/cmocka_git/include/cmocka.h:132: + error: redefinition of typedef ‘uintptr_t’ + xcc/install/builds/RG-2017.8-linux/X4H3I16w2D48w3a_2017_8/xtensa-elf/include/stdint.h:252: + error: previous declaration of ‘uintptr_t’ was here + +... then append this to your cmake invocation: ``-DEXTRA_CFLAGS=-D_UINTPTR_T_DEFINED=1`` + +Additional unit tests options can be found in :ref:`cmake`. + Example: Running tests for APL ============================== @@ -45,12 +67,6 @@ Example: Running tests for APL -DROOT_DIR=/xcc/install/builds/RG-2017.8-linux/X4H3I16w2D48w3a_2017_8/xtensa-elf .. make -j4 && ctest -j8 -.. note:: - - Use -DTOOLCHAIN=xt option, -DTOOLCHAIN=xtensa--elf is not supported - -Additional unit tests options can be found in :ref:`cmake`. - Compiling unit tests without a cross-compilation toolchain ========================================================== From a099bba192cead6ebd95be2758c9d861cf6e7e6c Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Wed, 29 Dec 2021 23:53:38 +0200 Subject: [PATCH 007/150] ktest: Change sof-mach-driver-defconfig to mach-driver-defconfig All machine drivers were merged under same defconfig in sof kconfig repository and the name of the defoconfig file was changed in the process. Signed-off-by: Jyri Sarha --- getting_started/setup/setup_ktest_environment.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting_started/setup/setup_ktest_environment.rst b/getting_started/setup/setup_ktest_environment.rst index 41ed55b1..1b800ffd 100644 --- a/getting_started/setup/setup_ktest_environment.rst +++ b/getting_started/setup/setup_ktest_environment.rst @@ -256,7 +256,7 @@ If you don't know what options are needed, you can start using configurations ma git clone https://github.com/thesofproject/kconfig.git cd linux make defconfig - scripts/kconfig/merge_config.sh .config ../kconfig/base-defconfig ../kconfig/sof-defconfig ../kconfig/sof-mach-driver-defconfig ../kconfig/hdaudio-codecs-defconfig + scripts/kconfig/merge_config.sh .config ../kconfig/base-defconfig ../kconfig/sof-defconfig ../kconfig/mach-driver-defconfig ../kconfig/hdaudio-codecs-defconfig cp .config ../sof-dev-defconfig make mrproper cd .. From f6377950c0c1e725e2cccc36917d21c9bb92bd67 Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Wed, 29 Dec 2021 13:36:20 +0100 Subject: [PATCH 008/150] Re-name architecture chapters tree Change DSP Architecture to Firmware Architecture. Signed-off-by: Michal Wasko --- architectures/{dsp => firmware}/index.rst | 11 +++++------ .../intel/cavs-boot/apollolake/apl-boot-ldr.rst | 0 .../intel/cavs-boot/apollolake/apl-boot-rom.rst | 0 .../intel/cavs-boot/apollolake/images/apl-rom-flow.pu | 0 .../intel/cavs-boot/apollolake/index.rst | 0 .../intel/cavs-boot/cavs-dsp-boot-overview.rst | 0 .../intel/cavs-boot/images/boot-dsp.pu | 0 .../intel/cavs-boot/images/boot-ldr-flow.pu | 0 .../intel/cavs-boot/images/loading-bins.pu | 0 .../intel/cavs-boot/images/write-bin.pu | 0 .../{dsp => firmware}/intel/cavs-boot/index.rst | 0 .../intel/images/idc-send-message.pu | 0 architectures/{dsp => firmware}/intel/index.rst | 0 architectures/{dsp => firmware}/intel/smp/index.rst | 0 architectures/index.rst | 4 ++-- 15 files changed, 7 insertions(+), 8 deletions(-) rename architectures/{dsp => firmware}/index.rst (96%) rename architectures/{dsp => firmware}/intel/cavs-boot/apollolake/apl-boot-ldr.rst (100%) rename architectures/{dsp => firmware}/intel/cavs-boot/apollolake/apl-boot-rom.rst (100%) rename architectures/{dsp => firmware}/intel/cavs-boot/apollolake/images/apl-rom-flow.pu (100%) rename architectures/{dsp => firmware}/intel/cavs-boot/apollolake/index.rst (100%) rename architectures/{dsp => firmware}/intel/cavs-boot/cavs-dsp-boot-overview.rst (100%) rename architectures/{dsp => firmware}/intel/cavs-boot/images/boot-dsp.pu (100%) rename architectures/{dsp => firmware}/intel/cavs-boot/images/boot-ldr-flow.pu (100%) rename architectures/{dsp => firmware}/intel/cavs-boot/images/loading-bins.pu (100%) rename architectures/{dsp => firmware}/intel/cavs-boot/images/write-bin.pu (100%) rename architectures/{dsp => firmware}/intel/cavs-boot/index.rst (100%) rename architectures/{dsp => firmware}/intel/images/idc-send-message.pu (100%) rename architectures/{dsp => firmware}/intel/index.rst (100%) rename architectures/{dsp => firmware}/intel/smp/index.rst (100%) diff --git a/architectures/dsp/index.rst b/architectures/firmware/index.rst similarity index 96% rename from architectures/dsp/index.rst rename to architectures/firmware/index.rst index 1d19a785..b7b25a2b 100644 --- a/architectures/dsp/index.rst +++ b/architectures/firmware/index.rst @@ -1,7 +1,7 @@ -.. _architecture-dsp: +.. _architecture-firmware: -DSP Architecture -################ +Firmware Architecture +##################### Currently SOF has support for the Cadence Xtensa DSP architecture in UP and SMP modes in the upstream code base today. @@ -43,7 +43,7 @@ main sections: Each section above is well insulated from the other sections by partitioning code into separate directories and by using DSP and platform agnostic generic -APIs for orchestration between the sections. +APIs for orchestration between the sections. Adding a new DSP architecture to SOF ==================================== @@ -78,7 +78,6 @@ from the SOF build in order to use the RTOS version if desireable i.e. allocator, schedulers, messaging etc. The final stage is to link the SOF audio code to the RTOS. - Vendor Specific Architecture Information ======================================== @@ -92,4 +91,4 @@ Intel .. toctree:: :maxdepth: 1 - intel/index + intel/index \ No newline at end of file diff --git a/architectures/dsp/intel/cavs-boot/apollolake/apl-boot-ldr.rst b/architectures/firmware/intel/cavs-boot/apollolake/apl-boot-ldr.rst similarity index 100% rename from architectures/dsp/intel/cavs-boot/apollolake/apl-boot-ldr.rst rename to architectures/firmware/intel/cavs-boot/apollolake/apl-boot-ldr.rst diff --git a/architectures/dsp/intel/cavs-boot/apollolake/apl-boot-rom.rst b/architectures/firmware/intel/cavs-boot/apollolake/apl-boot-rom.rst similarity index 100% rename from architectures/dsp/intel/cavs-boot/apollolake/apl-boot-rom.rst rename to architectures/firmware/intel/cavs-boot/apollolake/apl-boot-rom.rst diff --git a/architectures/dsp/intel/cavs-boot/apollolake/images/apl-rom-flow.pu b/architectures/firmware/intel/cavs-boot/apollolake/images/apl-rom-flow.pu similarity index 100% rename from architectures/dsp/intel/cavs-boot/apollolake/images/apl-rom-flow.pu rename to architectures/firmware/intel/cavs-boot/apollolake/images/apl-rom-flow.pu diff --git a/architectures/dsp/intel/cavs-boot/apollolake/index.rst b/architectures/firmware/intel/cavs-boot/apollolake/index.rst similarity index 100% rename from architectures/dsp/intel/cavs-boot/apollolake/index.rst rename to architectures/firmware/intel/cavs-boot/apollolake/index.rst diff --git a/architectures/dsp/intel/cavs-boot/cavs-dsp-boot-overview.rst b/architectures/firmware/intel/cavs-boot/cavs-dsp-boot-overview.rst similarity index 100% rename from architectures/dsp/intel/cavs-boot/cavs-dsp-boot-overview.rst rename to architectures/firmware/intel/cavs-boot/cavs-dsp-boot-overview.rst diff --git a/architectures/dsp/intel/cavs-boot/images/boot-dsp.pu b/architectures/firmware/intel/cavs-boot/images/boot-dsp.pu similarity index 100% rename from architectures/dsp/intel/cavs-boot/images/boot-dsp.pu rename to architectures/firmware/intel/cavs-boot/images/boot-dsp.pu diff --git a/architectures/dsp/intel/cavs-boot/images/boot-ldr-flow.pu b/architectures/firmware/intel/cavs-boot/images/boot-ldr-flow.pu similarity index 100% rename from architectures/dsp/intel/cavs-boot/images/boot-ldr-flow.pu rename to architectures/firmware/intel/cavs-boot/images/boot-ldr-flow.pu diff --git a/architectures/dsp/intel/cavs-boot/images/loading-bins.pu b/architectures/firmware/intel/cavs-boot/images/loading-bins.pu similarity index 100% rename from architectures/dsp/intel/cavs-boot/images/loading-bins.pu rename to architectures/firmware/intel/cavs-boot/images/loading-bins.pu diff --git a/architectures/dsp/intel/cavs-boot/images/write-bin.pu b/architectures/firmware/intel/cavs-boot/images/write-bin.pu similarity index 100% rename from architectures/dsp/intel/cavs-boot/images/write-bin.pu rename to architectures/firmware/intel/cavs-boot/images/write-bin.pu diff --git a/architectures/dsp/intel/cavs-boot/index.rst b/architectures/firmware/intel/cavs-boot/index.rst similarity index 100% rename from architectures/dsp/intel/cavs-boot/index.rst rename to architectures/firmware/intel/cavs-boot/index.rst diff --git a/architectures/dsp/intel/images/idc-send-message.pu b/architectures/firmware/intel/images/idc-send-message.pu similarity index 100% rename from architectures/dsp/intel/images/idc-send-message.pu rename to architectures/firmware/intel/images/idc-send-message.pu diff --git a/architectures/dsp/intel/index.rst b/architectures/firmware/intel/index.rst similarity index 100% rename from architectures/dsp/intel/index.rst rename to architectures/firmware/intel/index.rst diff --git a/architectures/dsp/intel/smp/index.rst b/architectures/firmware/intel/smp/index.rst similarity index 100% rename from architectures/dsp/intel/smp/index.rst rename to architectures/firmware/intel/smp/index.rst diff --git a/architectures/index.rst b/architectures/index.rst index 246cb14c..b16f224b 100644 --- a/architectures/index.rst +++ b/architectures/index.rst @@ -1,6 +1,6 @@ .. _architectures: -Supported Architectures +Architecture ####################### SOF is intended to run on many different hardware architectures and is therefore @@ -15,4 +15,4 @@ should always be consulted for the low level details. :maxdepth: 2 host/index - dsp/index + firmware/index From fa3716062486d70b51059ee7be0110e0088bc7c1 Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Wed, 29 Dec 2021 13:46:44 +0100 Subject: [PATCH 009/150] Move Add new DSP architecture chapter to developers guide Signed-off-by: Michal Wasko --- architectures/firmware/index.rst | 33 ------------------------------- developer_guides/add_new_arch.rst | 33 +++++++++++++++++++++++++++++++ developer_guides/index.rst | 1 + 3 files changed, 34 insertions(+), 33 deletions(-) create mode 100644 developer_guides/add_new_arch.rst diff --git a/architectures/firmware/index.rst b/architectures/firmware/index.rst index b7b25a2b..fd2ca745 100644 --- a/architectures/firmware/index.rst +++ b/architectures/firmware/index.rst @@ -45,39 +45,6 @@ Each section above is well insulated from the other sections by partitioning code into separate directories and by using DSP and platform agnostic generic APIs for orchestration between the sections. -Adding a new DSP architecture to SOF -==================================== - -This is not yet a guide for architecure porting, but in general are two ways to -add support for new DSP architectures to SOF. - -#. Write a new Hardware Abstraction Layer (HAL) for your DSP. - -#. Use an existing RTOS that supports your DSP architecture as a HAL for SOF. - -Both methods require a working compiler for the new DSP architecture and -preferrably an emulation environment or hardware debugger to help with the -bringup and debug. - -Method 1 - New HAL ------------------- - -The main work in adding the new architecture HAL is duplicating and porting the -src/arch directory to your new architecture. The code in the architecture -directory mainly deals with architecture abstraction and initialization of any -architecture IP like MMU, IRQs and caches alongside providing optimized -versions of some common C functions (memcpy, memset, etc) for that architecture. -Adding a new architecture also usually means adding a new host platform too. - -Method 2 - Use existing RTOS ----------------------------- - -This method involves creating a HAL by wrapping the RTOS functions used by SOF -as thinly as possible (i.e. to compile out). It also means removing unused code -from the SOF build in order to use the RTOS version if desireable i.e. -allocator, schedulers, messaging etc. The final stage is to link the SOF audio -code to the RTOS. - Vendor Specific Architecture Information ======================================== diff --git a/developer_guides/add_new_arch.rst b/developer_guides/add_new_arch.rst new file mode 100644 index 00000000..b0ba708c --- /dev/null +++ b/developer_guides/add_new_arch.rst @@ -0,0 +1,33 @@ +.. _add_new_arch: + +Adding a new DSP architecture to SOF +==================================== + +This is not yet a guide for architecure porting, but in general, you can add +support for a new DSP architectures to SOF in the following two ways: + +- Write a new Hardware Abstraction Layer (HAL) for your DSP. +- Use an existing RTOS that supports your DSP architecture as a HAL for SOF. + +Both methods require a working compiler for the new DSP architecture and +preferrably an emulation environment or hardware debugger to help with the +bringup and debug. + +Method 1 - New HAL +------------------ + +The main work in adding the new architecture HAL is duplicating and porting the +src/arch directory to your new architecture. The code in the architecture +directory mainly deals with architecture abstraction and initialization of any +architecture IP like MMU, IRQs and caches alongside providing optimized +versions of some common C functions (memcpy, memset, etc) for that architecture. +Adding a new architecture also usually means adding a new host platform too. + +Method 2 - Use existing RTOS +---------------------------- + +This method involves creating a HAL by wrapping the RTOS functions used by SOF +as thinly as possible (i.e. to compile out). It also means removing unused code +from the SOF build in order to use the RTOS version if desireable i.e. +allocator, schedulers, messaging etc. The final stage is to link the SOF audio +code to the RTOS. diff --git a/developer_guides/index.rst b/developer_guides/index.rst index 3ef80cdd..5ac976e5 100644 --- a/developer_guides/index.rst +++ b/developer_guides/index.rst @@ -24,6 +24,7 @@ terminology before reading further. virtualization/running fuzzing/index testbench/index + add_new_arch Technical Notes *************** From f5199233e93e1043e855e70798024a867bfe57b5 Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Wed, 29 Dec 2021 14:24:04 +0100 Subject: [PATCH 010/150] Move Linux Driver architecture to Architecture tree Signed-off-by: Michal Wasko --- architectures/host/index.rst | 63 +----------------- .../architecture/images/sof-driver-arch-1.png | Bin .../architecture/images/sof-driver-arch-2.png | Bin .../architecture/sof_driver_arch.rst | 14 +++- developer_guides/linux_driver/index.rst | 1 - 5 files changed, 15 insertions(+), 63 deletions(-) rename {developer_guides => architectures/host}/linux_driver/architecture/images/sof-driver-arch-1.png (100%) rename {developer_guides => architectures/host}/linux_driver/architecture/images/sof-driver-arch-2.png (100%) rename {developer_guides => architectures/host}/linux_driver/architecture/sof_driver_arch.rst (97%) diff --git a/architectures/host/index.rst b/architectures/host/index.rst index 30d8bb2a..a7a3cd13 100644 --- a/architectures/host/index.rst +++ b/architectures/host/index.rst @@ -3,64 +3,7 @@ Host Architecture ################# -SOF Driver Architecture -======================= - -|SOF| can either operate as a standalone firmware or alongside a host OS -driver for configuration and control. The |SOF| OS driver is responsible for -loading firmware, loading configuration and managing firmware use cases. -Currently |SOF| has a driver for the Linux OS. - -The |SOF| driver code is dual licensed GPLv2 and BSD and this means the user -can choose which licence they want to use (either BSD or GPLv2). The driver -stack is designed with maximum resuse so that large portions of it can be -taken and integrated into other OSs or RTOSs. - -.. seealso:: - - Refer to the indepth :ref:`sof_driver_arch` document for more information. - -Linux Driver ------------- - -The Linux ASoC driver is upstream in the Linux kernel from v5.2 onwards. The -architecture for |SOF| is shown in the diagram below. The driver -architecture is split into four layers, like a protocol stack, each with a -different purpose. - -#. **Machine driver.** The ASoC machine driver does all the - machine/board audio hardware integration. It also glues the platform - driver and drivers for any codec(s) together so they appear as a single - ALSA sound card. |SOF| can reuse existing upstream machine drivers (as - only the platform name needs to be changed) or can have bespoke machine - drivers. *Linux OS specific - GPLv2 only.* - -#. **Generic PCM Driver.** The PCM driver creates ALSA PCMs, DAPM, and - kcontrols based on the topology data loaded at run time. The PCM driver - also allocates buffers for DMA and registers with run time PM. It is - architecture and platform generic code. Generic for all **platforms**, - but OS specific - GPLv2 only.* - -#. **Generic IPC driver.** The IPC driver is the messaging bridge - between the host and DSP and defines the messaging ABI and protocol. It - is architecture and platform generic code. *Generic OS - BSD or GPLv2.* - -#. **DSP Platform Driver.** The platform driver is a platform specific - driver that abstracts the low level platform DSP hardware into a common - generic API that is used by the upper layers. This includes code that - will initialize the DSP and boot the firmware. *Generic OS - BSD or GPLv2.* - - - .. figure:: ../images/driver-arch-diag.png - :align: center - :alt: SOF Driver Architecture - :width: 800px - - `Sound Open Firmware Linux Driver Architecture. The right-hand side of - the diagram shows the mailbox/doorbell mechanism and the DSP. - The Linux PCM and IPC drivers can be reused without modification on every - platform. Runtime differentiation can be achived by regenerating - topology data to match device use cases whilst static hardware - differentiation is achieved via the machine driver and/or ACPI / Device - Tree configuration.` +.. toctree:: + :maxdepth: 1 + linux_driver/architecture/sof_driver_arch.rst diff --git a/developer_guides/linux_driver/architecture/images/sof-driver-arch-1.png b/architectures/host/linux_driver/architecture/images/sof-driver-arch-1.png similarity index 100% rename from developer_guides/linux_driver/architecture/images/sof-driver-arch-1.png rename to architectures/host/linux_driver/architecture/images/sof-driver-arch-1.png diff --git a/developer_guides/linux_driver/architecture/images/sof-driver-arch-2.png b/architectures/host/linux_driver/architecture/images/sof-driver-arch-2.png similarity index 100% rename from developer_guides/linux_driver/architecture/images/sof-driver-arch-2.png rename to architectures/host/linux_driver/architecture/images/sof-driver-arch-2.png diff --git a/developer_guides/linux_driver/architecture/sof_driver_arch.rst b/architectures/host/linux_driver/architecture/sof_driver_arch.rst similarity index 97% rename from developer_guides/linux_driver/architecture/sof_driver_arch.rst rename to architectures/host/linux_driver/architecture/sof_driver_arch.rst index a307b1d7..61f774f9 100644 --- a/developer_guides/linux_driver/architecture/sof_driver_arch.rst +++ b/architectures/host/linux_driver/architecture/sof_driver_arch.rst @@ -1,7 +1,17 @@ .. _sof_driver_arch: -SOF Driver Architecture -####################### +SOF Linux Driver Architecture +############################# + +|SOF| can either operate as a standalone firmware or alongside a host OS +driver for configuration and control. The |SOF| OS driver is responsible for +loading firmware, loading configuration and managing firmware use cases. +Currently |SOF| has a driver for the Linux OS. + +The |SOF| driver code is dual licensed GPLv2 and BSD and this means the user +can choose which licence they want to use (either BSD or GPLv2). The driver +stack is designed with maximum resuse so that large portions of it can be +taken and integrated into other OSs or RTOSs. .. contents:: :local: diff --git a/developer_guides/linux_driver/index.rst b/developer_guides/linux_driver/index.rst index 4082c00b..c6534d70 100644 --- a/developer_guides/linux_driver/index.rst +++ b/developer_guides/linux_driver/index.rst @@ -6,6 +6,5 @@ SOF Linux Driver .. toctree:: :maxdepth: 1 - architecture/sof_driver_arch third_party/index From be45234485fab19fb8c308712fa5f15231c12559 Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Wed, 29 Dec 2021 15:17:02 +0100 Subject: [PATCH 011/150] Move FW architecture details to Architecture tree Signed-off-by: Michal Wasko --- .../firmware/components/component-mgmt-api.rst | 0 .../firmware/components/component-overview.rst | 0 .../firmware/components/images/comp-dev-states.pu | 0 .../firmware/components/images/comp-driver.pu | 0 .../firmware/components/images/comp-new-flow.pu | 0 .../components/images/component-mgmt-api.pu | 0 .../firmware/components/index.rst | 0 .../firmware/drivers/dai/images/dai-ops.pu | 0 .../firmware/drivers/dai/images/dai-set-config.pu | 0 .../firmware/drivers/dai/index.rst | 0 .../firmware/drivers/dma/images/dma-ops.pu | 0 .../firmware/drivers/dma/images/dma-transfer.pu | 0 .../firmware/drivers/dma/index.rst | 0 .../firmware/drivers/dma/intel/hda-dma.rst | 0 .../drivers/dma/intel/images/hda-host-output.pu | 0 .../firmware/drivers/dma/intel/images/hda-link.pu | 0 .../drivers/dma/intel/images/hda-start-flow.pu | 0 .../drivers/dma/intel/images/hda-stop-flow.pu | 0 .../firmware/drivers/dma/intel/index.rst | 0 .../firmware/drivers/images/device-disco.pu | 0 .../firmware/drivers/images/device-probe.pu | 0 .../firmware/drivers/images/device-remove.pu | 0 .../firmware/drivers/index.rst | 0 .../firmware/images/edf-scheduler-deps.pu | 0 .../firmware/images/edf-scheduler-flow.pu | 0 .../firmware/images/ll-scheduler-deps.pu | 0 .../firmware/images/ll-scheduler-flow.pu | 0 .../firmware/images/memory-zones.dot | 0 .../firmware/images/runtime-zone.dot | 0 .../firmware/images/scheduler-ops.pu | 0 .../firmware/images/system-zone.dot | 0 architectures/firmware/index.rst | 14 ++++++++++++++ .../kd_integration/images/kd-component-diagram.pu | 0 .../images/kd-e2e-sequence-diagram.pu | 0 .../kd_integration/images/kd-state-diagram.pu | 0 .../kd_integration/images/kd-timing-diagram.pu | 0 .../firmware/kd_integration/index.rst | 0 .../firmware/kd_integration/kd-integration.rst | 0 .../firmware/mem-mgmt.rst | 0 .../firmware/pipelines/images/ppl-new.pu | 0 .../firmware/pipelines/images/ppl-op-downstream.pu | 0 .../firmware/pipelines/images/ppl-operations.pu | 0 .../firmware/pipelines/images/ppl-params.pu | 0 .../firmware/pipelines/images/ppl-reset.pu | 0 .../firmware/pipelines/images/ppl-struct.pu | 0 .../firmware/pipelines/images/ppl-task.pu | 0 .../firmware/pipelines/index.rst | 0 .../firmware/pm-runtime/images/pm-dsp-core-idle.pu | 0 .../firmware/pm-runtime/images/pm-dsp-core-init.pu | 0 .../firmware/pm-runtime/index.rst | 0 .../intel/images/dsp-core-lps-cavs-d0-d0i3-d0.pu | 0 .../firmware/pm-runtime/intel/pm-dsp-core-cavs.rst | 0 .../firmware/pm-runtime/pm-dsp-core.rst | 0 .../firmware/schedulers.rst | 0 developer_guides/firmware/index.rst | 7 ------- 55 files changed, 14 insertions(+), 7 deletions(-) rename {developer_guides => architectures}/firmware/components/component-mgmt-api.rst (100%) rename {developer_guides => architectures}/firmware/components/component-overview.rst (100%) rename {developer_guides => architectures}/firmware/components/images/comp-dev-states.pu (100%) rename {developer_guides => architectures}/firmware/components/images/comp-driver.pu (100%) rename {developer_guides => architectures}/firmware/components/images/comp-new-flow.pu (100%) rename {developer_guides => architectures}/firmware/components/images/component-mgmt-api.pu (100%) rename {developer_guides => architectures}/firmware/components/index.rst (100%) rename {developer_guides => architectures}/firmware/drivers/dai/images/dai-ops.pu (100%) rename {developer_guides => architectures}/firmware/drivers/dai/images/dai-set-config.pu (100%) rename {developer_guides => architectures}/firmware/drivers/dai/index.rst (100%) rename {developer_guides => architectures}/firmware/drivers/dma/images/dma-ops.pu (100%) rename {developer_guides => architectures}/firmware/drivers/dma/images/dma-transfer.pu (100%) rename {developer_guides => architectures}/firmware/drivers/dma/index.rst (100%) rename {developer_guides => architectures}/firmware/drivers/dma/intel/hda-dma.rst (100%) rename {developer_guides => architectures}/firmware/drivers/dma/intel/images/hda-host-output.pu (100%) rename {developer_guides => architectures}/firmware/drivers/dma/intel/images/hda-link.pu (100%) rename {developer_guides => architectures}/firmware/drivers/dma/intel/images/hda-start-flow.pu (100%) rename {developer_guides => architectures}/firmware/drivers/dma/intel/images/hda-stop-flow.pu (100%) rename {developer_guides => architectures}/firmware/drivers/dma/intel/index.rst (100%) rename {developer_guides => architectures}/firmware/drivers/images/device-disco.pu (100%) rename {developer_guides => architectures}/firmware/drivers/images/device-probe.pu (100%) rename {developer_guides => architectures}/firmware/drivers/images/device-remove.pu (100%) rename {developer_guides => architectures}/firmware/drivers/index.rst (100%) rename {developer_guides => architectures}/firmware/images/edf-scheduler-deps.pu (100%) rename {developer_guides => architectures}/firmware/images/edf-scheduler-flow.pu (100%) rename {developer_guides => architectures}/firmware/images/ll-scheduler-deps.pu (100%) rename {developer_guides => architectures}/firmware/images/ll-scheduler-flow.pu (100%) rename {developer_guides => architectures}/firmware/images/memory-zones.dot (100%) rename {developer_guides => architectures}/firmware/images/runtime-zone.dot (100%) rename {developer_guides => architectures}/firmware/images/scheduler-ops.pu (100%) rename {developer_guides => architectures}/firmware/images/system-zone.dot (100%) rename {developer_guides => architectures}/firmware/kd_integration/images/kd-component-diagram.pu (100%) rename {developer_guides => architectures}/firmware/kd_integration/images/kd-e2e-sequence-diagram.pu (100%) rename {developer_guides => architectures}/firmware/kd_integration/images/kd-state-diagram.pu (100%) rename {developer_guides => architectures}/firmware/kd_integration/images/kd-timing-diagram.pu (100%) rename {developer_guides => architectures}/firmware/kd_integration/index.rst (100%) rename {developer_guides => architectures}/firmware/kd_integration/kd-integration.rst (100%) rename {developer_guides => architectures}/firmware/mem-mgmt.rst (100%) rename {developer_guides => architectures}/firmware/pipelines/images/ppl-new.pu (100%) rename {developer_guides => architectures}/firmware/pipelines/images/ppl-op-downstream.pu (100%) rename {developer_guides => architectures}/firmware/pipelines/images/ppl-operations.pu (100%) rename {developer_guides => architectures}/firmware/pipelines/images/ppl-params.pu (100%) rename {developer_guides => architectures}/firmware/pipelines/images/ppl-reset.pu (100%) rename {developer_guides => architectures}/firmware/pipelines/images/ppl-struct.pu (100%) rename {developer_guides => architectures}/firmware/pipelines/images/ppl-task.pu (100%) rename {developer_guides => architectures}/firmware/pipelines/index.rst (100%) rename {developer_guides => architectures}/firmware/pm-runtime/images/pm-dsp-core-idle.pu (100%) rename {developer_guides => architectures}/firmware/pm-runtime/images/pm-dsp-core-init.pu (100%) rename {developer_guides => architectures}/firmware/pm-runtime/index.rst (100%) rename {developer_guides => architectures}/firmware/pm-runtime/intel/images/dsp-core-lps-cavs-d0-d0i3-d0.pu (100%) rename {developer_guides => architectures}/firmware/pm-runtime/intel/pm-dsp-core-cavs.rst (100%) rename {developer_guides => architectures}/firmware/pm-runtime/pm-dsp-core.rst (100%) rename {developer_guides => architectures}/firmware/schedulers.rst (100%) diff --git a/developer_guides/firmware/components/component-mgmt-api.rst b/architectures/firmware/components/component-mgmt-api.rst similarity index 100% rename from developer_guides/firmware/components/component-mgmt-api.rst rename to architectures/firmware/components/component-mgmt-api.rst diff --git a/developer_guides/firmware/components/component-overview.rst b/architectures/firmware/components/component-overview.rst similarity index 100% rename from developer_guides/firmware/components/component-overview.rst rename to architectures/firmware/components/component-overview.rst diff --git a/developer_guides/firmware/components/images/comp-dev-states.pu b/architectures/firmware/components/images/comp-dev-states.pu similarity index 100% rename from developer_guides/firmware/components/images/comp-dev-states.pu rename to architectures/firmware/components/images/comp-dev-states.pu diff --git a/developer_guides/firmware/components/images/comp-driver.pu b/architectures/firmware/components/images/comp-driver.pu similarity index 100% rename from developer_guides/firmware/components/images/comp-driver.pu rename to architectures/firmware/components/images/comp-driver.pu diff --git a/developer_guides/firmware/components/images/comp-new-flow.pu b/architectures/firmware/components/images/comp-new-flow.pu similarity index 100% rename from developer_guides/firmware/components/images/comp-new-flow.pu rename to architectures/firmware/components/images/comp-new-flow.pu diff --git a/developer_guides/firmware/components/images/component-mgmt-api.pu b/architectures/firmware/components/images/component-mgmt-api.pu similarity index 100% rename from developer_guides/firmware/components/images/component-mgmt-api.pu rename to architectures/firmware/components/images/component-mgmt-api.pu diff --git a/developer_guides/firmware/components/index.rst b/architectures/firmware/components/index.rst similarity index 100% rename from developer_guides/firmware/components/index.rst rename to architectures/firmware/components/index.rst diff --git a/developer_guides/firmware/drivers/dai/images/dai-ops.pu b/architectures/firmware/drivers/dai/images/dai-ops.pu similarity index 100% rename from developer_guides/firmware/drivers/dai/images/dai-ops.pu rename to architectures/firmware/drivers/dai/images/dai-ops.pu diff --git a/developer_guides/firmware/drivers/dai/images/dai-set-config.pu b/architectures/firmware/drivers/dai/images/dai-set-config.pu similarity index 100% rename from developer_guides/firmware/drivers/dai/images/dai-set-config.pu rename to architectures/firmware/drivers/dai/images/dai-set-config.pu diff --git a/developer_guides/firmware/drivers/dai/index.rst b/architectures/firmware/drivers/dai/index.rst similarity index 100% rename from developer_guides/firmware/drivers/dai/index.rst rename to architectures/firmware/drivers/dai/index.rst diff --git a/developer_guides/firmware/drivers/dma/images/dma-ops.pu b/architectures/firmware/drivers/dma/images/dma-ops.pu similarity index 100% rename from developer_guides/firmware/drivers/dma/images/dma-ops.pu rename to architectures/firmware/drivers/dma/images/dma-ops.pu diff --git a/developer_guides/firmware/drivers/dma/images/dma-transfer.pu b/architectures/firmware/drivers/dma/images/dma-transfer.pu similarity index 100% rename from developer_guides/firmware/drivers/dma/images/dma-transfer.pu rename to architectures/firmware/drivers/dma/images/dma-transfer.pu diff --git a/developer_guides/firmware/drivers/dma/index.rst b/architectures/firmware/drivers/dma/index.rst similarity index 100% rename from developer_guides/firmware/drivers/dma/index.rst rename to architectures/firmware/drivers/dma/index.rst diff --git a/developer_guides/firmware/drivers/dma/intel/hda-dma.rst b/architectures/firmware/drivers/dma/intel/hda-dma.rst similarity index 100% rename from developer_guides/firmware/drivers/dma/intel/hda-dma.rst rename to architectures/firmware/drivers/dma/intel/hda-dma.rst diff --git a/developer_guides/firmware/drivers/dma/intel/images/hda-host-output.pu b/architectures/firmware/drivers/dma/intel/images/hda-host-output.pu similarity index 100% rename from developer_guides/firmware/drivers/dma/intel/images/hda-host-output.pu rename to architectures/firmware/drivers/dma/intel/images/hda-host-output.pu diff --git a/developer_guides/firmware/drivers/dma/intel/images/hda-link.pu b/architectures/firmware/drivers/dma/intel/images/hda-link.pu similarity index 100% rename from developer_guides/firmware/drivers/dma/intel/images/hda-link.pu rename to architectures/firmware/drivers/dma/intel/images/hda-link.pu diff --git a/developer_guides/firmware/drivers/dma/intel/images/hda-start-flow.pu b/architectures/firmware/drivers/dma/intel/images/hda-start-flow.pu similarity index 100% rename from developer_guides/firmware/drivers/dma/intel/images/hda-start-flow.pu rename to architectures/firmware/drivers/dma/intel/images/hda-start-flow.pu diff --git a/developer_guides/firmware/drivers/dma/intel/images/hda-stop-flow.pu b/architectures/firmware/drivers/dma/intel/images/hda-stop-flow.pu similarity index 100% rename from developer_guides/firmware/drivers/dma/intel/images/hda-stop-flow.pu rename to architectures/firmware/drivers/dma/intel/images/hda-stop-flow.pu diff --git a/developer_guides/firmware/drivers/dma/intel/index.rst b/architectures/firmware/drivers/dma/intel/index.rst similarity index 100% rename from developer_guides/firmware/drivers/dma/intel/index.rst rename to architectures/firmware/drivers/dma/intel/index.rst diff --git a/developer_guides/firmware/drivers/images/device-disco.pu b/architectures/firmware/drivers/images/device-disco.pu similarity index 100% rename from developer_guides/firmware/drivers/images/device-disco.pu rename to architectures/firmware/drivers/images/device-disco.pu diff --git a/developer_guides/firmware/drivers/images/device-probe.pu b/architectures/firmware/drivers/images/device-probe.pu similarity index 100% rename from developer_guides/firmware/drivers/images/device-probe.pu rename to architectures/firmware/drivers/images/device-probe.pu diff --git a/developer_guides/firmware/drivers/images/device-remove.pu b/architectures/firmware/drivers/images/device-remove.pu similarity index 100% rename from developer_guides/firmware/drivers/images/device-remove.pu rename to architectures/firmware/drivers/images/device-remove.pu diff --git a/developer_guides/firmware/drivers/index.rst b/architectures/firmware/drivers/index.rst similarity index 100% rename from developer_guides/firmware/drivers/index.rst rename to architectures/firmware/drivers/index.rst diff --git a/developer_guides/firmware/images/edf-scheduler-deps.pu b/architectures/firmware/images/edf-scheduler-deps.pu similarity index 100% rename from developer_guides/firmware/images/edf-scheduler-deps.pu rename to architectures/firmware/images/edf-scheduler-deps.pu diff --git a/developer_guides/firmware/images/edf-scheduler-flow.pu b/architectures/firmware/images/edf-scheduler-flow.pu similarity index 100% rename from developer_guides/firmware/images/edf-scheduler-flow.pu rename to architectures/firmware/images/edf-scheduler-flow.pu diff --git a/developer_guides/firmware/images/ll-scheduler-deps.pu b/architectures/firmware/images/ll-scheduler-deps.pu similarity index 100% rename from developer_guides/firmware/images/ll-scheduler-deps.pu rename to architectures/firmware/images/ll-scheduler-deps.pu diff --git a/developer_guides/firmware/images/ll-scheduler-flow.pu b/architectures/firmware/images/ll-scheduler-flow.pu similarity index 100% rename from developer_guides/firmware/images/ll-scheduler-flow.pu rename to architectures/firmware/images/ll-scheduler-flow.pu diff --git a/developer_guides/firmware/images/memory-zones.dot b/architectures/firmware/images/memory-zones.dot similarity index 100% rename from developer_guides/firmware/images/memory-zones.dot rename to architectures/firmware/images/memory-zones.dot diff --git a/developer_guides/firmware/images/runtime-zone.dot b/architectures/firmware/images/runtime-zone.dot similarity index 100% rename from developer_guides/firmware/images/runtime-zone.dot rename to architectures/firmware/images/runtime-zone.dot diff --git a/developer_guides/firmware/images/scheduler-ops.pu b/architectures/firmware/images/scheduler-ops.pu similarity index 100% rename from developer_guides/firmware/images/scheduler-ops.pu rename to architectures/firmware/images/scheduler-ops.pu diff --git a/developer_guides/firmware/images/system-zone.dot b/architectures/firmware/images/system-zone.dot similarity index 100% rename from developer_guides/firmware/images/system-zone.dot rename to architectures/firmware/images/system-zone.dot diff --git a/architectures/firmware/index.rst b/architectures/firmware/index.rst index fd2ca745..0cd53d78 100644 --- a/architectures/firmware/index.rst +++ b/architectures/firmware/index.rst @@ -3,6 +3,9 @@ Firmware Architecture ##################### +Overview +======== + Currently SOF has support for the Cadence Xtensa DSP architecture in UP and SMP modes in the upstream code base today. @@ -45,6 +48,17 @@ Each section above is well insulated from the other sections by partitioning code into separate directories and by using DSP and platform agnostic generic APIs for orchestration between the sections. +.. toctree:: + :maxdepth: 1 + + mem-mgmt + pm-runtime/index + schedulers + drivers/index + components/index + pipelines/index + kd_integration/index + Vendor Specific Architecture Information ======================================== diff --git a/developer_guides/firmware/kd_integration/images/kd-component-diagram.pu b/architectures/firmware/kd_integration/images/kd-component-diagram.pu similarity index 100% rename from developer_guides/firmware/kd_integration/images/kd-component-diagram.pu rename to architectures/firmware/kd_integration/images/kd-component-diagram.pu diff --git a/developer_guides/firmware/kd_integration/images/kd-e2e-sequence-diagram.pu b/architectures/firmware/kd_integration/images/kd-e2e-sequence-diagram.pu similarity index 100% rename from developer_guides/firmware/kd_integration/images/kd-e2e-sequence-diagram.pu rename to architectures/firmware/kd_integration/images/kd-e2e-sequence-diagram.pu diff --git a/developer_guides/firmware/kd_integration/images/kd-state-diagram.pu b/architectures/firmware/kd_integration/images/kd-state-diagram.pu similarity index 100% rename from developer_guides/firmware/kd_integration/images/kd-state-diagram.pu rename to architectures/firmware/kd_integration/images/kd-state-diagram.pu diff --git a/developer_guides/firmware/kd_integration/images/kd-timing-diagram.pu b/architectures/firmware/kd_integration/images/kd-timing-diagram.pu similarity index 100% rename from developer_guides/firmware/kd_integration/images/kd-timing-diagram.pu rename to architectures/firmware/kd_integration/images/kd-timing-diagram.pu diff --git a/developer_guides/firmware/kd_integration/index.rst b/architectures/firmware/kd_integration/index.rst similarity index 100% rename from developer_guides/firmware/kd_integration/index.rst rename to architectures/firmware/kd_integration/index.rst diff --git a/developer_guides/firmware/kd_integration/kd-integration.rst b/architectures/firmware/kd_integration/kd-integration.rst similarity index 100% rename from developer_guides/firmware/kd_integration/kd-integration.rst rename to architectures/firmware/kd_integration/kd-integration.rst diff --git a/developer_guides/firmware/mem-mgmt.rst b/architectures/firmware/mem-mgmt.rst similarity index 100% rename from developer_guides/firmware/mem-mgmt.rst rename to architectures/firmware/mem-mgmt.rst diff --git a/developer_guides/firmware/pipelines/images/ppl-new.pu b/architectures/firmware/pipelines/images/ppl-new.pu similarity index 100% rename from developer_guides/firmware/pipelines/images/ppl-new.pu rename to architectures/firmware/pipelines/images/ppl-new.pu diff --git a/developer_guides/firmware/pipelines/images/ppl-op-downstream.pu b/architectures/firmware/pipelines/images/ppl-op-downstream.pu similarity index 100% rename from developer_guides/firmware/pipelines/images/ppl-op-downstream.pu rename to architectures/firmware/pipelines/images/ppl-op-downstream.pu diff --git a/developer_guides/firmware/pipelines/images/ppl-operations.pu b/architectures/firmware/pipelines/images/ppl-operations.pu similarity index 100% rename from developer_guides/firmware/pipelines/images/ppl-operations.pu rename to architectures/firmware/pipelines/images/ppl-operations.pu diff --git a/developer_guides/firmware/pipelines/images/ppl-params.pu b/architectures/firmware/pipelines/images/ppl-params.pu similarity index 100% rename from developer_guides/firmware/pipelines/images/ppl-params.pu rename to architectures/firmware/pipelines/images/ppl-params.pu diff --git a/developer_guides/firmware/pipelines/images/ppl-reset.pu b/architectures/firmware/pipelines/images/ppl-reset.pu similarity index 100% rename from developer_guides/firmware/pipelines/images/ppl-reset.pu rename to architectures/firmware/pipelines/images/ppl-reset.pu diff --git a/developer_guides/firmware/pipelines/images/ppl-struct.pu b/architectures/firmware/pipelines/images/ppl-struct.pu similarity index 100% rename from developer_guides/firmware/pipelines/images/ppl-struct.pu rename to architectures/firmware/pipelines/images/ppl-struct.pu diff --git a/developer_guides/firmware/pipelines/images/ppl-task.pu b/architectures/firmware/pipelines/images/ppl-task.pu similarity index 100% rename from developer_guides/firmware/pipelines/images/ppl-task.pu rename to architectures/firmware/pipelines/images/ppl-task.pu diff --git a/developer_guides/firmware/pipelines/index.rst b/architectures/firmware/pipelines/index.rst similarity index 100% rename from developer_guides/firmware/pipelines/index.rst rename to architectures/firmware/pipelines/index.rst diff --git a/developer_guides/firmware/pm-runtime/images/pm-dsp-core-idle.pu b/architectures/firmware/pm-runtime/images/pm-dsp-core-idle.pu similarity index 100% rename from developer_guides/firmware/pm-runtime/images/pm-dsp-core-idle.pu rename to architectures/firmware/pm-runtime/images/pm-dsp-core-idle.pu diff --git a/developer_guides/firmware/pm-runtime/images/pm-dsp-core-init.pu b/architectures/firmware/pm-runtime/images/pm-dsp-core-init.pu similarity index 100% rename from developer_guides/firmware/pm-runtime/images/pm-dsp-core-init.pu rename to architectures/firmware/pm-runtime/images/pm-dsp-core-init.pu diff --git a/developer_guides/firmware/pm-runtime/index.rst b/architectures/firmware/pm-runtime/index.rst similarity index 100% rename from developer_guides/firmware/pm-runtime/index.rst rename to architectures/firmware/pm-runtime/index.rst diff --git a/developer_guides/firmware/pm-runtime/intel/images/dsp-core-lps-cavs-d0-d0i3-d0.pu b/architectures/firmware/pm-runtime/intel/images/dsp-core-lps-cavs-d0-d0i3-d0.pu similarity index 100% rename from developer_guides/firmware/pm-runtime/intel/images/dsp-core-lps-cavs-d0-d0i3-d0.pu rename to architectures/firmware/pm-runtime/intel/images/dsp-core-lps-cavs-d0-d0i3-d0.pu diff --git a/developer_guides/firmware/pm-runtime/intel/pm-dsp-core-cavs.rst b/architectures/firmware/pm-runtime/intel/pm-dsp-core-cavs.rst similarity index 100% rename from developer_guides/firmware/pm-runtime/intel/pm-dsp-core-cavs.rst rename to architectures/firmware/pm-runtime/intel/pm-dsp-core-cavs.rst diff --git a/developer_guides/firmware/pm-runtime/pm-dsp-core.rst b/architectures/firmware/pm-runtime/pm-dsp-core.rst similarity index 100% rename from developer_guides/firmware/pm-runtime/pm-dsp-core.rst rename to architectures/firmware/pm-runtime/pm-dsp-core.rst diff --git a/developer_guides/firmware/schedulers.rst b/architectures/firmware/schedulers.rst similarity index 100% rename from developer_guides/firmware/schedulers.rst rename to architectures/firmware/schedulers.rst diff --git a/developer_guides/firmware/index.rst b/developer_guides/firmware/index.rst index 9584ee4f..6c9d3280 100644 --- a/developer_guides/firmware/index.rst +++ b/developer_guides/firmware/index.rst @@ -9,12 +9,5 @@ Developer guides and information for firmware development. :maxdepth: 1 component-tutorial/tut-intro - mem-mgmt - pm-runtime/index - schedulers - drivers/index - components/index - pipelines/index porting - kd_integration/index cmake From b8194a1a4ffab38720d1e91a69e667c3411e5b04 Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Wed, 29 Dec 2021 15:32:31 +0100 Subject: [PATCH 012/150] Move firmware architecture overview to separate file Signed-off-by: Michal Wasko --- architectures/firmware/index.rst | 46 +---------------------------- architectures/firmware/overview.rst | 46 +++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 45 deletions(-) create mode 100644 architectures/firmware/overview.rst diff --git a/architectures/firmware/index.rst b/architectures/firmware/index.rst index 0cd53d78..2e50cf73 100644 --- a/architectures/firmware/index.rst +++ b/architectures/firmware/index.rst @@ -3,54 +3,10 @@ Firmware Architecture ##################### -Overview -======== - -Currently SOF has support for the Cadence Xtensa DSP architecture in UP and SMP -modes in the upstream code base today. - -The diagram below shows the high-level firmware architecture with the -Baytrail platform integration as an example. The firmware is divided into four -main sections: - -#. **Generic microkernel.** The microkernel manages and abstracts the - DSP hardware for the rest of the system. It also exports C APIs for - memory allocation, scheduling work, event notifications, and power - management. - -#. **Audio components.** The audio components can be used to form an - audio processing pipeline from the host DMA buffer to the DSP digital - audio interface. Audio components will have a source and sink buffer - where they will usually transform or route audio data as part of their - processing. - -#. **Audio task.** The audio task manages the audio pipelines at run - time; it manages the transportation of data from source to sink - component within the pipeline. The pipelines are currently statically - defined in the firmware, but infrastructure is now in place to allow the - dynamic creation of pipelines from Linux userspace. - -#. **Platform drivers.** The platform drivers are used to control any - external IP to the DSP IP. This will usually be things like DMA engines - or DAI (Digital Audio Interface) controllers. These drivers are used by - the audio components and pipelines to send/receive data to/from the host - and external codecs. - - .. figure:: ../images/fw-arch-diag.png - :align: center - :alt: SOF Architecture - :width: 800px - - `Sound Open Firmware Architecture using Intel Baytrail Platform` - - -Each section above is well insulated from the other sections by partitioning -code into separate directories and by using DSP and platform agnostic generic -APIs for orchestration between the sections. - .. toctree:: :maxdepth: 1 + overview mem-mgmt pm-runtime/index schedulers diff --git a/architectures/firmware/overview.rst b/architectures/firmware/overview.rst new file mode 100644 index 00000000..48649106 --- /dev/null +++ b/architectures/firmware/overview.rst @@ -0,0 +1,46 @@ +.. _overview: + +Overview +########## + +Currently SOF has support for the Cadence Xtensa DSP architecture in UP and SMP +modes in the upstream code base. + +The diagram below shows the high-level firmware architecture with the +Bay Trail platform integration as an example. The firmware is divided into four +main sections: + +#. **Generic microkernel.** The microkernel manages and abstracts the + DSP hardware for the rest of the system. It also exports C APIs for + memory allocation, scheduling work, event notifications, and power + management. + +#. **Audio components.** The audio components can be used to form an + audio processing pipeline from the host DMA buffer to the DSP digital + audio interface. Audio components will have a source and sink buffer + where they will usually transform or route audio data as part of their + processing. + +#. **Audio task.** The audio task manages the audio pipelines at run + time; it manages the transportation of data from source to sink + component within the pipeline. The pipelines are currently statically + defined in the firmware, but infrastructure is now in place to allow the + dynamic creation of pipelines from Linux userspace. + +#. **Platform drivers.** The platform drivers are used to control any + external IP to the DSP IP. This will usually be things like DMA engines + or DAI (Digital Audio Interface) controllers. These drivers are used by + the audio components and pipelines to send/receive data to/from the host + and external codecs. + + .. figure:: ../images/fw-arch-diag.png + :align: center + :alt: SOF Architecture + :width: 800px + + `Sound Open Firmware Architecture using Intel Baytrail Platform` + + +Each section above is well insulated from the other sections by partitioning +code into separate directories and by using DSP and platform agnostic generic +APIs for orchestration between the sections. \ No newline at end of file From 5125972682400d8498f80e9bbca1de55df42eeb4 Mon Sep 17 00:00:00 2001 From: anton-intel Date: Sat, 1 Jan 2022 12:37:58 +0300 Subject: [PATCH 013/150] Update copyright to 2022 (#399) --- conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf.py b/conf.py index 4e7b7b53..02794784 100755 --- a/conf.py +++ b/conf.py @@ -63,7 +63,7 @@ # General information about the project. project = u'SOF Project' -copyright = u'2021, SOF Project' +copyright = u'2022, SOF Project' author = u'SOF Project developers' # The version info for the project you're documenting, acts as replacement for From a77b50fd4105cedccc9e846aebf7bd27e44535ef Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Tue, 1 Feb 2022 11:24:43 -0600 Subject: [PATCH 014/150] ktest: update needed git remotes and kconfig setups Reduce the number of remotes and use a script to create .config Signed-off-by: Pierre-Louis Bossart --- .../setup/setup_ktest_environment.rst | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/getting_started/setup/setup_ktest_environment.rst b/getting_started/setup/setup_ktest_environment.rst index 1b800ffd..77bc71fd 100644 --- a/getting_started/setup/setup_ktest_environment.rst +++ b/getting_started/setup/setup_ktest_environment.rst @@ -205,22 +205,19 @@ Create a linux development environment 2. Add a set of useful remotes ------------------------------ +The SOF contributions can be handled by different maintainers, so it's useful to point directly +to maintainer trees. + .. code-block:: bash git remote add sof https://github.com/thesofproject/linux.git git remote add takashi git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git git remote add broonie git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git - git remote add liam git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc.git - git remote add keyon git://github.com/keyonjie/linux.git git remote add vinod git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/sound.git - git remote add plb git://github.com/plbossart/sound.git git fetch sof git fetch takashi git fetch broonie - git fetch liam - git fetch keyon git fetch vinod - git fetch plb All of these branches will be accessible and can be updated from any worktree. Clone once and use fetch to update the main working tree. @@ -254,9 +251,8 @@ If you don't know what options are needed, you can start using configurations ma .. code-block:: bash git clone https://github.com/thesofproject/kconfig.git - cd linux - make defconfig - scripts/kconfig/merge_config.sh .config ../kconfig/base-defconfig ../kconfig/sof-defconfig ../kconfig/mach-driver-defconfig ../kconfig/hdaudio-codecs-defconfig + cd sof-dev + bash ../kconfig/kconfig-sof-default.sh cp .config ../sof-dev-defconfig make mrproper cd .. @@ -266,6 +262,14 @@ If you don't know what options are needed, you can start using configurations ma Use make proper since ktest.pl requires the source directory to be clean. All compilation happens in the -build directory. +.. note:: + + SOF developers and the Intel CI also use "kconfig-sof-nocodec.sh" on Up2 and UpExtreme boards. + +.. note:: + + Distributions should not use the options provided in kconfig/sof-dev-defconfig + 6. Edit ktest configuration as needed ------------------------------------- From 06388da6278b7bebc0ee6b0d6fda7fedb0bceb9d Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Mon, 24 Jan 2022 14:53:11 +0100 Subject: [PATCH 015/150] debugability: performance counters Performance counters usage descriptions added Signed-off-by: Michal Wasko --- developer_guides/debugability/index.rst | 1 + .../debugability/perf-counters/index.rst | 63 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 developer_guides/debugability/perf-counters/index.rst diff --git a/developer_guides/debugability/index.rst b/developer_guides/debugability/index.rst index 8c8f5d2a..02c712ef 100644 --- a/developer_guides/debugability/index.rst +++ b/developer_guides/debugability/index.rst @@ -11,3 +11,4 @@ Debugability coredump-reader/index probes/index ri-info/index + perf-counters/index diff --git a/developer_guides/debugability/perf-counters/index.rst b/developer_guides/debugability/perf-counters/index.rst new file mode 100644 index 00000000..db96c5c6 --- /dev/null +++ b/developer_guides/debugability/perf-counters/index.rst @@ -0,0 +1,63 @@ +.. _dbg-perf-counters: + +Performance Counters +#################### + +Firmware can be configured to trace performance counters for each processing +component. Each performance trace entry includes: + +- component UUID + +- peak platform and cpu timer ticks consumed during component's copy processing + +.. note:: + Performance timestamp macros use both the platform timer and cpu timer in case + the latter is not always running. + +Performance Counters usage +************************** + +Currently, you can only enable performance counters statically during FW build in +one of two ways: + +* Select **Performance counter** from **Debug** menu using ``make menuconfig`` + +* Add ``CONFIG_PERFORMANCE_COUNTERS=y`` to specific FW config, for +example, tigerlake_defconfig. + + +After you enable the performance counters, they are logged periodically for each +active component with the pipeline period frequency. + +Example +******* + +Performance counter trace example: + + .. code-block:: bash + + [ 8481257.031250] ( 51.562500) c0 demux 1.2 src/audio/pipeline.c:206 perf comp_copy peak plat 782 cpu 8136 + +``demux 1.2`` - processing component + +``plat 782`` - peak platform cycles consumed + +``cpu 8136`` - peak CPU cycles consumed + +MCPS calculation +---------------- + +The equation below illustrates how to calculate component MCPS (million cycles +per second) consumption. + + .. code-block:: bash + + MCPS = cpu_ticks / (pipeline_period[s] * 10^6) + + // for common pipeline_period = 1ms it can be simplified to + MCPS = cpu_ticks / 1000 + +In the trace example above, cpu_ticks = 8136, the pipeline_period is 1ms so the +demux consumption equals 8,136 MCPS + + From 749bf0c082f64f9cd8db9d916b6425299c27673d Mon Sep 17 00:00:00 2001 From: anton-intel Date: Wed, 2 Feb 2022 19:15:11 +0300 Subject: [PATCH 016/150] Fix for Performance Counters (#402) Build fails because of the following warning for perf-counters/index.rst: Bullet list ends without a blank line; unexpected unindent. Fixed the indent. Changed * to - for consistency. --- developer_guides/debugability/perf-counters/index.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/developer_guides/debugability/perf-counters/index.rst b/developer_guides/debugability/perf-counters/index.rst index db96c5c6..4e1ea77b 100644 --- a/developer_guides/debugability/perf-counters/index.rst +++ b/developer_guides/debugability/perf-counters/index.rst @@ -20,10 +20,10 @@ Performance Counters usage Currently, you can only enable performance counters statically during FW build in one of two ways: -* Select **Performance counter** from **Debug** menu using ``make menuconfig`` +- Select **Performance counter** from **Debug** menu using ``make menuconfig``. -* Add ``CONFIG_PERFORMANCE_COUNTERS=y`` to specific FW config, for -example, tigerlake_defconfig. +- Add ``CONFIG_PERFORMANCE_COUNTERS=y`` to specific FW config, for + example, tigerlake_defconfig. After you enable the performance counters, they are logged periodically for each From 2861c299abd15f3683ada6820201323a56275c7c Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Wed, 16 Feb 2022 13:57:41 +0100 Subject: [PATCH 017/150] Supported Platforms: Platform Clock column added Platform clock frequency information is required to get correct timestamps in sof-logger. Signed-off-by: Michal Wasko --- platforms/index.rst | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/platforms/index.rst b/platforms/index.rst index d968bf9d..c75379dc 100644 --- a/platforms/index.rst +++ b/platforms/index.rst @@ -9,27 +9,27 @@ Supported Platforms Platform and board specific support is continually added to the SOF project as documented below. .. csv-table:: Supported Platforms - :header: "Platform", "Architecture", "Cores/Clocks", "Memory", "Audio Interfaces" - :widths: 20, 20, 10, 10, 20 - - "Host Testbench", "PC command line", "N/A", "N/A", "N/A Files are used to simulate audio interfaces" - "Qemu", "All supported SOF HW platforms", "N/A", "N/A", "WiP Files will be used to simulate audio interfaces" - "Intel Baytrail / Merrifield", "Xtensa HiFi2 EP", "1 @ 50 - 400MHz", "96KB IRAM / 192KB DRAM", "3 x SSP (I2S, PCM)" - "Intel Cherrytrail / Braswell", "Xtensa HiFi2 EP", "1 @ 50 - 400MHz", "96KB IRAM / 192KB DRAM", "6 x SSP (I2S, PCM)" - "Intel Broadwell", "Xtensa HiFi2 EP", "1 @ 50 - 400MHz", "320KB IRAM / 640KB DRAM", "2 x SSP (I2S, PCM)" - "Intel Apollolake / Geminilake", "Xtensa HiFi3", "2 @ 100 - 400MHz", "128KB LP SRAM / 512KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC" - "Intel Cannonlake / Whiskeylake / Cometlake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "64KB LP / 3008KB HP SRAM", "3 x SSP (I2S, PCM), HDA, DMIC, Soundwire" - "Intel Suecreek", "Xtensa HiFi3", "2 @ 120 - 400MHz", "64KB LP SRAM / 4096KB HP SRAM", "6 x SSP (I2S, PCM), DMIC" - "Intel Icelake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "64KB LP SRAM / 3008KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" - "Intel Jasperlake", "Xtensa HiFi3", "2 @ 120 - 400MHz", "64KB LP SRAM / 1024KB HP SRAM", "3 x SSP (I2S, PCM), HDA, DMIC, Soundwire" - "Intel Tigerlake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "64KB LP SRAM / 2944KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" - "Intel Alderlake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "64KB LP SRAM / 2944KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" - "NXP i.MX8", "Xtensa HiFi4", "1 @ 666MHz", "64 KB TCM / 448 KB OCRAM / 8MB SDRAM", "1 x ESAI, 1 x SAI" - "NXP i.MX8X", "Xtensa HiFi4", "1 @ 640MHz", "64 KB TCM / 448 KB OCRAM / 8MB SDRAM", "1 x ESAI, 1 x SAI" - "NXP i.MX8M", "Xtensa HiFi4", "1 @ 800MHz", "64 KB TCM / 256 KB OCRAM / 8MB SDRAM", "1 x SAI, MICFIL" - "NXP i.MX8ULP", "Xtensa HiFi4", "1 @ 520MHz", "64 KB TCM / 256 KB OCRAM / 8MB SDRAM", "1 x SAI" - "AMD Renoir", "Xtensa HiFi3", "1 @ 600MHz", "20 KB LP SRAM / 1152 KB IRAM/DRAM", "1 x SP (I2S, PCM), 1 x BT (I2S, PCM), DMIC" - "Mediatek mt8195", "Xtensa HiFi4", "1 @ 220 - 720MHz", "256 KB SRAM / 16 MB DRAM", "2 x TDM Out, 1 x TDM In, DMIC" + :header: "Platform", "Architecture", "Cores/Clocks", "Platform Clock", "Memory", "Audio Interfaces" + :widths: 20, 20, 10, 10, 10, 20 + + "Host Testbench", "PC command line", "N/A", "N/A", "N/A", "N/A Files are used to simulate audio interfaces" + "Qemu", "All supported SOF HW platforms", "N/A", "N/A", "N/A", "WiP Files will be used to simulate audio interfaces" + "Intel Baytrail / Merrifield", "Xtensa HiFi2 EP", "1 @ 50 - 400MHz", "25MHz", "96KB IRAM / 192KB DRAM", "3 x SSP (I2S, PCM)" + "Intel Cherrytrail / Braswell", "Xtensa HiFi2 EP", "1 @ 50 - 400MHz", "19.2MHz", "96KB IRAM / 192KB DRAM", "6 x SSP (I2S, PCM)" + "Intel Broadwell", "Xtensa HiFi2 EP", "1 @ 50 - 400MHz", "24MHz", "320KB IRAM / 640KB DRAM", "2 x SSP (I2S, PCM)" + "Intel Apollolake / Geminilake", "Xtensa HiFi3", "2 @ 100 - 400MHz", "19.2MHz", "128KB LP SRAM / 512KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC" + "Intel Cannonlake / Whiskeylake / Cometlake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "19.2Hz or 24MHz strap selectable", "64KB LP / 3008KB HP SRAM", "3 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "Intel Suecreek", "Xtensa HiFi3", "2 @ 120 - 400MHz","19.2Hz or 24MHz strap selectable", "64KB LP SRAM / 4096KB HP SRAM", "6 x SSP (I2S, PCM), DMIC" + "Intel Icelake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "24MHz or 38.4MHz strap selectable", "64KB LP SRAM / 3008KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "Intel Jasperlake", "Xtensa HiFi3", "2 @ 120 - 400MHz", "24MHz or 38.4MHz strap selectable", "64KB LP SRAM / 1024KB HP SRAM", "3 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "Intel Tigerlake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "24MHz or 38.4MHz strap selectable", "64KB LP SRAM / 2944KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "Intel Alderlake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "24MHz or 38.4MHz strap selectable", "64KB LP SRAM / 2944KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "NXP i.MX8", "Xtensa HiFi4", "1 @ 666MHz", "TBD", "64 KB TCM / 448 KB OCRAM / 8MB SDRAM", "1 x ESAI, 1 x SAI" + "NXP i.MX8X", "Xtensa HiFi4", "1 @ 640MHz", "TBD", "64 KB TCM / 448 KB OCRAM / 8MB SDRAM", "1 x ESAI, 1 x SAI" + "NXP i.MX8M", "Xtensa HiFi4", "1 @ 800MHz", "TBD", "64 KB TCM / 256 KB OCRAM / 8MB SDRAM", "1 x SAI, MICFIL" + "NXP i.MX8ULP", "Xtensa HiFi4", "1 @ 520MHz", "TBD", "64 KB TCM / 256 KB OCRAM / 8MB SDRAM", "1 x SAI" + "AMD Renoir", "Xtensa HiFi3", "1 @ 600MHz", "TBD", "20 KB LP SRAM / 1152 KB IRAM/DRAM", "1 x SP (I2S, PCM), 1 x BT (I2S, PCM), DMIC" + "Mediatek mt8195", "Xtensa HiFi4", "1 @ 220 - 720MHz", "TBD", "256 KB SRAM / 16 MB DRAM", "2 x TDM Out, 1 x TDM In, DMIC" When support for a new platform is being added, certain interfaces required by SOF infrastructure must be implemented. Refer to Platform API documentation From f33a5da5ac5c5f387efa2d4175b361152c347cf5 Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Thu, 17 Feb 2022 09:54:14 +0100 Subject: [PATCH 018/150] Supported Platforms: intel platform clocks update Platform clock value limited to currently supported configuration. Signed-off-by: Michal Wasko --- platforms/index.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/platforms/index.rst b/platforms/index.rst index c75379dc..27fd5407 100644 --- a/platforms/index.rst +++ b/platforms/index.rst @@ -18,12 +18,12 @@ Platform and board specific support is continually added to the SOF project as d "Intel Cherrytrail / Braswell", "Xtensa HiFi2 EP", "1 @ 50 - 400MHz", "19.2MHz", "96KB IRAM / 192KB DRAM", "6 x SSP (I2S, PCM)" "Intel Broadwell", "Xtensa HiFi2 EP", "1 @ 50 - 400MHz", "24MHz", "320KB IRAM / 640KB DRAM", "2 x SSP (I2S, PCM)" "Intel Apollolake / Geminilake", "Xtensa HiFi3", "2 @ 100 - 400MHz", "19.2MHz", "128KB LP SRAM / 512KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC" - "Intel Cannonlake / Whiskeylake / Cometlake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "19.2Hz or 24MHz strap selectable", "64KB LP / 3008KB HP SRAM", "3 x SSP (I2S, PCM), HDA, DMIC, Soundwire" - "Intel Suecreek", "Xtensa HiFi3", "2 @ 120 - 400MHz","19.2Hz or 24MHz strap selectable", "64KB LP SRAM / 4096KB HP SRAM", "6 x SSP (I2S, PCM), DMIC" - "Intel Icelake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "24MHz or 38.4MHz strap selectable", "64KB LP SRAM / 3008KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" - "Intel Jasperlake", "Xtensa HiFi3", "2 @ 120 - 400MHz", "24MHz or 38.4MHz strap selectable", "64KB LP SRAM / 1024KB HP SRAM", "3 x SSP (I2S, PCM), HDA, DMIC, Soundwire" - "Intel Tigerlake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "24MHz or 38.4MHz strap selectable", "64KB LP SRAM / 2944KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" - "Intel Alderlake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "24MHz or 38.4MHz strap selectable", "64KB LP SRAM / 2944KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "Intel Cannonlake / Whiskeylake / Cometlake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "24MHz", "64KB LP / 3008KB HP SRAM", "3 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "Intel Suecreek", "Xtensa HiFi3", "2 @ 120 - 400MHz","24MHz", "64KB LP SRAM / 4096KB HP SRAM", "6 x SSP (I2S, PCM), DMIC" + "Intel Icelake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 3008KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "Intel Jasperlake", "Xtensa HiFi3", "2 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 1024KB HP SRAM", "3 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "Intel Tigerlake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 2944KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "Intel Alderlake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 2944KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" "NXP i.MX8", "Xtensa HiFi4", "1 @ 666MHz", "TBD", "64 KB TCM / 448 KB OCRAM / 8MB SDRAM", "1 x ESAI, 1 x SAI" "NXP i.MX8X", "Xtensa HiFi4", "1 @ 640MHz", "TBD", "64 KB TCM / 448 KB OCRAM / 8MB SDRAM", "1 x ESAI, 1 x SAI" "NXP i.MX8M", "Xtensa HiFi4", "1 @ 800MHz", "TBD", "64 KB TCM / 256 KB OCRAM / 8MB SDRAM", "1 x SAI, MICFIL" From b1be685e18748dc7bf9abf8aad276e01887528d0 Mon Sep 17 00:00:00 2001 From: Noah Klayman Date: Fri, 4 Feb 2022 20:00:24 +0000 Subject: [PATCH 019/150] feat(getting_started): update organization and instructions - Change the organization of the getting started section to make it easier to determine which guide to follow. - Add instructions for building a custom kernel with SOF config so that it can be booted on that same device. This is useful for people without dedicated test hardware who just want to try out the latest code, such as when they are running into issues with new hardware. - Revamp the ktest setup documentation. This was very out of date and had tons of errors, especially for using Fedora. It has now been validated to work on both Fedora and Ubuntu target devices, from a Ubuntu dev machine (but Fedora should work just fine too). Signed-off-by: Noah Klayman --- getting_started/index.rst | 32 ++- .../setup_linux/install_locally.rst | 109 +++++++ .../setup_linux/prepare_build_environment.rst | 102 +++++++ .../setup_ktest_environment.rst | 266 +++++++++--------- .../images/minnow_turbot.png | Bin .../setup_minnowboard_turbot.rst | 0 .../setup_up_2_board.rst | 0 7 files changed, 374 insertions(+), 135 deletions(-) create mode 100644 getting_started/setup_linux/install_locally.rst create mode 100644 getting_started/setup_linux/prepare_build_environment.rst rename getting_started/{setup => setup_linux}/setup_ktest_environment.rst (50%) rename getting_started/{setup => setup_special_device}/images/minnow_turbot.png (100%) rename getting_started/{setup => setup_special_device}/setup_minnowboard_turbot.rst (100%) rename getting_started/{setup => setup_special_device}/setup_up_2_board.rst (100%) diff --git a/getting_started/index.rst b/getting_started/index.rst index a9511ef1..a932ec3a 100755 --- a/getting_started/index.rst +++ b/getting_started/index.rst @@ -21,18 +21,36 @@ current distro release is always preferred. build-guide/build-3rd-party-toolchain build-guide/build-with-zephyr -Set up SOF on hardware -********************** +Set up SOF on a Linux machine +***************************** -SOF runs on a variety of devices with varying audio capabilities so -instructions may differ between devices. +You can build the Linux kernel with the latest SOF code and install it locally or remotely with ktest. + +Do this first: + +.. toctree:: + :maxdepth: 1 + + setup_linux/prepare_build_environment + +Then proceed based on if you are installing locally or through ktest: + +.. toctree:: + :maxdepth: 1 + + setup_linux/install_locally + setup_linux/setup_ktest_environment + +Set up SOF on a special device +****************************** + +SOF also runs on the MinnowBoard Turbot and the Up Squared board with Hifiberry Dac+. .. toctree:: :maxdepth: 1 - setup/setup_minnowboard_turbot - setup/setup_up_2_board - setup/setup_ktest_environment + setup_special_device/setup_minnowboard_turbot + setup_special_device/setup_up_2_board Debug Audio issues on Intel platforms ************************************* diff --git a/getting_started/setup_linux/install_locally.rst b/getting_started/setup_linux/install_locally.rst new file mode 100644 index 00000000..f62c0594 --- /dev/null +++ b/getting_started/setup_linux/install_locally.rst @@ -0,0 +1,109 @@ +.. _install-locally: + +Install the Kernel locally +####################################### + +.. contents:: + :local: + :depth: 3 + +Introduction +************ + +Make sure you have `setup your development environment `_ before following these steps. This page will guide you through the process of installing the kernel locally on your machine. It will be installed in addition to your distro's default kernel so that you can always change back to that in case something goes wrong. If you're interested in learning more about this process there's lots of online guides available, for example `Fedora's guide `_ or `this wiki page `_. + + +Build and install the kernel +**************************** + +(You should be in the ``~/sof/linux`` directory you created on the setup page) + +1. Load base kernel configuration +--------------------------------- + +.. code-block:: bash + + # This will copy the booted kernel's configuration so that it will be used as a base + cp /boot/config-$(uname -r)* .config + + +2. Apply SOF-specific configuration +----------------------------------- + +The following scripts will update your base config so that it uses the latest SOF modules. Run only one of them depending on your needs. If it prompts you with any questions, just press to accept the default value. Note that, by default, these scripts will set the configuration to only compile modules that are currently loaded in order to lower compile times. This means that when you've booted from the custom kernel some external devices may not work if they weren't connected while running this script. If you want to compile all modules, delete the line ``make localmodconfig`` from the script you will run in this step. + +.. code-block:: bash + + # For most users + ../kconfig/kconfig-distro-sof-update.sh + # For additional logging and experimental device support + ../kconfig/kconfig-distro-sof-dev-update.sh + +3. Compile the kernel +--------------------- + +.. code-block:: bash + + # The first time you run this it can take a while (over 30 minutes on some machines), + # so grab a coffee or take an exercise break while it runs + make -j$(nproc --all) + +4. Install the kernel +--------------------- + +.. code-block:: bash + + sudo make modules_install + sudo make install + +If all went well, your freshly-built kernel will be installed and available at next boot. Restart your computer, and you should have the option to pick a kernel when it turns on. Select the kernel that has "-sof" at the end of it, and your computer should boot as normal using the kernel you just built. On Ubuntu, the kernel option may be hidden behind the "Advanced options for Ubuntu" submenu. + +5. Updating and rebuilding +-------------------------- + +If you need to try some new changes, you'll have to download the updated code and rebuild the kernel. + +If you originally cloned the repo using git, you just need to pull the changes: + +.. code-block:: bash + + git pull + # You should run this after switching branches or configuration or any other major code change + # If you just pulled some minor updates, it's likely unnecessary and will increase your build time + make clean + +Now, repeat steps 3 and 4 to rebuild and reinstall the kernel. Reboot your computer, and select the kernel with -sof at the end to test it. + +Unfortunately, if you downloaded via zip, the entire process has to be restarted from the "Get the kernel source" section; there's no good way to incrementally update. However, the kernel build should be faster now as part of it will be cached. + +.. code-block:: bash + + cd .. + # Delete the old folder before starting over + rm -rf linux + +6. Removing the kernel +---------------------- + +If you run into issues or no longer need the custom kernel, you can remove it. + +Ubuntu: + +.. code-block:: bash + + cd ~/sof/linux + sudo rm /boot/*-$(make kernelversion) + sudo rm -rf /lib/modules/$(make kernelversion) + sudo update-grub + +Fedora: + +.. code-block:: bash + + cd ~/sof/linux + sudo rm /boot/*-$(make kernelversion)* + sudo rm -rf /lib/modules/$(make kernelversion) + sudo grubby --remove-kernel=/boot/vmlinuz-$(make kernelversion) + + +After rebooting, you should be back to your old kernel with all traces of the custom kernel installation gone. If you'd like, you can also delete the ``~sof`` directory to save disk space. diff --git a/getting_started/setup_linux/prepare_build_environment.rst b/getting_started/setup_linux/prepare_build_environment.rst new file mode 100644 index 00000000..30382aa7 --- /dev/null +++ b/getting_started/setup_linux/prepare_build_environment.rst @@ -0,0 +1,102 @@ +.. _prepare-build-environment: + +Set up a development environment to build the kernel +#################################################### + +.. contents:: + :local: + :depth: 3 + +Introduction +************ + + +These instructions will help you set up a development environment for the SOF branch of the Linux kernel. If you have dedicated test hardware you can use ktest to install it over ssh, otherwise you can install it locally on your device in addition to your default kernel. + +Prerequisites +************* + +1. Device requirements +----------------------- + +**Development device:** PC running Fedora 35+ or Ubuntu 20.04+. + +**Target device:** PC running Fedora 35+ or Ubuntu 20.04+, with secure boot disabled. If the target device is different than the development device you must be able to ssh into the target, which is typically on the same local network/VPN. + +2. Create working directory +--------------------------- + +This directory can be located anywhere, simply change the ``SOF_WORKSPACE`` variable if you would like to store your sources somewhere else. + +.. code-block:: bash + + export SOF_WORKSPACE=~/work/sof + mkdir -p $SOF_WORKSPACE + cd $SOF_WORKSPACE + +3. Install kernel build dependencies +------------------------------------ + +Fedora (see `their guide `_ for details): + +.. code-block:: bash + + sudo dnf install fedpkg + fedpkg clone -a kernel + cd kernel + sudo dnf builddep kernel.spec + sudo dnf install ccache + cd .. + +Ubuntu (see `their page `_ for details): + +.. code-block:: bash + + sudo apt update + sudo apt install git libncurses-dev gawk flex bison openssl libssl-dev dkms libelf-dev libudev-dev libpci-dev libiberty-dev autoconf dwarves zstd + +4. Download the configuration scripts +------------------------------------- + +.. code-block:: bash + + git clone https://github.com/thesofproject/kconfig.git + +Get the kernel source +********************* + +There are two ways to get the kernel source. We strongly recommend using git as it makes updates **much** easier, but the zip download may be more successful if you have an unstable connection. + +Option 1: Clone with git +------------------------ +.. code-block:: bash + + # If a maintainer requests that you check out a different branch + # to test a bug fix, add -b [branch] + # to the end of this command, where [branch] is the branch name + git clone https://github.com/thesofproject/linux.git --depth=1 + cd linux + +Option 2: Download via zip +-------------------------- + +Visit the SOF Linux fork at https://github.com/thesofproject/linux. If a maintainer asks you to test a specific branch, click the dropdown with the text "topic/sof-dev" and select the branch they asked you to test. Then, click the green "Code" dropdown and select "download zip". Once it's downloaded, extract it to the directory you created in the previous step: + +.. code-block:: bash + + cd ~/Downloads + unzip linux-*.zip -d $SOF_WORKSPACE + cd $SOF_WORKSPACE + mv linux-* linux + cd linux + +Build the kernel +**************** + +Your device should now be ready to configure and build the kernel. How to proceed depends on if you are installing locally or on dedicated test hardware. + +.. toctree:: + :maxdepth: 1 + + install_locally + setup_ktest_environment \ No newline at end of file diff --git a/getting_started/setup/setup_ktest_environment.rst b/getting_started/setup_linux/setup_ktest_environment.rst similarity index 50% rename from getting_started/setup/setup_ktest_environment.rst rename to getting_started/setup_linux/setup_ktest_environment.rst index 77bc71fd..b67e6ef7 100644 --- a/getting_started/setup/setup_ktest_environment.rst +++ b/getting_started/setup_linux/setup_ktest_environment.rst @@ -11,22 +11,20 @@ Introduction ************ These instructions explain how a target device can be configured to update the kernel over SSH. The use of ktest.pl and git worktrees -allow for simultaneous configs to be tested on multiple platforms, -though only one branch can be checked out at a time. Wired Ethernet -access is assumed as wireless is unreliable. If there is no Ethernet -port, use a USB-Ethernet dongle supported in the kernel. +allow for simultaneous configs to be tested on multiple platforms. +Wired Ethernet access is assumed as wireless is unreliable. If there +is no Ethernet port, use a USB-Ethernet dongle supported in the kernel. Prerequisites on the target device ********************************** The target device can be any of the SOF-supported platforms, -e.g. MinnowBoard, Up^2, Asus T100, Chromebooks) +e.g. MinnowBoard, Up^2, Asus T100, Chromebooks. 1. Install OS on target ----------------------- -Install ubuntu or debian (fedora is possible with a minor change -in the *initrd* generation) +Install Ubuntu, Debian, or Fedora. 2. Enable root password ----------------------- @@ -44,27 +42,59 @@ Copy your existing known-to-work kernels/initrd .. code-block:: bash - cp /boot/vmlinuz-4.13.0-16-generic /boot/vmlinuz-test - cp /boot/initrd.img-4.13.0-16-generic /boot/initrd.img-test + sudo cp /boot/vmlinuz-$(uname -r) /boot/vmlinuz-test -Change the extensions as needed to create an initial grub entry -for a test kernel. You will never override the default -Ubuntu/Debian stuff, so you will always have the ability to boot a -working kernel if your changes fail to boot. + # On Ubuntu: + sudo cp /boot/initrd.img-$(uname -r) /boot/initrd.img-test -4. Edit grub default --------------------- + # On Fedora: + sudo cp /boot/initramfs-$(uname -r).img /boot/initramfs-test.img + sudo grubby --add-kernel /boot/vmlinuz-test --title=test + +4. Edit grub settings +--------------------- + +This only needs to be run on Ubuntu and Debian, Fedora has the proper settings by default. .. code-block:: bash # Use your text editor of choice. sudo emacs /etc/default/grub + # Change GRUB_DEFAULT=[n] to GRUB_DEFAULT=saved + # Then add GRUB_DISABLE_SUBMENU=y to the end and save, + # submenus confuse ktest. sudo update-grub -Add ``GRUB_DISABLE_SUBMENU=y`` to the end and save. -Sub-menus confuse ktest. +5. Set the default kernel +------------------------- + +You will never override the default +distro kernel, so you will always have the ability to boot a +working kernel if your changes cause issues. +By setting the default kernel, you can return your system to a stable +state with just a power cycle, no grub menus involved. + +On Ubuntu: + +.. code-block:: bash + + # Print your currently booted (and known-safe) option + cat /proc/cmdline + # List the grub entries + awk '/^menuentry/ { print i++, '\t', $0 }' /boot/grub/grub.cfg + # Find the entry that matches the output of the + # first command you ran, and take note of it's number + sudo grub-set-default [n] # Where [n] is that number + # This should print saved_entry=[n] + grub-editenv list + +On Fedora: + +.. code-block:: bash + + sudo grubby --set-default /boot/vmlinuz-$(uname -r) -5. Get familiar with grub-reboot +6. Get familiar with grub-reboot -------------------------------- ktest relies on grub-reboot. grub-reboot lets you try a freshly built @@ -80,11 +110,13 @@ grub-reboot works is required to fully understand ktest configuration. It's much easier to discover grub-reboot alone than when entangled with ktest. -There's a lot of grub-reboot documentation online and offline but -apparently no good and very short cheat sheet so here is one below. For +Here's a quick cheat sheet for grub-reboot on Ubuntu/Debian. For more details search the documentation of your Linux distribution. The commands below have been tested on Ubuntu 20.04; they should be nearly -identical for most Linux distributions. +identical for most Debian-derived linux distributions. + +Warning: ``update-grub`` does not care about menuentry order and will +mess up what the numbers below point to! After running update-grub, make sure the default kernel index is correct and points towards a known-safe kernel. .. code-block:: bash @@ -95,94 +127,104 @@ identical for most Linux distributions. # See which GRUB entry was booted cat /proc/cmdline - # grub-reboot requires "unharcoding" GRUB_DEFAULT - printf 'GRUB_DEFAULT=saved\n' >> /etc/default/grub - update-grub - -Warning: ``update-grub`` does not care about menuentry order and will -mess up what the numbers below point to! - -.. code-block:: bash - - # Show the currently selected menuentry + # Show the default menuentry grub-editenv list - => saved_entry=6 + #=> saved_entry=6 # Show all, numbered kernel choices without (re)booting awk '/^menuentry/ { print i++, '\t', $0 }' /boot/grub/grub.cfg - => 5 menuentry ... - => 6 menuentry 'Ubuntu, with Linux 5.4.0-53-generic' --class ubuntu ... - => 7 menuentry ... + #=> 5 menuentry ... + #=> 6 menuentry 'Ubuntu, with Linux 5.4.0-53-generic' --class ubuntu ... + #=> 7 menuentry ... # Attempt to boot menuentry 4 only once - grub-reboot 4; grub-editenv list - => saved_entry=6 - => next_entry=4 + grub-reboot 4 + # Run this to see the updated settings + grub-editenv list + #=> saved_entry=6 + #=> next_entry=4 reboot # Switch to menuentry number 4 as the new "safe" kernel - grub-set-default 4; grub-editenv list - => saved_entry=4 + grub-set-default 4 Fedora and derived distributions have a more elaborate system to manage "installed" kernels. Instead of extracting ``menuentry`` lines from ``/boot/grub/grub.cfg`` with the ``awk`` command above, to list all -installed kernels use: ``grubby --info=ALL``. - -After copying it to ``/boot``/, "install" a new kernel with: -``grubby --add-kernel /boot/vmlinuz-softest --title=softest``. Check -``grubby``'s documentation for more details. +installed kernels use ``grubby --info=ALL``. +Check ``grubby``'s documentation for more details. +To boot a different kernel just once, use ``grub2-reboot [n]``, where ``[n]`` is the index of the menu entry you'd like to boot. 6. Install openssh-server ------------------------- .. code-block:: bash + # On Ubuntu, you need to install it sudo apt-get install openssh-server + + #On Fedora, you just need to enable it + sudo systemctl enable sshd + + # On either system, you'll need to update the config # Use your editor of choice. sudo emacs /etc/ssh/sshd_config -Replace ``PermitRootLogin without-password`` with ``PermitRootLogin yes`` -and save. +Replace ``#PermitRootLogin prohibit-password`` with ``PermitRootLogin yes`` +(make sure to remove the ``#``) and save. This is just temporary, you'll change this back once you've copied over your ssh key. -7. reboot target +7. Reboot target ---------------- +Make sure it boots automatically to your safe kernel. It's also recommended to test using grub-reboot to boot the test kernel, then rebooting again to make sure it goes back to the safe kernel. + Configure SSH without password ****************************** 1. Check SSH connection ----------------------- +You must be able to ssh into the target device, which is typically on the same local network/VPN. Run ``ip addr`` on the target to get its IP address. All other commands should be run on your dev machine, unless specified otherwise. + .. code-block:: bash - ssh root@ + # Make sure that you can connect and login to the target + ssh root@ 2. Generate an SSH key for the target ------------------------------------- +If you already have an ssh key you'd prefer to use, you can skip this step. + .. code-block:: bash - cd ~/.ssh - ssh-keygen -f sshktest - # Enter a 5+ character passphrase. + ssh-keygen -f ~/.ssh/sshktest + # This will prompt you for the target's root password. ssh-copy-id -i ~/.ssh/sshktest root@ - # This will prompt you for the root password. 3. Test the key --------------- .. code-block:: bash - ssh -i ~/.ssh/sshktest root@ - # Ubuntu unlocks the key so the -i option is not necessary. + ssh root@ + +.. note:: + + In most cases `ssh-agent` should automatically manage your password(s) and key(s). If you are still prompted for a password, it's likely your distro hasn't configured `ssh-agent`. You can either figure out how to enable it, or you can manually update your config. + To do this, put the following in ``~/.ssh/config`` (make sure to update ````) and then use ``ktest-target`` instead of the actual target's IP for ssh connections (ie ``ssh root@ktest-target``). + + .. code-block:: text + + Host ktest-target + HostName + IdentityFile ~/.ssh/sshktest 4. Disable root access ---------------------- - -Disable the root password on the target device if you -are concerned about access control. +Run this on the target device to disable root password, +you won't need it now that you've copied the key. .. code-block:: bash @@ -191,67 +233,33 @@ are concerned about access control. Replace ``PermitRootLogin yes`` by ``PermitRootLogin without-password``, save, and exit. -Create a linux development environment -************************************** - -1. Create a main working GIT tree ---------------------------------- - -.. code-block:: bash +Build and install the kernel with ktest +*************************************** - git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git linux-ref.git - cd linux-ref.git +Follow the `prepare build environment `_ instructions before proceeding. -2. Add a set of useful remotes ------------------------------- +1. Prepare ktest environment +---------------------------- -The SOF contributions can be handled by different maintainers, so it's useful to point directly -to maintainer trees. +If you're running this in a different terminal than you used for the prepare build environment page, you will need to re-set the SOF_WORKSPACE variable by running ``export SOF_WORKSPACE = ~/work/sof``. .. code-block:: bash - git remote add sof https://github.com/thesofproject/linux.git - git remote add takashi git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git - git remote add broonie git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git - git remote add vinod git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/sound.git - git fetch sof - git fetch takashi - git fetch broonie - git fetch vinod - -All of these branches will be accessible and can be updated from any -worktree. Clone once and use fetch to update the main working tree. - -3. Create a worktree for SOF in ~/ktest ---------------------------------------- - -.. note:: - Change the location of your ktest directory and which branch you use - as needed. - -.. code-block:: bash - - git worktree add ~/ktest/sof-dev sof/topic/sof-dev - -4. Set-up worktree ------------------- - -.. code-block:: bash - - cd ~/ktest/sof-dev + cd $SOF_WORKSPACE mkdir sof-dev-build mkfifo sof-dev-cat - cp sof-dev/tools/testing/ktest/ktest.pl . + cp linux/tools/testing/ktest/ktest.pl . -5. Save your kernel config as ~/ktest/sof-dev-defconfig -------------------------------------------------------- +2. Save your kernel config as sof-dev-defconfig +----------------------------------------------- If you don't know what options are needed, you can start using configurations maintained by SOF developers. .. code-block:: bash - git clone https://github.com/thesofproject/kconfig.git - cd sof-dev + cd linux + make O=../sof-dev-build olddefconfig + echo test > ../sof-dev-build/localversion bash ../kconfig/kconfig-sof-default.sh cp .config ../sof-dev-defconfig make mrproper @@ -264,16 +272,12 @@ If you don't know what options are needed, you can start using configurations ma .. note:: - SOF developers and the Intel CI also use "kconfig-sof-nocodec.sh" on Up2 and UpExtreme boards. - -.. note:: - - Distributions should not use the options provided in kconfig/sof-dev-defconfig + The options provided in kconfig/sof-dev-defconfig should not be used for a distro's production kernel. -6. Edit ktest configuration as needed +3. Edit ktest configuration as needed ------------------------------------- -Save the following in sof-dev.conf. +Save the following in ``sof-dev.conf``. Make sure to update the ``MACHINE=`` line with your target device's IP (or ``ktest-target`` if you had to do the additional ssh config). .. code-block:: perl @@ -285,7 +289,7 @@ Save the following in sof-dev.conf. SSH_USER = root THIS_DIR := ${PWD} # BUILD_DIR is the source directory - BUILD_DIR = ${THIS_DIR}/sof-dev + BUILD_DIR = ${THIS_DIR}/linux # OUTPUT_DIR is the actual build directory OUTPUT_DIR = ${THIS_DIR}/sof-dev-build BUILD_TARGET = arch/x86/boot/bzImage @@ -303,7 +307,7 @@ Save the following in sof-dev.conf. CONSOLE = cat ${THIS_DIR}/sof-dev-cat POWER_CYCLE = echo Power cycle the machine now and press ENTER; read a #set below to help ssh connection to close after sending reboot command - REBOOT = ssh -o 'ProxyCommand none' $SSH_USER@$MACHINE 'sudo reboot > /dev/null &' + REBOOT = ssh $SSH_USER@$MACHINE 'sudo reboot > /dev/null &' # This how ktest finds which menuentry number to pass to grub-reboot GRUB_FILE = /boot/grub/grub.cfg @@ -319,7 +323,7 @@ Save the following in sof-dev.conf. # mkinitramfs -o initrdfile 5.10.0-rc5test+ # ktest finds the real KERNEL_VERSION thanks to "make O=${OUTPUT_DIR} # kernelrelease" - POST_INSTALL = ssh -o 'ProxyCommand none' $SSH_USER@$MACHINE sudo /usr/sbin/mkinitramfs -o /boot/initrd.img-${LOCALVERSION} $KERNEL_VERSION + POST_INSTALL = ssh $SSH_USER@$MACHINE sudo /usr/sbin/mkinitramfs -o /boot/initrd.img-${LOCALVERSION} $KERNEL_VERSION #REBOOT_TYPE = script #REBOOT_SCRIPT = ssh $SSH_USER@$MACHINE "sed -i 's|^default.*$|default test|' /boot/loader/loader.conf" @@ -331,20 +335,24 @@ Save the following in sof-dev.conf. BUILD_NOCLEAN = 1 -For Fedora and derived distributions, make the following changes: +For targets running Fedora and derived distributions, make the following changes: .. code-block:: perl - GRUB_MENU = "title" of the kernel entry as displayed by: 'grubby --info=ALL' + # GRUB_MENU should be the title of the custom kernel entry you added, + # which will match LOCALVERSION ("test") if you followed the previous steps + # You can view all your kernel entries with `grubby --info=ALL` + GRUB_MENU = ${LOCALVERSION} GRUB_REBOOT = grub2-reboot REBOOT_TYPE = grub2bls - POST_INSTALL = ssh -o 'ProxyCommand none' $SSH_USER@$MACHINE sudo dracut --hostonly --force --kver ${LOCALVERSION} + POST_INSTALL = ssh $SSH_USER@$MACHINE sudo dracut --hostonly --force /boot/initramfs-${LOCALVERSION}.img $KERNEL_VERSION -7. Build and test +4. Build and test ----------------- .. code-block:: bash + # This can take a while, so don't kill it if it appears to freeze ./ktest.pl sof-dev.conf If this does not work, make sure you have all the following files in the @@ -352,29 +360,31 @@ local directory: * ktest.pl * sof-dev-cat -* sof-dev +* linux * sof-dev-build * sof-dev.conf * sof-dev-defconfig -Ktest will compile, install the new kernel, and reboot. Prompt -detection only works with a UART, not over SSH, so you will have to -``Control-C`` manually when the console is not enabled. +Ktest will compile and install the new kernel, then reboot the target device. Check which kernel is booted by running ``uname -r`` on the target. + +.. note:: + + KTest expects a UART connection to verify that the boot was successful. If you do not have a UART connection you will get some errors at the end of the ``ktest.pl`` script's execution, but you can ignore them as long as the custom kernel was installed and booted on the target device. -8. Enjoy! +5. Enjoy! --------- -9. Enjoy even more! +6. Enjoy even more! ------------------- -By having multiple worktrees and configs, you can run tests in parallel +By having multiple `Git worktrees `_ and configs, you can run tests in parallel on different machines on the same kernel or different branches. -10. Clean up /lib/modules +7. Clean up /lib/modules ------------------------- Ktest creates a separate module directory per kernel version. -User needs to clean up old module directory periodically. +User needs to clean up old module directory periodically on the target device. .. code-block:: bash diff --git a/getting_started/setup/images/minnow_turbot.png b/getting_started/setup_special_device/images/minnow_turbot.png similarity index 100% rename from getting_started/setup/images/minnow_turbot.png rename to getting_started/setup_special_device/images/minnow_turbot.png diff --git a/getting_started/setup/setup_minnowboard_turbot.rst b/getting_started/setup_special_device/setup_minnowboard_turbot.rst similarity index 100% rename from getting_started/setup/setup_minnowboard_turbot.rst rename to getting_started/setup_special_device/setup_minnowboard_turbot.rst diff --git a/getting_started/setup/setup_up_2_board.rst b/getting_started/setup_special_device/setup_up_2_board.rst similarity index 100% rename from getting_started/setup/setup_up_2_board.rst rename to getting_started/setup_special_device/setup_up_2_board.rst From 9f62952d63f7721fe7cfeebbe8004d7620cfb3f4 Mon Sep 17 00:00:00 2001 From: Anton Bobkov Date: Tue, 1 Mar 2022 11:09:09 +0300 Subject: [PATCH 020/150] Change formatting of the getting started docs --- .../setup_linux/install_locally.rst | 137 +++-- .../setup_linux/prepare_build_environment.rst | 115 ++-- .../setup_linux/setup_ktest_environment.rst | 538 +++++++++--------- 3 files changed, 396 insertions(+), 394 deletions(-) diff --git a/getting_started/setup_linux/install_locally.rst b/getting_started/setup_linux/install_locally.rst index f62c0594..d4b7f0b6 100644 --- a/getting_started/setup_linux/install_locally.rst +++ b/getting_started/setup_linux/install_locally.rst @@ -1,7 +1,7 @@ .. _install-locally: -Install the Kernel locally -####################################### +Install the Kernel Locally +########################## .. contents:: :local: @@ -9,101 +9,126 @@ Install the Kernel locally Introduction ************ - -Make sure you have `setup your development environment `_ before following these steps. This page will guide you through the process of installing the kernel locally on your machine. It will be installed in addition to your distro's default kernel so that you can always change back to that in case something goes wrong. If you're interested in learning more about this process there's lots of online guides available, for example `Fedora's guide `_ or `this wiki page `_. + +Make sure you have `set up your development environment `_ before following these steps. This page will guide you through the process of installing the kernel locally on your machine. It will be installed in addition to your distro's default kernel so that you can always change back to that in case something goes wrong. If you are interested in learning more about this process, there are lots of online guides available, for example `Fedora* Quick Docs `_ or `this wiki page `_. Build and install the kernel **************************** -(You should be in the ``~/sof/linux`` directory you created on the setup page) +1. Change directory to ``~/sof/linux`` that you created on the setup page. -1. Load base kernel configuration ---------------------------------- +#. Load the base kernel configuration. -.. code-block:: bash + The following command copies the configuration of the booted kernel so that it will be used as a base: + + .. code-block:: bash - # This will copy the booted kernel's configuration so that it will be used as a base - cp /boot/config-$(uname -r)* .config + cp /boot/config-$(uname -r)* .config -2. Apply SOF-specific configuration ------------------------------------ +#. Apply the SOF-specific configuration. -The following scripts will update your base config so that it uses the latest SOF modules. Run only one of them depending on your needs. If it prompts you with any questions, just press to accept the default value. Note that, by default, these scripts will set the configuration to only compile modules that are currently loaded in order to lower compile times. This means that when you've booted from the custom kernel some external devices may not work if they weren't connected while running this script. If you want to compile all modules, delete the line ``make localmodconfig`` from the script you will run in this step. -.. code-block:: bash + The following scripts update your base configuration so that it uses the latest SOF modules. Run only one of them depending on your needs. If it prompts you with any questions, just press **Enter** to accept the default value. Note that, by default, these scripts will set the configuration to only compile modules that are currently loaded in order to lower compile times. This means that when you've booted from the custom kernel, some external devices may not work if they were not connected while running this script. If you want to compile all modules, delete the line ``make localmodconfig`` from the script you will run in this step. - # For most users - ../kconfig/kconfig-distro-sof-update.sh - # For additional logging and experimental device support - ../kconfig/kconfig-distro-sof-dev-update.sh + - For most users: -3. Compile the kernel ---------------------- + .. code-block:: bash -.. code-block:: bash + ../kconfig/kconfig-distro-sof-update.sh - # The first time you run this it can take a while (over 30 minutes on some machines), - # so grab a coffee or take an exercise break while it runs - make -j$(nproc --all) -4. Install the kernel ---------------------- + - For additional logging and experimental device support: -.. code-block:: bash + .. code-block:: bash + + ../kconfig/kconfig-distro-sof-dev-update.sh - sudo make modules_install - sudo make install + .. _compile-kernel-step: -If all went well, your freshly-built kernel will be installed and available at next boot. Restart your computer, and you should have the option to pick a kernel when it turns on. Select the kernel that has "-sof" at the end of it, and your computer should boot as normal using the kernel you just built. On Ubuntu, the kernel option may be hidden behind the "Advanced options for Ubuntu" submenu. +#. Compile the kernel. -5. Updating and rebuilding --------------------------- + The first time you run this command, it can take a while (over 30 minutes on some machines), so grab a coffee or take an exercise break while it runs. -If you need to try some new changes, you'll have to download the updated code and rebuild the kernel. + .. code-block:: bash -If you originally cloned the repo using git, you just need to pull the changes: + make -j$(nproc --all) -.. code-block:: bash + .. _install-kernel-step: - git pull - # You should run this after switching branches or configuration or any other major code change - # If you just pulled some minor updates, it's likely unnecessary and will increase your build time - make clean +#. Install the kernel. -Now, repeat steps 3 and 4 to rebuild and reinstall the kernel. Reboot your computer, and select the kernel with -sof at the end to test it. + .. code-block:: bash + + sudo make modules_install + sudo make install + +If all went well, your freshly-built kernel will be installed and available at next boot. Restart your computer, and you should have the option to pick a kernel when it turns on. Select the kernel which name has ``-sof`` at the end of it, and your computer should boot as normal using the kernel you just built. On Ubuntu*, the kernel option may be hidden behind the **Advanced options for Ubuntu** submenu. + +Update and rebuild +****************** + +If you need to try some new changes, download the updated code and rebuild the kernel. + +Update the kernel cloned with git +--------------------------------- + +If you originally cloned the repo using git, perform the following steps to update and rebuild the kernel: + +1. Pull the changes. -Unfortunately, if you downloaded via zip, the entire process has to be restarted from the "Get the kernel source" section; there's no good way to incrementally update. However, the kernel build should be faster now as part of it will be cached. + .. code-block:: bash + + git pull + +#. Clean the directory. + + .. note:: You should clean up after switching branches or configuration or any other major code change. If you just pulled some minor updates, it's likely unnecessary and will increase your build time. + + .. code:: bash + + make clean + +#. Repeat :ref:`steps 4` :ref:`and 5` to rebuild and reinstall the kernel. + +#. Reboot your computer, and select the kernel with ``-sof`` at the end of its name to test it. + +Update the kernel downloaded via zip +------------------------------------ + +Unfortunately, if you downloaded via zip, the entire process has to be restarted from the :ref:`Get the kernel source` step. There is no good way to incrementally update. However, the kernel build should be faster now as part of it will be cached. + +Make sure you delete the old folder before starting over: .. code-block:: bash cd .. - # Delete the old folder before starting over rm -rf linux -6. Removing the kernel ----------------------- + +Remove the kernel +***************** If you run into issues or no longer need the custom kernel, you can remove it. -Ubuntu: +- Ubuntu: -.. code-block:: bash + .. code-block:: bash - cd ~/sof/linux - sudo rm /boot/*-$(make kernelversion) - sudo rm -rf /lib/modules/$(make kernelversion) - sudo update-grub + cd ~/sof/linux + sudo rm /boot/*-$(make kernelversion) + sudo rm -rf /lib/modules/$(make kernelversion) + sudo update-grub -Fedora: +- Fedora: -.. code-block:: bash + .. code-block:: bash - cd ~/sof/linux - sudo rm /boot/*-$(make kernelversion)* - sudo rm -rf /lib/modules/$(make kernelversion) - sudo grubby --remove-kernel=/boot/vmlinuz-$(make kernelversion) + cd ~/sof/linux + sudo rm /boot/*-$(make kernelversion)* + sudo rm -rf /lib/modules/$(make kernelversion) + sudo grubby --remove-kernel=/boot/vmlinuz-$(make kernelversion) After rebooting, you should be back to your old kernel with all traces of the custom kernel installation gone. If you'd like, you can also delete the ``~sof`` directory to save disk space. diff --git a/getting_started/setup_linux/prepare_build_environment.rst b/getting_started/setup_linux/prepare_build_environment.rst index 30382aa7..d86cb6aa 100644 --- a/getting_started/setup_linux/prepare_build_environment.rst +++ b/getting_started/setup_linux/prepare_build_environment.rst @@ -1,102 +1,79 @@ .. _prepare-build-environment: -Set up a development environment to build the kernel +Set up a Development Environment to Build the Kernel #################################################### -.. contents:: - :local: - :depth: 3 +These instructions will help you set up a development environment for the SOF branch of the Linux kernel. If you have dedicated test hardware, you can use ktest to install it over ssh. Otherwise, you can install it locally on your device in addition to your default kernel. -Introduction -************ +Review the following prerequisites: +- **Development device:** PC running Fedora* 35+ or Ubuntu* 20.04+. -These instructions will help you set up a development environment for the SOF branch of the Linux kernel. If you have dedicated test hardware you can use ktest to install it over ssh, otherwise you can install it locally on your device in addition to your default kernel. +- **Target device:** PC running Fedora 35+ or Ubuntu 20.04+, with secure boot disabled. If the target device is different than the development device, you must be able to ssh into the target, which is typically on the same local network/VPN. -Prerequisites -************* +1. Create a working directory. -1. Device requirements ------------------------ + This directory can be located anywhere. Simply change the ``SOF_WORKSPACE`` variable if you would like to store your sources somewhere else. -**Development device:** PC running Fedora 35+ or Ubuntu 20.04+. + .. code-block:: bash -**Target device:** PC running Fedora 35+ or Ubuntu 20.04+, with secure boot disabled. If the target device is different than the development device you must be able to ssh into the target, which is typically on the same local network/VPN. + export SOF_WORKSPACE=~/work/sof + mkdir -p $SOF_WORKSPACE + cd $SOF_WORKSPACE -2. Create working directory ---------------------------- +#. Install kernel build dependencies. -This directory can be located anywhere, simply change the ``SOF_WORKSPACE`` variable if you would like to store your sources somewhere else. + - Fedora (see `their guide `_ for details): -.. code-block:: bash + .. code-block:: bash - export SOF_WORKSPACE=~/work/sof - mkdir -p $SOF_WORKSPACE - cd $SOF_WORKSPACE + sudo dnf install fedpkg + fedpkg clone -a kernel + cd kernel + sudo dnf builddep kernel.spec + sudo dnf install ccache + cd .. -3. Install kernel build dependencies ------------------------------------- + - Ubuntu (see `their page `_ for details): -Fedora (see `their guide `_ for details): + .. code-block:: bash -.. code-block:: bash + sudo apt update + sudo apt install git libncurses-dev gawk flex bison openssl libssl-dev dkms libelf-dev libudev-dev libpci-dev libiberty-dev autoconf dwarves zstd - sudo dnf install fedpkg - fedpkg clone -a kernel - cd kernel - sudo dnf builddep kernel.spec - sudo dnf install ccache - cd .. +#. Download the configuration scripts. -Ubuntu (see `their page `_ for details): + .. code-block:: bash -.. code-block:: bash + git clone https://github.com/thesofproject/kconfig.git - sudo apt update - sudo apt install git libncurses-dev gawk flex bison openssl libssl-dev dkms libelf-dev libudev-dev libpci-dev libiberty-dev autoconf dwarves zstd + .. _get-kernel-source: + +#. Get the kernel source. -4. Download the configuration scripts -------------------------------------- + There are two ways to get the kernel source. We strongly recommend using git as it makes updates **much** easier, but the zip download may be more successful if you have an unstable connection. -.. code-block:: bash + - Option 1: Clone with git. - git clone https://github.com/thesofproject/kconfig.git + .. code-block:: bash -Get the kernel source -********************* + git clone https://github.com/thesofproject/linux.git --depth=1 + cd linux -There are two ways to get the kernel source. We strongly recommend using git as it makes updates **much** easier, but the zip download may be more successful if you have an unstable connection. + .. note:: -Option 1: Clone with git ------------------------- -.. code-block:: bash + If a maintainer requests that you check out a different branch to test a bug fix, add ``-b [branch]`` to the end of this command, where `[branch]` is the branch name. - # If a maintainer requests that you check out a different branch - # to test a bug fix, add -b [branch] - # to the end of this command, where [branch] is the branch name - git clone https://github.com/thesofproject/linux.git --depth=1 - cd linux + - Option 2: Download via zip. -Option 2: Download via zip --------------------------- + Visit the SOF Linux fork at https://github.com/thesofproject/linux. If a maintainer asks you to test a specific branch, click the dropdown with the text "topic/sof-dev" and select the branch they asked you to test. Then, click the green **Code** dropdown and select **Download ZIP**. Once it is downloaded, extract it to the directory you created in the previous step: -Visit the SOF Linux fork at https://github.com/thesofproject/linux. If a maintainer asks you to test a specific branch, click the dropdown with the text "topic/sof-dev" and select the branch they asked you to test. Then, click the green "Code" dropdown and select "download zip". Once it's downloaded, extract it to the directory you created in the previous step: + .. code-block:: bash -.. code-block:: bash + cd ~/Downloads + unzip linux-*.zip -d $SOF_WORKSPACE + cd $SOF_WORKSPACE + mv linux-* linux + cd linux - cd ~/Downloads - unzip linux-*.zip -d $SOF_WORKSPACE - cd $SOF_WORKSPACE - mv linux-* linux - cd linux - -Build the kernel -**************** - -Your device should now be ready to configure and build the kernel. How to proceed depends on if you are installing locally or on dedicated test hardware. - -.. toctree:: - :maxdepth: 1 - - install_locally - setup_ktest_environment \ No newline at end of file +Your device should now be ready to configure and build the kernel. How to proceed depends on if you are installing :ref:`locally` or on :ref:`dedicated test hardware`. diff --git a/getting_started/setup_linux/setup_ktest_environment.rst b/getting_started/setup_linux/setup_ktest_environment.rst index b67e6ef7..37dddda3 100644 --- a/getting_started/setup_linux/setup_ktest_environment.rst +++ b/getting_started/setup_linux/setup_ktest_environment.rst @@ -1,6 +1,6 @@ .. _setup-ktest-environment: -Set up a Ktest-based environment +Set up a Ktest-based Environment ################################ .. contents:: @@ -9,389 +9,389 @@ Set up a Ktest-based environment Introduction ************ + These instructions explain how a target device can be configured to update the kernel over SSH. The use of ktest.pl and git worktrees allow for simultaneous configs to be tested on multiple platforms. Wired Ethernet access is assumed as wireless is unreliable. If there is no Ethernet port, use a USB-Ethernet dongle supported in the kernel. -Prerequisites on the target device -********************************** - The target device can be any of the SOF-supported platforms, -e.g. MinnowBoard, Up^2, Asus T100, Chromebooks. +such as MinnowBoard, Up^2, Asus T100, Chromebooks. + +Set up a target +*************** + +1. Install Ubuntu*, Debian*, or Fedora* on the target. + +#. Enable root password. + + .. code-block:: bash + + sudo su (enter your password) + passwd (enter new root password) + exit + +#. Create a test kernel. + + Copy your existing known-to-work kernels/initrd. -1. Install OS on target ------------------------ + .. code-block:: bash -Install Ubuntu, Debian, or Fedora. + sudo cp /boot/vmlinuz-$(uname -r) /boot/vmlinuz-test -2. Enable root password ------------------------ + # On Ubuntu: + sudo cp /boot/initrd.img-$(uname -r) /boot/initrd.img-test -.. code-block:: bash + # On Fedora: + sudo cp /boot/initramfs-$(uname -r).img /boot/initramfs-test.img + sudo grubby --add-kernel /boot/vmlinuz-test --title=test - sudo su (enter your password) - passwd (enter new root password) - exit +#. Edit grub settings. -3. Create test kernel ---------------------- + Perform these steps only on Ubuntu and Debian. Fedora has the proper settings by default. -Copy your existing known-to-work kernels/initrd + a) Open the grub configuration file in your editor of choice as a super user: -.. code-block:: bash + .. code-block:: bash - sudo cp /boot/vmlinuz-$(uname -r) /boot/vmlinuz-test + sudo emacs /etc/default/grub - # On Ubuntu: - sudo cp /boot/initrd.img-$(uname -r) /boot/initrd.img-test + b) Change ``GRUB_DEFAULT=[n]`` to ``GRUB_DEFAULT=saved``. + + c) Add ``GRUB_DISABLE_SUBMENU=y`` to the end of the file and save it. - # On Fedora: - sudo cp /boot/initramfs-$(uname -r).img /boot/initramfs-test.img - sudo grubby --add-kernel /boot/vmlinuz-test --title=test + This step is necessary because submenus confuse ktest. -4. Edit grub settings ---------------------- + d) Update the grub configuration. -This only needs to be run on Ubuntu and Debian, Fedora has the proper settings by default. + .. code-block:: + + sudo update-grub -.. code-block:: bash +#. Set the default kernel. - # Use your text editor of choice. - sudo emacs /etc/default/grub - # Change GRUB_DEFAULT=[n] to GRUB_DEFAULT=saved - # Then add GRUB_DISABLE_SUBMENU=y to the end and save, - # submenus confuse ktest. - sudo update-grub + You will never override the default + distro kernel, so you will always have the ability to boot a + working kernel if your changes cause issues. + By setting the default kernel, you can return your system to a stable + state with just a power cycle, no grub menus involved. -5. Set the default kernel -------------------------- + - On Ubuntu: -You will never override the default -distro kernel, so you will always have the ability to boot a -working kernel if your changes cause issues. -By setting the default kernel, you can return your system to a stable -state with just a power cycle, no grub menus involved. + .. code-block:: bash -On Ubuntu: + # Print your currently booted (and known-safe) option + cat /proc/cmdline + # List the grub entries + awk '/^menuentry/ { print i++, '\t', $0 }' /boot/grub/grub.cfg + # Find the entry that matches the output of the + # first command you ran, and take note of its number + sudo grub-set-default [n] # Where [n] is that number + # This should print saved_entry=[n] + grub-editenv list -.. code-block:: bash + - On Fedora: - # Print your currently booted (and known-safe) option - cat /proc/cmdline - # List the grub entries - awk '/^menuentry/ { print i++, '\t', $0 }' /boot/grub/grub.cfg - # Find the entry that matches the output of the - # first command you ran, and take note of it's number - sudo grub-set-default [n] # Where [n] is that number - # This should print saved_entry=[n] - grub-editenv list + .. code-block:: bash -On Fedora: + sudo grubby --set-default /boot/vmlinuz-$(uname -r) -.. code-block:: bash +6. Get familiar with grub-reboot. - sudo grubby --set-default /boot/vmlinuz-$(uname -r) + ktest relies on grub-reboot. grub-reboot lets you try a freshly built + kernel *only once* and then boot immediately a "safe" kernel again + without interacting with the boot menu: a simple power cycle is + enough. It's a must have for testing development kernels that may not + fully boot. -6. Get familiar with grub-reboot --------------------------------- + In case something goes wrong with ktest, being familiar with grub-reboot + may save you interacting with the boot menu or even better: it may save + you making your system unbootable by accident. Understanding how + grub-reboot works is required to fully understand ktest + configuration. It's much easier to discover grub-reboot alone than when + entangled with ktest. -ktest relies on grub-reboot. grub-reboot lets you try a freshly built -kernel *only once* and then boot immediately a "safe" kernel again -without interacting with the boot menu: a simple power cycle is -enough. It's a must have for testing development kernels that may not -fully boot. + Here is a quick cheat sheet for grub-reboot on Ubuntu/Debian. For + more details, search the documentation of your Linux distribution. The + commands below have been tested on Ubuntu 20.04. They should be nearly + identical for most Debian-derived Linux distributions. -In case something goes wrong with ktest, being familiar with grub-reboot -may save you interacting with the boot menu or even better: it may save -you making your system unbootable by accident. Understanding how -grub-reboot works is required to fully understand ktest -configuration. It's much easier to discover grub-reboot alone than when -entangled with ktest. + .. warning:: -Here's a quick cheat sheet for grub-reboot on Ubuntu/Debian. For -more details search the documentation of your Linux distribution. The -commands below have been tested on Ubuntu 20.04; they should be nearly -identical for most Debian-derived linux distributions. + ``update-grub`` does not care about menuentry order and will mess up what the numbers below point to! After running update-grub, make sure the default kernel index is correct and points towards a known-safe kernel. -Warning: ``update-grub`` does not care about menuentry order and will -mess up what the numbers below point to! After running update-grub, make sure the default kernel index is correct and points towards a known-safe kernel. + .. code-block:: bash -.. code-block:: bash + # Add/remove entries in grub.cfg after making changes in /boot/ + # grub.cfg is generated, don't edit it! + update-grub - # Add/remove entries in grub.cfg after making changes in /boot/ - # grub.cfg is generated, don't edit it! - update-grub + # See which GRUB entry was booted + cat /proc/cmdline - # See which GRUB entry was booted - cat /proc/cmdline + # Show the default menuentry + grub-editenv list + #=> saved_entry=6 - # Show the default menuentry - grub-editenv list - #=> saved_entry=6 + # Show all, numbered kernel choices without (re)booting + awk '/^menuentry/ { print i++, '\t', $0 }' /boot/grub/grub.cfg + #=> 5 menuentry ... + #=> 6 menuentry 'Ubuntu, with Linux 5.4.0-53-generic' --class ubuntu ... + #=> 7 menuentry ... - # Show all, numbered kernel choices without (re)booting - awk '/^menuentry/ { print i++, '\t', $0 }' /boot/grub/grub.cfg - #=> 5 menuentry ... - #=> 6 menuentry 'Ubuntu, with Linux 5.4.0-53-generic' --class ubuntu ... - #=> 7 menuentry ... + # Attempt to boot menuentry 4 only once + grub-reboot 4 + # Run this to see the updated settings + grub-editenv list + #=> saved_entry=6 + #=> next_entry=4 + reboot - # Attempt to boot menuentry 4 only once - grub-reboot 4 - # Run this to see the updated settings - grub-editenv list - #=> saved_entry=6 - #=> next_entry=4 - reboot + # Switch to menuentry number 4 as the new "safe" kernel + grub-set-default 4 - # Switch to menuentry number 4 as the new "safe" kernel - grub-set-default 4 + Fedora and derived distributions have a more elaborate system to manage + "installed" kernels. Instead of extracting ``menuentry`` lines from + ``/boot/grub/grub.cfg`` with the ``awk`` command above, to list all + installed kernels use ``grubby --info=ALL``. + Check ``grubby`` documentation for more details. + To boot a different kernel just once, use ``grub2-reboot [n]``, where ``[n]`` is the index of the menu entry you'd like to boot. -Fedora and derived distributions have a more elaborate system to manage -"installed" kernels. Instead of extracting ``menuentry`` lines from -``/boot/grub/grub.cfg`` with the ``awk`` command above, to list all -installed kernels use ``grubby --info=ALL``. -Check ``grubby``'s documentation for more details. -To boot a different kernel just once, use ``grub2-reboot [n]``, where ``[n]`` is the index of the menu entry you'd like to boot. +#. Install and configure openssh-server. -6. Install openssh-server -------------------------- + a) Install or enable openssh-server: -.. code-block:: bash + - On Ubuntu, install the server: - # On Ubuntu, you need to install it - sudo apt-get install openssh-server + .. code-block:: bash - #On Fedora, you just need to enable it - sudo systemctl enable sshd + sudo apt-get install openssh-server - # On either system, you'll need to update the config - # Use your editor of choice. - sudo emacs /etc/ssh/sshd_config + - On Fedora, enable the server: -Replace ``#PermitRootLogin prohibit-password`` with ``PermitRootLogin yes`` -(make sure to remove the ``#``) and save. This is just temporary, you'll change this back once you've copied over your ssh key. + .. code-block:: bash + + sudo systemctl enable sshd -7. Reboot target ----------------- + b) Update the openssh-server configuration using your editor of choice. -Make sure it boots automatically to your safe kernel. It's also recommended to test using grub-reboot to boot the test kernel, then rebooting again to make sure it goes back to the safe kernel. + .. code-block:: bash + + sudo emacs /etc/ssh/sshd_config + + Replace ``#PermitRootLogin prohibit-password`` with ``PermitRootLogin yes`` and save the file. Make sure to remove the hash character (#). + + This is just temporary, you will change this back once you have copied over your ssh key. + +#. Reboot the target. + + Make sure it boots automatically to your safe kernel. We also recommend to test using grub-reboot to boot the test kernel, then rebooting again to make sure it goes back to the safe kernel. Configure SSH without password ****************************** -1. Check SSH connection ------------------------ +1. Check the SSH connection. -You must be able to ssh into the target device, which is typically on the same local network/VPN. Run ``ip addr`` on the target to get its IP address. All other commands should be run on your dev machine, unless specified otherwise. + You must be able to ssh into the target device, which is typically on the same local network/VPN. Run ``ip addr`` on the target to get its IP address. All other commands should be run on your dev machine, unless specified otherwise. -.. code-block:: bash + .. code-block:: bash - # Make sure that you can connect and login to the target - ssh root@ + # Make sure that you can connect and login to the target + ssh root@ -2. Generate an SSH key for the target -------------------------------------- +#. Generate an SSH key for the target. -If you already have an ssh key you'd prefer to use, you can skip this step. + If you already have an ssh key you'd prefer to use, you can skip this step. -.. code-block:: bash + .. code-block:: bash - ssh-keygen -f ~/.ssh/sshktest - # This will prompt you for the target's root password. - ssh-copy-id -i ~/.ssh/sshktest root@ + ssh-keygen -f ~/.ssh/sshktest + # This will prompt you for the target's root password. + ssh-copy-id -i ~/.ssh/sshktest root@ -3. Test the key ---------------- +#. Test the key. -.. code-block:: bash + .. code-block:: bash - ssh root@ + ssh root@ -.. note:: + .. note:: - In most cases `ssh-agent` should automatically manage your password(s) and key(s). If you are still prompted for a password, it's likely your distro hasn't configured `ssh-agent`. You can either figure out how to enable it, or you can manually update your config. - To do this, put the following in ``~/.ssh/config`` (make sure to update ````) and then use ``ktest-target`` instead of the actual target's IP for ssh connections (ie ``ssh root@ktest-target``). + In most cases `ssh-agent` should automatically manage your password(s) and key(s). If you are still prompted for a password, it's likely your distro hasn't configured `ssh-agent`. You can either figure out how to enable it, or you can manually update your config. + To do this, put the following in ``~/.ssh/config`` (make sure to update ````) and then use ``ktest-target`` instead of the actual target's IP for ssh connections (for example, ``ssh root@ktest-target``). - .. code-block:: text + .. code-block:: text - Host ktest-target - HostName - IdentityFile ~/.ssh/sshktest + Host ktest-target + HostName + IdentityFile ~/.ssh/sshktest -4. Disable root access ----------------------- -Run this on the target device to disable root password, -you won't need it now that you've copied the key. +#. Disable root access. -.. code-block:: bash + Run this on the target device to disable root password, + you do not need it now that you have copied the key. - # Use your editor of choice. - sudo emacs /etc/ssh/sshd_config + .. code-block:: bash -Replace ``PermitRootLogin yes`` by ``PermitRootLogin without-password``, save, and exit. + # Use your editor of choice. + sudo emacs /etc/ssh/sshd_config + + Replace ``PermitRootLogin yes`` by ``PermitRootLogin without-password``, save, and exit. Build and install the kernel with ktest *************************************** Follow the `prepare build environment `_ instructions before proceeding. -1. Prepare ktest environment ----------------------------- +1. Prepare the ktest environment. + + If you run this in a different terminal than you used for the `prepare build environment `_ instructions, you need to re-set the SOF_WORKSPACE variable by running ``export SOF_WORKSPACE = ~/work/sof``. + + .. code-block:: bash + + cd $SOF_WORKSPACE + mkdir sof-dev-build + mkfifo sof-dev-cat + cp linux/tools/testing/ktest/ktest.pl . -If you're running this in a different terminal than you used for the prepare build environment page, you will need to re-set the SOF_WORKSPACE variable by running ``export SOF_WORKSPACE = ~/work/sof``. +#. Save your kernel configuration as ``sof-dev-defconfig``. -.. code-block:: bash + If you do not know what options are needed, you can start using configurations maintained by SOF developers. - cd $SOF_WORKSPACE - mkdir sof-dev-build - mkfifo sof-dev-cat - cp linux/tools/testing/ktest/ktest.pl . + .. code-block:: bash -2. Save your kernel config as sof-dev-defconfig ------------------------------------------------ + cd linux + make O=../sof-dev-build olddefconfig + echo test > ../sof-dev-build/localversion + bash ../kconfig/kconfig-sof-default.sh + cp .config ../sof-dev-defconfig + make mrproper + cd .. -If you don't know what options are needed, you can start using configurations maintained by SOF developers. + .. note:: -.. code-block:: bash + Use make proper since ktest.pl requires the source directory + to be clean. All compilation happens in the -build directory. - cd linux - make O=../sof-dev-build olddefconfig - echo test > ../sof-dev-build/localversion - bash ../kconfig/kconfig-sof-default.sh - cp .config ../sof-dev-defconfig - make mrproper - cd .. + .. note:: -.. note:: + The options provided in kconfig/sof-dev-defconfig should not be used for a distro's production kernel. - Use make proper since ktest.pl requires the source directory - to be clean. All compilation happens in the -build directory. +#. Edit ktest configuration as needed. -.. note:: + Save the following in ``sof-dev.conf``. Make sure to update the ``MACHINE=`` line with your target device's IP (or ``ktest-target`` if you had to do the additional ssh config). - The options provided in kconfig/sof-dev-defconfig should not be used for a distro's production kernel. + .. code-block:: perl -3. Edit ktest configuration as needed -------------------------------------- + # The difference between config variables (:=) and ktest options (=) and a + # few other things are explained in tools/testing/ktest/examples/sample.conf -Save the following in ``sof-dev.conf``. Make sure to update the ``MACHINE=`` line with your target device's IP (or ``ktest-target`` if you had to do the additional ssh config). + MACHINE = 192.168.1.205 + CLEAR_LOG = 1 + SSH_USER = root + THIS_DIR := ${PWD} + # BUILD_DIR is the source directory + BUILD_DIR = ${THIS_DIR}/linux + # OUTPUT_DIR is the actual build directory + OUTPUT_DIR = ${THIS_DIR}/sof-dev-build + BUILD_TARGET = arch/x86/boot/bzImage -.. code-block:: perl + # ktest requires LOCALVERSION. This is normally a '-something' suffix like + # in 'vmlinuz-5.10-rc5-something'. Let's (ab)use it as the full version so + # we have a constant 'vmlinuz-something' filename and we don't have to + # make changes in /boot/ all the time. + # update-grub will complain but work anyway. + LOCALVERSION = test + TARGET_IMAGE = /boot/vmlinuz-${LOCALVERSION} - # The difference between config variables (:=) and ktest options (=) and a - # few other things are explained in tools/testing/ktest/examples/sample.conf + BUILD_OPTIONS = -j8 + LOG_FILE = ${OUTPUT_DIR}/sof-dev.log + CONSOLE = cat ${THIS_DIR}/sof-dev-cat + POWER_CYCLE = echo Power cycle the machine now and press ENTER; read a + #set below to help ssh connection to close after sending reboot command + REBOOT = ssh $SSH_USER@$MACHINE 'sudo reboot > /dev/null &' - MACHINE = 192.168.1.205 - CLEAR_LOG = 1 - SSH_USER = root - THIS_DIR := ${PWD} - # BUILD_DIR is the source directory - BUILD_DIR = ${THIS_DIR}/linux - # OUTPUT_DIR is the actual build directory - OUTPUT_DIR = ${THIS_DIR}/sof-dev-build - BUILD_TARGET = arch/x86/boot/bzImage + # This how ktest finds which menuentry number to pass to grub-reboot + GRUB_FILE = /boot/grub/grub.cfg + GRUB_MENU = Ubuntu, with Linux ${LOCALVERSION} + #GRUB_MENU = ubilinux GNU/Linux, with Linux ${LOCALVERSION} + #GRUB_MENU = GalliumOS GNU/Linux, with Linux ${LOCALVERSION} + GRUB_REBOOT = grub-reboot + REBOOT_TYPE = grub2 - # ktest requires LOCALVERSION. This is normally a '-something' suffix like - # in 'vmlinuz-5.10-rc5-something'. Let's (ab)use it as the full version so - # we have a constant 'vmlinuz-something' filename and we don't have to - # make changes in /boot/ all the time. - # update-grub will complain but work anyway. - LOCALVERSION = test - TARGET_IMAGE = /boot/vmlinuz-${LOCALVERSION} + # update-initramfs does not support any "version-less" 'vmlinuz-test' because it + # does not tell where to find modules like '/lib/modules/5.10.0-rc5test+' + # So we have to use a lower level, more explicit command like: + # mkinitramfs -o initrdfile 5.10.0-rc5test+ + # ktest finds the real KERNEL_VERSION thanks to "make O=${OUTPUT_DIR} + # kernelrelease" + POST_INSTALL = ssh $SSH_USER@$MACHINE sudo /usr/sbin/mkinitramfs -o /boot/initrd.img-${LOCALVERSION} $KERNEL_VERSION - BUILD_OPTIONS = -j8 - LOG_FILE = ${OUTPUT_DIR}/sof-dev.log - CONSOLE = cat ${THIS_DIR}/sof-dev-cat - POWER_CYCLE = echo Power cycle the machine now and press ENTER; read a - #set below to help ssh connection to close after sending reboot command - REBOOT = ssh $SSH_USER@$MACHINE 'sudo reboot > /dev/null &' + #REBOOT_TYPE = script + #REBOOT_SCRIPT = ssh $SSH_USER@$MACHINE "sed -i 's|^default.*$|default test|' /boot/loader/loader.conf" - # This how ktest finds which menuentry number to pass to grub-reboot - GRUB_FILE = /boot/grub/grub.cfg - GRUB_MENU = Ubuntu, with Linux ${LOCALVERSION} - #GRUB_MENU = ubilinux GNU/Linux, with Linux ${LOCALVERSION} - #GRUB_MENU = GalliumOS GNU/Linux, with Linux ${LOCALVERSION} - GRUB_REBOOT = grub-reboot - REBOOT_TYPE = grub2 + TEST_START + # TEST_TYPE can be: build, install, boot, ... + TEST_TYPE = boot + BUILD_TYPE = useconfig:${THIS_DIR}/sof-dev-defconfig + BUILD_NOCLEAN = 1 - # update-initramfs does not support any "version-less" 'vmlinuz-test' because it - # does not tell where to find modules like '/lib/modules/5.10.0-rc5test+' - # So we have to use a lower level, more explicit command like: - # mkinitramfs -o initrdfile 5.10.0-rc5test+ - # ktest finds the real KERNEL_VERSION thanks to "make O=${OUTPUT_DIR} - # kernelrelease" - POST_INSTALL = ssh $SSH_USER@$MACHINE sudo /usr/sbin/mkinitramfs -o /boot/initrd.img-${LOCALVERSION} $KERNEL_VERSION - #REBOOT_TYPE = script - #REBOOT_SCRIPT = ssh $SSH_USER@$MACHINE "sed -i 's|^default.*$|default test|' /boot/loader/loader.conf" + For targets running Fedora and derived distributions, make the following changes: - TEST_START - # TEST_TYPE can be: build, install, boot, ... - TEST_TYPE = boot - BUILD_TYPE = useconfig:${THIS_DIR}/sof-dev-defconfig - BUILD_NOCLEAN = 1 + .. code-block:: perl + # GRUB_MENU should be the title of the custom kernel entry you added, + # which will match LOCALVERSION ("test") if you followed the previous steps + # You can view all your kernel entries with `grubby --info=ALL` + GRUB_MENU = ${LOCALVERSION} + GRUB_REBOOT = grub2-reboot + REBOOT_TYPE = grub2bls + POST_INSTALL = ssh $SSH_USER@$MACHINE sudo dracut --hostonly --force /boot/initramfs-${LOCALVERSION}.img $KERNEL_VERSION -For targets running Fedora and derived distributions, make the following changes: +#. Build and test. -.. code-block:: perl + .. code-block:: bash - # GRUB_MENU should be the title of the custom kernel entry you added, - # which will match LOCALVERSION ("test") if you followed the previous steps - # You can view all your kernel entries with `grubby --info=ALL` - GRUB_MENU = ${LOCALVERSION} - GRUB_REBOOT = grub2-reboot - REBOOT_TYPE = grub2bls - POST_INSTALL = ssh $SSH_USER@$MACHINE sudo dracut --hostonly --force /boot/initramfs-${LOCALVERSION}.img $KERNEL_VERSION + # This can take a while, so don't kill it if it appears to freeze + ./ktest.pl sof-dev.conf -4. Build and test ------------------ + If this does not work, make sure you have all the following files in the + local directory: -.. code-block:: bash + * ktest.pl + * sof-dev-cat + * linux + * sof-dev-build + * sof-dev.conf + * sof-dev-defconfig - # This can take a while, so don't kill it if it appears to freeze - ./ktest.pl sof-dev.conf + Ktest will compile and install the new kernel, then reboot the target device. Check which kernel is booted by running ``uname -r`` on the target. -If this does not work, make sure you have all the following files in the -local directory: + .. note:: -* ktest.pl -* sof-dev-cat -* linux -* sof-dev-build -* sof-dev.conf -* sof-dev-defconfig + KTest expects a UART connection to verify that the boot was successful. If you do not have a UART connection you will get some errors at the end of the ``ktest.pl`` script's execution, but you can ignore them as long as the custom kernel was installed and booted on the target device. -Ktest will compile and install the new kernel, then reboot the target device. Check which kernel is booted by running ``uname -r`` on the target. +#. Enjoy! -.. note:: +#. Enjoy even more! - KTest expects a UART connection to verify that the boot was successful. If you do not have a UART connection you will get some errors at the end of the ``ktest.pl`` script's execution, but you can ignore them as long as the custom kernel was installed and booted on the target device. + By having multiple `Git worktrees `_ and configs, you can run tests in parallel + on different machines on the same kernel or different branches. -5. Enjoy! ---------- +#. Clean up `/lib/modules`. -6. Enjoy even more! -------------------- + Ktest creates a separate module directory per kernel version. + User needs to clean up old module directory periodically on the target device. + + .. code-block:: bash -By having multiple `Git worktrees `_ and configs, you can run tests in parallel -on different machines on the same kernel or different branches. - -7. Clean up /lib/modules -------------------------- - -Ktest creates a separate module directory per kernel version. -User needs to clean up old module directory periodically on the target device. - -.. code-block:: bash - - $ ls -al /lib/modules - drwxrwxr-x 3 ubuntu ubuntu 4096 Sep 28 15:07 5.9.0-rc4-test+ - drwxrwxr-x 3 ubuntu ubuntu 4096 Sep 24 11:06 5.9.0-rc5-test+ - drwxrwxr-x 3 ubuntu ubuntu 4096 Oct 5 16:39 5.9.0-rc6-test+ - drwxrwxr-x 3 ubuntu ubuntu 4096 Oct 14 21:42 5.9.0-rc7-test+ - drwxrwxr-x 3 ubuntu ubuntu 4096 Nov 2 12:16 5.9.0-rc8-test+ + $ ls -al /lib/modules + drwxrwxr-x 3 ubuntu ubuntu 4096 Sep 28 15:07 5.9.0-rc4-test+ + drwxrwxr-x 3 ubuntu ubuntu 4096 Sep 24 11:06 5.9.0-rc5-test+ + drwxrwxr-x 3 ubuntu ubuntu 4096 Oct 5 16:39 5.9.0-rc6-test+ + drwxrwxr-x 3 ubuntu ubuntu 4096 Oct 14 21:42 5.9.0-rc7-test+ + drwxrwxr-x 3 ubuntu ubuntu 4096 Nov 2 12:16 5.9.0-rc8-test+ From 2f88b994b72d3f41ed2a9f6f4693d72dd7eb45dd Mon Sep 17 00:00:00 2001 From: Anton Bobkov Date: Fri, 25 Mar 2022 17:41:51 +0300 Subject: [PATCH 021/150] Edit code names --- .../cavs-boot/apollolake/apl-boot-ldr.rst | 4 ++-- .../cavs-boot/apollolake/apl-boot-rom.rst | 4 ++-- .../intel/cavs-boot/apollolake/index.rst | 4 ++-- .../firmware/intel/cavs-boot/index.rst | 4 ++-- architectures/firmware/overview.rst | 4 ++-- developer_guides/topology/topology.rst | 2 +- .../build-guide/build-from-scratch.rst | 4 ++-- .../build-guide/build-with-docker.rst | 4 ++-- getting_started/intel_debug/introduction.rst | 14 ++++++------ introduction/index.rst | 2 +- platforms/index.rst | 22 +++++++++---------- platforms/intel-cavs/icelake/icl-memory.rst | 2 +- platforms/intel-cavs/index.rst | 2 +- platforms/intel-legacy/baytrail/index.rst | 12 +++++----- platforms/intel-legacy/index.rst | 2 +- platforms/intel-legacy/merrifield/index.rst | 4 ++-- 16 files changed, 45 insertions(+), 45 deletions(-) diff --git a/architectures/firmware/intel/cavs-boot/apollolake/apl-boot-ldr.rst b/architectures/firmware/intel/cavs-boot/apollolake/apl-boot-ldr.rst index 2b6c68c5..04fd5d0e 100644 --- a/architectures/firmware/intel/cavs-boot/apollolake/apl-boot-ldr.rst +++ b/architectures/firmware/intel/cavs-boot/apollolake/apl-boot-ldr.rst @@ -1,7 +1,7 @@ .. _apl-boot-ldr: -Apollolake Boot Loader -###################### +Apollo Lake Boot Loader +####################### * Additional HPSRAM memory initialization. * L2 cache disabled in ``boot_entry`` (enabled by default by APL ROM). diff --git a/architectures/firmware/intel/cavs-boot/apollolake/apl-boot-rom.rst b/architectures/firmware/intel/cavs-boot/apollolake/apl-boot-rom.rst index 037b5718..5070e745 100644 --- a/architectures/firmware/intel/cavs-boot/apollolake/apl-boot-rom.rst +++ b/architectures/firmware/intel/cavs-boot/apollolake/apl-boot-rom.rst @@ -1,7 +1,7 @@ .. _apl-boot-rom: -Apollolake Boot ROM -################### +Apollo Lake Boot ROM +#################### Progress of the boot process is reflected by the status information updated by the ROM in an SRAM area called *FW Registers*. It is available to the host diff --git a/architectures/firmware/intel/cavs-boot/apollolake/index.rst b/architectures/firmware/intel/cavs-boot/apollolake/index.rst index 043d6503..21ee69cb 100644 --- a/architectures/firmware/intel/cavs-boot/apollolake/index.rst +++ b/architectures/firmware/intel/cavs-boot/apollolake/index.rst @@ -1,7 +1,7 @@ .. _cavs-boot-apl: -Apollolake Boot Process -####################### +Apollo Lake Boot Process +######################## .. toctree:: :maxdepth: 1 diff --git a/architectures/firmware/intel/cavs-boot/index.rst b/architectures/firmware/intel/cavs-boot/index.rst index 098f12f2..54ba2ef6 100644 --- a/architectures/firmware/intel/cavs-boot/index.rst +++ b/architectures/firmware/intel/cavs-boot/index.rst @@ -4,9 +4,9 @@ Booting up CAVS ADSP #################### Intel has several generations of audio DSP. "CAVS" versions relate to the audio -DSP in Skylake Core and Apollolake Atom platforms onwards. +DSP in Skylake Core and Apollo Lake Atom platforms onwards. -Baytrail, Cherrytrail, Braswell, Haswell and Broadwell audio DSPs have a simpler +Bay Trail, Cherry Trail, Braswell, Haswell, and Broadwell audio DSPs have a simpler boot flow using memory copy and not authentication. diff --git a/architectures/firmware/overview.rst b/architectures/firmware/overview.rst index 48649106..4cbe26b5 100644 --- a/architectures/firmware/overview.rst +++ b/architectures/firmware/overview.rst @@ -38,9 +38,9 @@ main sections: :alt: SOF Architecture :width: 800px - `Sound Open Firmware Architecture using Intel Baytrail Platform` + `Sound Open Firmware Architecture using Intel Bay Trail Platform` Each section above is well insulated from the other sections by partitioning code into separate directories and by using DSP and platform agnostic generic -APIs for orchestration between the sections. \ No newline at end of file +APIs for orchestration between the sections. diff --git a/developer_guides/topology/topology.rst b/developer_guides/topology/topology.rst index d2f7a4ab..0f9b04a3 100644 --- a/developer_guides/topology/topology.rst +++ b/developer_guides/topology/topology.rst @@ -217,7 +217,7 @@ DAI_ADD macro defined as follows: | **dai_index**: index of the dai in the firmware. Please note that the DAI’s of different types can have the same dai_index. The dai_index information can be found by looking in platform-specific dai array - definitions in the firmware. For example, for apollolake these are + definitions in the firmware. For example, for Apollo Lake these are defined in src/platform/apollolake/dai.c. | **dai_be**: name of CPU DAI as defined in DAI array in the platform driver. | **buffer**: Source/sink buffer the DAI is connected to. This completes the diff --git a/getting_started/build-guide/build-from-scratch.rst b/getting_started/build-guide/build-from-scratch.rst index c2cda4dd..1ac50ffc 100755 --- a/getting_started/build-guide/build-from-scratch.rst +++ b/getting_started/build-guide/build-from-scratch.rst @@ -235,7 +235,7 @@ download gcc components. unset LD_LIBRARY_PATH - # Baytrail/Cherrytrail + # Bay Trail / Cherry Trail cp config-byt-gcc10.2-gdb9 .config ./ct-ng build # Haswell/Broadwell @@ -244,7 +244,7 @@ download gcc components. # Apollo Lake cp config-apl-gcc10.2-gdb9 .config ./ct-ng build - # Cannon Lake, Ice Lake, Jasper Lake and Tiger Lake + # Cannon Lake, Ice Lake, Jasper Lake, and Tiger Lake cp config-cnl-gcc10.2-gdb9 .config ./ct-ng build # i.MX8/i.MX8X diff --git a/getting_started/build-guide/build-with-docker.rst b/getting_started/build-guide/build-with-docker.rst index 62831f71..de972829 100644 --- a/getting_started/build-guide/build-with-docker.rst +++ b/getting_started/build-guide/build-with-docker.rst @@ -120,9 +120,9 @@ To build the SOF binaries for one or more platforms: .. code-block:: bash cd "${SOF_WORKSPACE}"/sof/ - # Baytrail + # Bay Trail ./scripts/docker-run.sh ./scripts/xtensa-build-all.sh byt - # Baytrail and Apollo Lake + # Bay Trail and Apollo Lake ./scripts/docker-run.sh ./scripts/xtensa-build-all.sh byt apl Build inside container diff --git a/getting_started/intel_debug/introduction.rst b/getting_started/intel_debug/introduction.rst index 7260602b..f07807bc 100644 --- a/getting_started/intel_debug/introduction.rst +++ b/getting_started/intel_debug/introduction.rst @@ -6,14 +6,14 @@ Overview of Intel hardware platforms ACPI platforms (introduced before and up to 2015) ************************************************* -On Baytrail, Cherrytrail, Braswell, and Broadwell devices (also referred to +On Bay Trail, Cherry Trail, Braswell, and Broadwell devices (also referred to as `legacy` devices), the DSP enumeration is handled by the ACPI subsystem. 1. Local audio accessories (mics, speakers, headset) ---------------------------------------------------- -On Baytrail, Cherrytrail, Braswell, and Broadwell, the BIOS can either +On Bay Trail, Cherry Trail, Braswell, and Broadwell, the BIOS can either enable or disable the DSP: * Enable the DSP. In this case, a DSP driver is required. This mode is @@ -28,7 +28,7 @@ enable or disable the DSP: On Broadwell, HDMI/DP is handled by an HDaudio controller. -On Baytrail/Cherrytrail and Braswell, the BIOS can enable two modes: +On Bay Trail/Cherry Trail and Braswell, the BIOS can enable two modes: * HDAudio-based solution (similar to Broadwell). @@ -55,12 +55,12 @@ exposes PCM devices and no audio processing capabilities. When OEM platforms integrate digital microphones attached directly to the Intel chipset (aka DMIC), or they use I2C/I2S or SoundWire interfaces, the DSP must be enabled by the BIOS. There is, however, one -more option. On Skylake and Kabylake platforms, the Intel DSP is handled by +more option. On Skylake and Kaby Lake platforms, the Intel DSP is handled by the ``snd-soc-skl`` module which relies on closed-source firmware. -SOF is available on Intel PCI devices starting with GeminiLake, and +SOF is available on Intel PCI devices starting with Gemini Lake, and has since been the only solution provided by Intel for the following -platforms: CometLake, IceLake, and TigerLake. +platforms: Comet Lake, Ice Lake, and Tiger Lake. Since multiple drivers can register for the same PCI ID, it was (until recently) common for users and distributions to use the wrong @@ -107,7 +107,7 @@ used. The Intel ME (Management Engine) is responsible for authentication of the firmware, whether it is signed by an Intel production key (consumer products), a community key (open development systems and Chromebooks -since GeminiLake) or an OEM key. If the Intel ME is disabled by an +since Gemini Lake) or an OEM key. If the Intel ME is disabled by an OEM, or disabled by user-accessible BIOS options, the firmware authentication will fail and the firmware boot will not complete. If the ME is disabled by the OEM, the only solution is to fall-back diff --git a/introduction/index.rst b/introduction/index.rst index 40a78904..6b007c57 100644 --- a/introduction/index.rst +++ b/introduction/index.rst @@ -49,7 +49,7 @@ there can be more than once choice for other ingredients as shown in the diagram :alt: SDK Overview :width: 1000px - `SDK example configuration showing development flow for SOF on the Intel Apollolake platform running Linux OS. Note the choice of compiler toolchains and choice of optional DSP emulators.` + `SDK example configuration showing development flow for SOF on the Intel Apollo Lake platform running Linux OS. Note the choice of compiler toolchains and choice of optional DSP emulators.` SOF source code, tools, and topologies diff --git a/platforms/index.rst b/platforms/index.rst index 27fd5407..585e1e00 100644 --- a/platforms/index.rst +++ b/platforms/index.rst @@ -14,16 +14,16 @@ Platform and board specific support is continually added to the SOF project as d "Host Testbench", "PC command line", "N/A", "N/A", "N/A", "N/A Files are used to simulate audio interfaces" "Qemu", "All supported SOF HW platforms", "N/A", "N/A", "N/A", "WiP Files will be used to simulate audio interfaces" - "Intel Baytrail / Merrifield", "Xtensa HiFi2 EP", "1 @ 50 - 400MHz", "25MHz", "96KB IRAM / 192KB DRAM", "3 x SSP (I2S, PCM)" - "Intel Cherrytrail / Braswell", "Xtensa HiFi2 EP", "1 @ 50 - 400MHz", "19.2MHz", "96KB IRAM / 192KB DRAM", "6 x SSP (I2S, PCM)" + "Intel Bay Trail / Merrifield", "Xtensa HiFi2 EP", "1 @ 50 - 400MHz", "25MHz", "96KB IRAM / 192KB DRAM", "3 x SSP (I2S, PCM)" + "Intel Cherry Trail / Braswell", "Xtensa HiFi2 EP", "1 @ 50 - 400MHz", "19.2MHz", "96KB IRAM / 192KB DRAM", "6 x SSP (I2S, PCM)" "Intel Broadwell", "Xtensa HiFi2 EP", "1 @ 50 - 400MHz", "24MHz", "320KB IRAM / 640KB DRAM", "2 x SSP (I2S, PCM)" - "Intel Apollolake / Geminilake", "Xtensa HiFi3", "2 @ 100 - 400MHz", "19.2MHz", "128KB LP SRAM / 512KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC" - "Intel Cannonlake / Whiskeylake / Cometlake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "24MHz", "64KB LP / 3008KB HP SRAM", "3 x SSP (I2S, PCM), HDA, DMIC, Soundwire" - "Intel Suecreek", "Xtensa HiFi3", "2 @ 120 - 400MHz","24MHz", "64KB LP SRAM / 4096KB HP SRAM", "6 x SSP (I2S, PCM), DMIC" - "Intel Icelake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 3008KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" - "Intel Jasperlake", "Xtensa HiFi3", "2 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 1024KB HP SRAM", "3 x SSP (I2S, PCM), HDA, DMIC, Soundwire" - "Intel Tigerlake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 2944KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" - "Intel Alderlake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 2944KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "Intel Apollo Lake / Gemini Lake", "Xtensa HiFi3", "2 @ 100 - 400MHz", "19.2MHz", "128KB LP SRAM / 512KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC" + "Intel Cannon Lake / Whiskey Lake / Comet Lake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "24MHz", "64KB LP / 3008KB HP SRAM", "3 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "Intel Sue Creek", "Xtensa HiFi3", "2 @ 120 - 400MHz","24MHz", "64KB LP SRAM / 4096KB HP SRAM", "6 x SSP (I2S, PCM), DMIC" + "Intel Ice Lake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 3008KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "Intel Jasper Lake", "Xtensa HiFi3", "2 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 1024KB HP SRAM", "3 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "Intel Tiger Lake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 2944KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "Intel Alder Lake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 2944KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" "NXP i.MX8", "Xtensa HiFi4", "1 @ 666MHz", "TBD", "64 KB TCM / 448 KB OCRAM / 8MB SDRAM", "1 x ESAI, 1 x SAI" "NXP i.MX8X", "Xtensa HiFi4", "1 @ 640MHz", "TBD", "64 KB TCM / 448 KB OCRAM / 8MB SDRAM", "1 x ESAI, 1 x SAI" "NXP i.MX8M", "Xtensa HiFi4", "1 @ 800MHz", "TBD", "64 KB TCM / 256 KB OCRAM / 8MB SDRAM", "1 x SAI, MICFIL" @@ -42,14 +42,14 @@ Footprint ========= DSP platforms can vary from vendor to vendor but in general SOF can run on -small platforms like Intel Baytrail DSP with 96kb of instruction RAM and 168kb +small platforms like Intel Bay Trail DSP with 96kb of instruction RAM and 168kb of data RAM. The SOF footprint can be shrunk to approximately 50kb of TEXT and DATA by fine-tuning runtime features via Kconfig. DSP Clock Speed =============== -Required DSP clock speed depends on the DSP processing load, so it can vary greatly depending on pipeline topology and the algorithm design that is running. SOF can run several volume passthrough pipelines on the Intel Baytrail DSP at 50MHz using unoptimized C code (SIMD disabled and compiled with GCC). +Required DSP clock speed depends on the DSP processing load, so it can vary greatly depending on pipeline topology and the algorithm design that is running. SOF can run several volume passthrough pipelines on the Intel Bay Trail DSP at 50MHz using unoptimized C code (SIMD disabled and compiled with GCC). Toolchain ========= diff --git a/platforms/intel-cavs/icelake/icl-memory.rst b/platforms/intel-cavs/icelake/icl-memory.rst index 689a316f..19e3e313 100644 --- a/platforms/intel-cavs/icelake/icl-memory.rst +++ b/platforms/intel-cavs/icelake/icl-memory.rst @@ -3,4 +3,4 @@ ICL Memory ########## -Memory map is the same as on Cannonlake. See :ref:`cnl-memory`. +Memory map is the same as on Cannon Lake. See :ref:`cnl-memory`. diff --git a/platforms/intel-cavs/index.rst b/platforms/intel-cavs/index.rst index 62950e1f..cc2b7bd1 100644 --- a/platforms/intel-cavs/index.rst +++ b/platforms/intel-cavs/index.rst @@ -15,7 +15,7 @@ Intel CAVS platforms supported by the |SOF|. | |ver. 2.5 | Tiger Lake | +---------+----------+-----------------------------------------+ -.. note:: While the Sky Lake and Kaby Lake platforms are also based on the +.. note:: While the Skylake and Kaby Lake platforms are also based on the cAVS 1.5 architecture, they are not supported at this time due to differences in boot flow and memory architecture. diff --git a/platforms/intel-legacy/baytrail/index.rst b/platforms/intel-legacy/baytrail/index.rst index 92bfa102..8b5040ca 100644 --- a/platforms/intel-legacy/baytrail/index.rst +++ b/platforms/intel-legacy/baytrail/index.rst @@ -1,20 +1,20 @@ .. _platform-baytrail: -Intel Baytrail/CherryTrail -########################## +Intel Bay Trail / Cherry Trail +############################## -Intel Baytrail platform is based on an Atom CPU and a Tensilica HiFi2 +Intel Bay Trail platform is based on an Atom CPU and a Tensilica HiFi2 EP DSP. It relies on both internal memory and caches to access DDR -memory. The Baytrail processor relies on a 25 MHz oscillator. +memory. The Bay Trail processor relies on a 25 MHz oscillator. Supported commercially-available platforms include the MinnowBoard Turbot, tablets and laptops built for Windows (SOF requires a Linux installation). -The Cherrytrail platform is similar to Baytrail but it relies on a +The Cherry Trail platform is similar to Bay Trail but it relies on a 19.2 MHz osciilator. Supported commercially-available platforms include the Up board and devices built for Windows (SOF requires a Linux installation). -Baytrail and Cherrytrail Chromebooks can support SOF but the official +Bay Trail and Cherry Trail Chromebooks can support SOF but the official images are still based on the closed-source firmware solution. diff --git a/platforms/intel-legacy/index.rst b/platforms/intel-legacy/index.rst index 0e257ef3..ccc590e8 100644 --- a/platforms/intel-legacy/index.rst +++ b/platforms/intel-legacy/index.rst @@ -8,7 +8,7 @@ Intel platforms based on the Tensilica Hifi2-EP DSP supported by the |SOF|. +------------+--------------------------------------------------+ | Atom/PCI | Merrifield (Edison) | +------------+--------------------------------------------------+ -| Atom/ACPI | Baytrail, Cherrytrail, Braswell | +| Atom/ACPI | Bay Trail, Cherry Trail, Braswell | +------------+--------------------------------------------------+ | Core/ACPI | Broadwell (Chromebook Pixel 2015, Dell XPS) | +------------+--------------------------------------------------+ diff --git a/platforms/intel-legacy/merrifield/index.rst b/platforms/intel-legacy/merrifield/index.rst index 0575d848..b6a7311d 100644 --- a/platforms/intel-legacy/merrifield/index.rst +++ b/platforms/intel-legacy/merrifield/index.rst @@ -4,8 +4,8 @@ Intel Merrifield ################ Intel Merrifield platform is based on an Atom CPU and a Tensilica HiFi2 -EP DSP. It is very similar to Baytrail but uses a PCI-based -enumeration and has a clocking structure similar to Cherrytrail. +EP DSP. It is very similar to Bay Trail but uses a PCI-based +enumeration and has a clocking structure similar to Cherry Trail. This platform is no longer commercially available, but the Edison platform is supported by the open-source community. From 82de566c4b81799c06ff950c59a5e8beaab70ce4 Mon Sep 17 00:00:00 2001 From: Deb Date: Mon, 18 Apr 2022 09:04:49 -0400 Subject: [PATCH 022/150] Updated release page to 2.1.1 Signed-off-by: Deb --- release.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.rst b/release.rst index 2d1f65d3..8ec14547 100755 --- a/release.rst +++ b/release.rst @@ -26,7 +26,7 @@ kernel, and documentation. Download the source code as a zip or tar.gz file: Source and Binary Releases -------------------------- -The latest SOF release is v2.0 (December 2021). +The latest SOF release is v2.1.1 (April 2022). View new feature information and release downloads for the latest and previous releases on GitHub. Firmware and SDK tool source code and binary From d6ee4f054d43895ec8c929fa6a95c0c1eb352548 Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Wed, 8 Jun 2022 18:04:55 -0700 Subject: [PATCH 023/150] conf.py: cpp_id_attributes = ["__sparse_cache"] With a recent enough sphinx-build --version, this fixes the gazillion of warnings recently added: ``` /home/runner/work/sof-docs/sof-docs/api/component-api.rst:21: WARNING: Error when parsing function declaration. If the function has no return type: Error in declarator or parameters-and-qualifiers Invalid C++ declaration: Expected identifier in nested name, got keyword: void [error at 18] static inline void comp_underrun (struct comp_dev *dev, struct comp_buffer __sparse_cache *source, uint32_t copy_bytes) ------------------^ If the function has a return type: Error in declarator or parameters-and-qualifiers If pointer to member declarator: Invalid C++ declaration: Expected '::' in pointer to member (function). [error at 33] static inline void comp_underrun (struct comp_dev *dev, struct comp_buffer __sparse_cache *source, uint32_t copy_bytes) ---------------------------------^ If declarator-id: Invalid C++ declaration: Expecting "," or ")" in parameters-and-qualifiers, got "*". [error at 90] static inline void comp_underrun (struct comp_dev *dev, struct comp_buffer __sparse_cache *source, uint32_t copy_bytes) ------------------------------------------------------------------------------------------^ ``` Signed-off-by: Marc Herbert --- conf.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/conf.py b/conf.py index 02794784..e60cb085 100755 --- a/conf.py +++ b/conf.py @@ -52,6 +52,12 @@ # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] +# Fixes "WARNING: Error when parsing function declaration." +c_id_attributes = ["__sparse_cache"] +# Not clear why Sphinx thinks some C files are C++ +cpp_id_attributes = c_id_attributes +# cpp_paren_attributes = ["_ALIAS_OF", "__printf_like"] + # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # From 8f4871976fb9528758c5501e39e9ff33e5086bc1 Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Wed, 8 Jun 2022 18:06:17 -0700 Subject: [PATCH 024/150] conf.py: language = None -> en Fixes Sphinx 5 warning: Running Sphinx v5.0.1 WARNING: Invalid configuration value found: 'language = None'. Update your configuration to a valid langauge code. Falling back to 'en' (English). Signed-off-by: Marc Herbert --- conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf.py b/conf.py index e60cb085..8132100c 100755 --- a/conf.py +++ b/conf.py @@ -89,7 +89,7 @@ # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = 'en' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. From d334f72a1c699ace7c63971a3499bd6b72f99689 Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Wed, 8 Jun 2022 18:07:36 -0700 Subject: [PATCH 025/150] conf.py: extlinks: fix captions, from "" to None Fixes Sphinx 5 warning: WARNING: extlinks: Sphinx-6.0 will require a caption string to contain exactly one '%s' and all other '%' need to be escaped as '%%'. Signed-off-by: Marc Herbert --- conf.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/conf.py b/conf.py index 8132100c..0a356391 100755 --- a/conf.py +++ b/conf.py @@ -174,13 +174,13 @@ # as required. extlinks = { 'git-sof-mainline': - (SOF_GIT + '/sof/tree/master/%s', ""), + (SOF_GIT + '/sof/tree/master/%s', None), 'git-sof-docs-mainline': - (SOF_GIT + '/sof-docs/tree/master/%s', ""), + (SOF_GIT + '/sof-docs/tree/master/%s', None), 'git-sof-kconfig': - (SOF_GIT + '/kconfig/tree/master/%s', ""), + (SOF_GIT + '/kconfig/tree/master/%s', None), 'git-alsa': - ('https://git.alsa-project.org/?p=%s.git', ""), + ('https://git.alsa-project.org/?p=%s.git', None), } # Add any paths that contain custom static files (such as style sheets) here, From 99343a2b4105940efe72e5f0e983c2eeb1bde21a Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Tue, 7 Jun 2022 21:55:25 +0000 Subject: [PATCH 026/150] zephyr: simplify west init command west init knows how to create a directory, no need to ask the user. Signed-off-by: Marc Herbert --- getting_started/build-guide/build-with-zephyr.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/getting_started/build-guide/build-with-zephyr.rst b/getting_started/build-guide/build-with-zephyr.rst index 303282ce..f3bad129 100755 --- a/getting_started/build-guide/build-with-zephyr.rst +++ b/getting_started/build-guide/build-with-zephyr.rst @@ -41,10 +41,9 @@ Check out and build .. code-block:: bash - mkdir $ZEPHYR_WORKSPACE - cd $ZEPHYR_WORKSPACE - west init + west init $ZEPHYR_WORKSPACE # Significantly smaller and faster than a full "west update" + cd $ZEPHYR_WORKSPACE west update hal_xtensa sof #. Build and sign a firmware image: From ab552a3454ed5c1a17cdda9f1e564f336f4bd163 Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Wed, 8 Jun 2022 23:27:05 +0000 Subject: [PATCH 027/150] build-with-zephyr: fix submodules, get ready for new python script Add missing `git submodule update` as reported by @plbossart (thx!) Also make the documentation ready for `xtensa-build-zephyr.py` which... does not have any hack to automatically download git submodules like the older .sh script has. As a side-effect, this breaks down the process and adds an intermediate `west build` step which removes one layer of indirection in case of some Zephyr environment issue. Cannot fully switch to the Python version yet because of bugs like https://github.com/thesofproject/sof/pull/5906 but do recommend users to start trying it. Signed-off-by: Marc Herbert --- .../build-guide/build-with-zephyr.rst | 45 ++++++++++++++----- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/getting_started/build-guide/build-with-zephyr.rst b/getting_started/build-guide/build-with-zephyr.rst index f3bad129..3a54092e 100755 --- a/getting_started/build-guide/build-with-zephyr.rst +++ b/getting_started/build-guide/build-with-zephyr.rst @@ -30,8 +30,8 @@ Check out and build .. note:: If you need a different SOF version than the one that west - automatically checks out, change to ``modules/audio/sof`` and use git - to select your preferred version. You need at least version 1.6 to use + automatically checks out, instructions below show how to change ``modules/audio/sof`` + and select your preferred version. You need at least Zephyr version 1.6 to use it with Zephyr. Make sure you branch or tag your code in git; otherwise, a future ``west update`` may lose it. See the west user guide. @@ -46,15 +46,19 @@ Check out and build cd $ZEPHYR_WORKSPACE west update hal_xtensa sof -#. Build and sign a firmware image: +#. Make sure the appropriate Zephyr SDK or other toolchain of your + choice can be found for your desired ``--board`` and that every + other Zephyr dependency is set up properly: .. code-block:: bash - cd $ZEPHYR_WORKSPACE - ./modules/audio/sof/scripts/xtensa-build-zephyr.sh -h # shows usage - ./modules/audio/sof/scripts/xtensa-build-zephyr.sh $your_platforms - ls build-*/zephyr/zephyr.* - => build-*/zephyr/zephyr.ri ... + ls zephyr/boards/xtensa/ + west build --board intel_adsp_cavs25 ./zephyr/samples/subsys/audio/sof/ + + For now the ``.elf`` file produced by ``west build`` is missing a + manifest and signature. The wrapper script below invokes *both* + ``west build`` and ``west sign`` and produces a complete ``.ri`` + file; you won't need to call ``west build`` again. #. Fetch and switch to the latest SOF code @@ -69,8 +73,29 @@ Check out and build git fetch sof git switch --track sof/main - You can also delete the ``sof`` clone downloaded by ``west`` and - replace it with an older clone; west will automatically adjust. + # If needed, correct submodule URLs in .git/config with latest .gitmodules file. + git submodule sync --recursive + # Download submodules + git submodule update --init --recursive + + Alternatively, feel free to delete the ``sof`` clone downloaded by + ``west`` and replace it with any other ``sof`` clone you already + have; west will automatically adjust. + +#. Build and sign a firmware image: + + .. code-block:: bash + + cd $ZEPHYR_WORKSPACE + ./modules/audio/sof/scripts/xtensa-build-zephyr.sh -h # shows usage + ./modules/audio/sof/scripts/xtensa-build-zephyr.sh $your_platforms + ls build-*/zephyr/zephyr.* + => build-*/zephyr/zephyr.ri ... + + +There is work in progress to substitute ``xtensa-build-zephyr.sh`` with +a Python replacement ``xtensa-build-zephyr.py`` for Windows +compatibility. It can already be used in many cases. Run *** From 5e7a34287206251669ab6a8999bf9bbb14d2aeac Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 9 Jun 2022 15:45:51 +0300 Subject: [PATCH 028/150] getting_started: setup_linux: intall_locally: Add link to Arch Linux guide Arch users tend to bump into new issues due to the fact that they are using more recent kernels compared to non rolling distro users. Add a link to Arch's manual kernel compilation and installation page as well. Signed-off-by: Peter Ujfalusi --- getting_started/setup_linux/install_locally.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting_started/setup_linux/install_locally.rst b/getting_started/setup_linux/install_locally.rst index d4b7f0b6..d70f9774 100644 --- a/getting_started/setup_linux/install_locally.rst +++ b/getting_started/setup_linux/install_locally.rst @@ -10,7 +10,7 @@ Install the Kernel Locally Introduction ************ -Make sure you have `set up your development environment `_ before following these steps. This page will guide you through the process of installing the kernel locally on your machine. It will be installed in addition to your distro's default kernel so that you can always change back to that in case something goes wrong. If you are interested in learning more about this process, there are lots of online guides available, for example `Fedora* Quick Docs `_ or `this wiki page `_. +Make sure you have `set up your development environment `_ before following these steps. This page will guide you through the process of installing the kernel locally on your machine. It will be installed in addition to your distro's default kernel so that you can always change back to that in case something goes wrong. If you are interested in learning more about this process, there are lots of online guides available, for example `Fedora* Quick Docs `_, `Arch Linux documentation `_ or `this wiki page `_. Build and install the kernel From 5f45198666cdfcf05585a94319873fb62c76a535 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 15 Jun 2022 14:51:57 +0300 Subject: [PATCH 029/150] developer_guides: debugability: probes: Update for sof client version of probes The probes got converted to sof client mode, update the documentation to be up to date. Signed-off-by: Peter Ujfalusi --- .../debugability/probes/index.rst | 47 ++++++++++++++++--- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/developer_guides/debugability/probes/index.rst b/developer_guides/debugability/probes/index.rst index c05bd91a..dc019629 100644 --- a/developer_guides/debugability/probes/index.rst +++ b/developer_guides/debugability/probes/index.rst @@ -17,15 +17,49 @@ Requirements Enabling Probes *************** -- Enable the following Linux kernel configuration options: +Kernel side +=========== + +- The probes support is enabled by Kconfig on supported platforms as a SOF client + driver, check the kernel config for ``SND_SOC_SOF_DEBUG_PROBES``. + The debugfs also needs to be enabled for the probes to be usable. .. code-block:: bash CONFIG_DEBUG_FS=y - CONFIG_SND_SOC_SOF_DEBUG_PROBES=y - CONFIG_SND_SOC_SOF_HDA_PROBES=y -- Enable the Probe module in the SOF firmware ``kconfig`` using this command: +- The probes client needs to be enabled via the 'enable' module parameter (e.g. ``/etc/modprobe.d/sof.conf``): + + .. code-block:: bash + + options snd_sof_probes enable=1 + + To make sure that the sound card for the probes is consistent between boots, a + card slot can be forced for the module. + For example to use card3, this can be added to the sof.conf file: + + .. code-block:: bash + + options snd slots=,,,snd_sof_probes + + Remove and re-load the driver: + + .. code-block:: bash + + rmmod snd_sof_probes + modprobe snd_sof_probes + + Verify that the card is available (if not, try to reboot): + + .. code-block:: bash + + cat /proc/asound/cards | grep sofprobes + +Firmware side +============= + +- The Probe module can be enabled under the 'Probe' menu's 'Probes enabled' prompt (``PROBES``) + To edit the ``kconfig`` use this command: .. code-block:: bash @@ -49,13 +83,14 @@ the last stage of extraction. .. code-block:: bash - crecord -c0 -d23 -b8192 -f4 -FS32_LE -R48000 -C4 /tmp/extract.dat + crecord -c3 -d0 -b8192 -f4 -FS32_LE -R48000 -C4 /tmp/extract.dat Usage: .. code-block:: none - -d : device ID; equals 23 in the above example. + -c : card number; 3 in the above example if a slot is forced + -d : device ID; equals 0 in the above example (probes card only have 1 compressed capture stream). -b : buffer size. For probes, this is part of the probe initialization IPC and denotes the extraction stream buffer size on the host side. -f : fragments is basically number of periods for compress stream. From 1b019895ac40bd77f769caaadeaabd387333a8b7 Mon Sep 17 00:00:00 2001 From: Deb Date: Fri, 1 Jul 2022 09:12:01 -0400 Subject: [PATCH 030/150] Update page to signify 2.2 release --- release.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.rst b/release.rst index 8ec14547..93fb89d8 100755 --- a/release.rst +++ b/release.rst @@ -26,7 +26,7 @@ kernel, and documentation. Download the source code as a zip or tar.gz file: Source and Binary Releases -------------------------- -The latest SOF release is v2.1.1 (April 2022). +The latest SOF release is v2.2 (July 2022). View new feature information and release downloads for the latest and previous releases on GitHub. Firmware and SDK tool source code and binary From 211a7e0cad9330f562f72fdfd0501e85f1792829 Mon Sep 17 00:00:00 2001 From: Deb Date: Thu, 7 Jul 2022 08:10:22 -0500 Subject: [PATCH 031/150] Update conf.py to reflect 2.2 release Signed-off-by: Deb --- conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf.py b/conf.py index 0a356391..fa9c4429 100755 --- a/conf.py +++ b/conf.py @@ -76,7 +76,7 @@ # |version| and |release|, also used in various other places throughout the # built documents. -version = release = "2.0" +version = release = "2.2" # # The short X.Y version. From 9788c4be32cfbfb7538806ab9a568c23447b365e Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Thu, 7 Jul 2022 19:19:57 -0700 Subject: [PATCH 032/150] Makefile: stop recommending users to build doxygen in SOF source dir CMake is all about "out of source" build directories which among others make it super easy to clean: just delete the build directory, done. So stop recommending users to build doxygen inside their SOF source tree which pollutes it with many files they have to delete one by one. Before this commit: git -C ../sof/ status --ignored Untracked/Ignored files: (use "git add ..." to include in what will be committed) doc/.ninja_log doc/CMakeCache.txt doc/CMakeFiles/ doc/build.ninja doc/cmake_install.cmake doc/doxygen/ doc/sof.doxygen After this commit: git -C ../sof/ status --ignored Ignored files: (use "git add -f ..." to include in what will be committed) build_doxygen/ Signed-off-by: Marc Herbert --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f2b63f5a..52fed184 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ else Q = @ endif -SOF_DOC_BUILD = ../sof/doc +SOF_DOC_BUILD = ../sof/build_doxygen/ SPHINXBUILD = sphinx-build SPHINXPROJ = "SOF Project" SOURCEDIR = . From 99db6790351116ebe46cb6707d4ce9f6fa6663de Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Wed, 6 Jul 2022 15:40:19 -0500 Subject: [PATCH 033/150] intel_debug: add suggestions for DMIC and ES8336 platforms Instead of repeating the same things on GitHub issues, maybe this documentation will help. Signed-off-by: Pierre-Louis Bossart --- getting_started/intel_debug/suggestions.rst | 136 ++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/getting_started/intel_debug/suggestions.rst b/getting_started/intel_debug/suggestions.rst index 9b9c9b3c..4a24c855 100644 --- a/getting_started/intel_debug/suggestions.rst +++ b/getting_started/intel_debug/suggestions.rst @@ -140,3 +140,139 @@ to snd_sof module: .. code-block:: options snd_sof sof_debug=1 + + +Digital mic issues +****************** + +The SOF driver and firmware have limited information related to the +number of digital microphones and their physical location. + +On devices designed for Windows, the presence of the microphone is +reported as an NHLT endpoint (ACPI table in the BIOS). The SOF Linux +driver will report this information with a 'dmesg' log such as + +.. code-block:: + + [ 4.301490] sof-audio-pci-intel-tgl 0000:00:1f.3: DMICs detected in NHLT tables: 2 + +Recent versions of the ACPICA tools (acpica-tools package) can also be +used to visualize the ACPI tables. + +In some instances the number of DMICs reported by the NHLT does not +match the hardware layout. The SOF driver provides a means to alter +the value with a kernel parameter which can be added in +/etc/modprobe.d/alsa-base.conf (or any other configuration file with +this .conf extension). A reboot is necessary after changing the value + +.. code-block:: + + options snd_sof_intel_hda_common dmic_num=4 + +The following command can then be used to check if the microphones are active at the lowest level + +.. code-block:: bash + + arecord -Dhw:0,6 -c4 -r48000 -sS32_LE -d 10 test.wav + +In 99% of the cases, hardware designers connect the two microphones on +the PDM0 controller. Some platforms use PDM1, which cannot really be +detected by the OS. By capturing in 4ch mode, it's possible that +channel3 and 4 capture data while channel0 and channel1 only show +signs of transitions and DC-removal. Simply talking or recording music +in this 10s test, then visualizing the recorded file with Audacity is +often enough to diagnose the presence of 2 microphones on the 'wrong' +PDM controller. + +In that case, a different topology file needs to be used, typically +sof-hda-generic-2ch-pdm1.tplg. On older distributions, it will be +necessary to override the file installed in +/lib/firmware/intel/sof-tplg/sof-hda-generic-2ch.tplg. On kernels +5.20+ a kernel parameter will be enough with no need to change and +override installed topology files, e.g. + +.. code-block:: + + options snd-sof-pci tplg_filename=sof-hda-generic-2ch-pdm1.tplg + +These PDM1 issues are tracked in GitHub with the label 'DMIC-PDM1' in the +`firmware issues `_ +and in the `Linux issues `_. + +Users running Linux distributions on Chromebooks routinely experience +issues with digital microphones. In the Chrome environment, the +topology always exposes 4 channels, and UCM files for specific +platforms specify which of the 4 channels are valid. A plugin will +then drop the useless/non-populated channels. This capability does not +exist yet in upstream UCM/Linux. Capturing with the 'arecord; command +above will help understand which channels are valid and configure UCM +files. + +ES8336 support +************** + +Since 2021, a number of OEMs relied on the ES8336 codec from Everest +Audio on platforms as varied as AppoloLake, GeminiLake, JasperLake, +CometLake, AlderLake. + +End-users can verify if the hardware uses this configuration by +running the 'alsa-info' command and checking for the presence an ACPI +_HID, e.g. + +.. code-block:: + + /sys/bus/acpi/devices/ESSX8336:00/status 15 + +.. code-block:: + + /sys/bus/acpi/devices/ESSX8326:00/status 15 + +Support for this platform only stated upstream with the kernel +5.19-rc1. Any attempts with earlier kernels will require backports and +experimental patches to be added. In the case of the 8326, the codec +vendor submitted a driver to the ALSA/ASoC maintainers, which was not +merged as of July 2022. In this specific case end-users will be forced +to compile their own kernel. + +The SOF driver implemented an automatic detection of the SSP/I2S port +used by hardware and the presence of digital microphones based on +platform firmware/NHLT. + +There are however a number of hardware configurations that cannot be +detected from platform firmware. To work-around this limitation, the +'sof-es8336' machine driver exposes a 'quirk' kernel parameter which +can be used for modify GPIO and jack detection settings. Existing +quirks are listed in the sound/soc/intel/boards/sof_es8336.c machine +driver: + +.. code-block:: c + + #define SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK BIT(4) + #define SOF_ES8336_JD_INVERTED BIT(6) + #define SOF_ES8336_HEADPHONE_GPIO BIT(7) + #define SOC_ES8336_HEADSET_MIC1 BIT(8) + + +The default quirk value for the platform can be read from +/sys/module/snd_soc_sof_es8336/parameters/quirk (the value is reported +as plain integer, not hexadecimal). Changes to the default can be +added with the following option in +e.g. /etc/modprobe.d/alsa-base.conf. Only the bits listed above can be +modified, others need to be kept as is. + +.. code-block:: + + options snd_soc_sof_es8336 quirk= + +Changing quirk values is an extremely experimental endeavor that +should only attempted by users with working knowledge of the Linux +audio subsystem and an understanding that playing with hardware +settings MAY DAMAGE HARDWARE or generate extremely loud sounds that +MAY DAMAGE YOUR HEARING. + +In rare cases, some platforms use the MCLK1 signal instead of +MCLK0. As of July 2022, there is no turn-key solution for those +platforms. + +These ES8336 issues are tracked in GitHub with the label 'codec +ES8336' in the `Linux ES8336 issues `_. From d56a799ebe23a3f2ba4ab3bc8eabfbe9700a4bab Mon Sep 17 00:00:00 2001 From: Noah Klayman Date: Fri, 15 Jul 2022 23:23:30 +0000 Subject: [PATCH 034/150] testbench: add note to install runtime deps I've found Valgrind and bc are necessary to run the testbench. Neither are listed in the general dependency list for Ubuntu 20.04 and only Valgrind is listed for other versions. Signed-off-by: Noah Klayman --- developer_guides/testbench/build_testbench.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/developer_guides/testbench/build_testbench.rst b/developer_guides/testbench/build_testbench.rst index b371757d..3f707b10 100644 --- a/developer_guides/testbench/build_testbench.rst +++ b/developer_guides/testbench/build_testbench.rst @@ -3,6 +3,13 @@ Build and Run Testbench ####################### +First, you'll need to install some dependencies to run the testbench: + +.. code-block:: bash + + sudo apt install valgrind bc # For Ubuntu/Debian + sudo dnf install valgrind bc # For Fedora + Retrieve the required firmware from the ``thesofproject`` repository in Github as described in :ref:`build-from-scratch`. Start a shell at the firmware repository top level in the ``$SOF_WORKSPACE/sof`` directory as also described. From d5afee8984daea970c366cfc812001020fa365fc Mon Sep 17 00:00:00 2001 From: Noah Klayman Date: Sat, 16 Jul 2022 22:26:43 +0000 Subject: [PATCH 035/150] getting_started/build-guide: add dep list for Fedora Signed-off-by: Noah Klayman --- .../build-guide/build-from-scratch.rst | 54 ++++++++++--------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/getting_started/build-guide/build-from-scratch.rst b/getting_started/build-guide/build-from-scratch.rst index 1ac50ffc..2cc602e2 100755 --- a/getting_started/build-guide/build-from-scratch.rst +++ b/getting_started/build-guide/build-from-scratch.rst @@ -12,10 +12,9 @@ Intel platforms include: |BYT|, |CHT|, |HSW|, |BDW|, |APL|, |CNL|, |ICL|, |JSL|, Support also exists for NXP i.MX8/i.MX8X/i.MX8M platforms. -The following steps describe how to install the SOF development -environment on Ubuntu 16.04, 18.04, 18.10, and 20.04. They should work on -19.04, 19.10 and other Linux distributions with minor or no -modifications. +The following steps describe how to install the SOF development environment on +Ubuntu 16.04, 18.04, 18.10, and 20.04, and Fedora 36. They should work on Ubuntu +19.04, 19.10 and other Linux distributions with minor or no modifications. .. note:: @@ -50,7 +49,7 @@ Install package dependencies ============================ .. note:: - This guide uses Ubuntu as an example but any modern distribution can be + This guide uses Ubuntu/Fedora as an example but any modern distribution can be used for SOF development. Due to continuous default package updates in distributions, SOF @@ -58,39 +57,42 @@ documentation may not include explicit instructions for possible missing tools and packages. When you encounter missing dependencies, refer to your distribution's documentation on how to install them. -Make sure that ``build-essential`` and ``git`` are installed: +* For Fedora (tested with v36, other recent versions should work fine): -.. code-block:: bash + .. code-block:: bash - sudo apt-get install build-essential git + sudo dnf group install "Development Tools" "C Development Tools and Libraries" + sudo dnf install ncurses-devel gtk3-devel gettext-devel texinfo help2man \ + glibc-static libstdc++-static openssl-devel tree * For Ubuntu 20.04: .. code-block:: bash - sudo apt install autoconf flex bison texinfo help2man gawk libtool-bin \ - libncurses5 libncurses5-dev libssl-dev libgtk-3-dev tree \ - ninja-build gettext libasound2-dev + sudo apt install build-essential git autoconf flex bison texinfo help2man \ + gawk libtool-bin libncurses5 libncurses5-dev libssl-dev libgtk-3-dev \ + tree ninja-build gettext libasound2-dev * For Ubuntu 18.10: .. code-block:: bash - sudo apt-get install libgtk-3-dev libsdl1.2-dev libspice-protocol-dev \ - libspice-server-dev libusb-1.0-0-dev libusbredirhost-dev libtool-bin \ - acpica-tools valgrind texinfo virt-manager qemu-kvm \ - libvirt-daemon-system libvirt-clients virtinst libfdt-dev libssl-dev \ - pkg-config help2man gawk libncurses5 libncurses5-dev + sudo apt-get install build-essential git libgtk-3-dev libsdl1.2-dev \ + libspice-protocol-dev libspice-server-dev libusb-1.0-0-dev \ + libusbredirhost-dev libtool-bin acpica-tools valgrind texinfo \ + virt-manager qemu-kvm libvirt-daemon-system libvirt-clients virtinst \ + libfdt-dev libssl-dev pkg-config help2man gawk libncurses5 \ + libncurses5-dev * For Ubuntu 16.04 and 18.04: .. code-block:: bash - sudo apt-get install libgtk-3-dev libsdl1.2-dev libspice-protocol-dev \ - libspice-server-dev libusb-1.0-0-dev libusbredirhost-dev libtool-bin \ - iasl valgrind texinfo virt-manager qemu-kvm libvirt-bin virtinst \ - libfdt-dev libssl-dev pkg-config help2man gawk libncurses5 \ - libncurses5-dev + sudo apt-get install build-essential git libgtk-3-dev libsdl1.2-dev \ + libspice-protocol-dev libspice-server-dev libusb-1.0-0-dev \ + libusbredirhost-dev libtool-bin iasl valgrind texinfo virt-manager \ + qemu-kvm libvirt-bin virtinst libfdt-dev libssl-dev pkg-config help2man \ + gawk libncurses5 libncurses5-dev If you are using Ubuntu 16.04, the gcc version must be updated to gcc 7.3+ in order for the Advanced Linux Sound Architecture (ALSA) to build. @@ -105,11 +107,12 @@ in order for the Advanced Linux Sound Architecture (ALSA) to build. Install CMake ============= -If you use Ubuntu 18.04+ you can install CMake with apt: +If you use Ubuntu 18.04+ or Fedora you can install CMake with apt/dnf: .. code-block:: bash - sudo apt-get install cmake + sudo apt-get install cmake # Ubuntu + sudo dnf install cmake # Fedora For Ubuntu 16.04, CMake from apt is outdated and you must install CMake from sources. Refer to this short guide: https://cmake.org/install/. @@ -143,7 +146,8 @@ before you configure alsa-utils. .. code-block:: bash - sudo apt-get install libfftw3-dev libfftw3-doc + sudo apt-get install libfftw3-dev libfftw3-doc # Ubuntu + sudo dnf install fftw3-devel # Fedora Clone, build, and install alsa-utils. @@ -234,7 +238,7 @@ download gcc components. .. code-block:: bash unset LD_LIBRARY_PATH - + # Bay Trail / Cherry Trail cp config-byt-gcc10.2-gdb9 .config ./ct-ng build From 81345c613827d1b56c6e24fdd8b86f2931c46b05 Mon Sep 17 00:00:00 2001 From: Andrey Borisovich Date: Tue, 9 Aug 2022 18:44:49 +0200 Subject: [PATCH 036/150] getting_started/build-guide: update Build SOF with zephyr Introduction of west tool to SOF project required to update build guide on how to use python convenience script and west tool. Signed-off-by: Andrey Borisovich --- .../build-guide/build-with-zephyr.rst | 258 +++++++++++++----- 1 file changed, 193 insertions(+), 65 deletions(-) diff --git a/getting_started/build-guide/build-with-zephyr.rst b/getting_started/build-guide/build-with-zephyr.rst index 3a54092e..998b3924 100755 --- a/getting_started/build-guide/build-with-zephyr.rst +++ b/getting_started/build-guide/build-with-zephyr.rst @@ -12,108 +12,217 @@ This guide describes how to build and run |SOF| as a Zephyr application. .. note:: The following example uses ``$ZEPHYR_WORKSPACE`` as the working - directory. + directory for both SOF and Zephyr projects. Prepare ******* -The easiest way to build Zephyr is to use its recommended toolchain. Follow -instructions in `Install a Toolchain `_ for details. +- The easiest way to build Zephyr is to use its recommended toolchain. Follow + instructions in `Install a Toolchain `_ for details. -Check out and build -******************* +- Install **west** - Zephyr uses west as a source management and building system. Follow + the Zephyr `Getting Started `_ guide for dependencies and for the west installation. -#. Install **west**. - Zephyr uses west as a source management and building system. Follow - the Zephyr `Getting Started `_ guide for dependencies and for the west installation. +Clone and initialize SOF project +******************************** - .. note:: +Initialize west manifest ``$ZEPHYR_WORKSPACE/sof/west.yml`` using ``west tool``: - If you need a different SOF version than the one that west - automatically checks out, instructions below show how to change ``modules/audio/sof`` - and select your preferred version. You need at least Zephyr version 1.6 to use - it with Zephyr. Make sure you branch or tag your code in git; - otherwise, a future ``west update`` may lose it. See the west user - guide. + - Clone SOF repository -#. Initialize a new ``west`` repository. This checks out all Zephyr sources, - including SOF: + .. code-block:: bash + + mkdir $ZEPHYR_WORKSPACE && cd $ZEPHYR_WORKSPACE + west init -m https://github.com/thesofproject/sof + + - Or initialize west manifest from existing SOF clone (when using python convenience script this is not mandatory - see below) + + .. code-block:: bash + + cd $ZEPHYR_WORKSPACE + west init -l ./sof + + + .. tip:: + | Zephyr project also uses west manifest. It may happen that your west tool is already initialized to manifest of zephyr. + | During initialization west will issue following error: + | *"FATAL ERROR: already initialized in $ZEPHYR_WORKSPACE, aborting."* + | + | To verify manifest currently used by west tool, in ``$ZEPHYR_WORKSPACE`` directory execute command: + | ``west config -l``. + | + | If command output shows: + | *manifest.path=zephyr* + | *manifest.file=west.yml* + | You need to remove ``$ZEPHYR_WORKSPACE/.west`` directory and reinitialize west in on of two methods described above. + + .. danger:: + | SOF project **must** be cloned to "sof" directory - this name is hardcoded in west manifest file! + | Failure to do so may result in SOF dependencies being cloned to newly created ``$ZEPHYR_WORKSPACE/sof/rimage`` directory + | along with other not desired consequences. + + **All commands described in the guide from this point should be executed in ``$ZEPHYR_WORKSPACE`` directory.** + + +Check out and build using python convenience script +*************************************************** + +| SOF project offers python convenience script: ``./sof/scripts/xtensa-build-zephyr.py`` +| used to provide more friendly build process for end-user. +| It is a wrapper for a **west tool** that performs steps described in `Check out and build using West Tool directly `_ section. +| Script may be used on both Windows and Linux operating systems. +| It will be removed in future as soon as SOF project will have better integration with **west tool** commands. + +Script automates following steps that are required to build a firmware for SOF platform: + - Initializes your west tool to SOFs west manifest + - Clones and checks out SOF and Zephyr dependencies + - Builds a firmware ``.elf`` file for requested platform + - Builds a **rimage tool** + - Uses **rimage tool** and a **private key** to sign the ``.elf`` file producing final firmware image file with ``.ri`` extension. + - Uses **smex tool** to generate a debugging symbols file with ``.ldc`` extension. + +| List of platforms that may be built with the script is shown in the help message: +| ``./sof/scripts/xtensa-build-zephyr.py --help`` + +Usage example 1: + You cloned SOF project and would like to build a firmware for *Tigerlake* platform. .. code-block:: bash - west init $ZEPHYR_WORKSPACE - # Significantly smaller and faster than a full "west update" - cd $ZEPHYR_WORKSPACE - west update hal_xtensa sof + ./sof/scripts/xtensa-build-zephyr.py -u tgl -#. Make sure the appropriate Zephyr SDK or other toolchain of your - choice can be found for your desired ``--board`` and that every - other Zephyr dependency is set up properly: + Running this command will: + + - Initialize west to ``./sof/west.yml`` manifest is not already initialized. + - Clone and checkout projects to revision defined in ``./sof/west.yml`` file: + + - SOFs submodules (Rimage and Tomlc99) + - Zephyr project + - Zephyr project dependencies needed by SOF in ``$ZEPHYR_WORKSPACE/modules`` directory + + - Build a signed firmware image ``./build-tgl/zephyr/zephyr.ri`` and debug symbols file ``./build-sof-staging/sof/sof-tgl.ldc``. + + .. tip:: + You may wish to rebuild all files from scratch. + To do this, add ``-p`` flag to script invocation. + To provide better build verbosity, use ``-v`` flag. + Make sure to check script ``--help`` to see all build options. + +Usage example 2: + You have your environment set up - cloned SOF project and working on your fork/branch of Zephyr and Rimage submodule. + You wish to build *Tigerlake* platform with your changes. .. code-block:: bash - ls zephyr/boards/xtensa/ - west build --board intel_adsp_cavs25 ./zephyr/samples/subsys/audio/sof/ + ./sof/scripts/xtensa-build-zephyr.py tgl + + Running this command will: + - Initialize west to ``./sof/west.yml`` manifest is not already initialized. + - Build a signed firmware image ``./build-tgl/zephyr/zephyr.ri`` and debug symbols file ``./build-sof-staging/sof/sof-tgl.ldc``. + - Skip cloning dependencies and checking them out to revision from ``./sof/west.yml`` manifest. + +Usage example 3: + You have your environment set up - cloned SOF project and working on your fork/branch of Zephyr and Rimage submodule. + You wish to restore default revisions for SOF dependencies from ``./sof/west.yml`` manifest. + + .. code-block:: bash + + ./sof/scripts/xtensa-build-zephyr.py -u + + - Initialize west to ``./sof/west.yml`` manifest is not already initialized. + - Clone and checkout projects to revisions defined in ``./sof/west.yml`` file. + - Skip building firmware image. + +Output directory + For convenience, the ``xtensa-build-zephyr.py`` script copies all + firmware files into a single, "staging" directory: + + .. code-block:: bash - For now the ``.elf`` file produced by ``west build`` is missing a - manifest and signature. The wrapper script below invokes *both* - ``west build`` and ``west sign`` and produces a complete ``.ri`` - file; you won't need to call ``west build`` again. + $ tree build-sof-staging/ -#. Fetch and switch to the latest SOF code + build-sof-staging/ + ├── sof + │   ├── community + │   │   ├── sof-apl.ri + │   │   ├── sof-imx8.ri + │   │   └── sof-tgl-h.ri - By policy, zephyr modules are carefully versioned with west and not - automatically synchronized with the latest code. To switch to the - latest: + +Check out and build using West Tool directly +******************************************** + +#. Clone and check out SOF dependencies - submodules, Zephyr project and some of its modules needed by SOF: .. code-block:: bash - cd modules/audio/sof/ - git remote add sof https://github.com/thesofproject/sof - git fetch sof - git switch --track sof/main + west update - # If needed, correct submodule URLs in .git/config with latest .gitmodules file. - git submodule sync --recursive - # Download submodules - git submodule update --init --recursive + .. warning:: + This command will check out revisions specified in ``$ZEPHYR_WORKSPACE/sof/west.yml`` file for projects: + - Rimage (SOF submodule) + - Tomlc99 (Rimage submodule) + - Zephyr + - projects in ``$ZEPHYR_WORKSPACE/modules`` directory. - Alternatively, feel free to delete the ``sof`` clone downloaded by - ``west`` and replace it with any other ``sof`` clone you already - have; west will automatically adjust. + Make sure to backup your work before changing revisions! + It will not affect your SOF project revision. -#. Build and sign a firmware image: +#. Build a board - make sure the appropriate Zephyr SDK or other toolchain of your + choice. Boards to build are listed in ``$ZEPHYR_WORKSPACE/sof/app/boards`` directory. .. code-block:: bash - cd $ZEPHYR_WORKSPACE - ./modules/audio/sof/scripts/xtensa-build-zephyr.sh -h # shows usage - ./modules/audio/sof/scripts/xtensa-build-zephyr.sh $your_platforms - ls build-*/zephyr/zephyr.* - => build-*/zephyr/zephyr.ri ... + west build --build-dir build-tgl --board intel_adsp_cavs25 ./sof/app + .. hint:: + SOF project defines platform names that have Zephyr board counterpart. + In this example platform *Tigerlake* matches Zephyr board *inteL_adsp_cavs25* + (this is why output directory is named *build-tgl* however you may use any name you wish). -There is work in progress to substitute ``xtensa-build-zephyr.sh`` with -a Python replacement ``xtensa-build-zephyr.py`` for Windows -compatibility. It can already be used in many cases. + .. tip:: + - To add verbosity to the build output use -v -v flags. Example: + ``west -v -v build --build-dir build-tgl --board intel_adsp_cavs25 ./sof/app`` -Run -*** + - To perform complete clean rebuild use --pristine flag. Example: + ``west -v -v build --build-dir build-tgl --pristine always --board intel_adsp_cavs25 ./sof/app`` -For convenience, the ``xtensa-build-zephyr.sh`` script copies all -firmware files into a single, "staging" directory: + ``.elf`` file produced by ``west build`` is missing a + manifest and signature. You need to sign the file using **rimage tool** + and a **private key** to generate final firmware image (``.ri`` file). + +#. Build rimage tool .. code-block:: bash - $ tree build-sof-staging/ + cmake -B ./build-rimage -S ./sof/rimage + cmake --build ./build-rimage + +#. Sign firmware using rimage tool and a private key + + .. code-block:: bash + + west sign --build-dir ./build-tgl -t rimage --tool-path ./build-rimage/rimage --tool-data ./sof/rimage/config -- -k ./sof/keys/otc_private_key_3k.pem + + **Signed output firmware image file is** ``./build-tgl/zephyr/zephyr.ri`` **.** + + .. hint:: + SOF project provides some pre-generated key pairs of different lengths: + - ``./sof/keys/otc_private_key_3k.pem`` + ``./sof/keys/otc_public_key_3k.pem`` + - ``./sof/keys/otc_private_key.pem`` + ``./sof/keys/otc_public_key.pem`` + + You may wish to generate your own set of keys for firmware signing. + +#. (Optional) Generate debug symbols - build-sof-staging/ - ├── sof - │   ├── community - │   │   ├── sof-apl.ri - │   │   ├── sof-imx8.ri - │   │   └── sof-tgl-h.ri + .. code-block::bash + ./build-tgl/zephyr/smex_ep/build/smex -l ./build-tgl/zephyr/zephyr.ldc ./build-tgl/zephyr/zephyr.elf + + Output file ``./build-tgl/zephyr/zephyr.ldc`` may be used for reading firmware logs. + +Run +*** #. Copy the firmware image(s) to the usual location on all your target systems. Example: @@ -155,3 +264,22 @@ For firmware log extraction, use You might also need to build and update your system audio topology file. For details see :ref:`build-from-scratch`. + + +Troubleshooting +*************** + +#. West tool version is older than minimal version requirement defined in ``./sof/west.yml`` manifest. + + | Manifest file defines minimal yaml schema version that sets compatibility with west tool + | according to https://docs.zephyrproject.org/latest/develop/west/manifest.html#version . + | If west tools version is not sufficient to process manifest file, west raises not very user-friendly + | exception (reference to west 0.12.0 for Windows): + + .. code-block:: bash + + west.manifest.ManifestVersionError: ('0.13', WindowsPath('$ZEPHYR_WORKSPACE/.west/manifest-tmp/west.yml')) + + | In this example ``./sof/west.yml`` defines minimal version as ``0.13`` while west tool used has version ``0.12.0``. + | Update your west tool to newer version to proceed. + From 1a699cf0b5e96c85b2d360156b274f21abd00fb8 Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Tue, 16 Aug 2022 10:46:15 +0000 Subject: [PATCH 037/150] Add missing code-block:: types Fixes many warnings found by sphinx 1.8.5 and likely other versions. Don't forget to "make clean" so see all warnings. Signed-off-by: Marc Herbert --- contribute/doc_guidelines.rst | 2 +- developer_guides/topology/topology.rst | 6 +++--- getting_started/intel_debug/introduction.rst | 4 ++-- getting_started/intel_debug/suggestions.rst | 18 +++++++++--------- .../setup_linux/setup_ktest_environment.rst | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/contribute/doc_guidelines.rst b/contribute/doc_guidelines.rst index f2aa0d96..caee341b 100644 --- a/contribute/doc_guidelines.rst +++ b/contribute/doc_guidelines.rst @@ -386,7 +386,7 @@ the first non-white space in the preceding line. For example: 1. And for numbered list items, the continuation line should align with the text of the line above. - .. code-block:: + .. code-block:: none The text within a directive block should align with the first character of the directive name. diff --git a/developer_guides/topology/topology.rst b/developer_guides/topology/topology.rst index 0f9b04a3..3e2a23af 100644 --- a/developer_guides/topology/topology.rst +++ b/developer_guides/topology/topology.rst @@ -303,7 +303,7 @@ be scheduled. To specify the DSP core for a pipeline, use the SOF_TKN_SCHED_CORE token located in tools/topology/m4/pipeline.m4: -.. code-block:: +.. code-block:: none W_PIPELINE(stream, period, priority, core, initiator, platform) ... @@ -313,14 +313,14 @@ located in tools/topology/m4/pipeline.m4: Then specify this 'core' in your pipeline definition, such as in tools/topology/sof/pipe-dai-playback.m4: -.. code-block:: +.. code-block:: none W_PIPELINE(N_DAI_OUT, SCHEDULE_PERIOD, SCHEDULE_PRIORITY, SCHEDULE_CORE, SCHEDULE_TIME_DOMAIN, pipe_dai_schedule_plat) To specify the DSP core for a component/widget, use the SOF_TKN_COMP_CORE_ID token located in tools/topology/m4/pga.m4: -.. code-block:: +.. code-block:: none dnl W_PGA(name, format, periods_sink, periods_source, core, kcontrol0. kcontrol1...etc) ... diff --git a/getting_started/intel_debug/introduction.rst b/getting_started/intel_debug/introduction.rst index f07807bc..9842ca1c 100644 --- a/getting_started/intel_debug/introduction.rst +++ b/getting_started/intel_debug/introduction.rst @@ -71,7 +71,7 @@ The ``snd-intel-dspcfg`` module introduced in early 2020 exposes an API used by all drivers, and the user can now override default choices by setting the ``dsp_driver`` parameter. For example, setting -.. code-block:: +.. code-block:: cfg options snd-intel-dspcfg dsp_driver=1 @@ -83,7 +83,7 @@ Conversely, when a platform does not require a DSP-based platform, but the DSP is still enabled by the OEM, the user or integration can force the SOF Linux driver to be used. -.. code-block:: +.. code-block:: cfg options snd-intel-dspcfg dsp_driver=3 diff --git a/getting_started/intel_debug/suggestions.rst b/getting_started/intel_debug/suggestions.rst index 4a24c855..68541bc7 100644 --- a/getting_started/intel_debug/suggestions.rst +++ b/getting_started/intel_debug/suggestions.rst @@ -58,7 +58,7 @@ issues are possible. Use the following commands to check if the SOF driver is functional at the hardware device level: -.. code-block:: +.. code-block:: console speaker-test -Dhw:0,0 -c2 -r48000 -f S16_LE arecord -Dhw:0,0 -c2 -r48000 -f S16_LE -d 10 test.wav @@ -95,7 +95,7 @@ may not be enough to debug a specific issue, and the recommendation is to add the following options to the ``/etc/modprobe.d/sof-dyndbg.conf`` file: -.. code-block:: +.. code-block:: cfg options snd_sof_intel_byt dyndbg=+p options snd_sof_intel_bdw dyndbg=+p @@ -137,7 +137,7 @@ Trace support might need to be enabled on distribution kernels in case the ``/sys/kernel/debug/sof/trace`` file is not present by adding sof_debug=1 option to snd_sof module: -.. code-block:: +.. code-block:: cfg options snd_sof sof_debug=1 @@ -152,7 +152,7 @@ On devices designed for Windows, the presence of the microphone is reported as an NHLT endpoint (ACPI table in the BIOS). The SOF Linux driver will report this information with a 'dmesg' log such as -.. code-block:: +.. code-block:: none [ 4.301490] sof-audio-pci-intel-tgl 0000:00:1f.3: DMICs detected in NHLT tables: 2 @@ -165,7 +165,7 @@ the value with a kernel parameter which can be added in /etc/modprobe.d/alsa-base.conf (or any other configuration file with this .conf extension). A reboot is necessary after changing the value -.. code-block:: +.. code-block:: cfg options snd_sof_intel_hda_common dmic_num=4 @@ -191,7 +191,7 @@ necessary to override the file installed in 5.20+ a kernel parameter will be enough with no need to change and override installed topology files, e.g. -.. code-block:: +.. code-block:: cfg options snd-sof-pci tplg_filename=sof-hda-generic-2ch-pdm1.tplg @@ -219,11 +219,11 @@ End-users can verify if the hardware uses this configuration by running the 'alsa-info' command and checking for the presence an ACPI _HID, e.g. -.. code-block:: +.. code-block:: none /sys/bus/acpi/devices/ESSX8336:00/status 15 -.. code-block:: +.. code-block:: none /sys/bus/acpi/devices/ESSX8326:00/status 15 @@ -260,7 +260,7 @@ added with the following option in e.g. /etc/modprobe.d/alsa-base.conf. Only the bits listed above can be modified, others need to be kept as is. -.. code-block:: +.. code-block:: cfg options snd_soc_sof_es8336 quirk= diff --git a/getting_started/setup_linux/setup_ktest_environment.rst b/getting_started/setup_linux/setup_ktest_environment.rst index 37dddda3..4ab236b5 100644 --- a/getting_started/setup_linux/setup_ktest_environment.rst +++ b/getting_started/setup_linux/setup_ktest_environment.rst @@ -65,7 +65,7 @@ Set up a target d) Update the grub configuration. - .. code-block:: + .. code-block:: console sudo update-grub From 285d2d9e42597642ec5b1919333eba9d6f71e7e6 Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Tue, 16 Aug 2022 10:43:38 +0000 Subject: [PATCH 038/150] Finally document how to achieve instant builds Without instant builds there is no drive-by contributor submitting quick fixes. Also update requirements-lax.txt to request sphinxcontrib.plantuml>=0.11,<0.25 - Version 0.11 is the first version that supports plantuml_output_format=none which makes the build at least 15 times faster. https://pypi.org/project/sphinxcontrib-plantuml/0.11/ - 0.24 is the last version successfully tested with PIP_IGNORE_INSTALLED=0 and Ubuntu 20.04 (see .github/worflows/) Signed-off-by: Marc Herbert --- Makefile | 5 ++++- conf.py | 9 +++++++-- scripts/requirements-lax.txt | 16 +++++++++++++++- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 52fed184..64785f0d 100644 --- a/Makefile +++ b/Makefile @@ -44,8 +44,11 @@ apidocs: ifeq (${APIS_CMAKE},$(wildcard ${APIS_CMAKE})) ninja -C ${SOF_DOC_BUILD} $${VERBOSE:+-v} doc else - # To build doxygen APIs too run this first: + # To include doxygen APIs run this first: # cmake -GNinja -S ../sof/doc -B ${SOF_DOC_BUILD} + # Note this will make the build CONSIDERABLY LONGER! + # Conversely, you can have _instant builds from scratch_ + # by disabling UML diagrams in the conf.py file. endif html: apidocs diff --git a/conf.py b/conf.py index fa9c4429..b57e4291 100755 --- a/conf.py +++ b/conf.py @@ -45,8 +45,13 @@ plantuml = 'java -jar ' + os.path.join(os.path.abspath('.'), 'scripts/plantuml.jar') \ + ' -config ' + os.path.join(os.path.abspath('.'), 'scripts/plantuml.cfg') -# Temporarily set this to "none" for a build without diagrams but ~= 15 -# times faster from scratch. +# More than half of the time building from scratch is consumed by the +# sphinx extension "breathe" that converts doxygen XML. Most of the rest +# is consumed by plantUML here. So you can set the variable below to +# 'none' for an _almost instant_ sphinx build! (with zero UML diagram +# and no doxygen). 'none' requires sphinxcontrib.plantuml>=0.11 but +# pre-0.11 errors can be ignored. (of course don't disable UML when +# you're touching UML stuff) plantuml_output_format = 'svg' # Add any paths that contain templates here, relative to this directory. diff --git a/scripts/requirements-lax.txt b/scripts/requirements-lax.txt index 64c9b91c..b6cb59af 100644 --- a/scripts/requirements-lax.txt +++ b/scripts/requirements-lax.txt @@ -13,7 +13,21 @@ breathe>=4.7.3 sphinx>=1.6.7 docutils>=0.14 sphinx_rtd_theme>=0.2.4 -sphinxcontrib-plantuml + +# - Version 0.11 is the first version that supports +# `plantuml_output_format=none` which is required for instant builds. +# https://pypi.org/project/sphinxcontrib-plantuml/0.11/ +# +# - 0.24 is the last version successfully tested with +# PIP_IGNORE_INSTALLED=0 and Ubuntu 20.04 (see .github/worflows/) +# +# - Note 0.9 is the minimum to fix this fatal import failure: +# +# sphinx.util.compat.Directive class is now deprecated. Please +# use instead docutils.parsers.rst.Directive +# +# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=896485#12 +sphinxcontrib.plantuml>=0.11,<0.25 # Differences between these "lax" version requirements and the official From 9f42ccbfdc97cbf5675df3d735f833c9b80372dd Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Thu, 9 Jun 2022 00:01:48 +0000 Subject: [PATCH 039/150] .github: upgrade LAX environment to Ubuntu 22.04 Unlike scripts/requirements.txt, the purpose of scripts/requirements-lax.txt is to run the latest and greatest. Signed-off-by: Marc Herbert --- .github/workflows/pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 1437ec59..5ad42d65 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -102,7 +102,7 @@ jobs: lax: name: "PIP_IGNORE_INSTALLED=0 requirements-lax.txt" - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 # Makefile downgrades the Sphinx warnings, they are not errors any more env: {LAX: 1} steps: From 3b65ca297748ad21ff1cc7f25fb7966e12fc16bf Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Wed, 17 Aug 2022 08:56:23 -0700 Subject: [PATCH 040/150] Toolchains build: replace `cd` with `git -C`; minor simplification No need to change directory to run a single git command. This makes the "script" shorter and "more stateless". Signed-off-by: Marc Herbert --- getting_started/build-guide/build-from-scratch.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/getting_started/build-guide/build-from-scratch.rst b/getting_started/build-guide/build-from-scratch.rst index 2cc602e2..5d2d2103 100755 --- a/getting_started/build-guide/build-from-scratch.rst +++ b/getting_started/build-guide/build-from-scratch.rst @@ -212,15 +212,14 @@ Clone both repos and check out the ``sof-gcc10.2`` and ``sof-gcc10x`` branch. cd "$SOF_WORKSPACE" git clone https://github.com/thesofproject/xtensa-overlay git clone https://github.com/thesofproject/crosstool-ng - cd xtensa-overlay - git checkout sof-gcc10.2 - cd ../crosstool-ng - git checkout sof-gcc10x + git -C xtensa-overlay/ checkout sof-gcc10.2 + git -C crosstool-ng/ checkout sof-gcc10x Build crosstool-ng and install it in its own source directory. .. code-block:: bash + cd crosstool-ng/ ./bootstrap ./configure --prefix=$(pwd) make From f89312a460396770d5ee0bafb4fa4920a1caf4f2 Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Wed, 17 Aug 2022 09:29:09 -0700 Subject: [PATCH 041/150] Toolchains build: replace ./ct-ng copy/paste with a `for` loop Copy/paste/diverge, still alive and well in 2022. Signed-off-by: Marc Herbert --- .../build-guide/build-from-scratch.rst | 54 ++++++++----------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/getting_started/build-guide/build-from-scratch.rst b/getting_started/build-guide/build-from-scratch.rst index 5d2d2103..aefcbdb8 100755 --- a/getting_started/build-guide/build-from-scratch.rst +++ b/getting_started/build-guide/build-from-scratch.rst @@ -231,31 +231,33 @@ Toolchains The config files provided refer to ``../xtensa-overlay/`` and point at different ``./builds/xtensa-*-elf`` subdirectories. Copy the ones you want to ``.config`` and build the cross-compiler(s) for your target -platform(s). Note that ``./ct-ng build`` requires an network connection to -download gcc components. +platform(s). Note that ``./ct-ng build`` requires an network connection +to download gcc components. While other steps take minutes at most, +building all toolchains may last about an hour depending on your network +connection and the performance of your system. .. code-block:: bash unset LD_LIBRARY_PATH - # Bay Trail / Cherry Trail - cp config-byt-gcc10.2-gdb9 .config - ./ct-ng build - # Haswell/Broadwell - cp config-hsw-gcc10.2-gdb9 .config - ./ct-ng build - # Apollo Lake - cp config-apl-gcc10.2-gdb9 .config - ./ct-ng build - # Cannon Lake, Ice Lake, Jasper Lake, and Tiger Lake - cp config-cnl-gcc10.2-gdb9 .config - ./ct-ng build - # i.MX8/i.MX8X - cp config-imx-gcc10.2-gdb9 .config - ./ct-ng build - # i.MX8M - cp config-imx8m-gcc10.2-gdb9 .config - ./ct-ng build + # byt = Bay Trail / Cherry Trail + # hsw = Haswell/Broadwell + # apl = Apollo Lake + # cnl = Cannon Lake, Ice Lake, Jasper Lake, and Tiger Lake + # imx = i.MX8/i.MX8X + # imx8m = i.MX8M + + # Omit the toolchains you don't want to save (a lot of) time + time for i in byt hsw apl cnl imx imx8m; do + cp config-$i-gcc10.2-gdb9 .config && + time ./ct-ng build || break + done + + # ... or just build all toolchains + time for i in config*gcc10.2-gdb9; do + cp "$i" .config && time ./ct-ng build || break + done + ``./ct-ng`` is a Linux kernel style Makefile; so the sample commands below can be used to fix some out of date ``config-*-gcc10.2-gdb9`` file or find @@ -268,18 +270,6 @@ default values missing from it: ./ct-ng oldconfig V=1 diff -u config-apl-gcc10.2-gdb9 .config -While other steps take minutes at most, building all toolchains may last -about an hour depending on the performance of your system. Run this loop -to build all toolchains without interruption: - -.. code-block:: bash - - unset LD_LIBRARY_PATH; - time for i in config*gcc10.2-gdb9; do - cp "$i" .config && ./ct-ng build || break ; - done - - "Install" toolchains in the expected location by linking from ``$SOF_WORKSPACE`` to them: From 5fc9896a751d8b06417d15f8db74c1e085928eca Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Wed, 17 Aug 2022 09:56:49 -0700 Subject: [PATCH 042/150] Toolchains build: rephrase optional PATH addition Fixes commit c4f0b1a067d4e ("Grammatical edits to build from scratch; small conf.py edit") Signed-off-by: Marc Herbert --- getting_started/build-guide/build-from-scratch.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/getting_started/build-guide/build-from-scratch.rst b/getting_started/build-guide/build-from-scratch.rst index aefcbdb8..55080327 100755 --- a/getting_started/build-guide/build-from-scratch.rst +++ b/getting_started/build-guide/build-from-scratch.rst @@ -311,9 +311,11 @@ switch to the `xtensa` branch. git checkout -b xtensa origin/xtensa Temporarily add toolchains to your PATH variable. This is *not* required -when using high-level scripts described below; it's only required here or -when invoking CMake manually. In other words, you don't need to adjust your -PATH permanently because no risk of interfere with non-SOF tasks exists. +when using the high-level, "every day" build scripts described in the +next sections. It's only required for this once-off ``newlib`` headers +step or when invoking CMake manually. In other words, you don't need to +change your PATH permanently which would interfere with other, non-SOF +work. .. code-block:: bash @@ -324,6 +326,7 @@ Build and install the newlib headers for each toolchain: .. code-block:: bash XTENSA_ROOT="${SOF_WORKSPACE}"/xtensa-root + cd "${SOF_WORKSPACE}"/newlib-xtensa time for toolchain in ../xtensa-*-elf; do ./configure --target="${toolchain#../}" --prefix="$XTENSA_ROOT" && make && make install || break; From 07f723d24ed4a41c29f06c95da0b964943f68ae3 Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Wed, 17 Aug 2022 12:43:57 -0700 Subject: [PATCH 043/150] git clone --recursive submodule https://github.com/thesofproject/sof Now that the Zephyr build has been migrated to west by PR #6005, we should remove the recursive cloning hack in CMake. Downloading and building must be kept separate. Signed-off-by: Marc Herbert --- getting_started/build-guide/build-from-scratch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting_started/build-guide/build-from-scratch.rst b/getting_started/build-guide/build-from-scratch.rst index 55080327..fa49ef08 100755 --- a/getting_started/build-guide/build-from-scratch.rst +++ b/getting_started/build-guide/build-from-scratch.rst @@ -355,7 +355,7 @@ After the SOF environment is set up, clone the *sof* repo: .. code-block:: bash cd "$SOF_WORKSPACE" - git clone https://github.com/thesofproject/sof + git clone --recursive https://github.com/thesofproject/sof cd sof From ebf3f1b0bd33a17f575ee81342ee27119a298648 Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Wed, 17 Aug 2022 12:54:47 -0700 Subject: [PATCH 044/150] Add -j 4 example to "make -C installer" example The test says the build is parallel and fast but the example was not. Signed-off-by: Marc Herbert --- getting_started/build-guide/build-from-scratch.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/getting_started/build-guide/build-from-scratch.rst b/getting_started/build-guide/build-from-scratch.rst index fa49ef08..4c0519af 100755 --- a/getting_started/build-guide/build-from-scratch.rst +++ b/getting_started/build-guide/build-from-scratch.rst @@ -365,7 +365,10 @@ optional target hostname in the latter file. Then run the installer: .. code-block:: bash - make -C installer/ + make -C installer/ [ -j 4 ] + +Adjust the ``-j 4`` example to your number of CPU cores or remove it +when the build fails. This builds multiple platforms in parallel and deploys firmware and topologies to ``/lib/firmware/intel/`` on the local or remote From 2eb8aa7bcc364a7907daec17f886d277db8a9112 Mon Sep 17 00:00:00 2001 From: Deb Date: Fri, 19 Aug 2022 09:27:26 -0600 Subject: [PATCH 045/150] Grammar and style updates to SOF-Zephyr file Signed-off-by: Deb --- .../build-guide/build-with-zephyr.rst | 168 ++++++++---------- 1 file changed, 75 insertions(+), 93 deletions(-) diff --git a/getting_started/build-guide/build-with-zephyr.rst b/getting_started/build-guide/build-with-zephyr.rst index 998b3924..781dc920 100755 --- a/getting_started/build-guide/build-with-zephyr.rst +++ b/getting_started/build-guide/build-with-zephyr.rst @@ -17,25 +17,24 @@ This guide describes how to build and run |SOF| as a Zephyr application. Prepare ******* -- The easiest way to build Zephyr is to use its recommended toolchain. Follow - instructions in `Install a Toolchain `_ for details. +- The easiest way to build Zephyr is to use its recommended toolchain which is included in its SDK. Refer to `Install Zephyr SDK `_ for details. -- Install **west** - Zephyr uses west as a source management and building system. Follow +- Install **west**. Zephyr uses west as a source management and building system. Follow the Zephyr `Getting Started `_ guide for dependencies and for the west installation. Clone and initialize SOF project ******************************** -Initialize west manifest ``$ZEPHYR_WORKSPACE/sof/west.yml`` using ``west tool``: +Initialize the west manifest ``$ZEPHYR_WORKSPACE/sof/west.yml`` using the ``west tool``: - - Clone SOF repository + - Clone the SOF repository: .. code-block:: bash mkdir $ZEPHYR_WORKSPACE && cd $ZEPHYR_WORKSPACE west init -m https://github.com/thesofproject/sof - - Or initialize west manifest from existing SOF clone (when using python convenience script this is not mandatory - see below) + - Or initialize the west manifest from the existing SOF clone. Note that when using the Python convenience script, as described in the next section, this is not mandatory. .. code-block:: bash @@ -43,49 +42,43 @@ Initialize west manifest ``$ZEPHYR_WORKSPACE/sof/west.yml`` using ``west tool``: west init -l ./sof - .. tip:: - | Zephyr project also uses west manifest. It may happen that your west tool is already initialized to manifest of zephyr. - | During initialization west will issue following error: + .. note:: + | Since the Zephyr project also uses the west manifest, your west tool might already be initialized to manifest Zephyr. In this case, west issues the following error during initialization: | *"FATAL ERROR: already initialized in $ZEPHYR_WORKSPACE, aborting."* | - | To verify manifest currently used by west tool, in ``$ZEPHYR_WORKSPACE`` directory execute command: + | To verify that the manifest is currently used by the west tool, execute the following command from the ``$ZEPHYR_WORKSPACE`` directory: | ``west config -l``. | - | If command output shows: + | If command output shows the following, remove the ``$ZEPHYR_WORKSPACE/.west`` directory and reinitialize the west manifest using one of the two methods described above: | *manifest.path=zephyr* | *manifest.file=west.yml* - | You need to remove ``$ZEPHYR_WORKSPACE/.west`` directory and reinitialize west in on of two methods described above. - .. danger:: - | SOF project **must** be cloned to "sof" directory - this name is hardcoded in west manifest file! - | Failure to do so may result in SOF dependencies being cloned to newly created ``$ZEPHYR_WORKSPACE/sof/rimage`` directory - | along with other not desired consequences. + .. important:: + The SOF project **must** be cloned to the ``sof`` directory because this name is hardcoded in the west manifest file. Failure to do so may result in SOF dependencies being cloned into a newly created ``$ZEPHYR_WORKSPACE/sof/rimage`` directory along with other undesirable consequences. - **All commands described in the guide from this point should be executed in ``$ZEPHYR_WORKSPACE`` directory.** + **All commands described in the guide from this point should be executed from the $ZEPHYR_WORKSPACE directory.** -Check out and build using python convenience script +Check out and build using Python convenience script *************************************************** -| SOF project offers python convenience script: ``./sof/scripts/xtensa-build-zephyr.py`` -| used to provide more friendly build process for end-user. -| It is a wrapper for a **west tool** that performs steps described in `Check out and build using West Tool directly `_ section. -| Script may be used on both Windows and Linux operating systems. -| It will be removed in future as soon as SOF project will have better integration with **west tool** commands. - -Script automates following steps that are required to build a firmware for SOF platform: - - Initializes your west tool to SOFs west manifest - - Clones and checks out SOF and Zephyr dependencies - - Builds a firmware ``.elf`` file for requested platform - - Builds a **rimage tool** - - Uses **rimage tool** and a **private key** to sign the ``.elf`` file producing final firmware image file with ``.ri`` extension. - - Uses **smex tool** to generate a debugging symbols file with ``.ldc`` extension. - -| List of platforms that may be built with the script is shown in the help message: +The SOF project offers a Python convenience script, ``./sof/scripts/xtensa-build-zephyr.py``, that provides a friendly build process for the end user. It is a wrapper for a **west tool** that performs steps described in the `Check out and build using west tool directly`_ section below. + +This script can be used on both Windows and Linux operating systems. Note that it will be removed when the SOF project creates better integration with west tool commands. + +The script automates the following steps that are required to build firmware for the SOF platform: + - Initializes your west tool to SOF's west manifest. + - Clones and checks out SOF and Zephyr dependencies. + - Builds a firmware ``.elf`` file for the requested platform. + - Builds a **rimage tool**. + - Uses the **rimage tool** and a **private key** to sign the ``.elf`` file. It produces a final firmware image file with the ``.ri`` extension. + - Uses the **smex tool** to generate debugging symbols file with the ``.ldc`` extension. + +| A list of platforms that can be built with the script is shown in this help message: | ``./sof/scripts/xtensa-build-zephyr.py --help`` Usage example 1: - You cloned SOF project and would like to build a firmware for *Tigerlake* platform. + You cloned the SOF project and you want to build firmware for the *Tigerlake* platform. .. code-block:: bash @@ -93,8 +86,8 @@ Usage example 1: Running this command will: - - Initialize west to ``./sof/west.yml`` manifest is not already initialized. - - Clone and checkout projects to revision defined in ``./sof/west.yml`` file: + - Initialize west to the ``./sof/west.yml`` manifest if it is not already initialized. + - Clone and check out projects to the revision defined in the ``./sof/west.yml`` file: - SOFs submodules (Rimage and Tomlc99) - Zephyr project @@ -102,40 +95,38 @@ Usage example 1: - Build a signed firmware image ``./build-tgl/zephyr/zephyr.ri`` and debug symbols file ``./build-sof-staging/sof/sof-tgl.ldc``. - .. tip:: - You may wish to rebuild all files from scratch. - To do this, add ``-p`` flag to script invocation. - To provide better build verbosity, use ``-v`` flag. - Make sure to check script ``--help`` to see all build options. + .. note:: + You may wish to rebuild all files from scratch. To do this, add a ``-p`` flag to the script invocation. To provide better build verbosity, use the ``-v`` flag. Make sure to check ``--help`` to see all build options. Usage example 2: - You have your environment set up - cloned SOF project and working on your fork/branch of Zephyr and Rimage submodule. - You wish to build *Tigerlake* platform with your changes. + Your environment is set up as a cloned SOF project and you are working on a fork/branch of the Zephyr and Rimage submodules. You want to build a *Tigerlake* platform with your changes. .. code-block:: bash ./sof/scripts/xtensa-build-zephyr.py tgl Running this command will: - - Initialize west to ``./sof/west.yml`` manifest is not already initialized. + + - Initialize west to the ``./sof/west.yml`` manifest if it is not already initialized. - Build a signed firmware image ``./build-tgl/zephyr/zephyr.ri`` and debug symbols file ``./build-sof-staging/sof/sof-tgl.ldc``. - - Skip cloning dependencies and checking them out to revision from ``./sof/west.yml`` manifest. + - Skip cloning dependencies and check them out to revisions from the ``./sof/west.yml`` manifest. Usage example 3: - You have your environment set up - cloned SOF project and working on your fork/branch of Zephyr and Rimage submodule. - You wish to restore default revisions for SOF dependencies from ``./sof/west.yml`` manifest. + Your environment is set up as a cloned SOF project and you are working on a fork/branch of the Zephyr and Rimage submodules. You want to restore default revisions for SOF dependencies from the ``./sof/west.yml`` manifest. .. code-block:: bash ./sof/scripts/xtensa-build-zephyr.py -u - - Initialize west to ``./sof/west.yml`` manifest is not already initialized. - - Clone and checkout projects to revisions defined in ``./sof/west.yml`` file. - - Skip building firmware image. + Running this command will: + + - Initialize west to the ``./sof/west.yml`` manifest if it is not already initialized. + - Clone and checkout projects to revisions defined in the ``./sof/west.yml`` file. + - Skip building the firmware image. Output directory For convenience, the ``xtensa-build-zephyr.py`` script copies all - firmware files into a single, "staging" directory: + firmware files into a single, staging directory: .. code-block:: bash @@ -149,77 +140,74 @@ Output directory │   │   └── sof-tgl-h.ri -Check out and build using West Tool directly +Check out and build using west tool directly ******************************************** -#. Clone and check out SOF dependencies - submodules, Zephyr project and some of its modules needed by SOF: +#. Clone and check out SOF dependencies such as submodules, the Zephyr project, and some of its modules needed by SOF: .. code-block:: bash west update - .. warning:: - This command will check out revisions specified in ``$ZEPHYR_WORKSPACE/sof/west.yml`` file for projects: + .. important:: + This command will check out revisions specified in the ``$ZEPHYR_WORKSPACE/sof/west.yml`` file for the following projects: - Rimage (SOF submodule) - Tomlc99 (Rimage submodule) - Zephyr - projects in ``$ZEPHYR_WORKSPACE/modules`` directory. - Make sure to backup your work before changing revisions! - It will not affect your SOF project revision. + **Make sure you back up your work before changing revisions!** + This will not affect your SOF project revision. -#. Build a board - make sure the appropriate Zephyr SDK or other toolchain of your - choice. Boards to build are listed in ``$ZEPHYR_WORKSPACE/sof/app/boards`` directory. +#. Build a board. Make sure to use the appropriate Zephyr SDK or other toolchain of your choice. Boards to build are listed in the ``$ZEPHYR_WORKSPACE/sof/app/boards`` directory. .. code-block:: bash west build --build-dir build-tgl --board intel_adsp_cavs25 ./sof/app - .. hint:: - SOF project defines platform names that have Zephyr board counterpart. - In this example platform *Tigerlake* matches Zephyr board *inteL_adsp_cavs25* - (this is why output directory is named *build-tgl* however you may use any name you wish). + + Note that the SOF project defines platform names that have Zephyr board counterparts. In the above example, the *Tigerlake* platform matches the ``inteL_adsp_cavs25`` Zephyr board. This is why the output directory is named ``build-tgl``; however, you may use any name you wish. - .. tip:: - - To add verbosity to the build output use -v -v flags. Example: + .. note:: + To add verbosity to the build output use the -v -v flags. Example: ``west -v -v build --build-dir build-tgl --board intel_adsp_cavs25 ./sof/app`` - - To perform complete clean rebuild use --pristine flag. Example: + To perform a complete clean rebuild, use the --pristine flag. Example: ``west -v -v build --build-dir build-tgl --pristine always --board intel_adsp_cavs25 ./sof/app`` - ``.elf`` file produced by ``west build`` is missing a - manifest and signature. You need to sign the file using **rimage tool** - and a **private key** to generate final firmware image (``.ri`` file). + The ``.elf`` file produced by the ``west build`` is missing a + manifest and signature. A a result, you must sign the file using the **rimage tool** + and a **private key** to generate the final firmware image (``.ri`` file). -#. Build rimage tool +#. Build the rimage tool by running the following: .. code-block:: bash cmake -B ./build-rimage -S ./sof/rimage cmake --build ./build-rimage -#. Sign firmware using rimage tool and a private key +#. Sign the firmware using the rimage tool and a private key by running the following: .. code-block:: bash west sign --build-dir ./build-tgl -t rimage --tool-path ./build-rimage/rimage --tool-data ./sof/rimage/config -- -k ./sof/keys/otc_private_key_3k.pem - **Signed output firmware image file is** ``./build-tgl/zephyr/zephyr.ri`` **.** + **The signed output firmware image file is** ``./build-tgl/zephyr/zephyr.ri`` **.** - .. hint:: - SOF project provides some pre-generated key pairs of different lengths: + .. note:: + The SOF project provides some pre-generated key pairs of different lengths: - ``./sof/keys/otc_private_key_3k.pem`` + ``./sof/keys/otc_public_key_3k.pem`` - ``./sof/keys/otc_private_key.pem`` + ``./sof/keys/otc_public_key.pem`` You may wish to generate your own set of keys for firmware signing. -#. (Optional) Generate debug symbols +#. (Optional) Generate debug symbols. .. code-block::bash ./build-tgl/zephyr/smex_ep/build/smex -l ./build-tgl/zephyr/zephyr.ldc ./build-tgl/zephyr/zephyr.elf - Output file ``./build-tgl/zephyr/zephyr.ldc`` may be used for reading firmware logs. + The output file ``./build-tgl/zephyr/zephyr.ldc`` may be used for reading firmware logs. Run *** @@ -231,16 +219,14 @@ Run sudo rsync -a build-sof-staging/sof/ testsystemN.local:/lib/firmware/intel/sof/ - ``rsync`` also works locally and unlike ``cp -R`` it is always - idempotent. You may want to use the ``rsync -a --delete`` option to - make absolutely sure you're not running some older version but only - after backing up your original ``sof/`` directory first. The - ``--delete`` option is dangerous, use it only in very well tested + Note that ``rsync`` also works locally and, unlike ``cp -R``, it is always + idempotent. You may want to use the ``rsync -a --delete`` option to + make absolutely sure you're not running some older version, **but do so + only after first backing up your original sof/ directory**. The + ``--delete`` option is dangerous; use it only in very well-tested scripts. - Also make sure nothing in ``/lib/firmware/updates`` takes precedence, - see - https://www.kernel.org/doc/html/v5.5/driver-api/firmware/fw_search_path.html + Also make sure nothing in ``/lib/firmware/updates`` takes precedence. Refer to `Firmware search paths `_. #. Reboot the system. Note that the location and name of your SOF firmware image may vary by system. Search your kernel logs with @@ -266,20 +252,16 @@ You might also need to build and update your system audio topology file. For details see :ref:`build-from-scratch`. -Troubleshooting -*************** +Troubleshoot +************ -#. West tool version is older than minimal version requirement defined in ``./sof/west.yml`` manifest. +#. The west tool version is older than the minimal version requirement defined in the ``./sof/west.yml`` manifest. - | Manifest file defines minimal yaml schema version that sets compatibility with west tool - | according to https://docs.zephyrproject.org/latest/develop/west/manifest.html#version . - | If west tools version is not sufficient to process manifest file, west raises not very user-friendly - | exception (reference to west 0.12.0 for Windows): + | The manifest file defines the minimal yaml schema version that sets compatibility with west tool according to `Zephyr documentation `_. If your west tools version is not sufficient to process the manifest file, west raises an exception (reference to west 0.12.0 for Windows): .. code-block:: bash west.manifest.ManifestVersionError: ('0.13', WindowsPath('$ZEPHYR_WORKSPACE/.west/manifest-tmp/west.yml')) - | In this example ``./sof/west.yml`` defines minimal version as ``0.13`` while west tool used has version ``0.12.0``. - | Update your west tool to newer version to proceed. + | In this example, ``./sof/west.yml`` defines minimal version as ``0.13`` while the west tool used has version ``0.12.0``. Update your west tool to a newer version. From 1a9ab3a32a290fc9a96f0b4d7747f515e8174d7f Mon Sep 17 00:00:00 2001 From: bhiregoudar <87515748+bhiregoudar@users.noreply.github.com> Date: Tue, 23 Aug 2022 18:56:17 +0530 Subject: [PATCH 046/150] Update index.rst Updated with AMD Rembrandt platform specs --- platforms/index.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platforms/index.rst b/platforms/index.rst index 585e1e00..9d80e0f7 100644 --- a/platforms/index.rst +++ b/platforms/index.rst @@ -28,7 +28,8 @@ Platform and board specific support is continually added to the SOF project as d "NXP i.MX8X", "Xtensa HiFi4", "1 @ 640MHz", "TBD", "64 KB TCM / 448 KB OCRAM / 8MB SDRAM", "1 x ESAI, 1 x SAI" "NXP i.MX8M", "Xtensa HiFi4", "1 @ 800MHz", "TBD", "64 KB TCM / 256 KB OCRAM / 8MB SDRAM", "1 x SAI, MICFIL" "NXP i.MX8ULP", "Xtensa HiFi4", "1 @ 520MHz", "TBD", "64 KB TCM / 256 KB OCRAM / 8MB SDRAM", "1 x SAI" - "AMD Renoir", "Xtensa HiFi3", "1 @ 600MHz", "TBD", "20 KB LP SRAM / 1152 KB IRAM/DRAM", "1 x SP (I2S, PCM), 1 x BT (I2S, PCM), DMIC" + "AMD Renoir", "Xtensa HiFi3", "1 @ 200-600MHz", "TBD", "20 KB LP SRAM / 1152 KB IRAM/DRAM", "1 x SP (I2S, PCM), 1 x BT (I2S, PCM), DMIC" + "AMD Rembrandt", "Xtensa HiFi5", "1 @ 200-800MHz", "TBD", "1.75 MB HP SRAM / 512 KB IRAM/DRAM", "1 x SP (I2S, PCM), 1 x BT (I2S, PCM), 1 x HS(I2S, PCM), DMIC" "Mediatek mt8195", "Xtensa HiFi4", "1 @ 220 - 720MHz", "TBD", "256 KB SRAM / 16 MB DRAM", "2 x TDM Out, 1 x TDM In, DMIC" When support for a new platform is being added, certain interfaces required by From 73de46eb6d6004118a41fef511f17640de08965e Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Thu, 17 Feb 2022 09:43:27 +0100 Subject: [PATCH 047/150] arch: fw: intel: move cavs arch to sub-folder Group Intel cAVS vendor specific architecture chapters in one folder. Signed-off-by: Michal Wasko --- architectures/firmware/index.rst | 5 +---- .../{ => cavs}/cavs-boot/apollolake/apl-boot-ldr.rst | 0 .../{ => cavs}/cavs-boot/apollolake/apl-boot-rom.rst | 0 .../cavs-boot/apollolake/images/apl-rom-flow.pu | 0 .../intel/{ => cavs}/cavs-boot/apollolake/index.rst | 0 .../{ => cavs}/cavs-boot/cavs-dsp-boot-overview.rst | 0 .../intel/{ => cavs}/cavs-boot/images/boot-dsp.pu | 0 .../intel/{ => cavs}/cavs-boot/images/boot-ldr-flow.pu | 0 .../intel/{ => cavs}/cavs-boot/images/loading-bins.pu | 0 .../intel/{ => cavs}/cavs-boot/images/write-bin.pu | 0 .../firmware/intel/{ => cavs}/cavs-boot/index.rst | 0 .../firmware/intel/{ => cavs}/images/idc-send-message.pu | 0 architectures/firmware/intel/{ => cavs}/index.rst | 9 +++++---- architectures/firmware/intel/{ => cavs}/smp/index.rst | 4 ++-- 14 files changed, 8 insertions(+), 10 deletions(-) rename architectures/firmware/intel/{ => cavs}/cavs-boot/apollolake/apl-boot-ldr.rst (100%) rename architectures/firmware/intel/{ => cavs}/cavs-boot/apollolake/apl-boot-rom.rst (100%) rename architectures/firmware/intel/{ => cavs}/cavs-boot/apollolake/images/apl-rom-flow.pu (100%) rename architectures/firmware/intel/{ => cavs}/cavs-boot/apollolake/index.rst (100%) rename architectures/firmware/intel/{ => cavs}/cavs-boot/cavs-dsp-boot-overview.rst (100%) rename architectures/firmware/intel/{ => cavs}/cavs-boot/images/boot-dsp.pu (100%) rename architectures/firmware/intel/{ => cavs}/cavs-boot/images/boot-ldr-flow.pu (100%) rename architectures/firmware/intel/{ => cavs}/cavs-boot/images/loading-bins.pu (100%) rename architectures/firmware/intel/{ => cavs}/cavs-boot/images/write-bin.pu (100%) rename architectures/firmware/intel/{ => cavs}/cavs-boot/index.rst (100%) rename architectures/firmware/intel/{ => cavs}/images/idc-send-message.pu (100%) rename architectures/firmware/intel/{ => cavs}/index.rst (54%) rename architectures/firmware/intel/{ => cavs}/smp/index.rst (98%) diff --git a/architectures/firmware/index.rst b/architectures/firmware/index.rst index 2e50cf73..92160766 100644 --- a/architectures/firmware/index.rst +++ b/architectures/firmware/index.rst @@ -22,10 +22,7 @@ Architecture details of any vendor specific code and flows. This is architecture specific to a single vendor that falls outside the scope of the high level generic SOF architecture. -Intel ------ - .. toctree:: :maxdepth: 1 - intel/index \ No newline at end of file + intel/cavs/index \ No newline at end of file diff --git a/architectures/firmware/intel/cavs-boot/apollolake/apl-boot-ldr.rst b/architectures/firmware/intel/cavs/cavs-boot/apollolake/apl-boot-ldr.rst similarity index 100% rename from architectures/firmware/intel/cavs-boot/apollolake/apl-boot-ldr.rst rename to architectures/firmware/intel/cavs/cavs-boot/apollolake/apl-boot-ldr.rst diff --git a/architectures/firmware/intel/cavs-boot/apollolake/apl-boot-rom.rst b/architectures/firmware/intel/cavs/cavs-boot/apollolake/apl-boot-rom.rst similarity index 100% rename from architectures/firmware/intel/cavs-boot/apollolake/apl-boot-rom.rst rename to architectures/firmware/intel/cavs/cavs-boot/apollolake/apl-boot-rom.rst diff --git a/architectures/firmware/intel/cavs-boot/apollolake/images/apl-rom-flow.pu b/architectures/firmware/intel/cavs/cavs-boot/apollolake/images/apl-rom-flow.pu similarity index 100% rename from architectures/firmware/intel/cavs-boot/apollolake/images/apl-rom-flow.pu rename to architectures/firmware/intel/cavs/cavs-boot/apollolake/images/apl-rom-flow.pu diff --git a/architectures/firmware/intel/cavs-boot/apollolake/index.rst b/architectures/firmware/intel/cavs/cavs-boot/apollolake/index.rst similarity index 100% rename from architectures/firmware/intel/cavs-boot/apollolake/index.rst rename to architectures/firmware/intel/cavs/cavs-boot/apollolake/index.rst diff --git a/architectures/firmware/intel/cavs-boot/cavs-dsp-boot-overview.rst b/architectures/firmware/intel/cavs/cavs-boot/cavs-dsp-boot-overview.rst similarity index 100% rename from architectures/firmware/intel/cavs-boot/cavs-dsp-boot-overview.rst rename to architectures/firmware/intel/cavs/cavs-boot/cavs-dsp-boot-overview.rst diff --git a/architectures/firmware/intel/cavs-boot/images/boot-dsp.pu b/architectures/firmware/intel/cavs/cavs-boot/images/boot-dsp.pu similarity index 100% rename from architectures/firmware/intel/cavs-boot/images/boot-dsp.pu rename to architectures/firmware/intel/cavs/cavs-boot/images/boot-dsp.pu diff --git a/architectures/firmware/intel/cavs-boot/images/boot-ldr-flow.pu b/architectures/firmware/intel/cavs/cavs-boot/images/boot-ldr-flow.pu similarity index 100% rename from architectures/firmware/intel/cavs-boot/images/boot-ldr-flow.pu rename to architectures/firmware/intel/cavs/cavs-boot/images/boot-ldr-flow.pu diff --git a/architectures/firmware/intel/cavs-boot/images/loading-bins.pu b/architectures/firmware/intel/cavs/cavs-boot/images/loading-bins.pu similarity index 100% rename from architectures/firmware/intel/cavs-boot/images/loading-bins.pu rename to architectures/firmware/intel/cavs/cavs-boot/images/loading-bins.pu diff --git a/architectures/firmware/intel/cavs-boot/images/write-bin.pu b/architectures/firmware/intel/cavs/cavs-boot/images/write-bin.pu similarity index 100% rename from architectures/firmware/intel/cavs-boot/images/write-bin.pu rename to architectures/firmware/intel/cavs/cavs-boot/images/write-bin.pu diff --git a/architectures/firmware/intel/cavs-boot/index.rst b/architectures/firmware/intel/cavs/cavs-boot/index.rst similarity index 100% rename from architectures/firmware/intel/cavs-boot/index.rst rename to architectures/firmware/intel/cavs/cavs-boot/index.rst diff --git a/architectures/firmware/intel/images/idc-send-message.pu b/architectures/firmware/intel/cavs/images/idc-send-message.pu similarity index 100% rename from architectures/firmware/intel/images/idc-send-message.pu rename to architectures/firmware/intel/cavs/images/idc-send-message.pu diff --git a/architectures/firmware/intel/index.rst b/architectures/firmware/intel/cavs/index.rst similarity index 54% rename from architectures/firmware/intel/index.rst rename to architectures/firmware/intel/cavs/index.rst index cd96cc5a..4f3ac9a7 100644 --- a/architectures/firmware/intel/index.rst +++ b/architectures/firmware/intel/cavs/index.rst @@ -1,9 +1,10 @@ -.. _architecture-intel: +.. _cavs-architecture-intel: -Intel DSP Architecture -###################### +Intel cAVS Architecture +####################### -The details below are specific to Intel products with an audio DSP using SOF. +The details below are specific to Intel products with an audio DSP cAVS +architecture using SOF. .. toctree:: :maxdepth: 1 diff --git a/architectures/firmware/intel/smp/index.rst b/architectures/firmware/intel/cavs/smp/index.rst similarity index 98% rename from architectures/firmware/intel/smp/index.rst rename to architectures/firmware/intel/cavs/smp/index.rst index b3893da3..5aff7fc0 100644 --- a/architectures/firmware/intel/smp/index.rst +++ b/architectures/firmware/intel/cavs/smp/index.rst @@ -1,7 +1,7 @@ .. _architecture-intel-smp: -Intel Architecture -################## +Intel SMP Architecture +###################### Description *********** From ef566722dfc2a90cc489c9813fb757b303d1f30a Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Fri, 11 Mar 2022 15:53:58 +0100 Subject: [PATCH 048/150] arch: fw: define sof-xtos arch section Move existing FW architecture to sof-xtos section to separate from Zephyr variant. Signed-off-by: Michal Wasko --- architectures/firmware/index.rst | 9 +-------- .../components/component-mgmt-api.rst | 0 .../components/component-overview.rst | 0 .../components/images/comp-dev-states.pu | 0 .../components/images/comp-driver.pu | 0 .../components/images/comp-new-flow.pu | 0 .../components/images/component-mgmt-api.pu | 0 .../{ => sof-xtos}/components/index.rst | 0 .../drivers/dai/images/dai-ops.pu | 0 .../drivers/dai/images/dai-set-config.pu | 0 .../{ => sof-xtos}/drivers/dai/index.rst | 0 .../drivers/dma/images/dma-ops.pu | 0 .../drivers/dma/images/dma-transfer.pu | 0 .../{ => sof-xtos}/drivers/dma/index.rst | 0 .../drivers/dma/intel/hda-dma.rst | 0 .../drivers/dma/intel/images/hda-host-output.pu | 0 .../drivers/dma/intel/images/hda-link.pu | 0 .../drivers/dma/intel/images/hda-start-flow.pu | 0 .../drivers/dma/intel/images/hda-stop-flow.pu | 0 .../{ => sof-xtos}/drivers/dma/intel/index.rst | 0 .../drivers/images/device-disco.pu | 0 .../drivers/images/device-probe.pu | 0 .../drivers/images/device-remove.pu | 0 .../firmware/{ => sof-xtos}/drivers/index.rst | 0 .../{ => sof-xtos}/images/edf-scheduler-deps.pu | 0 .../{ => sof-xtos}/images/edf-scheduler-flow.pu | 0 .../sof-xtos}/images/fw-arch-diag.png | Bin .../{ => sof-xtos}/images/ll-scheduler-deps.pu | 0 .../{ => sof-xtos}/images/ll-scheduler-flow.pu | 0 .../{ => sof-xtos}/images/memory-zones.dot | 0 .../{ => sof-xtos}/images/runtime-zone.dot | 0 .../{ => sof-xtos}/images/scheduler-ops.pu | 0 .../{ => sof-xtos}/images/system-zone.dot | 0 architectures/firmware/sof-xtos/index.rst | 16 ++++++++++++++++ .../images/kd-component-diagram.pu | 0 .../images/kd-e2e-sequence-diagram.pu | 0 .../kd_integration/images/kd-state-diagram.pu | 0 .../kd_integration/images/kd-timing-diagram.pu | 0 .../{ => sof-xtos}/kd_integration/index.rst | 0 .../kd_integration/kd-integration.rst | 0 .../firmware/{ => sof-xtos}/mem-mgmt.rst | 0 .../firmware/{ => sof-xtos}/overview.rst | 2 +- .../{ => sof-xtos}/pipelines/images/ppl-new.pu | 0 .../pipelines/images/ppl-op-downstream.pu | 0 .../pipelines/images/ppl-operations.pu | 0 .../pipelines/images/ppl-params.pu | 0 .../pipelines/images/ppl-reset.pu | 0 .../pipelines/images/ppl-struct.pu | 0 .../{ => sof-xtos}/pipelines/images/ppl-task.pu | 0 .../firmware/{ => sof-xtos}/pipelines/index.rst | 0 .../pm-runtime/images/pm-dsp-core-idle.pu | 0 .../pm-runtime/images/pm-dsp-core-init.pu | 0 .../{ => sof-xtos}/pm-runtime/index.rst | 0 .../images/dsp-core-lps-cavs-d0-d0i3-d0.pu | 0 .../pm-runtime/intel/pm-dsp-core-cavs.rst | 0 .../{ => sof-xtos}/pm-runtime/pm-dsp-core.rst | 0 .../firmware/{ => sof-xtos}/schedulers.rst | 0 57 files changed, 18 insertions(+), 9 deletions(-) rename architectures/firmware/{ => sof-xtos}/components/component-mgmt-api.rst (100%) rename architectures/firmware/{ => sof-xtos}/components/component-overview.rst (100%) rename architectures/firmware/{ => sof-xtos}/components/images/comp-dev-states.pu (100%) rename architectures/firmware/{ => sof-xtos}/components/images/comp-driver.pu (100%) rename architectures/firmware/{ => sof-xtos}/components/images/comp-new-flow.pu (100%) rename architectures/firmware/{ => sof-xtos}/components/images/component-mgmt-api.pu (100%) rename architectures/firmware/{ => sof-xtos}/components/index.rst (100%) rename architectures/firmware/{ => sof-xtos}/drivers/dai/images/dai-ops.pu (100%) rename architectures/firmware/{ => sof-xtos}/drivers/dai/images/dai-set-config.pu (100%) rename architectures/firmware/{ => sof-xtos}/drivers/dai/index.rst (100%) rename architectures/firmware/{ => sof-xtos}/drivers/dma/images/dma-ops.pu (100%) rename architectures/firmware/{ => sof-xtos}/drivers/dma/images/dma-transfer.pu (100%) rename architectures/firmware/{ => sof-xtos}/drivers/dma/index.rst (100%) rename architectures/firmware/{ => sof-xtos}/drivers/dma/intel/hda-dma.rst (100%) rename architectures/firmware/{ => sof-xtos}/drivers/dma/intel/images/hda-host-output.pu (100%) rename architectures/firmware/{ => sof-xtos}/drivers/dma/intel/images/hda-link.pu (100%) rename architectures/firmware/{ => sof-xtos}/drivers/dma/intel/images/hda-start-flow.pu (100%) rename architectures/firmware/{ => sof-xtos}/drivers/dma/intel/images/hda-stop-flow.pu (100%) rename architectures/firmware/{ => sof-xtos}/drivers/dma/intel/index.rst (100%) rename architectures/firmware/{ => sof-xtos}/drivers/images/device-disco.pu (100%) rename architectures/firmware/{ => sof-xtos}/drivers/images/device-probe.pu (100%) rename architectures/firmware/{ => sof-xtos}/drivers/images/device-remove.pu (100%) rename architectures/firmware/{ => sof-xtos}/drivers/index.rst (100%) rename architectures/firmware/{ => sof-xtos}/images/edf-scheduler-deps.pu (100%) rename architectures/firmware/{ => sof-xtos}/images/edf-scheduler-flow.pu (100%) rename architectures/{ => firmware/sof-xtos}/images/fw-arch-diag.png (100%) rename architectures/firmware/{ => sof-xtos}/images/ll-scheduler-deps.pu (100%) rename architectures/firmware/{ => sof-xtos}/images/ll-scheduler-flow.pu (100%) rename architectures/firmware/{ => sof-xtos}/images/memory-zones.dot (100%) rename architectures/firmware/{ => sof-xtos}/images/runtime-zone.dot (100%) rename architectures/firmware/{ => sof-xtos}/images/scheduler-ops.pu (100%) rename architectures/firmware/{ => sof-xtos}/images/system-zone.dot (100%) create mode 100644 architectures/firmware/sof-xtos/index.rst rename architectures/firmware/{ => sof-xtos}/kd_integration/images/kd-component-diagram.pu (100%) rename architectures/firmware/{ => sof-xtos}/kd_integration/images/kd-e2e-sequence-diagram.pu (100%) rename architectures/firmware/{ => sof-xtos}/kd_integration/images/kd-state-diagram.pu (100%) rename architectures/firmware/{ => sof-xtos}/kd_integration/images/kd-timing-diagram.pu (100%) rename architectures/firmware/{ => sof-xtos}/kd_integration/index.rst (100%) rename architectures/firmware/{ => sof-xtos}/kd_integration/kd-integration.rst (100%) rename architectures/firmware/{ => sof-xtos}/mem-mgmt.rst (100%) rename architectures/firmware/{ => sof-xtos}/overview.rst (97%) rename architectures/firmware/{ => sof-xtos}/pipelines/images/ppl-new.pu (100%) rename architectures/firmware/{ => sof-xtos}/pipelines/images/ppl-op-downstream.pu (100%) rename architectures/firmware/{ => sof-xtos}/pipelines/images/ppl-operations.pu (100%) rename architectures/firmware/{ => sof-xtos}/pipelines/images/ppl-params.pu (100%) rename architectures/firmware/{ => sof-xtos}/pipelines/images/ppl-reset.pu (100%) rename architectures/firmware/{ => sof-xtos}/pipelines/images/ppl-struct.pu (100%) rename architectures/firmware/{ => sof-xtos}/pipelines/images/ppl-task.pu (100%) rename architectures/firmware/{ => sof-xtos}/pipelines/index.rst (100%) rename architectures/firmware/{ => sof-xtos}/pm-runtime/images/pm-dsp-core-idle.pu (100%) rename architectures/firmware/{ => sof-xtos}/pm-runtime/images/pm-dsp-core-init.pu (100%) rename architectures/firmware/{ => sof-xtos}/pm-runtime/index.rst (100%) rename architectures/firmware/{ => sof-xtos}/pm-runtime/intel/images/dsp-core-lps-cavs-d0-d0i3-d0.pu (100%) rename architectures/firmware/{ => sof-xtos}/pm-runtime/intel/pm-dsp-core-cavs.rst (100%) rename architectures/firmware/{ => sof-xtos}/pm-runtime/pm-dsp-core.rst (100%) rename architectures/firmware/{ => sof-xtos}/schedulers.rst (100%) diff --git a/architectures/firmware/index.rst b/architectures/firmware/index.rst index 92160766..80f8c91b 100644 --- a/architectures/firmware/index.rst +++ b/architectures/firmware/index.rst @@ -6,14 +6,7 @@ Firmware Architecture .. toctree:: :maxdepth: 1 - overview - mem-mgmt - pm-runtime/index - schedulers - drivers/index - components/index - pipelines/index - kd_integration/index + sof-xtos/index Vendor Specific Architecture Information ======================================== diff --git a/architectures/firmware/components/component-mgmt-api.rst b/architectures/firmware/sof-xtos/components/component-mgmt-api.rst similarity index 100% rename from architectures/firmware/components/component-mgmt-api.rst rename to architectures/firmware/sof-xtos/components/component-mgmt-api.rst diff --git a/architectures/firmware/components/component-overview.rst b/architectures/firmware/sof-xtos/components/component-overview.rst similarity index 100% rename from architectures/firmware/components/component-overview.rst rename to architectures/firmware/sof-xtos/components/component-overview.rst diff --git a/architectures/firmware/components/images/comp-dev-states.pu b/architectures/firmware/sof-xtos/components/images/comp-dev-states.pu similarity index 100% rename from architectures/firmware/components/images/comp-dev-states.pu rename to architectures/firmware/sof-xtos/components/images/comp-dev-states.pu diff --git a/architectures/firmware/components/images/comp-driver.pu b/architectures/firmware/sof-xtos/components/images/comp-driver.pu similarity index 100% rename from architectures/firmware/components/images/comp-driver.pu rename to architectures/firmware/sof-xtos/components/images/comp-driver.pu diff --git a/architectures/firmware/components/images/comp-new-flow.pu b/architectures/firmware/sof-xtos/components/images/comp-new-flow.pu similarity index 100% rename from architectures/firmware/components/images/comp-new-flow.pu rename to architectures/firmware/sof-xtos/components/images/comp-new-flow.pu diff --git a/architectures/firmware/components/images/component-mgmt-api.pu b/architectures/firmware/sof-xtos/components/images/component-mgmt-api.pu similarity index 100% rename from architectures/firmware/components/images/component-mgmt-api.pu rename to architectures/firmware/sof-xtos/components/images/component-mgmt-api.pu diff --git a/architectures/firmware/components/index.rst b/architectures/firmware/sof-xtos/components/index.rst similarity index 100% rename from architectures/firmware/components/index.rst rename to architectures/firmware/sof-xtos/components/index.rst diff --git a/architectures/firmware/drivers/dai/images/dai-ops.pu b/architectures/firmware/sof-xtos/drivers/dai/images/dai-ops.pu similarity index 100% rename from architectures/firmware/drivers/dai/images/dai-ops.pu rename to architectures/firmware/sof-xtos/drivers/dai/images/dai-ops.pu diff --git a/architectures/firmware/drivers/dai/images/dai-set-config.pu b/architectures/firmware/sof-xtos/drivers/dai/images/dai-set-config.pu similarity index 100% rename from architectures/firmware/drivers/dai/images/dai-set-config.pu rename to architectures/firmware/sof-xtos/drivers/dai/images/dai-set-config.pu diff --git a/architectures/firmware/drivers/dai/index.rst b/architectures/firmware/sof-xtos/drivers/dai/index.rst similarity index 100% rename from architectures/firmware/drivers/dai/index.rst rename to architectures/firmware/sof-xtos/drivers/dai/index.rst diff --git a/architectures/firmware/drivers/dma/images/dma-ops.pu b/architectures/firmware/sof-xtos/drivers/dma/images/dma-ops.pu similarity index 100% rename from architectures/firmware/drivers/dma/images/dma-ops.pu rename to architectures/firmware/sof-xtos/drivers/dma/images/dma-ops.pu diff --git a/architectures/firmware/drivers/dma/images/dma-transfer.pu b/architectures/firmware/sof-xtos/drivers/dma/images/dma-transfer.pu similarity index 100% rename from architectures/firmware/drivers/dma/images/dma-transfer.pu rename to architectures/firmware/sof-xtos/drivers/dma/images/dma-transfer.pu diff --git a/architectures/firmware/drivers/dma/index.rst b/architectures/firmware/sof-xtos/drivers/dma/index.rst similarity index 100% rename from architectures/firmware/drivers/dma/index.rst rename to architectures/firmware/sof-xtos/drivers/dma/index.rst diff --git a/architectures/firmware/drivers/dma/intel/hda-dma.rst b/architectures/firmware/sof-xtos/drivers/dma/intel/hda-dma.rst similarity index 100% rename from architectures/firmware/drivers/dma/intel/hda-dma.rst rename to architectures/firmware/sof-xtos/drivers/dma/intel/hda-dma.rst diff --git a/architectures/firmware/drivers/dma/intel/images/hda-host-output.pu b/architectures/firmware/sof-xtos/drivers/dma/intel/images/hda-host-output.pu similarity index 100% rename from architectures/firmware/drivers/dma/intel/images/hda-host-output.pu rename to architectures/firmware/sof-xtos/drivers/dma/intel/images/hda-host-output.pu diff --git a/architectures/firmware/drivers/dma/intel/images/hda-link.pu b/architectures/firmware/sof-xtos/drivers/dma/intel/images/hda-link.pu similarity index 100% rename from architectures/firmware/drivers/dma/intel/images/hda-link.pu rename to architectures/firmware/sof-xtos/drivers/dma/intel/images/hda-link.pu diff --git a/architectures/firmware/drivers/dma/intel/images/hda-start-flow.pu b/architectures/firmware/sof-xtos/drivers/dma/intel/images/hda-start-flow.pu similarity index 100% rename from architectures/firmware/drivers/dma/intel/images/hda-start-flow.pu rename to architectures/firmware/sof-xtos/drivers/dma/intel/images/hda-start-flow.pu diff --git a/architectures/firmware/drivers/dma/intel/images/hda-stop-flow.pu b/architectures/firmware/sof-xtos/drivers/dma/intel/images/hda-stop-flow.pu similarity index 100% rename from architectures/firmware/drivers/dma/intel/images/hda-stop-flow.pu rename to architectures/firmware/sof-xtos/drivers/dma/intel/images/hda-stop-flow.pu diff --git a/architectures/firmware/drivers/dma/intel/index.rst b/architectures/firmware/sof-xtos/drivers/dma/intel/index.rst similarity index 100% rename from architectures/firmware/drivers/dma/intel/index.rst rename to architectures/firmware/sof-xtos/drivers/dma/intel/index.rst diff --git a/architectures/firmware/drivers/images/device-disco.pu b/architectures/firmware/sof-xtos/drivers/images/device-disco.pu similarity index 100% rename from architectures/firmware/drivers/images/device-disco.pu rename to architectures/firmware/sof-xtos/drivers/images/device-disco.pu diff --git a/architectures/firmware/drivers/images/device-probe.pu b/architectures/firmware/sof-xtos/drivers/images/device-probe.pu similarity index 100% rename from architectures/firmware/drivers/images/device-probe.pu rename to architectures/firmware/sof-xtos/drivers/images/device-probe.pu diff --git a/architectures/firmware/drivers/images/device-remove.pu b/architectures/firmware/sof-xtos/drivers/images/device-remove.pu similarity index 100% rename from architectures/firmware/drivers/images/device-remove.pu rename to architectures/firmware/sof-xtos/drivers/images/device-remove.pu diff --git a/architectures/firmware/drivers/index.rst b/architectures/firmware/sof-xtos/drivers/index.rst similarity index 100% rename from architectures/firmware/drivers/index.rst rename to architectures/firmware/sof-xtos/drivers/index.rst diff --git a/architectures/firmware/images/edf-scheduler-deps.pu b/architectures/firmware/sof-xtos/images/edf-scheduler-deps.pu similarity index 100% rename from architectures/firmware/images/edf-scheduler-deps.pu rename to architectures/firmware/sof-xtos/images/edf-scheduler-deps.pu diff --git a/architectures/firmware/images/edf-scheduler-flow.pu b/architectures/firmware/sof-xtos/images/edf-scheduler-flow.pu similarity index 100% rename from architectures/firmware/images/edf-scheduler-flow.pu rename to architectures/firmware/sof-xtos/images/edf-scheduler-flow.pu diff --git a/architectures/images/fw-arch-diag.png b/architectures/firmware/sof-xtos/images/fw-arch-diag.png similarity index 100% rename from architectures/images/fw-arch-diag.png rename to architectures/firmware/sof-xtos/images/fw-arch-diag.png diff --git a/architectures/firmware/images/ll-scheduler-deps.pu b/architectures/firmware/sof-xtos/images/ll-scheduler-deps.pu similarity index 100% rename from architectures/firmware/images/ll-scheduler-deps.pu rename to architectures/firmware/sof-xtos/images/ll-scheduler-deps.pu diff --git a/architectures/firmware/images/ll-scheduler-flow.pu b/architectures/firmware/sof-xtos/images/ll-scheduler-flow.pu similarity index 100% rename from architectures/firmware/images/ll-scheduler-flow.pu rename to architectures/firmware/sof-xtos/images/ll-scheduler-flow.pu diff --git a/architectures/firmware/images/memory-zones.dot b/architectures/firmware/sof-xtos/images/memory-zones.dot similarity index 100% rename from architectures/firmware/images/memory-zones.dot rename to architectures/firmware/sof-xtos/images/memory-zones.dot diff --git a/architectures/firmware/images/runtime-zone.dot b/architectures/firmware/sof-xtos/images/runtime-zone.dot similarity index 100% rename from architectures/firmware/images/runtime-zone.dot rename to architectures/firmware/sof-xtos/images/runtime-zone.dot diff --git a/architectures/firmware/images/scheduler-ops.pu b/architectures/firmware/sof-xtos/images/scheduler-ops.pu similarity index 100% rename from architectures/firmware/images/scheduler-ops.pu rename to architectures/firmware/sof-xtos/images/scheduler-ops.pu diff --git a/architectures/firmware/images/system-zone.dot b/architectures/firmware/sof-xtos/images/system-zone.dot similarity index 100% rename from architectures/firmware/images/system-zone.dot rename to architectures/firmware/sof-xtos/images/system-zone.dot diff --git a/architectures/firmware/sof-xtos/index.rst b/architectures/firmware/sof-xtos/index.rst new file mode 100644 index 00000000..2909242d --- /dev/null +++ b/architectures/firmware/sof-xtos/index.rst @@ -0,0 +1,16 @@ +.. _sof-xtos: + +SOF with XTOS Architecture +########################## + +.. toctree:: + :maxdepth: 1 + + overview + mem-mgmt + pm-runtime/index + schedulers + drivers/index + components/index + pipelines/index + kd_integration/index diff --git a/architectures/firmware/kd_integration/images/kd-component-diagram.pu b/architectures/firmware/sof-xtos/kd_integration/images/kd-component-diagram.pu similarity index 100% rename from architectures/firmware/kd_integration/images/kd-component-diagram.pu rename to architectures/firmware/sof-xtos/kd_integration/images/kd-component-diagram.pu diff --git a/architectures/firmware/kd_integration/images/kd-e2e-sequence-diagram.pu b/architectures/firmware/sof-xtos/kd_integration/images/kd-e2e-sequence-diagram.pu similarity index 100% rename from architectures/firmware/kd_integration/images/kd-e2e-sequence-diagram.pu rename to architectures/firmware/sof-xtos/kd_integration/images/kd-e2e-sequence-diagram.pu diff --git a/architectures/firmware/kd_integration/images/kd-state-diagram.pu b/architectures/firmware/sof-xtos/kd_integration/images/kd-state-diagram.pu similarity index 100% rename from architectures/firmware/kd_integration/images/kd-state-diagram.pu rename to architectures/firmware/sof-xtos/kd_integration/images/kd-state-diagram.pu diff --git a/architectures/firmware/kd_integration/images/kd-timing-diagram.pu b/architectures/firmware/sof-xtos/kd_integration/images/kd-timing-diagram.pu similarity index 100% rename from architectures/firmware/kd_integration/images/kd-timing-diagram.pu rename to architectures/firmware/sof-xtos/kd_integration/images/kd-timing-diagram.pu diff --git a/architectures/firmware/kd_integration/index.rst b/architectures/firmware/sof-xtos/kd_integration/index.rst similarity index 100% rename from architectures/firmware/kd_integration/index.rst rename to architectures/firmware/sof-xtos/kd_integration/index.rst diff --git a/architectures/firmware/kd_integration/kd-integration.rst b/architectures/firmware/sof-xtos/kd_integration/kd-integration.rst similarity index 100% rename from architectures/firmware/kd_integration/kd-integration.rst rename to architectures/firmware/sof-xtos/kd_integration/kd-integration.rst diff --git a/architectures/firmware/mem-mgmt.rst b/architectures/firmware/sof-xtos/mem-mgmt.rst similarity index 100% rename from architectures/firmware/mem-mgmt.rst rename to architectures/firmware/sof-xtos/mem-mgmt.rst diff --git a/architectures/firmware/overview.rst b/architectures/firmware/sof-xtos/overview.rst similarity index 97% rename from architectures/firmware/overview.rst rename to architectures/firmware/sof-xtos/overview.rst index 4cbe26b5..a01dc1f0 100644 --- a/architectures/firmware/overview.rst +++ b/architectures/firmware/sof-xtos/overview.rst @@ -33,7 +33,7 @@ main sections: the audio components and pipelines to send/receive data to/from the host and external codecs. - .. figure:: ../images/fw-arch-diag.png + .. figure:: ./images/fw-arch-diag.png :align: center :alt: SOF Architecture :width: 800px diff --git a/architectures/firmware/pipelines/images/ppl-new.pu b/architectures/firmware/sof-xtos/pipelines/images/ppl-new.pu similarity index 100% rename from architectures/firmware/pipelines/images/ppl-new.pu rename to architectures/firmware/sof-xtos/pipelines/images/ppl-new.pu diff --git a/architectures/firmware/pipelines/images/ppl-op-downstream.pu b/architectures/firmware/sof-xtos/pipelines/images/ppl-op-downstream.pu similarity index 100% rename from architectures/firmware/pipelines/images/ppl-op-downstream.pu rename to architectures/firmware/sof-xtos/pipelines/images/ppl-op-downstream.pu diff --git a/architectures/firmware/pipelines/images/ppl-operations.pu b/architectures/firmware/sof-xtos/pipelines/images/ppl-operations.pu similarity index 100% rename from architectures/firmware/pipelines/images/ppl-operations.pu rename to architectures/firmware/sof-xtos/pipelines/images/ppl-operations.pu diff --git a/architectures/firmware/pipelines/images/ppl-params.pu b/architectures/firmware/sof-xtos/pipelines/images/ppl-params.pu similarity index 100% rename from architectures/firmware/pipelines/images/ppl-params.pu rename to architectures/firmware/sof-xtos/pipelines/images/ppl-params.pu diff --git a/architectures/firmware/pipelines/images/ppl-reset.pu b/architectures/firmware/sof-xtos/pipelines/images/ppl-reset.pu similarity index 100% rename from architectures/firmware/pipelines/images/ppl-reset.pu rename to architectures/firmware/sof-xtos/pipelines/images/ppl-reset.pu diff --git a/architectures/firmware/pipelines/images/ppl-struct.pu b/architectures/firmware/sof-xtos/pipelines/images/ppl-struct.pu similarity index 100% rename from architectures/firmware/pipelines/images/ppl-struct.pu rename to architectures/firmware/sof-xtos/pipelines/images/ppl-struct.pu diff --git a/architectures/firmware/pipelines/images/ppl-task.pu b/architectures/firmware/sof-xtos/pipelines/images/ppl-task.pu similarity index 100% rename from architectures/firmware/pipelines/images/ppl-task.pu rename to architectures/firmware/sof-xtos/pipelines/images/ppl-task.pu diff --git a/architectures/firmware/pipelines/index.rst b/architectures/firmware/sof-xtos/pipelines/index.rst similarity index 100% rename from architectures/firmware/pipelines/index.rst rename to architectures/firmware/sof-xtos/pipelines/index.rst diff --git a/architectures/firmware/pm-runtime/images/pm-dsp-core-idle.pu b/architectures/firmware/sof-xtos/pm-runtime/images/pm-dsp-core-idle.pu similarity index 100% rename from architectures/firmware/pm-runtime/images/pm-dsp-core-idle.pu rename to architectures/firmware/sof-xtos/pm-runtime/images/pm-dsp-core-idle.pu diff --git a/architectures/firmware/pm-runtime/images/pm-dsp-core-init.pu b/architectures/firmware/sof-xtos/pm-runtime/images/pm-dsp-core-init.pu similarity index 100% rename from architectures/firmware/pm-runtime/images/pm-dsp-core-init.pu rename to architectures/firmware/sof-xtos/pm-runtime/images/pm-dsp-core-init.pu diff --git a/architectures/firmware/pm-runtime/index.rst b/architectures/firmware/sof-xtos/pm-runtime/index.rst similarity index 100% rename from architectures/firmware/pm-runtime/index.rst rename to architectures/firmware/sof-xtos/pm-runtime/index.rst diff --git a/architectures/firmware/pm-runtime/intel/images/dsp-core-lps-cavs-d0-d0i3-d0.pu b/architectures/firmware/sof-xtos/pm-runtime/intel/images/dsp-core-lps-cavs-d0-d0i3-d0.pu similarity index 100% rename from architectures/firmware/pm-runtime/intel/images/dsp-core-lps-cavs-d0-d0i3-d0.pu rename to architectures/firmware/sof-xtos/pm-runtime/intel/images/dsp-core-lps-cavs-d0-d0i3-d0.pu diff --git a/architectures/firmware/pm-runtime/intel/pm-dsp-core-cavs.rst b/architectures/firmware/sof-xtos/pm-runtime/intel/pm-dsp-core-cavs.rst similarity index 100% rename from architectures/firmware/pm-runtime/intel/pm-dsp-core-cavs.rst rename to architectures/firmware/sof-xtos/pm-runtime/intel/pm-dsp-core-cavs.rst diff --git a/architectures/firmware/pm-runtime/pm-dsp-core.rst b/architectures/firmware/sof-xtos/pm-runtime/pm-dsp-core.rst similarity index 100% rename from architectures/firmware/pm-runtime/pm-dsp-core.rst rename to architectures/firmware/sof-xtos/pm-runtime/pm-dsp-core.rst diff --git a/architectures/firmware/schedulers.rst b/architectures/firmware/sof-xtos/schedulers.rst similarity index 100% rename from architectures/firmware/schedulers.rst rename to architectures/firmware/sof-xtos/schedulers.rst From f195f55a055f5ac6bc6b494f8654ff4998f6fbe1 Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Mon, 14 Mar 2022 13:48:16 +0100 Subject: [PATCH 049/150] arch: fw: sof-zephyr overview Add overview chapter with architecture diagram that present SOF-Zephyr integration Signed-off-by: Michal Wasko --- architectures/firmware/index.rst | 1 + architectures/firmware/sof-xtos/overview.rst | 8 ++-- .../sof-zephyr/images/overview_diagram.pu | 42 +++++++++++++++++++ architectures/firmware/sof-zephyr/index.rst | 9 ++++ .../firmware/sof-zephyr/overview.rst | 12 ++++++ 5 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 architectures/firmware/sof-zephyr/images/overview_diagram.pu create mode 100644 architectures/firmware/sof-zephyr/index.rst create mode 100644 architectures/firmware/sof-zephyr/overview.rst diff --git a/architectures/firmware/index.rst b/architectures/firmware/index.rst index 80f8c91b..ba64102a 100644 --- a/architectures/firmware/index.rst +++ b/architectures/firmware/index.rst @@ -7,6 +7,7 @@ Firmware Architecture :maxdepth: 1 sof-xtos/index + sof-zephyr/index Vendor Specific Architecture Information ======================================== diff --git a/architectures/firmware/sof-xtos/overview.rst b/architectures/firmware/sof-xtos/overview.rst index a01dc1f0..94b44a8a 100644 --- a/architectures/firmware/sof-xtos/overview.rst +++ b/architectures/firmware/sof-xtos/overview.rst @@ -1,9 +1,9 @@ -.. _overview: +.. _sof-legacy-overview: Overview ########## -Currently SOF has support for the Cadence Xtensa DSP architecture in UP and SMP +Currently SOF has support for the Cadence Xtensa DSP architecture in UP and SMP modes in the upstream code base. The diagram below shows the high-level firmware architecture with the @@ -41,6 +41,6 @@ main sections: `Sound Open Firmware Architecture using Intel Bay Trail Platform` -Each section above is well insulated from the other sections by partitioning -code into separate directories and by using DSP and platform agnostic generic +Each section above is well insulated from the other sections by partitioning +code into separate directories and by using DSP and platform agnostic generic APIs for orchestration between the sections. diff --git a/architectures/firmware/sof-zephyr/images/overview_diagram.pu b/architectures/firmware/sof-zephyr/images/overview_diagram.pu new file mode 100644 index 00000000..8ee7f089 --- /dev/null +++ b/architectures/firmware/sof-zephyr/images/overview_diagram.pu @@ -0,0 +1,42 @@ +@startuml +allowmixing + +scale max 1280 width + +package "SOF" { + + package "Application layer - user space" as APPLICATION_LAYER { + component "3rd party algorithms" - private" as 3RD_PARTY_ALGOS + component "Loadable libraries" as LOADABLE_COMPONENTS + component "Built-in Processing components" as BUILTIN_COMPONENTS + + BUILTIN_COMPONENTS -[hidden]right- LOADABLE_COMPONENTS + LOADABLE_COMPONENTS -[hidden]right- 3RD_PARTY_ALGOS + } + + package "Kernel space" { + + package "Media Processing Pipelines layer - kernel extension" as KERNEL_EXTENSION { + component "Communication" as COMMUNICATION + component "Pipelines and Component Infrastructure" as PIPELINE_COMPONENT_INFRASTRUCTURE + component "AVS Scheduling" as AVS_SCHEDULERS + + COMMUNICATION -[hidden]right- PIPELINE_COMPONENT_INFRASTRUCTURE + PIPELINE_COMPONENT_INFRASTRUCTURE -[hidden]right- AVS_SCHEDULERS + } + + package "Zephyr RTOS layer" as RTOS { + component "Services" as SERVICES + component "SoC HAL" as SOC + component "Drivers" as DRIVERS + + SERVICES --[hidden]right-- SOC + SOC --[hidden]right-- DRIVERS + } + + APPLICATION_LAYER -[hidden]down- KERNEL_EXTENSION + KERNEL_EXTENSION -[hidden]down- RTOS + } +} + +@enduml diff --git a/architectures/firmware/sof-zephyr/index.rst b/architectures/firmware/sof-zephyr/index.rst new file mode 100644 index 00000000..66e2132e --- /dev/null +++ b/architectures/firmware/sof-zephyr/index.rst @@ -0,0 +1,9 @@ +.. _sof-zephyr: + +SOF with Zephyr Architecture +############################ + +.. toctree:: + :maxdepth: 1 + + overview diff --git a/architectures/firmware/sof-zephyr/overview.rst b/architectures/firmware/sof-zephyr/overview.rst new file mode 100644 index 00000000..e9969e29 --- /dev/null +++ b/architectures/firmware/sof-zephyr/overview.rst @@ -0,0 +1,12 @@ +.. _sof-zephyr-overview: + +Overview +######## + +New SOF firmware architecture is based on Zephyr RTOS and introduce new IPC4 +Host protocol ABI. In result FW has been re-organized into layers. The +interaction between the components across the layers is limited to the +internally defined interfaces. + +.. uml:: images/overview_diagram.pu + :caption: SOF with Zephyr Architecture overview From de1a1222c09e080bf70cc560a8a70c4583f7745d Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Tue, 15 Mar 2022 14:54:43 +0100 Subject: [PATCH 050/150] arch: fw: app layer description Application layer components description in SOF with Zephyr architecture Signed-off-by: Michal Wasko --- .../app_layer/images/app_layer_diagram.pu | 68 +++++++++++++++++++ .../firmware/sof-zephyr/app_layer/index.rst | 40 +++++++++++ architectures/firmware/sof-zephyr/index.rst | 1 + 3 files changed, 109 insertions(+) create mode 100644 architectures/firmware/sof-zephyr/app_layer/images/app_layer_diagram.pu create mode 100644 architectures/firmware/sof-zephyr/app_layer/index.rst diff --git a/architectures/firmware/sof-zephyr/app_layer/images/app_layer_diagram.pu b/architectures/firmware/sof-zephyr/app_layer/images/app_layer_diagram.pu new file mode 100644 index 00000000..a3581f25 --- /dev/null +++ b/architectures/firmware/sof-zephyr/app_layer/images/app_layer_diagram.pu @@ -0,0 +1,68 @@ +@startuml +allowmixing + +scale max 1280 width + +package "SOF" { + + package "Application layer" as APP_CUSTOMIZATION { + + package "Example Loadable Components" as LOADABLE_COMPONENTS { + component "3rd Party Post-Processing" as PROCESSING_3RD_PARTY + component "WoV" as WOV_MODULE + component "ACA" as ACA_MODULE + component "Other modules" as OTHER_MODULES + + PROCESSING_3RD_PARTY -[hidden]right- WOV_MODULE + WOV_MODULE -[hidden]right- ACA_MODULE + ACA_MODULE -[hidden]right- OTHER_MODULES + } + + package "Built-in Components" as BUILTIN_COMPONENTS { + component "Copier" as COPIER + component "SRC" as SRC + component "Mixers" as MIXERS + component "History Buffer/KPB" as HISTORY_BUFFER + component "Probe" as PROBE + + COPIER -[hidden]right- SRC + SRC -[hidden]right- MIXERS + MIXERS -[hidden]right- HISTORY_BUFFER + HISTORY_BUFFER -[hidden]right- PROBE + } + + BUILTIN_COMPONENTS -[hidden]down- LOADABLE_COMPONENTS + } + + package "System Services" as SYS_SERVICES { + + interface "System Services" as SS + + package "Media Processing Pipelines Services extension" as KERNEL_EXTENSION { + component "Communication" as COMMUNICATION + component "Pipelines and Component Infrastructure" as PIPELINE_COMPONENT_INFRASTRUCTURE + component "AVS Scheduling" as AVS_SCHEDULERS + + COMMUNICATION -[hidden]right- PIPELINE_COMPONENT_INFRASTRUCTURE + PIPELINE_COMPONENT_INFRASTRUCTURE -[hidden]right- AVS_SCHEDULERS + } + + package "Zephyr" as ZEPHYR { + component "Services" as SERVICES + } + + SS -[hidden]down- KERNEL_EXTENSION + SS -[hidden]down- ZEPHYR + + KERNEL_EXTENSION -[hidden]right- ZEPHYR + } + + APP_CUSTOMIZATION -[hidden]down- SYS_SERVICES + BUILTIN_COMPONENTS .down. SS + PROCESSING_3RD_PARTY .down. SS + WOV_MODULE .down. SS + ACA_MODULE .down. SS + OTHER_MODULES .down. SS +} + +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/app_layer/index.rst b/architectures/firmware/sof-zephyr/app_layer/index.rst new file mode 100644 index 00000000..0ee0f56e --- /dev/null +++ b/architectures/firmware/sof-zephyr/app_layer/index.rst @@ -0,0 +1,40 @@ +.. _app_layer: + +Application Layer +################# + +Application Layer represents the built-in FW processing components, loadable FW +components and example templates with application libraries required for +components integration. Application layer content is assumed to be open source +and only proprietary 3rd party components should remain private. + +.. uml:: images/app_layer_diagram.pu + :caption: Application Layer + +Components in Application Layer +******************************* + +The built-in components are built together with base firmware and they have +direct access to all firmware drivers and service APIs. When built-in module +is enabled in configuration, it is guaranteed to exist in firmware binary. + +The loadable components are built separately from base firmware and they are +loaded dynamically as a separate binary, depending on the host audio +configuration. + +All the application layer components access base firmware services via System +Services ABI. + +**NOTE:** The built-in components are utility components provided by base +firmware/kernel. + +Examples of built-in components: + +* Audio built-in components: Copiers, Mixers, Volume, SRC, etc. + +Probe +===== + +The probe module is special module in FW infrastructure that allows to inject +or extract data from a specified probe point. The traditional client +platforms use HDA DMAs to transfer data in and out of such module. diff --git a/architectures/firmware/sof-zephyr/index.rst b/architectures/firmware/sof-zephyr/index.rst index 66e2132e..390e50ba 100644 --- a/architectures/firmware/sof-zephyr/index.rst +++ b/architectures/firmware/sof-zephyr/index.rst @@ -7,3 +7,4 @@ SOF with Zephyr Architecture :maxdepth: 1 overview + app_layer/index From 0d0516199dfa327c6c8302f52683b6ad8f7529e4 Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Mon, 21 Mar 2022 16:32:18 +0100 Subject: [PATCH 051/150] arch: fw: mpp layer description Media Processing Pipelines layer diagram and descripion. Signed-off-by: Michal Wasko --- architectures/firmware/sof-zephyr/index.rst | 1 + .../mpp_layer/images/mpp_layer_diagram.pu | 55 +++++++++++ .../firmware/sof-zephyr/mpp_layer/index.rst | 13 +++ .../sof-zephyr/mpp_layer/mpp_overview.rst | 94 +++++++++++++++++++ 4 files changed, 163 insertions(+) create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/mpp_layer_diagram.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/index.rst create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/mpp_overview.rst diff --git a/architectures/firmware/sof-zephyr/index.rst b/architectures/firmware/sof-zephyr/index.rst index 390e50ba..e4b3f29c 100644 --- a/architectures/firmware/sof-zephyr/index.rst +++ b/architectures/firmware/sof-zephyr/index.rst @@ -8,3 +8,4 @@ SOF with Zephyr Architecture overview app_layer/index + mpp_layer/index diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_layer_diagram.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_layer_diagram.pu new file mode 100644 index 00000000..24f8c175 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_layer_diagram.pu @@ -0,0 +1,55 @@ +@startuml + +allowmixing + +scale max 1024 width + +package "SOF" { + + package "Media Processing Pipelines layer" as MEDIA_PROCESSING_PIPELINES { + package "MPP Scheduling" as MPP_SCHEDULING { + component "LL Tasks" as LL_TASKS + component "DP Tasks" as DP_TASKS + + DP_TASKS -[hidden]down- LL_TASKS + } + + package "Communication" as COMMUNICATION { + component "IPC Message Processing and common command definitions" as IPC_MESSAGE_PROCESSING + component "Async Messaging" as ASYNC_MESSAGING + + IPC_MESSAGE_PROCESSING -[hidden]right- ASYNC_MESSAGING + } + + package "Pipeline/Component Infrastructure" as PIPELINE_COMPONENT_INFRASTRUCTURE { + component "Pipeline Management" as PIPELINE_MANAGEMENT + component "Host/DAI Gateways" as HOST_DAI_GATEWAYS + component "Processing Component Management" as PROCESSING_COMPONENT_MANAGEMENT + + PIPELINE_MANAGEMENT -[hidden]right- HOST_DAI_GATEWAYS + HOST_DAI_GATEWAYS -[hidden]right- PROCESSING_COMPONENT_MANAGEMENT + } + + COMMUNICATION -[hidden]down- PIPELINE_COMPONENT_INFRASTRUCTURE + COMMUNICATION -[hidden]right- MPP_SCHEDULING + } + + package "Zephyr" as ZEPHYR { + interface "Zephyr Services, SoC HAL and Driver Interfaces" as SS + + component "SoC HAL" as SOC + component "Drivers" as DRIVERS + component "XTHAL" as XTHAL + component "Services" as SERVICES + + SS -[hidden]down- SERVICES + SERVICES -[hidden]right- SOC + SOC -[hidden]right- DRIVERS + DRIVERS -[hidden]right- XTHAL + } + + MEDIA_PROCESSING_PIPELINES -[hidden]down- ZEPHYR + PIPELINE_COMPONENT_INFRASTRUCTURE -[hidden]down- ZEPHYR +} + +@enduml diff --git a/architectures/firmware/sof-zephyr/mpp_layer/index.rst b/architectures/firmware/sof-zephyr/mpp_layer/index.rst new file mode 100644 index 00000000..ddcd77f2 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/index.rst @@ -0,0 +1,13 @@ +.. _mpp_layer: + +Media Processing Pipelines Layer +################################ + +The Media Processing Pipelines (MPP) is a FW infrastructure layer independent to +the HW. The MPP components serve as kernel services extension that is available +to the Application layer. + +.. toctree:: + :maxdepth: 1 + + mpp_overview diff --git a/architectures/firmware/sof-zephyr/mpp_layer/mpp_overview.rst b/architectures/firmware/sof-zephyr/mpp_layer/mpp_overview.rst new file mode 100644 index 00000000..955a3781 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/mpp_overview.rst @@ -0,0 +1,94 @@ +.. _mpp_layer_overview: + +Media Processing Pipelines Overview +################################### + +The Media Processing Pipelines (MPP) layer role is to enable SOF specific use +cases that are not supported directly by Zephyr. The MPP is responsible for host +communication, tasks scheduling, pipeline and component management. + +.. uml:: images/mpp_layer_diagram.pu + :caption: Media Processing Pipelines Layer diagram + +Services in Media Processing Pipelines Layer +******************************************** + +Gateways +======== + +The gateways are a key element in SOF data exchange with host, external audio +peripherals and internally between firmware components. They serve as an +abstraction layer for multiple data protocols. + +The typical audio stream (chain of pipelines) starts and ends with I/O gateway. +I/O gateway represents a sink or a source interface that can be read or written +via DMA operations on I/O FIFO (i.e. DMIC, SNDW, etc.) or directly via memory +operations (i.e. memory buffers of IPC Gateway). Host Gateway is unique as it +exposes interface endpoint to the Host driver. + +The stream audio gateways are created as a part of Copier component +configuration. + +.. TODO: Add link to Copier detailed description + +Examples of gateways: + +- DMIC Gateway, +- SoundWire Gateway, +- I2S Gateway, +- HD/A Gateway, +- IPC Gateway, + +.. TODO: Add link to Gateways detailed specification. + +*NOTE:* Not all I/O gateways must be available in all configurations. + +Pipeline Management +=================== + +The Pipeline Management is a host IPC driven service that is used to: + +- create / delete pipeline +- switch pipeline state +- create pipeline processing tasks +- allocate pipeline buffers memory + +.. TODO: Add link to Pipeline Management IPC interface. + +Processing Component Management +=============================== + +Processing Component Management is driven by host IPC requests. It is used to: + +- instantiate / delete components +- configure components +- bind / unbind components into processing paths +- load components into ADSP memory + +.. TODO: Add link to Component Management IPC interface. + +Asynchronous Messaging +====================== + +Asynchronous Messaging Service (AMS) provides functionality to: + +- send asynchronous messages to firmware components or host, +- broadcast messages to multiple consumers, +- asynchronous message exchange between components running on different cores + +.. TODO: Add link to Asynchronous Messaging Service detailed description + +MPP Scheduling +============== + +MPP Scheduling is dedicated to support Media Processing Pipelines services tasks +scheduling. It exposes SOF specific interface that is implemented on top of +Zephyr scheduling API. + +MPP Scheduling features: + +- Low Latency tasks scheduling, +- Data Processing tasks scheduling, +- Tasks with budget scheduling + +.. TODO: Add link to MPP Scheduling detailed description From c84d15fe41d6abf1b46a4a2cc37251e2e799252c Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Tue, 22 Mar 2022 17:06:56 +0100 Subject: [PATCH 052/150] arch: fw: zephyr based kernel description Add RTOS layer chapter with kernel description that include low level drivers, services, SoC HAL, and overview diagrams. Signed-off-by: Michal Wasko --- architectures/firmware/sof-zephyr/index.rst | 1 + .../rtos_layer/images/kernel_services.pu | 57 +++ .../images/zephyr_kernel_diagram.pu | 124 ++++++ .../firmware/sof-zephyr/rtos_layer/index.rst | 13 + .../rtos_layer/zephyr_kernel_overview.rst | 372 ++++++++++++++++++ 5 files changed, 567 insertions(+) create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/images/kernel_services.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/images/zephyr_kernel_diagram.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/index.rst create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/zephyr_kernel_overview.rst diff --git a/architectures/firmware/sof-zephyr/index.rst b/architectures/firmware/sof-zephyr/index.rst index e4b3f29c..c3f5df01 100644 --- a/architectures/firmware/sof-zephyr/index.rst +++ b/architectures/firmware/sof-zephyr/index.rst @@ -9,3 +9,4 @@ SOF with Zephyr Architecture overview app_layer/index mpp_layer/index + rtos_layer/index diff --git a/architectures/firmware/sof-zephyr/rtos_layer/images/kernel_services.pu b/architectures/firmware/sof-zephyr/rtos_layer/images/kernel_services.pu new file mode 100644 index 00000000..f1d19987 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/images/kernel_services.pu @@ -0,0 +1,57 @@ +@startuml +allowmixing + +scale max 1280 width + +package "SOF" { + package "Kernel Infrastructure" { + interface "Zephyr System Services" as SS + + package "Services" { + component "Memory Manager" as MEMORY_MANAGER + component "Power Manager" as POWER_MANAGER + component "IPC/IDC" as IXC + component "Logging" as LOGGING + component "Debug" as DEBUG + component "Interrupt Handler" as INTERRUPT_HANDLER + } + + SS .down. MEMORY_MANAGER + SS .down. POWER_MANAGER + SS .down. IXC + SS .down. LOGGING + SS .down. DEBUG + SS .down. INTERRUPT_HANDLER + } + + package "Kernel Extension" { + interface "Extended System Services" as ESS + + component "AVS Scheduling" as AVS_Scheduling + + package "Extended Services" as EXTENDED_SERVICES { + component "Firmware Manager" as FIRMWARE_MANAGEMENT + component "Pipeline Management" as PIPELINE_MANAGEMENT + component "Async Messaging" as ASYNC_MESSAGING + component "Processing Component Management" as COMPONENT_MANAGEMENT + component "IPC Message Processing" as IPC_MESSAGE_PROCESSING + } + + ESS .down. FIRMWARE_MANAGEMENT + ESS .down. PIPELINE_MANAGEMENT + ESS .down. ASYNC_MESSAGING + ESS .down. IPC_MESSAGE_PROCESSING + ESS .down. COMPONENT_MANAGEMENT + + AVS_Scheduling -[hidden]down- EXTENDED_SERVICES + } + + package "Loadable modules" { + component "WoV" as WOV + + WOV .down. SS + WOV .down. ESS + } +} + +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/rtos_layer/images/zephyr_kernel_diagram.pu b/architectures/firmware/sof-zephyr/rtos_layer/images/zephyr_kernel_diagram.pu new file mode 100644 index 00000000..f7bf622a --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/images/zephyr_kernel_diagram.pu @@ -0,0 +1,124 @@ +@startuml +allowmixing + +scale max 1280 width + +package "Kernel space" { + + package "Media Processing Pipelines - kernel extension" as MPP_KERNEL_EXTENSION { + interface "Extended System Services" as ESS + + component "Firmware Manager" as FIRMWARE_MANAGER + + package "Communication" as COMMUNICATION { + component "IPC Message Processing" as IPC_MESSAGE_PROCESSING + component "Async Messaging" as ASYNC_MESSAGING + + IPC_MESSAGE_PROCESSING -[hidden]right- ASYNC_MESSAGING + } + + package "Pipeline/Component Infrastructure" as PIPELINE_COMPONENT_INFRASTRUCTURE { + component "Pipeline Management" as PIPELINE_MANAGEMENT + component "Host/DAI Gateways" as HOST_DAI_GATEWAYS + component "Processing Component Management" as PROCESSING_COMPONENT_MANAGEMENT + + PIPELINE_MANAGEMENT -[hidden]right- HOST_DAI_GATEWAYS + HOST_DAI_GATEWAYS -[hidden]right- PROCESSING_COMPONENT_MANAGEMENT + } + + package "AVS Scheduling" as AVS_SCHEDULING { + component "Data Processing (DP) Tasks (EDF based)" as DP_TASKS + component "Low Latency (LL) Tasks" as LL_TASKS + + DP_TASKS -[hidden]right- LL_TASKS + } + + FIRMWARE_MANAGER -[hidden]right- PIPELINE_COMPONENT_INFRASTRUCTURE + FIRMWARE_MANAGER -[hidden]down- COMMUNICATION + COMMUNICATION -[hidden]right- AVS_SCHEDULING + + ESS -[hidden]down- FIRMWARE_MANAGER + ESS -[hidden]down- PIPELINE_COMPONENT_INFRASTRUCTURE + } + + package "Zephyr" as Zephyr_RTOS { + interface "Zephyr System Services" as SS + + package "Schedulers" as SCHEDULERS { + component "RTOS Scheduling" as RTOS_SCHEDULER + } + + package "Services" as SERVICES { + component "Memory Manager" as MEMORY_MANAGER + component "Power Manager" as POWER_MANAGER + component "IPC/IDC" as IXC + component "Logging" as LOGGING + component "Debug" as DEBUG + component "Timer Manager" as TIMER_MANAGER + component "Interrupt Handler" as INTERRUPT_HANDLER + + MEMORY_MANAGER -[hidden]right- POWER_MANAGER + POWER_MANAGER -[hidden]right- IXC + IXC -[hidden]down- LOGGING + LOGGING -[hidden]right- TIMER_MANAGER + TIMER_MANAGER -[hidden]right- INTERRUPT_HANDLER + } + + package "SoC HAL" as SOC { + component "OEM SoC 1" as SOC_1 + component "OEM SoC 2" as SOC_2 + component "Other SoCs" as OTHER_SOCS + + SOC_1 -[hidden]right- SOC_2 + SOC_2 -[hidden]right- OTHER_SOCS + } + + package "Drivers" as DRIVERS { + package "Common Drivers" as COMMON_DRIVERS { + component "GPDMA" as GPDMA + component "Timer" as TIMER + component "SHA-384" as SHA384 + component "Watchdog" as WATCHDOG + component "IPC" as IPC + component "IDC" as IDC + } + + package "Audio Drivers" as AUDIO_DRIVERS{ + component "DMIC" as DMIC + component "I2S" as I2S + component "SDW" as SDW + component "HDA" as HDA + + DMIC -[hidden]right- I2S + I2S -[hidden]right- SDW + SDW -[hidden]right- HDA + } + + package "Sensing Drivers" as SENSING_DRIVERS { + component "I2C" as I2C + component "GPIO" as GPIO + component "I3C" as I3C + component "SPI" as SPI + component "UART" as UART + + I2C -[hidden]right- GPIO + GPIO -[hidden]right- I3C + I3C -[hidden]right- SPI + SPI -[hidden]right- UART + } + } + + component "XTHAL" as XTHAL + + SS -[hidden]down- SCHEDULERS + SS -[hidden]down- SERVICES + SCHEDULERS -[hidden]right- SERVICES + SERVICES -[hidden]right- SOC + SERVICES --[hidden]down-- DRIVERS + DRIVERS -[hidden]down- XTHAL + } + + MPP_KERNEL_EXTENSION --[hidden]down-- Zephyr_RTOS +} + +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/index.rst b/architectures/firmware/sof-zephyr/rtos_layer/index.rst new file mode 100644 index 00000000..80efe77c --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/index.rst @@ -0,0 +1,13 @@ +.. _rtos_layer: + +RTOS Layer Infrastructure +######################### + +The RTOS layer is based on Zephyr that provide generic and scalable open source +solution with options for SW partitioning of product subsystems to run audio +workloads. + +.. toctree:: + :maxdepth: 1 + + zephyr_kernel_overview diff --git a/architectures/firmware/sof-zephyr/rtos_layer/zephyr_kernel_overview.rst b/architectures/firmware/sof-zephyr/rtos_layer/zephyr_kernel_overview.rst new file mode 100644 index 00000000..b6d0e3fb --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/zephyr_kernel_overview.rst @@ -0,0 +1,372 @@ +.. _kernel_overview: + +Zephyr based kernel +################### + +Zephyr has been introduced as an IP agnostic solution that replaced existing SOF +audio specific kernel. The Zephyr base kernel has been complemented with SOF Low +Level Drivers, SoC HAL and kernel extensions. The new solution continues +scalable kernel concept and it serves as a generic part of infrastructure that +can be statically and dynamically customized based on usage, compute, and memory +constrains, HW configuration etc. + +As a result of the kernel customization, a firmware infrastructure is produced. +This firmware infrastructure can run on a given processor type and it is tuned +for specified usage. + +For more Zephyr kernel details, see `Zephyr Introduction +documentation `__ + +The Zephyr based kernel consists of the following components: + +- Hardware integration layer: XTHAL, +- Low Level Drivers, + + - DMIC, + - I2S, + - SNDW, + - GPIO, + - I2C, + - I3C, + - timers, + - GPDMA, + - IDC, + - IPC, + - watchdog, + - etc. + +- SoC HAL, + + - OEM SoC specific code, + +- Services: shared resource services, communication services, memory manager, + power manager, interrupt manager, system service, etc. +- Kernel extensions: + + - AVS schedulers, + - Firmware Manager, + - Media Processing Pipeline Components, + +The Zephyr base kernel expectations: + +- it can scale down to meet all KPIs via static and dynamic scaling options, +- Zephyr itself is IP agnostic and shared across other SW and FW projects, +- it is available and maintain under open source license, + +.. uml:: images/zephyr_kernel_diagram.pu + :caption: Zephyr Kernel diagram + +Scaling Options +''''''''''''''' + +Zephyr kernel offers scaling options to adjust to selected HW configuration, +scale down to meet aggressive KPIs on a given platform, scale up to meet +functional requirements. + +The scaling is achieved in two ways: + +- static, kernel components can be selectively enabled in the build process + + - Drivers selected depending on SoC Configuration + - Services and execution frameworks chosen in Zephyr + +- dynamic, not used parts can be unloaded and saved in "backup storage" memory, + that typically has large capacity and high access latency. They will be + loaded again once a specific event will happen + + - It is only applicable to SoCs that support it. + - It is achieved via one of the following mechanisms: + + - Firmware Paging (if present) - Only currently executing modules are in + SRAM. + - Split Firmware into modules - Modules are loaded from "backup storage" + or unloaded on explicit request. No runtime dynamism. + +Handling Project Configuration +'''''''''''''''''''''''''''''' + +Zephyr is prepared to be configured via device tree that describe given SoC +board audio hardware configuration. + +A SoC board device tree allows configuring: + +* HW configuration + + * number of HP DSP cores, + * types of memories available per cores, + * supported clocks, + * number of I/Os, + * number of IPC and IDC interfaces for DSP cores, + * etc. + + * DSP memory space, + * IPC mailbox address, + * etc. + +Low Level Drivers +''''''''''''''''' + +SOF is capable to support hardware with several audio I/Os, sensor I/Os, DSP +accelerators and DMAs which count can be customized per architcture. + +HW resources with low level drivers: + +* Audio I/Os: I2S, DMIC, SNDW, HD/A, +* Sensor I/Os: I2C, I3C, GPIO, UART, SPI, ADC, PWM, +* Common resources: HP GPDMA, IPC, IDC, Timers, SHA-384, Watchdog + +**NOTE:** Not all I/Os are supported in each SoC board. + +.. TODO: add link to supported audio architectures + +Zephyr based firmware provides low level drivers for all these resources. A +specific driver can be enabled during build process. + +SoC HAL +''''''' + +The SoC HAL include implementation and configuration details specific for +selected SoC architecture. The SoC HAL abstraction allow to seamlesly switch +between target SoC configuration builds. + +More details can be found in Zephyr documentation: + +* `Zephyr Board Porting Guide `__ +* `Zephyr Architecture Porting Guide `__ + +Services +'''''''' + +.. uml:: images/kernel_services.pu + :caption: Example of kernel services + +The base Zephyr services provide generic system management functionality for +memory, interrupts, autonomous power control (clock and power gating, clock +management). + +The SOF specific functionality is exposed in a form of an extended kernel +services. The extended services utilize Zephyr base services infrastructure and +low level drivers to supply user space interface for the firmware application +layer components. The user space separation from hardware and low level drivers +significantly increase the firmware security and stability. + +Firmware Management +------------------- + +The firmware manager is a core service that is responsible for: + +- reading HW capabilities (number of cores, memory available, etc.), +- firmware initialization, +- instantiation and initialization of Low Level drivers for the existing HW + components, + + - memory type drivers initialization with size read form capability + registers + - audio drivers for supported interfaces + +- instantiate and initialize Extended Kernel Services + + - component manager + - pipeline manager + - IPC/IDC communication service + - async messaging service + - debug service + +.. TODO: add other components that require initialization by the firmware manager + +Interrupt Management +-------------------- + +The interrupt handler service allows to: + +- enable and disable an interrupt for DSP core, +- register a callback that will be called once a specified interrupt occur, + +For more details, see `Zephyr Interrupts +documentation `__ + +Memory Management +----------------- + +The Memory Manager provides a service to other FW components to allocate a block +out of available memory pools, it provides high level API, scans for unused +memory areas, handles physical memory defragmentation, prefetch and cache +policies. Most of the memory is expected to be paged. + +All allocation requests refer to virtual memory address space, which shall be +continuous. This also applies to DMA buffer allocations, where continuous memory +is guaranteed by either continuous physical memory or VA/PA translation. + +The map of available memory resources is passed to the Memory Manager during +initialization of Memory Manager via firmware infrastructure. + +For more details, see `Zephyr Memory Management +documentation `__. + +Power Management +---------------- + +The power management behavior highly depends on platform that firmware runs on, +and it can be configured during build time. There are platforms that only allow +clock gating and power gating is not applicable. + +The power management interface provides the following functionality: + +- allow and prevent power gating, +- allow and prevent clock gating, +- allow and prevent slower clock, +- allow and prevent XTAL shutdown, + +In all cases, the implementation relies on atomic counter which is incremented +every time when prevent function is called and decremented when allow function +is called. + +.. TODO: Add link to SOF Power Management detailed description with flows + +`Zephyr Power Management documentation +`__. + +IPC and IDC Service +------------------- + +The IPC and IDC Service provides communication channel over IPC or IDC. IPCs are +used for the external communication with Host, other processors within SoC or +other subsystems within PCH. IDCs are used for the internal communication +between processors within SOF subsystem. + +The introduction of SOF with Zephyr is followed with new IPC4 interface and +message formats that replaced IPC3. + +The following types of sequences are supported: + +- request-response initiated by Host, + + - it is synchronous sequence, + - long-running operations shall queue request and send response immediately. + The actual completion information should be sent via one-way asynchronous + notification, + +- one-way asynchronous notification, + +.. TODO: Add link to Communication section (when ready) + +Debugging +--------- + +The Zephyr based kernel provides a few services that helps with debugging FW. + +Logging +~~~~~~~ + +The Logger Service provides a lightweight mechanism to push log entries to all +firmware modules that are based on Zephyr logging infrastructure. + +It is a very useful mechanism to do a first level of debugging. + +.. TODO: Add link to Logger Service section (when ready) +.. TODO: Add link to SOF Enable Logs interface +.. TODO: Add link to SOF status and error codes registers + +Zephyr related documentation: + +- `Zephyr + Logging `__ + +Probes +~~~~~~ + +SOF supports injection and extraction probes. The probes are mainly used to +extract audio data from queues between components. + +The other probe use cases include: + +- injection of audio data to a component input queue - useful during testing + and debugging, +- injection of data to internal probes, +- extraction of data from internal probes i.e. internal component states, + intermediate data, debug information, +- logging - probes can be used as transport for firmware logs, + +.. TODO: Add link to Probe configuration interface (when ready) + +Performance Measurements +~~~~~~~~~~~~~~~~~~~~~~~~ + +The firmware infrastructures support performance measurements to collect +information about DSP cycles or amount of data moved via interfaces. + +.. TODO: Add link to Performance Measurements State firmware interface +.. TODO: Add link to firmware Global Performance Data description + + +Telemetry +~~~~~~~~~ + +Firmware infrastructure supports collection of telemetry events which then can +be read by the Host Software. The modules running in FW infrastructure can push +telemetry events via System Services. + +If the telemetry collection is started, the telemetry events will be written to +a common circular buffer. + +If the telemetry collection is stopped/disabled, the telemetry events will be +dropped at telemetry service level and they will not be written to the telemetry +circular buffer. During transition from started to stopped state, the telemetry +events that are already in the circular buffer will be dropped. + +.. TODO: Add link to SOF Telemetry interface documentation + +.. _Schedulers: + +Schedulers +---------- + +The scheduling method depends on compute and memory available for firmware +running on processor as well as type of workloads executed on given domain. + +There are following types of schedulers supported in SOF + +- AVS scheduling, + +.. TODO: Add link to Scheduling detailed section + +Async Messaging Service +----------------------- + +Asynchronous Messaging Service (AMS) is mechanism to exchange asynchronous +events between components running in the same firmware infrastructure or running +on the another processor (e.g. between HiFi and Fusion cores). + +The Async Messages can be also injected and extracted via Host Async Message +Gateway module by Host SW. + +.. TODO: Add link to Asynchronous Messaging detailed section + +System Services +--------------- + +The FW components do not know location of driver and service functions in base +firmware library, so they need to access base firmware services via System +Services. + +In SOF with Zephyr the `Zephyr interfaces for +drivers `__ +were adopted. All newly developed drivers must be compliant to this standard and +the legacy ones must be ported to it. + +In Zephyr based firmware, a driver instance is obtained via +``device_get_binding`` function call with a name of a driver instance. There is +no explicit driver initialization call as a driver instance is initialized with +the first call. + +A driver implementation must be ready for using the same hardware instance from +many modules and from many cores (it must be thread-safe implementation). There +can be more than one device instance if there is more than 1 instance of a +hardware (i.e. 2 I2C owner controllers). + +The example functionalities that should be exposed via system services: + +- IPC and IDC, +- Logger Service, +- RTOS scheduler functionalities, like yield, +- Async Messaging Service, From 6fff403d28c032c0fc3384f8d8ff25dcaa752d2f Mon Sep 17 00:00:00 2001 From: Deb Date: Mon, 3 Oct 2022 17:08:26 -0600 Subject: [PATCH 053/150] Edit vendor-specific toc for better navigation Signed-off-by: Deb --- architectures/firmware/index.rst | 13 +- architectures/firmware/intel/cavs/index.rst | 0 .../firmware/vendor-specific/index.rst | 13 ++ .../cavs-boot/apollolake/apl-boot-ldr.rst | 20 +++ .../cavs-boot/apollolake/apl-boot-rom.rst | 163 ++++++++++++++++++ .../apollolake/images/apl-rom-flow.pu | 59 +++++++ .../vend-intel/cavs-boot/apollolake/index.rst | 10 ++ .../cavs-boot/cavs-dsp-boot-overview.rst | 127 ++++++++++++++ .../vend-intel/cavs-boot/images/boot-dsp.pu | 21 +++ .../cavs-boot/images/boot-ldr-flow.pu | 28 +++ .../cavs-boot/images/loading-bins.pu | 41 +++++ .../vend-intel/cavs-boot/images/write-bin.pu | 10 ++ .../vend-intel/cavs-boot/index.rst | 17 ++ .../vend-intel/images/idc-send-message.pu | 30 ++++ .../vendor-specific/vend-intel/index.rst | 13 ++ .../vendor-specific/vend-intel/smp/index.rst | 64 +++++++ architectures/index.rst | 4 +- 17 files changed, 620 insertions(+), 13 deletions(-) mode change 100644 => 100755 architectures/firmware/index.rst mode change 100644 => 100755 architectures/firmware/intel/cavs/index.rst create mode 100755 architectures/firmware/vendor-specific/index.rst create mode 100644 architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/apl-boot-ldr.rst create mode 100644 architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/apl-boot-rom.rst create mode 100644 architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/images/apl-rom-flow.pu create mode 100755 architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/index.rst create mode 100755 architectures/firmware/vendor-specific/vend-intel/cavs-boot/cavs-dsp-boot-overview.rst create mode 100644 architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/boot-dsp.pu create mode 100644 architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/boot-ldr-flow.pu create mode 100644 architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/loading-bins.pu create mode 100644 architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/write-bin.pu create mode 100644 architectures/firmware/vendor-specific/vend-intel/cavs-boot/index.rst create mode 100644 architectures/firmware/vendor-specific/vend-intel/images/idc-send-message.pu create mode 100755 architectures/firmware/vendor-specific/vend-intel/index.rst create mode 100644 architectures/firmware/vendor-specific/vend-intel/smp/index.rst mode change 100644 => 100755 architectures/index.rst diff --git a/architectures/firmware/index.rst b/architectures/firmware/index.rst old mode 100644 new mode 100755 index ba64102a..f44e7ae3 --- a/architectures/firmware/index.rst +++ b/architectures/firmware/index.rst @@ -8,15 +8,4 @@ Firmware Architecture sof-xtos/index sof-zephyr/index - -Vendor Specific Architecture Information -======================================== - -Architecture details of any vendor specific code and flows. This is architecture -specific to a single vendor that falls outside the scope of the high level -generic SOF architecture. - -.. toctree:: - :maxdepth: 1 - - intel/cavs/index \ No newline at end of file + vendor-specific/index \ No newline at end of file diff --git a/architectures/firmware/intel/cavs/index.rst b/architectures/firmware/intel/cavs/index.rst old mode 100644 new mode 100755 diff --git a/architectures/firmware/vendor-specific/index.rst b/architectures/firmware/vendor-specific/index.rst new file mode 100755 index 00000000..6a4e56ee --- /dev/null +++ b/architectures/firmware/vendor-specific/index.rst @@ -0,0 +1,13 @@ +.. _vendor-specific: + +Vendor-Specific Architecture Information +######################################## + +Architecture details of any vendor specific code and flows. This is architecture +specific to a single vendor that falls outside the scope of the high level +generic SOF architecture. + +.. toctree:: + :maxdepth: 1 + + vend-intel/index \ No newline at end of file diff --git a/architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/apl-boot-ldr.rst b/architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/apl-boot-ldr.rst new file mode 100644 index 00000000..04fd5d0e --- /dev/null +++ b/architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/apl-boot-ldr.rst @@ -0,0 +1,20 @@ +.. _apl-boot-ldr: + +Apollo Lake Boot Loader +####################### + +* Additional HPSRAM memory initialization. +* L2 cache disabled in ``boot_entry`` (enabled by default by APL ROM). + +Example list of sections in the APL boot_ldr:: + + Idx Name Size VMA LMA File off Algn + 0 .boot_entry.text 00000036 b000a000 b000a000 000000d4 2**2 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 1 .boot_entry.literal 0000000c b000a040 b000a040 0000010c 2**2 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 2 .text 000007d2 b000a0b0 b000a0b0 00000120 2**4 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 3 .rodata 00000008 b0002000 b0002000 000008f4 2**2 + CONTENTS, ALLOC, LOAD, DATA + ... more debug sections ... diff --git a/architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/apl-boot-rom.rst b/architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/apl-boot-rom.rst new file mode 100644 index 00000000..5070e745 --- /dev/null +++ b/architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/apl-boot-rom.rst @@ -0,0 +1,163 @@ +.. _apl-boot-rom: + +Apollo Lake Boot ROM +#################### + +Progress of the boot process is reflected by the status information updated by +the ROM in an SRAM area called *FW Registers*. It is available to the host +driver through a memory window. + +ROM FW Registers +**************** + +This SRAM area updated by the ROM during the boot process is available via +memory window #0, the limit is set to 4K. + +Offset 0x00 + FwStatus - Current ROM status + +Offset 0x04 + ErrorCode - Last ROM error code + +Offset 0x08 + FwPwrStatus - Current DSP clock status (ToBeVerified on APL/CNL) + +FwStatus +======== + +The FwStatus register contains current FW status, initialized to 0 on the DSP +startup. + +The ErrorCode register is updated by ROM when *FwStatus* ``running`` bit is +set to “halted on critical error”, initialized to 0 (`ADSP_SUCCESS`) on the +DSP startup. + +Once Base FW is being executed, *ErrorCode* is updated every time some error is +detected while calling internal API components. Some of the error codes might be +helpful for driver writers hence documented in this specification. + +.. code-block:: c + + union fw_status_reg + { + int32_t full; + struct Bits + { + uint32_t state : 24; + uint32_t wait_state : 4; + uint32_t module : 3; + uint32_t running : 1; + } bits; + }; + +running + This field is used to report current FW running state. + 0 – running, + 1 – halted. + When FW reports halted state, ErrorCode register contains error + code. + +module + This field is used to report FW module (that indicates boot phase + component/module in this context, not a processing module) that is being + executed. + +wait_state + This field is updated to non-zero code of operation when ROM is waiting + for completion of that operation. + +state + This field is used to report phase of the FW module that is being executed. + When FW switches to another module (reported by Module field) this value + may get started again from 0, so it is Module context sensitive. + +.. uml:: images/apl-rom-flow.pu + :caption: APL ROM Boot Sequence + +.. code-block:: c + :caption: APL ROM Wait States + + // Waiting for IPC busy bit to be set + #define WAIT_FOR_IPC_BUSY 0x1 + // Waiting for IPC done bit to be set + #define WAIT_FOR_IPC_DONE 0x2 + // Waiting for L2$ invalidation to be ack'ed + #define WAIT_FOR_CACHE_INVALIDATION 0x3 + // Waiting for DMA buffer to be filled + #define WAIT_FOR_DMA_BUFFER_FULL 0x5 + +.. code-block:: c + :caption: APL ROM Status Codes + + #define FSR_ROM_INIT 0x0 + #define FSR_ROM_INIT_DONE 0x1 + #define FSR_ROM_CSE_MANIFEST_LOADED 0x2 + #define FSR_ROM_FW_MANIFEST_LOADED 0x3 + #define FSR_ROM_FW_FW_LOADED 0x4 + #define FSR_ROM_FW_ENTERED 0x5 + #define FSR_ROM_VERIFY_FEATURE_MASK 0x6 + #define FSR_ROM_GET_LOAD_OFFSET 0x7 + #define FSR_ROM_BASEFW_CSE_IMR_REQUEST 0x10 + #define FSR_ROM_BASEFW_CSE_IMR_GRANTED 0x11 + #define FSR_ROM_BASEFW_CSE_VALIDATE_IMAGE_REQUEST 0x12 + #define FSR_ROM_BASEFW_CSE_IMAGE_VALIDATED 0x13 + +.. code-block:: c + :caption: APL ROM Error Codes + + #define ADSP_UNHANDLED_INTERRUPT 0xBEE00000 + + // Memory hole/ECC error + // Status bits are provided: + // [0] - L2 SRAM ECC error + // [1] - L2 memory hole error + #define ADSP_MEMORY_HOLE_ECC 0xECC00000 + #define ADSP_USER_EXCEPTION 0xBEEF0000 + #define ADSP_KERNEL_EXCEPTION 0xCAFE0000 + + // Other critical error + #define ADSP_FAILURE 6 + // FW image does not match the feature mask read from HW register. + #define ADSP_INVALID_FEAT_MASK 20 + // Invalid parameter + #define ADSP_INVALID_PARAM 21 + // CSE responded with error on an IPC request + #define ADSP_CSE_ERROR 40 + // Invalid IPC response sent back by CSE. + #define ADSP_CSE_WRONG_RESPONSE 41 + // Size of IMR assigned by CSE is too small to load FW Image. + #define ADSP_IMR_TOO_SMALL 42 + // Base FW module not found in FW Image. + #define ADSP_BASE_FW_NOT_FOUND 43 + // CSE responded with error on FW image validation request. + #define ADSP_CSE_VALIDATION_FAILED 44 + // IPC communication failed with fatal error. + #define ADSP_IPC_FATAL_ERROR 45 + // L2 cache command failed. + #define ADSP_L2_CACHE_ERROR 46 + // Load offset set in FW Image Manifest is too small. + #define ADSP_LOAD_OFFSET_TOO_SMALL 47 + +ROM -> FW Transition +==================== + +Once APL ROM jumps to the entry point of the first module in the main binary, +the memory and caches are in the following state: + +* L2$ is turned on, so the FW boot procedure may either execute via L2 + cacheable address space or directly via L2 uncacheable alias. + +* HPSRAM areas allocated by the ROM listed in the next table. + +APL ROM HPSRAM Allocation +========================= + ++---------------------+------------+--------------+ +| Area | Base Addr | Size | ++=====================+============+==============+ +| Code load buffer | 0xBE008000 | 0x8000 (32K) | ++---------------------+------------+--------------+ +| BSS (inc. stack) | 0xBE010000 | 0x8000 (32K) | ++---------------------+------------+--------------+ +| FW Registers | 0xBE01E000 | 0x800 (2K) | ++---------------------+------------+--------------+ diff --git a/architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/images/apl-rom-flow.pu b/architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/images/apl-rom-flow.pu new file mode 100644 index 00000000..4624b4d1 --- /dev/null +++ b/architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/images/apl-rom-flow.pu @@ -0,0 +1,59 @@ +participant "State" as st +participant "Error" as err +participant "Host\nDriver" as host +participant "APL\nROM" as rom +participant "CSE" as cse + +host -> rom : <> RomControl (purge=1, dma_id) + +== Initialization == +rom -> rom : Boot + err <[#red]- rom : ADSP_UNHANDLED_INTERRUPT [anytime unhandled int reported] + err <[#red]- rom : ADSP_MEMORY_HOLE_ECC [anytime memory hole int reported] + err <[#red]- rom : ADSP_USER_EXCEPTION [anytime unhandled user mode exception happens] + err <[#red]- rom : ADSP_KERNEL_EXCEPTION [anytime unhandled kernel mode exception happens] + +rom -> rom : L2Cache Initialization + err <[#red]- rom : ADSP_L2_CACHE_ERROR [Failed to init L2$] + +rom -> rom : Requesting IMR + st <[#green]- rom : FSR_ROM_BASEFW_CSE_IMR_REQUEST + rom -> cse : <> IPC_ADSP2CSE_REQUEST_IMR + rom <- cse : <> IPC_CSE2ADSP_REQUEST_IMR_RESPONSE + st <[#green]- rom : FSR_ROM_BASEFW_CSE_IMR_GRANTED + +rom -> rom : Initializing Code Load DMA + err <[#red]- rom : ADSP_INVALID_PARAM [dma_id out of range] + +st <[#green]- rom : FSR_ROM_INIT_DONE + +== Loading Image == + rom -> rom : Loading Firmware + ' First fw image block is loaded and feature mask is verified + st <[#green]- rom : FSR_ROM_VERIFY_FEATURE_MASK + err <[#red]- rom : ADSP_INVALID_FEAT_MASK [mft mask does not match SKUID] + ' Load offset is verified + st <[#green]- rom : FSR_ROM_GET_LOAD_OFFSET + err <[#red]- rom : ADSP_LOAD_OFFSET_TOO_SMALL [load offset less then Rsvd space] + err <[#red]- rom : ADSP_IMR_TOO_SMALL [load offset greater than assigned IMR size] + ' CSE Manifest if loaded + rom -> rom : Loading CSE Manifest + err <[#red]- rom : ADSP_IMR_TOO_SMALL [CSE manifest > IMR size] + st <[#green]- rom : FSR_ROM_CSE_MANIFEST_LOADED + ' FW Manifest is loaded + rom -> rom : Loading ADSP FW Manifest + err <[#red]- rom : ADSP_IMR_TOO_SMALL [ADSP FW manifest > IMR size] + st <[#green]- rom : FSR_ROM_FW_MANIFEST_LOADED + err <[#red]- rom : ADSP_BASE_FW_NOT_FOUND [module entry not found in manifest] + ' Loading rest of FW + rom -> rom : Loading FW + st <[#green]- rom : FSR_ROM_FW_FW_LOADED + +== Authenticating Image == + st <[#green]- rom : FSR_ROM_BASEFW_CSE_VALIDATE_IMAGE_REQUEST + rom -> cse : <> IPC_CSE2ADSP_START_FW_AUTH + rom <- cse : <> IPC_CSE2ADSP_START_FW_AUTH_RESPONSE + err <[#red]- rom : ADSP_CSE_VALIDATION_FAILED [invalid image signature] + st <[#green]- rom : FSR_ROM_BASEFW_CSE_IMAGE_VALIDATED +== Booting FW == + st <[#green]- rom : FSR_ROM_FW_ENTERED diff --git a/architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/index.rst b/architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/index.rst new file mode 100755 index 00000000..21ee69cb --- /dev/null +++ b/architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/index.rst @@ -0,0 +1,10 @@ +.. _cavs-boot-apl: + +Apollo Lake Boot Process +######################## + +.. toctree:: + :maxdepth: 1 + + apl-boot-rom + apl-boot-ldr diff --git a/architectures/firmware/vendor-specific/vend-intel/cavs-boot/cavs-dsp-boot-overview.rst b/architectures/firmware/vendor-specific/vend-intel/cavs-boot/cavs-dsp-boot-overview.rst new file mode 100755 index 00000000..24fde842 --- /dev/null +++ b/architectures/firmware/vendor-specific/vend-intel/cavs-boot/cavs-dsp-boot-overview.rst @@ -0,0 +1,127 @@ +.. _cavs-dsp-boot-overview: + +Overview +######## + +There are two main DSP boot flows: + +* **Cold boot** performed when the host CPU exits an Sx state. FW binaries are + loaded into DSP memory and full state re-initialization is required. This + flow is also referred as *Purge Flow* in the figures below. + +* **RTD3 boot** when the DSP state is restored from the DSP internal memory. + This flow is available on platforms with access to Isolated Memory Region + (IMR) allocated for the DSP. + +IPC Communication with DSP ROM +****************************** + +Once the primary DSP core (#0) is powered up and reset by the host driver, an +IPC communication with the DSP ROM is required in order to set the boot +options (see Boot Path Control Messages for details and list of platforms that +require this step). It is a one-way message that does not require a response +from the DSP. + +There may be some specific requirements about the order of the DSP core reset, +sending IPC message, and the DSP core unstall operations. It is assumed that +the following order is required unless specified otherwise by Boot Path +Control Message in case of a specific platform: + +1. Power up and reset the DSP Core 0, +#. Send ROM Control IPC, +#. Unstall DSP Core 0. + +The ROM Control IPC message includes “purge” parameter that should be set to 1 +in case of the cold boot. Otherwise it may be set to 0 after coming out of +RTD3 to attempt quicker state restore flow. In the latter case, the driver +just waits for FW Ready notification (no library loading is needed). + +The flow is illustrated in the next figure. + +.. uml:: images/boot-dsp.pu + +Loading Binaries to ADSP Memory +******************************* + +The ADSP FW binary code may be divided into: + +* The Base FW binary file, which contains FW infrastructure code (Base FW + module) required by all the platforms, optionally followed by other modules, + +* Set of libraries (modules) containing additional processing modules code + that may be optionally loaded into ADSP FW memory based on the platform’s + requirements and configuration. + +.. note:: This section contains general information about the structure of + binaries necessary to understand the loading process. For a complete + documentation refer to FW Binaries documentation. + +There are two main parts of the main binary: + +* Manifest, +* Modules binary code. + +Determining Part of Binary to be Loaded +======================================= + +The binary begins with the Manifest that is loaded into the DSP memory. The +Manifest contains ``preload_page_count`` parameter that determines part of the +binary to be loaded by the driver during the boot process. The preload size is +expressed in pages, where size of the page is 4096 bytes for all platforms. If +IMR is available and allocated for the DSP on the platform, the preload size +includes the entire binary. Otherwise it includes only the critical part of +the binary while other parts (so called loadable modules) may be loaded on +demand when needed (see Load Multiple Modules IPC) to limit SRAM usage and +save the power. + +For example, the Base FW binary file may be setup in a way that +``preload_page_count`` includes size of the Manifest as well as size of the +following Base FW module (it is always module 0 in the Base FW binary) since +its presence in the DSP memory is absolutely necessary for the boot to +complete. If the Base FW module is followed by other modules code, they may be +either included in the preload or not, depending on the platform memory +availability. + +The ``preload_page_count`` is one of the ``AdspFwBinaryHeader`` parameters. +The header starts with “$AM1” tag (0x314D4124) and is located at offset 0x2000 +of the binary file. + +.. note:: All the binary file offsets specified by the Manifest are computed + relatively to the beginning of the Manifest. + +Preparing DMA to Transfer Binaries +================================== + +The driver programs the DMA engine that is used to transfer the binaries into +the DSP memory. It is either dedicated Code Load DMA if available, or one of +the HD/A host output DMAs otherwise. In the latter case the ROM Control IPC is +required since the DMA identifier must be passed to the DSP ROM in order to +program the DMA on the DSP side. + +Note that the DMA buffers are managed independently on the host side and the +DSP side. + +Loading Binaries +================ + +Once the DMA is ready, the driver loads the Base FW binary, waits for the FW +Ready IPC notification and then loads additional binaries (libraries/modules). + +.. note:: Loading additional modules must be finished before any stream is + opened for the first time and the DMA is reclaimed for HD/A streaming. + +The complete flow is illustrated in the next figure. + +.. uml:: images/loading-bins.pu + :caption: Loading FW Binaries to ADSP Memory + +The details of *_write(....binary)* step are illustrated in the next figure. + +.. uml:: images/write-bin.pu + :caption: Writing a Binary + +Booting with Boot Loader +************************ + +.. uml:: images/boot-ldr-flow.pu + :caption: SOF Boot Loader Flow diff --git a/architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/boot-dsp.pu b/architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/boot-dsp.pu new file mode 100644 index 00000000..59acf2df --- /dev/null +++ b/architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/boot-dsp.pu @@ -0,0 +1,21 @@ +actor Host +participant mw0 as "MemWnd0" +participant core0 as "DSP Core0" +participant rom as "DSP ROM" + +Host -> core0 : power up and reset + +Host -> rom : <> ROM Control(set_boot_config) +Host -> core0 : unstall + core0 -> rom : ResetVector() + activate rom + +Host -> mw0 : wait for(FSR_ROM_INIT_DONE) + + rom -> rom : Process ROM Control + + mw0 <- rom : FwRegsSetState(FSR_ROM_INIT_DONE) + +Host <-- mw0 + +Host -> Host : binaries loading diff --git a/architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/boot-ldr-flow.pu b/architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/boot-ldr-flow.pu new file mode 100644 index 00000000..643cca70 --- /dev/null +++ b/architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/boot-ldr-flow.pu @@ -0,0 +1,28 @@ +actor "ROM" as rom +box "boot_ldr @IMR" #6fccdd + participant ".boot_entry.text" as bup_be + participant ".text" as bup +end box +participant "sof" as fw + +rom -> bup_be : boot_entry() @boot_ldr.ep (boot_entry.S) + activate bup_be + bup_be -> bup_be : j boot_init: + note right: Platform specific actions (compilation flags)\n\ +- reset MHE\n\ +- disable L2$ + bup_be -> bup : call8 boot_pri_core() (boot_loader.c) + activate bup + bup -> bup : hp_sram_init() + opt defined(CONFIG_BOOT_LOADER) + bup -> bup : parse_manifest() + note right: copying of FW IMR -> SRAM done here + end + + bup -> bup : _ResetVector() + activate bup + bup -> fw : _MainEntry() @SOF_TEXT_START + fw -> fw : call0 _start + activate fw + fw -> fw : call main + activate fw diff --git a/architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/loading-bins.pu b/architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/loading-bins.pu new file mode 100644 index 00000000..0c0dedb6 --- /dev/null +++ b/architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/loading-bins.pu @@ -0,0 +1,41 @@ +actor host as "Host" +participant cldma as "CodeLoadDMA" +participant mw0 as "MemWnd0" +participant core0 as "DSP Core0" +participant rom as "DSP ROM" +participant fw as "DSP FW" + +activate rom +activate host +host -> cldma : init_host_side() + +rom -> cldma : init_dsp_side() +note right: Unified cAVS1.5+ flow + +host -> mw0 : wait for (FSR_ROM_INIT_DONE) + mw0 <- rom : FSR_ROM_INIT_DONE +host <-- mw0 + +host -> cldma : write(base fw binary) + cldma <- rom : read() : base fw manifest + rom -> rom : veirfy(base fw manifest) + cldma <- rom : read() : base fw code + mw0 <- rom : FSR_ROM_FW_ENTERED + + create fw + rom -> fw : start() + activate fw + fw -> fw : initialization() + host <- fw : <> FW Ready + deactivate fw + +loop libraries loading + host -> cldma : write(library binary) + host -> fw : <> Load Library + activate fw + cldma <- fw : read() : library manifest + fw -> fw : verify(library manifest) + cldma <- fw : read() : library code + host <-- fw + deactivate fw +end loop diff --git a/architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/write-bin.pu b/architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/write-bin.pu new file mode 100644 index 00000000..451ca627 --- /dev/null +++ b/architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/write-bin.pu @@ -0,0 +1,10 @@ +actor host as "Host" +participant cldma as "CodeLoadDMA" + +activate host +host -> host : read(): binary +host -> host : detect and strip Extended Manifest : binary_mft_code +host -> host : retrieve preload size (binary_mft_code) : preload_size + +host -> cldma : write (binary_mft_code, mft_size) +host -> cldma : write (binary_mft_code+mft_size, preload_size-mft_size) diff --git a/architectures/firmware/vendor-specific/vend-intel/cavs-boot/index.rst b/architectures/firmware/vendor-specific/vend-intel/cavs-boot/index.rst new file mode 100644 index 00000000..54ba2ef6 --- /dev/null +++ b/architectures/firmware/vendor-specific/vend-intel/cavs-boot/index.rst @@ -0,0 +1,17 @@ +.. _architecture-intel-cavs-boot: + +Booting up CAVS ADSP +#################### + +Intel has several generations of audio DSP. "CAVS" versions relate to the audio +DSP in Skylake Core and Apollo Lake Atom platforms onwards. + +Bay Trail, Cherry Trail, Braswell, Haswell, and Broadwell audio DSPs have a simpler +boot flow using memory copy and not authentication. + + +.. toctree:: + :maxdepth: 2 + + cavs-dsp-boot-overview + apollolake/index diff --git a/architectures/firmware/vendor-specific/vend-intel/images/idc-send-message.pu b/architectures/firmware/vendor-specific/vend-intel/images/idc-send-message.pu new file mode 100644 index 00000000..f19d027e --- /dev/null +++ b/architectures/firmware/vendor-specific/vend-intel/images/idc-send-message.pu @@ -0,0 +1,30 @@ +participant core0 +participant core1 +participant idc +participant platform + +core0 -> idc : idc_init() + activate idc + + idc -> platform : interrupt_register(irq, auto_unmask, irq_handler, idc) + activate platform + idc <-- platform + deactivate platform + +core0 <-- idc +deactivate idc + +core0 -> idc : idc_send_msg(idc_msg, mode) + activate idc + + idc -> core1 : irq_handler() + activate core1 + idc <-- core1 + deactivate core1 +core0 <-- idc +deactivate idc + +core1 -> idc : idc_do_cmd(data) + activate idc +idc <-- core1 +deactivate idc diff --git a/architectures/firmware/vendor-specific/vend-intel/index.rst b/architectures/firmware/vendor-specific/vend-intel/index.rst new file mode 100755 index 00000000..4f3ac9a7 --- /dev/null +++ b/architectures/firmware/vendor-specific/vend-intel/index.rst @@ -0,0 +1,13 @@ +.. _cavs-architecture-intel: + +Intel cAVS Architecture +####################### + +The details below are specific to Intel products with an audio DSP cAVS +architecture using SOF. + +.. toctree:: + :maxdepth: 1 + + cavs-boot/index + smp/index \ No newline at end of file diff --git a/architectures/firmware/vendor-specific/vend-intel/smp/index.rst b/architectures/firmware/vendor-specific/vend-intel/smp/index.rst new file mode 100644 index 00000000..5aff7fc0 --- /dev/null +++ b/architectures/firmware/vendor-specific/vend-intel/smp/index.rst @@ -0,0 +1,64 @@ +.. _architecture-intel-smp: + +Intel SMP Architecture +###################### + +Description +*********** + +SMP architecture is used in the environment, where multiple processors are +connected to a single shared memory, have access to all input and output +interfaces, and are controlled by a single operating system. In our case, +we have multiple Xtensa DSP cores, which use the same Firmware binary loaded +to the shared L2 SRAM, and are controlled by the same instance of the XTOS. + +Using SMP architecture +********************** + +|SOF| implementation of SMP architecture involves separate and modified XTOS, +which can be chosen by selecting appropriate arch flag during configuration +step of building FW binary. + +.. code-block:: bash + + ./configure --with-arch=xtensa-smp --with-platform= --with-dsp-core= --with-root-dir= --host= + +Implementation details +********************** + +The data structures critical to core execution need to be instantiated +per core, instead of being accessed using static pointers. +SMP implementation creates ``struct core_context`` to meet those demands. +This structure contains pointers to the XTOS data along with +``struct irq_task``, ``struct schedule_data``, ``struct work_queue`` etc. + +.. code-block:: c + + struct core_context { + struct thread_data td; + struct irq_task *irq_low_task; + struct irq_task *irq_med_task; + struct irq_task *irq_high_task; + struct schedule_data *sch; + struct work_queue *queue; + struct idc *idc; + }; + +``struct core_context`` is allocated by primary core for secondary cores before +secondary core boot. Address of the ``struct core_context`` is written into +``THREADPTR`` processor register, which can later be retrieved by the secondary core +after boot. Every core has its own instance of ``THREADPTR``, +so ``struct core_context`` address can be read anytime at any place of the code. + +Communication between cores +*************************** + +Primary core can communicate with secondary cores by sending messages using +the IDC mechanism. This mechanism is pretty much the same as IPC. +Important data can be sent in two 32-bit IDC registers. Cores use interrupts +to register for the incoming messages. + +.. uml:: ../images/idc-send-message.pu + +.. comment "master" has been replaced with "primary" +.. comment "slave" has been replaced with "secondary" \ No newline at end of file diff --git a/architectures/index.rst b/architectures/index.rst old mode 100644 new mode 100755 index b16f224b..a82a0be0 --- a/architectures/index.rst +++ b/architectures/index.rst @@ -8,7 +8,7 @@ not coupled to any particular DSP or host hardware architecture. The SOF |TSC| ensures that any DSP or host architecture specific code is partitioned to reside in architecture-specific directories with generic APIs to common code. -This section outlines the architecture at a high level, however the source code +This section outlines the architecture at a high level; however, the source code should always be consulted for the low level details. .. toctree:: @@ -16,3 +16,5 @@ should always be consulted for the low level details. host/index firmware/index + + From 618eed37e7a979c60b2d13283729be68a81b04bd Mon Sep 17 00:00:00 2001 From: Deb Taylor Date: Tue, 4 Oct 2022 17:41:58 -0600 Subject: [PATCH 054/150] Edit vendor-specific toc for better navigation; fix build breaks 4 (#434) Signed-off-by: Deb Signed-off-by: Deb --- .../cavs-boot/apollolake/apl-boot-ldr.rst | 20 --- .../cavs-boot/apollolake/apl-boot-rom.rst | 163 ------------------ .../apollolake/images/apl-rom-flow.pu | 59 ------- .../intel/cavs/cavs-boot/apollolake/index.rst | 10 -- .../cavs/cavs-boot/cavs-dsp-boot-overview.rst | 127 -------------- .../intel/cavs/cavs-boot/images/boot-dsp.pu | 21 --- .../cavs/cavs-boot/images/boot-ldr-flow.pu | 28 --- .../cavs/cavs-boot/images/loading-bins.pu | 41 ----- .../intel/cavs/cavs-boot/images/write-bin.pu | 10 -- .../firmware/intel/cavs/cavs-boot/index.rst | 17 -- .../intel/cavs/images/idc-send-message.pu | 30 ---- .../firmware/intel/cavs/smp/index.rst | 64 ------- .../firmware/sof-xtos/schedulers.rst | 2 +- .../rtos_layer/zephyr_kernel_overview.rst | 2 +- 14 files changed, 2 insertions(+), 592 deletions(-) delete mode 100644 architectures/firmware/intel/cavs/cavs-boot/apollolake/apl-boot-ldr.rst delete mode 100644 architectures/firmware/intel/cavs/cavs-boot/apollolake/apl-boot-rom.rst delete mode 100644 architectures/firmware/intel/cavs/cavs-boot/apollolake/images/apl-rom-flow.pu delete mode 100644 architectures/firmware/intel/cavs/cavs-boot/apollolake/index.rst delete mode 100755 architectures/firmware/intel/cavs/cavs-boot/cavs-dsp-boot-overview.rst delete mode 100644 architectures/firmware/intel/cavs/cavs-boot/images/boot-dsp.pu delete mode 100644 architectures/firmware/intel/cavs/cavs-boot/images/boot-ldr-flow.pu delete mode 100644 architectures/firmware/intel/cavs/cavs-boot/images/loading-bins.pu delete mode 100644 architectures/firmware/intel/cavs/cavs-boot/images/write-bin.pu delete mode 100644 architectures/firmware/intel/cavs/cavs-boot/index.rst delete mode 100644 architectures/firmware/intel/cavs/images/idc-send-message.pu delete mode 100644 architectures/firmware/intel/cavs/smp/index.rst mode change 100644 => 100755 architectures/firmware/sof-xtos/schedulers.rst mode change 100644 => 100755 architectures/firmware/sof-zephyr/rtos_layer/zephyr_kernel_overview.rst diff --git a/architectures/firmware/intel/cavs/cavs-boot/apollolake/apl-boot-ldr.rst b/architectures/firmware/intel/cavs/cavs-boot/apollolake/apl-boot-ldr.rst deleted file mode 100644 index 04fd5d0e..00000000 --- a/architectures/firmware/intel/cavs/cavs-boot/apollolake/apl-boot-ldr.rst +++ /dev/null @@ -1,20 +0,0 @@ -.. _apl-boot-ldr: - -Apollo Lake Boot Loader -####################### - -* Additional HPSRAM memory initialization. -* L2 cache disabled in ``boot_entry`` (enabled by default by APL ROM). - -Example list of sections in the APL boot_ldr:: - - Idx Name Size VMA LMA File off Algn - 0 .boot_entry.text 00000036 b000a000 b000a000 000000d4 2**2 - CONTENTS, ALLOC, LOAD, READONLY, CODE - 1 .boot_entry.literal 0000000c b000a040 b000a040 0000010c 2**2 - CONTENTS, ALLOC, LOAD, READONLY, CODE - 2 .text 000007d2 b000a0b0 b000a0b0 00000120 2**4 - CONTENTS, ALLOC, LOAD, READONLY, CODE - 3 .rodata 00000008 b0002000 b0002000 000008f4 2**2 - CONTENTS, ALLOC, LOAD, DATA - ... more debug sections ... diff --git a/architectures/firmware/intel/cavs/cavs-boot/apollolake/apl-boot-rom.rst b/architectures/firmware/intel/cavs/cavs-boot/apollolake/apl-boot-rom.rst deleted file mode 100644 index 5070e745..00000000 --- a/architectures/firmware/intel/cavs/cavs-boot/apollolake/apl-boot-rom.rst +++ /dev/null @@ -1,163 +0,0 @@ -.. _apl-boot-rom: - -Apollo Lake Boot ROM -#################### - -Progress of the boot process is reflected by the status information updated by -the ROM in an SRAM area called *FW Registers*. It is available to the host -driver through a memory window. - -ROM FW Registers -**************** - -This SRAM area updated by the ROM during the boot process is available via -memory window #0, the limit is set to 4K. - -Offset 0x00 - FwStatus - Current ROM status - -Offset 0x04 - ErrorCode - Last ROM error code - -Offset 0x08 - FwPwrStatus - Current DSP clock status (ToBeVerified on APL/CNL) - -FwStatus -======== - -The FwStatus register contains current FW status, initialized to 0 on the DSP -startup. - -The ErrorCode register is updated by ROM when *FwStatus* ``running`` bit is -set to “halted on critical error”, initialized to 0 (`ADSP_SUCCESS`) on the -DSP startup. - -Once Base FW is being executed, *ErrorCode* is updated every time some error is -detected while calling internal API components. Some of the error codes might be -helpful for driver writers hence documented in this specification. - -.. code-block:: c - - union fw_status_reg - { - int32_t full; - struct Bits - { - uint32_t state : 24; - uint32_t wait_state : 4; - uint32_t module : 3; - uint32_t running : 1; - } bits; - }; - -running - This field is used to report current FW running state. - 0 – running, - 1 – halted. - When FW reports halted state, ErrorCode register contains error - code. - -module - This field is used to report FW module (that indicates boot phase - component/module in this context, not a processing module) that is being - executed. - -wait_state - This field is updated to non-zero code of operation when ROM is waiting - for completion of that operation. - -state - This field is used to report phase of the FW module that is being executed. - When FW switches to another module (reported by Module field) this value - may get started again from 0, so it is Module context sensitive. - -.. uml:: images/apl-rom-flow.pu - :caption: APL ROM Boot Sequence - -.. code-block:: c - :caption: APL ROM Wait States - - // Waiting for IPC busy bit to be set - #define WAIT_FOR_IPC_BUSY 0x1 - // Waiting for IPC done bit to be set - #define WAIT_FOR_IPC_DONE 0x2 - // Waiting for L2$ invalidation to be ack'ed - #define WAIT_FOR_CACHE_INVALIDATION 0x3 - // Waiting for DMA buffer to be filled - #define WAIT_FOR_DMA_BUFFER_FULL 0x5 - -.. code-block:: c - :caption: APL ROM Status Codes - - #define FSR_ROM_INIT 0x0 - #define FSR_ROM_INIT_DONE 0x1 - #define FSR_ROM_CSE_MANIFEST_LOADED 0x2 - #define FSR_ROM_FW_MANIFEST_LOADED 0x3 - #define FSR_ROM_FW_FW_LOADED 0x4 - #define FSR_ROM_FW_ENTERED 0x5 - #define FSR_ROM_VERIFY_FEATURE_MASK 0x6 - #define FSR_ROM_GET_LOAD_OFFSET 0x7 - #define FSR_ROM_BASEFW_CSE_IMR_REQUEST 0x10 - #define FSR_ROM_BASEFW_CSE_IMR_GRANTED 0x11 - #define FSR_ROM_BASEFW_CSE_VALIDATE_IMAGE_REQUEST 0x12 - #define FSR_ROM_BASEFW_CSE_IMAGE_VALIDATED 0x13 - -.. code-block:: c - :caption: APL ROM Error Codes - - #define ADSP_UNHANDLED_INTERRUPT 0xBEE00000 - - // Memory hole/ECC error - // Status bits are provided: - // [0] - L2 SRAM ECC error - // [1] - L2 memory hole error - #define ADSP_MEMORY_HOLE_ECC 0xECC00000 - #define ADSP_USER_EXCEPTION 0xBEEF0000 - #define ADSP_KERNEL_EXCEPTION 0xCAFE0000 - - // Other critical error - #define ADSP_FAILURE 6 - // FW image does not match the feature mask read from HW register. - #define ADSP_INVALID_FEAT_MASK 20 - // Invalid parameter - #define ADSP_INVALID_PARAM 21 - // CSE responded with error on an IPC request - #define ADSP_CSE_ERROR 40 - // Invalid IPC response sent back by CSE. - #define ADSP_CSE_WRONG_RESPONSE 41 - // Size of IMR assigned by CSE is too small to load FW Image. - #define ADSP_IMR_TOO_SMALL 42 - // Base FW module not found in FW Image. - #define ADSP_BASE_FW_NOT_FOUND 43 - // CSE responded with error on FW image validation request. - #define ADSP_CSE_VALIDATION_FAILED 44 - // IPC communication failed with fatal error. - #define ADSP_IPC_FATAL_ERROR 45 - // L2 cache command failed. - #define ADSP_L2_CACHE_ERROR 46 - // Load offset set in FW Image Manifest is too small. - #define ADSP_LOAD_OFFSET_TOO_SMALL 47 - -ROM -> FW Transition -==================== - -Once APL ROM jumps to the entry point of the first module in the main binary, -the memory and caches are in the following state: - -* L2$ is turned on, so the FW boot procedure may either execute via L2 - cacheable address space or directly via L2 uncacheable alias. - -* HPSRAM areas allocated by the ROM listed in the next table. - -APL ROM HPSRAM Allocation -========================= - -+---------------------+------------+--------------+ -| Area | Base Addr | Size | -+=====================+============+==============+ -| Code load buffer | 0xBE008000 | 0x8000 (32K) | -+---------------------+------------+--------------+ -| BSS (inc. stack) | 0xBE010000 | 0x8000 (32K) | -+---------------------+------------+--------------+ -| FW Registers | 0xBE01E000 | 0x800 (2K) | -+---------------------+------------+--------------+ diff --git a/architectures/firmware/intel/cavs/cavs-boot/apollolake/images/apl-rom-flow.pu b/architectures/firmware/intel/cavs/cavs-boot/apollolake/images/apl-rom-flow.pu deleted file mode 100644 index 4624b4d1..00000000 --- a/architectures/firmware/intel/cavs/cavs-boot/apollolake/images/apl-rom-flow.pu +++ /dev/null @@ -1,59 +0,0 @@ -participant "State" as st -participant "Error" as err -participant "Host\nDriver" as host -participant "APL\nROM" as rom -participant "CSE" as cse - -host -> rom : <> RomControl (purge=1, dma_id) - -== Initialization == -rom -> rom : Boot - err <[#red]- rom : ADSP_UNHANDLED_INTERRUPT [anytime unhandled int reported] - err <[#red]- rom : ADSP_MEMORY_HOLE_ECC [anytime memory hole int reported] - err <[#red]- rom : ADSP_USER_EXCEPTION [anytime unhandled user mode exception happens] - err <[#red]- rom : ADSP_KERNEL_EXCEPTION [anytime unhandled kernel mode exception happens] - -rom -> rom : L2Cache Initialization - err <[#red]- rom : ADSP_L2_CACHE_ERROR [Failed to init L2$] - -rom -> rom : Requesting IMR - st <[#green]- rom : FSR_ROM_BASEFW_CSE_IMR_REQUEST - rom -> cse : <> IPC_ADSP2CSE_REQUEST_IMR - rom <- cse : <> IPC_CSE2ADSP_REQUEST_IMR_RESPONSE - st <[#green]- rom : FSR_ROM_BASEFW_CSE_IMR_GRANTED - -rom -> rom : Initializing Code Load DMA - err <[#red]- rom : ADSP_INVALID_PARAM [dma_id out of range] - -st <[#green]- rom : FSR_ROM_INIT_DONE - -== Loading Image == - rom -> rom : Loading Firmware - ' First fw image block is loaded and feature mask is verified - st <[#green]- rom : FSR_ROM_VERIFY_FEATURE_MASK - err <[#red]- rom : ADSP_INVALID_FEAT_MASK [mft mask does not match SKUID] - ' Load offset is verified - st <[#green]- rom : FSR_ROM_GET_LOAD_OFFSET - err <[#red]- rom : ADSP_LOAD_OFFSET_TOO_SMALL [load offset less then Rsvd space] - err <[#red]- rom : ADSP_IMR_TOO_SMALL [load offset greater than assigned IMR size] - ' CSE Manifest if loaded - rom -> rom : Loading CSE Manifest - err <[#red]- rom : ADSP_IMR_TOO_SMALL [CSE manifest > IMR size] - st <[#green]- rom : FSR_ROM_CSE_MANIFEST_LOADED - ' FW Manifest is loaded - rom -> rom : Loading ADSP FW Manifest - err <[#red]- rom : ADSP_IMR_TOO_SMALL [ADSP FW manifest > IMR size] - st <[#green]- rom : FSR_ROM_FW_MANIFEST_LOADED - err <[#red]- rom : ADSP_BASE_FW_NOT_FOUND [module entry not found in manifest] - ' Loading rest of FW - rom -> rom : Loading FW - st <[#green]- rom : FSR_ROM_FW_FW_LOADED - -== Authenticating Image == - st <[#green]- rom : FSR_ROM_BASEFW_CSE_VALIDATE_IMAGE_REQUEST - rom -> cse : <> IPC_CSE2ADSP_START_FW_AUTH - rom <- cse : <> IPC_CSE2ADSP_START_FW_AUTH_RESPONSE - err <[#red]- rom : ADSP_CSE_VALIDATION_FAILED [invalid image signature] - st <[#green]- rom : FSR_ROM_BASEFW_CSE_IMAGE_VALIDATED -== Booting FW == - st <[#green]- rom : FSR_ROM_FW_ENTERED diff --git a/architectures/firmware/intel/cavs/cavs-boot/apollolake/index.rst b/architectures/firmware/intel/cavs/cavs-boot/apollolake/index.rst deleted file mode 100644 index 21ee69cb..00000000 --- a/architectures/firmware/intel/cavs/cavs-boot/apollolake/index.rst +++ /dev/null @@ -1,10 +0,0 @@ -.. _cavs-boot-apl: - -Apollo Lake Boot Process -######################## - -.. toctree:: - :maxdepth: 1 - - apl-boot-rom - apl-boot-ldr diff --git a/architectures/firmware/intel/cavs/cavs-boot/cavs-dsp-boot-overview.rst b/architectures/firmware/intel/cavs/cavs-boot/cavs-dsp-boot-overview.rst deleted file mode 100755 index 24fde842..00000000 --- a/architectures/firmware/intel/cavs/cavs-boot/cavs-dsp-boot-overview.rst +++ /dev/null @@ -1,127 +0,0 @@ -.. _cavs-dsp-boot-overview: - -Overview -######## - -There are two main DSP boot flows: - -* **Cold boot** performed when the host CPU exits an Sx state. FW binaries are - loaded into DSP memory and full state re-initialization is required. This - flow is also referred as *Purge Flow* in the figures below. - -* **RTD3 boot** when the DSP state is restored from the DSP internal memory. - This flow is available on platforms with access to Isolated Memory Region - (IMR) allocated for the DSP. - -IPC Communication with DSP ROM -****************************** - -Once the primary DSP core (#0) is powered up and reset by the host driver, an -IPC communication with the DSP ROM is required in order to set the boot -options (see Boot Path Control Messages for details and list of platforms that -require this step). It is a one-way message that does not require a response -from the DSP. - -There may be some specific requirements about the order of the DSP core reset, -sending IPC message, and the DSP core unstall operations. It is assumed that -the following order is required unless specified otherwise by Boot Path -Control Message in case of a specific platform: - -1. Power up and reset the DSP Core 0, -#. Send ROM Control IPC, -#. Unstall DSP Core 0. - -The ROM Control IPC message includes “purge” parameter that should be set to 1 -in case of the cold boot. Otherwise it may be set to 0 after coming out of -RTD3 to attempt quicker state restore flow. In the latter case, the driver -just waits for FW Ready notification (no library loading is needed). - -The flow is illustrated in the next figure. - -.. uml:: images/boot-dsp.pu - -Loading Binaries to ADSP Memory -******************************* - -The ADSP FW binary code may be divided into: - -* The Base FW binary file, which contains FW infrastructure code (Base FW - module) required by all the platforms, optionally followed by other modules, - -* Set of libraries (modules) containing additional processing modules code - that may be optionally loaded into ADSP FW memory based on the platform’s - requirements and configuration. - -.. note:: This section contains general information about the structure of - binaries necessary to understand the loading process. For a complete - documentation refer to FW Binaries documentation. - -There are two main parts of the main binary: - -* Manifest, -* Modules binary code. - -Determining Part of Binary to be Loaded -======================================= - -The binary begins with the Manifest that is loaded into the DSP memory. The -Manifest contains ``preload_page_count`` parameter that determines part of the -binary to be loaded by the driver during the boot process. The preload size is -expressed in pages, where size of the page is 4096 bytes for all platforms. If -IMR is available and allocated for the DSP on the platform, the preload size -includes the entire binary. Otherwise it includes only the critical part of -the binary while other parts (so called loadable modules) may be loaded on -demand when needed (see Load Multiple Modules IPC) to limit SRAM usage and -save the power. - -For example, the Base FW binary file may be setup in a way that -``preload_page_count`` includes size of the Manifest as well as size of the -following Base FW module (it is always module 0 in the Base FW binary) since -its presence in the DSP memory is absolutely necessary for the boot to -complete. If the Base FW module is followed by other modules code, they may be -either included in the preload or not, depending on the platform memory -availability. - -The ``preload_page_count`` is one of the ``AdspFwBinaryHeader`` parameters. -The header starts with “$AM1” tag (0x314D4124) and is located at offset 0x2000 -of the binary file. - -.. note:: All the binary file offsets specified by the Manifest are computed - relatively to the beginning of the Manifest. - -Preparing DMA to Transfer Binaries -================================== - -The driver programs the DMA engine that is used to transfer the binaries into -the DSP memory. It is either dedicated Code Load DMA if available, or one of -the HD/A host output DMAs otherwise. In the latter case the ROM Control IPC is -required since the DMA identifier must be passed to the DSP ROM in order to -program the DMA on the DSP side. - -Note that the DMA buffers are managed independently on the host side and the -DSP side. - -Loading Binaries -================ - -Once the DMA is ready, the driver loads the Base FW binary, waits for the FW -Ready IPC notification and then loads additional binaries (libraries/modules). - -.. note:: Loading additional modules must be finished before any stream is - opened for the first time and the DMA is reclaimed for HD/A streaming. - -The complete flow is illustrated in the next figure. - -.. uml:: images/loading-bins.pu - :caption: Loading FW Binaries to ADSP Memory - -The details of *_write(....binary)* step are illustrated in the next figure. - -.. uml:: images/write-bin.pu - :caption: Writing a Binary - -Booting with Boot Loader -************************ - -.. uml:: images/boot-ldr-flow.pu - :caption: SOF Boot Loader Flow diff --git a/architectures/firmware/intel/cavs/cavs-boot/images/boot-dsp.pu b/architectures/firmware/intel/cavs/cavs-boot/images/boot-dsp.pu deleted file mode 100644 index 59acf2df..00000000 --- a/architectures/firmware/intel/cavs/cavs-boot/images/boot-dsp.pu +++ /dev/null @@ -1,21 +0,0 @@ -actor Host -participant mw0 as "MemWnd0" -participant core0 as "DSP Core0" -participant rom as "DSP ROM" - -Host -> core0 : power up and reset - -Host -> rom : <> ROM Control(set_boot_config) -Host -> core0 : unstall - core0 -> rom : ResetVector() - activate rom - -Host -> mw0 : wait for(FSR_ROM_INIT_DONE) - - rom -> rom : Process ROM Control - - mw0 <- rom : FwRegsSetState(FSR_ROM_INIT_DONE) - -Host <-- mw0 - -Host -> Host : binaries loading diff --git a/architectures/firmware/intel/cavs/cavs-boot/images/boot-ldr-flow.pu b/architectures/firmware/intel/cavs/cavs-boot/images/boot-ldr-flow.pu deleted file mode 100644 index 643cca70..00000000 --- a/architectures/firmware/intel/cavs/cavs-boot/images/boot-ldr-flow.pu +++ /dev/null @@ -1,28 +0,0 @@ -actor "ROM" as rom -box "boot_ldr @IMR" #6fccdd - participant ".boot_entry.text" as bup_be - participant ".text" as bup -end box -participant "sof" as fw - -rom -> bup_be : boot_entry() @boot_ldr.ep (boot_entry.S) - activate bup_be - bup_be -> bup_be : j boot_init: - note right: Platform specific actions (compilation flags)\n\ -- reset MHE\n\ -- disable L2$ - bup_be -> bup : call8 boot_pri_core() (boot_loader.c) - activate bup - bup -> bup : hp_sram_init() - opt defined(CONFIG_BOOT_LOADER) - bup -> bup : parse_manifest() - note right: copying of FW IMR -> SRAM done here - end - - bup -> bup : _ResetVector() - activate bup - bup -> fw : _MainEntry() @SOF_TEXT_START - fw -> fw : call0 _start - activate fw - fw -> fw : call main - activate fw diff --git a/architectures/firmware/intel/cavs/cavs-boot/images/loading-bins.pu b/architectures/firmware/intel/cavs/cavs-boot/images/loading-bins.pu deleted file mode 100644 index 0c0dedb6..00000000 --- a/architectures/firmware/intel/cavs/cavs-boot/images/loading-bins.pu +++ /dev/null @@ -1,41 +0,0 @@ -actor host as "Host" -participant cldma as "CodeLoadDMA" -participant mw0 as "MemWnd0" -participant core0 as "DSP Core0" -participant rom as "DSP ROM" -participant fw as "DSP FW" - -activate rom -activate host -host -> cldma : init_host_side() - -rom -> cldma : init_dsp_side() -note right: Unified cAVS1.5+ flow - -host -> mw0 : wait for (FSR_ROM_INIT_DONE) - mw0 <- rom : FSR_ROM_INIT_DONE -host <-- mw0 - -host -> cldma : write(base fw binary) - cldma <- rom : read() : base fw manifest - rom -> rom : veirfy(base fw manifest) - cldma <- rom : read() : base fw code - mw0 <- rom : FSR_ROM_FW_ENTERED - - create fw - rom -> fw : start() - activate fw - fw -> fw : initialization() - host <- fw : <> FW Ready - deactivate fw - -loop libraries loading - host -> cldma : write(library binary) - host -> fw : <> Load Library - activate fw - cldma <- fw : read() : library manifest - fw -> fw : verify(library manifest) - cldma <- fw : read() : library code - host <-- fw - deactivate fw -end loop diff --git a/architectures/firmware/intel/cavs/cavs-boot/images/write-bin.pu b/architectures/firmware/intel/cavs/cavs-boot/images/write-bin.pu deleted file mode 100644 index 451ca627..00000000 --- a/architectures/firmware/intel/cavs/cavs-boot/images/write-bin.pu +++ /dev/null @@ -1,10 +0,0 @@ -actor host as "Host" -participant cldma as "CodeLoadDMA" - -activate host -host -> host : read(): binary -host -> host : detect and strip Extended Manifest : binary_mft_code -host -> host : retrieve preload size (binary_mft_code) : preload_size - -host -> cldma : write (binary_mft_code, mft_size) -host -> cldma : write (binary_mft_code+mft_size, preload_size-mft_size) diff --git a/architectures/firmware/intel/cavs/cavs-boot/index.rst b/architectures/firmware/intel/cavs/cavs-boot/index.rst deleted file mode 100644 index 54ba2ef6..00000000 --- a/architectures/firmware/intel/cavs/cavs-boot/index.rst +++ /dev/null @@ -1,17 +0,0 @@ -.. _architecture-intel-cavs-boot: - -Booting up CAVS ADSP -#################### - -Intel has several generations of audio DSP. "CAVS" versions relate to the audio -DSP in Skylake Core and Apollo Lake Atom platforms onwards. - -Bay Trail, Cherry Trail, Braswell, Haswell, and Broadwell audio DSPs have a simpler -boot flow using memory copy and not authentication. - - -.. toctree:: - :maxdepth: 2 - - cavs-dsp-boot-overview - apollolake/index diff --git a/architectures/firmware/intel/cavs/images/idc-send-message.pu b/architectures/firmware/intel/cavs/images/idc-send-message.pu deleted file mode 100644 index f19d027e..00000000 --- a/architectures/firmware/intel/cavs/images/idc-send-message.pu +++ /dev/null @@ -1,30 +0,0 @@ -participant core0 -participant core1 -participant idc -participant platform - -core0 -> idc : idc_init() - activate idc - - idc -> platform : interrupt_register(irq, auto_unmask, irq_handler, idc) - activate platform - idc <-- platform - deactivate platform - -core0 <-- idc -deactivate idc - -core0 -> idc : idc_send_msg(idc_msg, mode) - activate idc - - idc -> core1 : irq_handler() - activate core1 - idc <-- core1 - deactivate core1 -core0 <-- idc -deactivate idc - -core1 -> idc : idc_do_cmd(data) - activate idc -idc <-- core1 -deactivate idc diff --git a/architectures/firmware/intel/cavs/smp/index.rst b/architectures/firmware/intel/cavs/smp/index.rst deleted file mode 100644 index 5aff7fc0..00000000 --- a/architectures/firmware/intel/cavs/smp/index.rst +++ /dev/null @@ -1,64 +0,0 @@ -.. _architecture-intel-smp: - -Intel SMP Architecture -###################### - -Description -*********** - -SMP architecture is used in the environment, where multiple processors are -connected to a single shared memory, have access to all input and output -interfaces, and are controlled by a single operating system. In our case, -we have multiple Xtensa DSP cores, which use the same Firmware binary loaded -to the shared L2 SRAM, and are controlled by the same instance of the XTOS. - -Using SMP architecture -********************** - -|SOF| implementation of SMP architecture involves separate and modified XTOS, -which can be chosen by selecting appropriate arch flag during configuration -step of building FW binary. - -.. code-block:: bash - - ./configure --with-arch=xtensa-smp --with-platform= --with-dsp-core= --with-root-dir= --host= - -Implementation details -********************** - -The data structures critical to core execution need to be instantiated -per core, instead of being accessed using static pointers. -SMP implementation creates ``struct core_context`` to meet those demands. -This structure contains pointers to the XTOS data along with -``struct irq_task``, ``struct schedule_data``, ``struct work_queue`` etc. - -.. code-block:: c - - struct core_context { - struct thread_data td; - struct irq_task *irq_low_task; - struct irq_task *irq_med_task; - struct irq_task *irq_high_task; - struct schedule_data *sch; - struct work_queue *queue; - struct idc *idc; - }; - -``struct core_context`` is allocated by primary core for secondary cores before -secondary core boot. Address of the ``struct core_context`` is written into -``THREADPTR`` processor register, which can later be retrieved by the secondary core -after boot. Every core has its own instance of ``THREADPTR``, -so ``struct core_context`` address can be read anytime at any place of the code. - -Communication between cores -*************************** - -Primary core can communicate with secondary cores by sending messages using -the IDC mechanism. This mechanism is pretty much the same as IPC. -Important data can be sent in two 32-bit IDC registers. Cores use interrupts -to register for the incoming messages. - -.. uml:: ../images/idc-send-message.pu - -.. comment "master" has been replaced with "primary" -.. comment "slave" has been replaced with "secondary" \ No newline at end of file diff --git a/architectures/firmware/sof-xtos/schedulers.rst b/architectures/firmware/sof-xtos/schedulers.rst old mode 100644 new mode 100755 index 3070599c..17d751d2 --- a/architectures/firmware/sof-xtos/schedulers.rst +++ b/architectures/firmware/sof-xtos/schedulers.rst @@ -1,4 +1,4 @@ -.. _schedulers: +.. _schedulers_xtos: Schedulers ########## diff --git a/architectures/firmware/sof-zephyr/rtos_layer/zephyr_kernel_overview.rst b/architectures/firmware/sof-zephyr/rtos_layer/zephyr_kernel_overview.rst old mode 100644 new mode 100755 index b6d0e3fb..e8e9ada2 --- a/architectures/firmware/sof-zephyr/rtos_layer/zephyr_kernel_overview.rst +++ b/architectures/firmware/sof-zephyr/rtos_layer/zephyr_kernel_overview.rst @@ -316,7 +316,7 @@ events that are already in the circular buffer will be dropped. .. TODO: Add link to SOF Telemetry interface documentation -.. _Schedulers: +.. _schedulers_zephyr: Schedulers ---------- From 30cfc411efbb726878ba7ed42d24a3a7bda1e04e Mon Sep 17 00:00:00 2001 From: Deb Date: Tue, 4 Oct 2022 18:00:02 -0600 Subject: [PATCH 055/150] remove unnecessary file Signed-off-by: Deb --- architectures/firmware/intel/cavs/index.rst | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100755 architectures/firmware/intel/cavs/index.rst diff --git a/architectures/firmware/intel/cavs/index.rst b/architectures/firmware/intel/cavs/index.rst deleted file mode 100755 index 4f3ac9a7..00000000 --- a/architectures/firmware/intel/cavs/index.rst +++ /dev/null @@ -1,13 +0,0 @@ -.. _cavs-architecture-intel: - -Intel cAVS Architecture -####################### - -The details below are specific to Intel products with an audio DSP cAVS -architecture using SOF. - -.. toctree:: - :maxdepth: 1 - - cavs-boot/index - smp/index \ No newline at end of file From 9839169bc1d896dc6131cb92150a07c52653d47e Mon Sep 17 00:00:00 2001 From: Deb Date: Tue, 4 Oct 2022 19:05:47 -0600 Subject: [PATCH 056/150] Add release 2.3 info Signed-off-by: Deb --- release.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.rst b/release.rst index 93fb89d8..922761a6 100755 --- a/release.rst +++ b/release.rst @@ -26,7 +26,7 @@ kernel, and documentation. Download the source code as a zip or tar.gz file: Source and Binary Releases -------------------------- -The latest SOF release is v2.2 (July 2022). +The latest SOF release is v2.3 (Oct 2022). View new feature information and release downloads for the latest and previous releases on GitHub. Firmware and SDK tool source code and binary From 5aaf07ab6fc8ad3503024406741c0923b3c1bfc1 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 4 Oct 2022 19:22:07 +0300 Subject: [PATCH 057/150] developer_guides: debugability: probes: Logging backend sof-probes update Added firmware kconfig options for enabling probes and logging backend. Also added notes about the latest updates for sof-probes demuxing tool. Signed-off-by: Jyri Sarha --- .../debugability/probes/index.rst | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/developer_guides/debugability/probes/index.rst b/developer_guides/debugability/probes/index.rst index dc019629..1984392a 100644 --- a/developer_guides/debugability/probes/index.rst +++ b/developer_guides/debugability/probes/index.rst @@ -65,6 +65,28 @@ Firmware side make menuconfig + The following options available + + Required for audio probes: + + .. code-block:: bash + + CONFIG_PROBE=y # enable probes + CONFIG_PROBE_POINTS_MAX=16 # max probepoints + + Required for logging through probes interface: + + .. code-block:: bash + + CONFIG_LOG_BACKEND_SOF_PROBE=y + CONFIG_ZEPHYR_LOG=y + + This option enables the probes logging automatically when probes extraction DMA is started: + + .. code-block:: bash + + CONFIG_LOG_BACKEND_SOF_PROBE_OUTPUT_AUTO_ENABLE=y + - Refer to **Step 3 Build firmware binaries** in :ref:`Build SOF from Scratch ` for reference. Note that you do not need to modify the audio topology file. @@ -101,6 +123,7 @@ the last stage of extraction. - Pause the playback stream. (optional) - Add probe points via the ``debugfs`` "probe_points" entry in ``/sys/kernel/debug/sof`` + For example, to add a buffer with 7 probe points: .. code-block:: bash @@ -159,4 +182,14 @@ Usage and ouput: sof-probes: done As a result, ``buffer_7.wav`` is generated in the *tools/build_tools/probes* folder. The wave file can then be examined with your tool of choice -such as ``Audacity``. \ No newline at end of file +such as ``Audacity``. + + +Simple logging case +******************* + +With the crecord and sof-probes in path, probes logging backend with auto enable option it is possible to get the firmware logs to stdout with this command combination: + +.. code-block:: bash + + crecord -c3 -d0 -b8192 -f4 -FS32_LE -R48000 -C4 | sof-probes -l From 510fc9df6b675deb3934185d1ab87a6731b7ed85 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 4 Oct 2022 19:26:53 +0300 Subject: [PATCH 058/150] developer_guides: debugability: probes: Fix misleading statement The statement about enabling a single probe point for buffer #7 was misleading. Signed-off-by: Jyri Sarha --- developer_guides/debugability/probes/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/developer_guides/debugability/probes/index.rst b/developer_guides/debugability/probes/index.rst index 1984392a..880328b1 100644 --- a/developer_guides/debugability/probes/index.rst +++ b/developer_guides/debugability/probes/index.rst @@ -124,7 +124,7 @@ the last stage of extraction. - Add probe points via the ``debugfs`` "probe_points" entry in ``/sys/kernel/debug/sof`` - For example, to add a buffer with 7 probe points: + For example, to add buffer 7 with a probe point: .. code-block:: bash From 30431cf5ed224019386460b1f17dea61a5c50451 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 4 Oct 2022 19:41:23 +0300 Subject: [PATCH 059/150] developer_guides: debugability: probes: Document IPC3 and IPC4 differences Signed-off-by: Jyri Sarha --- .../debugability/probes/index.rst | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/developer_guides/debugability/probes/index.rst b/developer_guides/debugability/probes/index.rst index 880328b1..0ef12784 100644 --- a/developer_guides/debugability/probes/index.rst +++ b/developer_guides/debugability/probes/index.rst @@ -124,7 +124,7 @@ the last stage of extraction. - Add probe points via the ``debugfs`` "probe_points" entry in ``/sys/kernel/debug/sof`` - For example, to add buffer 7 with a probe point: + For example, to add buffer 7 with a probe point (IPC3): .. code-block:: bash @@ -161,6 +161,52 @@ the last stage of extraction. strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 ? tw->sname : "none"); + For IPC4 system, the above example looks like this: + + .. code-block:: bash + + echo 2,0,0 > probe_points + + The semantics of the buffer_id are quite different on IPC4 system: + + .. code-block:: c + + typedef union probe_point_id { + uint32_t full_id; + struct { + uint32_t module_id : 16; /**< Target module ID */ + uint32_t instance_id : 8; /**< Target module instance ID */ + uint32_t type : 2; /**< Probe point type as specified by ProbeType enumeration */ + uint32_t index : 6; /**< Queue index inside target module */ + } fields; + } __attribute__((packed, aligned(4))) probe_point_id_t; + + .. code-block:: c + + /** + * Description of probe point + */ + struct probe_point { + probe_point_id_t buffer_id; /**< ID of buffer to which probe is attached */ + uint32_t purpose; /**< PROBE_PURPOSE_xxx */ + uint32_t stream_tag; /**< Stream tag of DMA via which data will be provided for injection. + * For extraction purposes, stream tag is ignored when received, + * but returned actual extraction stream tag via INFO function. + */ + } __attribute__((packed, aligned(4))); + +Enabling the log in IPC3 system (in case auto enable is not on): + + .. code-block:: bash + + echo 0,1,0 > probe_points + +And on IPC4 system: + + .. code-block:: bash + + echo 0,0,0 > probe_points + 2. Unpause the playback stream. (optional) #. Close the playback stream when done. #. Close the crecord tool. From 1f00d980a64b032365bca0274bad5d9d7c65192d Mon Sep 17 00:00:00 2001 From: Deb Date: Thu, 13 Oct 2022 17:05:00 -0500 Subject: [PATCH 060/150] correct naming structure under firmware Signed-off-by: Deb --- architectures/firmware/index.rst | 2 +- .../cavs}/cavs-boot/apollolake/apl-boot-ldr.rst | 0 .../cavs}/cavs-boot/apollolake/apl-boot-rom.rst | 0 .../cavs}/cavs-boot/apollolake/images/apl-rom-flow.pu | 0 .../vend-intel => intel/cavs}/cavs-boot/apollolake/index.rst | 0 .../cavs}/cavs-boot/cavs-dsp-boot-overview.rst | 0 .../vend-intel => intel/cavs}/cavs-boot/images/boot-dsp.pu | 0 .../vend-intel => intel/cavs}/cavs-boot/images/boot-ldr-flow.pu | 0 .../vend-intel => intel/cavs}/cavs-boot/images/loading-bins.pu | 0 .../vend-intel => intel/cavs}/cavs-boot/images/write-bin.pu | 0 .../vend-intel => intel/cavs}/cavs-boot/index.rst | 0 .../vend-intel => intel/cavs}/images/idc-send-message.pu | 0 .../{vendor-specific/vend-intel => intel/cavs}/index.rst | 0 .../{vendor-specific/vend-intel => intel/cavs}/smp/index.rst | 0 architectures/firmware/{vendor-specific => intel}/index.rst | 2 +- 15 files changed, 2 insertions(+), 2 deletions(-) rename architectures/firmware/{vendor-specific/vend-intel => intel/cavs}/cavs-boot/apollolake/apl-boot-ldr.rst (100%) rename architectures/firmware/{vendor-specific/vend-intel => intel/cavs}/cavs-boot/apollolake/apl-boot-rom.rst (100%) rename architectures/firmware/{vendor-specific/vend-intel => intel/cavs}/cavs-boot/apollolake/images/apl-rom-flow.pu (100%) rename architectures/firmware/{vendor-specific/vend-intel => intel/cavs}/cavs-boot/apollolake/index.rst (100%) rename architectures/firmware/{vendor-specific/vend-intel => intel/cavs}/cavs-boot/cavs-dsp-boot-overview.rst (100%) rename architectures/firmware/{vendor-specific/vend-intel => intel/cavs}/cavs-boot/images/boot-dsp.pu (100%) rename architectures/firmware/{vendor-specific/vend-intel => intel/cavs}/cavs-boot/images/boot-ldr-flow.pu (100%) rename architectures/firmware/{vendor-specific/vend-intel => intel/cavs}/cavs-boot/images/loading-bins.pu (100%) rename architectures/firmware/{vendor-specific/vend-intel => intel/cavs}/cavs-boot/images/write-bin.pu (100%) rename architectures/firmware/{vendor-specific/vend-intel => intel/cavs}/cavs-boot/index.rst (100%) rename architectures/firmware/{vendor-specific/vend-intel => intel/cavs}/images/idc-send-message.pu (100%) rename architectures/firmware/{vendor-specific/vend-intel => intel/cavs}/index.rst (100%) rename architectures/firmware/{vendor-specific/vend-intel => intel/cavs}/smp/index.rst (100%) rename architectures/firmware/{vendor-specific => intel}/index.rst (94%) diff --git a/architectures/firmware/index.rst b/architectures/firmware/index.rst index f44e7ae3..839ff2e4 100755 --- a/architectures/firmware/index.rst +++ b/architectures/firmware/index.rst @@ -8,4 +8,4 @@ Firmware Architecture sof-xtos/index sof-zephyr/index - vendor-specific/index \ No newline at end of file + intel/index \ No newline at end of file diff --git a/architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/apl-boot-ldr.rst b/architectures/firmware/intel/cavs/cavs-boot/apollolake/apl-boot-ldr.rst similarity index 100% rename from architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/apl-boot-ldr.rst rename to architectures/firmware/intel/cavs/cavs-boot/apollolake/apl-boot-ldr.rst diff --git a/architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/apl-boot-rom.rst b/architectures/firmware/intel/cavs/cavs-boot/apollolake/apl-boot-rom.rst similarity index 100% rename from architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/apl-boot-rom.rst rename to architectures/firmware/intel/cavs/cavs-boot/apollolake/apl-boot-rom.rst diff --git a/architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/images/apl-rom-flow.pu b/architectures/firmware/intel/cavs/cavs-boot/apollolake/images/apl-rom-flow.pu similarity index 100% rename from architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/images/apl-rom-flow.pu rename to architectures/firmware/intel/cavs/cavs-boot/apollolake/images/apl-rom-flow.pu diff --git a/architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/index.rst b/architectures/firmware/intel/cavs/cavs-boot/apollolake/index.rst similarity index 100% rename from architectures/firmware/vendor-specific/vend-intel/cavs-boot/apollolake/index.rst rename to architectures/firmware/intel/cavs/cavs-boot/apollolake/index.rst diff --git a/architectures/firmware/vendor-specific/vend-intel/cavs-boot/cavs-dsp-boot-overview.rst b/architectures/firmware/intel/cavs/cavs-boot/cavs-dsp-boot-overview.rst similarity index 100% rename from architectures/firmware/vendor-specific/vend-intel/cavs-boot/cavs-dsp-boot-overview.rst rename to architectures/firmware/intel/cavs/cavs-boot/cavs-dsp-boot-overview.rst diff --git a/architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/boot-dsp.pu b/architectures/firmware/intel/cavs/cavs-boot/images/boot-dsp.pu similarity index 100% rename from architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/boot-dsp.pu rename to architectures/firmware/intel/cavs/cavs-boot/images/boot-dsp.pu diff --git a/architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/boot-ldr-flow.pu b/architectures/firmware/intel/cavs/cavs-boot/images/boot-ldr-flow.pu similarity index 100% rename from architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/boot-ldr-flow.pu rename to architectures/firmware/intel/cavs/cavs-boot/images/boot-ldr-flow.pu diff --git a/architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/loading-bins.pu b/architectures/firmware/intel/cavs/cavs-boot/images/loading-bins.pu similarity index 100% rename from architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/loading-bins.pu rename to architectures/firmware/intel/cavs/cavs-boot/images/loading-bins.pu diff --git a/architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/write-bin.pu b/architectures/firmware/intel/cavs/cavs-boot/images/write-bin.pu similarity index 100% rename from architectures/firmware/vendor-specific/vend-intel/cavs-boot/images/write-bin.pu rename to architectures/firmware/intel/cavs/cavs-boot/images/write-bin.pu diff --git a/architectures/firmware/vendor-specific/vend-intel/cavs-boot/index.rst b/architectures/firmware/intel/cavs/cavs-boot/index.rst similarity index 100% rename from architectures/firmware/vendor-specific/vend-intel/cavs-boot/index.rst rename to architectures/firmware/intel/cavs/cavs-boot/index.rst diff --git a/architectures/firmware/vendor-specific/vend-intel/images/idc-send-message.pu b/architectures/firmware/intel/cavs/images/idc-send-message.pu similarity index 100% rename from architectures/firmware/vendor-specific/vend-intel/images/idc-send-message.pu rename to architectures/firmware/intel/cavs/images/idc-send-message.pu diff --git a/architectures/firmware/vendor-specific/vend-intel/index.rst b/architectures/firmware/intel/cavs/index.rst similarity index 100% rename from architectures/firmware/vendor-specific/vend-intel/index.rst rename to architectures/firmware/intel/cavs/index.rst diff --git a/architectures/firmware/vendor-specific/vend-intel/smp/index.rst b/architectures/firmware/intel/cavs/smp/index.rst similarity index 100% rename from architectures/firmware/vendor-specific/vend-intel/smp/index.rst rename to architectures/firmware/intel/cavs/smp/index.rst diff --git a/architectures/firmware/vendor-specific/index.rst b/architectures/firmware/intel/index.rst similarity index 94% rename from architectures/firmware/vendor-specific/index.rst rename to architectures/firmware/intel/index.rst index 6a4e56ee..de288ec2 100755 --- a/architectures/firmware/vendor-specific/index.rst +++ b/architectures/firmware/intel/index.rst @@ -10,4 +10,4 @@ generic SOF architecture. .. toctree:: :maxdepth: 1 - vend-intel/index \ No newline at end of file + cavs/index \ No newline at end of file From 2371a1d23a5ef73984595de1f8b2843d9f1e490f Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Wed, 6 Apr 2022 14:34:51 +0200 Subject: [PATCH 061/150] sphinx blockdiag support sphinxcontrib-blockdiag extension added to generate diagrams from the code Signed-off-by: Michal Wasko --- conf.py | 2 +- scripts/requirements-lax.txt | 2 +- scripts/requirements.txt | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/conf.py b/conf.py index b57e4291..61b5957d 100755 --- a/conf.py +++ b/conf.py @@ -31,7 +31,7 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = ['breathe', 'sphinx.ext.graphviz', 'sphinxcontrib.plantuml', - 'sphinx.ext.todo', 'sphinx.ext.extlinks', + 'sphinx.ext.todo', 'sphinx.ext.extlinks', 'sphinxcontrib.blockdiag' ] diff --git a/scripts/requirements-lax.txt b/scripts/requirements-lax.txt index b6cb59af..7287ddf0 100644 --- a/scripts/requirements-lax.txt +++ b/scripts/requirements-lax.txt @@ -13,6 +13,7 @@ breathe>=4.7.3 sphinx>=1.6.7 docutils>=0.14 sphinx_rtd_theme>=0.2.4 +sphinxcontrib-blockdiag>=3.0.0 # - Version 0.11 is the first version that supports # `plantuml_output_format=none` which is required for instant builds. @@ -29,7 +30,6 @@ sphinx_rtd_theme>=0.2.4 # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=896485#12 sphinxcontrib.plantuml>=0.11,<0.25 - # Differences between these "lax" version requirements and the official # ones in requirements.txt: diff --git a/scripts/requirements.txt b/scripts/requirements.txt index 516d4e06..bc8d82c1 100644 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -5,3 +5,4 @@ sphinx==2.4.4 docutils==0.16 sphinx_rtd_theme sphinxcontrib-plantuml +sphinxcontrib-blockdiag From 6ec5940222f8a0ec7bdda50c68e4353a476eaa8b Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Thu, 31 Mar 2022 17:37:47 +0200 Subject: [PATCH 062/150] arch: fw: mpp scheduling using zephyr SOF MPP scheduling description and flows using zephyr rtos infrastructure Signed-off-by: Michal Wasko --- .../images/mpp_scheduling/edf_scheduling.diag | 39 +++ .../example_DP_secondary_core_timeline.pu | 136 ++++++++ .../mpp_scheduling/example_LL_DP_timeline.pu | 95 ++++++ .../example_multiple_cores_timeline.pu | 108 +++++++ .../example_task_with_budget.pu | 50 +++ .../mpp_scheduling/schedulers_diagram.pu | 60 ++++ .../schedulers_threads_periodic_update.pu | 38 +++ .../mpp_scheduling/schedulers_zephyr.pu | 88 +++++ .../firmware/sof-zephyr/mpp_layer/index.rst | 1 + .../sof-zephyr/mpp_layer/mpp_scheduling.rst | 302 ++++++++++++++++++ 10 files changed, 917 insertions(+) create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/edf_scheduling.diag create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/example_DP_secondary_core_timeline.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/example_LL_DP_timeline.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/example_multiple_cores_timeline.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/example_task_with_budget.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/schedulers_diagram.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/schedulers_threads_periodic_update.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/schedulers_zephyr.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/mpp_scheduling.rst diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/edf_scheduling.diag b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/edf_scheduling.diag new file mode 100644 index 00000000..46a3e974 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/edf_scheduling.diag @@ -0,0 +1,39 @@ +blockdiag edf_scheduling { + + node_width = 250; + node_height = 120; + default_fontsize = 16; + + Comp_1 -> Comp_2 + comment_1 -> Comp_2 [style=dashed] + Comp_2 -> Comp_3 + comment_2 -> Comp_3 [style=dashed] + Comp_3 -> Comp_4 + comment_3 -> Comp_4 [style=dashed] + Comp_4 -> sink + comment_4 -> sink [style=dashed] + + Comp_1 [label="DP component 1\n + *processing period\n + *compute requirement"] + Comp_2 [label="DP component 2\n + *processing period\n + *compute requirement"] + Comp_3 [label="DP component 3\n + *processing period\n + *compute requirement"] + Comp_4 [label="DP component 4\n + *processing period\n + *compute requirement"] + + sink [label="real time sink", shape=endpoint, fontsize = 16] + + comment_1 [label="DP1 to deliver data let\n + DP2 meet its objective"] + comment_2 [label="DP2 to deliver data let\n + DP3 meet its objective"] + comment_3 [label="DP3 to deliver data let\n + DP4 meet its objective"] + comment_4 [label="DP4 to deliver data\n + to real time-sink"] +} diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/example_DP_secondary_core_timeline.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/example_DP_secondary_core_timeline.pu new file mode 100644 index 00000000..2d3e35c9 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/example_DP_secondary_core_timeline.pu @@ -0,0 +1,136 @@ +@startuml + +Title DP tasks scheduling on secondary DSP core + +legend +Assumptions: +1) 1ms scheduling +2) No LL tasks assigned to example secondary DSP core +3) DP Task B do not depend on Task A completion +(otherwise, Task B would start on next timer interrupt after A +completion) +end legend + +scale 1 as 150 pixels + +concise "Task B" as Task_B +concise "Task A" as Task_A + +concise "DP task processing" as DP_Processing +robust "DSP" as DSP +concise "Timer interrupt" as Interrupt + + +@Task_A +0 is Busy +1.5 is {-} + +4 is Busy +5.5 is {-} + +8 is Busy +9.5 is {-} + +@0 <-> @4: Task A schedule period (4ms) +@4 <-> @5.5: Task A execution time (1.5ms) + +DP_Processing@0 -[#Orange]> Task_A@0 +DP_Processing@1 -[#Orange]> Task_A@1 +DP_Processing@1.5 -[#Orange]> Task_A@1.5 + + +@Task_B +0 is Busy +2 is {-} + +6 is Busy +8 is {-} + +@0 <-> @6: Task B schedule period (6ms) +@6 <-> @8: Task B execution time (2ms) + +DP_Processing@1.5 -[#Brown]> Task_B@0 +DP_Processing@2 -[#Brown]> Task_B@0.5 +DP_Processing@3 -[#Brown]> Task_B@1.5 +DP_Processing@3.5 -[#Brown]> Task_B@2 + +DSP is Idle +DP_Processing is {-} + +@0 +DP_Processing is "A" + +@0 +Interrupt -[#DarkViolet]> DSP +DSP -> DP_Processing +DSP is "Scheduling" +DP_Processing is "A" + +@1 +Interrupt -[#DarkViolet]> DSP +DSP -> DP_Processing +DP_Processing is "A" + +@1.5 +DP_Processing -> DSP +DSP -> DP_Processing +DP_Processing is "B" + +@2 +Interrupt -[#DarkViolet]> DSP +DSP -> DP_Processing +DP_Processing is "B" + +@3 +Interrupt -[#DarkViolet]> DSP +DSP -> DP_Processing +DP_Processing is "B" + +@3.5 +DP_Processing -> DSP +DSP is Idle +DP_Processing is {-} + +@4 +Interrupt -[#DarkViolet]> DSP +DSP is "Scheduling" +DSP -> DP_Processing +DP_Processing is "A" + +@5 +Interrupt -[#DarkViolet]> DSP +DSP -> DP_Processing +DP_Processing is "A" + +@5.5 +DP_Processing -> DSP +DSP is Idle +DP_Processing is {-} + +@6.001 +Interrupt -[#DarkViolet]> DSP +DSP -> DP_Processing +DSP is "Scheduling" +DP_Processing is "B" + +@7.001 +Interrupt -[#DarkViolet]> DSP +DSP -> DP_Processing +DP_Processing is "B" + +@8.001 +Interrupt -[#DarkViolet]> DSP +DSP -> DP_Processing +DP_Processing is "A" + +@9.001 +Interrupt -[#DarkViolet]> DSP +DSP -> DP_Processing +DP_Processing is "A" + +@9.5 +DP_Processing -> DSP +DSP is Idle +DP_Processing is {-} + +@enduml diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/example_LL_DP_timeline.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/example_LL_DP_timeline.pu new file mode 100644 index 00000000..74a91cce --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/example_LL_DP_timeline.pu @@ -0,0 +1,95 @@ +@startuml + +Title Task scheduling on DSP core + +legend +Assumptions: +1) 1ms scheduling +2) 0.1ms takes LL task execution +3) 0.5ms takes execution of all DP tasks +end legend + +scale 1 as 200 pixels + +concise "DP Tasks Processing" as DP_Processing +concise "LL Tasks Processing" as LL_Processing +robust "DSP" as DSP +concise "Timer Interrupt" as Interrupt + +DSP is Idle + +@DSP +@1.2 <-> @2: Time available for\nDP tasks execution +@2.2 <-> @2.7: Actual execution time\nof DP tasks +@3 <-> @3.2: Actual execution time\nof LL tasks + +@Interrupt +@0 <-> @1 : Schedule period + +@0 +Interrupt -> DSP +DSP -> LL_Processing +DSP is "Scheduling tasks" +LL_Processing is Busy +DP_Processing is {-} + +@+0.2 +DSP -> DP_Processing +LL_Processing is {-} +DP_Processing is Busy + +@+0.5 +DP_Processing -> DSP +DP_Processing is {-} +DSP is Idle + +@1 +Interrupt -> DSP +DSP -> LL_Processing +DSP is "Scheduling tasks" +LL_Processing is Busy + +@+0.2 +DSP -> DP_Processing +LL_Processing is {-} +DP_Processing is Busy + +@+0.5 +DP_Processing -> DSP +DP_Processing is {-} +DSP is Idle + +@2 +Interrupt -> DSP +DSP -> LL_Processing +DSP is "Scheduling tasks" +LL_Processing is Busy + +@+0.2 +DSP -> DP_Processing +LL_Processing is {-} +DP_Processing is Busy + +@+0.5 +DP_Processing -> DSP +DP_Processing is {-} +DSP is Idle + +@3 +Interrupt -> DSP +DSP -> LL_Processing +DSP is "Scheduling tasks" +LL_Processing is Busy + +@+0.2 +DSP -> DP_Processing + +LL_Processing is {-} +DP_Processing is Busy + +@+0.5 +DP_Processing -> DSP +DP_Processing is {-} +DSP is Idle + +@enduml diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/example_multiple_cores_timeline.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/example_multiple_cores_timeline.pu new file mode 100644 index 00000000..1aa419e7 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/example_multiple_cores_timeline.pu @@ -0,0 +1,108 @@ +@startuml + +Title Tasks scheduling on multiple DSP cores + +legend +Assumptions: +1) 1ms system tick + +Notes: +2) Core #0 has only LL tasks assigned schedule in 1ms period +3) Core #1 has one DP task assigned that is dependent on Core #0 LL tasks data, scheduled in 1ms period +(e.g. multicore pipeline with DP module scheduled on separate core) +4) Core #2 has LL tasks scheduled in 1ms period and DP task scheduled in 2ms period +(e.g. pipeline processing with LL and DP components components where DP component has 2ms scheduling period) +end legend + +scale 1 as 300 pixels + +concise "DSP #2" as DSP_2 +concise "DSP #1" as DSP_1 +concise "DSP #0" as DSP_0 + +concise "Timer interrupt" as Interrupt + +@DSP_0 +0 is "LL proc." +0.5 is {-} + +1 is "LL proc." +1.5 is {-} + +2 is "LL proc." +2.5 is {-} + +3 is "LL proc." +3.5 is {-} + +4 is "LL proc." +4.5 is {-} + +@0 <-> @1: DSP#0 LL schedule period (1ms) + +@DSP_1 +0 is {-} + +1 is "DP proc." +1.6 is {-} + +2 is "DP proc." +2.6 is {-} + +3 is "DP proc." +3.6 is {-} + +4 is "DP proc." +4.6 is {-} +5 is {-} + +@0 <-> @1: delay one period (waiting for first DSP#0 LL data) +@1 <-> @2: DSP#1 DP schedule period (1ms) + +@DSP_2 + +0 is "LL proc." +0.3 is {-} + +1 is "LL proc." +1.3 is {-} + +2 is "LL proc." +2.3 is "DP proc." + +3 is "LL proc." +3.3 is "DP proc." +3.7 is {-} + +4 is "LL proc." +4.3 is "DP proc." + +@0 <-> @1: DSP#2 LL schedule period (1ms) +@2.3 <-> @4.3: DSP#2 DP schedule period (2ms) + +@0 +Interrupt -[#DarkViolet]> DSP_0 +Interrupt -[#DarkViolet]> DSP_1 +Interrupt -[#DarkViolet]> DSP_2 + +@1 +Interrupt -[#DarkViolet]> DSP_0 +Interrupt -[#DarkViolet]> DSP_1 +Interrupt -[#DarkViolet]> DSP_2 + +@2 +Interrupt -[#DarkViolet]> DSP_0 +Interrupt -[#DarkViolet]> DSP_1 +Interrupt -[#DarkViolet]> DSP_2 + +@3 +Interrupt -[#DarkViolet]> DSP_0 +Interrupt -[#DarkViolet]> DSP_1 +Interrupt -[#DarkViolet]> DSP_2 + +@4 +Interrupt -[#DarkViolet]> DSP_0 +Interrupt -[#DarkViolet]> DSP_1 +Interrupt -[#DarkViolet]> DSP_2 + +@enduml diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/example_task_with_budget.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/example_task_with_budget.pu new file mode 100644 index 00000000..c4b27de9 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/example_task_with_budget.pu @@ -0,0 +1,50 @@ +@startuml + +skinparam maxMessageSize 400 +skinparam BoxPadding 4 + +box "SOF Firmware" #LightBlue + participant "Firmware Manager" + participant "MPP Scheduling" + participant "Zephyr Scheduler" + participant "Zephyr Thread" +end box + +activate "Zephyr Scheduler" + +"Zephyr Scheduler"-> "Zephyr Thread": schedule IPC Task with Budget (TWB) thread\n(MEDIUM_PRIO) +activate "Zephyr Thread" + + "Zephyr Thread"-> "Zephyr Thread": run + "Zephyr Thread"-> "MPP Scheduling": on processing complete + activate "MPP Scheduling" + "MPP Scheduling"-> "Zephyr Thread": k_thread_runtime_stats_get + activate "Zephyr Thread" + return + "MPP Scheduling"-> "MPP Scheduling": update IPC Task with budget\ncycles_consumed_in_sys_tick + return + "Zephyr Thread"-> "Zephyr Thread": suspend TWB Zephyr Thread\n(k_sem_take) +return + +"Zephyr Scheduler"-> "Zephyr Thread": schedule EDF thread\n(LOW_PRIO) +activate "Zephyr Thread" + "Zephyr Thread"-> "Zephyr Thread": run + + activate "Firmware Manager" + "Firmware Manager"-> "Firmware Manager": Host IPC message received + "Firmware Manager"-> "MPP Scheduling": request IPC processing + activate "MPP Scheduling" + "MPP Scheduling"-> "Zephyr Thread": resume IPC TWB Zephyr Thread\n(k_sem_give) + "MPP Scheduling" --> "Firmware Manager" + deactivate "MPP Scheduling" + deactivate "Firmware Manager" + +"Zephyr Thread" --> "Zephyr Scheduler": EDF thread gets preempted +deactivate "Zephyr Thread" + +"Zephyr Scheduler"-> "Zephyr Thread": schedule IPC task with budget thread\n(MEDIUM_PRIO) + activate "Zephyr Thread" + "Zephyr Thread"-> "Zephyr Thread": run + return + +@enduml diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/schedulers_diagram.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/schedulers_diagram.pu new file mode 100644 index 00000000..b7e6895a --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/schedulers_diagram.pu @@ -0,0 +1,60 @@ +@startuml +allowmixing + +scale max 1280 width + +package “RTOS layer” { + + package "SOF kernel extension" as KERNEL_EXTENSION { + package "MPP Scheduling" as MPP_SCHEDULING { + component "LL Tasks" as LL_TASKS + component "DP Tasks" as DP_TASKS + component "Tasks with Budget" as TWB + component "Idle Tasks" as IDLE_TASKS + + LL_TASKS -[hidden]right- DP_TASKS + DP_TASKS -[hidden]right- TWB + TWB -[hidden]right- IDLE_TASKS + } + } + + package "Zephyr" as ZEPHYR_LAYER { + package "Services" as SERVICES { + component "Timing" as TIMING + component "Interrupts" as INTERRUPTS + } + + package "Scheduling" as SCHEDULING { + component "Threads" as THREADS + component "EDF Scheduler" as EDF + component "Time-Slice Scheduler" as TIME_SLICE_SCHEDULING + + THREADS -[hidden]right- EDF + EDF -[hidden]right- TIME_SLICE_SCHEDULING + } + + package "Drivers" as DRIVERS { + component "Timer" as TIMER_DRV + component "Watchdog" as WATCHDOG_DRV + } + + package “SoC HAL” as SOC_HAL { + component "OEM SoC 1" as OEM_SOC_1 + component "OEM SoC 2" as OEM_SOC_2 + component "Other SoCs" as OTHER_SOCS + } + + component "XTHAL" as XTHAL + + SERVICES -[hidden]right- SCHEDULING + SERVICES -[hidden]down- XTHAL + SCHEDULING -[hidden]down- SOC_HAL + SCHEDULING -[hidden]down- DRIVERS + DRIVERS -[hidden]right- SOC_HAL + DRIVERS -[hidden]right- XTHAL + } + + KERNEL_EXTENSION -[hidden]down- ZEPHYR_LAYER +} + +@enduml diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/schedulers_threads_periodic_update.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/schedulers_threads_periodic_update.pu new file mode 100644 index 00000000..5eee1041 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/schedulers_threads_periodic_update.pu @@ -0,0 +1,38 @@ +@startuml + +scale max 1280 width + +skinparam maxMessageSize 400 +skinparam BoxPadding 4 + +box "SOF Firmware" #LightBlue + participant "MPP Scheduling" + participant "Zephyr Thread" + participant "Timer" +end box + +"Timer" -> "MPP Scheduling": sys_tick callback +activate "MPP Scheduling" + +loop for each Task with Budget + "MPP Scheduling"-> "MPP Scheduling": reset task with budget\ncycles_consumed_in_sys_tick + "MPP Scheduling" -> "Zephyr Thread": k_thread_priority_set(thread, MEDIUM_PRIO) + "MPP Scheduling" -> "Zephyr Thread": k_thread_time_slice_set(thread, slice_ticks = budget) + note right: Reset priority and budget\nto default value + "MPP Scheduling"-> "Zephyr Thread": k_thread_runtime_stats_get(thread) + activate "Zephyr Thread" + return return thread_cycles - absolute number of cycles consumed + "MPP Scheduling"-> "MPP Scheduling": save thread_ref_cycles = thread_cycles as a reference +end + +loop for each DP task + opt if DP task is ready for processing + "MPP Scheduling"-> "MPP Scheduling": re-calculate task deadline + "MPP Scheduling" -> "Zephyr Thread": k_thread_deadline_set(thread, deadline) + "MPP Scheduling" -> "Zephyr Thread": resume thread + end +end + +deactivate "MPP Scheduling" + +@enduml diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/schedulers_zephyr.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/schedulers_zephyr.pu new file mode 100644 index 00000000..834b28c4 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/schedulers_zephyr.pu @@ -0,0 +1,88 @@ +@startuml + +scale max 1280 width + +skinparam maxMessageSize 400 +skinparam BoxPadding 4 + +box "SOF" #LightBlue + participant "MPP Scheduling" + participant "Zephyr Scheduler" + participant "Zephyr Thread" + participant "Timer" +end box + +"Timer" -> "MPP Scheduling": sys_tick callback +activate "MPP Scheduling" + loop for each core + "MPP Scheduling"-> "Zephyr Scheduler": resume LL Zephyr Thread\n(k_sem_give) + activate "Zephyr Scheduler" + end + + "MPP Scheduling"-> "MPP Scheduling": DP and Task with Budget\nZephyr Threads update + +"Zephyr Scheduler"-> "Zephyr Thread": schedule LL Zephyr Thread\n(context switch) + deactivate "MPP Scheduling" + activate "Zephyr Thread" + "Zephyr Thread"-> "Zephyr Thread": zephyr_ll_run + activate "Zephyr Thread" + + loop for each LL pending task + note left: LL pending tasks are scheduled operations\nthat are waiting for certain circumstances\n(like data arrival) to start processing + opt if task is ready for processing + "Zephyr Thread"-> "Zephyr Thread": move task \nto LL run queue + end + end + + loop for each task in LL queues + "Zephyr Thread"-> "Zephyr Thread": run LL task callback + end + return + + "Zephyr Thread"-> "Zephyr Thread": suspend LL Zephyr Thread\n(k_sem_take) + return + +loop for each Task With Budget (TwB) Zephyr Thread + "Zephyr Scheduler"-> "Zephyr Thread": schedule TwB Zephyr Thread\n(context switch) + activate "Zephyr Thread" + "Zephyr Thread"-> "Zephyr Thread": run + + alt if time_slice (budget) timeout + "Zephyr Thread"-> "Zephyr Scheduler": time_slice timeout + "Zephyr Scheduler"-> "MPP Scheduling": time_slice callback(thread) + activate "MPP Scheduling" + "MPP Scheduling"-> "Zephyr Thread": k_thread_priority_set(thread, LOW_PRIO) + note right: when budget is consumed\nreset time_slice to default\nand lower priority + "MPP Scheduling"-> "Zephyr Thread": k_thread_time_slice_set(thread, slice_ticks = budget) + deactivate "MPP Scheduling" + + else if processing complete (no time_slice timeout) + "Zephyr Thread"-> "MPP Scheduling": on processing complete (thread) + activate "MPP Scheduling" + "MPP Scheduling"-> "Zephyr Thread": k_thread_runtime_stats_get(thread) + activate "Zephyr Thread" + return return thread_cycles - absolute number of cycles consumed by thread + "MPP Scheduling"->"MPP Scheduling": update thread\ncycles_consumed_in_sys_tick += (thread_cycles - thread_ref_cycles) + note right: thread_ref_cycles is a reference number of cycles consumed by thread\nupdated on each sys_tick start and processing complete + "MPP Scheduling"->"MPP Scheduling": update thread_ref_cycles = thread_cycles + return + deactivate "MPP Scheduling" + + "Zephyr Thread" -> "Zephyr Thread": suspend TwB Zephyr Thread\n(k_sem_take) + note left: TwB Threads are expected to be resumed when there is new data for processing\nfor example IPC TwB Thread will be resumed on IPC interrupt + "Zephyr Thread" --> "Zephyr Scheduler" + deactivate "Zephyr Thread" + end +end + +loop for each DP Zephyr Thread + "Zephyr Scheduler"-> "Zephyr Thread": schedule DP Zephyr Thread with earlieast deadline\n(context switch) + note right: TwB Threads with low priority are treated\nas threads with max deadline and will be\nscheduled after DP threads complete processing + activate "Zephyr Thread" + "Zephyr Thread"-> "Zephyr Thread": run + note right: DP thread runs till completion\nor till earlier deadline or\nhigher priority thread is available + return + deactivate "Zephyr Thread" +end + +@enduml diff --git a/architectures/firmware/sof-zephyr/mpp_layer/index.rst b/architectures/firmware/sof-zephyr/mpp_layer/index.rst index ddcd77f2..f28f6ab4 100644 --- a/architectures/firmware/sof-zephyr/mpp_layer/index.rst +++ b/architectures/firmware/sof-zephyr/mpp_layer/index.rst @@ -11,3 +11,4 @@ to the Application layer. :maxdepth: 1 mpp_overview + mpp_scheduling diff --git a/architectures/firmware/sof-zephyr/mpp_layer/mpp_scheduling.rst b/architectures/firmware/sof-zephyr/mpp_layer/mpp_scheduling.rst new file mode 100644 index 00000000..c4ff5631 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/mpp_scheduling.rst @@ -0,0 +1,302 @@ +.. _sof-zephyr_mpp_scheduling: + +MPP Scheduling +############## + +This section describes MPP scheduling flows, task types and their usage in SOF +based on Zephyr API. + +MPP Scheduling defines four task categories: + +- Low Latency audio data processing tasks (LL) - high priority, +- Tasks with Budget (TwB) - medium priority, +- audio Data Processing tasks (DP) - low priority, +- background (idle) priority tasks + +**NOTE:** As of today, only LL tasks has been integrated with Zephyr. TwB, DP +and idle tasks are work in progress (WIP). + +The role of MPP Scheduling is limited to task threads definition, configuration +and state management. The thread scheduling itself is handled by Zephyr. + +MPP Scheduling is designed to: + +- address strict real-time requirements, + + - i.e. to avoid under/overflows on isochronous interfaces such as + I2S, + +- provide predictable latency, +- reduce amount of buffering needed, + +MPP Scheduling defines two tasks categories: + +Task categories characteristic: + +- LL tasks for latency sensitive audio data processing, + + - LL tasks are organized in queues shared between component instances, + - there is one non-preemptive high priority LL Thread assigned to exactly + one core. For example, for HW configuration with 4 cores there will be 4 + LL Threads, + - each queue is statically linked to one LL Thread and all queue tasks will + be processed on a core that LL Thread is assigned to, + - there are multiple queues per LL Thread which represent a priority and + guarantee tasks execution order, + +.. TODO: Add LL tasks, Threads and queues relation diagram, + +- TwB for medium priority processing (e.g., IPC/IDC message handling), + + - each TwB is scheduled as a separate preemptive thread, + - TwB has assigned budget for processing that is refreshed in each sys tick + (`Zephyr Thread time slicing + `__), + - TwB priority is dropped to low when budget is consumed, + +- DP tasks for low priority audio processing, + + - DP tasks are scheduled based on earliest deadline first (EDF) algorithm, + - each DP task is scheduled as a separate preemptive thread, + - DP tasks can be assigned to one of the available cores, + +- idle tasks for background processing, + + - idle tasks are scheduled as separate preemptive threads, + - they have the lowest priority and are scheduled when all other tasks + completed their processing, + - they are used in Fast Mode. For example, in data draining from firmware to + host. + +**NOTE:** Each task is assigned by MPP Scheduling to one core. Tasks are +executed by the assigned core till termination. + +**NOTE:** For Earliest Deadline First (EDF) algorithm description, please refer +to link: +`Wikipedia `__. + +**NOTE:** For Zephyr Scheduling description, please refer to link: +`Zephyr +Scheduling `__. + +.. uml:: images/mpp_scheduling/schedulers_diagram.pu + :caption: SOF MPP Scheduling based on Zephyr + +LL Tasks +******** + +Low Latency Tasks are executed within one of the non-preemptive high priority LL +Threads that runs all ready-to-run tasks till completion during a single cycle. +There is one LL Thread scheduled per core with its own queues and LL tasks to +execute. + +MPP Scheduling adds ready tasks to LL queues at the beginning of each scheduling +period. There are a number of queues to add tasks to. LL Thread iterates over +the queues, and runs all tasks from one queue before moving to the next queue. +Therefore, it is possible to guarantee that some tasks are always run before +others during a cycle. + +There are also two special queues: pre-run queue and post-run queue. Tasks from +pre-run queue are run at the beginning of each cycle (may consider them to have +the highest priority). + +Tasks from post-run queue are run at the end of each cycle (may consider them to +have the lowest priority). + +Example of a pre-run task may be a task registered by the sink driver that +starts the sink at the very beginning of the cycle if data was supplied during +the previous cycles and link has been stopped. + +.. TODO: Evaluate option to add time slice limit for LL thread (set limit it to + 90% to not starve potential IPC communication tasks) + +DP Tasks +******** + +The data processing components are represented as a DP tasks that are scheduled as +separate preemptive threads. DP threads scheduling is done according to EDF +(Earliest Deadline First) algorithm that is part of Zephyr. + +To meet real-time processing criteria algorithm operates by choosing component task +that is closest to its deadline (time when output data is required). + +For playback case algorithm starts from sink and going backward calculates +deadline for data delivery: + + * Time required by component to process data depend on processing period and compute. + * Goal is to process data through chain before real-time sink deadline + +EDF scheduling example + +.. blockdiag:: images/mpp_scheduling/edf_scheduling.diag + +The capture pipelines operate in the same way. + +It is important to consider that EDF assumes preemptive scheduling of the DP +Tasks and lack of dependency between them. + +Task With Budget +**************** + +This is a specialized version of DP task that has pre-allocated MCPS budget +renewed with every system tick. When the task is ready to run, then depending on +the budget left in the current system tick, either MEDIUM_PRIORITY or +LOW_PRIORITY is assigned to task thread. The latter allows for opportunistic +execution if there is no other ready task with a higher priority while the +budget is already spent. + +Examples of tasks with budget: Ipc Task, Idc Task. + +Task with Budget (TWB) has two key parameters assigned: + +- *cycles granted*: the budget per system tick, +- *cycles consumed*: number of cycles consumed in a given system_tick + for task execution + +The number of cycles consumed is being reset to 0 at the beginning of each +system_tick, renewing TWB budget. When the number of cycles consumed exceed +cycles granted, the task is switched from MEDIUM to LOW priority. When the task +with budget thread is created the MPP Scheduling is responsible to set thread +time slice equal to task budget along with setting callback on time slice +timeout. Thread time slicing guarantee that Zephyr scheduler will interrupt +execution when the budget is spent, so MPP Scheduling timeout callback can +re-evaluate task priority. + +If there is a budget left in some system tick (task spent less time or started +executing close to the system tick that preempts execution), it is reset and not +carried over to the next tick. + +**NOTE** The Zephyr Scheduler track time slice budget of the TWB when preempted +and log warning if the budget is significantly exceeded (some long critical +section inside the task’s code might be responsible for this). + +**NOTE** The MPP Scheduling must be notified by TWB on processing complete and +update cycles consumed in the current system tick. This allows to schedule TWB +more than once (if necessary) in the single system tick with MEDIUM_PRIORITY. +The second TWB schedule should be done with modified time slice value, equal to +delta between budget and cycles consumed. + +Scheduling flows +**************** + +Zephyr scheduling +================= + +The presented Zephyr scheduling flow takes place on each core that has +MPP tasks scheduled. + +.. uml:: images/mpp_scheduling/schedulers_zephyr.pu + :caption: Zephyr scheduling of MPP threads flow + + +MPP Data Processing and Task with Budget threads periodic update +================================================================ + +Zoom in to Data Processing (Earliest Deadline First) and Task with Budget +Threads periodic update operations on each system tick start. + +.. uml:: images/mpp_scheduling/schedulers_threads_periodic_update.pu + :caption: DP and TWB threads sys tick update flow + + +Task with budget scheduling +=========================== + +.. uml:: images/mpp_scheduling/example_task_with_budget.pu + :caption: Task with budget example scheduling flow + + +Example timeline of MPP Scheduling on a DSP core +================================================= + +The below diagram shows how scheduling looks like on a DSP core. At the timer +interrupt, LL scheduler runs as the first one and then DP scheduler is executed. + +.. uml:: images/mpp_scheduling/example_LL_DP_timeline.pu + :caption: Example timeline of MPP Scheduling on DSP core with LL and DP tasks scheduling + + +Example timeline of DP tasks scheduling on secondary DSP core +============================================================== + +The below diagram shows a detailed example of how DP tasks are scheduled +on the secondary DSP core. + +.. uml:: images/mpp_scheduling/example_DP_secondary_core_timeline.pu + :caption: Example of DP tasks scheduling on secondary DSP core + + +Example timeline of MPP scheduling on multiple DSP cores +======================================================== + +The below diagram shows how scheduling looks like on many DSP cores. The DP task +deadlines are reevaluated on each core in Timer sys tick callback. + +.. uml:: images/mpp_scheduling/example_multiple_cores_timeline.pu + :caption: Example of MPP Scheduling on many cores - LL and DP tasks scheduling + +Fast Mode +********* + +The Fast Mode is used to process data faster than real time. The processing +faster than real time is only needed for a short time period and it happens i.e. +when firmware performs low power Wake on Voice. In such case SOF firmware is +working in low power mode, performing i.e. key phrase detection algorithm, +accumulating last few seconds of audio samples in history buffer. When a key +phrase detection happens, there is a need to stream the accumulated history to +Host as quickly as possible with optional additional processing on DSP. It is +only possible when a sink interface to Host transfer burst of data from DSP. + +The Fast Mode is an idle low priority task. The task is only executed when other +DP tasks with deadlines has completed their processing and there is still enough +DSP cycles before a next system tick. + +When the Fast Mode task is created by i.e. History Buffer, the component +instance (i.e. History Buffer) needs to provide a list of LL component instances +that will be executed within a Fast Mode thread, similar as it is done with LL +tasks queues and LL Thread. When the Fast Mode thread is executed it will +trigger processing of LL components in similar way as LL Thread does. The Fast +Mode task is executed in the critical section. It will check if there is data +available in an input queue and there is enough space in an output queue. Only +then it will execute a LL component. What is important to note is that the Fast +Mode task does not call processing on the DP components directly. + +As described in the previous sections, the processing on DP components is called +according to EDF algorithm. A periodicity of a component processing is +determined by time needed to fill an input queue using real time source of data. +When an input queue has sufficient amount of data, the processing on DP +component can be called. The input queues for DP components that are on the Fast +Mode task path will be filling much faster than real time as the side effect of +the Fast Mode task execution - LL components will move data to DP component +input queue and out of DP component output queue. As the result, DP component +can be executed much earlier than real time - a DSP task reports “ready to run” +as soon as it has sufficient amount of data in input queue and output queue has +enough space for produced frame. That can lead to starvation of other tasks and +to prevent it a Fast Mode tasks must be scheduled as idle tasks in background. + +Watchdog timer +************** + +Depending on HW configuration there can be a single watchdog timer, watchdog +available for each DSP core or none. + +All DSP cores shall enable watchdog when they are active to monitor health of +subsystem. When one of watchdogs will expire, the entire subsystem will be reset +by Host. + +Watchdog shall be enabled when: + +- DSP core is enabled, +- tasks are assigned to DSP core, + +Watchdog shall be disabled when: + +- DSP core is disabled, +- no tasks are assigned to DSP core, +- DSP core goes to low power state, + +Watchdog timer shall be programmed to value of a few scheduling periods. + +Watchdog timer when enabled shall be updated at every system tick. In case of +primary DSP core, it should be after running LL tasks. In case of secondary HP +DSP cores, it should be on system tick end. \ No newline at end of file From e5a27a4bb57f2ac77a885933c12663c7ac076978 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 18 Oct 2022 18:01:36 +0300 Subject: [PATCH 063/150] developer_guides: debugability: probes: Rewrite probes logging enable quide One of the PRs for automatic enabling of logging through probes interface was not accepted, and since there is not better alternative to enable the logs at the moment, document the old mething for enabling them. Restructure the documrent a bit while at it. Signed-off-by: Jyri Sarha --- .../debugability/probes/index.rst | 47 +++++++++++-------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/developer_guides/debugability/probes/index.rst b/developer_guides/debugability/probes/index.rst index 0ef12784..4f9cd559 100644 --- a/developer_guides/debugability/probes/index.rst +++ b/developer_guides/debugability/probes/index.rst @@ -12,11 +12,15 @@ from each buffer. Requirements ************ +.. _install-tinycompress: + - Install `tinycompress `_ (crecord tool) Enabling Probes *************** +.. _kernel-side: + Kernel side =========== @@ -55,6 +59,8 @@ Kernel side cat /proc/asound/cards | grep sofprobes +.. _firmware-side: + Firmware side ============= @@ -81,13 +87,9 @@ Firmware side CONFIG_LOG_BACKEND_SOF_PROBE=y CONFIG_ZEPHYR_LOG=y - This option enables the probes logging automatically when probes extraction DMA is started: + Refer to :ref:`Simple logging case` for quick guide to use probes logging interface. - .. code-block:: bash - - CONFIG_LOG_BACKEND_SOF_PROBE_OUTPUT_AUTO_ENABLE=y - -- Refer to **Step 3 Build firmware binaries** in :ref:`Build SOF from Scratch ` for reference. +- Refer to **Step 3 Build firmware binaries** in :ref:`Build SOF from Scratch ` for reference on how to build SOF FW. Note that you do not need to modify the audio topology file. @@ -195,22 +197,12 @@ the last stage of extraction. */ } __attribute__((packed, aligned(4))); -Enabling the log in IPC3 system (in case auto enable is not on): - - .. code-block:: bash - - echo 0,1,0 > probe_points - -And on IPC4 system: - - .. code-block:: bash - - echo 0,0,0 > probe_points - 2. Unpause the playback stream. (optional) #. Close the playback stream when done. #. Close the crecord tool. +.. _data-parsing: + Data parsing ************ @@ -230,12 +222,29 @@ Usage and ouput: As a result, ``buffer_7.wav`` is generated in the *tools/build_tools/probes* folder. The wave file can then be examined with your tool of choice such as ``Audacity``. +.. _simple-logging-case: Simple logging case ******************* -With the crecord and sof-probes in path, probes logging backend with auto enable option it is possible to get the firmware logs to stdout with this command combination: +With the :ref:`crecord` and :ref:`sof-probes` in path, FW built with :ref:`probes logging enabled`, and probes enabled from :ref:`Linux side`, it should be possible to extract the logs with following steps: + +#. crecord has to be started first: .. code-block:: bash crecord -c3 -d0 -b8192 -f4 -FS32_LE -R48000 -C4 | sof-probes -l + +#. then to enable logs through probes sysfw interface use following commands as root, + + IPC3 system: + +.. code-block:: bash + + echo 0,1,0 > /sys/kernel/debug/sof/probe_points + + IPC4 system: + +.. code-block:: bash + + echo 0,0,0 > /sys/kernel/debug/sof/probe_points From e1f4f89cb851b73b90abf9c21bc06aa3af52ec37 Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Tue, 26 Jul 2022 16:22:10 +0200 Subject: [PATCH 064/150] arch: fw: sof-zephyr io drivers sof-zephyr rtos architecture chapter for io drivers Signed-off-by: Michal Wasko --- .../firmware/sof-zephyr/rtos_layer/index.rst | 1 + .../io_drivers/images/io_drivers_diagram.pu | 16 ++++++++++++++ .../rtos_layer/io_drivers/index.rst | 21 +++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/io_drivers/images/io_drivers_diagram.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/io_drivers/index.rst diff --git a/architectures/firmware/sof-zephyr/rtos_layer/index.rst b/architectures/firmware/sof-zephyr/rtos_layer/index.rst index 80efe77c..f8e741bf 100644 --- a/architectures/firmware/sof-zephyr/rtos_layer/index.rst +++ b/architectures/firmware/sof-zephyr/rtos_layer/index.rst @@ -11,3 +11,4 @@ workloads. :maxdepth: 1 zephyr_kernel_overview + io_drivers/index diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/images/io_drivers_diagram.pu b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/images/io_drivers_diagram.pu new file mode 100644 index 00000000..37ce38ce --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/images/io_drivers_diagram.pu @@ -0,0 +1,16 @@ +frame "SOF" { + component Gateway + component GatewayExtension <> +} + +frame "Zephyr" { + component IoDriver <> + component DMA +} + +Gateway *-right- GatewayExtension + +Gateway -down- IoDriver +Gateway -down- DMA + +GatewayExtension ..> IoDriver diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/index.rst b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/index.rst new file mode 100644 index 00000000..fcf5f665 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/index.rst @@ -0,0 +1,21 @@ +.. _io_drivers: + +IO Drivers +########## + +The IO Drivers provide access to an IO HW Interfaces connected to the DSP, e.g. +I2S, DMIC, etc. and are managed as a part of the Zephyr RTOS. The Audio IO +Drivers share generic `Zephyr DAI interface `__. +For a full list of IO drivers available on the specific platform, refer to +:ref:`platforms`. HW IO is accessed via the `Gateway` interface inside the FW. +The actual implementation of that interface depends on the underlying HW IO +mechanism. Gateways use the Zephyr DMA interface to transmit the data to/from +the represented HW IO. DMA interface implementation depends on the underlying +DMA method (HDA-DMA, GPDMA, etc.). + +**NOTE:** The introduction of Gateways concept to SOF with Zephyr is a work in +progress. In existing implementation the SOF Host and DAI implementation is +still in use as a substitute of Gateways. + +.. uml:: images/io_drivers_diagram.pu + :caption: IO Drivers diagram From 2c312336c5eeae2793c88b8d39fb0826a52922af Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Tue, 26 Jul 2022 16:46:00 +0200 Subject: [PATCH 065/150] arch: fw: sof-zephyr hda io driver sof-zephyr hda io driver architecture chapter Signed-off-by: Michal Wasko --- .../rtos_layer/io_drivers/hda/hda_driver.rst | 50 +++++++++++++++++++ .../io_drivers/hda/images/hda_capture.pu | 15 ++++++ .../hda/images/hda_io_driver_deps.pu | 12 +++++ .../io_drivers/hda/images/hda_playback.pu | 15 ++++++ .../rtos_layer/io_drivers/index.rst | 8 +++ 5 files changed, 100 insertions(+) create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/io_drivers/hda/hda_driver.rst create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/io_drivers/hda/images/hda_capture.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/io_drivers/hda/images/hda_io_driver_deps.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/io_drivers/hda/images/hda_playback.pu diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/hda/hda_driver.rst b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/hda/hda_driver.rst new file mode 100644 index 00000000..3165775c --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/hda/hda_driver.rst @@ -0,0 +1,50 @@ +.. _hda_driver: + +HD-A IO Driver +############## + +.. uml:: images/hda_io_driver_deps.pu + :caption: HD-A IO Driver overview + +HD-A Gateways +************* + +Gateway Node Addressing +======================= + +There are four types of HD-A gateways. Note that the naming convention +(inherited from c-spec) names the data flow direction based on the external +entity's perspective. Therefore, "output" means that data comes to FW from the +external source and "input" means that data is sent from FW to the external +sink. + +.. uml:: images/hda_playback.pu + :caption: HD-A Playback + +.. uml:: images/hda_capture.pu + :caption: HD-A Capture + +HD-A Gateway types: + - HDA-A DMA Source, + + - DMA Host Output, + - DMA Link Input, + + - HDA-A DMA Sink, + + - DMA Host Input, + - DMA Link Output + +HD-A to HDMI +============ + +There following options are available: + + 1. Legacy HD/A (not recommended), + 2. HW chaining in the DSP (depends on HW support), + 3. SW chaining in the DSP (recommended), + 4. Full Copier-...-Copier pipeline (more resources required). + +The most resource-efficient way to do a simple HD/A to HD/A playback via the DSP +is to use the "DMA Chaining" feature. FW provides an IPC command to connect two +HD/A gateways with a simple data copier task running in the LL domain. diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/hda/images/hda_capture.pu b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/hda/images/hda_capture.pu new file mode 100644 index 00000000..37e6a371 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/hda/images/hda_capture.pu @@ -0,0 +1,15 @@ +@startuml + +component "host capture" as hc + +package FW { + component "Host Input" as hi + component "Link Output" as lo +} + +component "link capture" as lc +hc <- hi +hi <- lo +lo <- lc + +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/hda/images/hda_io_driver_deps.pu b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/hda/images/hda_io_driver_deps.pu new file mode 100644 index 00000000..8cfdd590 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/hda/images/hda_io_driver_deps.pu @@ -0,0 +1,12 @@ + +@startuml +allowmixing + +component "hd-a io driver" as io_drv +component "hd-a gateway" as gateway +component "hd-a dma" as dma + +io_drv -right-> gateway : provides +gateway -down-> dma : use + +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/hda/images/hda_playback.pu b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/hda/images/hda_playback.pu new file mode 100644 index 00000000..7988d2b3 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/hda/images/hda_playback.pu @@ -0,0 +1,15 @@ +@startuml + +component "host playback" as hp + +package FW { + component "Host Output" as ho + component "Link Input" as li +} + +component "link playback" as lp +hp -> ho +ho -> li +li -> lp + +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/index.rst b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/index.rst index fcf5f665..bc4bcc3e 100644 --- a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/index.rst +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/index.rst @@ -19,3 +19,11 @@ still in use as a substitute of Gateways. .. uml:: images/io_drivers_diagram.pu :caption: IO Drivers diagram + +Drivers +******* + +.. toctree:: + :maxdepth: 1 + + hda/hda_driver From 0c8fa85a13bac417b8309400cf19bbad6e8034b8 Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Fri, 29 Jul 2022 15:39:05 +0200 Subject: [PATCH 066/150] arch: fw: sof-zephyr i2s io driver sof-zephyr i2s io driver architecture chapter Signed-off-by: Michal Wasko --- .../rtos_layer/io_drivers/i2s/i2s_driver.rst | 110 ++++++++++++++++++ .../io_drivers/i2s/images/i2s_diagram.pu | 18 +++ .../io_drivers/i2s/images/i2s_tdm.dot | 38 ++++++ .../rtos_layer/io_drivers/index.rst | 1 + 4 files changed, 167 insertions(+) create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/images/i2s_diagram.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/images/i2s_tdm.dot diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst new file mode 100644 index 00000000..110bace9 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst @@ -0,0 +1,110 @@ +.. _i2s_driver: + +I2S IO Driver +############# + +.. uml:: images/i2s_diagram.pu + :caption: I2S IO Driver overview + +Configuration BLOB +****************** + +The Configuration Blob is a build of block structures: + - TDM slot Map, + - I2S base registers, + - MCLK configuration that allows for specifying the ratio for multiple + dividers, + - Aggregation configuration + +The ``I2sConfigurationBlobHeader`` begins with a signature followed by the BLOB +version and size. + +.. code-block:: text + + I2sConfigurationBlobHeader + { + signature and version { 0xEE, BLOB version } + size in bytes + } + +Blob Configuration structure that follows the header depends on the BLOB version. +Currently, only v2.5 is supported with the structure as follows: + +.. code-block:: text + + I2sConfigurationBlob2 + { + I2sConfigurationBlobHeader + TDM slot map ver.2 [I2S_TDM_MAX_SLOT_MAP_COUNT] + I2S base registers + MCLK configuration ver.2 + { + 2.5: Aggregation configuration + } + } + +TDM Time Slots +============== + +TDM time slots are statically assigned to streams by definition coming from +ACPI. A single stream transmits data through time slots of a single time slot +group. For example, 8 TDM time slots may be grouped by the following definition +from ACPI: + +.. code-block:: text + + tsd[0] = 0xFFFFFF43, tsd[1] = 0xFFFFFF01, ... + +where: + - Stream 0 specifies time_slot_group_index = 1, + - Stream 1 uses time_slot_group_index = 0 + +that would mean that the 1st TDM slot is mapped to S0 Ch0; the 0th TDM slot is +mapped to S0 Ch1; the 3rd TDM slot is mapped to S1 Ch0, and 4th TDM slot is +mapped to S1 Ch1. + +.. graphviz:: images/i2s_tdm.dot + :caption: I2S TDM + +Configuring BCLK Clock Input Source +=================================== + +The I2S Link BCLK may be configured to use on the SoC available clock sources. + +Example BCLK clock sources: + + - XTAL Oscillator clock, + - Audio Cardinal clock, + - Audio PLL fixed clock, + - MCLK + +Clock selection is programmed using values provided in the I2S Configuration +BLOB for the MCDSS and MNDSS fields of the MDIVCTRL register. + +Link Synchronization (and Aggregation) +====================================== + +Applies to sync of the streams started together as well as to synchronizing new +stream with already running ones. + +.. note:: The same configuration must be set to all involved I2S ports. Specifically, + all the ports must be driven by the same clock source. Moreover, there might + be clock source SoC limitations. For example, in the TGL the M/N divider has + to be selected for aggregation case. + +.. list-table:: + :widths: 25 25 50 + :header-rows: 1 + + * - Synchronized + - Provider Mode + - Consumer Mode + * - Stream start + - Yes + - Yes + * - BCLK, SFRM + - Yes + - By hooking up to the same I2S provider + +"Single" I2S links may be synchronized and aggregated by sending I2sSyncData to +the I2S IO Driver. diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/images/i2s_diagram.pu b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/images/i2s_diagram.pu new file mode 100644 index 00000000..d49b4d50 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/images/i2s_diagram.pu @@ -0,0 +1,18 @@ +@startuml + +hide methods +hide attributes + +class I2sSink --() Gateway +class I2sSource --() Gateway +class I2sDriver --() IoDriver +class I2sChannel +class I2sInputChannel + +I2sChannel --* I2sDriver +I2sInputChannel --|> I2sChannel +I2sOutputChannel --|> I2sChannel +I2sSink --o I2sOutputChannel +I2sSource --o I2sInputChannel + +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/images/i2s_tdm.dot b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/images/i2s_tdm.dot new file mode 100644 index 00000000..db699bbd --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/images/i2s_tdm.dot @@ -0,0 +1,38 @@ +digraph G { + node [fontsize=10,shape=record,height=.1]; + splines=false + + subgraph clusterAcpi { + label="tdm_ts_group[8]"; fontsize=10; + tdm_acpi [label="FFFFFF43 |FFFFFF01 |..."]; + } + + subgraph clusterStr0 { + label="Stream 0"; fontsize=10; color="#C4D600"; + + str0_cfg [label="\{ time_slot_group_index=1\}"]; + str0_cfg -> tdm_acpi:acpi1 [style=dotted]; + + str0 [label="L |R |... |

" color="#C4D600"]; + } + + subgraph clusterStr1 { + label="Stream 1"; fontsize=10; color="#FFA300" + + str1_cfg [label="\{ time_slot_group_index=0\}"] + str1_cfg -> tdm_acpi:acpi0 [style=dotted] + + str1 [label="L |R |..." color="#FFA300"] + } + + str [label="<0>R |<1>L |<2> |<3>L |<4>R |<5> |<6> |<7> "] + + str0:l -> str:1 + str0:r -> str:0 + + str1:l -> str:3 + str1:r -> str:4 + + {rank=min; tdm_acpi} + {rank=max; str} +} diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/index.rst b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/index.rst index bc4bcc3e..83abc6e5 100644 --- a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/index.rst +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/index.rst @@ -27,3 +27,4 @@ Drivers :maxdepth: 1 hda/hda_driver + i2s/i2s_driver From 074ea66fbb90b521950865b2f0bff54222ddabcb Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Thu, 11 Aug 2022 11:59:32 +0200 Subject: [PATCH 067/150] arch: fw: sof-zephyr dmic io driver dmic io driver architecture chapter Signed-off-by: Michal Wasko --- .../io_drivers/dmic/dmic_driver.rst | 44 +++++++++++++++++++ .../io_drivers/dmic/images/dmic_diagram.pu | 30 +++++++++++++ .../dmic/images/dmic_gateway_init.pu | 23 ++++++++++ .../dmic/images/dmic_gateway_release.pu | 23 ++++++++++ .../images/dmic_gateway_state_transitions.pu | 19 ++++++++ .../rtos_layer/io_drivers/index.rst | 1 + 6 files changed, 140 insertions(+) create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/io_drivers/dmic/dmic_driver.rst create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/io_drivers/dmic/images/dmic_diagram.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/io_drivers/dmic/images/dmic_gateway_init.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/io_drivers/dmic/images/dmic_gateway_release.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/io_drivers/dmic/images/dmic_gateway_state_transitions.pu diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/dmic/dmic_driver.rst b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/dmic/dmic_driver.rst new file mode 100644 index 00000000..6da57691 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/dmic/dmic_driver.rst @@ -0,0 +1,44 @@ +.. _dmic_driver: + +DMIC IO Driver +############## + +.. uml:: images/dmic_diagram.pu + :caption: DMIC IO Driver overview + +Gateway Initialization +********************** + +.. uml:: images/dmic_gateway_init.pu + :caption: DMIC Input Gateway Initialization + +DMIC HW is initialized as follows: + + 1. Mute microphones. + 2. Enable clock on microphones (also enable CIC and FIRs). + 3. Wait for clock stabilization (SoC defined delay). + 4. Unmute microphones using a curved ramp until the DC offset is gone and + replaced with the live stream. + +Configuration BLOB +****************** + +DMIC IO Driver is prepared for the configuration BLOB to come in context of any +instance of the DmicInput at any time. The configuration may be rejected if the +current state of PDM controllers and FIFOs is inappropriate. Accepting the +configuration does not always mean that it is immediately programmed to the HW. +The configuration is global, so when sent by an instance of DmicInput while +another instance is already running it is just compared with already programmed +data for the sake of consistency. + +Gateway Release +*************** + +.. uml:: images/dmic_gateway_release.pu + :caption: DMIC Input Gateway Release + +State Transitions +***************** + +.. uml:: images/dmic_gateway_state_transitions.pu + :caption: DMIC Input Gateway State Transition diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/dmic/images/dmic_diagram.pu b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/dmic/images/dmic_diagram.pu new file mode 100644 index 00000000..6dc94a0c --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/dmic/images/dmic_diagram.pu @@ -0,0 +1,30 @@ +@startuml + +hide methods +hide attributes + +component Zephyr { + class DmicDriver + interface dai_dmic_ops + interface dai_driver_api +} + +component MPP { + interface Gateway + + interface IoDriver + class DmicManager + class DmicInput +} + +DmicDriver -up- dai_dmic_ops + +dai_dmic_ops -left-|> dai_driver_api : implements + +DmicManager -up- IoDriver +DmicManager -left-> DmicInput : manages +DmicInput -up- Gateway +DmicInput -down-> dai_dmic_ops : calls +DmicDriver --* DmicInput + +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/dmic/images/dmic_gateway_init.pu b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/dmic/images/dmic_gateway_init.pu new file mode 100644 index 00000000..f8a938f4 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/dmic/images/dmic_gateway_init.pu @@ -0,0 +1,23 @@ +@startuml + +participant "DMIC Manager" as dmic_manager +participant "Zephyr PM Subsystem" as zephyr_pm +participant "DMIC Driver" as dmic_driver + +-> dmic_manager : gateway_allocate() + activate dmic_manager + dmic_manager -> zephyr_pm : pm_runtime_device_get (dmic) + + activate zephyr_pm + zephyr_pm -> zephyr_pm : increase usage count + opt if usage == 1 + zephyr_pm -> dmic_driver : pm_device_resume + activate dmic_driver + return + end + return + + deactivate dmic_manager +<-- dmic_manager + +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/dmic/images/dmic_gateway_release.pu b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/dmic/images/dmic_gateway_release.pu new file mode 100644 index 00000000..9afebab9 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/dmic/images/dmic_gateway_release.pu @@ -0,0 +1,23 @@ +@startuml + +participant "DMIC Manager" as dmic_manager +participant "Zephyr PM Subsystem" as zephyr_pm +participant "DMIC Driver" as dmic_driver + +-> dmic_manager : gateway_release() + activate dmic_manager + dmic_manager -> zephyr_pm : pm_runtime_device_put (dmic) + + activate zephyr_pm + zephyr_pm -> zephyr_pm : decrease usage count + opt if usage == 0 + zephyr_pm -> dmic_driver : pm_device_suspend + activate dmic_driver + return + end + return + + deactivate dmic_manager +<-- dmic_manager + +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/dmic/images/dmic_gateway_state_transitions.pu b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/dmic/images/dmic_gateway_state_transitions.pu new file mode 100644 index 00000000..ee592ed6 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/dmic/images/dmic_gateway_state_transitions.pu @@ -0,0 +1,19 @@ + +participant "Dmic Input\nGateway" as dmic_input +participant "DMA" as dma + +== Dmic Input : STOPPED == + +-> dmic_input : STOPPED + dmic_input -> dma : stop() + +== Dmic Input : PAUSED == + +-> dmic_input : PAUSED + dmic_input -> dma : init_transfer() + dmic_input -> dma : pause() + +== Dmic Input : RUNNING == + +-> dmic_input : RUNNING + dmic_input -> dma : start() diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/index.rst b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/index.rst index 83abc6e5..52562049 100644 --- a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/index.rst +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/index.rst @@ -28,3 +28,4 @@ Drivers hda/hda_driver i2s/i2s_driver + dmic/dmic_driver From c8dde81408ab5df7b6d56ebac8bf154a662ae3ca Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Tue, 5 Apr 2022 08:59:16 +0200 Subject: [PATCH 068/150] arch: fw: asynchronous messaging service Introduction of service to exchange events between firmware components Signed-off-by: Michal Wasko --- .../sof-zephyr/mpp_layer/async_messaging.rst | 42 +++++ .../flow_prod_cons_same_core.pu | 83 ++++++++++ .../flow_prod_primary_cons_secondary_core.pu | 153 ++++++++++++++++++ .../firmware/sof-zephyr/mpp_layer/index.rst | 1 + 4 files changed, 279 insertions(+) create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/async_messaging.rst create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/async_messaging/flow_prod_cons_same_core.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/async_messaging/flow_prod_primary_cons_secondary_core.pu diff --git a/architectures/firmware/sof-zephyr/mpp_layer/async_messaging.rst b/architectures/firmware/sof-zephyr/mpp_layer/async_messaging.rst new file mode 100644 index 00000000..bb6517b1 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/async_messaging.rst @@ -0,0 +1,42 @@ +.. _async_msg: + +Asynchronous Messaging Service +############################## + +Asynchronous Messaging Service (AMS) is designed to exchange sporadic / +asynchronous events between firmware components, such as key phrase detection. +It can also be optionally selected in the firmware build configuration. The +service exposes an external interface to the host and is API accessible from +firmware components. + +**NOTE:** The AMS integration is currently a work in progress; it might not be +fully functional in SOF main branch. + +Asynchronous messages are one-way from producer to all consumers and allows to: + + - direct asynchronous communication between components (1:1) + - sending one asynchronous message to many components (1:N) + - producing asynchronous messages by many modules where 1 is receiving (M:1) + - producing asynchronous messages by many modules where many are receiving (M:N) + +Messages are exchanged over IDC protocol and shared memory with multi-core +support. Message producers and consumers can be run on different cores. + +.. TODO: Add link to AMS interface generated from code + +Asynchronous Messaging Flows +**************************** + +Producer and consumer on the same core +====================================== + +.. uml:: images/async_messaging/flow_prod_cons_same_core.pu + :caption: Asynchronous Messaging example with WoV producer and custom module consumer running on single core + +Producer on primary core, consumer on secondary core +==================================================== + +.. uml:: images/async_messaging/flow_prod_primary_cons_secondary_core.pu + :caption: Asynchronous Messaging example with WoV producer on primary core and custom module consumer running on secondary core + +.. TODO: Port additional async messaging uml flows from internal FAS documentation diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/async_messaging/flow_prod_cons_same_core.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/async_messaging/flow_prod_cons_same_core.pu new file mode 100644 index 00000000..876bea23 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/async_messaging/flow_prod_cons_same_core.pu @@ -0,0 +1,83 @@ +@startuml + +box "DSP #0 (primary)" #LightBlue + participant "DSP #0: AMS" as ams + participant "DSP #0: KR" as kr + participant "DSP #0: Custom module" as custom_module +end box + +box "Shared SRAM" + participant "AMS database" as ams_db +end box + +... + +group Register KEY_PHRASE_DETECTED producer + group Get Message ID + kr -> ams: am_service_get_message_type_id(KEY_PHRASE_DETECTED UUID) + activate ams + ams -> ams_db: Find ID for KEY_PHRASE_DETECTED message + activate ams_db + alt If no KEY_PHRASE_DETECTED is found + ams -> ams_db: Assign ID to KEY_PHRASE_DETECTED message + return + end + return + end + + kr -> ams: am_service_register_producer(message_id) + activate ams + return +end + +... + +group Register KEY_PHRASE_DETECTED consumer + group Get Message ID + custom_module-> custom_module + end + + custom_module -> ams: am_service_register_consumer(message_id, callback) + activate ams + ams -> ams_db: Add KEY_PHRASE_DETECTED message consumer + return +end + +... + +group Send Async Message + kr -> ams: am_service_send_message(lp_kpd_id, message) + activate ams + + ams -> ams_db: Get KEY_PHRASE_DETECTED consumers + loop Until all consumer are called + ams -> ams_db: Get AMS consumer Processor ID + + alt AMS Consumer Processor ID != Current Processor ID + ams -> ams: Forward AMS message to the consumer's core + else AMS Consumer Processor ID == Current Processor ID + ams -> ams_db: Get AMS consumer callback + ams -> ams: Call consumer AMS callback + end + end + return +end + +... + +group Unregister KEY_PHRASE_DETECTED consumer + custom_module -> ams: am_service_unregister_consumer(message_id, callback) + activate ams + ams -> ams_db: Remove KEY_PHRASE_DETECTED message consumer + return +end + +... + +group Unregister KEY_PHRASE_DETECTED producer + kr -> ams: am_service_unregister_producer(message_id) + activate ams + return +end + +@enduml diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/async_messaging/flow_prod_primary_cons_secondary_core.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/async_messaging/flow_prod_primary_cons_secondary_core.pu new file mode 100644 index 00000000..60b9a7db --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/async_messaging/flow_prod_primary_cons_secondary_core.pu @@ -0,0 +1,153 @@ +@startuml + +scale max 1280 width + +box "DSP #0 (primary)" #LightBlue + participant "DSP #0: IXC Service" as ixc_service_dsp_0 + participant "DSP #0: IDC" as idc_dsp_0 + participant "DSP #0: AMS" as ams_dsp_0 + participant "DSP #0: KR" as kr_dsp_0 +end box + +box "DSP #1 (secondary)" #LightGreen + participant "DSP #1: IDC" as idc_dsp_1 + participant "DSP #1: Scheduler" as scheduler_dsp_1 + participant "DSP #1: IDC Task" as idc_dsp_1 + participant "DSP #1: IXC Service" as ixc_service_dsp_1 + participant "DSP #1: AMS" as ams_dsp_1 + participant "DSP #1: Custom module" as custom_module_dsp_1 +end box + +box "Shared SRAM" + participant "AMS database" as ams_db +end box + +... + +group Register KEY_PHRASE_DETECTED producer + group Get Message ID + kr_dsp_0 -> ams_dsp_0: am_service_get_message_type_id(KEY_PHRASE_DETECTED UUID) + activate ams_dsp_0 + ams_dsp_0 -> ams_db: Find ID for KEY_PHRASE_DETECTED message + activate ams_db + alt If no KEY_PHRASE_DETECTED is found + ams_dsp_0 -> ams_db: Assign ID to KEY_PHRASE_DETECTED message + end + return + return + end + + kr_dsp_0 -> ams_dsp_0: am_service_register_producer(message_id) + activate ams_dsp_0 + return +end + +... + +group Register KEY_PHRASE_DETECTED consumer + group Get Message ID + custom_module_dsp_1 -> ams_dsp_1: am_service_get_message_type_id(KEY_PHRASE_DETECTED UUID) + activate ams_dsp_1 + + ams_dsp_0 -> ams_db: Find ID for KEY_PHRASE_DETECTED message + activate ams_db + alt If no KEY_PHRASE_DETECTED is found + ams_dsp_0 -> ams_db: Assign ID to KEY_PHRASE_DETECTED message + end + return + end + + custom_module_dsp_1 -> ams_dsp_1: am_service_register_consumer(message_id) + activate ams_dsp_1 + ams_dsp_1 -> ams_db: Add KEY_PHRASE_DETECTED message consumer + return +end + +... + +group Send Async Message + kr_dsp_0 -> ams_dsp_0: am_service_send_message(message_id, message) + activate ams_dsp_0 + ams_dsp_0 -> ams_db: Get KEY_PHRASE_DETECTED consumers + + note left of ams_db + "External" means the consumers located on the other DSP cores. + "Internal" means the consumers located on the same DSP core. + end note + + loop Until all consumer are called + ams_dsp_0 -> ams_db: Get AMS consumer Processor ID + + alt AMS Consumer Processor ID != Current Processor ID + alt If a first time AMS consumer on this DSP core + alt If it is a first external AMS consumer + loop Until AMS message slot is reserved or limit of tries is reached + ams_dsp_0 -> ams_db: Reserve AMS message slot + end + + ams_dsp_0 -> ams_db: Increment a 'core use count' for AMS slot + ams_dsp_0 -> ams_db: Set MOVEMENT_REPORT message + ams_dsp_0 -> ams_dsp_0: Flush/Invalidate L1 cache + end + + ams_dsp_0 -> ixc_service_dsp_0: Send FORWARD_AMS_MESSAGE(ams_message_slot_id) IDC to the consumer's core + activate ixc_service_dsp_0 + ixc_service_dsp_0 -> idc_dsp_0: IDC Interrupt + activate idc_dsp_0 + idc_dsp_1 -> scheduler_dsp_1: Add/unblock IDC task + return + return + end + else AMS Consumer Processor ID == Current Processor ID + ams_dsp_0 -> ams_db: Get AMS consumer callback + ams_dsp_0 -> ams_dsp_0: Call consumer AMS callback + end + end + return + + ... + + scheduler_dsp_1 -> idc_dsp_1: Execute task + activate idc_dsp_1 + idc_dsp_1 -> ixc_service_dsp_1: Process IDC message + activate ixc_service_dsp_1 + ixc_service_dsp_1 -> ams_dsp_1: FORWARD_AMS_MESSAGE(ams_message_slot_id) + activate ams_dsp_1 + ams_dsp_1 -> ams_db: Get KEY_PHRASE_DETECTED consumers + loop Until all consumer are called + ams_dsp_1 -> ams_db: Get AMS consumer Processor ID + + alt AMS Consumer Processor ID == Current Processor ID + ams_dsp_1 -> ams_db: Get AMS consumer callback + alt If Custom module consumer + ams_dsp_1 -> custom_module_dsp_1: Call AMS Custom module callback + activate custom_module_dsp_1 + return + else + ams_dsp_1 -> ams_dsp_0: Call consumer AMS callback + end + end + end + return + return + return +end + +... + +group Unregister KEY_PHRASE_DETECTED produce + kr_dsp_0 -> ams_dsp_0: am_service_unregister_producer(message_id) + activate ams_dsp_0 + return +end + +... + +group Unregister KEY_PHRASE_DETECTED consumer + custom_module_dsp_1 -> ams_dsp_1: am_service_unregister_consumer(message_id) + activate ams_dsp_1 + ams_dsp_1 -> ams_db: Remove KEY_PHRASE_DETECTED message consumer + return +end + +@enduml diff --git a/architectures/firmware/sof-zephyr/mpp_layer/index.rst b/architectures/firmware/sof-zephyr/mpp_layer/index.rst index f28f6ab4..729a465e 100644 --- a/architectures/firmware/sof-zephyr/mpp_layer/index.rst +++ b/architectures/firmware/sof-zephyr/mpp_layer/index.rst @@ -12,3 +12,4 @@ to the Application layer. mpp_overview mpp_scheduling + async_messaging From 80407cb4dd77414ef62d64dbddaac3af6b3e8e8c Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Tue, 31 May 2022 09:24:39 +0200 Subject: [PATCH 069/150] developer guides: async messaging Best practices of asynchronous messaging implementation Signed-off-by: Michal Wasko --- .../sof-zephyr/mpp_layer/async_messaging.rst | 2 + .../async_messaging_best_practices.rst | 651 ++++++++++++++++++ developer_guides/firmware/index.rst | 1 + 3 files changed, 654 insertions(+) create mode 100644 developer_guides/firmware/async_messaging_best_practices.rst diff --git a/architectures/firmware/sof-zephyr/mpp_layer/async_messaging.rst b/architectures/firmware/sof-zephyr/mpp_layer/async_messaging.rst index bb6517b1..77813193 100644 --- a/architectures/firmware/sof-zephyr/mpp_layer/async_messaging.rst +++ b/architectures/firmware/sof-zephyr/mpp_layer/async_messaging.rst @@ -22,6 +22,8 @@ Asynchronous messages are one-way from producer to all consumers and allows to: Messages are exchanged over IDC protocol and shared memory with multi-core support. Message producers and consumers can be run on different cores. +Development guide: :ref:`async_messaging_best_practices` + .. TODO: Add link to AMS interface generated from code Asynchronous Messaging Flows diff --git a/developer_guides/firmware/async_messaging_best_practices.rst b/developer_guides/firmware/async_messaging_best_practices.rst new file mode 100644 index 00000000..efc49c1b --- /dev/null +++ b/developer_guides/firmware/async_messaging_best_practices.rst @@ -0,0 +1,651 @@ +.. _async_messaging_best_practices: + +Async Messaging Best Practices +############################## + +This section provides best practices and point out issues that developers should +be aware of when using asynchronous messages in their components. + +Message Type IDs +**************** + +The only unique value that is guaranteed to not change is UUID. The message type +IDs can change every time when a component is registering as a message +consumer/producer. In fact it depends on initialization order of components and +it may seem to be static. However it can change i.e. with addition of a new +component to pipeline and the entire mechanism will stop working. + +The components must not hardcode this value and they must use a runtime value of +component instance ID returned during producer/consumer registration. + +.. _message_handling: + +Message Handling +**************** + +The asynchronous messages consumers must be prepared to handle the messages +asynchronously. A message can be received while a component is processing data +and it can lead to undefined behavior when internal state is changed +immediately. The recommended way of handling asynchronous messages is to save a +message and apply the changes during a next processing time i.e. at the +beginning of processing. + +- When a processing of asynchronous message is done at the beginning of + component processing (Process Data), only then component processing is + deterministic. + +If an asynchronous message cannot be processed immediately by a consumer, it is +a good practice to implement a queue of incoming asynchronous messages in a +component or at least count asynchronous messages since last processing to +detect this kind of situation. + +A consumer component cannot assume that it can save a message pointer and +dereference is later. The message memory is released as soon as Asynchronous +Messaging Service will finish processing, so a consumer component must copy a +content of asynchronous message. + +Example - the pseudo code on a consumer side: + +.. code:: cpp + + queue_t request_queue; + + struct request_t { + uint8_t new_state; + }; + + struct message_context_t { + int32_t error; + queue_t *request_queue; + }; + + message_context_t message_context; + + void callback(const ams_message_payload_s * const ams_message_payload, void *ctx) { + if(ams_message_payload->message_length != sizeof(request_t)) { + ((message_context_t *)ctx)->error = 1; + return; + } + + queue_push(((message_context_t *)ctx)->request_queue, (request_t *)(ams_message_payload->message)); + } + + error_code componentA::Init(Pipeline* parent_ppl, const ModuleACfg* cfg) { + //getting Message Type ID + error = am_service_get_message_type_id(MESSAGE_A, &message_type_id); + if(error != 0) { + //error handling + } + + //registering consumer + message_context.error = 0; + message_context.request_queue = &request_queue; + error = am_service_register_consumer(message_type_id, GetcomponentID(), GetInstanceID(), callback, &message_context); + if(error != 0) { + //error handling + } + } + + error_code componentA::ProcessData(size_t max_output_data_size, uint32_t* custom_error_code) { + while(queue_size(message_context.request_queue) > 0) { + if(message_context.error != 0) { + //error handling + } + + request_t *r = queue_pop(message_context.request_queue); + //handling of async message + process_request(r); + } + + //regular processing + } + +.. _processing_in_a_consumer_callback: + +Processing in a consumer callback +********************************* + +The consumer callbacks must not do any heavy processing. Best if the callback +only saves information and a component will process it in the next processing +slot. + +- The asynchronous message callbacks are called in the context of a message + producer or in the context of IDC task. +- If a heavy processing is done in a message, then a producer MPCS or IDC task + budget needs to take into account this heavy processing. While it may be + possible to take into account additional budget for simple cases, it is + impossible to accommodate MCPS requirements in the general case (i.e. large + number of consumers with heavy processing). + +The example described in :ref:`message_handling` is also applicable for this issue. + +.. _message_filtering_mechanism: + +Message Filtering Mechanism +*************************** + +1. If a consumer is interested in async messages from one particular producer, + it needs to register for that particular producer using component ID and + instance ID. A component ID and instance ID of producer should be passed as + ``LARGE_CONFIG_SET`` parameter to the consumer. +2. If a producer wants to target a specific component instance, then it should + use send function that is parametrized with component ID and instance ID. + +Passing Pointers In Asynchronous Messages +***************************************** + +The asynchronous messages do not prevent to pass pointers between components. It +seems like a good idea at the beginning when a developer wants to return a +result. While it is simple solution, it may lead into the following issues: + +- there can be more than one consumer of a message and each of them needs to + have an allocated slot in the memory, +- the firmware framework cannot guarantee that component memory will be still + available when async message is processed i.e. a component can be subject of + firmware paging and the firmware infrastructure can decide to evict component + memory, + +The recommended method is to not pass pointers in the asynchronous messages. + +One-way Messages +**************** + +The asynchronous messages are one-way messages and there is no explicit feedback +whether a message was received or processed. The ``send`` functions return only +information whether the async messaging service return an error. + +Two-way Messages - Example #1 +***************************** + +The asynchronous messages are One-way Messages. Sometimes there is a need to +implement “function call” like functionality where a component instance wants +another component instance to take an action and return a result. This +functionality should be implemented with following issues in mind: + +- the result will not be returned immediately - :ref:`message_handling`, +- avoiding heavy processing in a consumer callback - :ref:`processing_in_a_consumer_callback`, +- 1:1 vs. M:N communication - :ref:`message_filtering_mechanism`, +- blocking vs. non-blocking execution: + + - If a producer depends on a result, it has to be handled as a blocking call + and the producer has to block its execution until result is received. To + do that, a blockade should be used when ``send`` functions return. + + - the task blockade must be removed when a result is received (in a + result callback), it will allow to continue a component execution, + - when the task blockade is set, the component execution is preempted and + the component with the highest priority is called, + +- one vs. two messages for handling action and result + + - the “function call” can be implemented as two separate messages: one for + triggering action from component A to component B and then second one for + passing result from component B to component A, it increases amount of + asynchronous messages, + - the recommended way is to implement it as one asynchronous message where + component A and B are both consumer and producer of the same asynchronous + message + + - it is important to note that filtering mechanism must be used to break + recursion - component A must discard a message from itself, + +Example - 1:1 function call: + +Consumer (component instance A) code: + +.. code:: cpp + + uint32_t message_type_id; + + queue_t request_queue; + + struct message_context_t { + int32_t error; + queue_t *request_queue; + }; + + message_context_t message_context; + + queue_t request_queue; + + struct request_t { + uint8_t message_type; //1 - request, 2 - response + uint8_t new_state; + }; + + void consumer_callback(const ams_message_payload_s * const payload, void *ctx) { + if(payload->message_length != sizeof(request_t)) { + ((message_context_t *)ctx)->error = 1; + return; + } + + //only requests are supported by a consumer + if((request_t *)(payload->message)->message_type != 1) { + ((message_context_t *)ctx)->error = 2; + return; + } + + queue_push(((message_context_t *)ctx)->request_queue, (request_t *)(payload->message)); + } + + error_code componentB::Init(Pipeline* parent_ppl, const ModuelCfg* cfg) { + //getting Message Type ID + error = am_service_get_message_type_id(MESSAGE_A, &message_type_id); + if(error != 0) { + //error handling + } + + //registering consumer + message_context.error = 0; + message_context.request_queue = &request_queue; + error = am_service_register_consumer_mi(message_type_id, GetcomponentID(), GetInstanceID(), component_A_id, component_A_instance_id, callback, &message_context); + if(error != 0) { + //error handling + } + } + + error_code componentB::ProcessData(size_t max_output_data_size, uint32_t* custom_error_code) { + while(queue_size(request_queue) > 0) { + if(message_context.error != 0) { + //error handling + } + + request_t *r = queue_pop(request_queue); + + //handling of async message + process_request(r); + + //message response + request_t response; + response.message_type = 2; + + error_code error = am_service_send_mi(message_type_id, GetcomponentID(), GetInstanceID(), component_A_id, component_A_instance_id, sizeof(request_t), &response); + if(e != 0) { + //error handling + } + } + + //regular processing + } + +Producer code: + +.. code:: cpp + + uint32_t message_type_id; + + queue_t request_queue; + + struct message_requestor_context_t { + int32_t error; + queue_t *request_queue; + uint32_t blockade; + }; + + message_requestor_context_t message_context; + + struct request_t { + uint8_t message_type; //1 - request, 2 - response + uint8_t new_state; + }; + + void consumer_callback(const ams_message_payload_s * const payload, void *ctx) { + if(payload->message_length != sizeof(request_t)) { + (message_requestor_context_t *)ctx->error = 1; + return; + } + + //only responses are supported by a producer + if((request_t *)(payload->message)->message_type != 2) { + (message_requestor_context_t *)ctx->error = 2; + return; + } + + queue_push(((message_context_t *)ctx)->request_queue, (request_t *)(payload->message)); + (message_requestor_context_t *)ctx->blockade = 0; //unblock a producer component execution + } + + error_code componentA::Init(Pipeline* parent_ppl, const ModuleACfg* cfg) { + //getting Message Type ID + error = am_service_get_message_type_id(MESSAGE_A, &message_type_id); + if(error != 0) { + //error handling + } + + //registering consumer + message_context.error = 0; + message_context.blockade = 0; + message_context.request_queue = &request_queue; + error = am_service_register_consumer_mi(message_type_id, GetcomponentID(), GetInstanceID(), component_B_id, component_B_instance_id, callback, &message_context); + if(error != 0) { + //error handling + } + + //registering as a producer + error = am_service_register_producer(message_type_id); + if(error != 0) { + //error handling + } + } + + error_code componentA::ProcessData(size_t max_output_data_size, uint32_t* custom_error_code) { + ... + SystemServiceInternal const* services = get_system_services(); + ... + //message request + request_t response; + response.message_type = 1; + + message_context.blockade = 1; //initialize blockade + error_code error = am_service_send_mi(message_type_id, GetcomponentID(), GetInstanceID(), component_B_id, component_B_instance_id, sizeof(request_t), &response); + if(e != 0) { + //error handling + } + + //block a component execution until a consumer will reply with a result + _AdspCurrentTaskBlockade blockade; + services->SetTaskRunCondition(&blockade, (uint32_t*)(&message_context.blockade), 0 /*unblocking value*/, 0xffffffff); + services->RemoveTaskRunCondition(&blockade); + + while(queue_size(request_queue) > 0) { + if(message_context.error != 0) { + //error handling + } + + request_t *r = queue_pop(request_queue); + + //handling of async message + process_request(r); + } + ... + //regular processing + } + +Two-way Messages - Example #2 +***************************** + +The below example shows a real use case where multiple control interfaces are +supported (IPC and I2C). Control application needs to produce an async message +and when async message response is received, it needs to respond to the correct +requestor IPC vs. I2C. To make it happen, the unique async message ID needs to +be introduced. The unique ID can be generated globally or locally when source +component is tracked. In the below pseudo-code, the ID is generated locally and +component B needs to respond to the correct component. + +Example - 1:1 function call: + +Consumer (component instance B) code: + +.. code:: cpp + + uint32_t message_request_id; + uint32_t message_response_id; + uint32_t current_state; + + queue_t request_queue; + queue_t requestor_info_queue; + + struct unique_message_id { + uint16_t component_id; + uint16_t instance_id; + uint32_t message_id; + }; + + struct message_context_t { + int32_t error; + queue_t *request_queue; + queue_t *requestor_info_queue; + }; + + message_context_t message_context; + + struct request_t { + unique_message_id uid; + uint32_t requested_state; + }; + + struct requestor_info_t { + unique_message_id uid; + uint16_t component_id; + uint16_t instance_id; + }; + + struct response_t { + unique_message_id uid; + uint32_t current_state; + }; + + void consumer_callback(const ams_message_payload_s * const payload, void *ctx) { + if(payload->message_length != sizeof(request_t)) { + ((message_context_t *)ctx)->error = 1; + return; + } + + queue_push(((message_context_t *)ctx)->request_queue, (request_t *)(payload->message)); + + requestor_info_t info; + info.uid = (request_t *)(payload->message)->uid; + info.component_id = payload->producer_component_id; + info.instance_id = payload->producer_instance_id; + queue_push(((message_context_t *)ctx)->requestor_info_queue, info); + } + + error_code componentB::Init(Pipeline* parent_ppl, const ModuelCfg* cfg) { + //getting Message Type ID for requests + error = am_service_get_message_type_id(MESSAGE_REQUEST, &message_request_id); + if(error != 0) { + //error handling + } + + //registering consumer + message_context.error = 0; + message_context.request_queue = &request_queue; + message_context.requestor_info_queue = &requestor_info_queue; + error = am_service_register_consumer(message_request_id, GetcomponentID(), GetInstanceID(), callback, &message_context); + if(error != 0) { + //error handling + } + + //getting Message Type ID for responses + error = am_service_get_message_type_id(MESSAGE_RESPONSE, &message_response_id); + if(error != 0) { + //error handling + } + + //registering producer + error = am_service_register_producer(message_response_id, GetcomponentID(), GetInstanceID()); + if(error != 0) { + //error handling + } + } + + void process_request(request_t *r) { + current_state = r->requested_state; + } + + uint32_t get_current_state() { + return current_state; + } + + error_code componentB::ProcessData(size_t max_output_data_size, uint32_t* custom_error_code) { + while(queue_size(request_queue) > 0) { + if(message_context.error != 0) { + //error handling + } + + request_t *r = queue_pop(request_queue); + + //handling of async message + process_request(r); + + //message response + response_t response; + response.uid = r->uid; + response.current_state = get_current_state(); + + //find requestor information + requestor_info_t *ri = find(requestor_info_queue, r->uid); + if(ri == NULL) { + //error handling + } + queue_pop(requestor_info_queue, ri); + + error_code error = am_service_send_mi(message_type_id, GetcomponentID(), GetInstanceID(), ri->component_id, ri->instance_id, sizeof(response_t), &response_t); + if(e != 0) { + //error handling + } + } + + //regular processing + ... + } + +Producer code: + +.. code:: cpp + + uint32_t message_request_id; + uint32_t message_response_id; + uint32_t message_id_counter; + + queue_t response_queue; + queue_t request_source_queue; + + struct unique_message_id { + uint16_t component_id; + uint16_t instance_id; + uint32_t message_id; + }; + + struct message_requestor_context_t { + int32_t error; + queue_t *response_queue; + uint32_t blockade; + }; + + message_requestor_context_t message_context; + + struct request_source_t { + unique_message_id uid; + uint32_t source; //0 - IPC, 1 - I2C + }; + + struct request_t { + unique_message_id uid; + uint32_t requested_state; + }; + + struct response_t { + unique_message_id uid; + uint32_t current_state; + }; + + void consumer_callback(const ams_message_payload_s * const payload, void *ctx) { + if(payload->message_length != sizeof(response_t)) { + (message_requestor_context_t *)ctx->error = 1; + return; + } + + queue_push(((message_context_t *)ctx)->response_queue, (request_t *)(payload->message)); + } + + error_code componentA::Init(Pipeline* parent_ppl, const ModuleACfg* cfg) { + message_id_counter = 0; + + //getting Message Type ID for response + error = am_service_get_message_type_id(MESSAGE_RESPONSE, &message_response_id); + if(error != 0) { + //error handling + } + + //registering consumer + message_context.error = 0; + message_context.blockade = 0; + message_context.response_queue = &response_queue; + error = am_service_register_consumer(message_response_id, GetcomponentID(), GetInstanceID(), callback, &message_context); + if(error != 0) { + //error handling + } + + //getting Message Type ID for request + error = am_service_get_message_type_id(MESSAGE_REQUEST, &message_request_id); + if(error != 0) { + //error handling + } + + //registering as a producer + error = am_service_register_producer(message_request_id, GetcomponentID(), GetInstanceID()); + if(error != 0) { + //error handling + } + } + + Message::IxcStatus componentA::LargeConfigSet(uint32_t large_param_id, + bool init_block, + bool final_block, + uint32_t data_off_size, + const ByteArray* data, + ByteArray* response) + { + ... + //message request + request_t request; + response.uid = {GetcomponentID(), GetInstanceID(), message_id_counter++}; + response.requested_state = state_from_request; + + request_source_t source; + source.uid = response.uid; + source.source = 0; //IPC + queue_push(request_source_queue, source); + + error_code error = am_service_send_mi(message_type_id, GetcomponentID(), GetInstanceID(), component_B_id, component_B_instance_id, sizeof(request_t), &response); + if(e != 0) { + //error handling + } + ... + } + + void process_request(response_t *r) { + ... + request_source_t *rs = find(request_source_queue, r->uid); + if(rs == NULL) { + //error handling + } + + if(rs->source == 0) { + //send response over IPC + } + + queue_pop(request_source_queue, rs); + ... + } + + error_code componentA::ProcessData(size_t max_output_data_size, uint32_t* custom_error_code) { + ... + while(queue_size(response_queue) > 0) { + if(message_context.error != 0) { + //error handling + } + + response_t *r = queue_pop(request_queue); + + //handling of async message + process_request(r); + } + ... + //regular processing + } + +Max message size +**************** + +The asynchronous message size is limited by size of an async message slot in the +AM queue, which is currently 4KB and should not be exceeded. + +Queue is Full +************* + +The queue of asynchronous messages is used when there are customers of messages +registered on other core than producer’s core. This queue has limited size and +it can happen that ``send`` function will fail. In such case, the best strategy +is to retry ``send`` function call in the next execution period. diff --git a/developer_guides/firmware/index.rst b/developer_guides/firmware/index.rst index 6c9d3280..c0a0709a 100644 --- a/developer_guides/firmware/index.rst +++ b/developer_guides/firmware/index.rst @@ -11,3 +11,4 @@ Developer guides and information for firmware development. component-tutorial/tut-intro porting cmake + async_messaging_best_practices From af9da2d36f3e506cdba50d7de689455d7b0d7e51 Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Mon, 30 May 2022 09:47:29 +0200 Subject: [PATCH 070/150] plantuml config: add default diagram parameters Add default values for maxMessageSize and BoxPadding Set skinparams for activity and activityDiamond Signed-off-by: Michal Wasko --- scripts/plantuml.cfg | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/scripts/plantuml.cfg b/scripts/plantuml.cfg index ec0fc4db..2d1574e5 100644 --- a/scripts/plantuml.cfg +++ b/scripts/plantuml.cfg @@ -56,3 +56,17 @@ skinparam note { backgroundColor #f6ed80 borderColor #d6d6de } + +skinparam activity { + borderColor #33335b + backgroundColor #ffffff +} + +skinparam activityDiamond { + borderColor #33335b + backgroundColor #ffffff +} + +skinparam arrowColor #f05772 +skinparam maxMessageSize 400 +skinparam BoxPadding 4 From 8fc025bc2859797cdb2b6f46dbd46e0f1d82aba5 Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Mon, 4 Apr 2022 15:34:05 +0200 Subject: [PATCH 071/150] arch: fw: zephyr based power management SOF power management architecture description and flows using Zephyr RTOS infrastructure Signed-off-by: Michal Wasko Co-authored-by: Marcin Maka Co-authored-by: Deb Taylor --- .../images/power/dsp_fw_power_states.pu | 14 ++ .../images/power/dx_state_transitions.pu | 10 ++ .../images/power/flow_disable_d0i3.pu | 19 +++ .../rtos_layer/images/power/flow_dsp_idle.pu | 41 +++++ .../images/power/flow_enable_d0i3.pu | 29 ++++ .../power/flow_primary_core_power_down.pu | 56 +++++++ .../images/power/flow_secondary_core_boot.pu | 48 ++++++ .../power/flow_secondary_core_power_down.pu | 56 +++++++ .../images/power/power_components.pu | 30 ++++ .../firmware/sof-zephyr/rtos_layer/index.rst | 1 + .../rtos_layer/power_management.rst | 158 ++++++++++++++++++ 11 files changed, 462 insertions(+) create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/images/power/dsp_fw_power_states.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/images/power/dx_state_transitions.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_disable_d0i3.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_dsp_idle.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_enable_d0i3.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_primary_core_power_down.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_secondary_core_boot.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_secondary_core_power_down.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/images/power/power_components.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/power_management.rst diff --git a/architectures/firmware/sof-zephyr/rtos_layer/images/power/dsp_fw_power_states.pu b/architectures/firmware/sof-zephyr/rtos_layer/images/power/dsp_fw_power_states.pu new file mode 100644 index 00000000..c864c743 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/images/power/dsp_fw_power_states.pu @@ -0,0 +1,14 @@ +@startuml +hide empty description + +state "D0 / D0ix" as D0 { + [*] --> PM_STATE_ACTIVE: Initialization + PM_STATE_ACTIVE -> PM_STATE_RUNTIME_IDLE + PM_STATE_RUNTIME_IDLE -> PM_STATE_ACTIVE + PM_STATE_ACTIVE --> [*] +} + +[*] --> D0: Go to D0 / Power DSP on +D0 --> [*]: Go to D3 / Power DSP Off + +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/images/power/dx_state_transitions.pu b/architectures/firmware/sof-zephyr/rtos_layer/images/power/dx_state_transitions.pu new file mode 100644 index 00000000..1a1870b2 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/images/power/dx_state_transitions.pu @@ -0,0 +1,10 @@ +@startuml + +[*] --> D3 +D3 --> D0 +D0 --> D0ix: SET_D0ix(wake = 0) +D0ix --> D0: SET_D0ix(wake = 1) +D0ix --> D3: ENTER_DX_STATE +D0 --> D3: ENTER_DX_STATE + +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_disable_d0i3.pu b/architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_disable_d0i3.pu new file mode 100644 index 00000000..9279b09d --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_disable_d0i3.pu @@ -0,0 +1,19 @@ +@startuml + +box "Host" #LightSkyBlue + participant "Driver" as DRIVER +end box + +box "SOF" #LightBlue + participant "Core #0: Zephyr lib" as sof_zephyr_lib + participant "Zephyr Power Manager" as zephyr_power_manager +end box + +DRIVER -> sof_zephyr_lib: SET_D0ix(prevent_power_gating = 1) IPC request +activate sof_zephyr_lib + sof_zephyr_lib -> zephyr_power_manager: pm_policy_state_lock_get\n(PM_STATE_RUNTIME_IDLE) + activate zephyr_power_manager + return +return SET_D0ix IPC response + +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_dsp_idle.pu b/architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_dsp_idle.pu new file mode 100644 index 00000000..123751e5 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_dsp_idle.pu @@ -0,0 +1,41 @@ +@startuml + +box "SOF" #LightBlue + participant "Core #N: Zephyr lib" as sof_zephyr_lib + participant "Zephyr Power Manager" as zephyr_power_manager + participant "Zephyr SoC HAL" as soc_hal +end box + +box "Hardware" #LightGreen + participant "Core #N: Control" as core_hw_control +end box + +opt When Core is Idle + + zephyr_power_manager -> sof_zephyr_lib: pm_policy_next_state (PID: Core #N, ticks) + activate sof_zephyr_lib + activate zephyr_power_manager + sof_zephyr_lib -> zephyr_power_manager: pm_policy_state_lock_get\n(PM_STATE_RUNTIME_IDLE) + activate zephyr_power_manager + return + alt if no lock on D0ix state + return PM_STATE_RUNTIME_IDLE + else if there is lock on D0ix state + return PM_STATE_ACTIVE + end + + zephyr_power_manager -> soc_hal: pm_power_state_set\n(power_state, PID: Core #N) + activate soc_hal + alt If power_state is PM_STATE_IDLE + soc_hal -> soc_hal: arch_clear_power_gating_prevent (Core #N) + soc_hal -> core_hw_control: Clear power gating prevent + else if PM_STATE_RUNTIME_ACTIVE + soc_hal -> soc_hal: arch_set_power_gating_prevent (Core #N) + soc_hal -> core_hw_control: Set power gating prevent + end + return + + deactivate zephyr_power_manager +end + +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_enable_d0i3.pu b/architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_enable_d0i3.pu new file mode 100644 index 00000000..70b3ea8b --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_enable_d0i3.pu @@ -0,0 +1,29 @@ +@startuml + +box "Host" #LightSkyBlue + participant "driver" as driver +end box + +box "SOF" #LightBlue + participant "Core #0: Zephyr lib" as sof_zephyr_lib + participant "Zephyr Power Manager" as zephyr_power_manager +end box + +driver -> sof_zephyr_lib: SET_D0ix(prevent_power_gating = 0) IPC request +activate sof_zephyr_lib + sof_zephyr_lib -> zephyr_power_manager: pm_policy_state_lock_put\n(PM_STATE_RUNTIME_IDLE) + activate zephyr_power_manager + return + sof_zephyr_lib -> zephyr_power_manager: pm_policy_state_lock_is_active\n(PM_STATE_RUNTIME_IDLE) + activate zephyr_power_manager + return + + alt if D0ix is still locked + sof_zephyr_lib --> driver: return ERROR + note right: Zephyr PM Policy can be used concurrently\nand there can be more then one lock\non D0ix state + else + sof_zephyr_lib --> driver: return SUCCESS + end + + deactivate sof_zephyr_lib +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_primary_core_power_down.pu b/architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_primary_core_power_down.pu new file mode 100644 index 00000000..c904de25 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_primary_core_power_down.pu @@ -0,0 +1,56 @@ +@startuml + +scale max 1280 width + +box "Host" #LightSkyBlue + participant "driver" as driver +end box + +box "SOF" #LightBlue + participant "Core #0: Zephyr lib" as sof_zephyr_lib_0 + participant "Zephyr Power Manager" as zephyr_power_manager + participant "Zephyr SoC HAL" as soc_hal +end box + +box "Hardware" #LightGreen + participant "Core #0: Control" as core_hw_control +end box + +opt If D0ix is enabled + driver -> sof_zephyr_lib_0: SET_D0ix(prevent D0ix) IPC request + activate sof_zephyr_lib_0 + sof_zephyr_lib_0 -> zephyr_power_manager: pm_policy_state_lock_get\n(PM_STATE_RUNTIME_IDLE) + activate zephyr_power_manager + return + return +end + +== DSP FW in PM_STATE_ACTIVE == + +driver -> sof_zephyr_lib_0: SET_DX(PID: Core #0, D3) IPC request +activate sof_zephyr_lib_0 + sof_zephyr_lib_0 -> zephyr_power_manager: Read status of secondary cores + activate zephyr_power_manager + return + + alt If any secondary core is powered up + sof_zephyr_lib_0 --> driver: SET_DX(ERROR) IPC response + else else + sof_zephyr_lib_0 -> zephyr_power_manager: pm_power_state_force\n(PM_STATE_SOFT_OFF, PID: Core #0) + activate zephyr_power_manager + zephyr_power_manager -> soc_hal: pm_power_state_set\n(PM_STATE_SOFT_OFF, PID: Core #0) + activate soc_hal + soc_hal -> soc_hal: Save context + soc_hal -> soc_hal: Prepare restore vector + return + return + +return SET_DX(SUCCESS) IPC response +end + +driver -> core_hw_control: clear power register +loop Until Core #0 power is down + driver -> core_hw_control: Read Core #0 power bit +end + +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_secondary_core_boot.pu b/architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_secondary_core_boot.pu new file mode 100644 index 00000000..dc8704e9 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_secondary_core_boot.pu @@ -0,0 +1,48 @@ +@startuml + +box "Host" #LightSkyBlue + participant "driver" as driver +end box + +box "SOF" #LightBlue + participant "Core #0: Zephyr lib" as sof_zephyr_lib_0 + participant "Core #1: FW Init" as fw_init_1 + participant "Zephyr Power Manager" as zephyr_power_manager + participant "Zephyr SoC HAL" as soc_hal +end box + +box "Hardware" #LightGreen + participant "Core #1: Control" as core_control_1 +end box + +opt If D0ix is enabled + driver -> sof_zephyr_lib_0: SET_D0ix(prevent D0/D0ix) IPC request + activate sof_zephyr_lib_0 + sof_zephyr_lib_0 -> zephyr_power_manager: pm_policy_state_lock_get\n(PM_STATE_RUNTIME_IDLE) + activate zephyr_power_manager + return + return +end + +== DSP FW in PM_STATE_ACTIVE == + +driver -> sof_zephyr_lib_0: SET_DX(PID: Core #1, D0) IPC request +activate sof_zephyr_lib_0 + sof_zephyr_lib_0 -> soc_hal: arch_start_cpu(PID: Core #1) + activate soc_hal + soc_hal -> core_control_1: Set alternate boot vector to FW Init + note right: Cores share the \nsame FW binary\nand the firmware must be\npresent in SRAM. + soc_hal -> core_control_1: Set SPA bit + + core_control_1 -> fw_init_1: Start and jump to alternate boot vector + activate fw_init_1 + fw_init_1 -> fw_init_1: Restore context\nif any saved + + loop Until Core #1 is enabled + soc_hal -> core_control_1: read power register + end + deactivate fw_init_1 + return +return + +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_secondary_core_power_down.pu b/architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_secondary_core_power_down.pu new file mode 100644 index 00000000..05d6c6c8 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/images/power/flow_secondary_core_power_down.pu @@ -0,0 +1,56 @@ +@startuml + +scale max 1280 width + +box "Host" #LightSkyBlue + participant "driver" as driver +end box + +box "SOF" #LightBlue + participant "Core #0: Zephyr lib" as sof_zephyr_lib_0 + participant "Zephyr Power Manager" as zephyr_power_manager + participant "Zephyr SoC HAL" as soc_hal +end box + +box "Hardware" #LightGreen + participant "Core #1: Control" as core_1_control +end box + +opt If D0ix is enabled + driver -> sof_zephyr_lib_0: SET_D0ix(prevent D0ix) IPC request + activate sof_zephyr_lib_0 + sof_zephyr_lib_0 -> zephyr_power_manager: pm_policy_state_lock_get\n(PM_STATE_RUNTIME_IDLE) + activate zephyr_power_manager + return + return +end + +== DSP FW in PM_STATE_ACTIVE == + +driver -> sof_zephyr_lib_0: SET_DX(PID: Core #1, D3) IPC request +activate sof_zephyr_lib_0 + sof_zephyr_lib_0 -> zephyr_power_manager: pm_power_state_force\n(PM_STATE_SOFT_OFF, PID: Core #1) + activate zephyr_power_manager + zephyr_power_manager -> soc_hal: pm_power_state_set\n(PM_STATE_SOFT_OFF, PID: Core #1) + activate soc_hal + soc_hal -> soc_hal: Save context to IMR + return + deactivate zephyr_power_manager + + loop Until Core #1 transition to PM_STATE_SOFT_OFF + sof_zephyr_lib_0 -> zephyr_power_manager: pm_power_state_get(PID: Core #1) + activate zephyr_power_manager + return + end + + sof_zephyr_lib_0 -> soc_hal: arch_stop_cpu(PID: Core #1) + activate soc_hal + soc_hal -> core_1_control: clear power bit + loop Until Core #1 is disabled + soc_hal -> core_1_control: read power register + end + return + +return SET_DX(SUCCESS) IPC response + +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/images/power/power_components.pu b/architectures/firmware/sof-zephyr/rtos_layer/images/power/power_components.pu new file mode 100644 index 00000000..f111ae24 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/images/power/power_components.pu @@ -0,0 +1,30 @@ +node sw_driver [ + SW Driver + * DSP power control over IPC protocol +] + +node fw [ + SOF Zephyr Library + + * Exposes interface of SOF with XTOS for Host Power IPC handling + * Executes requested sequence of Zephyr power operations + * Waits and verifies power request completion + + --- + Zephyr Power Management + Generic RTOS Power Management service + + * Manages System Power States + * Manages Power Policies + * Manages Device Runtime Power + + --- + SoC HAL + Hardware specific power control + + * Moves SoC and its resources to power state requested by Zephyr + * Interacts directly with hardware and power registers + * Suppors different power states depending on the target SoC +] + +sw_driver -down-> fw : <> Set Dx - power state transition D0/D3\n<> Set D0ix - power gating override (on/off) diff --git a/architectures/firmware/sof-zephyr/rtos_layer/index.rst b/architectures/firmware/sof-zephyr/rtos_layer/index.rst index f8e741bf..d65b2dab 100644 --- a/architectures/firmware/sof-zephyr/rtos_layer/index.rst +++ b/architectures/firmware/sof-zephyr/rtos_layer/index.rst @@ -11,4 +11,5 @@ workloads. :maxdepth: 1 zephyr_kernel_overview + power_management io_drivers/index diff --git a/architectures/firmware/sof-zephyr/rtos_layer/power_management.rst b/architectures/firmware/sof-zephyr/rtos_layer/power_management.rst new file mode 100644 index 00000000..c394f52c --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/power_management.rst @@ -0,0 +1,158 @@ +.. _power_mgmt: + +Power Management +################ + +The Power Manager is responsible for system and device power management. The +power management behavior can be customized by power policy configuration and +direct power API requests which allows you to adjust system power savings to the +current firmware activity. + +.. uml:: images/power/power_components.pu + :caption: Participants of the Firmware power management. + +`Zephyr Power Management +documentation `__ + +DSP Cores +********* + +Each DSP core can be separately powered up and down. + +The assumption is that DSP #0 is a primary core and is responsible for powering +up all secondary cores. The primary core powers up the secondary cores on Set Dx +IPC request. + +The secondary core shall be powered up prior to any task allocated to it by the SW +driver. + +Power Transitions +***************** + +There are three DSP core power states: + +.. list-table:: + :widths: 5 10 20 + :header-rows: 1 + + * - DSP Power State + - Zephyr Power State + - Notes + * - D0 + - PM_STATE_ACTIVE + - built-in state, no extra mapping required + * - D0i3 + - PM_STATE_RUNTIME_IDLE + - custom mapping in the Device Tree + *d0i3: idle { power-state-name = "runtime-idle" }* + * - D3 + - PM_STATE_SOFT_OFF + - custom mapping in the Device Tree + *d3: off { power-state-name = "soft-off" }* + +A major consumer of power related to the main part of the DSP subsystem +is a source of the clock that is wired to the DSP core and the DSP core itself. +Transitions to lower power states focus on this part. Another power consumer, +a bit less significant, is the L2 SRAM memory embedded in the DSP subsystem. + +The clock source and clock gating is managed by the Power Manager according to +Power Policy configuration settings. + +Memory power is controlled by the Memory Management Driver that is responsible +for memory setup on power state transitions and memory banks power gating on +map/unmap requests (if it is supported by the SoC). + +Other power-related settings are clock gating and power gating of I/Os (I2C, +I3C, GPIO, SPI, UART, DMIC, etc.) and external DSP accelerators (if supported by +the hardware). + +The low power state transition can be triggered either by Zephyr (on CPU idle) +or on the Host IPC request through the Zephyr force power state set request. The +entrance to D0i3 power state can be dynamically locked on SetD0ix IPC request +that configures the Zephyr Power Policy to prevent a selected power state transition. + +More details are in the `Zephyr Power Management +documentation `__ + +.. uml:: images/power/dsp_fw_power_states.pu + :caption: DSP and FW Power States + +.. uml:: images/power/dx_state_transitions.pu + :caption: D3, D0 and D0ix state transitions + +Power Up of Secondary Core (D3 to D0 transition) +================================================ + +The below diagram shows secondary core boot flow: + +.. uml:: images/power/flow_secondary_core_boot.pu + :caption: DSP Secondary Core Boot flow + +Power down of DSP core (D0 to D3 transition) +============================================ + +The below diagram shows a primary core power down flow: + +.. uml:: images/power/flow_primary_core_power_down.pu + :caption: DSP Primary Core Power Down flow + +Power down of Secondary Core (D0 to D3 transition) +================================================== + +The below diagram shows a secondary core power down flow: + +.. uml:: images/power/flow_secondary_core_power_down.pu + :caption: DSP Secondary Core Power Down flow + +Enable D0ix (D0 to D0ix) +======================== + +D0ix is enabled on explicit `SET_D0ix` IPC message with prevent_power_gating bit +set to 0. + +.. uml:: images/power/flow_enable_d0i3.pu + :caption: Enable D0i3 flow + +Disable D0ix (D0ix to D0) +========================= + +D0ix is disabled on explicit `SET_D0ix` IPC message with prevent_power_gating +bit set to 1. + +.. uml:: images/power/flow_disable_d0i3.pu + :caption: Disable D0i3 flow + +DSP idle state +============== + +.. uml:: images/power/flow_dsp_idle.pu + :caption: DSP idle state flow + +DSP Cores Clock Gating +====================== + +DSP clocks, similar to DSP cores, can be separately gated as well. Clock gating +shall be enabled by default for all DSP cores unless there is request to prevent +it. + +.. TODO: Create diagram with DSP power state transitions when either DSP clock + is gate or DSP power is gate. + +**NOTE:** Power and clock gating is controlled via `Set D0ix` IPC message. + +I/O Power and Clock Gating Management +************************************* + +Zephyr is responsible for I/O devices power and clock management. + +The I/O device power is controlled based on usage count. More details can be +found in `Zephyr Device Runtime Power Management +documentation `__ + +The I/O clock gating is configurable in driver power policy. Each driver shall +request the desired clock and clock power gating if it is necessary for I/O, +accelerator, etc. to work correctly. + +For instance, audio I/Os such as I2S associated with audio domain require a high +accuracy XTAL clock and may request it. This clock shall be used for as long as +audio I/Os are active. From bbab560ca8be1f133563cd392d9a6d9a9e60cf68 Mon Sep 17 00:00:00 2001 From: jxstelter Date: Mon, 27 Jun 2022 16:23:10 +0200 Subject: [PATCH 072/150] arch: fw: IADK modules adapter description MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IADK module adapter provides interface between SOF components API and IADK Framework developed modules. Signed-off-by: Jarosław Stelter --- .../firmware/intel/ace/iadk_modules.rst | 48 +++++++++++++++++++ architectures/firmware/intel/ace/index.rst | 13 +++++ architectures/firmware/intel/index.rst | 3 +- 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 architectures/firmware/intel/ace/iadk_modules.rst create mode 100644 architectures/firmware/intel/ace/index.rst diff --git a/architectures/firmware/intel/ace/iadk_modules.rst b/architectures/firmware/intel/ace/iadk_modules.rst new file mode 100644 index 00000000..2410faa7 --- /dev/null +++ b/architectures/firmware/intel/ace/iadk_modules.rst @@ -0,0 +1,48 @@ +.. _iadk-modules: + +IADK Modules Adapter +#################### + +IADK Modules +============ + +An IADK module is a software component that can be represented by a processing +block with some input pins and output pins capable to transport a digital +signal into the block or out of the block. Processing is applied on an input +signal or a combination of input signals, some input signals may only be used +as reference signals that influence the processing on other input signals. +The result of the processing is written into the output signals. The behavior +of the block can be controlled using a configuration parameter interface. + +An IADK module communicates with base firmware and other modules through +ProcessingModuleInterface API and access base firmware services via +System Service API. + + +IADK Module Adapter +=================== + +The IADK Module Adapter is an extension to SOF component infrastructure that +allows to integrate modules developed under IADK (Intel Audio Development Kit) +Framework. +IADK modules uses uniform set of interfaces and are linked into separate +library. These modules are loaded in runtime through Library Manager and then +after registration into SOF component infrastructure are interfaced through +module adapter API. +Since IADK modules uses ProcessingModuleInterface API to control/data transfer +and SystemService API to use base FW services from internal module code, there +is a communication shim layer defined. + +The SOF IADK Module Adapter is designed to interact with IADK modules without +their code modification. Therefore C++ function, structures and variables +definition are here kept with original form from IADK Framework. +This provides binary compatibility with already developed 3rd party modules. + +There are three entities in IADK Module Adapter Package: + * System Agent - A mediator to allow the custom module to interact with the + base SOF FW. It calls IADK module entry point and provides all necessary + information to connect both sides of ProcessingModuleInterface and + System Service. + * System Service - exposes of SOF base FW services to the module. + * Processing Module Adapter - SOF base FW side of ProcessingModuleInterface + API diff --git a/architectures/firmware/intel/ace/index.rst b/architectures/firmware/intel/ace/index.rst new file mode 100644 index 00000000..8f2507bd --- /dev/null +++ b/architectures/firmware/intel/ace/index.rst @@ -0,0 +1,13 @@ +.. _ace-architecture-intel: + +Intel ACE Architecture +###################### + +The details below are specific to Intel products with an audio DSP ACE +architecture using SOF. Intel ACE is a next generation of Intel Audio DSP +solution that replaces Intel cAVS architecture. + +.. toctree:: + :maxdepth: 1 + + iadk_modules diff --git a/architectures/firmware/intel/index.rst b/architectures/firmware/intel/index.rst index de288ec2..c7a5c4ea 100755 --- a/architectures/firmware/intel/index.rst +++ b/architectures/firmware/intel/index.rst @@ -10,4 +10,5 @@ generic SOF architecture. .. toctree:: :maxdepth: 1 - cavs/index \ No newline at end of file + cavs/index + ace/index \ No newline at end of file From b2366192a7d2ed206b9f630dec31448fc2556a75 Mon Sep 17 00:00:00 2001 From: jxstelter Date: Mon, 27 Jun 2022 13:39:57 +0200 Subject: [PATCH 073/150] arch: fw: library manager description. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SOF library manager description and basic flows during loadable library operations: - library loading, - loadable module init instance, - loadable module delete instance. Signed-off-by: Jarosław Stelter Co-authored-by: Marcin Maka --- .../library_manager_delete_instance.pu | 56 ++++++++++++++++ .../library_manager_init_instance.pu | 65 +++++++++++++++++++ .../lib_manager/library_manager_load.pu | 49 ++++++++++++++ .../firmware/sof-zephyr/mpp_layer/index.rst | 1 + .../sof-zephyr/mpp_layer/lib_manager.rst | 58 +++++++++++++++++ 5 files changed, 229 insertions(+) create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/lib_manager/library_manager_delete_instance.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/lib_manager/library_manager_init_instance.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/lib_manager/library_manager_load.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/lib_manager.rst diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/lib_manager/library_manager_delete_instance.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/lib_manager/library_manager_delete_instance.pu new file mode 100644 index 00000000..6a827e38 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/lib_manager/library_manager_delete_instance.pu @@ -0,0 +1,56 @@ +@startuml + +box "Host" #LightGreen + participant "Driver" as host_driver +end box + +box "SOF" #LightSkyBlue + participant "IPC4 Handler" as ipc4_handler + participant "Component Manager" as component_manager + participant "Library Manager" as library_manager +end box + +box "Zephyr RTOS" #LightBlue + participant "Memory Management Driver" as memory_management_driver +end box + +host_driver -> ipc4_handler: SOF_IPC4_MOD_DELETE_INSTANCE + activate ipc4_handler + ipc4_handler -> component_manager: Free comp_driver + activate component_manager + alt IADK module + component_manager -> library_manager: Deinitialize comp_driver \nwith Processing Module Adapter + activate library_manager + library_manager -> component_manager: return status + deactivate library_manager + else SOF module + component_manager -> library_manager: Deinitialize comp_driver + activate library_manager + library_manager -> component_manager: return status + deactivate library_manager + end alt + component_manager -> library_manager: Free comp_driver resources + activate library_manager + library_manager -> memory_management_driver: Free/Unmap L2 memory for code and rodata + activate memory_management_driver + memory_management_driver -> library_manager + deactivate memory_management_driver + library_manager -> memory_management_driver: Free/Unmap L2 memory for bss + activate memory_management_driver + memory_management_driver -> library_manager + deactivate memory_management_driver + loop Search library for shared module + library_manager -> library_manager: Check if shared module exists and is loaded + library_manager -> memory_management_driver: Free/Unmap L2 memory for shared module + activate memory_management_driver + memory_management_driver -> library_manager + deactivate memory_management_driver + end loop + library_manager -> component_manager: return status + deactivate library_manager + component_manager -> ipc4_handler: return status + deactivate component_manager +ipc4_handler -> host_driver: Complete IPC request +deactivate ipc4_handler + +@enduml diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/lib_manager/library_manager_init_instance.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/lib_manager/library_manager_init_instance.pu new file mode 100644 index 00000000..9b16f5fd --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/lib_manager/library_manager_init_instance.pu @@ -0,0 +1,65 @@ +@startuml + +box "Host" #LightGreen + participant "Driver" as host_driver +end box + +box "SOF" #LightSkyBlue + participant "IPC4 Handler" as ipc4_handler + participant "Component Manager" as component_manager + participant "Library Manager" as library_manager +end box + +box "Zephyr RTOS" #LightBlue + participant "Memory Management Driver" as memory_management_driver +end box + +host_driver -> ipc4_handler: SOF_IPC4_MOD_INIT_INSTANCE + activate ipc4_handler + ipc4_handler -> library_manager: lib_manager_register_module() + activate library_manager + library_manager -> ipc4_handler: return status + deactivate library_manager + ipc4_handler -> component_manager: Create comp_driver + activate component_manager + component_manager -> library_manager: Allocate L2 memory for module + activate library_manager + library_manager -> memory_management_driver: Map L2 memory + deactivate library_manager + activate memory_management_driver + memory_management_driver -> library_manager + deactivate memory_management_driver + activate library_manager + library_manager -> memory_management_driver: Load module code and rodata \nfrom L3 to L2 memory + activate memory_management_driver + memory_management_driver -> library_manager + deactivate memory_management_driver + library_manager -> memory_management_driver: Initialize L2 memory for bss + activate memory_management_driver + memory_management_driver -> library_manager + deactivate memory_management_driver + loop Search library for shared module + library_manager -> library_manager: Check if shared module exists and is not loaded + library_manager -> memory_management_driver: Allocate/Map L2 memory for shared module + activate memory_management_driver + memory_management_driver -> library_manager + deactivate memory_management_driver + library_manager -> memory_management_driver: Load shared module code and rodata \nfrom L3 to L2 memory + activate memory_management_driver + memory_management_driver -> library_manager + deactivate memory_management_driver + end loop + alt IADK module + component_manager -> library_manager: Create/Initialize comp_driver \nwith IADK Module Adapter + library_manager -> component_manager: return status + else SOF module + component_manager -> library_manager: Create/Initialize comp_driver + library_manager -> component_manager: return status + deactivate library_manager + end alt + component_manager -> ipc4_handler: return status + deactivate component_manager +ipc4_handler -> host_driver: Complete IPC request +deactivate ipc4_handler + +@enduml diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/lib_manager/library_manager_load.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/lib_manager/library_manager_load.pu new file mode 100644 index 00000000..714a5de5 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/lib_manager/library_manager_load.pu @@ -0,0 +1,49 @@ +@startuml + +box "Host" #LightGreen + participant "Driver" as host_driver +end box + +box "SOF" #LightBlue + participant "IPC4 Handler" as ipc4_handler + participant "Library Manager" as library_manager + participant "MPP Memory Manager" as mpp_memory_manager +end box + +box "ACE Platform" #LightYellow + participant "ROM EXT" as rom_ext +end box + + +host_driver -> ipc4_handler: SOF_IPC4_GLB_LOAD_LIBRARY + activate ipc4_handler + ipc4_handler -> library_manager: lib_manager_load_library() + activate library_manager + library_manager -> library_manager: Parse Manifest \nPrepare Storage Memory + library_manager -> mpp_memory_manager: Allocate L3 memory for library + activate mpp_memory_manager + mpp_memory_manager -> library_manager + deactivate mpp_memory_manager + library_manager -> library_manager: Prepare HDA DMA transfer + host_driver -> library_manager: Transfer library manifest over DMA\nto L3 memory + note right: if SoC does not support L3 memory\nthen L2 memory has to be used + opt if AUTH_API_ENABLED + library_manager -> rom_ext: Verify Manifest + activate rom_ext + rom_ext -> library_manager: result + deactivate rom_ext + end opt + host_driver -> library_manager: Transfer library code over DMA\nto L3 memory + opt if AUTH_API_ENABLED + library_manager -> rom_ext: Verify whole Library + activate rom_ext + rom_ext -> library_manager: result + deactivate rom_ext + end opt + library_manager -> library_manager: Update Library \ndescriptors table + library_manager -> ipc4_handler: return status + deactivate library_manager +ipc4_handler -> host_driver: Complete IPC request +deactivate ipc4_handler + +@enduml diff --git a/architectures/firmware/sof-zephyr/mpp_layer/index.rst b/architectures/firmware/sof-zephyr/mpp_layer/index.rst index 729a465e..67629b39 100644 --- a/architectures/firmware/sof-zephyr/mpp_layer/index.rst +++ b/architectures/firmware/sof-zephyr/mpp_layer/index.rst @@ -13,3 +13,4 @@ to the Application layer. mpp_overview mpp_scheduling async_messaging + lib_manager diff --git a/architectures/firmware/sof-zephyr/mpp_layer/lib_manager.rst b/architectures/firmware/sof-zephyr/mpp_layer/lib_manager.rst new file mode 100644 index 00000000..0bb4bccf --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/lib_manager.rst @@ -0,0 +1,58 @@ +.. _lib_manager: + +Loadable Library Manager +######################## + +The Loadable Library Manager is a MPP Layer component responsible for loading +and running loadable components provided in external libraries. It supports SOF +native components as well as IADK cAVS/ACE developed modules through +:doc:`../../intel/ace/iadk_modules`. + +Loading an external library is a feature available only for IPC4 protocol with +command: `SOF_IPC4_GLB_LOAD_LIBRARY`. + +.. uml:: images/lib_manager/library_manager_load.pu + :caption: Library Manager: Load library flow + +In the `SOF_IPC4_GLB_LOAD_LIBRARY` IPC flow the ``lib_manager_load_library()`` api +function loads binary from host driver to DSP memory and updates its internal +structure with library descriptor data. If ``AUTH_API`` Kconfig option is +selected, library manager communicates with platform ROM Extension library to +perform library image verification. In that case only trusted libraries will be +successfully loaded. + +**NOTE:** ``AUTH_API`` Kconfig option is available only for Intel platforms. + +During the `SOF_IPC4_MOD_INIT_INSTANCE` IPC4 protocol call, handler searches +for specific module among build-in components and if not found, verifies +manifests of all already loaded external libraries. When module is found in +external library, it is registered in SOF Firmware ``struct comp_driver_list`` +with ``lib_manager_register_module()`` api function and loaded from L3 memory to +L2 memory. Afterwards module is created with standard component device +operation. + +**NOTE:** If L3 memory is not available, the L2 memory has to be used and there +is no memory load operation required. + +.. uml:: images/lib_manager/library_manager_init_instance.pu + :caption: Init instance flow for loadable module + +External libraries could contain not only processing modules but also shared +library code that could be reused across several external modules. The library +manager searches external library manifest for such entities and loads them +together with first processing module loaded. + +When an external processing module is no longer needed, it could be unloaded +with the IPC4 call `SOF_IPC4_MOD_DELETE_INSTANCE`. The command performs reverse +flow to the previous one. It frees L2 SRAM memory allocated for the processing +module and if it is last one unloaded from given library, it frees also +resources used for all shared libraries loaded previously. + +.. uml:: images/lib_manager/library_manager_delete_instance.pu + :caption: Delete instance flow for loadable module + +In `SOF_IPC4_MOD_INIT_INSTANCE` and `SOF_IPC4_MOD_DELETE_INSTANCE` flows, +particular module could be loaded in more than one instance. Its `.text` and +`.rodata` memory sections are allocated only for the first instance and shared +for all other instances. Also the `.text` and `.rodata` resources are released +only for the last instance of given processing module. From a919d9031683bdd2d4386200cf52464bf820f78e Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Wed, 27 Apr 2022 15:39:35 +0200 Subject: [PATCH 074/150] arch: fw: sof common architecture section added Common architecture tree for chapters that apply both to SOF XTOS and SOF with Zephyr, like Components description. Signed-off-by: Michal Wasko --- architectures/firmware/index.rst | 1 + .../components/component-mgmt-api.rst | 0 .../components/component-overview.rst | 0 .../components/images/comp-dev-states.pu | 0 .../components/images/comp-driver.pu | 0 .../components/images/comp-new-flow.pu | 0 .../components/images/component-mgmt-api.pu | 0 .../{sof-xtos => sof-common}/components/index.rst | 0 architectures/firmware/sof-common/index.rst | 12 ++++++++++++ architectures/firmware/sof-xtos/index.rst | 1 - 10 files changed, 13 insertions(+), 1 deletion(-) rename architectures/firmware/{sof-xtos => sof-common}/components/component-mgmt-api.rst (100%) rename architectures/firmware/{sof-xtos => sof-common}/components/component-overview.rst (100%) rename architectures/firmware/{sof-xtos => sof-common}/components/images/comp-dev-states.pu (100%) rename architectures/firmware/{sof-xtos => sof-common}/components/images/comp-driver.pu (100%) rename architectures/firmware/{sof-xtos => sof-common}/components/images/comp-new-flow.pu (100%) rename architectures/firmware/{sof-xtos => sof-common}/components/images/component-mgmt-api.pu (100%) rename architectures/firmware/{sof-xtos => sof-common}/components/index.rst (100%) create mode 100644 architectures/firmware/sof-common/index.rst diff --git a/architectures/firmware/index.rst b/architectures/firmware/index.rst index 839ff2e4..86c79454 100755 --- a/architectures/firmware/index.rst +++ b/architectures/firmware/index.rst @@ -6,6 +6,7 @@ Firmware Architecture .. toctree:: :maxdepth: 1 + sof-common/index sof-xtos/index sof-zephyr/index intel/index \ No newline at end of file diff --git a/architectures/firmware/sof-xtos/components/component-mgmt-api.rst b/architectures/firmware/sof-common/components/component-mgmt-api.rst similarity index 100% rename from architectures/firmware/sof-xtos/components/component-mgmt-api.rst rename to architectures/firmware/sof-common/components/component-mgmt-api.rst diff --git a/architectures/firmware/sof-xtos/components/component-overview.rst b/architectures/firmware/sof-common/components/component-overview.rst similarity index 100% rename from architectures/firmware/sof-xtos/components/component-overview.rst rename to architectures/firmware/sof-common/components/component-overview.rst diff --git a/architectures/firmware/sof-xtos/components/images/comp-dev-states.pu b/architectures/firmware/sof-common/components/images/comp-dev-states.pu similarity index 100% rename from architectures/firmware/sof-xtos/components/images/comp-dev-states.pu rename to architectures/firmware/sof-common/components/images/comp-dev-states.pu diff --git a/architectures/firmware/sof-xtos/components/images/comp-driver.pu b/architectures/firmware/sof-common/components/images/comp-driver.pu similarity index 100% rename from architectures/firmware/sof-xtos/components/images/comp-driver.pu rename to architectures/firmware/sof-common/components/images/comp-driver.pu diff --git a/architectures/firmware/sof-xtos/components/images/comp-new-flow.pu b/architectures/firmware/sof-common/components/images/comp-new-flow.pu similarity index 100% rename from architectures/firmware/sof-xtos/components/images/comp-new-flow.pu rename to architectures/firmware/sof-common/components/images/comp-new-flow.pu diff --git a/architectures/firmware/sof-xtos/components/images/component-mgmt-api.pu b/architectures/firmware/sof-common/components/images/component-mgmt-api.pu similarity index 100% rename from architectures/firmware/sof-xtos/components/images/component-mgmt-api.pu rename to architectures/firmware/sof-common/components/images/component-mgmt-api.pu diff --git a/architectures/firmware/sof-xtos/components/index.rst b/architectures/firmware/sof-common/components/index.rst similarity index 100% rename from architectures/firmware/sof-xtos/components/index.rst rename to architectures/firmware/sof-common/components/index.rst diff --git a/architectures/firmware/sof-common/index.rst b/architectures/firmware/sof-common/index.rst new file mode 100644 index 00000000..6e093246 --- /dev/null +++ b/architectures/firmware/sof-common/index.rst @@ -0,0 +1,12 @@ +.. _sof-common: + +SOF Common Architecture +####################### + +Architecture chapters and details that are common both for SOF Legacy and SOF +with Zephyr. + +.. toctree:: + :maxdepth: 1 + + components/index diff --git a/architectures/firmware/sof-xtos/index.rst b/architectures/firmware/sof-xtos/index.rst index 2909242d..1063889e 100644 --- a/architectures/firmware/sof-xtos/index.rst +++ b/architectures/firmware/sof-xtos/index.rst @@ -11,6 +11,5 @@ SOF with XTOS Architecture pm-runtime/index schedulers drivers/index - components/index pipelines/index kd_integration/index From dd1737a49879ebf582a49500f15950900675e455 Mon Sep 17 00:00:00 2001 From: Marcin Maka Date: Fri, 3 Jun 2022 11:21:29 +0200 Subject: [PATCH 075/150] components: document comp_ops and module_interface dependencies This chapter documents dependencies between various component (module) interfaces in firmware. It also documents the direction of transition towards a single, simpler native module interface. Signed-off-by: Marcin Maka --- .../components/component-module-api.rst | 42 +++++ .../components/images/comp-copy-flow.pu | 42 +++++ .../components/images/comp-module-api.pu | 160 ++++++++++++++++++ .../components/images/comp-prepare-flow.pu | 22 +++ .../firmware/sof-common/components/index.rst | 1 + 5 files changed, 267 insertions(+) create mode 100644 architectures/firmware/sof-common/components/component-module-api.rst create mode 100644 architectures/firmware/sof-common/components/images/comp-copy-flow.pu create mode 100644 architectures/firmware/sof-common/components/images/comp-module-api.pu create mode 100644 architectures/firmware/sof-common/components/images/comp-prepare-flow.pu diff --git a/architectures/firmware/sof-common/components/component-module-api.rst b/architectures/firmware/sof-common/components/component-module-api.rst new file mode 100644 index 00000000..6441f421 --- /dev/null +++ b/architectures/firmware/sof-common/components/component-module-api.rst @@ -0,0 +1,42 @@ +.. apps-comp-world: + +Component & Module Interfaces +############################# + +Introduction of the Module Adapter, an intermediate layer which provides common +code for different module API adapters, created multi-level sequences of calls +to functions and this mechanism is very expensive during run-time processing +with regards to additional cycles consumed for parameter translation and copying +as well as the additional memory for extra buffers, contexts, and the call +stack. The `module_adapter` translates the `comp_ops` interface required by the +existing infrastructure (pipelines etc.) into the `module_interface`. Then +appropriate adapter translates the `module_interface` into the final module +interface like `Cadence Codec API` or `IADK ProcessingModuleInterface`. These +dependencies are illustrated in the next figure. + +.. uml:: images/comp-module-api.pu + :caption: Component & Module API + +Maintenance of two base component (alias module) interfaces is expensive and +also confusing for the developers who wants to create a module that provides SOF +native module API. It is unclear whether this should be the `comp_ops` or the +`module_interface`. The latter is much more convenient since it is tailored for +the audio processing modules while the `comp_ops` is a multipurpose interface +cluttered with many optional operations required for *dai-comp* modules only. + +Therefore the `module_interface` should become the only SOF native module +interface that the rest of underlying infrastructure would interact with +directly. The `comp_ops` would become obsolete and eventually would be removed +from the SOF. + +The cost of extra memory required at the moment for intermediate audio data +buffers allocated inside the `module_adapter` layer (see the *Preparation Flow* +figure below) as well as cost of extra cycles required to copy the data to/from +the intermediate buffers (see the *Processing Flow* figure below) could be +avoided by removing the `comp_ops` as well. + +.. uml:: images/comp-prepare-flow.pu + :caption: Preparation Flow + +.. uml:: images/comp-copy-flow.pu + :caption: Processing Flow diff --git a/architectures/firmware/sof-common/components/images/comp-copy-flow.pu b/architectures/firmware/sof-common/components/images/comp-copy-flow.pu new file mode 100644 index 00000000..0f015622 --- /dev/null +++ b/architectures/firmware/sof-common/components/images/comp-copy-flow.pu @@ -0,0 +1,42 @@ +actor pipeline +box "Module Adapter\no-- comp_ops" + participant "module_adapter" as module_adapter +end box +box "IADK Module Adapter\no-- module_interface" + participant "iadk_adapter" as iadk_adapter +end box +box "IADK Module\no-- ProcessingModuleInterface" + participant iadk_module +end box + +pipeline -> module_adapter : (1) ops->module_adapter_copy() + activate module_adapter + + module_adapter -> module_adapter : find min bytes\nto process + + note left of module_adapter + This logic is WRONG for some modules!! + end note + + module_adapter -> module_adapter : copy input from sources\nto internal buffers + + module_adapter -> module_adapter : module_process() + activate module_adapter +note left of module_adapter +Why all those extra internal calls +used only once?? +end note + + module_adapter -> iadk_adapter : (2) ops->process() + activate iadk_adapter + iadk_adapter -> iadk_module : (3) processing + module_adapter <-- iadk_adapter + deactivate iadk_adapter + + deactivate module_adapter + + module_adapter -> module_adapter : module_adapter_process_output() + activate module_adapter + module_adapter -> module_adapter : copy output from internal buffers\ntosinks + deactivate module_adapter +pipeline <-- module_adapter diff --git a/architectures/firmware/sof-common/components/images/comp-module-api.pu b/architectures/firmware/sof-common/components/images/comp-module-api.pu new file mode 100644 index 00000000..5f7ef971 --- /dev/null +++ b/architectures/firmware/sof-common/components/images/comp-module-api.pu @@ -0,0 +1,160 @@ +scale 1024 width + +component "pipelines" { + class pipeline + hide pipeline methods + hide pipeline attributes +} +component "component" { + + class comp_driver <> { + } + hide comp_driver methods + hide comp_driver attributes + + class comp_dev <> { + state + position + frames + pipeline + min_sink_bytes + min_source_bytes + task + size + period + ... + } + hide comp_dev methods + + interface buffer + hide buffer methods + hide buffer attributes + + interface comp_ops { + create() : comp_dev* + free(comp_dev*) + params(params) + dai_get_hw_params(params, dir) + dai_config(dai_config, dai_spec_config) + cmd(int cmd, void *data) + trigger(int cmd) + prepare() + reset() + copy() + position() + get_attribute() + set_attribute() + dai_ts_config() + dai_ts_start() + dai_ts_stop() + unbind() + get_large_config() + set_large_config() + } + hide comp_ops attributes + + + comp_driver -> comp_dev : creates + comp_dev *-right- comp_ops +} +pipeline -> comp_ops : calls + +component "module_adapter" { + + class module_adapter <> { + ops : comp_ops = + .create = adapter_shim_new + .prepare = module_adapter_prepare + .params = module_adapter_params + .copy = module_adapter_copy + + adapter_shim_new() + module_adapter_prepare() + module_adapter_params() + module_adapter_copy() + } + + interface module_interface { + init(processing_module*) + prepare(processing_module*) + process(processing_module*) + set_configuration() + get_configuration() + set_processing_mode() + get_processing_mode() + reset() + free() + } + hide module_interface attributes + + class processing_module <> { + stream_params + sink_buffer_list + period_bytes + deep_buff_bytes + output_buffer_size + input_buffers[] + output_buffers[] + } + hide processing_module methods + + module_adapter -left-> processing_module : creates + module_adapter -> module_interface : calls + +} +module_adapter -up-|> comp_ops + +component "cadence adapter" { + class cadence_codec { + cadence_codec_init() + cadence_codec_prepare() + cadence_codec_process() + cadence_codec_set_configuration() + cadence_codec_reset() + cadence_codec_free() + } + hide cadence_codec attributes + + interface "Cadence Codec API" as cadence_codec_api + hide cadence_codec_api methods + hide cadence_codec_api attributes + + cadence_codec -> cadence_codec_api : calls +} +cadence_codec -up-|> module_interface + +component "custom extensions" { + class "mp3 codec" as mp3_codec + hide mp3_codec methods + hide mp3_codec attributes + + class "aac codec" as aac_codec + hide aac_codec methods + hide aac_codec attributes +} +mp3_codec -up-|> cadence_codec_api +aac_codec -up-|> cadence_codec_api + +component "IADK adapter" { + class adp_interface { + intel_modules_init() + intel_modules_prepare() + intel_modules_process() + } + hide adp_interface attributes + + interface ProcessingModuleInterface <> { + Init() + Delete() + Process() + Reset() + SetProcessingMode() + GetProcessingMode() + SetConfiguration(config_id, fragment_pos, data_in, data_out) + GetConfiguration(config_id, fragment_pos, data_out) + } + hide ProcessingModuleInterface attributes + + adp_interface -> ProcessingModuleInterface : calls +} +adp_interface -up-|> module_interface diff --git a/architectures/firmware/sof-common/components/images/comp-prepare-flow.pu b/architectures/firmware/sof-common/components/images/comp-prepare-flow.pu new file mode 100644 index 00000000..960b8623 --- /dev/null +++ b/architectures/firmware/sof-common/components/images/comp-prepare-flow.pu @@ -0,0 +1,22 @@ +actor pipeline +box "Module Adapter\no-- comp_ops" + participant "module_adapter" as module_adapter +end box +box "IADK Module Adapter\no-- module_interface" + participant "iadk_adapter" as iadk_adapter +end box +box "IADK Module\no-- ProcessingModuleInterface" + participant iadk_module +end box + +pipeline -> module_adapter : (1) ops->module_adapter_prepare() + activate module_adapter + module_adapter -> module_adapter : module_prepare() + activate module_adapter + module_adapter -> iadk_adapter : (2) ops->prepare() + activate iadk_adapter + iadk_adapter -> iadk_module : (3) preparation + module_adapter <-- iadk_adapter + deactivate iadk_adapter + module_adapter -> module_adapter : alloc buf descriptors + module_adapter -> module_adapter : alloc buffers diff --git a/architectures/firmware/sof-common/components/index.rst b/architectures/firmware/sof-common/components/index.rst index a78e796e..76db7fdd 100644 --- a/architectures/firmware/sof-common/components/index.rst +++ b/architectures/firmware/sof-common/components/index.rst @@ -8,3 +8,4 @@ Components component-overview component-mgmt-api + component-module-api From 1a17d9cdeb5b147f882bfc0e32ef92714478a038 Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Thu, 29 Dec 2022 09:28:36 +0100 Subject: [PATCH 076/150] codeowners: add more people More people to receive a notification when a change to any file is being made. Signed-off-by: Michal Wasko --- CODEOWNERS | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 86c19cad..6339b6f0 100755 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,5 +1,8 @@ -#This file identifies people who are automatically notified when Pull Requests are made for /sof-docs. -#At this time, the following people are notified and are expected to review the PRs: -#Liam Girdwood (technical review), Anton Bobkov (technical/grammatical/style review), and Deb Taylor (grammatical/style review). +# This file identifies people who are automatically notified when Pull Requests are made for /sof-docs. +# At this time, the following people are notified and are expected to review the PRs: +# Liam Girdwood (technical review), # Deb Taylor (grammatical/style review), +# Marcin Maka (technical review) and Michal Wasko (technical review). -* @lgirdwood @anton-intel @deb-intel @intelkevinputnam @greg-intel +# So if a pull request only touches javascript files, only these owners + +* @lgirdwood @deb-intel @intelkevinputnam @greg-intel @mmaka1 @mwasko From 4fe2ca22f107942af393f8d1d90b5bc62a38d81f Mon Sep 17 00:00:00 2001 From: Marcin Maka Date: Mon, 16 May 2022 11:28:24 +0200 Subject: [PATCH 077/150] arch: fw: doc sof lib with zephyr and legacy configuration Documentation of a unified SOF lib interface for the upper code and implementation of the interfaces with both Zephyr and legacy SOF parts. Signed-off-by: Marcin Maka --- .../firmware/sof-zephyr/images/sof_lib.pu | 39 +++++++++ .../sof-zephyr/images/sof_lib_zephyr.pu | 53 ++++++++++++ architectures/firmware/sof-zephyr/index.rst | 1 + .../sof-zephyr/zephyr_api_integration.rst | 86 +++++++++++++++++++ 4 files changed, 179 insertions(+) create mode 100644 architectures/firmware/sof-zephyr/images/sof_lib.pu create mode 100644 architectures/firmware/sof-zephyr/images/sof_lib_zephyr.pu create mode 100644 architectures/firmware/sof-zephyr/zephyr_api_integration.rst diff --git a/architectures/firmware/sof-zephyr/images/sof_lib.pu b/architectures/firmware/sof-zephyr/images/sof_lib.pu new file mode 100644 index 00000000..b819e2e4 --- /dev/null +++ b/architectures/firmware/sof-zephyr/images/sof_lib.pu @@ -0,0 +1,39 @@ +component "app/mpp" as app + +component lib <> { + interface cpu + interface dai + interface dma + interface pm_runtime + + component dai_mng + dai_mng -up- dai + component dma_mng + dma_mng -up- dma + component pm_runtime_impl + pm_runtime_impl -up- pm_runtime +} + +app .down.> dai : uses +app .down.> dma : uses +app .down.> pm_runtime : uses +app .down.> cpu : uses + +component "arch/xtensa/lib" as arch_xtensa { + component arch_cpu +} +arch_cpu -up- cpu + +component vendor { + component platform { + component dai_init + dai_init .up.> dai_mng : initialize + component dma_init + dma_init .up.> dma_mng : initialize + component platform_pm_runtime + } + component drivers + drivers .up.> dma : uses +} +arch_cpu .down.> platform +pm_runtime_impl .down.> platform_pm_runtime diff --git a/architectures/firmware/sof-zephyr/images/sof_lib_zephyr.pu b/architectures/firmware/sof-zephyr/images/sof_lib_zephyr.pu new file mode 100644 index 00000000..d39e6c48 --- /dev/null +++ b/architectures/firmware/sof-zephyr/images/sof_lib_zephyr.pu @@ -0,0 +1,53 @@ +component "app/mpp" as app + +component lib <> { + interface cpu + interface dai + interface dma + interface pm_runtime + + ' component dai_mng + ' dai_mng -up- dai + ' component dma_mng + ' dma_mng -up- dma + ' component pm_runtime_impl + ' pm_runtime_impl -up- pm_runtime +} + +app .down.> dai : uses +app .down.> dma : uses +app .down.> pm_runtime : uses +app .down.> cpu : uses + +component "lib-zephyr" as lib_zephyr { + component "cpu-flows" as cpu_flows + cpu_flows -up- cpu +} + +component "zephyr" as zephyr { + component "api" as zephyr_api +} + +cpu_flows .down.> zephyr_api : uses +zephyr_api -up- dai +zephyr_api -up- dma +zephyr_api -up- pm_runtime + +' component "arch/xtensa/lib" as arch_xtensa { +' component arch_cpu +' } +' arch_cpu -up- cpu + +' component vendor { +' component platform { +' component dai_init +' dai_init .up.> dai_mng : initialize +' component dma_init +' dma_init .up.> dma_mng : initialize +' component platform_pm_runtime +' } +' component drivers +' drivers .up.> dma : uses +' } +' arch_cpu .down.> platform +' pm_runtime_impl .down.> platform_pm_runtime diff --git a/architectures/firmware/sof-zephyr/index.rst b/architectures/firmware/sof-zephyr/index.rst index c3f5df01..e89e5913 100644 --- a/architectures/firmware/sof-zephyr/index.rst +++ b/architectures/firmware/sof-zephyr/index.rst @@ -10,3 +10,4 @@ SOF with Zephyr Architecture app_layer/index mpp_layer/index rtos_layer/index + zephyr_api_integration diff --git a/architectures/firmware/sof-zephyr/zephyr_api_integration.rst b/architectures/firmware/sof-zephyr/zephyr_api_integration.rst new file mode 100644 index 00000000..fe351051 --- /dev/null +++ b/architectures/firmware/sof-zephyr/zephyr_api_integration.rst @@ -0,0 +1,86 @@ +.. _zephyr-api-integration: + +Zephyr API Integration +###################### + +Most of the interfaces between the application (audio) layer and the kernel are +aggregated inside the part of the legacy SOF architecture called "lib". The +interfaces are exposed by the *lib*, declared in header files in +*src/include/sof/lib* directory. Implementation is located in the *src/lib* +except for platform and architecture specific functions that are delegated to +*platform* and *arch* parts respectively. + +.. uml:: images/sof_lib.pu + :caption: Legacy SOF Lib + +Zephyr replaces *lib* and other architecture and platform specific code, +everything below the *app* & *mpp* layers. + +In order to unify the access to the lower parts from the *app* and *mpp*, the +library header files provides now a definition of unified interface but some +changes are introduced to the original set of APIs and/or the implementation. + +Let's have a look at possible cases. + +**Case #1: New Zephyr API replaces 1:1 legacy SOF lib API** + +If there is a Zephyr version of a SOF legacy API which provides exactly the same +functionality as the original function but has a different name, the Zephyr +function name is used as a replacement in the SOF *app* and *mpp* code. It +causes direct linking and call into the Zephyr code optimizing FW size and +performance when SOF is built with Zephyr. Building with legacy SOF *lib* +requires an implementation or just a simple adapter for the new Zephyr API. It +may or may not slightly increase the size and decrease the performance of the +legacy SOF. + +.. code-block:: c + + // src/include/sof/lib.cpu.h + #ifdef __ZEPHYR__ + #include + #else + // was: static inline int cpu_is_core_enabled(int id) + static inline bool arch_cpu_active(int id) + { + arch_cpu_is_core_enabled(id); + } + #endif /* __ZEPHYR__ */ + +**Case #2: Legacy SOF lib API requires multi-step implementation for Zephyr +configuration** + +There may be a case when SOF legacy API is implemented by a single function +provided by the *arch* or another package and there is no 1:1 API available in +Zephyr to replace that. In this case, the API is implemented in the *lib-zephyr* +part based on the native Zephyr APIs. + +.. code-block:: c + + // src/include/sof/lib/cpu.h + #ifdef __ZEPHYR__ + void cpu_disable_core(int id); + #else + static inline void cpu_disable_core(int id) + { + arch_cpu_disable_core(id); + } + #endif /* __ZEPHYR__ */ + + // src/lib-zephyr/cpu.c + void cpu_disable_core(int id) + { + // ... calls to Zephyr APIs + } + +**Case #3: Legacy SOF lib API is implemented completely inside the lib and does +not have any replacement in Zephyr** + +The agent code might be an example of the library functions that are common and +must be compiled and linked together with either legacy SOF *lib* or +*lib-zephyr*. + +The dependencies between the SOF *lib*, *lib-zephyr*, and *zephyr* are +illustrated in the below figure. + +.. uml:: images/sof_lib_zephyr.pu + :caption: SOF Lib + Zephyr From 0d8991b4114f50c67b2671d9e0e5a25297a36c1f Mon Sep 17 00:00:00 2001 From: Deb Date: Mon, 23 Jan 2023 12:40:41 -0600 Subject: [PATCH 078/150] Update req.txt file, update copyright, change release number Signed-off-by: Deb --- conf.py | 4 ++-- release.rst | 2 +- scripts/requirements.txt | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) mode change 100644 => 100755 scripts/requirements.txt diff --git a/conf.py b/conf.py index 61b5957d..2ee473e9 100755 --- a/conf.py +++ b/conf.py @@ -74,14 +74,14 @@ # General information about the project. project = u'SOF Project' -copyright = u'2022, SOF Project' +copyright = u'2023, SOF Project' author = u'SOF Project developers' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. -version = release = "2.2" +version = release = "2.4.1" # # The short X.Y version. diff --git a/release.rst b/release.rst index 922761a6..8c971457 100755 --- a/release.rst +++ b/release.rst @@ -26,7 +26,7 @@ kernel, and documentation. Download the source code as a zip or tar.gz file: Source and Binary Releases -------------------------- -The latest SOF release is v2.3 (Oct 2022). +The latest SOF release is v2.4.1 (Jan 2023). View new feature information and release downloads for the latest and previous releases on GitHub. Firmware and SDK tool source code and binary diff --git a/scripts/requirements.txt b/scripts/requirements.txt old mode 100644 new mode 100755 index bc8d82c1..3d50863c --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -1,8 +1,8 @@ # This file hardcodes validated versions with '==', # see requirements-lax.txt for an alternative. -breathe==4.14.1 -sphinx==2.4.4 -docutils==0.16 +breathe==4.29.2 +sphinx==4.5.0 +docutils==0.17.1 sphinx_rtd_theme sphinxcontrib-plantuml sphinxcontrib-blockdiag From 0960d7cb3910bdb2178b54788e3f17727e7afb68 Mon Sep 17 00:00:00 2001 From: Deb Taylor Date: Thu, 26 Jan 2023 14:32:01 -0600 Subject: [PATCH 079/150] Update deprecated actions (#450) * Update deprecated actions Signed-off-by: Deb --- .github/workflows/pull-request.yml | 8 ++++---- .github/workflows/woke.yml | 2 +- .github/workflows/woke_pr.yml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) mode change 100644 => 100755 .github/workflows/pull-request.yml mode change 100644 => 100755 .github/workflows/woke.yml mode change 100644 => 100755 .github/workflows/woke_pr.yml diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml old mode 100644 new mode 100755 index 5ad42d65..f10d87ff --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -35,7 +35,7 @@ jobs: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 # FIXME: remove this time consuming step once github stops # providing a broken package index, see @@ -74,7 +74,7 @@ jobs: # https://docs.github.com/en/actions/guides/storing-workflow-data-as-artifacts - name: upload HTML for deploy if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/publish' }} - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: html path: _build/html @@ -87,7 +87,7 @@ jobs: # download the build result from the same workflow # https://docs.github.com/en/actions/guides/storing-workflow-data-as-artifacts - name: download HTML - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: name: html path: html @@ -106,7 +106,7 @@ jobs: # Makefile downgrades the Sphinx warnings, they are not errors any more env: {LAX: 1} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 # FIXME: remove this time consuming step once github stops # providing a broken package index, see diff --git a/.github/workflows/woke.yml b/.github/workflows/woke.yml old mode 100644 new mode 100755 index 8943d2a7..8338578c --- a/.github/workflows/woke.yml +++ b/.github/workflows/woke.yml @@ -19,7 +19,7 @@ jobs: name: woke check for all file runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: woke uses: get-woke/woke-action@v0 with: diff --git a/.github/workflows/woke_pr.yml b/.github/workflows/woke_pr.yml old mode 100644 new mode 100755 index 0c307257..7aa97088 --- a/.github/workflows/woke_pr.yml +++ b/.github/workflows/woke_pr.yml @@ -21,7 +21,7 @@ jobs: name: woke check for patch runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: get-woke/woke-action-reviewdog@v0 with: github-token: ${{ secrets.GITHUB_TOKEN }} From 96128fedd03f5e1b5ae0a55da7282b1fcc2d2743 Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Thu, 30 Jun 2022 21:01:39 +0300 Subject: [PATCH 080/150] Algorithms: Add equalizers design tutorial This patch adds a section about measuring acoustical speaker frequency response and design of IIR and FIR equalizers to improve it. Signed-off-by: Seppo Ingalsuo --- algos/eq/Picture_FIR_equalized_response.png | Bin 0 -> 65252 bytes algos/eq/Picture_FIR_impulse_response.png | Bin 0 -> 27728 bytes algos/eq/Picture_FIR_response.png | Bin 0 -> 53684 bytes algos/eq/Picture_FIR_response_absolute.png | Bin 0 -> 51106 bytes .../Picture_FIR_right_channel_equalized.png | Bin 0 -> 64622 bytes ...re_IIR_FIR_target_vs_achieved_response.png | Bin 0 -> 60473 bytes algos/eq/Picture_iir_absolute_response.png | Bin 0 -> 51470 bytes ...re_iir_filter_response_vs_ideal_target.png | Bin 0 -> 54469 bytes algos/eq/Picture_iir_impulse_response.png | Bin 0 -> 18649 bytes algos/eq/Picture_iir_poles_and_zeros.png | Bin 0 -> 23782 bytes ...r_simulated_left_and_channel_responses.png | Bin 0 -> 66006 bytes ...re_imported_frequency_response_for_iir.png | Bin 0 -> 65366 bytes algos/eq/Picture_raw_frequency_response.png | Bin 0 -> 67499 bytes algos/eq/Picture_response_with_smoothing.png | Bin 0 -> 66261 bytes ...re_right_channel_FIR_absolute_response.png | Bin 0 -> 50603 bytes algos/eq/Picture_right_channel_response.png | Bin 0 -> 65771 bytes ...e_simulated_IIR_FIR_frequency_response.png | Bin 0 -> 73901 bytes ...lated_left_and_right_channel_responses.png | Bin 0 -> 72551 bytes algos/eq/Picture_speaker_meas.jpg | Bin 0 -> 116075 bytes ...ture_tested_speaker_frequency_response.png | Bin 0 -> 66862 bytes algos/eq/equalizers_tuning.rst | 924 ++++++++++++++++++ algos/index.rst | 3 +- 22 files changed, 926 insertions(+), 1 deletion(-) create mode 100644 algos/eq/Picture_FIR_equalized_response.png create mode 100644 algos/eq/Picture_FIR_impulse_response.png create mode 100644 algos/eq/Picture_FIR_response.png create mode 100644 algos/eq/Picture_FIR_response_absolute.png create mode 100644 algos/eq/Picture_FIR_right_channel_equalized.png create mode 100644 algos/eq/Picture_IIR_FIR_target_vs_achieved_response.png create mode 100644 algos/eq/Picture_iir_absolute_response.png create mode 100644 algos/eq/Picture_iir_filter_response_vs_ideal_target.png create mode 100644 algos/eq/Picture_iir_impulse_response.png create mode 100644 algos/eq/Picture_iir_poles_and_zeros.png create mode 100644 algos/eq/Picture_iir_simulated_left_and_channel_responses.png create mode 100644 algos/eq/Picture_imported_frequency_response_for_iir.png create mode 100644 algos/eq/Picture_raw_frequency_response.png create mode 100644 algos/eq/Picture_response_with_smoothing.png create mode 100644 algos/eq/Picture_right_channel_FIR_absolute_response.png create mode 100644 algos/eq/Picture_right_channel_response.png create mode 100644 algos/eq/Picture_simulated_IIR_FIR_frequency_response.png create mode 100644 algos/eq/Picture_simulated_left_and_right_channel_responses.png create mode 100644 algos/eq/Picture_speaker_meas.jpg create mode 100644 algos/eq/Picture_tested_speaker_frequency_response.png create mode 100644 algos/eq/equalizers_tuning.rst diff --git a/algos/eq/Picture_FIR_equalized_response.png b/algos/eq/Picture_FIR_equalized_response.png new file mode 100644 index 0000000000000000000000000000000000000000..9407914bdb6256ad6334a9ecf3cdb211a5d582d0 GIT binary patch literal 65252 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 Lu6m*BBme&b-k0P} literal 0 HcmV?d00001 diff --git a/algos/eq/Picture_FIR_impulse_response.png b/algos/eq/Picture_FIR_impulse_response.png new file mode 100644 index 0000000000000000000000000000000000000000..8abbb95d14ba62a2d553523acfb2f41e8124f4e3 GIT binary patch literal 27728 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 Uow_#-Rsmx$HL@}!>$}DM2bF`CZU6uP literal 0 HcmV?d00001 diff --git a/algos/eq/Picture_FIR_response.png b/algos/eq/Picture_FIR_response.png new file mode 100644 index 0000000000000000000000000000000000000000..9cbc688f65b8aa6e45acbaed2845abf3ed659617 GIT binary patch literal 53684 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 `giXHsS9$RI+cEp$2H)k$lG7sJt}jne&*Q41 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⪙ku!@(%-6kP9wN# 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¬u#0p-GvhT&LA8tSei1> zwwfj!oV)w2JU0L7LClidree=VhN;~#2H2E<`dhH@E|jzke*o{*9=8r*mc__n3X}y8#4PPBH@P4J0II|TIv-<)kBm$e!}Xj zm+jXj zoy^yOaOTH47T8uk7_QJxAlbKi#(a8-qTWgudn_^ovu?%In7014;-iu$7@h(#?$HzY ztE7=)pZ=@>z+&OvJ`+hlKNT%)zOO(DiD@2mq}YewB9s3=rt4e;-XxLN3WtosOla}7 zS?Puwn!ZzefrI(e)Pq;RNuq=X#!>i1<}NMN*dK)SVAY+zXbrK;p?TS7xbIoM{!i6= zTN7>td1;dGujFG!W^aG59>QKu4UUMLHVBQO$-S4tHU{EmNT^~k9%&5lZs*Au>s0q% z{;~YSIZ-wvLDS(X@YN)ikdh0-A$h3u1{ZQcQb;anoTp)nF{A6o?gvW7N8Na#f5F0N zu#-IjT~@mud;R$$GR#BQpa`yGQ^mb4X^!@Yf-|f+Plrc?$@YLo@=>^!&u?&HthN@j zBnBZ+WGF}Q*(}qabKzC#`nvJ)(-o`pixV_s^(biDnahG$cw*2^tqBE@^z+jcU;{fXc>htt^9?xlpj zoiaC-$jDboLB|IIZjuC0|00WDpcEy52l;T}AH^I%O_UIZ2+(zf(@t!4>}$_3bS!a^ zWpzgHZtV42{zqeRkkp@k9_LuvUzrg~FMjhx+ArP2w3>q?$-}=HPU6L(5{n#Urwktp zM)`%sChwB;$13i>GTd>xnJ9XGKm1>q0s{h1AGR^Qx#O7|A+r>}zFEDEa}bZLLivr8 zgKh%zs-nRbyEoR{nr6Sq!oY8Q#k~nOBitdD0~^-kj5lu=Ru;EUT#AscVX+T)3ay^~ z@74(B_s_=s6xZ!7?#CG4-qQ&HE$J}`4X}06DJS)<`tqR58S0zG#D^;`p;W&srvISN zgaxiyk9-Myy^`-_yYF|aUwYbVv5a5Epy3p|AILG;Rx|1LQq_FBNZlg-?y`E2g zi}iRT24vWbIlZf9t~nQIKJw*eoO39goo4#5MjD%A!!VKd3U?nRj3h`g4)NY7WYqR; z`?VDP{h8`DK9g%i;PS?7M<xvQUB)_1|=T~JrI=|)h&$;W`D7YtgQHlS8Mk7^U% zUCsSw))A(h>s@R{OqTgM5{q3S4Nrx!5~eCa1Lg({^F) zni~aIUSI;JVAk*EYCf^+>9v*}`S-VQ&vpnn$oV#$(-dtM$j?>^)f4+qs~xz^FuFibXryZnr}}$CO?Uw(4(*N+ z%&L+6#Cy7}R_za!kI8&6ueIit^>JjIBIT3If-_|?FAu2QTRpa&C3#PX6OdqciNZs9 z0-x&217+?7A~AqGt>d8%$?33Wj_DYpOTwCSSc$rpq*#*K_NF?sZM%S;GiP9Udu7V9 z=%O!Jw-5Q5>LT`B%I!#w%>!oX0C!cT1P1-?K@OuiyhkzR zFk$M2ZBu+g{3RKRhOEw|mha{|Qn}Q0@?!31RdYoUl{a698X8%is}JD%|D?%c8@lz+ zm(}8rxRWJnJ$FB&#FW)|vJ0bZVM4T!bp~9%q5`Zl@Vmu%CsZ<^-Iyps@8+!wkiN}x z3y-_ZvkM`&-fsQ%LAIVP^fz-&)j$HdKZ=VEj`TJHU4(!4#Nmt#>%C+&1-E9eb&;^^ zy6NtRA?cZVw>w%>z_SBpXIngs;((Pl3E>B@+8_&z6x;i~s;P>R$f^tXyOvnrKZm@X$#mO-dwGGBt{eRooY*~==)pSRtdN3M$R z_**%Qj5W8HqE^~pTTPiQ6fPH!_un>KOW_c<-VMR+fGom~CzSYz-mgXn$XM+4kzEqe+?{Tr0|dN;<4M_Rdrp z=BYKH_wQ1@3$X*y%S=b6 zBp8t=RLX>f z2?HRyX`uT#4mE;lL~!YjrT6|phL;l!u+R+L*3Vzk<-O6cUGp~VG6?r7TN9D+kQIIa zOiOqsFeJ8`aGkW^(3!CgI%e7GHD0&G4md(G(bqL5xkmbhgR@<}c<9Y~pSz?}D|+M3h(pzg z%gCc1x4?q-QWkH{71~<=J^oKF5BCutah!$AO4P4Y}#=xv3t|Nu;_jILjzc-bXbPyld&el zGt$!#nlY1flT6;%!jWPz7$Fn-zXCVn8W=+{OPDcfmF^pF)8|;NTpUCb#k{9h;;BLa zzZCM!QaR^yL&VG&KNSy$(SBi-W4~tc{3{K!Woe6+ko1CqyR5fuw7ti>C@osNZ*G*? zILurSU-2)Wo+-c6!r^<9)NM^7O4mMaTXX1=@$jy@;IC5ImSmxQPVLJ>@^{kKa1z~q zFueF&BO4#Ty_fx1VqRHrs(;FSX3Rd4jm|#yO>cAil4ASJvZ!oirF*zR?N$=wVJ^vGd$0o-)|0?4wEVGY4xIxSvM6J za0?ObggDuF8=gDq)%GHoK$j)%qyx>75-eeQ+;VGqR8kw}tidKg&Xr?U!;@BFaCuGd zwYvFuijmrpug;Ep(ryV0wGJ!xcvIt$iMpc&v?$Y9;ALY;v2lJtXI`s+w#G& zJhsnqGO)pO$F)yi@9wT%$BojfB9+erZCs4(7tY^*o2y@={-a9LsH`Hpz+>UD=ybA$ za(e@HtDVgUy&ILL6+CpGRN0fO{P73ZLIn?e=*&L0gdL|OEWFIossvP&%do)^P8UXu z#k+qo)0J+2bxZK;>}|6NBaYTR$;;8=8el;V4{fWM%fPI8pAT(b&1PX%pk9)&J=VV%X7>|NGpR0ERt#_}FirU#vuNXQU zgM7g^*M@SonMu~w_CO2>BZ|$66g%M>e9!R=ct*P%i%TUdek$e1UB)l+#!9p7nufJJ z7dp9erU#VAct-bk#P#m=GnfsH5BSVI4OLa^Z@Zj-1{8q>E?M;bS9{z3zh=5P#$vR3 zqesU_o78@dMb&Q)>b|u-s4d=$PBHuVYPr~ML4IN&nr#t6$k9^fq3I87ocnnaxbO-F z)xHe|yItF?0ajG0W;*Van z8nhv%ly?9An7nmsTqe=fYUs7|IzO!P$VeN#=g*mcTp@<<$L7LRE(k;h>K_xzFBsF+ zs@RFUx=`2FTbS*V#kX*@hZtxwh0iH{jN`ufQ{_v_8?XGK%G*kn_B9e+o2>-rMoHe#v;wFd_t=OkgUgc%)A-(#naOV)EG-g?+bLhv z+dXZi)*a>U)$w9hA7nftRuVy&#KZsPe)UpyuUv88_rUh+{PxMBEmk!t&2bOY?;8$3 z7Xuc;4D9=QC4IO0RoCk&Sj`hv(jmc3e71b_z5(M~^)6yaQ1QuS(Aa$#Vya`7d7pY& z&6brd_uedNVq1w_GJ}jz@CVpdws!Q+)d~P~ncNn#u{fJErea9Tke`|@HS$Wq*Xr!; zjN}#JA5wGVB(N5%;&OxB=B}VEt!T3qtiB>a7Hrf4;fsaueN*!_yJ4H6()@+;!G&*n z>zyDIM$C$w%y?sMrm2o!bTeSr2Gn=*INQ_O)&s{iJAhv?T{P;=OBV4njE8!VE1|t4 zQ&s3wZB0d)v&Nj9PohF$8J9&KVT0&b%fv;Fp?+c8s_iFi)-&_EnXR22o^ph{pR*k{ z!k?;k8rAUiezxbAmaJiHkK@7Zz*Dfx+zz&b;oZQh`(~?l0};yXEM7TdM-X1Pdt-C) zW>M(Nm5!TH&3sbYZ)>FUxSHaQ=@RD~RLXqs7fI2*pn3C){iEdVS)0T%v-+QFdc^zr zw4Zv;2*@2S-`cygBeO$aZ@W^x9Y=Z7LqP0u9yPhX^R3&(&n3DlhwN*AJ=RU>R{OE+ zQp;^%U;W0W~*ccjTzrsFTKpvA2^9(%btnCE>Y^1q>kMKWz(}i z)UC>_VmR9N61B~ilw)Sze$k%!z!BKad)Xy+O_ZLWWqUufs&X!VIzyKsDp)9Keda}L z)Ap+|27# zUHeZb4m%ky{(qI7cRben|NlEBgshAlTV?Oari_r4O0pA*O7>n+Mr6y55T)#S$;t>J zS180~@4d3u@A7N)rQ;hk61oT zrJK_a+ZG-f1jn{FZ>7?mV}JnapfE}g<@(ppX$tq(>3{B$>Eb9yF-W;KF}Tf<5pjLD z`g!&AiurUf1D(w6L~2A{ho%u1`IFHMRtes!iEo|}@goqGb}h3_Zqw zT_>8yzD?RtNbzQ_ZrT1SI)T@Yq3jm!!q0PYj`PL^ypnu=-Tr#WoFXuIfj3&T_6JZ{ z6ORY^99TBWZavp2G+Q_Gda+P#!Pecs72Aq``JBuNTjoZ^h2W}?z3W)yA6j;YJm!tA z?HN|ooo_dy?MLapm&QEAqqBZ&Ki3l;+4D{_MXS-+pMHIsk_v}#~%~H!wllhGoS)NUj#OTc_KadM(p5XCTAnVYI+rI793U9+j~HcGy6= z`?1$cY!zkk8$5A&sbJH@>_26?S%Mov71`vCJN@w(36W=(X0zvaW+^-zWz7vYPJD;v_;%8g)s*^n>mPK%&OtumD5Ip*jzd>P9 zdJtsWm%#Wf$>OO=qo$l{LO@Wqa_7C~MzkRZBg4{3F-Nq=Slp%A7@}CAObk>!Of2GA z!>Lmu{~murLpb*ArPtY@92wO5^El+t+qCMXaCH2@eVyEU<9q%4dfSUT$7sBEt;}{k z57<`Go0VBKKMR^7KIoD2#4-o*^=t9=kFc%msszg!Ks5S~l#Z!rWaWm+wV%hO;TVe+ zhwzk*ub$0B+&$b=BWhD{@>Li@wO$^Yrf{?{+u=s2<(D*4V6H~zz@BbO9BY{klI&_1 z%(wj_E;a?WsD-!PWBdEp&9YP4Ssgoa(u#L0nFZ&+$u!$ZxNGmbj}_bYFP(hfs7TEX zVZjQ>h%G3Qf*Mp~HlVHbH z>Ym@~GIBr8c}T>xjs8tjb>eRP+-_^bGLY@QUkka}bWURHg_)I zW`v8aPT<)U8OEb-KAM(P&nepzD4TorWUNE(fYmM0CIQoL6_I6Nu@Fm^OP37Sr%*wF zh95TGm``=J9T95u!uF+k-uy2)=hZhFQTvh6O^!}PF^-K@%o`iYB{lu`w`ph1gBeb> z*6D66UyIwod=cCaV{CdI>B%QJNBLuMG19bC@ABuL3bcf%0>bQQ+ag(3z8(2TsPzjj zvrhA-3f=zq(T_f|l}wC7oQr&W!dUKS` z;^*g$xe+!y2gw!Xqtz`w>Kl0IjpV&&?(3}#E9+U8mmgtukMZJ^E@YGDHA@-&i`G5I z1@DF)ywDiXt8P_S(tqf{u$?4XxM5}1=6P_2PiijBrWEh^eL+5 zb*JDcFX_rqjKsr`ij8&iE&dhH2UM-m<7uv+vn15RLx~T}cdSqFN=D9)__D{um7`erH9Jr+S zWenPt5S33cZB2Due?G2LN<-fkUYaASe;4DHlaIN#GvqfqzBe0sKKe(AjmS%;MMI~o z{4CD|2QS#sXAF2m=SyOI#GPJRaGRvLH^00mBq@_JT~TGXrg;**YRK4cYg@N!)(bwt z5F6d=7@M}cW}612)Mt3N5?X~S8;?!4%=z<1q{|J22@~G)`tW6cNh(fwzdtzXK@U}H zghLC}XN(z_*~B%wx{{4-sWCf$>2prftA5-`Ka;Xt%5z&kOsdA&);wCN888YbAvt)~ zTCvO?x6=HifU{%B>9nXpFa4^YJ^gx;dqIX~Q;CCOP?29FW&c`l@$)-;g{;HI7viiR4e-o{Z}{wikntXJ(5rxD4Uq_n{>&&h`F4^*SX#% z+$cnEB48tst^D{Db>V`>K{*qzpOLFlryEn&1>OV)w2t=>jn|TsS?!5xl_C#&OzwEy zUNtkLLHAi9E1B#|^=jp}wYSU%Ud(7B0Qmzs1OY)LWWv80^ z0X3S$^B`@2maj!-pr>qeCVg+bcj1&-t(z6?dEVvv!vR#6P5D+@Q@HvM!h&Z{HCw%fC>`4vs@B;8-<3#NrpYBo&HJ^D-Zz50CX zHG3LBghJ$Eu{p+vHFF9sVC2n-tjx>$6DtNM#9B^S53s~t9r`*vwH$fJpEz^${x*Ae zikz2ELmmfj!9{(PA8|L25z7PWFDLz0YAtJHhgaICQfQ^9`)|TZZ#Ah}fpx&OpuIi8 zVNtBWedxWK!Dd-Ux}L_5)ps%J{VC|rducIOgs#x&ju|>J<4LWTxK9@BuPo0LuPpRg z(eTwm%rMJpqv&UN9mxKT;(j!;~|fwrkuBki#_59Ysin@(F)pOo)P(g=xE zprTKg^Z(JFQin|n8Vnd~@t1W1iIBPGwa$R|Wl>^?75qSr)4v_n9qSt=q&^6OTJPf6<@coIq*o-r6mU}KY9&7s@bbz3Q0uN-?% zy%DXJL&H8;nN_{J^5N2oy_%`7jrOOMx&l?d(1KKss0)?%5_fHrTgHC$d$BUo?O&h% zFzYl{Bo`9F^`YG00S-|M=ccHxIL*Lwbw4x&YB;_gSLs{#N!M~L>fQE9$7<}#AJlYw z;_7Nza$;+$FHgkz{PAp1 z+VT3X)=bX_>ArA44z~Nlr1p^cv|9T2cEOa=q0bZMW#9xuh(p-x0Tzvuv=_4A4iUK@ z(4^YihgQn3L-?zT57fTiHiMEv&dRfEPvLe1dfGPfSBHrdG6U1JZa@-b^6(nswM`M^ zgHLnz{=|O7CNMC4ismW>Ggc zHJJeBo)HIz%Q!>fXc(7%ZfpgvGwiP`U_A$SXeKIG8ni;$sl4O zxQ#MrS7l))QQ}lpMFV_;8*YRq(8-JTXJil8EwJe<;@D*bJzy|KcPI$1KYr2> z%fcEC`~dP+p|=PX2HUb4wx^mlXI?0*H$ZlT?P9CX&fy&YPbh}%;;Jl?u$z;8u(dMY zk$L@1?cW~tii1@iwB(B9C z0oALDDd9S$ZN%-|e&WZrz?sZ0gqyP^ z3_b6}T$GqDQuG6LnyKqYBv?6Bj1--Ib9x9}zbebSN8CznxBl{p+0mNozoMd<&k%X7 z9amxNNmV$(JG~$^9r=b-()|yxyy@_U6<$%I;)E`uRwV0%WLck*J}YFO^m#2?`x#pF zM8p|H+=mY+QJ z_b>O2Qvv{45FGoT1gv)A%vdoNN~hYsIM1hx45K)1&Znemi_k~781<%$3`gmMU|!V zqrl4xqmHtv{~<^Wnx&|KV3Ei$Fshm>dD{ws4+wCRc0` zMu(axQuO>*wO}uTmdk+>78DYvk;LLR^7Iw_jkLp<(gUbuq&pQU2`aM#on#0ZSfM@O zZh}PovISuHN{5gPG7<#MXeEb|7h7kNAULX-(n0^7xqS85KsS!cpVMEqRQ*g?!Dv8%jO@1uqW2cEKp_Es0-}E;*lkwFwHgADl6LRG> z2#eA!Q}`zF$jKw4fw{ALfAVW4{(vCpi=l>aE0i%EU{$NTOa7U;p15w|&-g4*q!o1p z59e(tt>qawpn5oEy={+A=7R+65|K#tzaR;IM!)-!Tt%&F*oorjK5|)odPidh)n2|5 zXC!}AZmIrIq3ahQn#&5gwiMq@1c!h+bLgTohwJUPqR+7?P#lGx%|C)51<6JS)q;zY zXOUMYn_mM9qZCp6g4BL?1RbO;|J~C?3UNRhhi%nHq7vW11RCI2p9y@iq4*V2l)qLmbW|- zy7dSe{#VlK-_QA>0t+_W@b|H}Go;Z1f98?XONM3|57>AO%6a z_uIz!UybGj(;Xq)vw1L4Hy{^P;3b1YH|6@9pOCRPKtfsu6p6rUEQ8fR0L$Uk`=4Pe zz7GP`b;2~ld~iANdRX*QxB{wRPNV8CmjA(uYtCx7OgBfl1WE|GA8 z@CTEl^^@Pt@^=8`ZA^zb8Ko)mTV8K~3&9!CT5!exv$ecQv<6p`%waaie?R&`0~c;e z5nm-^%FAm9d{}GomH3`%wQVAqu#ckB;M~wa8XeD0Et`D^@`6utuz{w{CD@%~J&fi* z;n^3$1!&2cnVA&3e=d|jaQ&tKm?t&rnFU;|{i-Sd1Gb{hmj94*6d4i2I|G8TVkV#= zjrgnZ)jNrv<46fx1;I8GcBuMW#_t6b)rXa0p{I<+0leX_za9Tx69M#6BOT>S`Vfi| z^+G*T9yqoFA|nCx|W?+fvP>AfYSC`y0n5zn|TNw@hiSRTx57 zzdWfv4FVw4KC%&fPM@$l%#}U*@P6&k-`e;|NHvMteIF%ul^0H44;>^UY>#*&uq!A^ zhwR4?fI#Y~h};Y(Uz6g{l=-jTuGkfYPYNnxy2^JT8+9JvyJP{Yy!wX(6Gi~$_z3kb zjsIxsCR2ggJq^z1ppu&b7%TYH2tpc#8Tz%9_h!t~<**Z7w$>$+C}l|| z`~fxny36!2X$ocHy89sd3qCEt((Y#6774ql5B0>raRz~TEfNl{w}VxVENsZ`L!q`F z`>a8x0X93SZ+fEXc{(c~*m@HeDS1HLA7=1KD{h0Rfnmq@Yja)u3Ypqk)aUkEnn1+MCkAu$YwVD=3k#h@nD>bfw~fG0 zFGzz~>Q|u#*-}~aAb1%HBng8k+Tf!LT3R5Vp7|XK{(3D1Hs-;v5e)g)`!w$a?PJfD z*iZ3Ga2^hYunbU|GAMTpRs*&+;%DY3)weLl4;qWakv~f1PIor%(i2=7|2=qSXB#@B z5_0NUh6O7qp`u0jSJI84?b#tiZ)ysSJXX#e`}iU(vsp+&H9_q<`A}8QLK^JIg9Y$s(y{luo8-8`sJu62%*Y(to;Aj zRuurLO>f#sB$vfa@j`SO38-T~2O7!JuoHbrFnBA~xUMn}tfI5sXe`|su?X`X`B=$L z;Aiq5MO9|O!(j(52#`+-y`KIO_Mt>V&aiy{ZUrlWH$d%25n&&pIAGxlyy^TudoN)L z84Mo)0mUmIyM^VcLy_u#n|^<5J+Ra9KfT}ZyU{o@cgURlU9KXm6Q=2u^wZcX zd1Qdu7oOzN2g=x;KcNlS-yn|;W&Ta6hVjhkU+!US(^U|Pu>vvrw#xIGV(ssV^%~m6 zS6k1YYIL&$DWxeJgdt(GzUwlR`39FI3)(M-fjGoHl+YlwUDrl9kep-?jZ3M0&VnQc zx3%c;+Y=#t>i7*nul&|GRx$Ei-UR?`W@xF6EGbSlMB07Hq)trE`n50W)sry98c8ld zp&i34q)o4fv2HCXsNNmt^X1)*rNqRu_+PL|Q*+W;!nT}A2>_X~DA6|UfCX5qrt&@y zGN+;MLd-Yn!-E~9r|K_54g3Bv`^5n%YfstDe95h`NGy<#-U(w|Y!7}VC43;Lmd5Nv z;*w7Q)c79V%~fB@qMh}5J-0EulUnE`sRyBROHwSZs(0QdQ5!llD?Prz-dGtZd&hmg zxch$Sg{6@ozGgrM-EzC3ZU_k3p@v3<$M~$g5hzW~fFL{uXC^3@*S+h5$#wMUs`-;1 z7q~w=rv2q9SBd%6XEdFp-#}WS|Mq;?3-y=cpTxy=raID9hVCOh?qPB1ow-6oxstt| z4U(JTP5_@TqJ$k)7IPkZP@quA1Auc9Vu}iC`S-bUE3RRWOLPU;fBG|e-tyd=HEQY9 zkTGy`^pGoCtlGhSwz)YP8Uv<+^qU0&_(C%;DC_II_9wk?m8A2 zuu&V>YtDx=1|Sx!wDqPhU3ymZZbtQ%rTtxTVc|s4OKU~U zfZkWxkLuq@OyDM^9^9P}f#nejk#fKblp|$ZXSI#7LuX3~uBI{WDep>>?S1|Aj%tORKXCzg2Os`CH)`sz zfDzkF786CT?DIvQrWJ2ZB&g&XRvy*7SrTlBp{`mwUba+A7(A{c;>v_Pc25i;sBmvo zpAl%l4T61+2-zPDbe7!j2RA)E*WMd_1{BgG?t7!$Ja;GV6n(ke>P$P!z7A&FVY$HUjJw6858_-$ zy&rI{{(wbD*&cQErULx<=GjsNiiVgcO|bgHm)y22ZCXXoO(uG#zjezDX6uy>x!{=Z z!F5dzm>w=>#e@9N*$Q^VVr+C@?Vf{HYI+EqAq z2_Q!TAsdsJrEUl~%@?AjYwmIuTDmj1YG)KoH7vsi#IT_NA|WPR_j-El=_Jt)Qn3a? zKzLn`TfD4FS`ODF(IA+f8Cd{z9jFE;T-9hUgoJJizZlOq3x@dmi?gud@_nz4sY2X4 z6DW4^Hv+E>C(43c+F74c)ybhqLFo42Hk&`cq>={5Q-+pU0TZ8txUiPcK!N)TniL9} zQ9?y0Qa<&FuI9#u>3EH++%OlY_B#>!vHogQ#q7)(?DtSmTe?n#mC@@PQ`mw#t7U64 znQ<5GPS90_`~(UGWt9XfU3~?g7RuVZ5rhCHYJjD-U(85l4@_mhqT5^aRj@`^bg^Pp zJtb&^1HKm6aRIgu$iEG|MhdGw?0<&WYtj1qjC zM~3BhJ_Qctr&?=#mm?N?t%g}tTYfTJE3sH{9>vJDp?Kq6DE!4T02M-?leUI_uWVR| zaD>;Ws$xB>BU-2UzSfWeB@vzriVEgk7n!`MsWhy=N~VJset-qF<8=S^P| zbX%YETZ|<%jlGs<`Z;1qK;-?K>$sw)h2C=3>WR2-3~w;jk_y^r9`xHqj)R!784;{- zC#vbC-Jqq^C7yDyJwJm)q1Ibn^X$rK_h3vvy?c5lat4SX)I@mf*$EJTY-(3ztZe6J zTIC1`f{&pL%3Ex8o%AMRO-cmnAl8B^tG}51!_^pt*M5WVW0{iQa1EmT#L}uSuSE?y z_F2{(C&$dZ2mfnv@0ABQDINfjQ-K2FeRRNcdWoCF;#04fctH{R_M&^Y+#BRm^j_*3 zyem9}7|+S)=i9;-Jr>=(ix~w?8i; zX3UTm6WY4dEqzUvVTdJ`aev8Q(ERHwz!ut9A;a5{R|b`J`|}QQ%@i|lX1RujX^U@z z&hZQofv^Y>>=YHS?^O;QL(YQA8`76%D z&pSR`O`$wi8M2*H2YJ=c({GXu-Okp0XC}hquq1TN(D$S#$Od602dOqQCQq`$-N-@$ zSp=MBB}y3{vvGd1Z8O^N*>h)}x^?tgFBQ=#!6G8mfY(mnpmgvP7*M!kZC`Z~=(2GZ z-MOt_X=v^+->an#(-DXl<^IwacwNK;)v)sLudaYc9?vRlBiP4FY=fCAA3iW#6`-`E zJ;5_^hm39b>0REa+YHImM`_d7d_nO=pD0<* zHj`qq?^pZh@o>C3$Hm~ zhDE}Q!Mz2ilN(ut!|JEFAGf-31a>$g1NfEuD3*H`n!)j4)iiLA$8C}W3t%pbo$ zZv?A7Tql2Vlstwn!k4y8WDGE{BDxCn;n%A9ZcZ(BqzARWlqg+)-c;eT>a)k<&i>vh zmQ^jDVs7W9(?F(F;XXmfwl51D7_r+;v}Q`_l4zeC>G8E*-HcQh&s;Z`!l-(J$BOvT zr@HU{7@=77)6*w&FN|L9(2!h~U#d=Jw>*ZtUaxVb)KJ;( zE;othlOfPL^c(-!Xh?$?K{=R^XiBR4Mj|w z!Y;m=_DTQq3X{so9BiS@fQFBc^Cih`fd>CfJyq$s?eBmYosPc~K!$Sz)kbmjc>Z@d z*t@vNbmK_O44cfBGCz)g-KXZ6l&^O#-CE#lcKeoF9~x#-JxqWhGCN90v^sDMkC>=l z8$1(FCUqD?DSOMPnGeqN94QSpA+QQQiZaJ9*%l5O^=CpPCbA;{+bQcf;2~FhFl-T9?5p_n64DdBn22#85%K=-neX zl#kXnbUF8yv5H!jD7-Q34#mw4MRS4nz2!#67+42n-z;G8Q!JB{-y=O+IxdT19wPM! zkWU(oJuQy2K=kqcP+|h9G+wg*v*p0lqLXky9~kj>{a4_vw)4L^fjUa^7ln@;ve?CY zL|V#GyL?AZ==&feKgF3=%UaMb5*UY^%Aum=CHD#3xbw+Do~AZXd4^uXk!a>TI%wlE z4s*uLa)gt_nJ2x4%1ByL1< zG-^~6K0THQAp;)KQvcygtZ|AibNP+ZFB5PA=<3y-6xO<6A4zh=<|F* z!%D1C*QvGf|MJ!Q#E;1?9q6^bZbiqHgg4>ryKze1d|1+E=hTc0$dYPSTTAZ*@Kb1T zcYoC9oQTZ6mCxeLi^CRVtQo?Flj0xt?p{xx@d^-FIY@Q&y+7x%$oaafvrZj*L@nEL zR+Uo0;w3WfoD;_9o-q3!6h`XT3cdp)w<3lKIp)OE1EUV2av%B6JR&7NJwinGG+>nA zqTg<A2-@IBRr39bmRoIEVBOk&2);fxxF7mM}+f0B9KGhQZ`~ zfmDgL#|gWS>|*4Ti(boXqf)2ak-b{5tP@-3&?YvCqfUQRKwK#E&m(q8lId=(*o`%Q z)dtg5c9aC_rheuvlGRG#a4W=ioTb?oA6e4j?zCt`(4%p`B#HP)|NJ8R_{^%d8R|aQp4`-{a(!+r|KG~bx>^Bfc|Q1?3^d;2CRx+ zKRFRy!2d;I)%QJb+)yt2l|HyI|DVToWUNnTLVg_beH2fT(Hg!M<@3K?FaQ7jFrTIa Zl3HAzPb>H8td77x$_nc8IkLBX{ukI<^4I_X literal 0 HcmV?d00001 diff --git a/algos/eq/Picture_FIR_response_absolute.png b/algos/eq/Picture_FIR_response_absolute.png new file mode 100644 index 0000000000000000000000000000000000000000..35b615f0986be6f6a193e55b4262cfdbe1810304 GIT binary patch literal 51106 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 Q z)c`8{Gr;r4mG!H%KgZPb6`$pt&`QKu8is+5d#V{d6BJk4Xg^HYLt8#uUs*PQotD0* zU+MBKDud{hTo}N%5+VyJ7|X~1f~e&y-XK8WrCet7FLrXq_M4cHZR$x6Y3JC^uj_&E zT9Q?01Cb`s0UPi&L~k49m3Q7tvWie@fKr<&WZ@?!^~kqa($~|o1#g`u&dKf2WP$IA z0$?8z`+m%G68pA!~~p#r|;KWHcIF(Ru!f zQ`|RuHm5Yeqc?Y^RPt?0;6t4Dgzcm-eoD^QbB~&|mwjJ_ya35=NLV0?3nCNrg$Yqj zrquRAyMRvStY{Sz4bL(Cgx#8dx2qYG>A2bSfeo0MoRqHt?|VxKrbxK+L5A>q@N3&$ z1qAvXSx2-oM4lQ0NYQDL_;a!pB%wqvYE8#Jo+8^=V+4s>&4`nBm(f09sn=BJdyZ3D^d=8*-}9M z2a{WGa@I8`Cu4M}-#g!fK-E#Mmw6Ln$6ySw&yZ4U$-3*|I!&Rh?B6#01DGYKF*b;fbzGrgHYQwJ5`@n^jvTAnIl?)uYL^6F1qhQ=Ai z=LyE$+@QZe0b~S#<*5jE4bBXp=I52Vs83e?O=|o$?H#&ov4xDMz6foGb6YD1NewhZ z<;>TE&?!hA88)g=ShoflK<*~jxd8CxBwtq`Q|bNI=i6;dHOpt;{@921?+0$I-u#q@ z?eCAWlA;w!CoKoNVb6m2a=nke1`yzgn_ub5%)cxIPatfi~4-tkMX(S+XZbkiq3?TA=BM#C^ZS~!Mla?GHZ7RVHfc@kh8m* z4)!VBTOYKy1>Y|rdH1Kqy}hmJz#_l>J^!(mi-Ukwt2SgFzSX^CmExkp!E6TS214Aa zn9qq4W)*MCRXgt9f4Si8J@LJ05Q3E8(1^Ce*7101a(2&W3l(2)xkKM)vn&zRa-A!} z={dlnARQ57+^5nWevp`Sv;>EwD;g}bYnk(!pBfco6U>v3D!jZv3E*Bx8*9;h9l6=; zy5m7VHy@3H4yo7{#|MJu+ywU=gVPYV!ZqFlwtN&wM$vmJhQwzpyC8A4-4TFK7P<4G zXYyFEj7X=cWUo@Ek~5NH5#xYhKt~p}#&2?Q`24J=^0wV;;MhBN`N4YOyS5O}-ceb^ zwCV>kn7B6n6EO$@wgQ5|WQmvmR+CEH2s|SRzy)0hoBNYgU~tt_v9S08SNvR}{3O}q zdw``v7x(|M_SRuhu6_IOQp6%$7Ac?-1}&XRN+Tj5L-$Z3B@GG!3n>9kY7{~zSO8Li9ni&k<<`>RT48#ZIpH1h)a+UuJiQbm z<>7>9-K)XgmRD6MLC`3}`|k))UtJ-s5{}~Vz*H&_6YMJ>W9F0%$0+YXTgQ`_ckkTd z@>TZz`6d%;(7wy;?+CK+Pb|s|GHI+wWd|j&FaXRFKiF3z13=pVb;@8e0@5B;j#cE2 z;&A-IZK17n;k-xGk&Krx-r7}?*3IB%I)z@izZdmN!sHp>?D06iR+FH)(XBD6FUVeD zy}^Ztvfxi=*Fi}m1DeqmaeVLVD9fhps9pXR(c7j3mLB0Ja_1}j^&3RY6J}eLX>CfW zrI>orFVR_{ZzESc;cSm<4wr01zD*qBi$fJo9CmMYIyzBz<1f0gRFupY(6Y_9gF{$^LSIq`j^Xz4rm%c0RM} z`Gi(GBH8|qxRZaJSYYMDSsyc+Vb}RwJ19|F&TD92dYxb=_mJmu{@M*%*e7wXCq$I` z(X(<>D2O#MO0$`EBv5jD%f4s$zPqx8^*Z3Soxl1#?DnKo5@IHb{ zTaV++!RKu%YdALh0q%t9`fu$=2MomiT)prc6k3{cRay_L+UNAhAuCb8Se*X+RQ$mt zvxT%RHR+~nY_9>PFHeg-snpf@S}>W9R?@NU*Rbs;6#E;2ygh%2fOG7|gZbn}sy*!K zvJkJ<)B9(|v~`XI4R8o+o?)dLO1Et02oaqZM!$zk_u37d&Krye^!BQ0+Hjefg>8CF ziqCxEH^V#ne}kj{3?d)a38CRS5O^U5ohFTmbEgAqaei_1Ynj^~Fn?O*r=P)zyHc~x zCxfZ~+EuT%!G122;X<|5VR^rnEtg3y6#DY)V}6|U4CzAuo!1ji$|``K8%Ar0S{&+9 z{45t|sfJ207saiSH^-+|{qUoVi@nay56o2=j62&cxj?*VjFs)^%ro%XowtV>{N;;? zSU!6#4H3&znZS{H8&|)>1q@Z$mM$D}P~Bl%*IlGY-3s`*A_xb#0UD6@zl_2&;-6vS z2HQjdODM|8Z~lDqYkfGN$f?aY4>_OAF%$v~j)j^~qPv0RaLJy~K!hTp5_YVKc`;}c z9p>@Np)kS1iM>8if|efkGJ)gs@G5PDCXsCn&={(_Vb;ov!kF70o4jd$1wl&xez=yB*PM!UC9p3trd0r2Q25rP8Fc4ZAMUK74;j?6&vm zG1FJKS~uPkoI0}C83-r2yFlS!KtJKpz|$xg!pnhRj3kvg*Bg$fuV;`O5>8@}$q&CwUHfI2jA+)XA?(28YLwUPPJ&RSUvANlQn6Z27P4&oF-+ zbI9UBDT{6!FLTTy?3`M`T%!;HX-@!Iy4*bWG5QSy%9i9d3U=t%9z9C+4OmgcP>3P5 zG%{g_S8?Vsa!)hZO3fYywGkq=odwY~0}6itA(selVGm6Q%h%V5t#N3?5@uWo^7ITz z%Z54uySecQlRY=4Ps6O_xQpcm>K4KF>zlu20Wr$!0-Pp`r73y%O3@44eUd7j$$gz$ z0luo;S?M&QG*6W6#0aF*D63kpoP;4%RIdF*a!0hqJmG zIrm7DjGEg2kO9O?W=gKgq`qUwGRH^>HFs`->Hh7$G8Cp72C>%`;{>hCE5{QKt!6jr zznNf zgLaIHniS@DP&N;`KmTx%lxjRh!k?-q(=~H^P8&23q%r4v2+5GLM@8day==G-etGK6 z69wD+Yl*PUw-tWb3R6xF{m1{Aa;E>27kH%b#-oKV7f&N6q;0hp3I)UNGa^0ZZLa$& zF4-%njP@4})xQR~UG^G$CSPs;Fs_Q__=e117u9x=+S%bL?Cyx#PpSG+B;TggL78$SqJ4jHjz|2JO3J&AaC8_8hq%IFOJR3Wc|qY2b~c>k<$u@(($9{6 z#CxEg%Uzkh6M+uM`up?yK%*-je;P}vv2%PJEr(?t@DuBEQysVEXO111bYbgoqv!p( zw2c&b|K=CIlb?>ZJ#fdl1>k%Afg*Q?{K;35L6_-7fD7I69JvfsdXa`FsT{elxGgZC}Sn z6_aAps*vP`#xSuy%)eqyw*Ff5-Er9TsBuzQF90!DtWv8JAr0{jI~y&kiQ)|fWzs}F z5sbjTNx&Ff30~$5b#O*d5y(nibsQve!K*mIB}hc@oBYEO5jgt=_k^63z<<@23jQ#? zFeog{AyGguG948lw^Vj`PTPR27H}H??ErO6s79_Lf>bpznS6l4I+e|4#CvNACIA(! zaC6x0$}`a<;4zf}M+jlF7V-wcUTI&>-}m&x{&(Lpby68-qzDoR*&V%MLfJ~w6CpN% z=PwXlw+aNO$51*AG#e^=(F)$qZSws;tC=W4Kz6= zF!3BvRkfV&3VMvstUf07b!5?$2^W95#e}-mL}qqmeD2NzxhoWtv3Y{&K0H-=O#IcU zXILGg{n^~x9Yka?=c3VvnA&hsk62JyKRM)W*%cOil?SYYqhnvYkf@LKz~R+=%}A4BcI(!n2m8;9<_bR6F_nvjuJ zm=x8D5szuLq7G(COwM8{=k!$wH%Bys`oan(R>gMVJbAi-)yifKBj-J86sU2_=8>7Y zds7v*yQPI~_e{TrqpvA2DwvE)?~J{HO_L(muWEh~Uipug1$yohkyl@e(DhUlb=M3ej^&n*VnY>3xKQ#ckPUD|GWO5-mqk-tlKEm& z=z)NZ>%#JsqHmx?T-TrboD$`~f6fblZ!H?ttLKp!%V^?_JM2LjWg>^OBF%>mt5WOj zbVqyN{`r*JDRp|vIb9~mJ+8`^9+O&}Q*bUbn-ORh)^p;s1FY;5b# zCK&YfHoHw&)HQqK?eJU;o+#@;A$Cz}b0&hTQJbGOeY4}VE>Ljw6VE&nsO^vy7 z<>Q!-Nn+HJ$fL(eOMql5I2!1GH~#9+PnS-B_|(VnwM=)N>ybWDW6eN`yUjBkCq`#l zkA02%$2HTad`a>6WX9|{D%u{ZTo4%+N(Y`cJ-z%Jrh~W02koz($SdMfk+Igc#3bkD ze$+%XoEfd6j?GlL3~emo;&L%2*7`7x_ig+A{r=qF$E5im#9{GGHLsg^?Cjc}EKMz)W-})qU>GXrZC?PE+jp z0A0tJQ#!5au(5~l?$TD(Hy+#aq5F05{=|0zr^u!k1{cxiPRGv5qkOYT%joS?fL?Hv z-U&=w@*u?tw#91DgcBoU{mVli!&yqd3H`auomjb1DSXU!uFw4{V z=2aoe=%N6P*em!5wK&djs5XpH0f2sn2C)H&BfT()sc%n@E}>%wDXn6L4N>VWG+Z( zT`p!Bb8_#97lwofl4&I#~idK zK3yU=c*y<=lMW|amIR`}_@GEr$o}=yB@?woLF0#a!Ekx~@R->s-*au-J?8EUycwNe z#xkCVrv{Gl9SQVAOzYgj=4ACfCz`~J+GTjZ+rJL6oO=#4GYO;Yz)|WycEN8yP9nvX zM0mq80Db%=KjNey3gq>C;Z25H=>v7dPE&@?A)PQ3Gu`>s_5k#mGlp9W_lD8fQ8;;O zPG0V?%qwHM|DnV15wGZn`cpTBx4b6;*!(_A%EJ%AjZ%0KliMZS=!u!`x(#M)%w%@C zC;2~97H>9i?iCIX!?qEuw&1~KbN(eIAagc%AUjV!`hME^y2F!1Y^4{SzhCUUCkV3b ziS-`k&Z@N@NqL(k*htb-Jj7K7P;dLEo@K47k{Dm4DR%gEZDd=bV!_L4T$QQSdwBQ~ zU3n08?0PZ*DgVXN&0ZR(!Am7WkF*NjUKCvli(^8$*55^jcL#Q_F6yX9qOSGb9W@5C zejl|a^xQD5xz_fUOD~{xSxsr9VD0;Bc`Km@~r zq*Il7Hx`s3Z)RW-$$&+bm71tZgalOVFo)ibGq-p53*n5XyL@s+e} zetyZ95j83UOJSOQybgbbw9i*DO=qUIrQ%m`OZyUofJJpbz1{ z?0kI-L7TcicNbd)Ym%ave39=aQ z{H4A{9QcR-Mr^$dc|uoE4wbMV5B+QIK>%5nR06j7F!}WZj@bEhK!w@?v%Z;bZ>vea z0syd+yFZtrk?ywiBs)9Kuos1Q5Jo}&@tWcwJyW8Vh=AH)^?Mql0@EMaC;WYI*ns&4k&#p7p0sPEG;6*h zx)Sg$iWK2-F4XMpuHt+H0@D{D0K)S!LY(bwmxdNcL*LH-SE`^#`>_@S%&5%a#^?=k z*^4IM5Q`4Qn&e{~?W9MnY?dhyEIOyyk@N3=T6Ah3UkeB@`yHAeMe#VMyZLWSy`b`c zcByFUcMM9l&({rHk;@^$Ca?O3?6B8YnX0OD;21Txu&w3g)Ma0%-24+M(148f;nZC(wEy^YGOIF++$c_TXyULr9NtPW z2}2xuaZR7nNibZ1eYeC}seb7ogOE^LRWnWfZ_&6i!@y6oWWERC0`FrGnIeJ#nd7;e z&1V%As@<<{k=F37&%xJG7j8@nZaav~aD3R)tz}cCM(h0Tkia6Q$NTd?32s&*2!wT@ zAJ#l|#{pj?#|E;Ohamorc@IrCy_8%TO*W3uf2Zh`X=FF-3hzx$>?K=m+7h7RbWD;wksJ}qz!Xk z{KEJO7zY^@VMC0}Smu{t6rjkLhkT9UFw7$Z#a4qEaFE_{2lSl>!DET%$o2S=ber3O z2&`qsPMY~730;X`a|C?pxf77V+j)TPfng3NVcP+HYV7UdRW=v;R%+H4K?Z=Y1Vq-_ zx$L^c;F0&IVS*7;)IbHhBh09(f5xanFkSjU#@Sl!-eNcu@y))5 zfy#)uc=lwntJSQ;@kyvm0HT0^_h!7Azkyw9%Y9V_qX1}75a*;!1N8u>MVw4T^vT@F zE+C(})fxl9DGk)r6WI6Gs`=vp!3dfcvPzm^6whpJZT)2QSw$SfwK%l(D($s_E5PM2ggMUkYx7-70lZGF#JBCGS zBoNTAAJ<^kd00zW8@*CKpBEvrIj9P3YVSQ85A+DBmf?Q^@P4P84+#3&+WSg9L`r+RL!6Vw<$1f<8E#C z24y5DXW(i%c9cdloRHkXYG1qgdZb;Fi0e&&dNn*;IN`CcCt}AzP$rEdcRDA3o3)nY z(G0BAtRj%s)s$7~z;l)W%#T8Xd}{q0f4?goc+PwZiMGHcFf_75st;yMJmRFj!n2Fq zcE~(jH$v0)NsHa9)0em#gX+eB=_mNYXd;bc)$A!Pa>HqnpMxnIN0(F-pgZ^=MMe@9 z=rh@He9rNAkrMDBXE@FUIupB|dX<9;57bB;i;WbOh9T`o_y00?d#RU$<43}WTtlDR z(^3wtys4BXvTuKnunyFYNWT=m<+@Y_O63qCC78Cp{FV_l+I)D_%zR4`!L25rqT;@4 zYdAqP{bKgKbdY&1$M&E*hL%boiCu(-HnGSO^>?Pxjk}j#7`;s8ST%WuBS+ALGGki~ zA0^N+-mXp|qJ1CFz-n?4J}Tl-DrSX`o1;Ds5iUy z&*>oQ=M^|YIsY2CH>5vNUzFH}zSmj?TBAI}dm2vs&(ch`C`!qAiw3 z6CL|BS7EZ&_^8+%Ie7oVUW`!?r|rt**pY{k^riE1aiyH)tCZ(^Ms3|QuqGmiSW1z= zR#(v!dFRL3z?5D~f`{gc`A6f%L3gR6Q@(wfy@RO0@hm!Th56HK-eP+D<24^HSWG9C z@>t+xBS7XNZmX-knKKV1m3A*vCvnn!xH6KT6um|EzI9#6wrh7YNNz%Ui_q-?(Arpf zaNs0C9j%~ZJ~I19J5v7-jSd5+tP0ey_uCTy9y!~n1}I4QDrCWadFAnPha3i>e@JP1 zq^g}qTnLDmM(WBIxDp99=zHI0SNM*c24r0ol@MfIJ2;&%?cEa&wSN2BAhm zjjVv_x}%-yOKA@{A5cTX^V(%U_@03X(}vq^8G!g6zGrQ{roLH`%-A>V*>_VT8!k5C z8lzefnAJQf6C8bdc491$J!<#&Px8J3q!xo^XE1(yfX8ORlJ4QnG@#%TYDs8PLII<+OJr$px(AxQ1yzCm*kQMgac)AafAO;FB*oQ|H z*WG}6`kEUUPy_*yS)+ND71{llPLr0{LHg3!35d2*TwX$|RR!u*8QKRM`V}qO$bR=F zn$uOG{81iMtVMs_2e2d%48bNU2fd2<)BGqjkwVGTaWSDmpH5uA(vDytS`*Qn98$<0 z6iA1b68_koZzd9xEyX8Z@gk@&iD+$NJ?=O>wD~`Pv3ojcku(Z-oDlGj853$VD1p5~ zn^&PxG4{F^?`ygOGNelXFC`YaAWbBoGzTKj%Ooa$Q4WdX0p+_7I^Q2{%Mp_NU0q?&(LJ=cX> zhahO0^HJv`(IR`RXUZ&RE@)P^=FW4&+*R&PE~w?GU?l-xu-eyIIdY(;BjDOMei=@D zux5Sc>Tr0<=c`!^qQW39HRL`Kb6Yk1oNr^yy*h-erJdmeY^!L5`5h+EB87;GUN&fa z;#@6d-d732L>-t5nkCcOjNwGI%a#O-&yV7l53$^l4d~wn%~soYLe=|cKOI`lqh(#K zCektqjc;rw%4f^%Z6*znhuU;G`GJBmqAXeaDAEs0!0^@5jU>FZWFt%MIM^k2Z69io zX8K|4E=HUr!>M$U&4abz$ur47Mmn7abf5c{kr)Fr?pdzixBQz{V!Jb4;rsQ#f}c|_ z0 zYgRvqAWquO_%+6^I+3JIclBoZq?C)j$Ig<$aaT5rMcU=6i;76;hgIU_2WNTL-v@hJ z)$V|(G!q6Ca7}g9BL~sgjFcgqBoIsnhI57={y9C|b4~U{a6+dH_9#hyOHS!~W6s=j z$AUSV%x=hT+-chAvIVHwH3iO?zGbK)-ZrKKp@@RGLle1;Zlhu*ob+iuiV*(Bv4Kk- zcu*#n`SoCId9_LLueDf$SB`Q0e~Ik1p4r}0nq$_hGJTrUj4tltQZR$L(Qb`cyyxJV^l5DdKw8|0|GhC^+aO4frer6j%*UV z{}!Whcc;I^(&7<5@anU$RKIrY`e$cES3gK@mZ!|he{LBr35x9eLHn}Bit{n2V#GAz zQAWJ8?{9)xP(I!nL^1p;3P#rf9_BJ#)f=4*HeGs~_CynIGm|GTBDnM5qQ$}6IrHJ% zWu+1a9AtI^{?dmHoRu>R0Q{rY(7ccEdQYSkkK z#iDdExeg<;AekfJx`=H}1-Wo);wrEm@0c;7<^_ZLn%qdD1J*QJyu+!H;^Y8NBl`em zha~n~P-ry%J+sVl4ti&RWzkJ$m|yJ3Zdo=@EfU33>b*NSfr1J^L``t)Avhsmj(O&@ zMS2O?KX2C@9XVw4{mZ5-2wf>gWzzA7;LcH-J$(?H|-`OhKYktaTqNhbr$ z)^$lfA>$eKHC1yYBb43b9D4(CoO}Ql``*Q5^kM~QDu+?j}HD2V(R$-UkD}? zJG(ahQgwkEQ;mveTEqWmGfjh{`2i^BKX#h-CUjA!_NBe)Xb+RY!38I@*N;iY)zH_c zUbsnb4e7PNK#TMn6h0E%73d#7m1gpLYB8zl^rqsA#E?1qT&`bB6|VyNenvTJnUs(B;{%x;EaNr%hs57hzhIqS2E&4p% z;&&Ht)GMg|=b<>|M9n}_gRcwFJ2XPdMCma-Ig;}P(WfGgHI^?ay*$_6wgMNJ@PD%JZr zS~7>{17)bkk_{lm(AkPWjE3qK^^4p29}Y`bE7%~58ADWiwscp=^GgyrIIoaGoE>HErJks^V{BGol!OY@(k^~d-)o$8tL+vu^{P%N&tkAi^Qkp1nMy5#g_8Z3tp;R?4-=*u65O2bp zqsP4U)k*Khy`7qJ$MPc30cjqgUHt=9q_{}N(Y-ec(uN$i@2%a)UlJ6?LnhLt5 z(jlJu;qJNhRvwFfoV7JK%gc1sb7aldX+6wSD%S>U3)^jd?qyiXUhjb!Bt|u-3Y=S1 z&%n8bP{hW82wh+JF`l=zT+yZ_uWDd&gHfx~5vnkPXQkJAS&)wkO3usYIbxp(CmVe8 z%Y^nCpNk^MjNsRd+8h4DU3PdQmy!?9!#^1pvNT|0OPIDGap8TM3;5YsZ0e#7z zqg%cze@|*tlzYeFwOje+NkE{#t~SNs%Q|q5gDaL)`8r*7p(0cDTgPBZNk-qVClfFX7)x0%7sDfi{Hj=@oP%TDFTOuRs z-f}0l#4uY0b}QiI7DHxqFk^w9V$;Ly)bHmwo^V%xmS|TIXTkrSA`RysisUlMd z3xH>q=w&>UzevGGAL%bvM8I{IkoE+LT3K6$gmD#rgS+sl6 z;uZ3#MGq21uyX~0cH56*?V5l0av~ko0Y@6&Kt{6Q$?9GP*_D-DOT!PPK>AeVT5q~- z>~C9{TZO&j=r3tW+Eii^f$6+|sZ;qr16Q=Qwb0eC1Muo}3Cyf3n1#Kdi~L{j($M6a zdajqQijS5)d=)Ich+U=p@L?ssrt11gSrO-TDnmL~hQsN|#x;2;VDi-DI{)V&r=ph*wFTnO)^7)H?sMiTr-MS4$G@4OA9{QP6YqSfV6k0C zw&;98*d21sZ(Pz9vKVA&?6`eF2Pfy13hskCtIf>KDW;HVr0>!Z9b-!VUi;Ov`K=X# z#L^=B89-Z<3i%+xwCX}^6~ztPM?!!LhpYdYR#mX7whmXqFcGL1RoFnC~%9H>60Ah*t^ z=7+knpK%Vf0xrV4M;s_-E(adEO^!sj3CilpP{6XlVjO_V5pe@J=^rqb>|eU*RBtxf z7HNF+Pw#v&oMEujU9`GOq-DJPX|X1>=H>&74!CK+;C`!tr1bIn%?HogdrfnpO4?lu zPkEAca`aB9^TR^8ZzMHq&`}9{>uta=Fftix%pI7*o51%Oq{zr{tnexy)KNf*>$r-9 zbF6YIZgl-3x}SS4lLrAVkBn(vmGRRF*R&$%4e9Oo4H71watztzWC+MRyRxPls%RS1cEf}z zp5-8B2m@%zr*XctICXf*!}dKU`SX4bzigU#ZCmSjR&Az9!k^GLwQ1y8M-vIo`7W2h z1@f$diVK9W=a`2?uyy!@^c?u{&g9+<)w#H52VecU%QYK*iDJXBbewR}3niocwbM6S zpO=8P9$t-d-`#n;`qlqF_i$;);yY+xs$4~x_iTs%imkS)$O7KhzpxNR%$o%Cc@U-{ z^{0*i7Ny~~SE=uzZoA1ON8sAQh4o$<+8HaJtrzaYMQiY&%+Ka(kmW`?C5YVFDGHr` zs1s~Grl*Hu5Tfb3;yie_RFnud1~A$}NZwsMsO=nFDpKnUbl6`AQN#ry*2cx6t?$=t zyeZz);Z;y_=kCu{e8#jSN%Woix1am+v*K@i`8A?N@<7Dbd6=K$b#tDOQn;{Q*oIf9 zY&&XD#5uf@+o?&*1*QQ9Bcn%YQUt0FsSVNju#8o!nk$%*4E*0IA%Suj@wAPs?AtP5 z*X;&xGC!4M&d(;5FlE)F6E@7W?vv9L^irBarkUXoLe}gnYc|+7DwD@j>E+E5vt5qm zuIf#hbmvSd;P+YMwI)+BXaI>!n6>$WYy=!0lwkiMhbDOnr`J?0NKwCsGK>DY? zWWzEHkrd)Z=(CBVJXnjTr1X}ly=qIuH!aouu>%FVj~02v{i0`fH7~(0dANF3b&{@g zf!R_$LoXU&&n~dp=biVS)*borg(gH9W~%$|*4StB=~%<=HIR&@T9cJnY_&ti zkjd}jYM9X}oc;Ma=S@J={H29ISp=M^Z#xa2YIoh@u$Ugf==X*5a>#l@XqM#*L>y_6 zE|8CvK8q}8ADn5q{7pNqJAq-DGHr-qKrWRisXXSY22Jz>E0b)p&d7Lwg^12|+DmPp z$=0gc50_tkQ}vi`SU{}W#eT=lA1^7?DJc8L!mM}a!>e=hTa{dgpz_EepE3G$^cpD?5VzcSUjZ$9vIYXzGX z$pa&-0U<)F69ZBmH(@SxKV?U8mO)$#W$?Ik^8}68>8^*T-(3NUJcnYKgGB^IJi8~n zdWx5&r?2C)@URyStby|i>N!_U=T7b$l?ic8#=X3J$Q{alfCr)@l3|FmAa+@jBA9%s z(hwWVl004dM3#(67wCalJIkNPT8sGQ ze%JsuUELI_hi6m;KKqW2yN3jOFGDNQv4#ZZ;d_a`+gmy0P&=F>`)qrsDH1ZVZZHP@ z()@{|%okm@4fO1(gI$fWET&6JUS9t4+0JA@)i_vXY&c#*n?Xuz-#(}GV-lCDsQc_i z7u!4!MSU*Ho1X3lmYe$D=h@|#UQ4%Cusw)2u?#Q4<+}xB=YuD%`%Njez4X_dwImN6 zC1;0hB_!+<50CJDJ5l!r*G>EnTOMkT`<%hF*}*p^Z85*ut%Ht5Rqjz*_jA~LOA(Pb zTiTODgF$n3Geqg-96XbdWU!;CWn3~$Kk=o;ie?Lkk?=)<3<@4Z#04IKj%^1iGVBjP z*cW|sBYeSDzKoVZM;RMHreTz)ReZh8ICE)wla&kZSjFd}_o?Vt&Sf%#G(Gk6#CppY**uw-8aa)>n_F8^nK zIdviyeaP|ynBN9&m|IN3(E#H7mgU$-sv}l1tgxY*i}&UuOx=`=#i=sE_Wt_x&9< z77IjHD{6$ebdPL^BE|j`3xsE@_`mLnZ~b!hwQX>9sHVYFT92f1?ga>)#wflNF5}SY z3QHxD-pH^^BGGv+&auM>sny{}5yx*g5&XYbhJb@%&iv*YZH2woSF8TXF|k7QcD&Fh z)*dnjC50u**3~aEsj~%q4#e66x_Xy|^n~w`RhIGc-^|#-LWni`SeZ?NvJhm=f|#4E zSTmk4FWUa4r<&(VvvGg-idQRqWtv3OZu&=E8@KrmSV-e_XPzxa+nnG(|N~^wEi=-ka27lomK#PR_WB)9oC@C?UGn(`b?0mu~CS{wZ3~0bmx9k-PH!-i(u9R99pR7vH`r|3|@SLT5 z%*s~?Q;U}zb`i@K=JPd^c))5zcY)5@W_`NrhRH9Ijioel1+uoYb0h3MeqxsmctOqo z*lYf$d@+5f@Lh1_@ojaTKF_gp5o<_w@uc*8vJdGS$PsscqACCQ()GihH>VkY9e(vh z`pRtF-&CA}{B-=H)y-^~Mp~+eitVT%GRQ3jd!1|all19_)ruq049S6|MK@H!kv!5~ zlapT%ba8}f=}7l)pT=X-**VG6m&r|TJMy`9$ZdZ+PczjMfy=93aY>^mPw4=UhrB4( zt(4_{k%#s9pTPU zC;fFboF|r_zoWVI{c)zM)&SDyr`6$B&WU_x`Mz%B9`98?9VyAz2B?cDFlbWUmeV-G z-HPv!)0K)z+a%Ah8jNX^-+Q=_zArc5h@;~5@U1MloxM&YpgBCCtqWKik7JzX`X{8T zzQaZsxdm+~J^*zc!AL)LeyA2pnDu~@z9@|BXnL}}5W`~Cimc7^X#{U87A z`kVR(#}l_eki`5t$%~a)Z-7(8C&;s za<tDrpGx4PFRY9tzW5KL*88!Q7fBsK(#SA@;0L%-Y<#v+;A2t(JgRJF z{b1GODDVh>f*5F4W&9}fs9bRT%CA|JIVepOp#tXFk-*IF@UIgRep-!F-9L+b5>kS5 zJxXsySuKvF-KjS17ca{kQ4rY0(kx9kiSk#YEeHY9zMle}syI#obP^;~CV(u^4&0cG zzYkxL#gq<7ABgcmvT+jR);J(%Hxp=oSK&W*)kdQGK`+p2Ip+b9WjBjEBTa1DZR2)K zksk8An+m;sXS2&{3d|PPqMX-WNNZ70oMFY$9waS07Bp!bGul2saOHGPb`V(riNplb zVt`^$1n4QsuG6l>O2YwB*-DT*Qo5Smj`05x&T$qjJPWKg{64OZlBV%IfTg;y*Q2ap zb@ zAm;+G+RiItc#qO=BCre)aS(t$0(cnv#DAvZSjY~&2tFB9KWqI|>#3zdSAvPz9y8Fd z%iQ&P_>;fP;+DH149kHc2ze6dT%Bsk2Ma>F!%mtNEceTd?2zm*Bob)c1~lIASs{=J zr<%C};1~Xn9H<5zN1!6+YQ9rby;*Kq`D>w5D_?tx0_rmE8wqJ^F9Y=c*7K9J>`iqk z?BwZe>7;YX{n7F0i$4>p<$$mlotF8N(V&0=Dmdb_bBSoI3RqY{Q3Vo21__``v_i@` zF%#lZJQ1;ggp-}b^LhL7M^KI8O9ouU8Is83KX@7FsM zIZMI!m*(Eo8G)USKGL)ei^asn0>o?!sam)f0r3>~?8JOV-Mpx%&0*gcWRu!({Kmhj zWiSLm%rXJYa^w^z98_R+sniJ?wEgU!ucZdL#7P^b1-s~0@7$ek1Yr>z`|ig5zv;|C z{YOMlFYyX=weWQ8R+g<|*LIo-JNf$H(ntdMG>{~~mVp$u1Lqv9U{PMmb6N$6vh$YW z==WAx5;$p@V+aD^Mkv&Hiyo^1fL03h$`1IF3+y4pd65ekVHCmNRL})vzL^%6to+~dz1nK)M*3=!e};D>H-#)`U^7U5DxD~oj5ybPiiG%uw!)DLi`NQoJmQZXp% z6{_#9d^%*;^l&Vmr$B(t35t2O`oWNkoJK)IYzRJD5X}{C*t6AJxAO8-r>}-QX zCd{tzdjU=)flNIQa}|yDyib2JqU=*wV_uui$Yb$|FPK8{p}TFcoi>e@0HhW21Opj5=GLABsQ#@O$$xmr zk$uyBi3xi#F)EJDnai?B6bmt}Fu%%c<(-La#%}fuChO!x$lpT*=~t=w9${GS7mABI zNL47rlvF9fuFEp^8LHwKgQ)^t+ytjG6>k;H$~D643k#%6L5 zMwlFF=avF(MFB^Tncxe^CJD5Bzb|IGhs!KQ8Wy6vMEhRZ@fZ7E*&F9B2+g}9U+h$? zm0tpOmh%qV_c})l)7iEW1?G`5kk}e@nQ3vkF6d=6pIV|AvE8+>p#aJV;-r4NLZg?ra5ZW^m{pcnwoa4pug)KF7lMPE%n+pFT}Twx7va# zg9p|B8O^AvaaP<&Eef0hT}XWT+v1#dpaKz|as=cFr!>M&57tWS9Ugw^8r(OpsvFL= zCn)x##;J+92p+oo{yjlFC=MvJT=q=rjmJ$Z0_5P;)j|MBXo%iL8=(?4lwJbMJXvSh zP2zZVFQ=VbnkBYPzghGuWOo;TiPj_1-m_Hbz6L7~0RRpK6I+_7*0sA-VIagPyu zea_+@kXRtYC4t4b%9qbU=1MlsBNS zNyS4^bsaMg(A25T*`%|}AcWVi+j_hDlJ@s2kExIh-``RFXdW&sm5|db_ix<>g?3fH zxs;J)Uf`BV)YL5h471aj7j{_-*1S>lXbCe;=c4(j>Ww0=)j)OrYbN$EFQIV(%FSon zv2i*)*zRo7HAHg+DnlL=5G-&wR=5_Bc{eRJuk7yl!lBjGR2oOsM`^w7l7apY)|MBk z=kvOQ;5xGn=<6<`Hkp?9YxP!(H|`H__!=~|md_HIs6<&%|GThbflJZTSt2_}w>tet zM@RuY51`2gJuE#kxW~DK#+Xuo3;{M2oM05Wk46DnY`&C6Xtrlky5KUu<=5~D?i;C* z+kscke1Uwh5eNgH{JrR8y8kzCG;a~ER?GXh#)XV&a%B(-p4@KTNSllfwYIkGvl+Oo zS7w{A(En3FbJuU1_gozMl>}U{2oARo$EAS$gbY8@^x?6z?K;c03AzqihCp>| z8in08!d$zr?^_C8%eFbCkYsg0wxUXdFfu`ZuQxE^9qfU`vKy2;;4yCv8!z*;N)#wS+78 zx(#Ys$rW(FSa1{@J^97IIR6zFBT9vg4O0SI2;7JMCJxQ{p7oE=N=FDEU}W|?R{B|W z*Gi1^bG8{`JkShh2tm$o)I|j!E7vJQSP-^|1Fl>8Fiut8MHp~*KXp!!q??Eu?Qcej zY&tidwE4Ht?FweroAFS+feSEPNdc|Gv20Hg?yQYPmdUL3?VY0lLLepv8Dt{Pdbkab zjqS+d=7)p)2^d4cNrdgJfqrL_Dq~#~M=$+^=mQ{Z&xsdhG?nurksTf8zf;trWr3mk zhYR&^h9DxR#JRZ#T~%$ITRC2N=|;)-QLF`~J#&A(l_ilV_z6N5%GW-PIs$>z2?TdG z?XkToeVNzdqgoG_TTgwubYbiD3A>GpYusv7)>TC=5$$pP&Tjs+oyrmU!yK;uX3RSZ zH24s<*-r+zXUBoF5{#t{%fb2#<@1JH1bf^nq;C4*?XD)NDoCpOM_uAmH%pBwwbv^J z)L@yz11qI}!srEeOVR|!-wJ6|7mNqrwhkPfw=L2n7Ioxwx7(L|&XULnRv4H^f_2ou zoRg2`Hxeaw!@8`J)2tZxlV|$56Gt|SZ<6wY|kaguT>wd5L!6v0v zL>*Pl?}TKMWh-bFpmbyTbEZI+(qp;Mz-~u1I4Ku5``t%_%Yz#gj@=<1YX*XEs__5uyJ`T=*Rj0S zfV+|q{tMYc_8;zqfxjNwiWh7YZ|(7k_Rv_sv@%8bZ0<&UakCpcB~?!6;rI+(T&K*D z%`)o*?REFG(Uo2@C-=P?Gm>!MY~EIYZnmt4tc8p|tLFpj262_0doh4lKplcKE(jYb zfGk)I^hyV)A1D>-mf<{HTwHt`(Dx>;nD)Y&-@+rQcov;^8@h^WiWnJIB-*odNn1OW z@Ys-$ifeV3GdruEHO*#oTP@~NpT)S}#tql?8GU^U=+a?SHY9P=KMzN%-K-Rxdlnfp}5?EozOs3iQ@t; zkpqw;w{LQ54!iYp^j|1z@ChxRsw&eRwr{!PVl=5fE-nJqu}_7QRSXPVL56O83B-?(p=X9m*j(Aqc;`t-&`^C1au6s~%cODZXrl7udU?aX zaCE@EPYAg|qNw*o(MF$E{KTv6Y?Eo)+#4P(eWagWRUqeF2XtxeRiWPpOmm)}(&1#e z|5H6Qv=|gpw}zdzIW#M5=R3O*wLSKX-{JqTbPBICp@^vzW<3rBD9}<%@8I%^L$}f3 z8AS7kzo+*uJQ zPjbxc6y&Z&-pqX@{+s0-iT+9z(T$2QJL|R|okA>J=B*j83LifRlzac=1Iu?!|K+jD z$kiuMK@9{86|>q7psEbsxqqKKZCCs5D>j%|F;X3b8Ak zE3z2L*Q2OFpGPvx){a+`1Wmk&lgjT5dyL+Red|z>WjC7#a>#V12Xib$Il1eU46LXk z6;WHM_`$yF@kP}!43B-kpvzB6g30aZ=ugA_^U`anT zWQ#v%(%;Iqqj2Cm$jy$(?4P?+?L5pPu-S5L73=`t3(#M24{F8+?1NdYW1i`{-U2VGc7|sq$OAR}}59ad=qN=hK?*~!spF(1^DJtB z0YAJeYH!c}^%UCf<2^L}X{t(q=>J^(w9MhxD=kTdWz3 zNg61-@bXbcSd|UNl2H*$e@}#t;r>s6VUl0{cY+j~cLx+abss)BUNuJ$4zK{l5iQ!( z%xb>gZVmnJF3T(RGM;=+3FblIfUxe-fGc8Xh3u5=fZ%#{fSpnj&DW#E#IoU`QHYb& zXB=?GFZPd51oK43K^CdaKzVHdVKOlQ*{-@20z613;kJI`r^(jTOZABvFouEp&pcfWEHbOKaIX_8gIiXrZt>RX6KDtCRm-E25XZA>yqK|kAA1{R{Tu|nw`_5Xo;QqOFDt@iq zl?gNB?Ko+!^9O%r#PEIAJ=YF>%9}PnX@2Mo#FabeE_A=s;g$N%qzBo`J(NFzP$+-t35uPT*{l<{Ki%8jAu%$RF#dSqXd^_E ztOamEe>WM5ud2XzLZy@BX4vav+b)E)bM%A;Xsi^bg(-pDh`J?T1xtzJlZBpN6@%rq{6#oq+48fg#f2J3LU6-HTtLYRGHX77 zRKlm}ZhJfA0wn{x)ZbKPFek(rwUWcuw!3>CbDo5_YdA+bB-H-(42QhVOh3E!gbjXM zLJg-;Bf}1jg8z=iiL~!>Y+aG)U{N^p5-81 zJ*#||15sZhIpUA`WKocBuwA4%Gp#ARlUOw^=h zU2o}Y+2^^yp`!dWeyhHp@8<^n8N-vE;Uoyuv&n2P2$&YCc)Cy}=)c4E{hN#}K*Nov2%>7t+VYgei_=!X)cD-Bc9+&MQJJ)in53Ct{&D zVXJM!RJKugCNM8AcQS|<(>*Px&@`! z4m2uDx8VM-@9agLvEnvfT+Yepl)PlIs6Jf=oqbQyH*Im3Chz3;>h7xEPTE}K#GJ&i zmgi_XikiF#ipkqdA_Av?g7OboZ+tAKbintMx~tWm%H2sE)Em8+%MbZun6z4zr!)bu# zotYx@9)1^xZ=$>Dd4%$zW`$1GQIVQ4G!lMD`z=DSb0T}+b%g&B&vTFYSVgTQ2i+#K z_0XBq;RO!u*I+L|g_|Nyh)l%{!QI z8NiAhnDpt^dCR2B7lv*>c^j(TdloloAnDj}Zx_{M%8_Szu`D9dT zB_f&zZ|+XfjYEIiiDX`<`2E3i4zK~reUdBC4s#y(aSsp-NHMy0vxRS9K5Wut&8sJM zn5EVI0YUk-hq5Yq#$4ngOV#2}w&MJYCarc zO$PT=(A?Y@9=5{q?ZLxO0JV*`Oi6W0roXz;PsO zU@cjzskzcA2!1;~JQqu?zmzYRzqI`+K{>VeQozLi&O6i^#o4zg>7l8|Yviok(c60c z90G5IblH2U`%ng6Ftb~8X-Gix#neW>&-~<9p4%jbn>425@=EQ| zuGQ<$X2U2&UI#z1P`Xp2p3O)NhaFHrh#mjHvk(2A_j~{iBT=b9Dw({TUC;O&^<86~ zCK~?L;GQ3%mM&qw3l3fAYG?O}T(U`r_LC)!9YG2xa zLw;#9ljj>sRA7ynyBCU+P#Qnll+-kh4M&}je|7h+Vz^N`I$*DDb8&4k#4>TH$#U%3 zIoAD=gNO}JmycYJD^$~h7U`6x*m)9 zc&PbX`a&a4JE;5g!qffND+u0zWJDPH0TRxEe#ZOu1cLf@zgqp3@^K+EI4@?Q)WU(o zj%8oKya4GvOfx8k;{*$c&J*&zKf|D5A5N|u9vmm^7(c{V(6D$hd)CVHnF(-kP-6hz z25B)=_lV8!_=rnZxgC_`Ahka6%Lqn-VxZyT{VkHUPj~mFi{KS`keJ9_(Ke^P*JL8f zrdR3ave@HD7Za(C92-x({4T>dIoIN9~CDQfkB1-bMh|&{_>UyO1RQ#nDy|7@4L>F_6@w#bWLUo z$#edQ4tu=bEhb??58OQ*lB&+Md!VXE8RLN{mr6JKKECX+RSS4o@V zFYf|xv)w77%VKTV=P{4cvxLqSeHA(4)8xUHZMLnlpwj8$L7R+22P1jB_R%Q&B$Eg9 zxDz-_hCw!5CmMPumBm3f-O?XKoCPvWc+zPc;YNC9YY14!1#Mml*Xmayw%%y4VL*#>K2!_?~rqE=wZ+39~$u8sg#WE9yu`KN*hlj;N_gFM$D`&WQo3E=V zhvVm^S$6d1Jr`^70Ek&imQhrcu%1i~r?E~R|YL^#$w#;pm8bsB~NL$DGiqSJVFSjF_N$u(99 z=1lfHGIOZ+j-1N%SSozs7{JVqLHYtY7I z<8g=*j}e)oEYnPCuz~Ew1kDAA7i71;HcGcEgaOhPgpIRzdp^3sVp^|lfmbCz=(H}c zMv3&{!Gg4H&tGK*1n|t>EPUVoZEywdPo!A(Pas6GgJ%<>!gIxNtOmzLteD#t3;j7h z@azb>vIU2NLF90V#kBS-q}4T64lA@8znPN<6YI8XRzd?))netIIgr*(`~V>E=lX@4 z8|aDzQI**xnP?WhhY@S=zz4x>QY^|K0a|*|M%nE|i}roDKWFTJmWHtlkF5@>f&J2& znxp;7QZ>g)`;1M4AD84QxrJ#VC%T`D2*#)pn-&fmgNrJGcWW1&_8dw3kjng<_JKFa z1EBTqIiWuvl{%wVj_NL;neRwmE17g73@0n4 z3*ai%Dm9IC+i7+zaRi)-TvL^2+!-m2YSe1fiHpfT9)E_Ra9A242v^$AeF1h@4+N6!FOwGtJ*r%hnz^>C0@>2OT*wxmR=Rox5n$nY0Sv zihp35{_=lmkBYkWnI2G~XSl|K9W08T%=@qhnv8Q)Ir@Dp1p^Z1#3h0O`Vt zhOEt&62HHEh2H-UCm+GSjJ5Bokd#*6W4&qt4M_&9W^!YWQNW)WD4b2$aODgFYG>hT zxdn8=el|O?Hp{cMj?I8;XXU{nEWbbYN?+aoSRSIG=aup|i$EBmAnEWKApm3Mo&hrM zO|xkrSfZ+n>6rf81k+(2bWy5u>xme=8<|ODgyMtxJ8>gE{~3CgeQtoaNXjS*GNsf% z8bsQ^!gQ(dyK;{8m4ZlT8RX#{xIp9a!6(wUeaX%4jBC-uFrEtdTjxX&J~<*tg!yj7 zsWkvXyolv!>65(59*B!}Ej9UF6S`C1@? z{*Q<-tZ&69J|S+M9&fN3<8U2xxQ~tWpH9${Z0b{lH!CP_uk+gZLBV7P%+FApMKu8^ zt&Sz$Kqd62k#B9F)r0YUWtcVn#jI%-ZzF41;lu(RMzXW;1d916DV6KfQPr=aVTH!g zRp7U>W7riVTh;GUvutMkHuct(hw`Gesdxe-H@d-j{RghjU}>u>FPkI|JV@K>6NKHm z(UeG(zGJ|;jqg0{ETm^}&cmCxY#d^4+V$jMeT@pE7h%%XXLRQ(XNr)FvSoy9Tte{UzU!2^a$PPIrlLgCmw$!G8Jo) z9S&{{7PROr7=TthBV*`5=+J8M;cm5f`TDzMQig+n-q-8^2s|!BAgFe?0wDYr znBUbW6Fv5@1?tbXK!evm^Uo4c9@}J}!I;0WBbkc$>Z|hroh(ovs;Td=j)JV7gfJhm z%#8pA+em!-)eq$E8C%VvpR-F9cuHrJ202B5!~ZVcuI+k(x~U|6`yxuOQ=Nc`=8gK0-zEX`>p#BZ!(eCFjyUmC-MzJ?T&Vc2uo`=g~ zG`)J9&xv%U{8Xv)WmrRR_pJfeuBa!SR3m+z7pQwwqEErFJ`!^oN-$`8yAD|w((~?A zXR|Qwix!~n`l)ZPT^Ou7EH=7IhV4xD%Yl3X(Ue`{zBV7RaPc9L@Wh+>GU2vwim;u zL_(&5?CP7G5AVo5cj~11%{hTyoKLMZ0^+{YCMax(*b>UQit8N9crzzP@Xd72!HS<0 zDQWh{RX`OPE2#sxh6kV;buK@r4^meS852or~EqctsnltfHa0_E+p>xeJUAMDjA#3MWBl_ z`SY+U#Zq0fknQ4n@(A}I-vX2wdtZJtthwxD)99SzEY#vo6Ufl3rSwiz$a&V8$ed<=YpHlLBICpK72a0Jh(F8m*`3K;OlJCVcv|Y zb*R)~@y1-wU1jmr`u7;sPr(e_gh8Ubl{<#JU5STku4bI|CE~${D|O`Lm86@&a}Y_p zph(E36BmB@4gvWEOd^4?1b*qYjgDK>d-E9b-bI5<5a=<(ZuY>-FWRWyTsu1ZRF?$Q zl6Y-0{EFlVZ5Nkq%Qx@xT9f)cPF{n57B)oR4QyBXBQ0!zem-J1qQ7RXzsML4_tPyD zcg|DHPV7vElD9fZkPare{E8XmOocF2E}v0j&`%2SvZYdsGmCz$iBfu7z~X+tni44i z>z@haBMa`Qidn;|i#QN@2+vzr3rBv>pwwxN6X8XvdH$Zf*b>NFNf&jZ>n5GkVZ#e{ z9rF7vR&JB$YW~VhfJH;y1EKOCneFYs>U-*tJYRr>hAX4ue(68?c-kk|{Z-s<`jTJN zbyfGO>9Z^vq4}Mdimxr0Y_HUfdaU0ZR$?Q|V4ry@NG?QTtAFrwmR=a_n>kwwShDif z#&b0jCZgTeI^Q3tNKi9By2MQVyy4!qmvsNZ_82edeC!wBWzpU`55~Z?wH97N4Ax$r zPa`qap1gPhO-0E_3e(umq3uUtUcwe~hS6tsVP4U;vFU)a{VLyFMxyA#Se56>3ieDk znSrPrR+o=|dTqV~B>{rCmnFp5k+SW=mhI@Jx)&$#yv%FQh$`zwYS&m`Dp=SK@>QbTFpAWCA_uzlY`T*~q!-%ww-VidJG->2enFs}zV#dpL%11_by zb`B1fdUx&(jUBR>CAgTbcrszjf5lon!9*?9!tPY%4cJW@(Nna7b{|g8?g+;B@IpzVmk?p;!1T zrC|m8a8vMtr6$M%sl77;knf zbMsSzNufhn5Bi@QgS^tX%3s|vw8UG#{pW*DSK7&Ihym?WF%JFQN@-+p} zn~675`)+o5P-#+99fFxPdk;5LM7mZU!kt!@X-2dHB@k4>UtjP zoFKgtIz?-#$y~ViJN^NPA?@(} zO^m06v$G>r1mn_+@6_n=%cvKh1;F%K;%o0GnsQs5H{zVg+S9K>7QGABv<`|22bIOQ zJi+E?vO3XF;B@;9*WV=R2A2D|9Z=NH;ylPyvI~rZto@G1)@U?o5D6QLXy}% z*4#G8*LC0Qsiw-YQMp8R<;3G;JJRFVw%a-Don zH@9!>!4L6I*qL&x6%#zCY>YXO)>cAO(9;l44+`T za&OU~&KE!QpISA2XSt8c0MFG_I+b?vV@q9;>&EOQMC=##ESxm_rcan;_+JJc=shvG zi7BFgE4Ea8SuV04$&dbYS}EIML`#rf*mr}n+-q-qx%Rce8v1@v?a0AZO)h(=tM;dX zNt_k^)Ca4Ya7I-M|C><>-!r;viWgbJx396Jk-cQavlg*#QzG&t^du*lq?W;6`16gT zKOpP;X^YqwoGW}cE-|a=?GN^O3BCr{r*n=$>|7!_T`Wbfa5ySl&F4#_zgl20)u~$z z%M&5W_>R?U%oSfW@=SC(B$eh4|hKC0L?Wuv#NH@-va`%T z7BS8!vB0m76E|x~cuy|p@dRS!XrdmxRU^Wa(QFVL-t5yGTe)X-mUEP_*V(6?vK|#K zzPdv>C$;wVa?O5bkzoLzpvrLe%L27bR;{9EIxD(F@-$sZ=T(Sg$uB=_pY2SZhPB#J zKfn0zNOPGq;$5-F@5xhi=(r=VKBP*ufWuW-Z}h)tynSeO^Cp^K3@$qhxc;8A1yOdn z{yzWh4BvM-hTDJpUavc8Fj4$>7<-lV2sJxRm#cLHwff1%*C$CRsU;&fS_RsN9YZj-3^{N~c{>z2koW_`nEn?D$Q(F?Kj`y%bHnl{VNDP|=GKaVuunp{JY1BDD zSw|?(NN`nD=p&m#pX{G2TU_6?R!D7=PpQ#xoh?Ny<&pMB4f6R4xdJ)YVt#U?lgtXt zS_bYvvVdyj;p?+?X(8|MQ{`UYFoBo5-*(+6LZgizcX@ks7l|H3(UqMExwKbgLssi< zqkN4e?i3A$q60_34|jkIvnhP6&Ir@KO5I1Vh~~Q_*Qb$a!XNa)+>k=bl#e^b zb0*RAkSy(rS%xyo3smxC$1HBs#I5G z9Y-qQR3_vSN7i<#SIFnWV^LnnmqZ@Bf98KFo&RG~`2Tq_>8T?^!D?Z**BIyTf59Jl M8RgsAH}$>#4>3@zPAcaG8>L-)`yv>;uA4ALMaA|PFZq;xkTAl=;{UEjg` zzTfBh{(IMY&sr=Nb>=$z+SlH{*u#5OWiSrb3oIlgB%C*|Wz><79zl?hkUKEZf$uCW zgvbD&kX_ZmQb?skfADVY>B$)j{vOTC!2n@!f{-Ij&Et=-9#TJod&B4`rR}(7d4MzU#tC z`bMLxG93Ef)$xc8@#^2pEQlEL;@^u)5}OU@pDQ}$b7)f7KbM^1h?Ii#KNl@MG&?u@ zpNrrbV&vz@KUc(K2-N1^`*)!JU*29W%w)3Ea6L9M7z6JUScst8C$DYi7LQy2f9I4J zSReP_oBram8cJuPXOIvOa)yVns)aungnea#zWuWqD?-Z+9ibX?m)d;- z64G?6T|#H#;7A@8zc+Af*yHowuiIGtslbtVeb8*2r;^1!_=z{ZpS?lx>U78Y?zY~2 zXZ32QEEx#exbF|sc66JO&w-7n6Z(~|8_I%bzs=W{qd55b&-P{*e)yaxVRJN&5Q3c= zkHVO`KE1Lr`@ZvmXXqm-k5!7h`1LN&SjqC@0`a%|78JacgV7RwevMZ&xEg^-4cGe( zgXcG6S$7uombD&}2CmUtj&rWVqTK#>zP*EkymO+{$;`(dyT47bMzPszTiiPLf1De6 z?^bjVoYmM*sSA1RrW7-+@8E)j=#1ZAW=4o&KAj{7aADlOOT%7M)GV{=e=Po(fps->3>&RM!D@xYYmB>8=Sc6yL*eLE6oScis%!DXF2Tr%-;GmF&}ce$k3SN&fUbi+1rx zVm3$$&COCcCEpDC;&TU;mBP!YAfyFPEe|G^Y+aSnWbCwPBzvSuxQoqE%Je}4b9ynKYvGGPwZ&$jME zMd20gB_*-=Sx;)Gmm%v_|7Ob8@5}QjjwWa%(cQZVJ?l4qes|Q8uR$`{_jea7F@xt4 znunj@*OSe6)i=ZUH!-aM#8@zIr?@%1Nf+}74#Ob604Og?LgIs?tk zCqu%6lbG^i;`egtyK@aXen(NpDPyt3UeR{w>jSB@3ztKlil(OT!TYol#m85OF=d`k zw0k*JWSQq>1kAH2ccPYkgjJ$9Gfzb^D;|zc;$RwoS{ZU%f{-tz_+_ukz_86bPs~)F zVUaPBVb4xNmW{fFWCPgy%Y)u{hBP?k{kjCw{W^a$*S)C6uI^Nobews4j#Q{x>cs=THwjZO=SL&i7YhUn>hd%agPc>bBEOLBQZ(eP2n zES~>`G!r{JA1ICT{-QfiLXuG(4;dMsR1wd}XRmsFN0Zb2wIS-u&%qm~!FXa&qnP0j z0@RezXX#$c?_skp-Jp8(M|g|HR73bwz7#S<%bkzP9i}1tKI#R9bK2GUfzw@@Pw$U4VF^0gICU(tb*d4DHXqEF`PB>R0nO*J}-`6t{6Er0pi6Y;@53cjl9J!5G zzNk6Y8O-Y3C4C>E?{hw@jfr5mqgd*>oHX(o9H^?=pF!A+DK5p3^?8QRs25(wUny=1Fwf zH{)I^3`{EWyBaSIwuNFVsi_Dq@MfV=TM8QbmK8Xx&f7tuGQki1*Buj9o^ngicIX+YRPpyh-V{K^9Q?Wgdx_-PxSR=U|&eO}?q=qRN`x`HD#5o|#O!?8B zF9kWtwjM5s=J7cmLDxp>rIZA+42EOE%f=Llw1xBVxBfp1$;N&*6VgwX2bLU>WhRX8 zj+3Qv6JE;o+R;$h} zTbOcIs$rHXSTfI#oH`zt=i$11$0raF!=!+vIomSQ7Q9dkI4mcp%qwNw`I#G)ia*p$ zfSJT7^>GyU_`BC2f^hG%x&QKeh5@^!O4TrYq0?U)gZ}aN78n{T3B0zydVHhxyX^8< z1IMRmF?(&KbU!-DWa58`;O@wA7oCK48);jMm_p5RL8y&dxWaUkDdFj;3La#amKM8hOT-!X1c2 ze!0x&W;m^bK1<}w^fYu!qb0LHlguk3~5w{X#|%=-_=zc{=&D3I<$tNodtX@6B#OOX8Af$yeK=LCj~^n7Gqz zKO_$I9G}qylGBw2eq0pO6V!}QMJ0A{nE75Ja@<3^Ze5X?=W{a1Kgh&&N4#Y5vecDL zChSzORwd%~9ejBB^vx@<8skI7Q2F@AG#7Z#|Y|!aG!2ZJ7me8(>iM;Fs1s>=z~jRdi)WqR=Er7U%(6Y)_1LT>%r&%*+S=9;*D3Ckb(*y5%Hq?mHatmVrd@f%r7V4)WT7rBOz!G0_LkE|CJ0*z{axTdRiC16ZaWE? zr@=k!pz?OFwFj0nh4U9>S7He`)49ek8qF+DD<&S7OQg3r&`658zheiE%5KR26S!Az zu~DM_j}TA^6owM-EIuLSrn_XWU|g&k7PBj@9cVJQ7yp+JWD^jBb4Sel1<%OMmn7}R z3|hWF-(~4queaA|yL0-NW4thR(ZpioQ?;b5EGn&+7rR`IU)AF}KY79Ln11QR=iWJ` z?!Z!M()!3%g;P7vs<~QG_;kUAEpR(wbtDX ze2+St?!(S1!m|nognm;Fm*B4X4xgO>6d~KdW6H8=*!rjB_3|>>IX9@$q^z6jfFMM{ zPoM*R!qI)UcCCYnf!(qXnPai6kQIb+%`3NL_}mfgy@qpyw3ZdfQDo(XL6jXjlk18) zJ-I!E(poVGFN4nkQfVy;bJ0`*Rc71X-`&QSJ(cR8ew~P;M+N{>M|`{PuW#Z9*d%_} zCgM2q>_LBhizNrz^m>f07R71Hsk!UYj8n6r-u?zv?IEp3q9Di()jHEVuafoDPbaaCCP4I_=n zb>X0P1=q4J3&n`sbJpc&qqnPN-S%gclm3@NaQ~YX%06z~+IG30)>-eqo7X+7iNJ7< z94y8Z^$Vv9PvlbGyuXOiEup~ie5h06*fz2JAbX|ONQz{Tw$uQGmrcSxHe zkoATJh|WIn1m88h2OQ4?zYS>7GcZW^%|#E4cTi53$p7GD(+xZjJ%%jfJM)RbGnT173&0&Gi01XBc_S^>+ z5vDUB_1bZ+p7(OwS@pZiO4n+Ut#cE=0WXxuy3;=SM?7Q{^)#QACZg6ooj6(EnZDd8Js83&CB1=55@bTN@ehvm>t>CRqfnar^ z!)d#+-UKF%xU!$vLQnR6w6wI26`fnKL-6tPF3`?JdC^*Mq{DF&@x*U9FAM1xhk*Ur zWR#n$?G%epPH#iY5cTmm)>>ccBr#4%<*}wW&ZTr}y3A8d7vQ>N7HD&hdPhS5_FMi1 zfGJzt&$ElfRj;{P^(^0}90;AZNOo;mY^%9vZtea$Np)L1j_ogI#`fV16?u2%cG9$@ z2|I{!1F{19d?~|o{!Pya|9r$${f@d-9R)3nG88bmZ(4ePMO50o_#l!Zh0MMN=dk7kg{T2prdiPQ?sj)MFe+f;vtPoo&r+-1ox;WsaL0!AWT1ko7_&^1q;`uww29_iwZ13wR)MUfrrX^C{A(lF-2nVSaTJR}|zY-5il4G$xk> zN(EFS-bxscg1E+B8A(M66^4UYRZE{jFp0(!xRpl%a+v6wn5z5ZZ8Z#w7Ss|NL?S69 zExd>}RxKGq{H2E@d2s}QiScE&LElfPK4^gW9rY}kmARm+jz zI--h*7?VDcWflEVwk`88ZV*=vXBiVp84&0^IKd+7J7F&l2A52x&vQmMxY!+F)mRIR zMw73UtD??ZH?a5crxjbMwe5si56h}cbQ!*!vtY)jbHN!vqT#_h021h0X{dxU8!cQD zPb{~M%}P(Ie^}xWim^pBJ^J%dhED*Z+vFkyL0xB*Vkyp9BYJ`iq6lj1AN>MP%aOf= zgM@+8+WJoGvDi~n9?_BIj?OJ;EB3y>ZVR?hcP%+vUU(xpTSr`4&RPdskzyxPNE+GX z_6x;+;Ma~WbDl`GIkQCMp!xq?g4$%SJ+xC_Nnwcl2DBh=ceh-qf7$~9Y#CQI5edh3 z-zZjFZaoaaZ3wji+eL3UO-5V0QzM=q9-H8*M8%Qu+5TeWIkOf56tP3JJ*ccF0$<5- zC0uY5H);GW!yQ=E(A&6Ao zQr-3Ej#ftS6@+RlK7D#p~{mlJxU~Dn#D~)i;I-=Dr=mkp5 zLv7fVvTK=jhuw{#!R{2QetL>%P^rKRD3F|0^fvk+>Op%e`0T7a?QgYM4+oyg6<>yr zSgJwx7uafM&DayLN}KPlUhkxZ1_Fqt=^;;*vA86hBT*W~ztFrMsR~x^?susS9#Y~> z%zw0Zf>mzh&Ztx8fvJ}`mWU%2<BVxB^eInW{`8Qis3{&tZ1c+EWc8b1akPu zs2k0%M$L;POkZ-DaG_@Me5EU+{*#aemzqa`NvOMatM!Z6@8yknD8$;0%?C}_16P0a zH1d^slR2cI734T$(Jol_L=Sr(3fvAA^(pO~+`gJb%fRq3Klp=b>t@2ud#V;@1~0F` z7Wueu@=tPugiv2HsFp%HV%17)6P<$I=3%qJ&TrOv(9kmQ8!?yVrjR+Fr#3t`5q4$+ zPLcr~ISWGzNbW)zfGd`X1p>dtaf(48RK7Nr1ej4%k%P zyjVdBj0$-Al?M@Q6Y}{@TCJPkvB>5j{xc(5x9!^KN+um80s>8~u_seh2&kt)V}Pfx z-#-WLBNfONpPkELJE`II41w(bUTACZWD6Y@zKfc6CSE%mi}K~t)0?AD({3wzhL~(- zH+t3??z*gIZw~?0k+a4GWmxn)o#`7=a6o!GxvP`p+0NR6qVNRY-|*TyBb?D1VYqEU z@DPh@MmVu#n;ohRMn+;9nQ5TOfDyz9gyB9*&eo@ufs%nf(Fg+8=}i1LuB9lA5zEll zsM*5=j!E_y=lwj-{ zEQ&gy^pA&*&@3E2sC*coiF^9D$BUBd-t&(|*at=TciJNbqYRxmU4_vred@T%5Pp!- zjYr@~9tcE^)-#}-!IPfhqfL(%inj3XFvk5GL|G~o8DN1s&zYj1=o2XZfFhR#2RFh zLYfBX%?9$}{}el62(OxsAf#5v55&fy^NY<2sBo13RuV)`E~w;_fI19VTB0BD^6d{E zK+|VX$$%$NW|Ce2FDnRP{=2Sfw13Ou!xLyLZ9dcX)3oTzNTuzg<=l zph%<;9y2f>CYym|8B<(&faffaP;GetNiC)1Jj%wz!8_~iUnT6bsp9@k=Kpqc%lZ+T zaVq!FBe&pLf#$IW=8z@gHeBnUb}eYm-ao96X3dfep$=&`b;XXCDtaf2L^i_O3!bI+ z4M&*&97Wl6JoA1SkM z6kl^%^xz8uv~2JIm;VUBll&n4A$?`>$tysSe*nbmcG!Pn(|0CH(nJ6krMK#z5CG@Q zY9NI`KRj{-f`F>gWp~C*LF#^UY|`ESo^Os_3TX18(R90dM>-0aMoX}1{)^<`Ad(z zVVC=47VvK@{3g!leN^D0XSy2YTo(d>5SB^~_jzw*Ftmr`CCAc&KkYx;oGe?&R>~!?5cN5GbVX@x-;VLw9G&CUe5kOXg)rhaY~z%9H801JF96PbC#^U4CYn97<%?hUdn7Z&J858^S>+{c(t>2O(DdVSK7!s$2~K>9 zL|z71Gg~GZ{&$yoUOS^X;eP;?me4=|N<3+UZCUWQ69F}e0^HA1K1I+mYWDTv;B+fN z)k<9vH#zJewq}Fl6==nJ{69b!sG5(3_81!#!gEeHBNF4r4zahm3nA&c0pfn-Yz&zX z6+3Gi$XhYGyWeU{+eKwbfF-5{RBr1`AHWS#97U~n+cJx!mU*g@>&oE-xNJP8KO}?E z^T@0+b{3kONmuaI1J14F38)U8>+vnW#PW z?H~kE{wL8Z5R&O|;*9TEyoc%dVfslq?uU!W1+&#EL%X7ee!p!$s6$(+%N9!Y2MV#X zWp7?uN6s>LJllU36pd7?|NY!xEMK)*y4q?;?PM1clcAT4T z^rUM%$-Dstod#l1a4ul5*Eq~fkcV)C-g90b_}|-MiAX4uJi;cB#U<%I{%1cPAn+}W zP6*;Bq$woQ3{TPr?LpCk*Myw!+aDQy{6O(ldhiukK`RdcqyiAhT1!Dl7eB2X^Lfug zW*YnCj~WRIQlpa^><5_L$)uejF{_4iGu!ebFus7Qv}mYc;;ACqc_`o4po6Fr=8uX_ z?>T^uLk_^(oSD((Caa0+xwH5Fos_AA^3dRN#njtCWqvs6^`8_W{XV_znD#tpYP5~C zQd$_|GvGsM;<2a@Mtx0j_BW?ic^L z2IVTj&(B%olL{9WfM{oo_Vc|_J|Q?h`}Ne@>$iNb4WFXXm028l@w9nTep|FB(30`F z0PZLt$Yw&-H@+OqFqy zX~fme^^i(tfiP!AI)2fS#D5Fho^V++;IyT6hU|=mAP)siV*bQ^R86@Ngd}&p8#su& zUF+_bP$Z zd%d~!jfzryzfp?4CZOc&HUji1>a2p`oqU|&mIkw!0+c!yxaw&$=4b-fQ-qv5|5~WvrjZop`4DL^u8pGF=DtZ=G z$VcW_|Etj+uhKYeFK0z+3N)tSJ2eg`ayhO> z?D?mkJbur6VMO1<--#H@v6gIMK^iq&n1OiuYAeO(V-pb(#gbQjo;3^nX8DtJ>qgk|CrjTX&20A;uiG7l6S|Gk z*yCW274EiCDRT4-Z_I~r9r9R!@dXTh6DcKN4h$qH*HAq|3Hi)C+>7I;{T>Z-P7&kczwUyjEO&B96Pbg?p*trO5z)Q%2Vm@c>5my&G77xC zD=m7}FFT)USRQ`)1lq~vSd|a<Jx^z`=a{djJCPhvGsEZM$z&E1%daVgQGqZB)dwgN~+4ZBZBBH zSL80-5zwsU99a-QI10u9R(PombR_Dg6*t7i&Fnn@oJB}UWr~-$FV^BH!9`zdU(ctO zzlI;gG3?Y#u8y#n6Ze!+q*=JFhr4z!8v+dPP*52h)%r#g%z|0dSF@LRKk3(aQ?5}x zVjE8gsWlY$g?|nd$CY0m3aQfcRVWp3A za#K$ADv4`kPrVJ4rHTfi!k3oaA_9_q_GV4r1Is)1K0K&J0#d?|>w%7mdS^t>>ER>f zC#^XE-;?kKyAaPJ9W0`qi?eP|k4n8Rff&+>@4Ye-GyV({U^J#(uoVZ)L)VL(JK}=} z()v)?o%^3c#NWDAUe<>yL901KCf)@X%4z`ZY1*37mj>~=Z5ZGh+D_AK&2MQ`-ojN5 zyWT+A44XA3?C06Uw*}PJ6FTCpcSxp3lmJ%?}MS` zf8gm0s~w5#AEjx%{mrhiS`@Zvz7=*LE+FZ+pS2hrKk~^qsRv~K@>f+pf4+;XLVHQ+GjynL9m@5iFY`kz(u-$!N@bR@{{MS+NHgDph_EMYR zvGP3g<<;$q#a8{cdpzsk80a<>^MOjby3QvLOSWJuMbEyP-gh2PT4N2+d0|(tK}7|v zs?+CP3)8QcS#55;O}ns48prj&wkL=3qW`b(TLSvPKV7wmoNd480sjN?0SIC!2tnNB zXE5}GdB(p441b@vfP3!G(>5RIQDJK&VLGp50KYmpYHNmBV%=Sm;DNHyhjYLYSM_%I zqf$d5Mwmx7n*Xvhf`Y70z0}7kur334$E#x5haRg$WxX^$T|c~MRV&;d{BIrv0{TE# z45hyefGW@CXaWEc0cQ_dCk$y%wvTg~7naH!C{j*WMw|U4>KbN0_1)0#vO|+pU-!pg zVyEyPbX>+k7*d0$%bXF;8n=F+7@H=hYlc-4EnKvsV{F_R5KjmMWQ8FW64)j9BZ2_# zx-Hvo8$C|T>D>JJpI}nx`gv?*2Re=l=vF;|LMv7?o?Nv0p;X#Jqhfllyw=j~_INo# zy>5aYk^UeDvXE(q;kB{#kJ_G{5!(DYQoroR4#zIpH;-Di+v|R_HY78zO$fHzT#o*E zF;~aU%&&5$17feF1l7s!-$0v0j`RWns9*s5ge&~Y(uM@GK9A_@Rpf?e#cOqgVV1Qn+@03O!Mj6h`Wn2XAv z4PH*vmK6r10U9js%Wv_UB(?rPD;fzRsj?cx`a?16+HCNp%CoScXglC$`AB5zZi{eA zweXID&GG$i{Qk;B4;sf%T;c6woet)IyKL896m~=cqZB)14L-y$oFmcanxw~nA)O=t zPl`v%h}jn0SUlDry5>L24G<-bf$djjiL0+DSZPnJBC`>3*3UMrFzfZ_vp6(1*b(+~4!o=`O!rCsz|Mu9!=r7Vh7&CucnYdId-F{V9 z=9cbZ5j^rGC!$C?w|z0w<$*v^X$N7lrRz5vm~Bt>>X~k@hcKL29DXIOY?9hT*Pkuq z7TbwC6<)KBS?#;2l(B~XtNosJ^5#Cl=T`g?Dy!p5m`M)e3jWITBI9eVcN*{oaL-JG|& z-lykOVj23Zrwa!S%lH$->PZN5gt=2+>x|lD}X5V)?98i(ukN&@(^u z8q)_6^KT$Hk55j_)379ZxX_3?M`;exZ;@#$pOg9oB882(xfUV0|IV0y3^+%D&LNs_ zE*}KsnkHdApDy^Ao*BH9tqp{J~&+`yoZ-mJ@8(J%4)~tQ@~OR!3B6%M_Kc&*O?zGWZ3^g{^^| zEBcTmHM-`lB#wJ;hcnYhT%e1b)+w%jToTA?c|izq`fGvOe+U8;ytC%BBk(d3vegD|%WNUG3K?7qpG-#B21JWhj~pH7ivm=64`zxvoxOh;J+FP__M4XhGa@j0e!8kvRYmefWi) zoUQ&KDHtnvUiidf{7W6YG`X`xw81mg|0FzfY(SPtqaS#z`ipVFIM>ts~^=5^K;wwmEh@vgHZ9AZKg>x7!BnueTdfmJ{|XReY4p8DNkYC)Nry z_jor7ZD)-kY~*UoJbo?dE^5^u5*@b`kA>@sz=yC-mVY&CU^NU0m}W41l0Cjj+fNN6 zfn4K=#o~+e3_d=}7w5nIn8Q1cuU-3&q)`MY_FRDbj{g8K^L^nm;Qrxw1vf86uD61a zUoJa0jGh3~medo5OzlAT3a2?9i1d>b4QdwbqAJdIEw9!Oo= zg6hp~3pNP_PBHgefTK?1?xw8s6pen!-rb4xYtnt(hE`uSj<^Yw`dBv^EY!TcjASeq zhFH#=^<`x-eRTT%ocbNT&%ITUb5#De@~)UxAB$&C+vUlJz$LMjhBw6Y*)W8_Z24RF z*a1kbqBbe{7NS~p8g&(}I z?x)GlfB5y?u9IuTY!N~z2TMPu&xH5?;eF3bES}Mz%+7_5mE7cr$+ps95_&PmbnUqe zJwjOjLky=!Bln@BQ$C_=<`|C{<^U}#gLZT@@)OHS*#CI5%J7Mv+_cp+hpsnER~ePI zm)r|*;xSPY(k~VZcfqBN{lE-|+tL)rz^iC*pVgCI^tf!(^^&sgLdAtTPBg^fB2`hr%3yiS|CCu4L_a1yk}8!$h*x{qy71 z@EE1oJW7rvtFBgxu*cbJOVAP{rt8A9zMEsvu|I%*%bpwPn_`xn=DwFzCOgw-ydSej zspI_^DiA_!=eJ~_#NVXvymF1b23rxXT^_7kr=Ptq8`tesNfo2Z^L{+S_?H|%XwiRl z-!u^0(qsI|sqt6n0fLEg!j zV<}beP7NS%M1IZ5U5+z^wo-CPR=krgc=gt@_{J%p2{r?cioUMxOMh#AFGXJB;*Az2 z1oJ=?p3$RTa76oja`kT;oz~T6753PRHIF`^$?qM}4JB5QY!b@ta4W?hUA$m8S-l~# z?rS#6bik5>|B_Xx{uk^6@)$RGACRWV0pGl{6Wgm>^khXy0NIGj%x-4X%(OR6{59Pz zyWX-mI0}5=f34XxN=iTR6Sl0GhgstPB4c||_B~UZD^B*9zqZs3A?aSxbe$o@zfNk% zM=-WQtI474=In^+c&T`^O=Nr&Qs2G((t&iiz zV8wqZaQq7~vT8#a$fRs+WUF&Ji)UjfGTfls_}QK4Ylu*-6`)&@mw5NOPk(tdd3Ha? zBM*Z_$ENlguqL@*^!>|NtxUIMmI@{}7 z-Fq+7ywrFUVm1Rhtr?cJViN0q;jtpw9oe#>B>wyYS!?`7XkubwnntlsBcD!_=e@3; zB_>VWp8u44Boo4U$a#u_vbxXr3l9-sBCcGky7VfhI0-AG4=MQi8N(;8)NSs%ye|7h z%~$oi7U0|=*bDbVg}1QFw3D@k;b?waEnx^zn5yXa6AL{9qdh1o<$|Kv{U>UBZTmxF zNV6aJyQrk&`Q2(L2}F@}xjZ#o2>|;nq7Ot20B=hI)Tquz%Sex+S_nHw+cL1Gm*R_e zy6Zmk&_N+8Cjx;&j=*&0M$ecYvm`J_fL-x|gad!^uq|e15!Fj_*$uxU?C`YzrGSMe z`}e&mCy$8YKe+fO%KKp%`fg!>;wb*dE%RA^dMzQpS7fpG0$Sxav+&i@Zwcm6Z68XJkU#?pBr|*eA;w>bn~R{ysG1j z`>@;2q~3Ffe(TUBa24_V<$^c#i~XFT=!mb`?u)wZHIWtL@s0XuJvM6*;ki{3hmCXO z@1$Ab!?mC78;V9AF}U?7lg*bYf3%kObds-pi+_`y>=OMohnE)EKLOVdK6iT<41N5< ziv!VOiqO`_28Xr(fn%;|3T}(n_8DTJUSJp!7Y)wYqW4%xeOb*xuG)y|xk{#p-j*CN z3=u&K3`2afk}js>BNik7&r4kF=nW)MBWLsCg01!dp1owKF+25gina>c4tvGnW+l#J z>Q{j2_`;p_cU|bS_IPX2ZifAWXZe7MyT>K8+APj*2;UP>WA}6aE{Nv!>1bMNL#=3l zH?gJivTC*cP1NdS%to4q4{@oVPv-0&KR0mjEen5g^6UL=5bO)JBHO?l0tn86J|oT( zwTN02r;qn;E6K-0ZZZc(3$vBvC6!7u7TXEE@FAZa4y@cY>-VAxy=oeDzX}*3KjiNY ze{=TMy$iWfxpv7jw_J*im4!*h#CA0oVtC@=7*f~Zy~bpib`;DI_@?-novUNrRBC5} z8s>W6esHR>61mz}Q)o_shd=OIjO#g}h@~x7$%Ogf_1({eYS;(rx4l#KO$WZNsZXyV zkS79p%1Xm11k4XsV+4Tf@LxL8&|qO2xJ>}DOGlfHqN3_j#xZ`AsV+;OJNKE zDI?DWR2YPCDN)N3sPXV`S^OCFOr{tR|23#RHq1KWqG9&=Z^DT;JKj0N_%&x~nxjN$ z7dr}oF{PDcC%(ycv)2BV`Z#-0MWL8tKd8w~r2OSh)#L1H8^hEmnN@PiK7L`B(`~O; z=BcD|9x>G0Zt&F=+%Lb7+Od$f2mmy$MDznT&YB47=HA)Oi#(3paB4F=irIrS!1t;) zopEI1YQke+clmLR{xXF4CJ^kXtJS3D_ooMSOTZ#D-E@`#_M27Ym2aZK33FDC5Pjvx zl4>lGhvdDm?-q}>W+$%qcYWWRyx^9`-0hY^l{F-s-aV|y%Gb$G<+(T6bq-}4#3w9} zin_yNy8bnenB?$=S z102ctBDIhLsJK_1K~^O(@pZ`bj;^Xp|L&88H#a~2rY^On^1J$$oAat?lRd^btq4=_ zsZ-Jq(0wMMc2P20oc_WKf@FY`XQ@USgH4UcyPR*WAXSq@*Xc$&VuzhR47nHMvuXyo)LDAsM3zWZ(WX+TxP zu*WDeX=GdYhe4BB1kJ<|7D~eiH;C1U40tO5@8r+Q$0ZJlWR`a#2YMmpfAI$(z)`Fme)TyZ39JmISL z^gn%fokMLR^rV0o@64D*Y9~fCuP^f*h7y2E47+-Ls&JcQ%#$4A#KkpSKZ!8*;kY!L z?-19mR(o3svz5CcU&_bpX!YSyq*KYJdG?EDvBkrsU83_8r1PF$55$!Sdng>e@Sl|* z9EI53L<7S@cL3jH>F4X=5LS7WrHi0lf-e1fxzD{nHr${nhRC8zf1_0GHI1*@?fHpr z!N;O9bs-$n%z;a|KAJ@c0o~O{%eA7=p``3L{q~U=F`>P$T%2JU!OD;=OQCPtORrZ= zKYM!f*OP*R?P3IBG275f?;uVhR2Bf^O9Ou1c`?A!fZ3+Qul2?vXx&{c=k%`bi@5Nl zcDGNcy)SgU!cZiYonCr|N_9mkIcX_En7aL>J z!YL!?`Gtb)Gii%hXaAw7_jF!-Hjeh`4Fj7Osr167CxoO;-=yRtZvjJF*Uu&*zTN}j z^}^lz7#Uk2ej8db32cW_ffJ|9knvlkc(w*xEGg8JGKwskBEEe-ot|JOb=tk zSl3K2OTMqrZLp`aNn2F-X{$pG&$03S{VrewEk1tEWp*2>Y*<@eIWADv8N+Z%=wDJlaxl)yAkt3rY7~)os+A9gqnQW6=2IT z>af>B_IYRA6z)S|dow4vYeChQu)3S3e!@%hvPUa^QNIovR3UfE)?r6(dYLzh*MACGUc6sGSGY_sJNuL?4Ix z1>s4*N6)ZV8$L#nrMkTySRGmcda4n>>-w0!wD?uXBhn(HlXi;ktQ{ZB#}DM=?m_uX-uv=e;uN&u2oF|g_?bk!bneH9TB|Va zw=lni=r~q%4z#!H^f1M!a7``Af|3))gufbw2KE9z=l9s%^#rdwF9XHrPy57BRc`O|SWZ=oCzWs@ zKI-K(DeAo`c;Ny}f*oav$N4}PgaXn|s>12}xVkP2Wam-Xl5%TDHoeN;c?RYb1+^1s zK}!s^7@K`8QW_JCPu}6<)(RgCD|WEtVfXS^O&ol2IDeADz(PFex;CM{;+N7pUxO1n zAD=qC;3T%Uu@0TPmtFQTa*VL^S`DLuPyB8hJTCEAu~_R038)c<5F0(OehqUJ^^IxQ zq(T7FW4G*@Fs>5l=Q^I1Rtj!{ae4mBkg zkcq@M*`3FD)?$eaHGdQu;V2L&DAdHI5BTo`^1!>wb7iB5;n>17h;P8;OL_UBxdAZg z^Lgg=DBiLg0_h8@J8D4?CAi-P#Fm)TNs|P2g%h`t8Oa2$0qR^QFtePQ)44szKTZ5z z2BD>?d161==3C&kWTZE>J6u`0m1W`HpkQ&^5YyX*=hJf+oeMMR)+RkVEBd+j3ER@W zJxgILp1(gy?V$H=aC}nF5K_9TPWW--WHKKccc#=TSaKsiE1f!{E8*AgF1gTQ68n!l zSy|Ngo1z+G8D&ObtnAa$Iw;gjQNL2o@26?;0E>!%NC9X3r4xvzY>i>;8wmm=X9hz@puD}GrQ+yKCF6Xzew?*tZ%_r8Ir>0Eb%+b{qpJD8=_t}(nu2LFbZ(KW<EqTOqxsQe1`6vX^4Bwa)L@}WP%9xZ|b?&MdqhFa+&d{e& zkzmxUMQSRG6_{^HWtmLs^)sicI0~kyM9gzl?!ue<*WYCI??)3ouK5*#;KnJ(WzRwTyN3Ld3AGIExwS z8g`-8{eM)QcOcbY{Qskrk`Y;P&16$XHX)Ij8P`e?vah|fi)^lJ60&n$dy{#ySN6R2 zR`&Rvt3KcF_xFF}db{s)UgPtq~9kM zSHKV{xclnOBD&a6^L1WWAU+jaxt-*XOJjeZ3^_!&TWE=zQq<-9=uO_>T$Ep!KPy8L zmZs~V-+?LW)_D=zf&D|A_H;IT;X`GjTe&l*dL@#4DQ*^gI>|4SXL8;jyW1@LpuL^)nJMD!pLAioII08lSy7$+ z_CJVqiRnl*ttfL|=dglm%XJ<78Z9zzeJ2X;$FXD`(y86>5QC%#CYddWcgqI|d$Q{E21pTqA7K_n}+!F8N$hUl5Ln*BuP3NsnZP ze|E&xJXc?^fb1@WQj#LPVt10eStCqrBv=*h(QsQNB(vouoU6j8JigrBUtImFY*v>)S}{~38_-$`|Fg!VKwCdl z^USsA0qp3^^XotZrJDI|>?4jm1^KSy%*67Jntu5eai>_0&neuf&;zJAuS)QuQXJ{g z8{-yUXVjpqO|*fMP0Wx=d4$xwh|btCgU;B%;q6xUqRmmo>r>8t6FV~{AE`5fLNhdd zkPw6Wy7;s8?K5h#zdJgdv}p58mlQS+^@RSUOY$^-SPD>xYexjjt0TGDKWpea!&M(! zeaUy5^@^V=3Qw9c`K;KHYa#bykBzDrh z-G!ZlXU_-71LdcC+B#ltQPa1H)zU?p4!z6onB0ABN>FU|qPTGbEH`44;BRgl@k2M4 zO>x;^C1Vt_YsEZftHh&vTK9nt>NW0=D$FR=L#U$isj|DUp#hbcio6z=dYyBGpQMDY zF0l2v2K`CIAUHnV<7XQ!p{WE@Hym)@ip9A5NeA?*DFuKw)AP?zmY)&ClCYU2X@zgl zU7tn}FCt-u6TB5yWi7^#=2;n;;Jwg(EdzYMy^?)5^E%ZCpS{4r!O7CiWGg3FeHfaB zId->(y;4@n0VrfdF#IIo&1;M|Hc7}{(e#BT*`HT0u(@pmG|*lIE{*qWD_(=M*XX9L zX8hR`I{LJugOps)#b_fGTNxFjOUCJ|CZ*4NqvMDf35kd~Fs1OMLJ=zym^_1!mJ?9_ z;udQq?I_*qj{YKJuSl~k5ENEho!L%=Z$VS53?Dkl$*)+lWOc92Sl5eh$LF1%X0@hn zV7xP0XO_TGyK_xvc-a|o42qz0C1!=VJgzA7+A(?6=;?S9nS*3@s$(&FcLg|Vsx(0D zd_rIC*NmXf@PZ0rdv~i7k>wrL)LI`m#Hkz?>REk1?4YXs97{#cE>#P0`tcd!_wH8v zs%&BG2HvhokDIg^zN@rB#r)f&x#Rlwgx31lVAHLLxyR&kvjz3BXy;TW)Rw3;e9|e{ z^{hW`OwR70HLyYCxz?m(prx_fP{p(OovG-;tnpAGncoxRqB@ZQ!`Tm8tj%nu37G-%d zmuvZH%jtpCd@ao8G(^$Dqw2^Ftij0ngX4D;yMbw;EHuVRc;kH%s`qu1f70!HS91qq$?R= z$|fMJIuKcR{Wu=9c0gv~Lg|ZwA$MO=dGHH*Tz9mleK1nPt1`vO68T0%2~PNc`_a?i zdT96SLd)bwN&_lc`-uV*wtgO<0{Pfudku4MOgN2OEe_sz^7WMkPpr`mAt+GUdt&^k zjX}KRd^b9|m*qw$;%Q%K)5%e+T*I2a3CX107GuDjoY4$|X(B``sdMqoO6X@ z>ffcSnU#q+Wdl~x*PL?awDqd>dUGd|-~EaMVt0A>1t;{9v&-MKQt0SxEvfBqYr(2co>nL*fGW5eI%4N zH?)s9oHpd$`>`L#K{BezIwCq|xF|8ATvjvweE49E&HW{JjNi$-#Wm_*#WMSa&{wyj zYV#IRK30h_f5-}0<3g)LCC7fKe9eEUt~2^O9MMT+%yf{<8Io$l-s8CWPW<*Oqxv23 zni239GCPT!s3exHl_Lw?Gcwk>lZ-UJ)n(&_j=Q`@5i(t579wUd;fQ`B@x0B4PyOlh z4-@}vQFtF5`ynh;>yErWzKOQ0U2V~#!Y_=lanxk?o|bTm_Sk@X?H*1#E38;RGST<~ zs0wQ<<1<~t=d%{!?R8zGtXsOCG4P_edZ%MGc>P7vjx%9r?$TCtDD59U`?cIPCh>Wn zN_Z#>8wwtGI>g^oPUKi?3TYPslG`Ls#qRxBZM*q${<=fG)qiB=v_8yaw zEXR)rymcgdzYJJa@Yy1^1SnZNX*OA^_pZlpm0R>_6gT7M&>jHWo@z``CP)&9f_N+RM}h8AO6mLCGsi3jp+^_CUe3d6xj! zr-EkQR70hWOva2J+t2AxG@+-aj(mC9j$x8`63cOdIEMA57^^>C7O}?Y_8|RhelCND zuLH2=_9YPJ{+3R?{1B2H}48nE&%r=oS<%em4dh@%o{)I ziWXkfI?ba8I`%?o<+_YlHk-*hYtP8rPwYuvqhAftjFuW#Xb-7HZQL`bEZ77ps9MM#dlU>NqJy2xAkehj{9YYO;uOS(59ya-CZhdXAAj+YYe7_ zXg9{s>+rtT4dHX43kv~y6?S#&#!sc=T>(Of}l%vQ5 zZHl>wW$5WjybeNrClKaDQ8TrTJvugX0vqDA`q2w5e6>RGcDicj|VB4PlWL9hJ-u zBf69iZ-j-Ae^7I|gErT2@u8x6`eXjZ5t?{2uJrB?zj=Z7Ay4v-DQjIqnRo-gwU5!5f!5hiV3@pDUx-%MApLalDp3CVZ- zJxkhpw(?_3*0zy+(bbRZ2cdCE1ia{QZq8Wi(0iTx>@efzUV-S+p_!9J_yQ#FG|!)G z4F-9D+@#@5?O}@=3fK&@xNDZ~c-NQicv#n_0~AH97=LTVcqBfsZ9a`(H@h=fnxT0D z%$;}!KQ_z?@>t00{#e_1vT_?b2IdzWT-7;Pl!m=>mJ;RU=5V;1p*+!)f9M&W!^2|Z zLyZ)I{+ZHcS(0d*OFThW6uQEiPd+O7Zv1*#sl5NPut>aYP|tey_fi(B((`SCwURKF zji%o%qNiq>mgDU89+rsH!^jC~0)nvNo#ZwJG})h%lO`Xw6&~AM4|H80kM+^pd3U*_ zsfrAFWfvZmT!O(G#vhW0%RiVD%&f*7pFFnOHemSL6&J8Lm&?|hWh3!W60EzK&)&u) zuKDUng{%z_c+ooL^L2Y?{*lXxn-GKsm@?l*@o#md z5co1;BuvW<7;*66Z=*5-uD+5j6NGyGctt54FkI!#a6!vm3jPV70azY0$1fUl~kG`469!#^QLUx7lxXQQkyO7coBE_X~Brb z(MS4)D-3H>D)4rjl%H|Q9e;AwBCRnZZ#!^1O?SOvd>NnDwZum=hw6ity^cLy+|hGw zHVI**E|?Yt4i|T)s)++3DT_~)ZRkXGg$0Q%jwt(SwwRspX?BaEb3<0|S#kC6{YzuVMi*NziSKMx>EmLy8r=1>BCGXWZCEL2*_Apr-y8aUQ+42 zM0Cr@smAK``S-ilA~gj_NF?cCANC)x^}JZ&ZCTdIOAb+4EQq$DfXugJ!;*3pB?F0! z)>6}4T;)F|oqxJut)a8EN49c|TMCiPeD(jqhb1eEnf#)VW%)8zS3AS)aHa zHcaEEyCxrOVszwm^wI7@dn;H*(%$-1EhQz*Kzpn{qf`QsQChP4-lP0Y;puEn&hD8k zOsUcLS3C)_g9^v;K^K0PANAzM-jWsfQW`YR>0g~?Wm|2I>M__dSk)8FEhzKlk55r8?n zLobkOP5tEG!*(RuNV2eY!T*)F-3F0G9XqZb99*s7_YT`}=kwn+bW`RnUu%5yPQ)yp zr-S;?3Aul0kNhQD+|l+fy=BTTTU8s46OI)VAfW z#QU_*EWXq!5op2{S;uO0r{WFX7S5fw8K|S@Mu=66X(p-_9(#`I!u2og?LUU*_CMX6 z%jx+kcprJ4Qfe*FlB4VT0IQV6?^XR>@8rc!>GH`3Fq1H3)dm;kcbB|;J+znMmw&4$ zcCkeH8;;0d;y~8i2ZrY@7~7Lf5=L6yA$<|6A8x>w+zOXJJBVw?($zJ0*Opy7dTxRC zU1AQQ{ed;>0 z{HxY>vU(3)2+SubI~V0q14b9F_9+u1-nr|Occ%If6Kb|=K_Tdt8e;pRrW--R64z#d zLZ3n^Bzwn+QrI#hD5KPL8tW*V-WH0l#_f28JBt%aFX3WV)#KNVx5N1V2uRv zvH>5KYYXePF3r~pXC$C;Iv$AIdzOj^M${H=VIQs8;{=s;6*rJ1qdlP={R;I=Y~k6R}0J20KGoOH#SW0%Tw8S)NuUd_Ot?6LSJ z>r|A$9?@^>4}Qf7j4i;pp*=K?ckSV`2!k-POPoPz2AUSLN*?M9woqT`l;m#DUki&C zqf$WosG9U|*CtHUPk`lqQpJ$P9Q0`5O*8tHX46rlxloR7-B0duYX_~CAb&D-$$FRj zFUek3?D3L1fKC_HMCgZvIL zS$TtJDtTwTSat_kWWsMgk9&s0Et@w%1fBMJRr5)wPLnN|WL!|ls5y-7=-ls(Nhd>4 zttcT)#Hla#k<&@vuEYj&yS4OZo%bkYv$z=^Ba$rBcCpJmbGMp#cj0pov#{{jH3MsA z_U@iY-9$0EXnB&I;|*V)y_5K2r#yP(GllaiKUkWXPkz-Ob1%po&6;_uEW-}ayC(+`JzTM%+<`7L(wUawi~n# zNNTG(gH#4&19z2jWOnPY-tEzwh7@xFO8)UY!B@9+N+&<#?E3?=P5pYs?^2<+#HUp1 z3h3suo(tAy1$S=KT#U}wRO|} z(YSX_8B1jIkXzF2)N-xIUcY zHaGZ*l9w97*)XPU6__8ziT>Etn*7~vN&M(2W8P$p!4Y!UIpq&bf*e8zp<;?=nazE| z9Yjz=EB|uZJI+U)5cCj-Y#T&pFoRA`1+0l1I4nCdGl5JzlvVPFso9hn~BKbKq zLa0&5Temg2yWK#!+vP+;uy&iX*GX6}+XDa}HUv7g6)fx!yfwwsQuaHt?=vFD`UsNB z4U{(%nAh<8W^Syj90;VUoCjbjn}TIu@{W#|sYe#D+3=DqRgzzk&1-JMiG*;5=uVi9 z`J$Fu`R49!W>Ceo?^Ru(ND&rm529t2pP0>>ak8kj(H0ix)I4?j^jwtG%o%Csephx4 zn1DJo13#e674WsHBPncRTQ;06&Sy%2dV3-|;#;77WOGC?@dbJe$GAj{2in7(qo8zMi>+ zgZ*ovBU)dC;0Z*aPf~~~b*zyOj|vY|#!?}7#3dyNW_BAw0OF+vP_d2a?(`@VDC@nh zZ!-DgO;1{cRgvF?-msk~+j4FqiAJLr2AqH;tw+!A)~^6E z<=ZIHPn^Hw>>XS8c=br?GknjOH2rSidHHK?2FuUyfqg1LqCw4{h~C^0=VCs$bG*@b zgn`Zrz}YxR)YBALf}{_5X-8VJ85B;`4`NHLnTCIg?XVvT6CTli?4IjDS@m?qtk0<$ z@7`0hvxVa4{k=q+Im-ei9J8XXxSZQ0?hWKRLz(U-@RJ>+t9-{vDna-uEq{NIOoT~Q^#0)Nq9k`m z6#Ior?l5y*kyUKs!eE=MJgR3%JrtR2E>{k`vaPrDp$nwduvy^}E z!=)79g20evmJXh)wtI#C8T>Y-$27K~_?a#JR)e=PGi1gAlMR;>1u5O$NxF4Jo5V~j zwKkZY-QgmQn?1J|>&~uH2HeT5fVQZjI$P=c;-u)uOzeffvpnaPaumd9E zZH5nWh^qz*OG`J1cO10XxQa8o5yuh|3vYeCMDbv5B4e+3Hzk$|Ki!odO5E0^UJ@$S ztMzgQ@oEgFVgi#td$8Hk`9I?@B;pH@9~rOsXFto=P&W0g7uBW9c8-DgfT`6rN?x>*~epc3}a<;a610-_p+<%mBQ^yZ$;}7 zX|%ujIA=z$AdPqKUsRWYzY(yTA{9?7T=dBBv$i%laHJBkC)zq|O$R(A+DN zI^VBx57YKLAftxqYhQ~FP;dsUfO>aWF7kxVaDU@=D(}5OUGQCcTP_&T`;ONobDi&L z+IYk7kHs>u)#zwrrAlG)2#b7O-TV5ocRLN;NI$#NKtVwv7M$VO$6oR?lXv}aU|`^9 zXj(IF0XNw_Db%5EmdD1!fZ^l}^nS; zw(```KbUs`@nN+mjTlO%W%bKMJhLs~MVly}Dp{sz6Jee9cY`o*hp7CqZ|5ft4XC~Z zDDqFQy1#P8dRJx8@K{16sL*>IgMTNha!I%vBYsoq)5TIvlvmhEQ&`i#0_ghsu;H^n zit5vqJBR|Qv=g`Ng!h>O24jA|Ar2#^ylE@l&)vU5ovjKqVa=TSUpzppm1C1gu{65BaQ^jmC z=qqxw1LIpnrj|cXB`p4=AKPr}Q`-qd@aMhk2urRu9-nIVrm~h|C(RaDr<=4~v*?@h zuBD#tCwQN|HvvTa0f|ZnKW=g?yQ-1XT$5Ya+jf}nHb{NL_0_d+ZO>R==cC568GU^b z=tf|EOrF8dSO|fFhAn=H=ZVFGsqE%Hm{fE)xk9&7>4q5)9Sq7=-!*eAKBt$2qgLVB7) zpDlT-1I^MoyS+&h)S?J96&1qo%XDZWcdXEA<}p$+1J`76(B} z!{f~oDh(-in?GdcyOCoB!V6|y4Si}`Tb~L3)9K8j@X zkYU682yan-WpLyg*oTzK+98uVPj7K%*(+}fqkF|&XEw|;Valn8G{rZ7!gsjT%?|dl za>tIXeN^g7(!nmZ&YNv6bqMD~uD%y_fjEg6gtOWL2Z&65JzMexHZ2_6N$^djbIeQA z&<-1p5CTv2#=nYBTVDhaPOwE9nQ@73dTB*7zn>NUp7NP0OiPxX%fR0bvi_bte+5Y8 zUz55#9#q14KH4TOt|^TFnQd)YScKfREgX0};F?);F^1_fUOhG`pBdi7X*vhzr#q%I z+!0QG-vh*Un=1j_T|B8=r(QufcctWaCBFL))624B10W-~O81!a*cu!@g-JY_sVb-zcsu&wXs_fWKO&g@ zpuM4TZDD1{V&M=pGaZle&_3LFT}nuGJ2|t=j=o!+oDyMLLG&o}Nw^}M)I$E#;haZ! z9)!~oQrK9!UP$^L1$>?g!v4b{(IcHEMcFUSX7f{aPJcdC)SdTM=}!A^f-_qK0Atq~ z4*;1`+j5`?+{9C&DwxX=bT`Uj@OPvupzi$e8K7xgRLR4JbB8{5r&SD;s!g33>`jw7 zX>G*WI47|X5*Tt;3&bTRr;uQDp(Fy604XSAhkVlPg|{%~oJ-DghT?4$?s&KjLuzyU zsZfqqj2v3_lZmn)h>IF9`}X^huq*S|amPG!Q>m5?Ey3t#MX8Yff zq#Q=(+W_=%nQeViKduADWDnc)_vichpWkr3fNFXjI`8Ri-s`Be_s{=@lr6Iyn@L!b z9S1K720mH9@d0#0T9v1JEvrfS1F4BzjB%~yfn;f(;318#>h+ptO`NUp2xYcum_K?| zj9jjlTZ|LpJ`CxtLi_n=Xc})90{!gux7K#SXOt?NLi&qjWF3Kjx}}I@*E+>XOioni z%p#3dto4TqHy#N5#Z~|dw_{vJW~%U~Kt=CWB7v6O| z?%VT8rGnJq(7{dly@+axumc+&1JWQKq1Ekb6nM0yndsEPO`H5xPlG3U+ijId@1)y9 zT{L-Ar0+4e-n6q1#v&(lfd1*Z`rToTMjce}v3EsOBI8vcb7m&L)Pv{<(p!{qyuF+P z*GCP^VT@dt=M3Ocep+yWv31uHtPo+?xqs5s6G4c;E)&hoSAqftSU)j$K*Ps0H6aTO zEAbtGWMfksT*94ZqyXS^#3napC^`_eyA~Fii)faeo@^uQ*uh8;d$HH!R$4{Iy00|k zgi)1Gbo$~JP`2oH1>DCISdR%`)M#IM#{4nkF7r&uyBCqc7Pr&?OjgT25AivV%COm} zm#cH{VF5!FUd1V^(1z-V6AT2q0@iv`X34)bd^ogq7!n19@Vd&RwK_|=Rp802)wjR; zTG(5|hS>yMU6e{D3d zKKXfw_2nnZZZB85lFb%os7ZJaW5u2XIMb=d5X_(4#*QRe5OcDce$bM<+L2q`6XT~j zluW78ayApG=bD}77MyT!Fh`_52#Db>^BQDN&3x*`dG*OO*CQnHhEX_=BFtXG$8V){uHeg^4aP}xLbiqh5i zS-_vV#xMP#2TCWCH#pEz@iDHx_666PkmBRG+yO|%^$m5;Hrsff>fWE%(_7MlLM!M0 zf?xu3q+#)=RT7etFN}ik%bA+pP=6|TL-M_D1gm-w+a16YVBgG<-lPO9lNp>NRY~DN zM_LKaye+Zu<-S~zK`ZzDjvir^$M#BUJ|z(=>OpDe?sz{-OA0+K3Xw-mBHWMIP8A`A z1rv;fg!=U3>if11&Az*ktlm`#_hie-3gDjr7)n93^Q!GETNc5PGGrX@EMFmIfr}$b zK4?XzQ1T=xi+~lCl_QOJo8=3xG53F$I>1`c9_EPG(>;uMNZr!+g?BIdSIRA6b^(DV zY%EKVr;u`4vuM7KHHOj5V|HxAr$>8l?1d?dn?vXrItW}InfKqHW;kys+(3N6DD@Xk zI(To^zzrD;&H0~|t&2}|rM+SF?z?Hr%+1|X{P)GXRp7;o!cXT%>D}?_%yl7|#Zt~r zyn=sK-He}#YpYw28J!20fvGhEv?eh@2CXc+O*aFpPR3Ni&2-0LRc7x^VpeF5Q!V&? z*u#)47ywn{_s&`s@_$3gFCtJuJOI-(<-sfvANl_cS-WzQSQ>z6CFMZehfLIMD&7P>x0K}1K_q%d-=9QKO`3CnNlj3r& z{?ylDOB4unMy{KXjqvCI&sp+qS_tqozQ^EJF?7>!R}YF21d z4=N4C{LjX@88}tp`pHDlgHLc;P$Ucl6W6<@JYJCWKQM)(rVT!GR+f-G@00&S_G+x} z){VapfHV2>VdKsV|C$B1iGl1|lc8i&ieL-x*E{3)`4$T0-8Li+)F*V$mzkEE|Hs@>2ZjP7>lhVmrI6Kmk_`_t`q$ zGIN7J7MAb(ri*6Z?6R7aTga*h{mO{R>P4`@(S}z zAxU|A7u0oW8vUx1ZQFf+J(g{L3-FSj_d9(*iK4HmCl6XCnp~~eY0cpn2+&HZxiZni za<$~)#4Y0NnHC>UO@zy&GLQgA|IAs+X3mcUu73sPk~@nIbA^+wrnVn+hD$Z3Yt<>2 zc=gSMTB`m51u>|aMqIYSBs^bY#z7VzO7>(rl52vG1c?FaA~M97R&q=dBJ2p-9lPCWu3 z^lG^1_Re|eNvqsQaSOu!P5c{7vW5zid{XBe8Pt#5Dq@24V}M8VElz;$^B(qHqJ&EX)Nr@dTFp*cU<3&@nIZq%Ap>4=(t4%SZ`>0nL1u25Sy1;M6<%|igL z&@Okr6+_U^0o5cfsF=@%zGlIC8On)QiU z@#)t+V^`Z>Y@?N~wT#>q*GJ|OoahKxOYqpl6_TXZ+zFRDE4d#$_CL3mOP5*oA8)u1 z77u^PlwK9QP4(X{uzJ`1LZ( zw4ogs#4AiysSB(U*}gWesiQ{#P=S^L(xO6}d_P-Uz_3-hJ+3R%n@NOu=ys=T0BO{K z$LAV>=J7{9(jRC5UVV4#|M2TEBv)gzyUhHz!3?rdBWa#&eNPiv^Q>goUaBl~pgRKG!SC++nxwtC-+znJSu>eC zfWneX)w`+aguGYB3xoznzQ3tU#wL!94Mv?@jVIh(PwSUDzEUZZ4v84<42vE)j(FsZ zZF%Zv6;04wPumcL{x7N*w5U=~0v(ZR0a^fVw?YI3+J}DrrvDaUEys^!6Eb8T{$4ZN zarhFKfd(%qc()tOgPf2}pkw|NR~_Bnz0+ZRW{ugG`0+4v^gN!eL4ESVR`} zn<>vkX?AXv;Li*es~0jwqt2x$f2>Z$Yn0zm`LS@s%dGs^m!b33gevfT+AhAy>k`}Z zX7q3XerE>x7o*E&v(O)ykO#^%e;F{Yu|s~4S!3%Y5Q2U?D$LMAg`Sah9?+z)Yy=fX z>C=Rfjle+FbNRij@*hUq{9r`RfK}`lpvoiy>z_#>=(Pvj+Q~pX@y-_%(=K<0`*H!3 z*XvZSP*kAuX_*yE90<##aSK;6tYZk_K1x{Ek0bh(=%m#_!l>05P;2_Rt)$Yzq%DwV zS`UN&#RVKZCLr)|N_}TN>(C{#_jRQ$#6)?;34o_KE%aV%0R+RAGI#V=DHStgoTVsI zg%Ny=#YFVdO;b3O%Kt;KxdRhWE_IU>z6$YZVX=HgU5 z*~H~X5WUuv@+nkY+d;cP$w1OEhFrXow&Yv&1C!w6a zJVSlh7?hATzrR+kGjY>ubmiJl&wErgOavWeTo1PT`)A`IFexBLl(ti@W&)!k46l7)05 z_JvPN*|ZOk6E3a%6>xdJzPFuoFl2*aYBHC^J25Tmm3q0dtx@ixg;+V|0i*t3M1}?8 z+%Y!gH1^u(a6_|ykPA?T^s_gwIU+UEn!^Xckaxmcf=*z~-}>m;*}~1M=rw`P!SLxA zraz#&zvVs0ig^}^Cou^ z47$lFkYa~FwzOcT`j%Y71MYCMKtfEPPAD`e!4=9WuEXGrug4~I@F~i>mJj6-%mdJ- zJSD$euX-{s$IcF11#>$(fKHXL^vzn8O(obqU&o@jzYOGuB*^)6`#o3=N3VF%l{Ii^ z#ags^YAUh5#Wd~l4R|RuqWgW%cN^E6U*b)dnndSU?6~B(6l?B&5&%{?!k}fniT_Fo zvTiHAnk(B}!D+Z8_P(b|Y(c^V`t*OMlDRLw|NZ!dE&Lm{Z1Wyf{$%cy2(10kEp9%N zxh*QBB5aeEU8q2)RZcnY(PDzVWMdi>y_$Uq*~B1p8($56Q}ux`f^JU{M3SD~3B+N% zNQ3h+vS+=md2;0q9z)R;NeFft2}|}ssb3$rkSzuP_ZrG!W}Re6r#usoTT+}ca>$P% zlfBDdG&tX}M|__x%6#`m2mBzmc$di^k6$=pPs9t_efd9e015mS@c4Q%@?RQ4oi>cP z6OUZ^5r7`#9{*RLp3LJGE2@j+Wj07@2^}*-k!R4Cdf}LO|-txm?WQ6M#5OEtlhNJL06{I?k$gxD&E?H_Y(bEb+jK zwa_~xM0MdZYXd{k;zCl0{#eoLHOjlr=>^b8Wch+<*`!8Vi+2Oh%_?_3fnm?k%s|ek zo+z&LKjYb12~r``gQPayv3a4*4oC)26k+`vzyYk61*nweA4L!lQOK3O#38MJf(vDo zt4}L|*)wtwHGqiZ%~87-m`#}8kkG?j<{RCZ6+LKb0UURIyD9I@{7QBaIBxRZg4SZAxIg>w z*bZr%m!G}1d1RTxw=81Vy<%U{3k%WF^V=5!8%&Tqq`%kg!FzNDCnW2r#~5#&!xTSo zD43N}bK+R|5`L%nmHU5a*#AO525kN(^njKnG%XaaI)1CT?Nu2Adc%*pTJe}$tMR$MAXHRoIS8N=V0lwXT5JFts~WZ65)!i;| zw5<_-5+J`?8UZ*$^~|#Aj!SZT&pRK28_wbU@tugB+dX3sIV-%Aflshti~eMqkR6UJzk1NdTd9SmSNefIp0%j z&6@?)xi3Eu-uj0<`kxU2K%PWM!)ovRR#*Q%>{R<)YswW&VM+6}5>?K?_2>i;^zUR* z&&^B_8T>#9dnCX2W0wFR$NmxYE?Ksi?2}ovu;o;xiq|9{WC`X~Nl)tw>cWRED%Uxc zID&Dx!81AmKbw;X^ooz;(6~KdQ~6*nt^eeO{&8!)7ESk#XvfENTEd6o5T;x5b@JPQ z;af_$VP;aEfiuO*63srv=Rb@BB^BS_HQrx_S5uecuj-5UM++p+D~FM@n`nDuoijr@ zP1iqlzL*jdj3dVS#*p@@9tCHI`SwTy6!-J$UJ&GR`J{oOh4i3vJHI0T7Ms^>Sto+T zH~)5z{LlZ1&^f8UJ4il!6e;!H^j3?Nj>P2Ne0mJtDT2mux7)C~rh1M#*-NXtw z952VhV)4iG-XvW{3ifpLec`Z{WhY1vKncBR{j`wx8xzVd3xJ~x6p!3~!yKA?53)1p zU-;ulJ~V5SezJQafb7XD+0UKV==SUyt|hp+@7NfE=?-ng1!sG~6KT>xtRJT;XdcZb z+Bf5Ez9F*4nT<-V(wi;_qq0fr1Wjt=63bO)?x$$|&!0&aY-VtR0tlqxDDUad?!WlT zsht0|ErPLj;^4ebdh!1?mLc{&Ly#MXJCCq`^Qt*u7ruC58gNHI9pJ@4kMcM6E0?bM zH_2wg|DKc+yzXsfBg^^STfFM`>dG5f6q0nukK9<@7sGyp+-<3MUreF;Yc-u0W3{#ry_eL7^Mq)diG*Cvb-P?!xtJ`ZU&c;b(&TCXs0 z(Jh=Vyc7mT5bGyqk?&??&33AlNL8J0YcrI4x*Yy4rs}~=BZ;9gnZj@BCZ*O2fK)Ji zDH~;&8qWoUUe7~%r94hNd+*=A>={9t4D16~aZ<1j2V|g!pF`>13kl)nfb5~(FB9Nv zHUFJam%5sLVP;@$~gfRcfy|xlLki!?j43wUgNQC!;WnHNF8^054s z{abvso6z7#e1;}f7(5qLzbke~wMujVOBnoC{HB@DKuWTgi-2CT@7j*U@iL?NR83{g=`JcO?FC@0$O7@NXBPk#JB?&z#8$s9InCcQepDSLCSnZi zeVuSS+ISPTh7ho$6jldaV2cPi5Df-nGXl)^!9xxou^HifYvP-MbH1x62@L?3Out`- zn%SKfAR1CkX#NxLLNlR+VhZWeTnP79ue0Nr#>oVo)~tVKugF5d01mB$4_2-EW8tqB5@kyb2@knP@~ z{`XqVclE9DMOPb77+r9aa$yodq`x#wl!Hi@HB9#X_V4`AFd3c&%}SQ&`cgsn70BW)uKKB^T%hplD#4GIKBj)z$!`TR3jD$dAx>%R826q=QdFJ?A zRrT&?JEUUNu(3%_fer7(9z;@jZ&6gPqs@#{L_dd8u>O$g7!*`Q3>aGESO8{^Vnj93aRdD*~B~3wb}Ua_J?ZL|%oTDDgOA zPp3|sKfx0WJT*Ie|K67{6KEFazGlny6W>@N?9>&FNRc2HGOYDomB3r@((zDv?!P31V-k;Y~soltrK$1_$k_!uct3 zr)qRtu4DT{W5xT*bbBNZuAoeWXlzUbCheN{AQI8wK(?TS)9Bdn9%~Uv=Tv}G-OKQZ zFpsh~a?UKrS0#(N**=^oMHR*{@#IP~ltToU0dSZctCUW1yor~wS9$`C zUA(C5ZgFl>{zABexv68Y$HRKHeexb9ju+6y_Y7vv zi}NHSrg`SZx#N~uCRdvv*IEA#IdcSCPD~KJQV~Cx8nBZ2uV#M#UP0Jxb_O#Eut^ZS!)#LuKK-YACPYhcUGSPYBpLv0!a|6mP3>Ji4h{0M}7W`2! ziV5zbB){);4BL(P~gIdOZL68yoA>4KfXD4YqI62C*b8FO{+%20S51!qlbt z*{HcI$zy!;DIm+_$@y8Q<%(!ah4cJ0Jk~jt^~S-;+K*YBwecf>2%qT(=1+Cw1r$il z1S!ycnC@b!L3)pV zFK8($A_RYeaaqCbt4%&RQg|R=F)jYodKMD_O`BeT4~l-ND@H>DJ8f7XMwb^O0oXL^ z%~7(nlo&9$_Hb;8Un=u*7=hO7i_8TBJxR03A_{Wu8GW4&DC<;>g4f~peVq!|dP}#O z6wBplF`Z_rZEQ)%S7{Tr5fGakp{t*_Xa9c|8{4B6uZVFzRIsc$G;(fo9{l3|pssl1 z7(`+1cGBBlw(vREQX(}| zbk3aeLHOk#gn-!Y`ZP$wn_w&YYV-Gcjn0t4v}U*p!?!VEF(wp5+6zW!^RyQc-sgL% zu=ArO6i6O4Jx?@tftAg92s3~vX8BKd*FZc)^b3V6(%YC7H_^0R!Ie52!`PU7PPq4e z3YUJ?Mugv)aA)vaZzcG#pA&NRIwokvzM{=b_5acJ-tkoS@&9;alT}&SDtks&_BfRy z8RZaCGAfxFNoH1^Y?bX)Mj3I+h$wr6LlLR$nN7(0y{>a~-}mS9{rvvA?;gpy&UL-7 z*L;p|#QC~0+&JiYLrm-U6ltDRQl%G_#`}D#3fiQ?0(7qrU&QkEtPYg%sea(-5|jH~ z#@RUEH*dwuTe9k;$hS?cw-0hG8NV_>J1tKz)iGAT2qS5wB3*mwr`Dq@muv1np^b5! zujQreim13fE!!0iOA0E0j6$o-1=s~w>onh(5^cZky9qavm31PXrt(v+l22PLkaK<*EK&<~& zAW>CW--)CA)b01Z`prJaM_W!NtP^g8i!%Cz_$#iwJ`Ws6Maem3G<)DHCN#@h#v6P5 zM_;mUq*&wM;#ZIL^}%GKs0P1CV~qqBMWPyWZTZc2BjYJYn<>fbir&oh7I_Q_HZkw` zv%1>@<^_miyEf9-l+p9!VXnAY_9LtJEQMGr0X9*u1;pZpMx_iLb^DHVjeV{~xpxXI zD`N_Vbb!)$<~esbGzTj&RIt!LFQAXQK3aciaXM?fjwv+6bavw+dO)2ZjtrS5rFpVlJlSe-KZM5pvr+D)X$+(w4^A)9* z;Uk|@nhE0e1gwoE-AdTm99MIldDGKewX=0=@~7I@uCs^Eafu+|JkF1)HuD%rPu`g#Ez4Pz>ixXv-aF>j z!lgV=7fijMG~A2gpkJAGW@VBnjps=XXF`NPUafBa>d98}I2m!|rYBdXg18^zU)|o`s5e^w zY%ke6u;8Yo@wr`CXV}3c8_;}~?RnsDZ}N+X%eof~y{QW!SmKoFEnnsIi>uA4njfWO z7rUOcsZT$<&vTzwK(V^u2&+cvNR~ufh&h-14~2N>X8_FoYkp>+glTkXe^+UVh8NSw zt+n^x-(K45)ISI{(3e#hX}kv+EO93Aa$>0qUk2P2JB99k#9tKkK>yK9S5xKsSW@WC z16-6vm#3nbye-rim6(<2P0lUQ23y0Ga;2wL93y3eOlS?>mR$NN0zfcOYDZF`$%edc zo!kD%(WFQ12}cZ$NAGJtKCE{#foyL@wHX!v5W5EqRQcQTB>MTf6?TDUar+Zx$mhG~ zc#qOK_h9ESkK0v7xHrgM82N^gspZYn?4^+BH8za*9(&pPvU-e621Hr6GdxNpvr!$he*+67{Kqk? z&4v-AFUA_XXlQ4-qy@wFpsJi z%a&K1sb}b%wr-5@fQg^2)J5A;t17=vEQ(9|8Y!kmGvg|q%+U!T?H8dy3Xy03#U6v^u80{Ua3L@1f<6@*F7+?N%N_#kZ=yvl$yJY;A zN^`xYO1qBf!+L>xEu**@wQDH{V-O?`@RPRd84}n02BHrk+cBAD{Aniitux~Bv{uxD zIA`4E3I78`pTk3(;ucll@vyj5%SrM;(5MoTIt8CbWkqyux-U)%-EJTfZR8^v6(h0l zYF!IM*iL@o(E%Ocha!%w#>q-x$LRQGmzqUyb$7*tUDp0wku2i!jU?IA){D8P*KN}@ zh3}M?#l2s8+-mh+De5F*{^=1^$|cV7r}Zi#VN8uo%fT<)R*3gz?9sEWa&J=aZF^7l zy?I&oNAhKDakacOZ& zaIB?}@>b$a$$nvz7-#p=oy#PWj6sm1c`Y;#zx(ohCXDpoF>Y8`7v3hym=%-oQz3+E znZv&nmR;EvqUS)!A`Mva%XV2wJM@Hwh1nCVj;bj%X(Nbv@x85St4@%ybm%R5o)r`= zaWxV!<*6+1c8%u`vyzzkB|?+lhF5kEh;wcBKK+`CN~6>BRUDXY_Lk-Pj*EE zWA&6n>;}1})Wk_@mxosd$Vu5YY;yavjn6gYxn;l}k=N8&1u;df+wU<+m3-*7ag%Vn zcvNaidE?l-?W?KZUW)>>oB-)1_!n>|wt@V+%MF83veIMMTG<*1_U6XP%`n-IocJB3 zZru7*uEjn0BWa?PP)X^}va+)GoZ_4+CO>RN`eED)Pa3_c5{ z_XF1Nx)w1iKID*#q1eaKSRJtUliMTJKiL+3>!WDG^oWj{!ah;fGUl z$`*osDbpjQS^Yb4W-`t-w1h6FFNNOHV#_ZBch3!XJDJd=i4>cr^4%LRE-e7g~!~VLf0-mRK?9#>v zL%U=Y_oLhKH@UWT3~W*v0Nx8+orL`*uZnJX;3|T34_qzBl7}MOUuW1;;-euFME&~y z{_Y)z@8xgGG=1ab(1Gw58?6Lw?V^<&Enxc^a23t8wWnDf4Ke6HYOZ?v)fGy%*RYd= zqlIh(7H=TG54uM3QB&CJTC~8{238Sr;5bOJw`d6)vgTfKVp5~c^g!qlDgg0*$MaW1 zFZw&09yR?N^3GTNVcV5TyO!V5bAs(J8UX16<~G!ahk{D6?p~0iyHU zGh=m6Z|5RTYu$|Z4EIC8zw09@J_iPd?yxaI_QOTz?KRE>vS2Cu#dIgd(Kx9d#hiU` zwSc+ej&3`EqHXI%POpc5Cf!NIJ@w}=S#zJ`m1b{os}4U4v0M5~9&x)eiL_XqvEb+lXs}T1bD9SLL-)W?b zNr4sH7Jtj8V(Q=~?CZTi;=^sa<{SqAdU7YGJ31NweY6lRlR3qkkq3Yjmh}%0*-4oG zSszbJ`ZhPObLn=kt&Fw0jY?W6LfI1K2joAK6xf)$E1^HBS&6Gv-trfFHx^oS+*PV;=(bL1)mb184))^=Ckxc{p~hlXG+9iCwC6xcMPCh@!K=O;SJ% zFa?+gNQnIeF-2T|s|20TtK!0+r3E8)Djjy|H_CSC6bm<;Uq?%z^yWM+ZupnvYUq@o zy8vcsP!bMA8EwY{7MxJKNYT*H#O&l!81aiF^3fyd9IdSp^1zBwYI8PXj*RpX;^6H! z@8lE=k^SB19mERG4TsFe7^A!+nu!_?uezGvD*yDony_4&via&*DZVL&>>t+o{AVku z_U%Arsx-5d69uu0!C6qpKC@lQg}xwhwgIeL2Y|JuQg2n088=i($yh@a1?kO1tvP5 zN0!m}!rNohDqm@4@>v7WT<{7T- zoE{v`fJ;UpoRF>8m>>l=ZFiV&$pR6Wki>v)^j}%3w zdW*Bl&N*OpAGQWbPQ%kW9%O%0U9jdlYT91!{!dU$+x~19?q0S+ag50lPNV~>g&OLu z4;ca<@ILR-ja_Hi0ANC=)lDUSlKuG=13|*51m1RZkyGgApAb#qUq8->82y$%qr=wo zf!+&h&x0P`lr#3^@H#m*;Q!bR`mF!Hd*yIe{B4{JwOKsYHb8%NFqG%Ge7xU40Ohkw z?{0U3^887)5ngDmEPo8z1O6k`luz*X6YJSqr8nKHMtW-k_KYJoq!6nK<$q;`){NL( zA*dsH3sh+Xsf({zFH=(eWuoUvh9Z4?X>`S(sh7_^rn?vG58Z0KUQl_B`*7X#)ip90 zqS-vV2nDTWp)AKoCG>?=$++7EkD{74wqJn40-{``eYlrIvhf}C7k^PnnvxgM%CrfA zKrM?+W|>4#(GWTH!JzN>%|6-nTql_DB>V_O-THvld@SyDeD+n0(H+US)Jx?p-IQ(P z6oPv6sB!?Y>POMbQ6)|&^iOr(R=V`h3mDj*`}|C2NVzLSAvFuo`e%OXbfVbeC75hf zql!g4j}kngVR{u9m!jkmL%shf8BP5pqW0xuV`wVy&)`^;vTd9Y;dOJr$ov3+eu{y4U!E|&j`7Y zUNjdBr}tk*af0t4(d7mvyNK&V;NsAmK$>;K2I-=q)MDF>iPadp>w$lzWB4B+GIq{F zPS7SnwIzB8LC;3O)N<%=&WG$q4TBH12OMTb*EiP|#wfZt!_xW!p)ae)^Ix=$AgJO& z)sbA9j_Hoyq8SZDQJ(BoxtF;2PV$@soG%RYeoB_Gju-cbmWH=|B6nL`lV^ljNVu$K8j}GkwInzSR3R z=}g4q0w09M7t@8;><7VyK-U)6A6w4U(bSLn2kMU@Ogu zeZ|oOZl^*id3?|1mxF5C46f^$Rw(`0{_qDjL)uVFnKtqey~&35qVU`bf&Qa{jjS}J z78ES`D{$2*q=W%|IDNB8q!_c;SB7>ZA#5I}`s4Td#+JTfeh>fpvpTu+y-NurW^&Hn z13HY+S1EV3Y7Dj?SxHFmF)WK_8EAtcB_{zgNGLeFaSmPliu#t-lUmCNINhbn`%mAa zCCo4dd>=ymHJZ^Ug$>@jbXd+XHjaqZ13FXY09om~+47ddcSTaYhN#_MtG^w)d^1l0 zsmm-;dIi|$q%-tGVrMQDoA_;Q+6doUyw)oN8j5Cej6ZhE_ezZE%-$dMqyBq2i?c;* zC`VcT&elFnk`XK2UDl5~(%pGzMq*efTb!0||N3h9GuH&ylqQT?l07#4x)bj^B6 zDz;y`bAqcMsL8kslBtx}KD-<4xkwlxoy54$z`gLJ@-DT!9WYkI}8liE2eJ-wPpZCtZ>A_lDFiWhB}{sC4U z{nf@G%0qhpLrIzfd8oqQI~INerc7HKFnp{VFkK1uC`TG2Qdd>z>CYEfsvJ|B-dg=B z&nl_2CY4vaKP-r1-|21)C4osp6(FR@Jow-%b)HnWDIsi5M z((#WtEHP(jhr}#425BZ2x><`VXVhZsl1b)Di8Z@>GvVYC+tda_!e*(Y2)f}j(}4OM zd=_(so#k?A$h%y!Zmj;O-e-i&##E1| z`FI3+n03!x)+KSn+O)fwhmzQ~>!K%pOD^(MBrDIqMf4{?Gd(lYaNEvx_BF zTW3`_eidJR=!KMv*O|P@F@?O=+E5KHF#87Xi5{@4JWR^g7C1$nZp@hngDuMn#p|(~ zQ`;oxy=ETSZhYNtDsDr*2#KT@se}Y7a!wGCPZ2~+;k+UM1ShIR4qh&e2OUlEYg|n* zMiKO>L6&jkDZOucEJYzH%ajaFet%aYEHYajigpvE_(% z5pZaZe;Tb9Cz4=%PP2n_3QcpK0#HvZo%iM2dgkr1FpXa@1K|B4bGjjN5CbuphFIOP zDl_)&5LQd6o$px&JTRN?Q-7;~wtOTSN=_0KeFu6Tvg^QIFi0bK52Y)ygUv`mxcO)VRxR3 zR#bH6{=ia3mOuqGuKiOUDV#gFCaUt=oTo4eW#=Zl^hRpNF0{-V+&S7_F7RO5nzBM2 z(QBBj4pKlndHVs{djJ`JJ0ZJndn=#-RYk(eitX`wxRGq|A!ui6Z zK5Z$4W7UdpZfQA|wNC>|&XLSW37JHX>V@omNd2zT?2d{A{@xRiIan^xYwAFQ6Sh}j+OX3@bh^Ozm7QYWAAB%o@;Zxm$c~;lZuBn%po!ez9CEZ`G)``19S2 z^R&BUy7@r;D)`9SY~;hTF{Z#a3OAY;%*ECbTB=`x5$(*09e=JAILJ8I?v6OG2eW*f zvQyi5lI%V9o^kii3|nm8fE_*r_9 zc2=&9U!cBFU25ITSN0&8qMDiyDO<{$Z#dp`%;}S6>6{B!DFv)vgdw9eord8zEM}wm zcNcpS6Pkw~I>lXT|MB$1^gc3*im*lHVAdPehib*^bl_DaW3cI>b`Ev$BvyQcIa=Lk zQ;(Tu@;P;4__Jf#?VpIdtx8S%`>>Bzdx99P`#4Jir>IgNTB3*Uo6Wj7rwRS;%8gMFpc zG+<*m_0NmKsFCYi>mHzC6_?Wlq8R$p3QNe8CmuUSsCGac;$^E0x!Anf5F>hnfio`U zPEEs@v6Ow-u~jn&>3fEn(G|;|jSN=g^5SSr1ZjS$Q9;G}rh!wq`z=<-ZWO$H$tH=Z zjprezyVb+Q)nb~YX!$8m%UkImwDIVHRVvBAu*1qg?V9)s7+C!Z7tt<+cZSHp&D~(M zGzW$iq7(2^93`4U7zG1xkqL%OR*zehWS#mi_PxD1t=zE34k@_KSNYv_%P50EI_Fy#Jtl_+^f9#j&WWh z8;LA1GY`}PIne(5{(!=37bP?U}wOZ)GBrW6m-3ZmdiTf=7uQO2Q&&^}^-W z$I_jJmunCh8-{bWZd&+hA+Nvmc{*erP>&zlI4}M(Jca*Y;NNc`=dC+rad#>B2T6fR5(@1>!IG1h~&G zE#XEM^0CUs7LnK0eWa{Mi{B&L=|5*N5Ooah)3L|w;uiT! z$OdbG2)_E`dW1NOux%gXM)VQxLc5?n(RBy-=~=t1v#;mxE!1<#GoCv|-;lPwENJxj zJ3wB>c9LWrY%sO!3-cu&-col1q@H(Oh)1b--3u0)eVE(d9?)Uyo-G2_Oc_J6+0DNw zXNKPy#hZn~$#ud18ZRq2L4Qll;8LGG!SUhB-ic`c1jsEm3l+a1j|U@8{WAKchIHW3dnz^fPb&+$JZC zXAbKx++E_z0UxM`$`(P_74J6a+g4Z|UHaG@X#x;f#+=f~Un4dvNu0~r$A?i$MM~^H zB&m|c&ELkgr6?!Sa1~0hew@LhcvRw&z*MxbtZ9&c?Q1m1qJ-&^+F2MdN!x~Hhml@? zc7QDGq8c2=wzig-RVa%bMf^8T&ld_Hpv*T(OW$s7v#c+u@H96cy%(htxfE-+Me^f$ z5UabYhPC28zdfPOto_zy2KvqbjW&B>!1d9tVDwz(o|2xq2SGHKOLdZm-fxf~M!xeA zX1I3YTVHY>Y#)iuq94>wmOg91#jU|h9otX6Xf&Z<*dgZQc+d5L+ZkHYU>eOc2YrhM zb81|M>%GT@g2}lkR*#+bFYE^!J>3hIyjCCQj6$7kmhF9~<`-9KMqeGjrDt~N-l0=j zq@iq<+D+esSf7z8cw7`2kX;*%8P$cYycE@6os-3veXJOKe|@-pLbWkk7bwKS)Ii+&Hu^K+WMSv`V|yti#}8H&5t5R zUe}j2zBRq4m%2bi*~1cWq63yDlkT`zZSBOIi%?GN3Ia|Yn8>2Po?vFtay5fokfQ-89(V)Iz;Z-d zoBtl&jS7}j4_6*B5J139oHXG-ZjKbPVi!xy{l0j|v^x5|{l)oB(z{!2fGaHx+2sa4 zn}o!54%Lz;aT9f5cX2or2P`jTv_{#%T8PqyT;hFM9KK4#D%e#|E{ukt_XTi^=>0~S zE=Q#KRWF)qA(*%ZYkZ~-#6f>AW5rWYkvkvh?-v0*Sn1Q=wzi+R=GmVNTfp)`GqQ3m zx$o<(569PCu!&baij8b{FaydvvF*fEHBgsrhz01*;_ppY>hVB9SCC_H4kAnsM2Kr1 zjGhI(g0=WjZG(#hRo7&5Xpr>FE^KEJsYkPD5@;b+e#%3eN6LOd>R4+n4vkU?T^XfnK2cdr*PNDpxQa*`W0*E_^%_d}|{=?v0YN_ffV1 zE}{T%puXhE(9?DUiFyi|P6F=#BjXRa9cXBx-IPc^FTKeNasx(mZJV{i3blh2M9g0E zWH3P>4yr;Mj{b*`%p4SuU8R~ux7dPm3iE-4s3nAe6d*q_+!rSHA|AM>SXkS}(M)Bh zio8)Tb5sfurZAy5fU3mxO!5n>f-CijVPkIc;g^F(0>;MdLLe1GmR2U!m zl>yj8iM}*wW9UENm4V_5&DsZey*4F2WkPYqMA>v|8KG<>4v!J%7U4(x&OEu~ZwDO< z=Z1Hu@~(ll0{U=?F1to~Kr}zs?E@KgjZ*fmVgY@RqWJu!b)LDhoCkbO+au5oi4f5C zCxC@#Og*w&KtpWKBULb^p#0onc`rW}BE`MXpH)NIxL*)P1#g^_&S%Y>VfcFn5!DR} zsa%Iecai{RoyHI-W*JE)QT8AB3M>x)gMNH+>D+=Dyo7_UL-lq4=+G@qAu&$ooF0W!`iUec|vS4@vCDG8*9hEQR_dz9P$o@kb zvakO~$^h<$0(?G!Ay14MKteLL%Yh}owWD5LWXlipqjos&3#ZLN2>Yl42uZ-yfWSsq z0MJXp&-_E}ux6v*^~uF^iEA5mj0ytk&5|n#Dc4v~kp~Br<=^YvUa63VUoasxK#s_9 z>9C<%BojMF?Q^__O+mD%+y%!-4T4AgUhoHJf{+Z560hIZ1l@sG%LhHJ=H5R|;X64NHPt5;;t*Xat2X!3dQomGaac3}q+m z7X}{f3N|3Odh$^zcTc`3NI-oo!0K!Oiwy=+JPuH{zFo>pzZ%N9`t|S=mj*RkyGCs< z_0SJQC0uL6zTLHJ$z0gmE=2;;z#K*;IIJzgZ3jH*UxGiO*L{at+xid!W$@MRy1#>s5HRoNJsD=3Jf1c&p( zt6L+z&gnG+ge^h=%*CrGAHV`UfcXm|4>`ok|KU+bpcbdoJR0O3UCt^GK=Y+hM*#a= zxNkuCAgJRv3#p&x^4wLb-njMct@yc);vkHOeM8O9QpIyQ>3~w`2I`uKbkjcq067&x z7vE|5;k}E_JbFyU&{;O!o=-Va(yq{dqINuM3g`fxwA%Tfb_aVo@uh6n0l1+Zks#_1Rc++ZBXCEs0KucDb zW0d7XK{ds=Cj}yETzg~Uq&Q)^DV{LZ-739*&?|Cs4gxA*&G&t%E}1)8S}hk5X0 z9qZUtfPD}zn9u*D^|Rqe(2xdRi)!nje^C&azf>2Ol6Hat0cN@`XAiTC2nk;NrtvRb zUqo`2tK78h#y2=nX-OycbI)Vi+mQiRKsr4LK_7u#!P^lZ>(;p{g z3N=E8m^#V)tIf!=wdeB-;%g|k<}NZ^43Pc6{gy_#F!X}!gE!;j!E@mO?*7%)f!Vp~ zL#zt4mI5c0CtmgUQvn;2n__-Sfq+y3CfV?Z&&6KT_Q9H@A;BQn{Ea~aY0st)6_ zBx5>tyE?MJzhC_??!D~D>c^C(SV84(M5GWAywVq()v@3eR*9(LzHd$!12C?!7W~J& zMW6CEf(im6P=Wm1Uh`DzM}!0lJDDeQ_R=b2qxOakz^eBbkQ2^LW&E+K zQtdh#$Z7;$`(zMEbpYJ^-+GGR)By|d!wTr))1Hkz=!dcL1)DE_@$~eZU?qoG*BA{X z>lye6fK~&7dJ>R%eCb@`fTO0ybSFQg9Fg~|5YhQ$5Wf}w;XUm^L^2LR2M~S);8Opg z*kj00*Q;Y@T+ej%TwS?~Hw`W!{E#C2R^)dh^k~AC1{H|)nA{K@?S9G8oFJGlZ-pZ4 z4Uq}f?p0&sx&Ly<5jHxt-Cz|@K|CgL`&iZ z3nf)zb)U9{HjZZr%7-$&vt+j{peqR6{m-srfQ}TPxJM^~$>$7ETIp1@fz}mr2)l<&XO0Co^`REsL*1d1l0 zX7c*JPD`CWK~p2XO@W^VsI5GKVl&7AE|YzO#`WvS=w0*Rbmw0cj7WdoHuA2+F8(|` z0_ti4I)YLmb%5)YDz_1-MrgcQ#0+SnaepJ?-8B?cRZ5$c-$b8(`nuw3UYYc)X!=c4 z%mh-e_$eJ1td3k?8W&X-6C9BGGs>L*(EL&#=K8|b%R!)iPD9@ z>0bSLJ))H;;K3Y=C}gG&5#KN8e}!E)oli9*>}_?ajAIe}II4?&+D0N&!5~(|Sj{4i z9_f7z+V6ZI*AX%HUgn`STxj0M(H5wjKP{#`(tAF9WIXK5DFgl!*0l_TfzJSWSCPh# zpgXgPdhXdeI#8F(k$AE_`-{*<>MJrEi@nFx?YNHgsv?Ez;lT|^Mh(*?)BmXeze~5k zAkR{aUz%7%!`f_QD5`>;5=Otmx=d&d3o6=DCOyEA0`D{cQby}^WE`86)=eVipJ#usYbu^30aCeP zFi@4JD3Fvc%B4uSh@o4XRN@Lia(If&$Y2pb1(u7;BSh#b(W%T-0sZnqbEHwkXns;s zbNL;8gVeJOQ=Q1B0V=T!E^#nO-wzTJ#4-%2`ALp~P%_U?{4aakX`|3Xr+XS5+S{Y@ zcT^01-|au*eOzTX8N=2X-UH{x8Rg6w)JsI1*!|vA2Vv#(ZyLs965zd~M@lAfp1}Ny zSyp&)@v8DAG|<&-o^-<<&%Y#mZ~B-Xcj=~PbkkO>T~`oPG-9djBPyliu*g-q3$kgP z;>ZM+s8GNNHECvXH|Sj`p~Joq6BQ(a=4Dvi!X{x^35}O_Fe^*$bBTITIi{WSR7Ht! z%~Vs!x(EIm5xs!6mRuo&xXdMlT4sSdAx+UR+RFjzP%YW7T{V5p>DIDz{>Rt}YRS;g z*0uD6^ILk)W5!;3CLiJ_aOF+UK_SjKL#RCK34#cqpagYu;C`4r(i0WKeQejD!qOGX zjjEEL5~*8FesUsKwc|3G2SAuaYkH8-dEx$rzY!c+jU;`m2dfWuT@PG;GWkKO`yv5X zC`leLJwq^b@li$UWk9eZFdj{pG(?{-jgFuG5}Fcg*GZ}SOG77yt6%N->y<7=w7M@M zDf1lRn0QU$|09mTcXG(bi=uFr6NrvfAg{;EV7fNQtRLUQOH5>0%x6u_;1oI~6`}x# z$bo4DJh&A9R}_<`6R&!Q!~9O6`YZB%QX1R$Vef8>EMfy?SHEz}YQWncsd`cL=FZ*x z#yAG#l4fm{(~ zkDLcfFx^kKx%5xnw1DN7bBvqZQ%AB}H#JeoPxPxfv2-cHkYaEGX_L=|e&0gsCZrR! zU{Ho?YbIMssH8$cpTf!|(D)N~{D~x0-g5&Xu~Z9ty`-J`OVu$fT^@dAwX$K~sJQ-j z%@obrfOE8{Hj7yN26u@})6z0kk|bPf-#j>86_w7Lr~;)juj#po>(I@G!yoq&gcA^4 z_h$_y;}@=kZOWH7N^1YvKai(YQXDn(5BpYRtG8(49E@n#ZaP!bdyhu#vQ!ai=g8}@ z(*|MZy|@1@lz6?5fp*bFZ_EEO1=D;sC(S*X*Jx zG%qe%n^+J6A2K%r`zH{8F!n{4nm;{WarU_CZ4>xdrh1P;>~Zj$(b&ZU{~u)%h8v}K z#I*PezIW$rfsp8$eiq;t7f~Vu1sf`;bR%JIozuAeVIa zbYZ#&zn0CV<0e(ky|CP(?XCE@(ew%Ah9F)i?-pD{M-cdeH{5V9;$~uppH?1inN>vH z{)G`N4Bf>uB78Nd;Clb|^n~9~^a-)}*4OVP0VR+t^RGx5v)j~c3X(0($D z{^de%MCIbgH{;FqiF2_t%EOcMH3YTbtE%WRJYoxi(L8} zK-y_-?$f?`%pF}yX0XY!<7>QAEdW;4Ta^mIZiD|YrN26gw9%*i)QxNBxo^I?kN!nk z)j|y)VW`8?gR3FNB>N=CLq)s7uQi|f1PX*qD-TVaoKP^;BCSw5s6vxC^Rg^?glIW7(Z35s6Kr2b5CSfT zLW~;@63D-dEC&VXD*q*3IZ~c*@!H;d*VcQQ_EXRG?gI_=w11tQ)N8w+V?%_H;uCx$ zX=?s|7*~jz8&rVP_V=cw^kD}4R2+DtA?WkSKQPw)XDrf=vf7m_N8Y z0}a}W0S=G?hf0cQ<)MZtWqGRge^aI2el8T)A7c6*@A=+&MUj91PkF1Z*)yKdC({s4 z1Ai}Jn?UF^2t)^MZ9t0zJp;4|+&1m>o;|ftx@wK00mq|A)CBuWeH!$<%OMD$c1CIF zDE>9f1b!Ch9%UIrdk=Q2qXt%s7Zj!V_;AicU~i#GY6<)Wovd-Pf2MJWNFK3d+Vj7~I$lMF97qqv*NTBP$bgLd4031^wg(atW$tDN%f`WE@2NAlq2c~z#{>{u* zcqKUp#DT0ED{a_$OwR)O2mM@J8s~X1#wabvh(^UhBLL0y6F>SYc8g<<{YfjlP!u0V_TmFf$Caz49!`}x4tWL&Fy^zvT9 z7xuA@60`T#Sd4#6+J6>sobY|Mf%ZV|bYqvA3T)aX>(UzCT7<%58=s>P51W~@X-pX| zBn_?YyiL@ET^;p#*pLL${f+#@d$F;a1{GCeY()*!_T5bMukQI>6p7jY;Co{l{0<(e zv~~l3>b*bG5OHwQXcpsaLn}EO;{akQsz2I);h>t#S$pxHuIEy3d_hN`lM_zFPWTRu z=^U8nqC9vQXw0En{}pG86rz8_TAF6)#R_=wp*SA;vM&qe3Aqn?AP5X-C(m?gPE%3P zY$cdGMIX9VVaOrxLy-dq4tOc;k^mIZ3YsGpUo})O9Hq{aK0-MPC zz4#?M67;X+96GiCtW4W&D_Gv!@+cd|D7P-PtL;?auJ^QUz6SZLZwD@kbTDnMR_(|s zn@scCh3<)5E7Vo>@R$#(rx8p%3H$qj?fECvS3$LiQq7w59W3Ch>#z0cnN}#_Qsb#_Xuh6IO(csc8-xr)=w^Egi5&b7;<`7S) zJ%7&MSq3O1!-?~-Mkg@EhM)eHiDdmP(d$*s-rR>`WvVA$fD%M=RvX)q6tAIhS3KD40xspo z_73R1M1KgPOd@%jj!vXhv+R5H^?ZER@W7VI_!c+rAyXz1)9`s%H5>NqFlZ_>QdZzu zdH-x$NZ3qNg>s}h@xqq=>CpG0FPrz1-oM>YM;qyxD^rDfe1|QVmAJx>Q$*yNR^5lu zmw24ggaOIGgM8D2Be(36E^Jhk4*%v-j<;2kv`_kG_xnziI^tH_xyf1L7f5{hx7SLUm?_b>;Lj5f9FYn-@AG&h%rFVL ztx5=2+n(oj4@kO3`J}dM?hGBwnp*VVe`Y2_RTV?x*|ZFQ33`K<@Fn<`{YV`_Bera>@cAnwXmK zU?ZnSND)161L^_Stbfy9|2#uU#ZAHIWIZqnb*Q<1a`Q5$_)zM>L&NIj1TW4yqfjai zN#5B(gi(g@GYPM8yfzLDB5aSNde~XP1maoj;G+ZcL0Gq7S@-)RR)fZS0$WBC zt(-86bMH5tj)ik}@O=m5?AXt~=t-czxT;6hzUe$hN{b&B^jG}A!9@`;YVRFj{cB}J z2mz~#D178I(e#G6bkLlkF-usc8bK2H%)+#6G z$+Ovq*o0WNMg^w4^z3XZp|xtZgP(abuU7k?X2fTwKX{rRCK-3~9Me!3Kd+=>^9G;x zVMe(K2IDh1{)Tj!WBJo|DYL^b+NZues@zEaap#_z$))7kFTZ9hS8o-pT>7~({U(Cf zoiP`*sL1&RBRiUz^=cVCG&uW}A3F6bzW=%y&xf;kZOk%pvApxJqt3*$u_FdI3>g;7 zvcjKt;1>rYkL7>Za`_~5+06Ldf+ZvR)QYj)`Q^Q;K2wDnd=r!m+=y+?6+8d!F9m+K z`v<81AgJgF(f){N0TfzeOmoTJqwNIx>zo6p`1_X9GK@%g(vnc{q5|sWuO<6W8&k*Y zQ(PZNA4;Xd;4-~&vX2rXGsp2ZI)NaSZ)Oweb9%|%gmNr+44<3&;>`W53(9_*UT#fC z5+9p8mDSCLBF2GA=AQj7s8`QLQPZ^FoQixC%GXZ`ud*n^a-mU-CG2w_F^7Z4i1 z@{$U?^(3HIhycuQEcOdGb>30lmPc=6e4KHQX|pFd#TC(%=Z|K*@!IBJn)1IVomP2w zz)lRMhe?QpG1QuxD{fH$_42qZXhi9$fUryH*D&xbj#ekH2bWvxPM;e6e**x zY;TYhdt6+#p1WQ;2Y)`p{p7hu-NTcI^kg~T(^IYLU*Yh?NWT48-KOapQxd5GlO~l5xUgtSf?A+LN?PttS3e@`-@J~tymf9mZ^V%}t|NGU)@XdOu zgkN>N4nF(#DPJs$2wnFdy)L5%LH7l7DA_~mtH*VN&jm=Y z>cwE=-RVd3$u5gr?Rgq$%Y@eR^mRJ=`tpiY%P=sI^jBsd{VM^jJpWvk|NOOJd~BD}A^e&YQuU!@kO7H4HfGovLA z;~ay6P3dLbvomUB7`TANz`WEq+CYAXGBZPKA6GfAlN|C_LL5r3_A#Rs&&hxYUQ06F z&iuok#}{;$seaRIH_e~E@0oGc>qyPJ^edTH*QTO7nl<2XJT1hPQtP$M+HbAg-@djQ zxDiyj7a#omY2jz`g%3gM85I{~Kts?r3hNdW`D-K6yV8)flP;yf?iDJ`gDMWyYd&Is8@5=YzAA{%O zU^qGEj#Itk9pt^*JRDT{`@oDn6RVl_`2&jRlpvP)Zsrpb|2YoFFMd%%pE6k276yK3 zidNZ67wvO{bUMO89epcmB}tzWZ_B%E`OUt|E=_M}v#TFZV;$mugpEI*5S9T4@B%y^ zQ~27uZ&};!138L%sltrrXMs-~wl_43ufu;N2|G`bvGV)zk8AkvB~MCKPv~15Q%1{H zoWgX2*!t5pfLoko=J--w0l?Q0d!1;)4az->F;!7U+qU9|?#^+3`?h(vu65w#9S%8^ z=uI&XZA`+;SHCp%2=BRtXdCdEF{XEr#mVkZhv`Ywc+dh zOvTm{7e;F;*T_G_qzgZXW#ST_`XB~_X9la3F97h6{@_Td!v}9+4kaq`{>LNCjwJCk z;ges$vxpWR0MP!tzlSl3NX<&-km@Ogx?ZSj8lQ5MRk~zf`KQABPleO9?{^kRA8$y= zpd#BJw5v(hlJB!jpperO8;tnVHu}Ti+;H1MT|xm|Ic-+)NffP%)!F{haPcW&B|8Tj zY7Gs}_4zvXo`LNlpj}Pj@tIu%yT|(ZFU{#L12ws&u}`9}@F?F`7hh*ys*5I1pcj9P{Pp;nji{JgopEnSce%%Ou4{4(La7>o z+_K<(EX|r@oU7rX!Xoi4M14OLa`A=ORA4t?lX#a7I2oR_55G7C-U#T>PbJ-h%2zfX z;{_U?u6ceIVUBFY^Akh1eO?VFv{byAgp#vZroiLm=Har;_evn?nx_E%NDw3^&K>w7 zy_Z^?Nl#_O9$(xhaV0g_cmgK6l-MTJqKlaMdk$Pdb> z3<#wNvDQ=*qYdDZR}u6-Jn}--UHwbGR>`U0te{W=?);{M@V~=eotE z%8IrFXsh>Sb-3j%jQ7nYo*i3*OGsTSI#a1O zoU*^oLYbWfERGeSGDxwS%Vj1}NH(B&^8nKwT5{>?7{i3k@tI}$v3}2J42#Q$f8z>c z6OdnSJ#Ims21LRL0Ouiv#DCIwxv9F?yJjy*2zE!PI~__verJW)2W(Nq#2#+BgrqR!h|q8|jhkiqh1pJeZd(GjTLv=CKH7C?& zxeOWqd8YkVa1*K`+njL|kDupcg=HM(69Val-FFCG>EkiUB`)$rEUpgF?D0+bKldc_ zWRB@8HPUTtz5QDEOpD_S{`4U|DA2|@VzDOX9Ci2zsQSS4SD6@wC+|eKG~#plB=cmu z3=~^i?;cstk><=pPMj=TEji)Dacs2#ObY9YbJTl-F-`s2d>+mfBnLud6%)z!l7!O- ze~Y9}B=d;GVpp0*_^x@)#eS+Wj}1vc3Mq+*+qlOv*j5b7PlK5BD6Gl9@i^PPt2Nw& z`s3?vOhUoJOIFl$K~LH>dX;I8V|SBwwn$em0Y$8|aoGO(!{-=hoQ1T>?TorDxlC*w zS%bq=jw~jD@cQ*Y@zqW5!h*zkxS&nvo&u{|DT(}4Ar^8NmV*U)uh!CI^p>z$q*&I3 z5&I)4T8fdmx*6jJ3@WGXsPfu>e08*(*?2Tom0#KATc}pXlsPEeJgM!=$O<9e*YA+L zQ|mGZUFeI4M}o`S%Xn`;z9T%#X?0`0xmg0&m?3i7f3GI?X=%%T^Up@F%%14lGilvW z_4NR;@NJ9C@H;QWMB1PhVcPG0B0>{6E4MRrLVk31#wb#Xh#S+LAT@X-ExEkeC6;AG z{m|qokIF%|8a0V%<5QiAaRRBC9mTd`LZ`D7(BI^rpnSM&Fi+#01}|`=;${s@8QE%e z_f&G+@Fs3=4u`Ftolzx52%-FvNTwaRX=C2c?G<+}3mVRQMtE>`xc=12 zSByv@9Bj{hObcb@wS-&9Y9P0|GHXNsuCj98EnrQ;F)XZ9fEdv`(rq2ixv+KBGfR)` zKX7@N^`A3d>vq238OKDj@qSNl8_`!;owdvhv2oZjq>Aft^-vvd{&-QexP$*_E>q(v z0y;cTaedJuAIOMgjDc4Vj%nTra4P9g`sX_M?m< zdPeviR)?+$@5ms{2cLHs=gJEezam=I?t=~!CgJ*@`%zHNr&ZzFZj=>9Do*s-eQN#0 zLxI}*tcB@b9Bnxk?$sZLd#zogJLCz~Ys-Z?s9y65TMrt!;+kjd@zO^yzH3uris*G> z<#!%q%FdbB&ieD#tl}W!()aMBR>8FA8xnEY=bYlKVd>XyG?d7b;kMsP{|g7-KflF{~f;@7Xo8av1Tp{k#fMG-f&K2>eqJ}*>y z-Mdm{^a#Cozsq`I{n+pQR#5wKr6C`Yi`B;G@M(QQ0c~!#A~ zl?&r-?24<5Qa?~z)V6>J0!cah&`T?tbjr0NjfhJUHc=2xs+?kR0tJ)9 zH_y%V&0o^YKGT-8UTgGTUZqcMFH6}!q_HI1A=ZN~HwQV`w0f`mK>cXEJFTYsN!liE z%2C0zw6?&1tlqmM<}cB*{qTZFv<$%P=q1~Oxj_}NEpGqPET-6-1~hV|`m$&NabKHg ze1_54e!x2Cwe_SAmOe`GLb@~Hpgx2M~`X3DJpiQy7@ooBL5fUbLTThZk$TG!rLv0pUdWRk` z5c88z@ckE~p(z89>`PFkfp&|mVRROcfMm>Pp0F3}vR1E7)^W#~tjp09 z>wZvpyGD8~C4uKJ)hF#l3+ehr8FmjqME%0d5+5uX_tg0h)@?MvN!? zZ~zi)?_K#Ku)awyF(-)@5NV+9mx-n3gSLl7vBr1Wk^wEV^QiPv^(^sq*zL35S?pxL zVjYuK*7w?kK6eFhvjiNGTU5DMn!C*k1OG%mmWe0Zn7A6xInJwtHI7FM(d_&j*i(k4 z;ItL9%S{W3+RW)4E-O;Ui(v!y_{s98=Rjk+0DGbeok3TCER4%Unjy+wTvVp1j7l^V zCgM1tuXw(6tOHT?%(PqpvW_=9DHKdmmLtKBwckZRxj7FYV~2b)PJl^U@@xJ0)X0@K z6n>O1nZcZq6eOAV<1MwCw%;G?WjY~Otp_+|@oS1R6Av^0h^|`zEsG1@%rt%lQDQg5 zC{C1x9K1XF?(L3+98SQW>a`yY%i(~j0FIAXTUhMg=C){Fo(OWvEAqv&?@x~8c|8L| z0tqTFmt=OkiDb?rk^{6p0c$X0@<2|GrV=xF=W-56?0j$vkw2$^5ZxNTsGb$a+D)b? zCXiXMzA%sb)_hFZUhKJzw`KT8zcNSD+>p02BDyG+Y38!C$i`ginj()^`aqx1qd=Jg zR8Epib-4oENd??i45L7$x!u3Mj&ywv>hnL~E7zrs?(l0-Itc3YfsQW1e(4s+QXh`S zXS0~E=&hcLSq9vSPaghw&M_C5Rx>~@tNfA6bB+KNtAcQ!yx`&ZYL_zd_3-Cb&Vf4t z)dDo9wE(Hm9iw9oIPy&Zw|@$Lp4hwv=mEP(Q6y6#74gvpYwD0r`Sla~Y;jh#isW|K-MX5QA#>5=hPYL^6#tOaTBazzbuZGzUhl@=d7x%ihY7ny63f#xHqL zgZFauBM&N7Ut}2?~tPAg7q}PibFH!}}5Bew8Y6IFkA1sEMZQ8`L&Y2a6c`BUoZ0Ta8sDk#7!Qz|qj?>0`)CqehYukyz2xbqC ziMin~*gcwcw0pW=Y{nrPMm_n;$GX&^JLuN8`}U3TYvh>gPbyt6^mh_54m{QgU()!2 zBX!B-tBFHLtufT3(?21H4#E4+HcasC<+ zR$|>NCmLo*3B5>i*-RP4p3|N7y z!1lsVw}s!MGdBKf2Lj7rqb*M|=BN}wR-%W;q@QIp;X}}-ob8qgE};A=t_|TQ8iX|; z7Nex-=fO^B;}Xzbr6wFf$6F5w-#RS1G4hF_yv6J7(fwl-IA^GC#><3B$-vpYTM_oH}Q>(p;k&cI!3LdEOD?ps+( z@`L@NfP%oVKQQ%oYE^xwJTjF1t36CbMZ4cL+H^$S7w3>R6crV1u~Z6(i{MOQ`Dd;S z$B8)jX`vtM&xne0JNmuXGBMPhCWQkVoAND|p1++(;e`CeOS>kMtPq8p+wtL!K-8R0s;44Y{^h2XI@MN)+Z=U|!~)7RLv^~b zVQ)Zu(o5K@;74h)E|%z=yVTK4qU9K4%guHs%q+mYJJcf>c-6;Vp0zd;hdyK1AhEKr z_h=EJeryRKo^aXXB8lg!-ap6gmjIVQ=CtgDPtM-NPSem}YQKIK*vqWu;Z%51u-D@f z_#jTptnSG><&vU{oK4_^Z@~L2kcd^@9=;W0{W6k40PJtp@)IfU4s-LaX6fQ0b{4$M z$-IGN&|Non2N{>>3OBITE6`oL82IW9XGlc$OaYmq3zxmuq>A(~V*Xd$(c>dG+h{Ya zax=lTg^bxWTb~qLASXL;%{<^>bdqMfU(&jjR0@=w-pA86FBM|ygoZslzGsK07nU?B z3?t&it0OLlrJ}c%zT|)H?HF-*?aU-*&ayI)Mchvg=kyaC{-m2V+^VU#koq7~?Cwht zi8C<<-Z5y&VzYXMI+d^c+#?9KMy0*`^I@DX$e%2j40-<#?{& zQ|GFgSA_H`Hq4H<@>M;PJDgK2ywZpPmYH@*Y?FFJ7>l0g7o;-hodUd7e^1l)fbc2s zix#^ZvUX>}f0RRj_6LYyb@9%ON~e(VQ~I>sU4c)#E&N)>#lk1mOxY7XUSlWvsT-+v zulsm^FMu%oyTgj(6SIGWmIku0=-X<77N?{|-IKB(PIVu@IJI}wH2o4C{a*jkg00ya zSyCucXW{;V&mOeP>AiB*W>Il+FV>TP_T#J#Wld7*{;EsRDCW6ox`OAU`dPaXDETZd z&O3R)=Ep!`3L_R%E`1M7wbQB~FrxTiMW|%#EDgIOh`5~-p#)@EQy^M_Zczx{sqC>P z<|I%VSJAHfBeC?V}OX zIJWud@IdiXtLRcD);%o7VyDIJNN>w0d9}Uiuv;9z^x)`;k(I}U+2QTAyZ7RD);!AP z_s|J>xOTFIqQIw33d!Qz0Ci?tjgq~1`6Db$%*K-WlKV5G>t}(tC+lX{bbL1~=72ZQ z!meugpO|{3vZUNB9R}tmj~5t5lg^DRI8D)I>B-J`zcdeKgyvm{Xjr%_H;W&S{AQFe zrc{}>^AHq;{JwhgH78Kd_f{q^&28q`Jcmcb@&_r@LSYeC`p(0m%iK0gSj6Tw%vUBs zEK%BP&|D$!Ud`jHYvGr!BbmtKuGt9cOzdnWKw%JWWLzG*f`(yLlEaWllr{9qrO z2#pcR2c5$nUHSKavT-B9VH>2KuP8~phU#&K#XTT&ZG*s!6^3y2Fsd>JTMFVg=5pVm zk|{Hbi|^GiDfqr79yuM@<|ls~0xSpOnFJx^#jI_c(wdkM@nwdv9NEWXEGy)F6q0IA z5IR(ntobMT$bEHKVOZ%_X9OMZO4J4nS?V<@9<+C}e%uYmVN^^e$QrtS*&+E!?dC^e z%6m-OU&U+2+@r@e4tcYUcnjpr;?t{o0W&_&&e%h9Q_jMB+|xO_$I@pSWsi&H*mmh_ zkWihxEjw;|+}USCZ^sQY{hi53&*?K2JQY#k0Cwf5k`}>cP>6EhO6jl@wm=k?*@4(u z9d+12-M?*QobMR+YeGYTMU0q)v+7q=6eqaMMf{%{%<181dgCpJmL;p>{UNWPSGl*> zCSAsLZDv6zL)DqgOm=S5u?*B?{;f2d#U}xv(^3e%LCFnAzV`v}Teht8zlN;5`9U6< zY;Tcy?UiAM7^*@_4MMSLU8E*X-L;}?^g-_F8ONQU@prFWbt$s~Kk^LfT1_;W{0Kms3L3Klg%*}0k#34gFk$i@=Bo*}OA@g@JLBHY zx!*wMR(+T~qzwk~KGJ*^*-0|AS&$Q3&QYp!J&x1)asBGm1KBp5iG^p6WFm z*jExIQjad~@YE{A&{?gR)qrvTwZ?6iJCr_-*QNRC;gS-zUBhz9)U1P0ze~*Ku4<)2 z`y^>fzV4+0>A?VA@%-Xn-h}zecr5l-#Tr3$QCTdH#J(eYQYG7{*ySYT`u8Q;K@9Fg z=F)Sl7VK1;6&fDz8F1Lt_7)GkvP0a);p@QtC1<^hU(E6?$hk7|o!-3c#hBda`K1YONPPn^ z=bSWVLnyEZ7Z?ll`2hoB8F3}Cjp53g>;0l=5#N(WV)l3tDKu~)s$-*uA z9+G5LYKL4YH5*~|up%qm-FN6cpT$?+nS}4$nAFZ`z|JURBkV&2V%~`hDb7;~SHMZ# z)bcH)#pvNgbc2$CjV^$M5CiD{e$YjoC^-S{w%3G2a?XsEJr-mB=&ivn=*Q$}8MtS6 zAj=T9iL~aMn~e8hu)vEU$bCm9InHH@pMn_BIy>=u7+eN+Ls8ub72DR^`1ZM znenk96>U_*O2HSz)JT+G?QMP0tMTxbJC_piizf}6P{pkZa)n6j4Yb}GT1H>kXBLIq zs_agMPDMy^1@2}yinWH9>x3`$$WB%cP1JcJT;Kj8@BbLdv$HbtU?S-F@O}wn7HfMM zrS--xDA6PHFD^~}4Pe_LWoCLwor!uunfrQMevj#m{p@hg@*v7T3xvjFr~#xHNyjY&Rl*vAXh)h}X|Egc z9%cdlE5l_Ap!s9fPo`d|m?7jR0}b>{Om=fH$+>Fs6!2O+TsE>8D5Y%~A5lw^vheq_ z=|sp|3@<@J)#oJNvYEM^@@BsLpvq?r_V*?j< z;aC!R%W1z55X38xtUCRBq{3lzcJ7{}21}Gc9^zt3R6zODgYA(A+;V1A(eA3;5M`tx zAF;}JZzC?q34rGPD@9%U+-r%XPv5V?9BYy9plC@@i2|ED8?0$*oC_hh?sD4t-q&I& zJg3f`$uco}JWX}F?KxIW?tX-n29zgO;M9dpN&?2UjAbGe)JykK@Un|&7-IRCKzz=( z1uQH=QbZeb-X>~D^WrP_kC&Y>CSBwLnfJ+FP-4dW`{`GzCdAc~lO*s=y6i(R{qhaV zuIW0!wTkbCUwck-n}VB_4Ujr8XK5qSB*Oop5BqTAYFtQtD54`VDk**qRfrmGOZ0{C zzBgzcp}^zDDO#v!kK-M=T4jV^FBgtEutG2#z2RUF_B*KArP`)Ja_b;1AUn{fE&*q! zt9EZ;1%AE~WiPjlf`loc{@fC@;YCAN3`^7xNVU_5&A7~Fg?R`a^!B9<-m`>|16d+^ zYh**w8^p`>l46X9zF$!&F4A@fgz5fxcA3LmA_*nTEGnwxsU6Y`Mc4kzMgJdi`v2hr b(g#PXT3D-M%fX&g#2;-Qpa=|&l=M&of|P&=gCZ><4&9BwfFLT; z4U$q)-yZaN-{<|#I{%z?*3u<|!#(@H_ukj_t4+i`Ehsq&6Un)A=g2i~sop<#?gH%G zx$~_=1mHVU6CtYLpYyKwp~~lq`&gF13p_ieyGrNImBx}DS>l7&#Ll;jT+f}OXuNF+OK|lKWx63dL~Ys?0(#; znK;(+_-4=ReK42&rnc6^6{ z$Ou|?aSuR+Om4H4wycFh*6_kgiZ$wa3#Fn7h3u-x!6G^~CqMtTmcqe9@3pFhhcoRl z`toco<38(x0S7(ig$-!u+2_!1Ven!VyYLMQ0(WsMSm>~@g7DuS&Y6CQSPxo2Igk^e|uy?NXeG&_cr5G znp6)yg9%4T-R?_=ZxtFR#}lWfLiPJrJ@|*~rzcJa?Narebv}E2BlO-gF;cUygDK)? zVinEQW0-8@p{A{0zdJPuCYySs7Q#MsKV?%m*|$De^K9Th{atceJ$yY)+zyrQ+9zGM z@X804{qFVa#;0tYF3rTehU>vK<+h)gQbn!9K9n#!Vw7Ha&tH~auieh6sQ8?Jx|Ev< z;w#%`o-r;jUtP2A zKz(?{uHcJtH<23mLYsKcB_=I?h-Lo0`|~lYv9&c?LPFwJ|10@9r+~w>bf2}VvWHzX zMjstBcDxTLEP9dzU6%85ySZcKtmI!Q_*JKS&!;Bwx1XfFd|9}#@F~rX7_#fxFTdBR zcs!)o1)iK^;#|&@G@?N48=|7s=`u0X9blvD-RU{;F{Oe)cdUXXG`sXm06Y?CCzGCcJKE#CR)X-4|NFQ{>bI zJ_}w)NiOP6ts&uXy6bdmE4fA_`U-mIXYF=hnN=G}fdcqKcB_T`WPrv&A{%3Sx~+K1 zt$5I-odb05&Ftx{a)RA*C|+kM$;%UR7rMr^P_v-(Q!(% zn^M^}qwg)Z3e1mhpUjz`w9$}ODU(vEe>TN9XYK5#O&qVPgcrh` zUZZ$4MLAMx=02=9a!+7g&%{IkES)bSd*5u5O$!?ujH`Qexq08!@_vPpg&9UFy`xX}B;4Qi zOFx9a`0e0J-$xuk$tcqJ^fd4yAuJZ5e=xp(STUqkj<*p;&Rob?YJLdH?6=>{)S;8d zo3Q~7ekDk|X_pRG&x$_Uxz8#B?0&znBho4ZTgM#NA{c_322f{3W)cs}$QccX+cVmC zc6WCd5}+1@>wew8e*JnW(^b67B5s{yLa(Q?vu4~e7DV9zCkp|UW5mWBQ~s0pAiTyy z=eA&tp-p)y5JdJ|g@{B1X7bouem$76wF`6dd!?uYV)3j-#dQ2411UA~UaQgXiPK~A z0!zXW%9u)$@um`Y{;~V zuF(XrdyXNJW{{JIN89~2TeDpwE2#^Fz8>|$>4IVMh*G5DG~xa$FZNbuD-!G{#6=-q zn~!5IQCG$enC+en=4gmHjzM~^&$yl*^aoV-T}Jdi-tTP{ob=lI!Sv4tYGjj9?Hqs) z-WrM<+^3_XbEkrl5uZdh}sxjPr$a^1DN@h{s*tF?!7GAUSx67`v(J zpQX%*7PF7Kex)KJDl$KsW*8Y@S??F+j(5N|)gQ1q=RM2P3=wWlbPc*`TaN!)K0S(Y zy7bXv+;&(?*rHM0(+^i*&I7CKX{6VwV2ukZi(6*C;jQ!x+8ZgHO3bLhbtavVDElam zn*utSobV9I1xh=T)&2;6VqXtb=tBMJ@w%}Ut6hwrD~kuqq!^peYU#*h(4C=Y1*nl8 zme2pmIe09DKIVo2&xJk`l?NCajI=~M5p@{F6REbJ-O6}W+2>b@rz+7wkAp3gFMU-e zH6Z9yJoQ~EmA@3R(VS-`L>0p)beSB|(ejv4?1EYNfJ?CY%lBwCvV3%~UG&t~BZNN_TOag%<|dp|*_&L8wxz&Vf4oOQs**}q8df>b z%&I)LB~6usvRe%jm6uXtK3=@7P&CAx56l1xBlD;G=UHyKD+=xrdUPBpsS2!ZxWO*_ro zankG`PKC2qjI-oD-a{P+P5%mbRrUhEe5p z$njZN$;77iw}p6~*iI`X>{37RxXi)m?YlEdW&Y=~S7u2+28IOHx)spWVFlJ|HZgQEb+4HDb9j$2XlSosP+g zMUctn=KBo=vI5RZ#w0ui;e?O&tr-bZf!69QqS*9)%A=m)XJoOWn@rSAqM`xF0|WyyfDaM0;KJWmMRfh4PY-9HH0)24^;EyIQHt=TQ_8`mpb- z()!P+rrlS?8Suy#NODmH(uim0l4JHPyb`us5#KuEdcf+o&!9D~o#GLVjoeeY_f47A zvURWB^LH@&Q6o(P@}>fN5R%g{Oya=IVXu$C(w3cjVOT+(MLa}KnZ$W>KbqZtKg(T# z3hkS_8XNF)TS-ndC;IjD_GZRL1}$mpW#usokqT>o?&Cxl=S!1`-%m*=KFGPa*<@>N zURe@cb(@GSjM@H|{VL+oY8LOLyuCw)b8pq*HtBlk~rXbEkIqx(D&lAD}Or)z3!2hO!^Ygl;mqOSXdI#Jm`AV;*$g?~aVT=#||H?}) zl-~f58eBfi_q{2ppyQ*S{DIy4FD87)qt>xTAF&p5)(dqbfB8|+*<0j#erjQM@SJ7I z*1ongDUa=j7~3(DZMH|&jMGhP9&oO%o^9_e

+Z{T`j1;f7NA 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

mTE#)e4biSJntYq6I`NGXoSN2uU6`2ww?aXy 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 literal 0 HcmV?d00001 diff --git a/algos/eq/Picture_iir_absolute_response.png b/algos/eq/Picture_iir_absolute_response.png new file mode 100644 index 0000000000000000000000000000000000000000..5995dfc5231a55821d4c89cef7a3b7171a7620ec GIT binary patch literal 51470 zcmb4rc{J4T8+J)Wwn6r-u~wF{WEor5A$z{a7-Sz&4B5(3WM}MKwonuyOd?xl?CV%U zWZ#J_*_Zbj`u={uKi+fR^PZy|`UqY0gnsR`|!$>{t55WVVKc@{d)NOIWkH3T=m{zx)Qa{C}BR6-Sa%-p_8i zU)tOe|U?@h>h35)RUf zkJZh3LpUhxF3ol9$%%S*6ay1aPQ0W3w)^hs#Yq2O7kfv#TD$*f%DnK{cP`x{`?$%3 zxxlaxph{q{W$zs>Eg;_nvpO?-g znzWiY)%1HdwYR5;&a5?YB+>C3ij5M6?IL*7yXR~>Uh*7o>KtDt&1wi|XuBx)`?=cN zFMfvue(J?$HJo2@PvwtyyK)AOxBZS8q>MT=Gv#EjgG>I&_M3X~tE7qD<%fNq%H&*c z<`MSbcd&fK;!0_o(0WRjH}9SYzIv^ZWxXWINAtV6-(jP4!*BWH4f*v@9dFJ(At9m4 z>DYN00R;B#8YcVd9Vsve@ys`$ZaMBI`Ry_cdCjHIbV!Uv;Be)`k603XR-cZ=b@^_U z;p?o9Hsp`>k9ISUjm@6^`q(H<6B_pG)0i9$qx^1*j`e(Z7JfgN)g>g&W7I1~e=DKb zTg7*OcAW+t82TkUX9nrY>P!O8-1u)+S^LkIn`AvR>_+#F^?)| z=!g7{4{g4^AjR*0xjEWzWX@KJ4#_9GQGL^;AEM}ebi;2~L+WT}$|it9Jeo|X;=Ul? z;?}T}IT!2k!JIsNlHB>n*67pKdFka(W4`M>8aGr{&+YFl8r3m};<+%AiWs@QdDT$m zChzqYzP7;Q%yfl}vgUvkogu?P4ci6qAW9EI3s%9IzBqL*oD<11# z&QU4be36=Q-IbPe+MLHn(!?wk*O|GGpy8F9JsLJ~TH-N3J;r*Q%3=*X-oTSd{3UTPH|^WH#7#`#V0LM?0m z6gsuYAJoe?Z`U0ksuAl3LC#$mlb`ex4oPw4h2InPTmzUcWzX89y(JO1#lCq~&SVHreEQ=a^~gGJ zDq;{a==r9iry5oERdIK>IF8pi9OO2@z@i@unfvbA>`wE^Gm$!O?Z!lT zbHnm*6iO{=7kxib`R&w~c8CuvYx8Dfx^_PK?SGozp!+vwk&0w?!53(^Lsc{V^f8`l z{`*Q&LgZIOP~CnTsblY{5g`;`*g}ITgUOj_4%w69FaTeAN9) zA%+aMHs;zTt0z0F2c;Zj&}MBqLn47;IRcAF#f{plH&-hTjO?n2%XBk}qk8O<)7aZl zQ;(l?HH|aRZLO1SUE5jh;Bh}I2a|7;j%cg6n#6+3G} zLmkB@TaygU)iVaD~?2_%)qiEq*ro#HoWmp$LIRq zc7l-^(;=JXd4(4n{$>6fFOpx8!v#qdi5N%*7VPBrjk)haI7te-{Ejy8zE%(eZ^|*c zZHlZW2l0{Yqr-i8{ljY8WLglNmGggM;OtB_kLVECT2m1sV$EGV&rTU2MdT=Q^cV zBZ#RVQP_}6@LEvPSiYEoL$25+%fGmJ`_+}O9hq_MJ3-|;z9d(X47FsgA&mJ4djoas zl@`ln&~xoPQ-5~nGC2tE-a$#f(!o%-)1VelTE}lQYt9M?%QV$d^L}Av!D)_oHhR#DI3`vvLDm$RBIR#7!j+=9>Tfc0 za?zMd?}zDk8}sYAP7 zp+{)Sz#SX>e}Q0Ens$dSLrP0LBX|3Yed+p@{y9rThi;w|mSUUO=vJaqS)ra}mKBCk_io^4S2Hgf-qgR+ebwoQ58p{SDA zrB~9<`vxY|wQ04HEk8udSEu&eT>j7>{mXAW0Zh6>F^*ASrCxEbx3SoX^ip+hWU^CM zvMZ4exNkWa4eRh=Bl3?79bT(uUF0Mds@<7vHdcIw-sb4u;UY$LpN$EqsAp1izL`n7 zBcI7Mh8`gQhEX3Qe+P}&@gCs|I+9eKMM6U$+U*Kqb?2HobUBqU%T(LE?04(aCq$`@ zS*bQMER(4kx6dMliRmW;UB4bB@1OUk_kg(|OHh{Vw2F~dU#04K?)cA7Nlr;`Gg4Yp z(s5q4c-+M1p}aa(0TrPBx*YJa&AC5$6LV$KX@`4;$jX=+cK<2q*(yfCFf9sjv`|){hhCkMW0`ad! znM{7t`lL1M9Y&n)x-5rdQ`dgST$I#fl0r|6;rd9UwN#TZdCkiY zY&qFiXR--M^iACTkf@2ej@>N15V?;PUmpr#@nVCpg$^K1MNo4%49XWv=A14E*8I!EQ`d1DD7% zyQ~Sv6!x*Nw7&-ckefHQmfs)hy8h`9Ae|&orZmMzoRzG+MkBk%tmCw@=kiioeZ(^| zn>N-pZOS9<>UWPQnwmC7HEq@!>my9vuFiRA*LI1ndnSKa-8c9lSz9{k?`o`!JXrCl zBioCJzPBC<&4`-Mp9&K+(HydTcbx^TaPYDX;R_WjQ!c3F6M);C&hN$3-Q`Hj-85m%iQG5fp!h&y~2 z81mi!Wz!hJgkQ4tytyn)KaPSJ!Rab_a+mk!q*Mz;WBnpdcmUac-Gkr}PsNMBW^5))4-S-Wjzd1Y6QVvWl8 zcR=Dc^{27pqivJX;-2zO*phN&?K^?htzh{BC~S3qxh$$=#EwhI^Oei$XielyZsdh_ ziA0p7r*8SXh{(ZR02i+>6@JS2I6`kSea`Yyu#B;)03NMTYn~8U@zZ;wBhp62ajB^4 z5qG(!jhsp1;E#u&erC&j+#Y?((v~X0>_Z&$PGA%%74Gxl##V~JRI-$NZNS2zsr!&k z;dTM`VMzo1dd;d&*F8hrR-u!R2D|UhglgLlpM?@dGCD1;He{j1s3+HxVq;WChOG3H zp2P4PwTv~7Y`;7^t9K4*Kre9b3dhcui_^5pRFx3dZp_BZ*q`}B1lR*S?XmNkbK*X})- z>i^-qTwJ|=XR80{IDJRD^ryA_C!4Ed=H(+UZG@|I)XZf(WiI}FL-sD}&(gq+Mbij2 z>GHMC2Pp1f3Ksgq)GU=JuX6b&Jh(rUb;(IHyLYsnqmqFL z5btj;aD5ta(U?kLBOcELQ0uBxmE`t_Yr5rf^+snLgPCX6+M+CEA<5j=3p~yUK;$v0 zdNxI$7q2tPd3#P7l(eTx+<>i?S9$qd5rQbTr)&mp9DS-gEL>~t;EIyr^Z&^tAOk(3VUlE*uv{Z^FpouKzfEPLRYJ-e}UhqDB{U4 zFIGVsyO)qVirJQG5){lb#565k=f}Pp1iR?Rs-m-bd&S=~y_7<58TC6)_+aX!!(x3paB4~Lvn-d0+&Kb@J>m-6S ziBYHrLCQ(utR&o4PeSb#!(q9pY?fCgNCjVn*{d<-&8N9`+E?fEa%<@qSCLedhlEEr z-XukTb$%Gqt$2C2kw$oPz3qmC*~f1su3Qm?82<7}5q(X(y(@*j$E^@J3}W*0VKk%!s3S^WXRk#8jQ-Le|a z%Rbqhr!V+?RgG6HNYcbu;bsaF%D}Cd8J=Msk&`5D9c>uw(%UUel!i-r(N!9{k^cpq z*Wh6Y;mG2=1|AV&*lai610FH*WkIm^@=csw0T^#1rn!+m5~K6P>c(uMx2dC|Xd4&;cYaQuA9p^| zN-cnS5+y7XKZ}AUA~A`ACj$l@L6&^)zlk--&1u-~>LqQVF_~5{hllU9ETKwn#3l14 zf@ir|OE!?Bo@Q{~(tq$O8K6Pv+_0ZJ@gfvMJfSRYo$lDhD_F)K*ZGA$x8g5_zA19S z<_lpVM6y5ecdFb?(TV-|{LkHY;RTHUploil6&_&dvs-2al1bdKJC!% z^w-_4OX!#e{Ceb@Y*s=2k&4zn{30`)EJimzXC_S44OVkbUZLF+C9Tw@OP zE+>H)+TF`mh}BMmAsTW{hsj|Q7y1T<5F3;uZNJc|h@cW74gJwndFA=g3b{k0d+Bgo_aVa*}eXIV#3?b=OS6TW=QCTk2*dJkKW+6mrDfHfFe) z8TFP#{fRp2aSv-Ax7efHEE!r>bA-QEfl_75N3N8YX+37QHm+p7=u-l@iBh%}oDWIQt*&f8dQz+WZ4_h--TPwaSC;{ZWvqg zck0WPC?CA0c=&lT0#tPUxn9FYk9S~1dA);Y%KpX_nbDPpoeG9(J)UZQLGX=bhtsBeYLrs}B!?B|)G_i3Y@3P$`>W&?~}6{Gpcw8^U0SMX>7o@91IZ zU0;9h!840H-ivySg(%r%VGL#21YzZis2O;m;f2LgJS`MM-;^|q(rZeX zzG?(-%OqTT(m$15k@+9wg|U0rzu`+843W7QLw?g+@bHf%-j<<^cU)CWrP^i@&kG|~ zLC}GF`~UaehDKe4hx8;oR~z7r3D4Enlb6bA-2f18!`L4CY=$xls^)wozm&JP9M1Btq85W+#RVp8M}CWE`tbTJZeh z21{yFoBEv1?Wh{Q_vB9Dg%$5H82SP~uAo+;i;`U*V+e!2(E5A#%M7cit>#I!y8Heg zQ&ddEylk!%%y?qM9;J5K7)lx>F2l_|RyVQJ!@PurmAiBnETn{k%X9CSPH|F!{3*;` zu4vi97X-Oe1S_g2NiZ-)QFnR4wC$%OK@z8n%?p8wGZaZ$aV&@X@RlU3orL4WzW0y- zXkrMrL{Cgs+;>Yl%fKNkotcqMfy~m?Q;d4Lx495$sOs!h#K@)sw zF@(3P@V8guHU@l|U2bC|!z9r**R-hfBcCp5rM#lgxX#z=aqr!bC3HzCmiZuf-(4W@ zNILJ&`8fZ!sIeuPMX+ef_X#58D3-*m{68Vr8)|FU#le#MB#;7IstS3?DFUs zIEtEq+$qTWLgZ^F0sOtsi!{Lw)+#w6E-8SVpu#5ThFx4lp+^=`LrXN$izvD%!lFqbJf|L9gYav_ zyYQSDnk5{iV%JGZPJtl`--4x+NRS{vMG8Y>duU8zA@K03kRE37#flg7Gcb4?$D~l7 zn_6r?C@VZ1@bFuijwhoALgCpGunX3xzgYA`F}C5I$R2%N6U%8VTa6#{iVrAuvhu z_5(%ycA!X7{F_Neig8!*FM;Vj#WW6c;uG3WoacEnekG zBi2TOt1*dPxGmfKX;jJz4*Y6~RdDPci2Dc_!WRGup+0H3AX-4`=$ctGjN_vI?cm9P0_jd$eD^P^;ST-9ZS>;)j^rJzhG=#&$r=}D( z0my8bdTkpjxPF<9EK{aoM0T<{kkDi|*|`!>=Ji?)LTR4pt?UTG)Hyq&8+FJeIa{hkyWyyAX=k`)DjePKoWWqmLd?F-6|@#lrIx<1rJ z5|AdlxMOnCMyCkGzBBR^2lokc0d%LW^fsVd5h((@OAiz{e!?JLnMJ-PjeH;d4+IT5 zk0+n9T*aMZy@NPFrpkQhF+_e+o#R};dfmEphma?=lPcQJp_@)2)T=d8dtD_NZAsQdBdN1S`D1e%c{)?3LcRFOeOE#==4@xJ77*4p&Y~fQp^waL`mKqbXW9$_H zwDie>S79scmu)C=#wIVtTp%U?ngfb!$f``IKiMRvV*J1k{JtoQ5@U#RbSuwksMSo@ zF)?O!0A;uPE;%8e(s$~{f)u#&;~$WB3qef=^_a-w9mdcX!1q@mnnIOMZumB5CS#64 z!uND6`|uA=lDHOZz@6n1a|<<2LQaGENdZ_I1%K!xSR$r zgTGj3(*FX8v|pFtZI>mAz~TA7K>j*?O9F_v4HAMvzy&uAc-vg13HMEqe^0aj{}pM_ z4?sg<2-ASmBJww3&Y=XOo`iulq+tke^T5y(@_7JE2p$d=&+VM7CDcd7sPvQY0@!H? z;M{_o9E0G52_>t7GB&|28xYb31vzi{>*omg3ZVT8XZ0O>S?qh~COW0FgkGcT=%t*` zlc@v_5@H&CX6~EpM=!sB(Bn%vc$qcQ_sYdgi}Vwrj`H-WZw3ZMRy2cj8xF*-^F9~m zM!@o1HgyYSQx5*On?1o96+Sl4)mpfwOL6pGm!8jY{XnPn6q)|FrpNRATm#dUabsyQ zd0OQ!{wJHfws^K)u0)p+sCw?!;Su1DplOj6W5qc+}*=)LkB zDrWkKPB%EOclgza82Jk>>zDE77qc4B`|Yl6L}>Ua&OTo+0Oe#~n`hBDkbB>26EMgm z?f(Ab-_9S5l`wZEoaD`Ot03JLK-DOIxrtk)1&0dd(VoUJ@7YKE1pxs3&+o(sonxr2n)h82bJl8lhciU z0#azgUqVAIA;#PU@U(fQmsN1Ff>p5fAturOuCI;<7D59mETh%RXT)nEO@y&l^u8y9ve68lb{?MfPg{f2Tk|nXI*%KFNR)95Ua%MfBK??DDJ-lqJk7H z45Zg9)KO}H5&|*w*a#jjt>$AHIu_iaqT`0GuqqV*Du*Gc>8mLGVBXJ}IO6B}*qoXC zUN*MEYF8ViHJU9J!eC6m0E^`Cwtox(WwPc5hqp=S>`EdCNo&x^<1w~}7{&e%>d%>b z#lgE*I<916fY@D0Uyq8OwrjzOp z-i){pKaBL?L1_8334V$PJ_-Xs#WGX^n*NO*gOjurxBKeFoY;DL(LTl z4NpO;c>4^2L&t}t0v3Jz@k@D6as@wy}!yBCGS4mmKM4f3&54SywxI-rwL& zb)+%Htp)Y^=P39Hr4@}xQsS<(^!}6Kq4XBRDkZX5nF?fqClwWnxgx`jQnqS+|9r2; zcdzZo3~J4+sj>x$YT7u)_uk|igTEgS;vJhSYlY3JJe1K6z}a7KtAgGRB_j@eN1)3I zGVz}yt(ja3i&+*8O-wGW<#j7A_a8rg{M$l=T}W6G+4VILpG>jv(l@4N!Dyc-2O-4Y zX>mSc2@*~?Na|l|{BK2!SnWQLTT?VqmV4-1cZY?|f>LZBly+`DU5JnkW&;S&i4 z9DJ#}`IF7=2|#IAC+2(vr?o;;B@S83KdD!Ed+e%@r1 zAdnnT)V+BpP`Qg!L8N2Bc?PmVA)(zHkA654rMQ#ABfsvitp4TD-T~Jsa_T+j8OFmm_GW287i1SMlv*jm* z*I2!y6T_ZDm=%i{VlANdjQNi>fq50iGHnZiX{Fy5(E_tNh2$Q~o8yp=D)tHwz8tq| zWM7ZJzQnjtLc@T(nCp@mSuwt6ncVQtqaT)eU;jxQK}kYfaz(@~?V6*Z-%qFqP2q-a zXc2t9N#knGxf*OwK+LVH@9LwuYqYzr$zmkWu_w=YWQ;8-S9&cQD9bO-F^M5tVBC<&?=#iQ>gUELC#mS3t%>+mKHRx;?^67( z_^@NIr-7`RD))Kj0FiP3&^TK|##pPnUL@o#JKEEj;NM8yizTQ4m)>gTAZ|_92FWpl z%$x=^7jf&e3xTeQ7bl4neu)zCk9r&fHn3E`3PFNl)1v zKyI`*eQh#W(q-Z#7E8LgaUwQuX*nvI-4-{9QOeiBX35&_pfLQnQn>?R2v$*Vbi=@pH zro}XG8Z7&43L~w(Qg?jRSkUj$_`9A1*so%GX20L3JwfPzMebA?(I>YjkL#8u*IKTi zmYa+rZd`lA^8pa5smyTV1bf+HfC~uB;w!t(zt|j4X0K~c?rjyy=u(-@Dos)JpU!Ez zR%8{XY&}yse2eg~QmZG-*?&Q(sE`KCh)~lD0Ut$&kUb+5_WItHAt3yW4ZSMJ`6#nk zIp>B&=_*|@2JL1PIH=P&MD5OL-_2~6w6C%ZFxAQU=mWsV$y(Sw$VoNHO}Bs=0_2>t zw>Uh!bb1w3ebAK(Z=$jiKufYPqA((Elf(wXrn7j?oG5Fs4dvh@Kq!AAXZRP9`fVFo33hf?T1Wm5b z5Ge0}-|H~j35s~R9$US+XyQdtI4*)yy@o2Srt`smdoT2Z8%0 zRb?ye%v%Jludw&d?<>?ClbD`yLUjg3vsoW7b)Y3qC|g`cbr@rjxpiBKn&z8{X|m%y zLmTBSrE{kGHeHl!n+?4|Edx3ZaZYKnmK|GxaX+RV?8@6>sANBFxvz?@Z+dTU*uu0fFwd-&xj6A zW_MK`km@>SyG;ICz5Pf4^sSJuY+ENUkjXpd=&cz46dE1)|HJBoKQo4!nxlsg7Vd zd%|tnNFs7^j7pX7(8{_Ctc8Z9?K$d-0Ht8Pt=@rmOtHMfR=6SzZ=+{e4mg>#R(CA@ z4Rf9{b8{iPO+US@+K20l7IksMhT-}9nK4%EPqcGuOR-A2g(&KO#Q!Dq0TVe=Nq61a z8*1^py;=rzLBSUUiG@6qSg4hVtV)LdU2*zTN_QKX?ts>>0hv;oru~8#P0bk#08@L+ zCF(UX!`hM;{EIGiA?bkJFj*py>7dC7R7&L)TmMogPcRYD@iZ2l_WQ zUUa|QZglZF7#grXmd5)P%>+|^|3Z96j99M5l7>-TRPec8Q#_-UV-}5SmY47GLgpe&j zi%7u+!(ySFG#3)RGqRLuH0Qga4Ao1|zX)^Re7}dyQd+DCqP!+?OOAW^GbNkLh)sh^ zFmaL{Z)A9o=&b7SrMay}lS1wK_e?ihnyG&&aAq|2NhCV+^aN3&`;bb(4pJpX|X z=Ia$q*&+qFvbb&^Rzb_F9dvFp0)Q?dBp^VP4@eh9HD!7kh*zK@yyv6OuA9#Z4=fs| zY_;~FvY*<$QVKrd+1&skK&xj1=eH(uC1liVJ@{`X$z%9lU)!&x^OU*gR#JGYMqtKr zZZ4_bhwbjWd&XSvhwIYikaC{w_ZNJ&#iYiadZ%%6H=36*T~B;xWxUn`Z=N;7<^(na zCEy;={wAFOIoHEmUsep#`*XI*#aGgX#TI|w(FPT{7d5sEK33~y06eV%Xr2MoZ^W;s zIQ45Luoh-~uCC9=xbADhqxM2BX2z`^*}wK)tbndN z_FoV!UIzZr43i208l#J&8(7xg+j%xW>tvwj@((Kx+VBB0!+hJTSDy-fzV-8B8p+tb zbu{+gXjYyS!VP@Wgp=j9HUaKMg&t03mU63Rs&2KFrOl|t_|QDw+)Si=ikXpH+EiZn zW&2TUszZ2LXAp)od?=C7G2Ss{Efh)exU#Tm4KFBalLko!^&=y*PRymS*6--*?%m*u zy#|}9=@822eRVn8vfF>QJ2$eW#8`*MU5l93vCA%NQ>C4m@U|rBt&OCMo zbN;aN8`jYNv{ya%aM(<=eZjc&e))T(?ds#{H=s@k_YGm_N2DC{S)KQ-cYD+yf*Fp8 zuV3*~%^*dZ)@XvUyg-Lw(k0L}8RMwJMO5z!ql8hd-xkSklDwRde4S@R+V|}SR3SSp zL1iJc>x!P^m814)BqK{|(W8>(lV66InlC_1mkxJHy>{Li4)B2Xuj;(cDgr98}_!^UeaS*dkYGbK^>@Ys9$_R!?#P=}+ShXedU&0pS? z+4u%Sl-|+-I(o`_CamA4y#|(9b>RjZKgX{fLHAmV*b%YMO7retyYDjtZad&oAt0an z-N+L2a}uZkPyg7jDY1=j zsxah9nCS#+fy;9}W)>yvv3L>8T@>q4McR+KzQFP=F9b2!6K7VI7n%0h&HG>31U8=74l+a=GP5)Q@Qt><5lDd37`Ip zp!7Gh@3bopEfhz!*gK!ePX1ZQ(Y@loKC!KhnM#;NXaQF<_@-AD07r!GIYkpqRLylPBX3ANA7dqj)mg zkJ7_O9id+x3=1Dl=jz=kmX#S?Gle)A&;$DPWX%BzrziMML5|J0Y1B{IBf8zulwa%k z`U`5u_GB!pLA^{E!`O>?0?~hjSh+G6AR*fk8VoBWS=V6*r@|+2A$Ad^qr-@ab*kXa zq{8CVt2$STF1ft#A*oz)9%bR@oNz-0H~%PAg81&e7TUK%L11Dj0@b-MpA99$$2H+6iMF(sg@HpWKZ#70Xlkd2<{pBrRcnQKuD=fjx)=0F zNpI!-mSMc|qS^jd0-IABckzv`fwxmI=hJvXZ7MSN4VasAC;dt1%#?fZ!SV4-oJd_x z)~DzEi!a0LOM1r%)7EBSON-zi^)f1Yl*uy&bNh4d*^L#*^$mKDBf&$-^a=*!f_M z`;%eof{%H06szpLCu}0O-RperU~7@>?^8sxSG&o_2+juWfR>sYCx`*iiy8G>zw4=z zzRz>X0WJeU11Hh^E>Wo{1c{Q-5CVc7Rll}_w9iAgiV})K)6br}aPI`ci8jQmqas%!eC9ItZ#RGBMWr1yZgjG{pEzPq_KkM-`ol5gHl{y(Pz~lH)eD1>Ro?s zb)oHAl-v#edpX&pNK&H_^fEcsX}4C^fkzyDU%dCEDrfYopC97MuQ8qSI*Ztd%!Cg0 z>ok+%z`bKRoBe6J$Kpntp^;W}S4JOwhm>@YQgVd1{m0%JjYQDsaat2B1ujzQA5atC z#z%Vxm?>YQ3v&A}9Ur&c+ilK@YV%7IM;38NY1np%6+@ejq_zM#3Ogn4Us1YZ=Z%9e zF`26|zGs*g-TrzZG#Hu!!?1t(gw7_%yQ&boON`Pd^G6LR^=NzCBaLhOmeXB+k| z$*!BEPLS5Nj!AH5?;|B1?G=3H-6hFe_DXhM$!iBDPtK6^d)NAEG{bOU)KQi1%$|JWgV?B$tgU8#zOeB;{Kqey@Mo990No-m^Sdf z(?9{X{}2aE28TA?`IR? z9fg<_SBs1-gt;t}-#E?1q78kM=gX`!hxzUl2kf=E4`{_F$#C50Glp~l2;Ke?jd^Wr-klMN<1V{`V@y5uBVF?IQbb4K~#W^bLq*;JbHV9r{8Ak~s z%S8~bi{=<+P9r%nO~V>vOt)gZOXoTa(M}5NC5|O8zU)n8W=0=N`^A%cEkw@iiQb4` zM)9=ex{I~e)p@?~exsy|{9(w(P>=%X2wa&~wQ9D*U|Z?#jF$F5Kv%0dfCnrNLFGm* zqH&e`9p=F2;GMpm(rX@nzRbuYBiT-TXII6=GWhrYx_$jLEgyNpFQ;UIys>_v8^+%q ztT+y~2z?n?rkVq~aDI6})4u{D8N6*)u>x4zP8I9w70mZUJvq= zt4;z>pB84_XMke9Z;0Bqjj77LljX49h zLdR3?z`zICDQJ6vUI&XG7{Y&RQMC4XrDXk4$NXoA%SaZ{KoW5Kd0X0h1rPq%DJ{WQ z7fNS-I9A1V((1@eJjObrm4M`6v^96{lSJ6$hK#`nkN+nV<#0 z?b6upNOOkq(Ct zhxC)~#bBGvA$AHW_Wj=*E_X8-vVTkPK)$23P2E2kgF*c0{; zHV(jum~_cYYaKcFO78ZoDb0jUtada_GHPYlT!(boNF%(``hYo{SD&x2CWt+5Hq+1M zolJ+g-#a8;PQ$(0H+Fdt`faeh3hnRcJaK#IXcn^#Bkn)imJy7b6$)LH?_E2dg*Hox z0*Ye9A5a6I%W@Ks((l#&Qf&*eAdN@*%oUI5CDv&dbt(HC-ukf%~LY~{RL5$L3$fRmtJDkUrzKd8T7;6Uw z3C7lh&yonq8#cGUy)qgD>$2s?0Df{8X^)|ILt^M>#Nln&u*Y;S=%bu>2lWE1o5O8m zB16<2bW8oCuL$KYqt^Dj=fD1>HIFfSDtCR!TtxiIWo>0Rf%uf`qBn`Nt+|#dSe=iB#WJve`6P6B~IkyMu}c`>d|d-+uJ2ZquUchjlHXh~!R$lm6kGUAHJkYwO* zn$mE^_AKf?a>c5BR{xAZp~DX@Qa(jqkh44fxipS~S}HOB!|XhEPmx=qYvbwtR-)an z3-vYu^77CC^Lv8Y0LPv$uY87f6m$wpRXPUykn3xGa+>C=f8T{8-#>7>1(a>cTEKV~ zg#&LdP1>e5x3+MI|OmWDhvS(7ArDvja68C6lfDcsl&%jb-okHbW`hTnL@?% zDFur!Q16GpX&5OUAc!=8v-TRA^Q~ql!iZFmcW3LzFY1NEPxg@>%j13VbPOcUlbkp= zHAUpOA~5?(rq`Az*IVRQl}<%FaojSI^Xj{AJU87mJ?g%HE@(e8L!b&Np?$RWp=st* zQk029f`^Ibi7ub3t)e$hJd+~&5~$z-2a!4g)Jl#gjuFDv5pDvl*D&>3v&-$2ivwtt z7~=o>Jx+V_)z?daws$@o%} zc@?H~pp)nraBQcxJ26{mrUEN)muIeqWignU@|u|c;5~N1O_ff}=(HN2GebBGAI;{$ zS}(LPL~&eaxP^Rg>qs!VG&sBb(0$4d*|vA(HMI^cjILV?g%W%O%WZwT*uSntz3=~= zJ4uqjB%9?LA?KiN^Bni(g-smE+W7(hi5C#HJGsy*Zs2UlQM7!lz-Hv~W@P%PTiWjG z6?HqZLZeY6bm_qU^}${kAIs|Ndgr%YGM@yxqiGnth$Yd&*3A&B0Gogb>#=*5^T8}c zNKF=b#9mYi=l;))2uGiv%0r)(aH_);an@C-d@UcTKD8Bun*?8+syHzm(#Lr~*3#=W~mBEG5HDqG)l!ucvy-USudRktvn|lZ7@F)vVA-OvA|8V#U0FX6mY4 zCy#j{7Nq`RqWAqCw*fOuEOfAw9%1r0IsHq}gC;ar`R;U&eLo`RIS8s3E}l^=8!@{>u?Ei#6|S zzt>eGA0f(Y0w%qUl)+K*NQ0LwXSqLs-50N62z$4y5}^jXe_X=-VmmJ*jG~fxGG%N( zkbBFue{V9r+P3f?r?HBOiAi(_JQ>VB1b~X`byJII@3WG_v?g2 z4%eok%!$egG)bsd=L|hHd;tS6Fs_kV*t@KT6RdFncmX}4Q!xcY@6RXr{7rvWbr{A_ zX7_N9?_1zwGZ4^dhDF$^Xb_SG81BXs=jF-GCZ!6kVlTq@ye5S-92>k^`4YWZ1&unx zO!<>?5(L7n3R@M!ldn4DpZ%*rU<{3<5bbSynH%snaS6?Mx`J=%Tz{=Qzy-kj9}=s8 z9b@RCtxS`;4*?E&yrqx^II*tgLACc}1vJuV0(9)z3P8rH`i2+z>sdDNICU*T!Btub zDdKHT!Wce#d)|d!GkyY9$$Q4A1OM4}dKqQ*{h3`^@dr~k;KX2rJw`=`G(`d*1he=6 zTNsWq{O}YD7fb;G?k7Im>JDqA^Nhg%Zae_WkHch|gi%);bGi=q0;^y;Fh^1M#Q_@@ z94Jcvc?&?rbw0+9B5Us)ZTsWb_m_BE!xDymauP^7LE8WIIG-g9!lEX8>HX1-7CRl* z#gFSx0V4)XSJ`<4k2S$%`7eRH_h-rI$9Y9dMq$er!tZwcA)DyDmlm;NvQq?KKS}y` zXWgb5l-{EUtf=^V>eA{=ic5{cuG5FXl+nIj)|pBDG-N~JvSQkQ~qmY~HpM6Ys z4NEWJWg_?V05UYQwb?|u`;Cz3(lqpyXo-XsmV@BxE`-VUb%?d7dhN27a1-7++8~J8EoVM#^%r6liyxlH29uI7E2-9ClkuVpUzE7 zq)m=d2A-^0PM)XH>Ti{D9tF6>Nq_zQ{GFW%w)@BQ%Qetr4_o(351oHVgBiBlxkUzY zt_3X=ctqL@NYPl&_An=bwf*skA6MMxzy8lo2zp9(B`cffCh<+ez)Jvnzl>cRO&!&V zjz>^=X?V&B#%s%ObGxO+dZ!PlND^~DIqL3(O-=PQXru+r?4>};hnx`a7v!Ymsble* zFS9TOYdOF)wl4Nm|C``l)K4+nBJcU%O>dkOl!AoCuAUgSPB-^7=a2KYr48#p_A!{$SZRw9!wzCFY-IyT|1~O=dAN22yY-%=TGM z0^dmyXdS?F2A$X-PxdZ6Ydipd&g7Q(Yhi%fD;4$=;Ei?a`5>Nc)4cj^< zd9A>)dI^mU$*jiE@0WsIU_9sPPI$89)0Xt*?MkOlKiyBZ<`MoZOrh?>Y+&jpDFkhs znx;K2(gsm)>&jtybyXAY(Cfh4Tnyxv#9{&8=9@uTg{706?re(8_1wm+h0*t}xBe&N z0vZ}xLbr%|V_H=txm1Lq@8t%b z!}6hAuvawtK1!hVP8x~87}yD+9M@)ib7Bc~_H=tn{|-oAV(M}#(uhwH>HHj0{?K|C z7Ap*)>p_1l{C%=H3c&I1tDgx}B)vXKA=Y#G&gYyQm0(EBIM)v#kQt>l6eYCaCzG#< zl3st2xZspe1m=}pD<1p-AK7TaR^E>5705Hv%O3)Sr9SL!fbF0UhaAf~tik5jsG~Yy zEz`)9^WpsT%uL6~No*&C23TiIMylFAqaCxF7}h1^{`4#kwmxin9s<3_Gv@KI%&s#! z&pcTuQ_?ot(RW78>*1r?jhE#^n3}hRAr&Nt5z(vD`Vzl>wA>AfQ_~hsFtE^&=JS$} zlV6o9#U-we?SSncYy-89HU?2-<<)g8Ea}r<11`2X`Rxzi`o%l^e<(Zec&yw1@0X-x zM6$Px%#du#CZnNz**85N5P1JhS@M zfMu!b&xgUm^kLBo8lwmh9O+%SO_4neS~7FWQ=V0%+2AlQDt5<#6l#;3Q$W{XrJTtWT^6FFA_b zb93dONZl2_5DBd447oYjvQFN<*tits1@bYGI}~D|9xE=HXun(=kOOin@sBP&xYew( z48?3>?y34ye3=Sn$+68kEWmf-ta-LiPi!7HnLlSN>=MLAmY^2x=T|R9erLodWOz?c zQV{1mM>6KKI-*)NU5sXI!~_S~>1ymwRUROtmzRE3e(c_Z%k~Ba&V@l`#Til5V?M5h ziUC1pud4!KkXYsX2fTOrmLa_IFIt=(gRJ~68B9DxjT)V_MOf@90d~TkZ3V8~OqZUj z{J3QH$pPoW_+$XYd>1ouH9dzr=Gep@*u?BUMEQ%cx8j3+8GXH9F47Js5}M91<#6%q zHD`u1a+D3l{!aazo?5+VKM(ef10u@4*1qQbuqEAd=j@tmA@Uevl2Z*Wq!jWOAMuwx zYq>M*gR1R)|6$knyGC^?1dHA)0)QzN7c~r$w2{LGiBJp**+xB?O+P{)&-$I4bCxTu zo7nC;Zb+-9k+3l?_EHaYkEJi8R<1ggD*E?%_&#avhlvHh-W7KurP1PS7Fy2l5uJO3 zxl-uv20Gamk2UBamFHJI1IL|p#w-fpty28mzyohOh7-`RwJbMvO;gEyfH`R74hE0` z9YvO2(&5thLp|sw)ro%nSR-+}=fy7Kpmc(zH8I&ci%Yxn?uTj6{))Ifh-J%CA}Cal z3bjAr`DUm$fm0c$o%B-K^GmOq{q>rUAwmoR4aQ+QEEGI-{!jCl{EI&gYEm_~f1-iI z-q|w#4Gy%xq835_(gH_*UzS~!B3s}joAu*_!FteDmfXdcq+}hme{W@cuP{~t1N1$T zl?u;EQN<1~mg2-xU7IM|(+DvoIQd8q`E{_HH+5Jg?;$1?iR@F#4C4neDFa73`!TYk z>-z))NWFhd^Gv+f&%2^GU1Cs$@6|?9(D2o#fd})B1oRj?zms%Rj@;HJKnL0Fak!@> zwOZWO&OKo@g!g8cr}`e4TaxHcCA>E8yzrBTk9{1d)$BP=H!O|!;!CJ0{3GiXY;9O z*^yECPR2owu>{-~Molr>CyexFLCg#H3bySnB$-qq=V;o>TF3LOf(4~DK>Qj;V}E|o z^UU871@gp77jb{DJiOKGV0J_Q;a@akps>Y;CK_SO>CC`HFyu`+?wDmHm7a9@qZn){ zM3kA{rjCiOH=L!!JCVV2l;-@F8VUibAMh=>KXtd%DYpF;!A1HJuob|qzZ;dwEpxb~ z_=iVQhWciq27-I_`f7}{;lq&sQ28_G%*hy@Ps(s@T=!TWt!0f1d~*L~Wy1bB9F*(- zv-IBQS{T3M&(raMCY{%A!w(F&!M%v}BgokJFOMSJb`NE6rCwhOM+-iG`ONWX@3xH* z+0?czS>VJ_WXj>Os^G2ows5H5eHnh?|NH0Ka}(K+K4y5%OoHTp{ur$I^al8AUyc>P zyFF%TIiT9q^7VOL(sr5e`I|8~Fs3j%-mmW?)pgwJi3D-)FT=L_3X2CtP7{H4ErcTS zzF%?HkCv}UOafxH{2vl#Spp8Xqx)6&f&oY8?2Q{`aT)%;3FvwM%Z=(F<2&3!w0v1Zgk!)dZ)c2gPG3!KHz2pWx%$t~$LXge-*ku30`{s?}#PMOut z!5741Fmt!VYR^>eB=RdhhC`!F;*^>5ovsI>mM6g`S+h*3-7fql$nPN$@x8PZWE9kp zc|+ea8_cbcC44X9kpV6=rQ(9;mz4{d$Hk<{qOQygNt(_qZG9INc-SY7f(X6A2{VP} zP{@!vKWUq3Abka#96{Gc7_|%V z*5sMo7c-3<#2n z4`C88f;6gSdXOWURoJR!hbfZmG=Q>e|ak*B@7Ud^=e^U-eje(q^0)c>6F@jO=W zdic>eVvmAC#;`0A%i{Y;E1cp&XGicN|x3mqgz3Fr-1b%{=rk-H* z_-}E;VfU^b9;H6^G!B0amKVx(!J9nGr$*BK8J+;^KW51j$Q7j();A^**TfUPa6~`s z@U=T{%J1LoXGfDePz}fDF$8~2DJ)$XHR0enqt@C9S|)#Nw{c!! zZ_^%@>nF%%J_`>3*v8`fNB20nZ|{|mXJX*SV#Q>7h|tL|F$Wdki%6{6-_6(GeKI%W z*sX7g%fEepwzPlA(b12Y3By++k3ciJm%T@q;%@q0HGZ)o@WF1I8yn>@APBS?*x?-G z!*+bsk7{DbxiggI$Dr34il)6G*}0`B!(^A$>BVrTGafO)p}$1YQ;-w_LQ1BT)*K&L zDE*W))EqJ4`s3a#IWX~dv|w&+nWgO_Av)KYwBYCfg2NB-AZC0YSJHy+W&(JCVtsSC z-kxs7=b*{TxvMaKB30r$-RTd&@VU0i^pvhoblLje3UbUeq?bt<%DT7qcPs9Fe9RW+ zY~LLVh3J15tPZ|;bI;>eZuz&9uG3aK`&Gf9W8`X{Z-Ie2VDvtRLwywfkMq4;OD6vQ zMA5LPO$itpGSX^If6eI^413NuKg~>LxSxdnEgR5FK9)9&=GJcEDx8rk1w zVsH&(+E8wGY9(;%a5&Z!ydH@>l_ISC+d)n3#kI+TcP5Vdz7$R40>!C76qqO>m-3eF zWt%ukF#?lmrP*hipFf3d4;v1q=v$`wv+-))-W7U``SEiLaGtUu*RI2}x6+R2W_}-s zjNbQA$E=Gydshz??rkEI7!r2M3m|9aJN|3-R7RR|>dxQDcX4)CdIDA}5)yRi(nql2 z#MZs_C~VS*xhJkkRu(==0*f9HW-bX`ERwc15w-~MT6=f7;Q9ui!MCZg781dzn+A^6 zC2joN>!Fl<&=4M=m3JL@lO4uy58VuGcvX_abQwIxVM0i$wAU=~ z6+b)zUc9ONrt~;_uYKsE@WsPoSL^(>{nk$ykuphkAwJIIl~AsLrVDj%iSm!aklN-S zqJ)_VQ|&X$>Z?CJa=}LHUknD_?*}3z-~Am>%t|0eN@*&by~PodZI)^9x3DqM@!ga9 z_TD_Bc~N8!v&(6*o#jWfO1l(yT<$$;nnSA2$Jvf>Hnj)SloH>+m#;P96b?I*6L^wY zKPp4k`unbF*IAnvO?ndAv44KHQrW~h<8EcSoWIQc6l43~?W9mMGn@->0_X&tQ*S6E z)_eUI24i8Z-}GAfJ{}~rp(9@f6Z2s^@`Nq-FUYYEh>NQMK=Th9m$+;by)Wm4jM7u1o; z#;FiI)a0$S?Qx8(^xUj6SF*J140l$-C_Z?~I{MbjZEs}|$rB>KpzG4qXz@bR`QoU; zXHr)AAvDIuFe^-%1yc( zKbo35=SLFa{F^p9+$*W%+@`ZK!tMs_H~5kEoQM-FuyT#vC-3%#1hmJ7vo5D-845~(d2z}`|yfz zdN-{R+jNTet?~0EFvB-H{0eao=D8xPS{w?CiZ7>cZjSLx#&|eewoGV*x{qKcV_=A6 zVCDEZ-1&o3sxYMycNz=kQ6)L@mgI7%;DREjf*a8sZjDKe-(=^lnk0$ILu#b=t!T=* z_(u#mUXtR$64+rB#D?CEli*bld8dQh8GIdR)UhMKzr8N#)w|f-z<5mn=42N$3ccXX zC!-Ti6`S^{tK!>4j`Iq&xR;lF9*NZpOYjjB--Bgctpb{TZbV6pL`?FJ#H5&t>J`1Q zeid@;#y2MOBQKyjoKAmUr?KTG4hn&R4w&`PN4`$^MjZdi&%(Q_|8j-;I96xtEOzr8 z>!c!vK|8F&*WhN9JpcEI*&ei$$LjIHMvJ=kT^7}&3vZicYL_Jiz}cJ0e*9q}StBM)~-M7RxU$AN8Buw76<6wWlNdsk;d> z*<#DZ>H9>SfQjk=k_A?>Cz0qg>kqw0mu^sqD5F~wfE0? zDeMjSmTJA@=G4Q;D!66{Rhi>v;^mwJ1PsfSD_!OsN{YY8?X34Ww$?GvRw!xTv%(m1 zdp^o}t|xDRO~`>pQCYUa9=6+cC1BK@V89P~pTv*-;v*3p>w8TVy?bbF%OO_`f1&JmRk!jy3Hg_GQl!Yiz1to$bkh-2%rQRbgmK!XIcDt^rSC zuD-+L*4?CUUoAEo=nqZg#4K{z9LTj!2!=HP;q|PlwcYFr|1vcvs{+Mv{U)7!p~7e3 zw2yea3GWkl_H0b6JFCVSPG966Ba1xK*t<^lU_HHjF=D6Fmzh__Ad`Ob2vIT2tNp%;rdEGSazbK^t{EVc zU{H^Lxur1%)7W|o6Nj1Tb<96H!8>#&Mb=+8nVZlUc`Y!_#ov7c2e+b39VT}J?e|fp z98)7PtxB)AdAMWiaA=E0*P}JPupFCmU0_`loL5lxLfO2vTfqh;$ag$V^yoQiRpC^r zS(^_7SP8Q;r|^On;83#6Z8o{vOgR3y;Ji!Bjpmbt0W5Y_Pc0i-0Mrs|iS+h>&VdAg zA=9|Xo`1cXU(7k}_Sa8}mj>~W6>=+pQyTAk21()yG#mhy@#}!P-H=4khb>1$a2IA) z6Z@9N-+##Au3Mp&>ks)~&%9Qf6qZl_R5o~({;IqqOmDbER0tW(gF*ztVy_9ff@_-( z0AFM4Fu^)Hm^Xj1Y&RZxuI-x z)!3z5#R+k1v;P#Fl+9*zhcmQ-d2I*{yw1B83NeW)ReH_|8|3*NyKW*Zp5^LZ*m4)} z5zZ|L(RL^3%SknoGjRFkPrz=pPA@1!g>=%j5P{Gv`Nq+g3)$9RQ5hC9$Sf3_uPy?7 z5tr@Coj4D3td;n`k6u=6Xo8#9CXtBOBm8E{{=@ z17oNCJK!C=P#OYj7m{zll#)b$OGU2W>mkvr4j%EVQqxIP6>q>>-ty3WnEqFpEga#F zjuQsK1G@=ASPX$M_6Q7nez=pK?VR(Uug}Am(z@1i_Cxj?TF~@>Wex60xW~TJg1kPa-iXpL2uDYKI#ny%t8b$ zey#P#!EL8aF2DZi+@6fXb7Q#2Tw%{6glBl&iZc9zmRt*G6rR-Yay9!t`m{vzQUCDG ziNWqgGWs(h=5g48xlHR|#J-n!EFGL5p~+-sd(>L-=K(yCgQKYVCJ312l=t9!k%8EA z(M?c(LX(WX_Cj68_iC>$XzhR*2gjny@?;~_BV*G4J< z0u$FE5li7Ho7@6*KEMO;bv}3XS-`-A%#>=d9T{&34Pi<{eO1SIz`9j12{Os`l($~l zB1mLLBNB{DA4Yc+N`5HZ}%XP)_X zjTN^#NmCAQVL1Z6fIvUug4yA^Nu#>Zl)u(pVBj!E%YIUxMo3AOWW^!aJ}*W0-75a; ztA#DA?D6+jCbpnTIe(C$5S?E>*V|rS z4R{p%G64o!<44z74Kd0+D3l*FjGZnL_*TWwX~2UIe=wixU(U~#y&EQz6jf_&%4Vegw; za%1bNc5OpEs5jnFPuIM)I>^qCzVywPdbB0%h}R*r<6JI8Jv3xHq27dz*BO9UJmDGj zyO|!mcRb`(cL-jyrskz1+9~X;Qde((b_ns1ybT|Zu)Tb`s6GRtAaHr`kW^$VhUW@( zLhj*49bX%42!LjlwWBa?2zoB-ybEonBUTmwRutZz16or0f53e~!J^I&_T}tzo=UK4 zK_M3?AOdnk>@g^SQec{#tLOJNW?VqonvUGsJ6u?FD2zaq0!U|Jr~Ag{L5Ay)ocUyS z=Bw7B`l*sDUIEgEztL3#2P9(h>FKNSYvU%;kPi$^Wa?llvhnnB7lB_Fz|*+`ncXfF zDta|B2y!+99jE!ltu_9VwZ4mtizme#qmGs40F5JDF|=2x{-WweTp-srT^D=_UFnoa#q9UHaL{p3nZ`t6qwk#8JAd z)cJ?U+k-*>EtB90ixRYi)w>e%_}Pg))tnR|9E(F$h##xOv=PzYO%T@Er;r!3R2fe3 znGeUGV5&z0)v3N%e`%SnW|~T#xf0d7SozRwb&{ZIpnoz6)r|M%IBP55GCo|_pMbOo z!9euD$vMt|x_@dQA*Yq-$aKHx7{83}^uyC0sZ>$$_om4$r>&OnMj1_w?c|~%o zx^oLJ>xKNDwiQK+Sp#9AIaJ1vj$5B#MfScE_+4WD89u@qJ!1lEuqEsqPjqRt{?C(988T|Z87LxKCr&L|Z;q!}{Y>Pu4H7V`Jx5c}E&nq1eYYBG z#gmT~SRe#Xxr_T%-oo`eMR0B4&Thi!j)M3}3Phq*D{<`2{&4M0#nRPRq4Xaf5z^(x z%pRp5T<;FQ#R+%a!h_IJEtE~{8%V$(1Lr^%=M&z z&(?aHb1~LU=VpAasiX{fgZueXVtr+omLRVn;@V&s;fP>pc58yK#jc zCOikit;6(~1IUA~9k@a7U<~R)HlYj7hY9aJL7~44-IL>zBlvpU0aBsiy-olw~Oz_q=RuuUs;qAX1~Aq(Z#Ox#j>OOZCdRE z#{tVYmHn~e)w^AOZ%nry>o z$)XS#%dO3v5{%r>Ds`H>%|mypsxA*Eg^R29r%_#{d82w6IUGFY)U!2LUkB`=o=6!Hszt;j_+-ZNw zXfQ8GTbOwpbnGVfO)gtZlBCKVP9p>CFX5HaqqdVWi!G}9vL#m>-{!~4)R`H%GdFZt z9fdpf{dbR~-KaR>c+u0$)I>pP`Y1!?bKZfXoG`&6Har%VhTIM@7G%A7`H_{qc4S>r z)dT2R)s>|mj00V?91x{U&tGc(`AZ83CAi1J-QMu#Ncq>A!wyQ92yU!|Yl&KP(E5pQ+`CLo$vc$Z>R zEN@|a)qpJTMtV`gatw@+F7l6PzI!KfEMDZkyF?oG2!|<=7$>4Wsu&5o&~g+iDwli=UCX**8x6vZdQ@sgo6#9|fg`KVkQPQlJ>2K_K~Y_mhc6eU;zLowLkO-V-Tmh)h$8 zPKB=&^%w-sO04s*C*)dGmBnKm_Os;M<&1t`zvWRoq40z&Mb6HVGhIId`j7 zC`P{h>VNb5nBfFze?aJEQE}ZPFG*cQH}5tXi@_*TUD$xTwr4LG2r_ue3P%MtN5goR zU+Kz>nb!~2L`dhRDYa;a?r+xPseO%9`dD$|Gf53Y1Rhr zE%%%-y}TG`@*hgkCy&2Gk}B^%(6&o+OVi7vIo^e3*s)xC$1ja09UAixfM8R&WS)Pw z%*Nz=uh4__;rZ0xPUG=?Z(f${hbM4`r#2BInKEw6RiTNaL*w}tS+X0E z@G%9e&G@|ftAYWtQ_X!6g+fC6z@(~)F}uzbWyH99>~Sru!F~l5YCA%Qhp*lrBq{zoL3}QfbI8@#jkTiah7eGB$G;N;1cCIb{Q02wxJo&K~sFfib*u&1Pq3Y z#~$P1YCm|)iq{-N1dAddOiRFU_SduQ+`Ho3_45|%y)FS6DyQ=Kf%dgqlP8pw=Xgn~ zc2SA7)A&cd8Ou^25CB+p&-O6GU+BW%#*EM7(o0Xlp@mKV8r(nuj#C#;GBNa@c$$e{jyFdNL)b3q~Dtj9076%Q<2xdTmI z6ig5houms4GRel-VR~+8*=E?$Ee)YSlZhjnS6njLPyHFb`Tb*t+R}Xwcjcq-TkbJD zFAvij1QAhXSl{DXtJXIx-TGGq3(5>GIdcP}9#xS^X`HT(s4MpToOF~S0(5#95sf1N z9xGgvw1)7~6wR~2&PIdqrs#778^F6zC@Q^(Jobu+jNzc%r3Yk7Jq9rPI0jY|U=sY; zd|EsC_2LER_J>u=Fag}50n1c}G0%bwmDw10H9)ajVvr0 zoNCD=nou&69R!Y43_;RG_r&#-4}VsWw`Jwh0b-RCXRGDf#&M22VP=b5!abq4D*#ku zD)%_&(47j-YdkQ}UnkGyR0H!wAJAm;`B8z~ecQsnI2B=o0O<+VJV2mUzk;nhjRal= zUII7;#}s7M$a(MaJ(x?G8}v08&=vi~XbaVI=|Q+52w3>q(gIodP`X+M7c+vv4Zw@E zgwUx-^Drsy(nFCZS_#mt<}3cL-GAK3Fe7}u>Wmh57{!HKJ{yYcpG5NATFF4w>UNiAd=#M8eAp088cDM{NJ+*Y|Lr%7mkxvPTUCBGgv$iu4koa-R#H$Nl>K zL}S_1Dm=mxv|i5>7B=*&+=Zp|&|$b@*k492weW1jHESN{Dqm-30O^GBlg8-aY4Y6~ zTI%rNM|@j=aNypc!F6}n*d;EzVMK?5UcUh+OW&9c16EkKyJkf!`TJG(%-o!kf6un` zs6AM{X7{y3nWG*H2R1%Y?#fVG*wJY9K&=OD$hG0>PhfFCkIVCmW&1~^?Y_;2#U&^x zGaq2dL$U$fc3tbCEOLW}fle0z$G>g@YX`jjHFZ4B%Kj3fEOu?6tO$z4ZN07q6(U+; zC+6!XGS9(ipr^tv*(o*6G~hX(ld)m&8ipl>*LiCKFLN!ND2E!6;ZU4f?x zx+@3x><3kK5v8y^w!3cLW5d%F+n>Xt$EhkQA9ry#a!VWw1K8Wwi_jW2#x)u^C=5An zS=jF@ZFO>F@{M5`SN`ebJfV}5eA<@Z24u(@V@2VgKo8^DCi!t0^RvZjTjGh89Gwx@ z7~st%H`{lox6J(-Dpb;Mvqd`YF#`b9c|ln9-jkR}31>PyZuO$_LkMBOj1Hz7hV$z< z!fRk!SwN1&drv!o0dgEo`1n3_kJ*ocvu#rqm@}~05kH6PCFQ=zAtdb!)dyz>#_dqo zW0kVcv+Y^^gaducv{N=)4*BGhhBM59N6{~?^9QZd78V;_9lV7so-^zNR}$?|A$1@6 zri*Ta);t@d`@IjNWq5`vwrCMdFRY8CKA>s>VCJ|97*(^Egtb4eHI40jD0%M55ziNn zhwh9D#4qf)`Xp1@5Fj&@1h+Si2OoW>Q~TZeSjLWdQKfY_z+HE{)!uS#c`jN0uMMGdeHyE^G0vka*6KX zM8UUL{e>KNA}N6V32KmymyNSu+AhD-lttJAb<{9oKA(Lk=my(mMaz}~G; z$i~~C(#0uJz&PKHgX@mtck69wJHRz_N^}9@`;W&DaQeVHhv6~C*aNlqV@w-?cktZ@ zfjJ_rTQmZ$`xP9`=@Flx?=HiM%7*M)ey-#>)5z-W#aV>C=USHpT1)oM@(%6=Zs-H% z94lIZ7;kyARHI0Tm$zXSUoym}4o)_Z49s$)N z3Ioc171+T2msOAYNkxSmgSa1%?@S?bsupLkhbbK9Jz+G{Sujx0;3m8^LYr**1!w0m zuDnr0tOT2i95PYj=Wwc5XTr3>cow(O5CwCUxeZi{xI4lJx5f<{8i8n&J!{ePYKec639mTQ zJkZEi@_@2_S&~EuC%gqaXZV#1IR+W%AHsO3{^&ajQ_f0s0&Y1J5c~paCJH^&B2Rk% zp7u_cGJKv=|1n_5qZo2Fm1~17iIk5b%|LN60a!UHNJ?Y@*459cXVf-}+cZf$s#H{N zeb=`8Lee`z;(I0+9%RIT%7NwC1Ha_sa;s=^C}4a#wkNoXO$g4Rq&Hx0A-YL4)-4fB z=jk>{Y!*n4Sr?2fy-Z?2&So^#uDmx?R_7{E4o-Aa8QlKhpB;}?in2^ z;}U7D>7O6{-BIKc@SYgT?e#f!%4a_ufgye!p#*7Rkw=njl2knJ8C=FSe3N8mB$;lz z&-gP8s4)^+++tA9L8+VXMn*#5s-?&m;8dr3z_XH+k_(Ur>7$NP(jF%+QP6tiDvkN< z`5I9CxL6&KW1kdk!L&l>_Iev_0IH9GqLu@nZtt+GG?%;&Lz}$O2BH*lc01z#637yi z!?dhJ`j9$Wwx_4&v3h+~z@!bV#7n&pU21-$KmaLoPH+;!IEf%?U&R|FZOA>HHQvzG z5J>K=RaDVjaaIIBkVB_8*)B&DZ6u+CA)HN6kj{QQslbQm2qu;_VvI}u^xpb3@*z#4 z!&8wkVd@ag?uV85rJk?{@#-))9L1zZ?fl72o{%qC*X9jn)T z^SxrxfG3XzAVjShm>w(i^Ic9h!?Ytue<$l?(Ckmg}+LwLdR%3GXgW?x` zwceZ$%BUZEWGZVH&$RJ3VdtBuESw7{?A3h zk=!HA?UCvng*+vCNts?|&5hkolh5D3a*{G^E|BbdCQuj@EK48-K!0k#fX^^X3avX2 zS!k2@b#;Q3!=H)>Pyu6aq`TCs&UT}}mL(X|-~CTm_B&OaV}C>Gd@jG~MvFd2WPKDl zU{FG1-A}9wpK5(~I2I1>hl{wIqpOro%Qwd-+xy@C2_Ovkq|p(qZiWma62aG}3J?(y zyDk)b0gmS8pJ55J3wUaJkUK)D1c#ua7I^Ve2BFFr1H*;Vs#dKpx%A-!7X{9?YI}gptUuxv{gPrvxt`<{5Fbk$?&{|!U0*M)j_pnGL z_|Wu$5zpoeE>g$a{R`nhxp_!hzNlQA6fvi)ZR8aV&m{YReCSU2rtz=jDn$q70K^i>V7e_dXR2r38X z>^6TN?`y&&q#)|=3|?z!@pK^=^R+yt1&aYDU&zoFGs$UhaUYKHmUGOqy;(b$OF7m( z!O6vbXY^$85MOGTrpxI{Tz7gy_V-k)Fy}}}F9@+(igCRs`zL%WzTnocAG_fb^ku+| zm$+lMW<3NLIQZhNhgensN#kRIJxte6OQiF_L?UFR{edlP0(CqFH&0o0%z>*e&L!tI zROB08ZBWA!isoM0mMeFEc#>ANlW!LxjkqT)xJ&ek>TY@b6xf(pQkvNCw~^3V<-Uo} zGH4FH%8e?ly5MzDx%xNoA{%m_!?#n?3U9pf1V~Qkofqm=l&))CU~f5xx3?fk#5B?< z_3ySf(?kB>yB!G-2(`8Jf~C9;PrfaF5gOSO^bwyIfINxJ$FAQ0?r`#Oe#8n~{A^1P z>RRreUu>BMmRcOCjq5mt0V)4u1%NkcaXh7;a*&uUEL_ z(19+d<3lwOohM`;m^BlMOk9-=VjiO1Rzg4!5=SyU13w92cxR{pGH-fBNCnF)hOBEi z57|nQV4g&6rlXb`J3#>AFZr#cM+Vj_7-1rQ=t1V5S)XJMGB+3%b#_hY7>k(2dW}wq z8>SZAyC4T5ly&k65w%(nVFG%K$Az*L9#^voVR$x0#&bhFteI2} zf<{VnOft1f|Hen|X%N#gIk@-!woF5vHBE)|al1;vq`)Pppg`~YNe>M*;hlRoHc#d=&hw!%*59@LY~6zZ4u-bHZF+=g(c9$|{!cVb$b3l^Q5p-jUHIoV zv_h41>*K3W4sT~Gls0rLavq$-m5jk*y@h&t#c}l>O6JoWl1UQ17F@mvq!=780qgpB_%hlVJif*xnU#Wi}p92Dpv(Br!yvWom68UELoft>H$w#G;)BL|d>`QV+W zw*zhxL*UbMbHFe5>2q>LQ178!E4WSoZQN>-$kX^yN>TpSn6QW29n)Q~--9~`d?$ni z(DOm2$M$g_C}nuwl>SzC%?7aPSfW}7Kdx{*AU1&cq$YO}INgrj0_3x{G5s(p84*@Y z8LMU6RLu&&R+ND21xnhPP*CZv&S(qUYLhC4xJApxn&-8 zqsfZxl9vi;N{U|GNH?I?C5jN1V9ba7oPoo~DawN|S)RD&W!8j=$KWO4UE3VoTDiB* zK$PTESFPtvS|G=CCVjwplu3G6WDrEN9P}U!?ktOA-4}ehE{HOLYUQYa&R|*irsbs{ z<1P=<`a?fN5E0u>G(|oo_L1g1!FWH>b7R$uei(!B=Eb*mH}4ANb-aAl*6T9P`BT-M zryM2pLj+S*>n9ey=H5LG)d#l)>|^u$P_hqTzu+~;zN`AePcrp!60^S7WC3QO)uVBP zBg}{*u?X|y;bp&W2SA}lr}Bw?5mm>GN?jnligg0hYfIn7Yl0vNFkY3{xQ@DW1dB&I zzO3Y6;KnsUYC%7s(&2gU6QYdV6UFSz09j=3mx_3oUwD5$^n#F_OW0ysrqlNkD5sEH z&&eBSp4&Mu50GzBle-kZZGkyZDy z`LWU2rLeWEGwdU`u{weDzk$dmfTRlz*$bNC2Mv)s zb_kY5-ETDJF52d+Oc*6OHqbkb`qQc|u8c3f>NimpQ3!X>2o;YiDk?hm;ZwD5hUz_w zlMZf^0cZ~o+~8S61~68H zuOBND(zb+1g9Dimhdo>J1uhV*~FG*`yje80`{wX-v^3o zdENZAApciqcNpwtOB^dQdoA-#L9=K(V0QQYWGTb|#E>-x6ZM|cs|%oNKkW0g%?ix< z6TC^%phrtoVM=Hj3w>W$zZ;3@-iRRTJ-Y!-XDEsaCfliF8{eWRKBOYuT==m4%M^E_ zEe9(0kp~yT9sCc~%Tjz2N&`bPw`XW+nB7^S9fS$iic;>YHz5i++WS|(cg!iTF{^I2mTwMcw5{GUm@dx>UD0>L*3)63?~g&ka%J>2qxCw9 zpYG7!h34G*^`zch-@fR=k*oN%^l!!#&@L$DzSjWd#duBZyrP6M3S$;z{rxqtzc6vB z;an1A(?X!$;h8gzkz)IIi-Z$P%%g;R6JY2Mp9yDm$fRRYcHpY67`#3nY6)fs8}R^o z`cAlL1uFR^Jk|3-`PEs*esVSqdb`Odb{iL4E!sjzCVr`rMe$e(#(EqzjmVU_wO`lx zL&LRd|7(1j_L3w)7PMBrX`eXts47*xvV&iM{>_lr@4H1~@=K5xJl{Fe>kS`c?(PNur_X~zH$$SY z@~sR&8}%6nEIzZK_H#7X@^?tYfIS@h_KwSNwg!!q8qlvrLli}@Qm8fFBdx~o71sAG?3t;2 zhH;U-fX)v?HKiDFeQx65XD_GWuIMd>>Al4H0CMGIPyohLXc=Q9tB`)=e457P-I?EtaQ$;Oe#uor)^3U;b>=a6Ls(R0=auKs3hDiwa&BWB%Ft{Hxmd1usObm5GFW@2fx#E&Ay1G; z=;*C`F)$qP56Sd+*C8L?JXw2@(Jkr{uC{iBGdhM0+$Q-t+2;JyoF3! z%kp#URGQRQIJLUjNf1R}t;4K~Y=?dP*;y^m3jDb{^bU6(fG3@i)~ggOkMbnjZ>|E&q;*St;T zjwizGUh#majJoJ+0??2{>Y|*9+=$;+M&gjHQidVT-n+2k#M!bJ#@kFICugBl&X%#e zOBCF$P-;K^7@7dKpt~_(Mr1EE3hQe(pHhGE>t{=y)Hf+=BpAV>IQ}nY=>g`PnC#)u zzP7>5!QSw}e30z+-_AHc1+5TAIN}%EuqDHk|86|0O!o@@Zh)aF8WtgM28xUA=q~8Q z#u^*b8AQ$R^oQK{MCBo!FrO4!io)_5D_%9!T9957}? z9-)VE=^1x`wYxLNLRcnR6E%-vpoNJap_1Q{!4z&BxKKupiPPo3C7>lA>O5iQ(sfn< ziIgMvL+>K4Ha`gTN?o3!=C{2W4(>hKm3N2O_e;$*+m?F%rSEb{|r zMect<;q_?I=yw7!0_DD)22=Vzd_>k(oyt@>v zK_Pc`?IDsfEOr6UkZ=$Rk|(7Xt;1Y$_?>k;ZDZb5gHHnZ9)%zcdKAqQW2dRMLqoP= zE78V!RB=o=4ht{EiLxz_-Hm|N;Nj)K8NBg#uxwYek(+W#&R1Lk7C38c;pLHMm@sNv}q^+|M1X%#N@Z*xu zi@_crGU}-rgy{voi|ScqJj5#Nl&Y0rm7=u(IUI1E=jcE5;jrJtpZ!Sgfd^9n@oRQA ztZzAt@Y_Z-QL9RAf$41!k7${l-=6OJmc*bbZwyKadJJP8iF?WXDUz3i1a5wKBck;d zDD-%)C18!pp}Iif-(-gBzJt_ZvAp(1ux&j5;XmfpXr|>$M8;R&{h$O_;S7oj0m$3OWeq#Nv!0qJExG!Gw2R%kce@)iU_Dp_cB762XNAm>XwyzP( z@bG+=f$q(XPu;$jT|FY`kIvB8M!OJlb;D;55V8g!%zkEK+Fa1nG3#CICl>}vQT zz!~`He2Sm+>RG$f_E)_mUp(>GMZ=Z@{5C;**{h{m$6XH4lD-5dF@wkmILjS-x!mH5 zZMTmfCUe-%DlJ<(-(Nn_*qIq^aR>!$(v5v@*4@i;3#dw1(T}-j{>wjyWe)pMbkfx3 zcC^0AxYEjViivO0h0~wT({67vER!`PT*&DO8m(?o5|irJOzQ32nuEtAOKC`;^sB~p zhm-VOu!Y615q^L>RvkMYnPkk~;mtgl>PWIOoymd9h!$gLMrJyw0Y803sK+lAOOW1L zaBR)NC&a?GD#K5>SFc}ByA|qHuH<^H6<&54PNffZ*VDb9LG8H{)Byr-BH&|+aUh)v z=@bD?6C;qT6!jcA&VVQ`(ESNyDIj5o^J!mndyn6}5acVY?gjwSEmnLtge~~dNhAqS zl_a4Q`4a8e+zT>is7E0ZG%$C?zlwLT+o^XpER5!Lf9XA{dO<@nT^H_ZY(PP#?5Ps5YOlTk~;$Wq5PFT~2gmFB*7)sR2@gXIi8TvDGdy zz&`G(p|g-j(y(k;+(6z5DxIQ&WBJ{>kEU7P(ji5JO;tCa*+Mcg*wPyQKWu6EG*y1^ z)9FrwNSj4Ueb7XBBupDE7oDU?xSs*M$fOs99sJDDp2MH;c0n2(+(`>#5LD-LGb@8S z41q4;CJ+jHKHq2S-J@Fo%yDs(S3Xtgfi&>ipaA7yFWr`J)X-y|W8kO=W9x0@0+4x! z9nOR1DmEJ)76~QFisyNXB$l%Nd$s0oBi~NE5&vnmR_tFg2Kaj2WgoRKUY}qhzhL=u z%%78VWX;+Z$ty%EQH(L#PoNm%#0>vk5hyC0M@Z9X{WgM9FW|ao24J^V`1eveNr@Hy zm#!B^oJww)$DwnLvjDicXx)jPc^QP8yzqqlpbqtc)xm}gH-U(A>XInsx-KMR@_{Lp z62VI;l6Fk8BZ(wC>%jio+L>*MAi*6H%P|uSv91?sKtYt2e;%xkAt>Yf-)fyYRs5*E zx|>1NLOm~{#9!^pXBb_Gv%E6*trK?p{QhvHr9a{LxX!WK-KRPwQKE;UYsvW&%>66v zpaPTUG_n^*#gqRIchE$#aR!CJ*VFM1BO}L{bsd&+C?^~LepI3EU%RJzr4-6E%RA;% zJsJhDpJ~z^QkWaZu{R;o+JB!3#Yt^40vJOWb&Qt+#Jvt^wJpaiHofk!jWf2t#(Y4t zW;*&bf@WB!DTe-d!jeG@erw*$-uxJ66Yb`Fv=k!;4AWR~)2=s;S!~1zsb==)@5xR{ z>%lZ9CYger0HAkC0hEKrhq$Nr`ce6$oY0twzhhJsS%G?YdjE1MbRkqcU$Y)IFp?L4 zjaQ3~jW_B#iZHP3ya`jPuz>}=p7fga<~x!0>bq$}VhVI>K~l6xNE)v+;jE-UL-D;% z7VR1zU32~AYYq?h!+@hc<8<)-T*(OcEp$)=7Y!CafxqEO8Rsm@c%W^Tp_T|N z^}fermfmVi;e|=&usyHMOjnxTnVJl@O1C-Tf%Rv7uTs6(E+c4#UKCtqz||-XSO659 z#2n5NsLN=hh6-MRVw`iKJ-v)R(Asy3I))ir6wjPgYgOY!wFE{P$gs3wl6v6^R^dE)kT7S{U9QN7|@211@m4qE!H+2zqzt1BKGYY#rYo%sW-{L;O zn7Kc0h3K{X!2#L>5YhwgV4NS&4D;W*Zp#P3$cK(3jKPMxcI`zW{IPg-3|_$al35U| zC}TH&L1BZ0=`8#ZK8$nFq7{;3?B8u{r8XbHGt~t3$6STvQ{oP0;&k|bggjyH0)_xA z6#4^{P>kd&2`Bnag94s4-dAp|Ym_aX?DOGVmN1^_r>0mJM#nCIWnUW_4H zjW-XAgbju&NRM}n3vMD{Qtzv1jmyJ{{1YQO%-r6dLyKo*#MS9!=Q}eqalQdOIeQZP z8mcB$>msTyv`e;kp9FoPwU03Iz-n7PoB>I@Vi#U04xq|RB~A@|)#YPso9#`oy2RacY^0fQyt68|~v%dN(P8%>T%mMY)egnb@G zxd#QYCl&b7L|g*F>1p5`3;c}js&@3x@h6K{)C+-wqni2M+=uYM? zyuD|~RtPavl#J&XbQyXJPT(df*TLN69-O8`sLk+CJqdIJYIA<`Hy+Z@Em!8UUog;G z3GEvkyRlG`x%BMk+e7|+sS3V*VyR%xN@4Q)THXD|{iADt6EQ)+5enTW8#M1Q?Ji82 ze?0h7M|J96pRK~9dT|$hd$A`=Z%j=kO&eq-V7fn|uXAID*JI^XFUjKMz=Pw*=VK?2 zdi`n0G%;k>FL_EDsluTHDcJ4bH!VNjUEdT)pNZ9d!J!0CJ+{0Z;hc4!Re z1a)>U)2nzN>7TabJtPFfRPguRl?>FP~^ z%jQzZ4T(0|OYsgBYkeUsB|G8In`T(kIjf9I@RS<5RS7<&mS&z5rrqR!jxQ9CPXzNM z2NB$@`rHy~o*8&@|GoZemC~j~#ZLD(SI0y|Zwz}G6kl4ak9IvIQYUu~C49409}|YH zmZvu-H$;4ouS@QKQgA(kytWn+t}jYWQ?n;~9j7sD{+?avIOJ$_u)?uY%Ib;eNa#x7 zMY;nQ5tQO_Z~dAxs;~sFn5D&_t&roL4_4sQtPSRld(h%lB#=)XmAPJlIIh6YyJ%G0 zvh{N!)#n&>4VqMMv_ASlr6YM+yR7+J2J0_%e?9k|OMWUI5KNz&5LlH*O9py5Q2i-e z%%A0{to5-d0rR)2Yt%X9Hry#jvoz6XMI#iqpZVB@hH|4eAHSuE4q1x?(#5j!U9duT zS9t=8XR#skvdI$oMNBEP+`$~Fhjf*V)}P1p!2lkNq^^{^w+aRLo!8wy-btigw%(#@ z)J5(u7OIO3DU=*vw{<4rJxWG7IQ(MYz0Lbl^d^DiWt43RY~A&=KYR5}E3Sm?rtO3k z<^icQ;J@@1>t?3lllf8@?I@&b9P1u0XSJ3T^bocL)T1z~rR`X0L_^ z&GQvEzK3y7)Q3vY)=}#lv7-R{B==#DZsTC?tNGa?{$5Dzy5i5b-mAVyw2f^3Am@i#H%qB+KW?WsBi zJ8$OJ^ih|w*r{VS38>eQ24t+?*c<*s+u<>CLMS>WYa&(+lvYp9bukU{k6hp~zaw4z zpEeZyI@2%ik#B3qbw3yqY9H%bl=;K~`#WTxLg`Q*Z^d?wW-41t;~5gNjBtWrm-pY# z#r|`Y_^NDIJC(a~KZh-0H6(?dGm(Kt1+?AZH_xI*+SP~^j+~zGFf|lgu&eb#vuz|7 z+UH1V^S^xee$0-YI7)AxW;_|HPlu z9J|}LA9@IG%YB=F&qNSHtbzDtgpvOcmt_c7GN|7el$4eGT@1B3mJUS&+Bec_{6=#4EE8W+_j?hBMY4$aTYGHKw^A{w8{P$ z$&&BUsYWXV+utJI9dp&j3(HMKOjE%4rVG6^^-|EOL+b&(1$?rp5D1h3hVgzpF}9|2 zcPpDepZEbyfQ=L&E6lSnJ`UQwPzoQ9H(D&BTt+P$%5^A3|LTt;#LQxHww{~ZS!k!u z;xJH>`sU&)jMi5ioc#pa$fYYDoeRDz__wHfNX*JL1s_up#8K9Ogdfjk1IvI!82JIw& z9XJwC5K?Hz>j(mw2rGE~*5(qq0!GG--XCYmtXJJn|i60|I3X7n$76$S%XvH zlXF1YefxNz!C0asBDscMm(JDcLF$7zaUzhsoqfSvX3795zrE;H@WP!>rGj`lFDy=+ zyR67QlP6Qb`H7&`Y>iF20xwl3H_Yq}%mJ@`T|6-2pqCmbbI0}h!Akc#N1{Ul? zLjucU7V4C7jyP=MORX9TUU;I_u${j9YUpQdIXqK%9MV2UVsAF{$D#{a^j zV5m=JqSI}0oL%;MtenUzap{3tuqJI4gngi>E5T^Af7k#PSHyG?m{oB}ZTX_`RU=th z&c34%CUfU%rrhi_C{82&oREJY`%V>t)tDd5Dqk&3u-X-95;reA#IOiP{iAca6qcO# zntQoGA{|a1pWdyegP+5Y{22qp=k$=LyjgQPl=4Wc^^lIS_OYpe$`)|8{%(q9WnN>X z2-#|)Q68N&rIIbE!4X{%n2YNZ#O~75f@@YciVFAz(xV$bV>9a^q6I65b_O}LnpV#; zANDX`L~kNo{aQ=Gw?T^1;i+2JhX}@=Tu#2Jpl20;2->1z1_})Fq>+>C z38%4w^3Xi)HG4)bM1QDOKfUlf@GfE|f|)Y|0SVsOCz(F2ax3CfKo|lrM^o>}b2lr5fvHv`o@_xur4d8gV zp_+YGc{8gXxKWw-&dQGna%54mNIkzKWAa#I9ER}lwpbDz*hX@rlMzQgGF6k&!!*VW zy|T%EyBz?(0>tWx=@KLV`R02Qz90(R+!DJ;Jm4?;?KFJNc+X`u$HN{Z0O>ha*IE8R zIVHRZ!B_>TWF*q)i(uBzsb@D@HDXw}kLHE^B&1g2jso~Np&DRR<+z9Q&>VMac2?T+ zku1eC(a@^4qA9^S=%=E8bZ>TR+JLbU0k7?s7=LhQ2!@p-%b-gh_LUg~haC(r zPJNpo`a@ubbVB;*v*6cWdg%D4BFm%L0Jr|Et*2NO7Rnf3L`T)0xXhXgEk$LHX);`6 z)P|&R7*1K{F>Oag>qm)i4jcWHQnI@Ju1>vs8iW3LT&$!&ZH>_%DK9`Fa3A>CX*9>C z+Sh0iFEvvYmi&t=FM8&ok`*HYU*FNMU$b1li9PwdjKE&hIZ9AOKGJ|?L(@JG&HN8x z#L1Tz0A~9z`xe{%_Iu(9*(|nVZD<*8|Z>W zB2o&CI_`MHy!pyjDu|P)-!uw7TXa>yD=88RBwx94v)-M2lcFI90>$2&9U?9X*tY!J z^qD#tL#0Vjn}CZ;3dcH9P@1kI`%10e2DDx>?F6W+8UnkAg0Klq{FgAJavnv#TY;P_ z$#X7;&zu&4om#-TPmdct2S{BCm1E6)P?W({%^Yo6KNJ0h^(k3)1a= zgZond#w&41V6%&JwXzyV3ihN*&9oQpjTX(;eJ=vHDSuRD36ubIpZS302ONtaEWMHn zA426ct31s14dDC+ZL}sIV=|7sGCpf?EpzW8F+k;MWsDU8Q)@T4?@9z29M)-~Mvq9I zK-8!Oj&k7r*|D5ZRn`TyXxF|QMAKM#At(sOp$^Te4?EJ)G5C}Mn^Kc4POGVtr%5dN&&VuGMB2H84RbDvA zR_+Ql!S4&`0eJ?;`_c5u&!8aI5EIwq*{4Y&c?3-evGjfKiYpw^agKj}gK%1e@I2h! z+}dO)|HMtC3-h=+)i4=J53$+H^uhs-fP^w|MHUY31>;89_>u=X4pHrQl2gm-|b1cT3Xe1V$#?<%QM-<+a6mj^W90Q4XQG}jrTMFv;pgBVB76``#UY3Hm;W2HuDjpQo`QVkQjmWto~DctdJDi%n2vOu%gco<=N=S z*ka!pl%(KDvpjGS(G6V>_TtO~p^@@gbgTvj+r(Ep1)a$|P^>&#Wj!%4vLgMa2+>c& z{CiH{@%#sX8EHf;pik(y^Xz}5Yjh^N8Q%H|z8ljgzcsF8#6$XzdsI%)5!W{UJTY_q zBQ*=p?N|zrMoV!?jmaKiDLg4l3iBr!6HsAN%8Sul(T8kQ>|9Au*{<=a=WLoyS^L(# zdkfYF7$l->SL%ew6f!f+GKlC5dCEf05?Grky@y~eoK@$mgNwPddi>7!8@Cb)D~6sf zKTUNSv1&XRb!d*FHV#su4r3wPkaA>jk5kN$_0ot_N5zXn5`z!l2eGf-y`=ZKhu5*} z3qScAMAA&FTzgDs*(XoBWy|!n&fuG zEKnyB5FUuos~MVSxoK(`wV0t#FN-77&AXnT6XgzU7k)d^zT1jF_kFSIhs5D$n{{ME zF#U}(^zS);h)L|pa@*mzN3)x`gHyp0J+heIsiNP*a-zy?$mH{>hIL>y9 z?DYf+lnBSuIr80n$YO4 z0ydoQTEisPL#|4W+Ajgg>T#JyF5M~2B?hw1Cj}l)HP?)?)bQY|Fz=;gC6>`1$ca$^ zAd0jU5SepIBm;A>kqLl(WeGbuCxLmG{|&8Tdp8VV(7`NAB{MvI6|RpILcLbG1;>UFzW~mDlDVa z7Q8;85yHNcAb8c7dKj5{kece*Ezx5bqsBBEOBlvrs_?&;LUj?iDSr*^pH_$t?Rc+2x`(obzbQM>FUz1U4oV_KlC zLFloA0F?HRUCOV@Sj#ql5%2@sCwW z+@Q;sKDg3k27#chdJ4{yPZKJH z5j?-NP+ONRMZTf;qNVN{>|9G!LWC+hTG4V}pX6j`5KsRGN7Dk+*-WfB*t<1FM3XSCiz7_6Px@{wspt0{sf09~8HTqTLH6Yz4D3`TYP6>;e|`I;dtnrkNV07( zO(KGUPIG%CBDvdl>^A!|e~W#+E$#|ycv}#IIchg;avEXVZAr%3c+J=J`EgP@9qI6V zv&zaS?Q(6}EKJ72(9B(b?Z#tzr~b%3d0mjDajG;meX;F%-qdpxQEV_38(454@T%#g zz9T8Jo{nPP_ld+a3|A)tDAl9&DYS#e(Cid9~&CgCMWK~(i^Lg0Y zSbNz&xleQ=`l_kc)Mcp3dwq5w_-XgY$B{c)HV-^_-Z-m&F@MsddBv$ zTRT^$lT)E!gZ=LJY177ZnDpB@jvL-QOh7~t8ccc>1FAs9hrd7B zWF~!oIj)e}oVzB7;=P7pbgJ1~3Q;Tw3kW-MOkMA=o5`tl)gS}1$Y+w|h2W8B1v>qp zSNTo8+p@ul8IWo}Y@)n?)D*D3oZOO}a5HzRJs4%EsWVy9%y#K42F(y56?RO_HHUC@ zLrZdyZgYoIuKoH+)0DD zWdB0(gv1PjWW_@^rJ}VB2Ei2G{;Zz4$K_*;ORX6{_NthcMApl%kMw(Kd^zKkhu+M7 zrPuZRq)r5f(0rKy@`lLLo6W}qvr=T?rp@Js6$ATkiGgG%)O1hQTSh{DgjJa%Dkf)Y zufS<^=SkdR9jszJI*Pk)Yd7fGW)Ig}r`)PfPn%i&W@)4%@TOf$H!%Z7G{~#NKO$7& z9MT$_Og|4d(RWb6JRcaqxb!`)@+?Up9Gw3SmiRV zjI&V@GJEY-sQ;dtzjNC%=r{N<+wLADXZjH;Xj&;UBwQEr!aBqj0+o8-9Mj1df!m(- zQ75^YkV)C;&)u2hUgb=SObsOwlatFx{MPh`>s~24P$i(`!$Ybly)h!=q-dsbho*o> zu#pYSkB4WkA@Q%_@rV^G-a{-dYzJY(WcYMiIiiIPi;oXqlazG`u)G|S;bC;Jn%dJ&VKX^nrO_#oe zLTSF&NbXl)`C?^KhTq;-!?)pIZ@g&bwaZZR9x%31yVLo`}iQHqqmHmfO!o_gn& z{HSer-qzHZNep3fPNSy0N;r5j%b~z&fzq9AcN7_y+<8o%eEiQ9K1JcTw>^FjNynfO zyW~)=&mBp1NiG?KJP)OhQI>=U=!!*ylup^p?=02FEuDITC-eaUsi~_tNtqTDu#umj z51if1_Elfi+#!+v#a#TZ^E~hKcOsecAcH*ZE59|L)4N>|(@geVE+Y2U(LubIQCGv+ zqwp&+Bo&{Zj@44hROxgCOm(w z2r*=fNNtJ~08#NDMC96zaHWQDcndPr9Xb#)ufn~;*4)s;xpWQBfM9NN!cOr>6V*7&H#lS}E`&yp21#xPv)M zVFRmJzAoMoqAZ23ZXTbcI8Yy1c}nVXsHiFxSF|i1<4VMw*`y`9n%E}8+nPJl={c3| zvgjGurCY@9OgS4+$=8Z#EyKIjI2>Mod2DA|oDwBDCPj0acW@nabg(zF3#%k|KJTK} zX4zIg|6R!ygi@MPmz@1Z3Q;2>zk|bmp}&=G7QOlWQIMea&GgUbsi#oq(xpn4uREZ! zRR8Rpc~p3{#Pe{W06LyKhrLrY@0_oFWyx10nj&U>>YTCXCQ(4l0AV3 Pf6l0Bs}?C=zWaXwmRBo@ literal 0 HcmV?d00001 diff --git a/algos/eq/Picture_iir_filter_response_vs_ideal_target.png b/algos/eq/Picture_iir_filter_response_vs_ideal_target.png new file mode 100644 index 0000000000000000000000000000000000000000..26a4e27b39d21a278066b82759bd1b2f326864d5 GIT binary patch literal 54469 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 z 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 literal 0 HcmV?d00001 diff --git a/algos/eq/Picture_raw_frequency_response.png b/algos/eq/Picture_raw_frequency_response.png new file mode 100644 index 0000000000000000000000000000000000000000..d4bc8ff2708347f770960798520deb3b3233770b GIT binary patch literal 67499 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

Ni)B*E>hu^-xl&ztH&D5h4#dh>Z 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�FzQ8-hub=ks7DVnRPl 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�w>X8Cpb7YVg`V9F!A{ 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 T-l9?h`0u2Sp?0N~UHJb8bctWz literal 0 HcmV?d00001 diff --git a/algos/eq/Picture_response_with_smoothing.png b/algos/eq/Picture_response_with_smoothing.png new file mode 100644 index 0000000000000000000000000000000000000000..b9d1c7b591c39cfd83815eb4516d6a594849da21 GIT binary patch literal 66261 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 z zn2;jTMrdDP8EW|dqwB51qHOmsUK#}HR2V=I$pJx>?ozsup+QPSkOt|H29-v-JBO4G zQF3UcLt0X#uE=Z^JV>$4a*SL5k&e-3$!&hwRJQj7?Qgm?x;o(E8#Knb zyr5?l{y2C+pBxtJvbz3QKfI?@s`vN8sly`~xWO|zu7!3(?D+8Iu}m-bF^}U19=3xP z$3Dct_OX=f>U~MijxI}}nwdC_&Fn3iNBK9>4Zpq&52BAd%_Hu^;wlW5#G@Qq9X5=z z`9@YWNW5%&2eRQ29PzKB_q@{&4XzVo2fN1i&Slkl?9|CC8>31G$ZH-46e%1QMmvbn zCB}Z;VCo4N*;5s*6u+a45qk`2y@)yFKl+gE*>?n3k2Uye} z(CiE7;chOEX-f0cy^{r~w)}QX9y+vd;A}Mu5Jsekzf{ED?@gtpVg+GKZnu z#^oXtP3PB_JyD#K{iS{~Tp05k&ai_r$IF@IMX+aS4a zbRd??D|U3YIk43hEJN_%#K==GTuBgflyjI95F27&M{fOO&5Oâ*be^^5}KnM3cYy;ni4nW137CC&{cbKKvnB@Z7eQ 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 literal 0 HcmV?d00001 diff --git a/algos/eq/Picture_right_channel_FIR_absolute_response.png b/algos/eq/Picture_right_channel_FIR_absolute_response.png new file mode 100644 index 0000000000000000000000000000000000000000..50450729a2e00c12b02ec90eda1673454b6a5345 GIT binary patch literal 50603 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

w?3UP6AoezBMl9x43 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 HVdMKRQoy-c literal 0 HcmV?d00001 diff --git a/algos/eq/Picture_right_channel_response.png b/algos/eq/Picture_right_channel_response.png new file mode 100644 index 0000000000000000000000000000000000000000..e995b01aeb8c1d8a7c65b65c0285320bfd08202d GIT binary patch literal 65771 zcmbrmbx@RH7e0)Hl%xtGUD7Sxxim<#l#+``cT0nGOM{dME46ehNG#pmE8X3{2jBOd z`F%6rAK%RP%rJtp>^{$ZpL3n-y3V3AwB8DcnbW_ z%2Kcl@Xr%x4UiPl&q1;+;0IJINfk*Xq{>+A+Ye~K&zKJK`p!s5xW6C2o^;!PH%CHx zC{&P<)bcRi%|iFl(!Rd0ZfaXtI)AXgY20p{tT||G+Me}3XfczPc_&1J6`t#oO!Hp4 zGM9!Z&RANC!3Bdp*o9CEgHD1G^YDJd+loDHeqPKukwhRi=O(^k!+bwYc&K?paLDsO zkm+0Qe=mHDq+t#9|6CXtiV!Bo|6Hi3^spEIy^sS5!C3#jo=9S{q5bCy`J5Y^68N7> zN6TgFtx4Z;o3pL!{S|^;fUf3x)P z(e}sp@59@RK$KS5&hbHUmj-b7=hcTi$vEGC7P;QcpS`nRXsp?tu9SX?^O`Qz&?#cx z|KYC6yf;C9;BaG=Y-+{Wex^#6&u*U4ecmzbTrkJySfSzQ4=EzUzBS@j_LX6Vx5HLp zs$#iui}}G~%k0(YsD|fyJZODF*CZKONt>ML1LvhyU$EdsNbSnkV_!=vE1Qjua01%( zK9=(F{Uw<77|hwn9ax-+`n=p+eA34NmB-(dVqstad7W-L_F!HQ`QPW?-SD?vMNf9z zAI177JzV8Hj0pYx_KgM_6@+`&&oeZBud;#Z@b&(}|3UZuysoWR^kP0g*~optRYOxV zKZ3{jVVyxd-v9n2XSCW%4Z5i2f34}c5<(191-DTI20zd~6A-sw6j9N8m!o=zE`Aws zy9p9cn5nk1nL=xF+Y_RL-QQod!F%Fqd5Jg6ss~30@3wW@M*FswAC?|&{AYP%g!cuY zWO+$xX-sXGT^#Ei{#TK2KGjqBhdIbVjt}1D%UMr(T`aioG|RahHh8N2^gZrnP;zvv zeDkcteNb=%LKEdryNYx{n0EzioH2#pQ>#14q z-K92@MgIq1=%O^9XhDR_zCIY7?)D(4mhtk%3)7%~35aY286lwc!e!aM{!h z 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 K^?bCY|NjF9wUv(m literal 0 HcmV?d00001 diff --git a/algos/eq/Picture_simulated_IIR_FIR_frequency_response.png b/algos/eq/Picture_simulated_IIR_FIR_frequency_response.png new file mode 100644 index 0000000000000000000000000000000000000000..edd732a2ef1404f92b28862b19485f5185723582 GIT binary patch literal 73901 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�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

&7EDHRohbBvroqX!c4Ng>spXNBLz+Hi3m ze(WaVmRZR?bj!ri#YqVr+ISFhDj-RO9Zr#$8EC&&?t|1e$c{h#?tz?X;q#1pb~4b+!W7sx4t|uzSNu!_}KN4>&iH6^= zCcut=V9ur9<_sLrrppnIi1U4aVc3hw4od$0SsJV*(hB{og(Bh_3IB0q98bzNlu`a| z0i^^Y!-nBdT9$72D|oN5FNy8D%|782Xt}vfu+Q450^7J>{k^Ah z6aH%3bBrm#*Tp6o;ii!ZS$Qo|(sp}ssv z=f;Ea=i=Lx^O54-fKlNODhxfJ-|i1}ZhVIx+1$Uzq>eRdO9v-YTO_7cS%R4j%B_Et z;0FYswAJFfEiW%Vti zlN{>IvwvuU-#^ATR$Toyual<*n>9Kr{b5LE3VZ7ohC()__ zUyRiHS$E+M)6J^qa{PGi-M0@(>goc`p_vcY=3m#$Qj?E<5Uu<0%M3l`3^$tLs5|+! zNiULs+KGjTSynMZ4VY(S5kVlRncq_n@=vY3l1%0Dc_5ep{UJ4K${9l}Gx@=)PFx4kx<^qFK% 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�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 literal 0 HcmV?d00001 diff --git a/algos/eq/Picture_speaker_meas.jpg b/algos/eq/Picture_speaker_meas.jpg new file mode 100644 index 0000000000000000000000000000000000000000..414a3139331c5aac5c0e58628954cb1949f9e772 GIT binary patch literal 116075 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�tz@S;f}Q?5rDKPv5kvFHiTdSmNe+3-)n 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

}X&N%q$ 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 a3;k7ZN26aXiG)@uUoMUfE54?>n*Kl1FPJ0% literal 0 HcmV?d00001 diff --git a/algos/eq/Picture_tested_speaker_frequency_response.png b/algos/eq/Picture_tested_speaker_frequency_response.png new file mode 100644 index 0000000000000000000000000000000000000000..ec1cb73856aead222566f65412206ff89da779df GIT binary patch literal 66862 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 z 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 +digital. In both cases use of calibrated reference microphone is +needed. + +Preparations +************ + +The device should allow remote ssh without password for the automatic +scripts to work. Since the developers have usually their public and +private keys setup only this is needed. Find out the IP address from +ifconfig command output on your device. + +.. code-block:: bash + + ssh-copy-id -i ~/.ssh/id_rsa.pub user@aa.bb.cc.dd + +For ssh to work with low delay the development PC and tuned device +should be on the same local IP network. You can check that remote +playback works to DUT with example command: + +.. code-block:: bash + + ssh user@aa.bb.cc.dd "aplay -l" + +Since the tests are done with low-level ALSA aplay and arecord +utilities it is recommended to temporarily rename in DUT the audio +servers to disable them. Kill manually the processes or reboot to +avoid them continue running. The audio servers can be disabled from OS +system control in more elegant way but it is harder to remember how to +do it and restore to normal vs. the brute force way. + +.. code-block:: bash + + cd /usr/bin + sudo mv pulseaudio pulseaudio.disabled + sudo mv pipewire pipewire.disabled + + +Frequency response measurement +****************************** + +Note: More professional audio analyzer systems are recommended to be +used for final tuning. The procedures described in this document are +for coarse initial settings. Final tuning, especially if dependence +to regulations and standards need to be done with care in professional +environment with calibrated measurement equipment. + +To measure speakers an omnidirectional USB measurement microphone is +recommended, e.g. UMM6 [2]_ or UMIK-1 [3]_. Such microphones are +inexpensive and do not necessarily have a flat frequency response but +the manufacturers provide a serial number based downloadable +calibration file for them. The calibration can be applied to these +measurements in SOF as well by referencing the downloaded calibration +data to measurement script. + +Next step up are analog condenser measurement microphones with a +high-end USB sound card that can provide the 48V phantom voltage. But +analog microphones add more calibration consideration for analog +level. The measurement microphones can be also calibrated for absolute +level with dedicated microphone calibrators those can output into the +sealed compartment a reference 94 dBSPL tone. + +The tools for measurement and EQ design are in located in directory +$SOF_WORKSPACE/sof/tools/tune/eq. The test setup is such that the DUT +device plays back the measurement wav file via ssh commands and the +development PC connected USB microphone captures the output. To +achieve this the configuration files for playback and capture need to +be edited. + +The capture device UMM6 is hw:3.0 (card 3, device 0), this can be seen +from output of arecord command on a the development PC example. We +also know that this device supports one capture channel. + +.. code-block:: bash + + arecord -l + **** List of CAPTURE Hardware Devices **** + card 0: PCH [HDA Intel PCH], device 0: ALC257 Analog [ALC257 Analog] + Subdevices: 1/1 + Subdevice #0: subdevice #0 + card 1: Ultra [Fast Track Ultra], device 0: USB Audio [USB Audio] + Subdevices: 1/1 + Subdevice #0: subdevice #0 + card 2: Audio [ThinkPad Dock USB Audio], device 0: USB Audio [USB Audio] + Subdevices: 1/1 + Subdevice #0: subdevice #0 + card 3: UMM6 [UMM-6], device 0: USB Audio [USB Audio] + Subdevices: 1/1 + Subdevice #0: subdevice #0 + +The settings file + +.. code-block:: bash + + $ cat mls_rec_config.txt + %% Recording device configuration + + rec.ssh = 0; % Set to 1 for remote capture + rec.user = ''; % Set to user@domain for ssh + rec.dir = '/tmp'; % Directory for temporary files + rec.dev = 'hw:3,0'; % Audio capture device + rec.nch = 1; % Number audio capture channels to use + + % Use '' if calibration is not needed. Otherwise set to + % e.g. '1234567.txt'. Such calibration data format is supported for + % some reasonably priced measurement microphones. The ASCII text + % calibration data file is the measured frequency response of the used + % microphone. Lines in the beginning those start with character " are + % treated as comment. The successive lines should be + % number pairs. Their unit must be Hz and dB. + rec.cal = ''; + +Similarly check with remote aplay command the playback devices and +then edit the playback settings. + +.. code-block:: bash + + ssh user@aa.bb.cc.dd "aplay -l" + **** List of PLAYBACK Hardware Devices **** + card 0: sofglkda7219max [sof-glkda7219max], device 0: Speakers (*) [] + Subdevices: 1/1 + Subdevice #0: subdevice #0 + card 0: sofglkda7219max [sof-glkda7219max], device 1: Headset (*) [] + Subdevices: 1/1 + Subdevice #0: subdevice #0 + card 0: sofglkda7219max [sof-glkda7219max], device 5: HDMI1 (*) [] + Subdevices: 1/1 + Subdevice #0: subdevice #0 + card 0: sofglkda7219max [sof-glkda7219max], device 6: HDMI2 (*) [] + Subdevices: 1/1 + Subdevice #0: subdevice #0 + card 0: sofglkda7219max [sof-glkda7219max], device 7: HDMI3 (*) [] + Subdevices: 1/1 + Subdevice #0: subdevice #0 + +On the DUT the speakers are provided by device hw:0,0. It's known that +there's two playback channels in the device. + +.. code-block:: bash + + $ cat mls_play_config.txt + play.ssh = 1; % Set to use remote ssh commands + play.user = 'user@aa.bb.cc.dd'; % Set user@domain for ssh + play.dir = '/tmp'; % directory for temporary files + play.dev = 'hw:0,0'; % Audio device for playback + play.nch = 2; % Number of playback channels to test + +Next the measurement orientation and measurement microphone place is +considered. A notebook could be placed on top of a table symmetrically +where the measurement microphone location should be symmetrical to +display center axis. The microphone location could be near the center +of user’s ears. If the measurement microphone capture is too silent or +disturbed by ambient noise the microphone should be placed closer into +near field. + +.. figure:: Picture_speaker_meas.jpg + :width: 600 + + On-axis measurement position for bottom located speakers. + +Since this example device is a convertible type with a near 360 degree +display hinge there are several usage orientations. It was chosen to +measure the speakers from about their firing axis. Since the response +is impacted by orientation this was felt as safest choice. It also +gave the flattest looking frequency response. + +The MLS measurement tolerates some noise but the more silent the +environment is the better it is. An anechoic chamber would be ideal +naturally. The used MLS signal sets stress for the speakers so start +with a low volume setting with “alsamixer -Dhw:0”. Find the speaker +playback volume control PGA or volume controlin speaker amplifier and +start with e.g. 50%. + +Start Octave and launch the measurement + +.. code-block:: octave + + [f, m] = mls_freq_resp('DUT'); + +If the script warns about too silent audio increase the volume and/or +bring the microphone closer to the device. If the device has small +speakers and test signal playback sounds like at being near to their +capability limit, it is best to ignore the warning. The speakers may +permanently damage if the playback is too loud. + +If problems the script contains a self test for quick integrity +check. The self test measures a recursive filter that simulates a +non-flat response. The measurement and theoretical response that’s +computed directly from filter coefficients should match. + +.. code-block:: octave + + [f, m] = mls_freq_resp('selftest'); + +The test signal contains two chirps and a few times repeated +pseudo-random numbers sequence. The chirps are used to locate and +extract the MLS part. The MLS sequence has such a characteristic the +the correlation with itself is minimal. The sufficient length of the +sequence is used to suppress room reverberation from the +measurement. It provides nearly similar measured frequency responses +as achieved in anechoic conditions. As in anechoic chamber the setup +should be as much as possible like free-field. The desk/stand where +the device is measured should be away from reflecting surfaces. + +This MLS measurement would naturally also benefit from doing in +anechoic chamber since the MLS technique cannot eliminate all reverb +impact form measurement. Though usually in chambers there’s +professional equipment available like Audio Precision ® and other. If +such are available this measurement step with SOF can be avoided and +continued from next section for data import for tuning. + +.. figure:: Picture_raw_frequency_response.png + :width: 600 + + Frequency response measurement. The first channel is aligned to 0 + dB at 1 kHz. The second channel is shown with true offset + vs. first. + +After a successful measurement a plot with frequency (Hz) and +magnitude (dB) as x and y axis will be shown. The variable f will +contain the frequency response and variable m the magnitude. If the +number of measured channels was larger than 1 the m is a matrix. The +result can be saved for equalizer design into a .mat file. + +.. code-block:: octave + + save example_dut.mat f m + +Equalizer design +**************** + +It can be seen from the picture that the output of speakers is weak at +below 200 Hz. There’s two resonances, first at about 700 Hz and second +at about 5 kHz (better visible on table orientation). The response is +within -10 .. +10 dB in about 300 - 13000 Hz range. The equalization +should not be applied outside these frequencies to avoid a large loss +of SPL. It can be also seen that the left and right speaker have +slightly different frequency response. + +Next the measurement data is imported to SOF. It can be done by load +of previously saved file or importing e.g. in MS Excel format from +other equipment. The matrix columns for frequency and channel specific +levels need to be known. + +The tool in SOF is a set of functions to be used in user created +script. Therefore programming knowledge is needed. The benefit of +using script is the procedure is easy to repeat and documented by +itself. + +FIR equalizer +************* + +The finite impulse response (FIR) filter type has the advantages that +design for any finite time impulse response / frequency response is +simple and robust. The filters do not oscillate by design so the +rounding errors do not appear as noise. The rounding of coefficients +into a fixed word length only impairs slightly the response but the +effect can be usually ignored. Therefore the FIR equalizers especially +when used with 24 and 32 bit audio format are compatible with studio +like 24 bit audio quality. + +Due finite response (often limited by DSP resources) the FIR filters +are not practical for lowest frequencies unless very long filters are +used. The longer the filter is the more DSP RAM and MCPS the +processing consumes. However FIR filters are great for mid and high +frequencies equalization. The next example equalizes those frequencies +for the previously done measurement. + +The initial script for tuning is shown below. Alternatively for other +equipment the data import could be done in Excel format and use +function xlsread(); to read a matrix and then extract the frequency +and magnitude columns. + +.. code-block:: octave + + %% Load measurement data, variable f and m + load example_dut.mat; + + %% EQ settings + eq1 = eq_defaults(); % Get defaults + eq1.fs = 48e3; % Set sample rate + eq1.norm_type = 'loudness'; % Normalize criteria can be loudness/peak/1k + eq1.norm_offs_db = -3; % Offset in dB to normalize, -3dB loudness + eq1.logsmooth_plot = 1.0; % Smooth over 1.0 octaves + eq1.logsmooth_eq = 1.0; % Smooth over 1.0 octaves + eq1.enable_fir = 1; % By default both FIR and IIR disabled + eq1.fir_beta = 3.0; % Lower beta is more accurate but be careful + eq1.fir_length = 90; % Minimize this vs. fmin/fmax choice + eq1.fir_autoband = 0; % Select manually frequency limits + eq1.fmin_fir = 700; % Equalization starts from 800 Hz + eq1.fmax_fir = 13e3; % Equalization ends at 13 kHz + eq1.fir_minph = 1; % Check result carefully if 1 is used, 0 is safe + eq2 = eq1; % Copy settings to second EQ + + %% Design left channel EQ + eq1.raw_f = f; % Measurement Hz + eq1.raw_m_db = m(:,1); % Measurement dB, left ch + eq1 = eq_compute(eq1); + eq_plot(eq1, 10); + +The run of this script creates these plots. Note the choice of 1.0 +octaves smoothing for both plotting and EQ target derivation. It’s +best to start carefully with such a high amount of smoothing to avoid +to equalize highly uncertain details of frequency response. + +The smoothed version of the response becomes very flat in the +equalized version. However the simulated raw response still contains a +lot of ripple especially at high bands. It’s an industry standard to +use ⅓ octaves smoothing since it quite well matches human ear +psycho-acoustics. Therefore ⅓ octaves should be the smallest feasible +width of octaves smoothing to use. + +.. figure:: Picture_response_with_smoothing.png + :width: 600 + + Imported frequency response with and without octaves + smoothing. Note that the strong 1.0 octaves wide smoothing + “flattens” most of the narrow (high Q) resonances and leaves the + two mentioned resonances at 700 Hz and 4 kHz. + +.. figure:: Picture_FIR_right_channel_equalized.png + :width: 600 + + Simulated frequency response after equalization + +.. figure:: Picture_FIR_response.png + :width: 600 + + Frequency response of equalizer. The blue curve is the ideal + inverse response including the smoothing. The red curve is the band + limited and filter design parameters constrained actual EQ + response. The y-axis is offset in such way that 1 kHz frequency is + shifted to 0 dB. Try the impact of filter length to see how it + impacts the accuracy and find a fair compromise. + +.. figure:: Picture_FIR_response_absolute.png + :width: 600 + + Frequency response of equalizer. This curve shows the absolute gain + of the equalization. It can be seen that the normalization of + loudness (-3 dB) does some fairly high gain above 10 kHz. The + attenuation of frequencies below 200 Hz may or may not be + sufficient to give signal headroom for this boost. Need to watch + out for distortion in playback, if observed the loudness need to be + decreased. + +.. figure:: Picture_FIR_impulse_response.png + :width: 600 + + Impulse response of equalizer. The chosen minimum phase + non-symmetrical impulse response can be seen in the shape. A linear + phase response would have symmetrical pre- and post oscillation in + the impulse response. + +Add of right channel measurement import and EQ design is done by +adding these lines to above script. + + +.. code-block:: octave + + %% Design right channel EQ + eq2.raw_f = f; % Measurement Hz + eq2.raw_m_db = m(:,2); % Measurement dB, right ch + eq2 = eq_compute(eq2); + eq_plot(eq2, 20); + +The resulting EQ can be seen from these plots. If the left and right +channel results are different need to know if it is due to +non-symmetrical mechanics. If there’s designed non-symmetry it’s safe +to go ahead and design different EQ for left and right channels. If +the hardware is symmetrical then it is likely to better to equalize +e.g. average response of left and right instead. + +Note: The left and right responses are quite similar. The mechanics & +acoustics is likely symmetrical so a common EQ could be the best +choice. The average of left and right response could be suitable to +use. However in this in this case the design is done as stereo for +tutorial purpose. + +.. figure:: Picture_right_channel_response.png + :width: 600 + + Import right channel frequency response. + + +.. figure:: Picture_FIR_right_channel_equalized.png + :width: 600 + + Simulated response of equalizer. + +.. figure:: Picture_right_channel_FIR_absolute_response.png + :width: 600 + + Frequency response of the right channel filter. Notice the difference to left channel filter. + +The next step is to check the stereo EQ design. The left and right +channels should as equalized have similar loudness. Since the SOF tool +currently does not add much help to multi-channel design this step +needs some additional own code. + +.. code-block:: octave + + %% Stereo EQ + figure(30); + l_ch = eq1.m_db+eq1.fir_eq_db; + r_ch = eq2.m_db+eq2.fir_eq_db; + semilogx(eq1.f, l_ch, eq2.f, r_ch); + grid on; + axis([100 20e3 -20 10]); + xlabel('Frequency (Hz)'); + ylabel('Magnitude (dB)'); + + %% Calculate level offset at 1 - 4 kHz from RMS + idx0 = find(eq1.f < 4e3); + idx = find(eq1.f(idx0) > 1e3); + l_lev = 20*log10(sqrt(mean(10.^(l_ch(idx)/10)))); + r_lev = 20*log10(sqrt(mean(10.^(r_ch(idx)/10)))); + fprintf('L ch level %3.1f dB\n', l_lev); + fprintf('R ch level %3.1f dB\n', r_lev); + delta_lev = l_lev-r_lev; + fprintf('delta %3.1f dB\n', delta_lev); + +The plot shows the raw data plus EQ impact. Since the offset is hard +to judge from the non-smoothed plot (the smoothed data is +unfortunately for this purpose 1 kHz, 0 dB aligned) the offset is +computed from RMS level difference in 1 - 4 kHz band. In this example +the difference was 0.2 dB. The offset is next added to right channel +align. + +.. code-block:: octave + + %% Design right channel EQ + eq2.norm_offs_db = -3 + 0.2; % Offset in dB to normalize, -3dB plus L-R + eq2.raw_f = f; % Measurement Hz + eq2.raw_m_db = m(:,2); % Measurement dB, right ch + eq2 = eq_compute(eq2); + eq_plot(eq2, 20); + + +.. figure:: Picture_simulated_left_and_right_channel_responses.png + :width: 600 + + Simulated frequency responses of left and right speaker channels. + +The complete tuning script is shown below for completeness. It can be a +starting point for your own stereo speaker equalizer design case! + + +.. code-block:: octave + + %% Load measurement data, variable f and m + load example_dut.mat; + + %% EQ settings + eq1 = eq_defaults(); % Get defaults + eq1.fs = 48e3; % Set sample rate + eq1.norm_type = 'loudness'; % Normalize criteria can be loudness/peak/1k + eq1.norm_offs_db = -3; % Offset in dB to normalize, -3dB loudness + eq1.logsmooth_plot = 1.0; % Smooth over 1.0 octaves + eq1.logsmooth_eq = 1.0; % Smooth over 1.0 octaves + eq1.enable_fir = 1; % By default both FIR and IIR disabled + eq1.fir_beta = 3.0; % Lower beta is more accurate but be careful + eq1.fir_length = 90; % Minimize this vs. fmin/fmax choice + eq1.fir_autoband = 0; % Select manually frequency limits + eq1.fmin_fir = 700; % Equalization starts from 800 Hz + eq1.fmax_fir = 13e3; % Equalization ends at 20 kHz + eq1.fir_minph = 1; % Check result carefully if 1 is used, 0 is safe + eq2 = eq1; % Copy settings to second EQ + + %% Design left channel EQ + eq1.raw_f = f; % Measurement Hz + eq1.raw_m_db = m(:,1); % Measurement dB, left ch + eq1 = eq_compute(eq1); + eq_plot(eq1, 10); + + %% Design right channel EQ + eq2.norm_offs_db = -3 + 0.2; % Offset in dB to normalize, -3dB plus L-R + eq2.raw_f = f; % Measurement Hz + eq2.raw_m_db = m(:,2); % Measurement dB, right ch + eq2 = eq_compute(eq2); + eq_plot(eq2, 20); + + %% Stereo EQ + figure(30); + l_ch = eq1.m_db+eq1.fir_eq_db; + r_ch = eq2.m_db+eq2.fir_eq_db; + semilogx(eq1.f, l_ch, eq2.f, r_ch); + grid on; + axis([100 20e3 -20 10]); + xlabel('Frequency (Hz)'); + ylabel('Magnitude (dB)'); + + %% Calculate level offset at 1 - 4 kHz from RMS + idx0 = find(eq1.f < 4e3); + idx = find(eq1.f(idx0) > 1e3); + l_lev = 20*log10(sqrt(mean(10.^(l_ch(idx)/10)))); + r_lev = 20*log10(sqrt(mean(10.^(r_ch(idx)/10)))); + fprintf('L ch level %3.1f dB\n', l_lev); + fprintf('R ch level %3.1f dB\n', r_lev); + delta_lev = l_lev-r_lev; + fprintf('delta %3.1f dB\n', delta_lev); + +IIR equalizer +************* + +Infinite impulse response (IIR) filter is the other main filter type +for equalization. Here it’s described after FIR because despite the +simpler look (much lower filter orders needed) using them needs more +expertise. An IIR design can fail fatally if not used with care and +plenty of testing. Therefore it is recommended to use simple low order +filters and do the more complex response manipulation with FIR. The +risks of IIR are in stability (unwanted loud oscillation), noise, and +loss of SNR due to scaling need. However IIR filters are great for +enhancing frequency response at lowest frequencies and generally doing +stronger adjustment. + +The tool in SOF does not support automatic design. Instead the design +is manual with parametric first and second order blocks. The second +order blocks are called often bi-quads. The parametric blocks are +specified by their type (high-pass, low-pass, low-shelf, high-shelf, +peak/notch). The shelving and peaking filters are second order. The +high-pass and low-pass filters can be first or second order. Therefore +the parametric blocks are called with abbreviations HP1, HP2, LP1, +LP2, LS2, HS2, and PN2. All parametric blocks have a resonant +frequency parameter in Hz. The shelving filters and peaking filters +have also gain in Decibels as parameter. Finally the peaking filter +has a Q-value parameter. The higher the Q-value is the narrower is the +resonance. The syntax for describing parametric EQ is shown below: + +.. code-block:: octave + + eq1.peq = [ eq1.PEQ_HP2 200 0 0 ; ... + eq1.PEQ_PN2 750 -5.0 1.3 ; ... + eq1.PEQ_PN2 5000 -4.0 0.6 ; ... + ]; + + +The example can be equalized with IIR only. First, since there is very +little output from the speaker below 200 Hz we can with second order +high-pass suppress the not audible frequencies from output. It +increases the headroom for equalization a lot since typical music and +speech content has large energy there. Then, a peaking EQ is set to +attenuate the 750 Hz region by 5 dB and Q-value 1.3 for flatter +response. Finally, a peaking filter is set to attenuate the wide bump +at 5 kHz by 4 dB and Q-value 0.6. The resulting EQ is 6th order. It +also could be possible to boost the low frequencies at 400 Hz a bit +with a low-shelf but it is not done here to keep filter order +low. Boost at low frequencies creates risk for signal clipping while +the achievable bandwidth extension is not large. + +.. figure:: Picture_imported_frequency_response_for_iir.png + :width: 600 + + Simulated frequency response. The difference in parametric + low-order IIR can be seen as more remaining small ripple in the + smoothed equalized response vs. FIR. + +.. figure:: Picture_iir_filter_response_vs_ideal_target.png + :width: 600 + + IIR filter response vs. ideal target. + +.. figure:: Picture_iir_absolute_response.png + :width: 600 + + Absolute response. The loudness normalize suggests a fairly high + gain for the filter since a lot of loudness is lost due to suppress + of lowest frequencies. Need to be careful with this. + +.. figure:: Picture_iir_poles_and_zeros.png + :width: 600 + + Poles and zeros plot. In recursive filters the poles (x) need to be + inside unit circle for stable design. This plot is for 64 bit float + coefficients, fixed scaled coefficients could have issues even if + this looks OK. + +.. figure:: Picture_iir_impulse_response.png + :width: 600 + + Impulse response. The main purpose of this to do another stability + check. A stable filter decays to zero while an unstable design + might remain oscillation at steady or increasing amplitude. + +The right channel is tuned similarly. The resulting non-smoothed +left/right balance corrected responses and the complete code for +tuning are shown below. + + +.. figure:: Picture_iir_simulated_left_and_channel_responses.png + :width: 600 + + Simulated frequency responses of left and right speakers with + IIR equalizer. + + +.. code-block:: octave + + %% Load measurement data, variable f and m + load example_dut.mat; + + %% EQ settings + eq1 = eq_defaults(); % Get defaults + eq1.fs = 48e3; % Set sample rate + eq1.norm_type = 'loudness'; % Normalize criteria can be loudness/peak/1k + eq1.norm_offs_db = -3; % Offset in dB to normalize, -3 dB loudness + eq1.logsmooth_plot = 1.0; % Smooth over 1.0 octaves + eq1.logsmooth_eq = 1.0; % Smooth over 1.0 octaves + eq1.enable_iir = 1; % By default both FIR and IIR disabled + eq2 = eq1; % Copy settings to second EQ + + %% Design left channel EQ + eq1.raw_f = f; % Measurement Hz + eq1.raw_m_db = m(:,1); % Measurement dB, left ch + eq1.peq = [ eq1.PEQ_HP2 200 0 0 ; ... + eq1.PEQ_PN2 750 -5.0 1.3 ; ... + eq1.PEQ_PN2 5000 -4.0 0.6 ; ... + ]; + eq1 = eq_compute(eq1); + eq_plot(eq1, 10); + + %% Design right channel EQ + eq2.norm_offs_db = -3 + 0.1; % Offset in dB to normalize, -3dB plus L-R + eq2.raw_f = f; % Measurement Hz + eq2.raw_m_db = m(:,2); % Measurement dB, right ch + eq2.peq = [ eq2.PEQ_HP2 200 0 0 ; ... + eq2.PEQ_PN2 750 -5.0 1.4 ; ... + eq2.PEQ_PN2 4500 -4.0 0.6 ; ... + ]; + eq2 = eq_compute(eq2); + eq_plot(eq2, 20); + + %% Stereo EQ + figure(30); + l_ch = eq1.m_db+eq1.iir_eq_db; + r_ch = eq2.m_db+eq2.iir_eq_db; + semilogx(eq1.f, l_ch, eq2.f, r_ch); + grid on; + axis([100 20e3 -20 20]); + xlabel('Frequency (Hz)'); + ylabel('Magnitude (dB)'); + + %% Calculate level offset at 1 - 4 kHz from RMS + idx0 = find(eq1.f < 4e3); + idx = find(eq1.f(idx0) > 1e3); + l_lev = 20*log10(sqrt(mean(10.^(l_ch(idx)/10)))); + r_lev = 20*log10(sqrt(mean(10.^(r_ch(idx)/10)))); + fprintf('L ch level %3.1f dB\n', l_lev); + fprintf('R ch level %3.1f dB\n', r_lev); + delta_lev = l_lev-r_lev; + fprintf('delta %3.1f dB\n', delta_lev); + +Combined IIR and FIR +******************** + +The EQ tool can support use of both types simultaneously. The IIR type +is applied first and the impact is subtracted from the target. This +allows the FIR to fine tune the response where IIR could not match +fully the target. + +For this example the IIR high shelf is left out because FIR can do it +efficiently. Instead of boosting at 2 kHz this script tests +attenuation at 700 Hz to flatten and extend a bit the flat frequency +response region down. + +Note: In current version the norm_offs_db parameter impacts both FIR +and IIR part by the given amount. Therefore the level adjust need to +be entered as 0.5*adjust. + +.. figure:: Picture_IIR_FIR_target_vs_achieved_response.png + :width: 600 + + Right channel equalization filters. The red solid plot is the combined IIR and FIR response + that matches well the smoothed target response in solid blue. The dashed yellow and purple + lines show the IIR and FIR responses. + +.. figure:: Picture_simulated_IIR_FIR_frequency_response.png + :width: 600 + + Simulated raw frequency response + +Exporting coefficients to SOF +***************************** + +The coefficients can be exported into a format for m4 topology for +automatic boot time setup. The topology file can include the m4 +scripts instead of the default “flat” response coefficients. It is +also possible to set up an equalizer with .txt or .bin format blob in +device run-time with sof-ctl utility to test the response and iterate +the design. + +The complete script for equalizers tuning and coefficients export for +the previous example is shown below. + +.. code-block:: octave + + %% Load measurement data, variable f and m + load example_dut.mat; + + %% EQ settings + eq1 = eq_defaults(); % Get defaults + eq1.fs = 48e3; % Set sample rate + eq1.norm_type = 'loudness'; % Normalize criteria can be loudness/peak/1k + eq1.norm_offs_db = -3; % Offset in dB to normalize, -3dB loudness + eq1.logsmooth_plot = 1.0; % Smooth over 1.0 octaves + eq1.logsmooth_eq = 1.0; % Smooth over 1.0 octaves + eq1.enable_fir = 1; % By default both FIR and IIR disabled + eq1.enable_iir = 1; % Enable too + eq1.fir_beta = 3.0; % Lower beta is more accurate but be careful + eq1.fir_length = 40; % Minimize this vs. fmin/fmax choice + eq1.fir_autoband = 0; % Select manually frequency limits + eq1.fmin_fir = 700; % Equalization starts from 800 Hz + eq1.fmax_fir = 13e3; % Equalization ends at 13 kHz + eq1.fir_minph = 1; % Check result carefully if 1 is used, 0 is safe + eq2 = eq1; % Copy settings to second EQ + + %% Design left channel EQ + eq1.raw_f = f; % Measurement Hz + eq1.raw_m_db = m(:,1); % Measurement dB, left ch + eq1.peq = [ eq1.PEQ_HP2 200 0 0 ; ... + eq1.PEQ_PN2 750 -5.0 1.3 ; ... + ]; + eq1 = eq_compute(eq1); + eq_plot(eq1, 10); + + %% Design right channel EQ + eq2.norm_offs_db = -3 + 0.1; % Offset in dB to normalize, -4dB plus L-R + eq2.raw_f = f; % Measurement Hz + eq2.raw_m_db = m(:,2); % Measurement dB, right ch + eq2.peq = [ eq2.PEQ_HP2 200 0 0 ; ... + eq2.PEQ_PN2 750 -5.0 1.4 ; ... + ]; + eq2 = eq_compute(eq2); + eq_plot(eq2, 20); + + %% Stereo EQ + figure(30); + l_ch = eq1.m_db+eq1.tot_eq_db; + r_ch = eq2.m_db+eq2.tot_eq_db; + semilogx(eq1.f, l_ch, eq2.f, r_ch); + grid on; + axis([100 20e3 -20 10]); + xlabel('Frequency (Hz)'); + ylabel('Magnitude (dB)'); + + %% Calculate level offset at 1 - 4 kHz from RMS + idx0 = find(eq1.f < 4e3); + idx = find(eq1.f(idx0) > 1e3); + l_lev = 20*log10(sqrt(mean(10.^(l_ch(idx)/10)))); + r_lev = 20*log10(sqrt(mean(10.^(r_ch(idx)/10)))); + fprintf('L ch level %3.1f dB\n', l_lev); + fprintf('R ch level %3.1f dB\n', r_lev); + delta_lev = l_lev-r_lev; + fprintf('delta %3.1f dB\n', delta_lev); + + %% Export FIR + fir_ascii_fn = 'dut_spk_fir.txt'; + fir_tplg_fn = 'dut_spk_fir.m4'; + fir_eq1_quant = eq_fir_blob_quant(eq1.b_fir); + fir_eq2_quant = eq_fir_blob_quant(eq2.b_fir); + channels_in_config = 2; % Setup max 2 channels EQ + assign_response = [0 1]; % Switch to response #0 and #1 + num_responses = 2; % Two responses + fir_bm = eq_fir_blob_merge(channels_in_config, ... + num_responses, ... + assign_response, ... + [fir_eq1_quant fir_eq2_quant]); + fir_bp = eq_fir_blob_pack(fir_bm); + eq_alsactl_write(fir_ascii_fn, fir_bp); + eq_tplg_write(fir_tplg_fn, fir_bp, 'FIR'); + + %% Export IIR + iir_ascii_fn = 'dut_spk_iir.txt'; + iir_tplg_fn = 'dut_spk_iir.m4'; + iir_eq1_quant = eq_iir_blob_quant(eq1.p_z, eq1.p_p, eq1.p_k); + iir_eq2_quant = eq_iir_blob_quant(eq2.p_z, eq2.p_p, eq2.p_k); + iir_bm = eq_iir_blob_merge(channels_in_config, ... + num_responses, ... + assign_response, ... + [iir_eq1_quant iir_eq2_quant]); + iir_bp = eq_iir_blob_pack(iir_bm); + eq_alsactl_write(iir_ascii_fn, iir_bp); + eq_tplg_write(iir_tplg_fn, iir_bp, 'IIR'); + +Testing the response with sof-ctl +********************************* + +The sof-ctl tool is practical for testing new EQ settings and iterate +the design without need to reboot the device. The pre-requisite is that +the DUT runs for speaker path a topology that contains the IIR and FIR +equalizers. + +First the numids of the equalizers are found out with amixer +command. The lines with prompt $ are user entered commands and other +text shown is command output. + +.. code-block:: bash + + $ amixer -Dhw:0 controls | grep EQIIR + numid=66,iface=MIXER,name='EQIIR1.0 EQIIR' + + $ amixer -Dhw:0 controls | grep EQFIR + numid=67,iface=MIXER,name='EQFIR1.0 EQFIR' + +The numids are in this device 66 and 67 for IIR and FIR. Next the +exported ALSA binary controls are passed to equalizers with sof-ctl: + +.. code-block:: bash + + $ ./sof-eqctl -n 66 -s dut_spk_iir.txt + Applying configuration "dut_spk_iir.txt" into device hw:0 control numid=66. + + 4607827,0,196,50331648,0,0,0,0,196,2,2,0,0,0,0,0,1,2,2,0,0,0,0,3260252783,2107733822, + 528275171,3238416955,528275171,0,16384,3324016838,2034846530,497901563,3275128193, + 526872106,4294967293,20454,2,2,0,0,0,0,3260252783,2107733822,528275171,3238416955, + 528275171,0,16384,3317002057,2041827532,500647939,3271629404,527641448,4294967293,20551 + + Success. + + $ ./sof-eqctl -n 67 -s dut_spk_fir.txt + Applying configuration "dut_spk_fir.txt" into device hw:0 control numid=67. + + 4607827,0,244,50331648,0,0,0,0,244,131074,0,0,0,0,65536,44,0,0,0,0,3801503801,233243489, + 4293068324,74908123,1901269,7733144,6422742,4290772934,17039467,1114313,4293328827, + 4291756033,4289658785,4291297224,4293459912,589833,4294115318,4294246391,4294442989, + 1310731,13,0,44,0,0,0,0,3785054386,221118972,13436579,74515002,8520459,10551247,10944817, + 4292018112,23789790,4291559609,4293984167,4288479207,4290576265,4293394406,131047,1179673, + 4293853177,4293853167,4294901744,851980,6,0 + + Success. + + + +.. figure:: Picture_tested_speaker_frequency_response.png + :width: 600 + + The response is simple to test acoustically by re-running + mls_freq_resp(); The overall response is now much more flat and is + very similar to previously shown simulated response. + + +Using the EQ settings in topology +********************************* + +The generated .m4 suffix files for FIR and IIR can be included or +embedded into topology m4 scripts. There are a few examples of such +topologies in $SOF_WORKSPACE/sof/tools/topology/topology1/development. +The CMakeLists.txt file builds e.g. topologies +sof-cml-rt1011-rt5682-eq.tplg and sof-hda-generic-2ch-loud.tplg those +can be used as example. + +The playback pipeline is set with -DSPKPROC=eq-iir-eq-fir-volume +or -DHSPROC=eq-iir-eq-fir-volume to contain the equalizers and volume +control components. The macros -DHSPROC_FILTER1=eq_iir_coef_pass.m4 +and -DHSPROC_FILTER2=eq_fir_coef_pass.m4 are flat default responses. + +Setting -DHSPROC_FILTER1=dut_spk_iir.m4 and +-DHSPROC_FILTER2=dut_spk_fir.m4 would set the just exported equalizer +tuning to be applied at device boot. + +Note: Unfortunately the SOF topology1 equalizers definitions at top +CMakeLists.txt are not very systematic and there may be bugs with some +platforms triggered by small topology changes. The new topology needs +extensive testing for all audio endpoints (that other existing filters +are not modified) and preferably manual inspection of topology .conf +file that the m4 parsed output matches expectation. + +The development now focuses to to topology2 and hopefully this part +can be cleaned up and made easier for product audio tuning. + +References +********** + +.. [1] AES17-2020: AES standard method for digital audio engineering - Measurement of digital audio equipment, + https://www.aes.org/publications/standards/search.cfm?docID=21 + +.. [2] Dayton audio UMM-6 USB measurement microphone, + https://www.daytonaudio.com/product/1116/umm-6-usb-measurement-microphone + +.. [3] MiniDSP UMIK-1 USB measurement microphone, + https://www.minidsp.com/products/acoustic-measurement/umik-1 diff --git a/algos/index.rst b/algos/index.rst index 34776ba9..6cd9fb9c 100644 --- a/algos/index.rst +++ b/algos/index.rst @@ -37,6 +37,7 @@ Further information on specific algorithms is forthcoming. .. toctree:: :maxdepth: 1 - src/sample_rate_conversion demux/demux.rst + eq/equalizers_tuning + src/sample_rate_conversion tdfb/time_domain_fixed_beamformer From c9ace0034bd6f7d01b35ee37306c4a5ce76104b7 Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Mon, 25 Apr 2022 09:19:05 +0200 Subject: [PATCH 081/150] arch: fw: memory management based on Zephyr Memory management description, design and flows Co-authored-by: Marcin Maka Signed-off-by: Michal Wasko --- .../firmware/sof-zephyr/rtos_layer/index.rst | 1 + .../memory_management/heap_sharing.rst | 16 ++++ .../images/dynamic_module_load.pu | 77 +++++++++++++++++++ .../images/memory_allocation.pu | 21 +++++ .../memory_allocation_from_memory_driver.pu | 26 +++++++ .../images/memory_initialization.pu | 42 ++++++++++ .../images/memory_management_layers.pu | 60 +++++++++++++++ .../rtos_layer/memory_management/index.rst | 39 ++++++++++ .../memory_management_driver.rst | 21 +++++ .../memory_management_flows.rst | 41 ++++++++++ .../memory_management/memory_zones.rst | 11 +++ .../mpp_memory_management.rst | 19 +++++ 12 files changed, 374 insertions(+) create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/memory_management/heap_sharing.rst create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/dynamic_module_load.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/memory_allocation.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/memory_allocation_from_memory_driver.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/memory_initialization.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/memory_management_layers.pu create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/memory_management/index.rst create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/memory_management/memory_management_driver.rst create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/memory_management/memory_management_flows.rst create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/memory_management/memory_zones.rst create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/memory_management/mpp_memory_management.rst diff --git a/architectures/firmware/sof-zephyr/rtos_layer/index.rst b/architectures/firmware/sof-zephyr/rtos_layer/index.rst index d65b2dab..204b057a 100644 --- a/architectures/firmware/sof-zephyr/rtos_layer/index.rst +++ b/architectures/firmware/sof-zephyr/rtos_layer/index.rst @@ -11,5 +11,6 @@ workloads. :maxdepth: 1 zephyr_kernel_overview + memory_management/index power_management io_drivers/index diff --git a/architectures/firmware/sof-zephyr/rtos_layer/memory_management/heap_sharing.rst b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/heap_sharing.rst new file mode 100644 index 00000000..6819c0df --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/heap_sharing.rst @@ -0,0 +1,16 @@ +Heap sharing +############ + +The memory heap can be: + +- private - attached to one of the DSPs, +- shared - higher level memory shared across all DSP cores + +The shared memories are co-managed by all DSP cores that have access to it. + +The data structures needed to manage shared memories are initialized by primary +core, structure location in memory map is known at the build time and access to +it is controlled by mutex. + +The mutex uses atomic operation behind and all processors co-managing this +memory heap must support atomics. diff --git a/architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/dynamic_module_load.pu b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/dynamic_module_load.pu new file mode 100644 index 00000000..02c386d0 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/dynamic_module_load.pu @@ -0,0 +1,77 @@ +@startuml + +box "Host" #LightGreen + participant "Driver" as host_driver +end box + +box "Media Processing Pipelines Layer" #LightSkyBlue + participant "Component Manager" as component_manager + participant "Library Manager" as lib_manager + participant "MPP Memory Manager" as mpp_memory_manager +end box + +box "Zephyr RTOS" #LightBlue + participant "Memory Management Driver" as memory_management_driver +end box + +box "Hardware" #LightGrey + participant "Memory" as hw_memory +end box + +host_driver -> lib_manager: Load Library + activate lib_manager + lib_manager -> mpp_memory_manager: rmalloc(MEM_ZONE_RUNTIME, flags=NULL, MEM_CAPS_LOADABLE_LIBRARY, size) + activate mpp_memory_manager + return address to store library + lib_manager --> host_driver + deactivate lib_manager + +host_driver -> lib_manager: Transfer library over DMA\nto given address + +host_driver -> component_manager: Instantiate Component + activate component_manager + + opt if Component is Loadable and it is first instance + component_manager -> lib_manager: Load component + activate lib_manager + + loop repeat for Component TEXT, RODATA + lib_manager -> lib_manager: read Component virtual address and size from manifest + + lib_manager -> memory_management_driver: sys_mm_drv_map_region(virt*, phys=NULL, size, flags=NULL) + activate memory_management_driver + memory_management_driver -> memory_management_driver: allocate free phys pages + opt power up memory banks for allocated phys pages + memory_management_driver -> hw_memory: power up memory banks + end + memory_management_driver --> lib_manager + deactivate memory_management_driver + + lib_manager -> lib_manager: read Component address offset from library manifest + lib_manager -> lib_manager: mem_copy(virt*, library_store_addr + offset, size) + lib_manager -> memory_management_driver: sys_mm_drv_update_region(virt*, size, flags= CODE / RODATA) + activate memory_management_driver + note right: update region flags to prevent overwrite + return + + end + + opt if Component has BSS + lib_manager -> memory_management_driver: sys_mm_drv_map_region(virt*, phys=NULL, bss_size, flags) + activate memory_management_driver + memory_management_driver -> memory_management_driver: allocate free phys pages + opt power up memory banks for allocated phys pages + memory_management_driver -> hw_memory: power up memory banks + end + memory_management_driver --> lib_manager + deactivate memory_management_driver + end + + lib_manager --> component_manager + deactivate lib_manager + end + + component_manager -> component_manager: Instantiate Component + component_manager --> host_driver + +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/memory_allocation.pu b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/memory_allocation.pu new file mode 100644 index 00000000..82d84bf0 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/memory_allocation.pu @@ -0,0 +1,21 @@ +@startuml + +box "SOF" #LightBlue + participant "Component Management" as component_management + participant "MPP Memory Manager" as mpp_memory_manager +end box + +box "Zephyr" #LightGreen + participant "Zephyr Memory Manager" as zephyr_memory_manager +end box + +activate component_management +component_management -> mpp_memory_manager: rmalloc(mem_zone, flags, caps, size) + activate mpp_memory_manager + + mpp_memory_manager -> mpp_memory_manager: find memory heap that\nmatch zone and caps + mpp_memory_manager -> zephyr_memory_manager: k_heap_alloc (heap, size) + activate zephyr_memory_manager + return + mpp_memory_manager --> component_management +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/memory_allocation_from_memory_driver.pu b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/memory_allocation_from_memory_driver.pu new file mode 100644 index 00000000..a9d10fd7 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/memory_allocation_from_memory_driver.pu @@ -0,0 +1,26 @@ +@startuml + +box "SOF" #LightBlue + participant "Library Manager" as library_manager +end box + +box "Zephyr" #LightGreen + participant "Memory Management Driver" as memory_management_driver +end box + +box "Hardware" #LightGrey + participant "Memory" as hw_memory +end box + +activate library_manager + +library_manager -> memory_management_driver: sys_mm_drv_map_region\n(virt*, phys=NULL, size, flags) + activate memory_management_driver + memory_management_driver -> memory_management_driver: allocate memory phys pages + opt if phys memory pages require power up + memory_management_driver -> hw_memory: power up memory banks + end + + return + +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/memory_initialization.pu b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/memory_initialization.pu new file mode 100644 index 00000000..666e68b1 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/memory_initialization.pu @@ -0,0 +1,42 @@ +@startuml + +box "SOF" #LightBlue + participant "MPP Memory Manager" as mpp_memory_manager +end box + +box "Zephyr" #LightGreen + participant "Memory Manager" as zephyr_memory_manager + participant "Memory Management Driver" as memory_management_driver +end box + +box "Hardware" #LightGrey + participant "Memory" as hw_memory +end box + + +-> memory_management_driver: sys_mm_drv_mm_init + activate memory_management_driver + memory_management_driver -> memory_management_driver: read unused_main_mem_start_marker\nfrom linker + note right: The marker is used to\n identify where base firmware\n ends in memory (text, data, bss) + + memory_management_driver -> memory_management_driver: sys_mm_drv_unmap_region(unused_main_mem_start, unused_size) + activate memory_management_driver + opt If architecture support granular memory banks power control + memory_management_driver -> hw_memory: power down unused memory banks + deactivate memory_management_driver + end + + deactivate memory_management_driver + +-> mpp_memory_manager: mpp_mem_init + activate mpp_memory_manager + mpp_memory_manager -> mpp_memory_manager: read memory zones\nbase address and size + loop for each memory region create heap + mpp_memory_manager -> zephyr_memory_manager: k_heap_init\n(heap, mem*, size) + activate zephyr_memory_manager + return + end + + deactivate mpp_memory_manager + +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/memory_management_layers.pu b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/memory_management_layers.pu new file mode 100644 index 00000000..a2218c96 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/memory_management_layers.pu @@ -0,0 +1,60 @@ +@startuml + +allowmixing + +scale max 1024 width + +component SOF { + + package "Zephyr" as ZEPHYR_RTOS { + interface "Zephyr Memory Service interface" as ZMSI + hide ZMSI methods + hide ZMSI attributes + + package "Drivers" as DRIVERS { + component "Memory Management Driver" as MEMORY_MGMT_DRIVER + } + + package "Memory Manager" as ZEPHYR_MEM_MANAGER { + component "Multi Heap" as MULTI_HEAP + component "Memory Heaps" as MEM_HEAPS + component "Memory Blocks Allocator" as MEM_BLOCK_ALLOCATOR + component "Demand Paging" as DEMAND_PAGING + + MULTI_HEAP .[hidden]right. MEM_HEAPS + MEM_HEAPS .[hidden]right. MEM_BLOCK_ALLOCATOR + MEM_BLOCK_ALLOCATOR .[hidden]right. DEMAND_PAGING + } + + component "Device Tree" as DEV_TREE + + ZMSI -[hidden]down- MEM_BLOCK_ALLOCATOR + ZEPHYR_MEM_MANAGER -[hidden]down- DRIVERS + DRIVERS -[hidden]right- DEV_TREE + } + + package "Media Processing Pipelines layer" as MPP_LAYER { + component "Pipeline Manager" as PIPELINE_MANAGER + component "Communication" as COMMUNICATION + component "Component Manager" as COMPONENT_MANAGER + component "MPP Memory Manager" as MPP_MEM_MANAGER + + PIPELINE_MANAGER -[hidden]right- COMMUNICATION + COMMUNICATION -[hidden]right- MPP_MEM_MANAGER + MPP_MEM_MANAGER -[hidden]right- COMPONENT_MANAGER + + } + + package "Application layer" as APP_LAYER { + component "Loadable Components" as LOADABLE_COMPONENTS + component "Built-in Components" as BUILT_IN_COMPONENTS + + BUILT_IN_COMPONENTS -[hidden]right- LOADABLE_COMPONENTS + } + + APP_LAYER -[hidden]down- MPP_LAYER + MPP_LAYER -[hidden]down- ZEPHYR_RTOS + +} + +@enduml diff --git a/architectures/firmware/sof-zephyr/rtos_layer/memory_management/index.rst b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/index.rst new file mode 100644 index 00000000..c658ee02 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/index.rst @@ -0,0 +1,39 @@ +.. _memory_mgmt: + +Memory Management +################# + +Memory Management role is to provide service API for dynamic memory mapping and +allocation from available memory zones. + +Overview +******** + +The memory support functionality is delivered at two levels: + + - `Zephyr Memory Management Service `__, + + - `Memory Blocks Allocator `__, + - `Memory Management driver `__, + - `Heaps Management `__, + - `Demand Paging `__, + + - MPP Memory Management - SOF extension, + + - Memory Heaps initialization for supported memory zones, + - Memory allocation from selectable memory zones, + +.. uml:: images/memory_management_layers.pu + :caption: Example of Memory Management layers and interfaces + +Read More +********* + +.. toctree:: + :maxdepth: 1 + + memory_zones + mpp_memory_management + heap_sharing + memory_management_driver + memory_management_flows diff --git a/architectures/firmware/sof-zephyr/rtos_layer/memory_management/memory_management_driver.rst b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/memory_management_driver.rst new file mode 100644 index 00000000..097c450f --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/memory_management_driver.rst @@ -0,0 +1,21 @@ +Memory Management Driver +######################## + +The Memory Management Driver (MMD) is part of the Zephyr distributed drivers. +Each SoC may require unique Memory Management driver implementation. The MMD +shall implement common MMD interface that is exposed to kernel services. This +allows for explicit allocation and mapping of individual memory hardware pages +within the physical environment. + +All operations within Memory Management Driver are explicit. Hardware page IDs +represent real physical blocks of hardware memory. + +The MMD is responsible for identification what part of the SoC memory is used by +the base firmware (code, data, bss) and unmap the unused blocks. The unused +memory will be available for dynamic allocation. Base firmware code, read only +data and BSS are mapped in the TLB automatically with corresponding flags (CODE, +RODATA) to prevent incidental modification. + +Memory Management Driver can maintain memory power at a granular level if the +architecture support it. It has possibility to power up selected memory banks on +map requests and power down on unmap, which is a recommended flow. diff --git a/architectures/firmware/sof-zephyr/rtos_layer/memory_management/memory_management_flows.rst b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/memory_management_flows.rst new file mode 100644 index 00000000..aa90ebb2 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/memory_management_flows.rst @@ -0,0 +1,41 @@ +Flows +##### + +Memory initialization +********************* + +Main goal of Memory initialization is to unmap unused memory after firmware load +and create heaps for supported memory zones. + +.. uml:: images/memory_initialization.pu + :caption: Memory initialization flow + +Memory allocation +***************** + +The common memory allocation is expected to use one of the available memory +zones via Zephyr Heap that was created during initialization. + +.. uml:: images/memory_allocation.pu + :caption: Memory allocation example flow + +Memory allocation directly using Memory Management Driver +********************************************************* + +In specific use cases (e.g. Dynamic Component Load) it may be required to +allocate memory directly using Memory Management Driver to control what virtual +address will be mapped to physical memory. + +.. uml:: images/memory_allocation_from_memory_driver.pu + :caption: Example memory allocation using Memory Management Driver + +Dynamic Component Load +********************** + +The loadable components are stored in Loadable Library memory zone and can be +loaded on instantiate request to System memory. The components load to System +memory is optional and integrator can indicate if the components can be executed +directly from the Loadable Library memory zone. + +.. uml:: images/dynamic_module_load.pu + :caption: Dynamic component load and instantiation flow diff --git a/architectures/firmware/sof-zephyr/rtos_layer/memory_management/memory_zones.rst b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/memory_zones.rst new file mode 100644 index 00000000..5be17be8 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/memory_zones.rst @@ -0,0 +1,11 @@ +Memory Zones +############ + +Depending on the memory use case a different memory zone can be used for +allocation. Application and MPP layer components are using memory zones and +capabilities to identify a target memory. The memory zones mapping on physical +addresses is SoC specific. If the SoC support multiple memory types with +different characteristics, then it is up to SoC integrator to decide which +memory will be most suitable for zone mapping. For example, if SoC has access to +slow but large capacity memory then it can map it for Loadable Library memory +zone. diff --git a/architectures/firmware/sof-zephyr/rtos_layer/memory_management/mpp_memory_management.rst b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/mpp_memory_management.rst new file mode 100644 index 00000000..2f079186 --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/mpp_memory_management.rst @@ -0,0 +1,19 @@ +MPP Memory Management +##################### + +MPP Memory Management (MPP MM) is a SOF extension running on top of Zephyr +Memory Manager. The reason to create MPP MM was to add support for memory zones, +which are not natively supported by Zephyr. Zephyr by default initialize single +System Heap. + +The MPP MM roles: + + - initialization of Memory Heaps for supported memory zones, + - provide allocator API for memory allocation from different memory zones, + +Memory Heaps initialization is done based on SoC Memory Map that identify start +and end addresses of memory zones. + +.. note:: + Memory zones are expected to be defined as memory sections in a SoC linker script. + From 7be4c54a8b3cc6039572f34e507e1b5df328d1b5 Mon Sep 17 00:00:00 2001 From: Marcin Maka Date: Thu, 20 Oct 2022 12:07:53 +0200 Subject: [PATCH 082/150] arch: fw: add heap sharing concept Signed-off-by: Marcin Maka --- .../memory_management/heap_sharing.rst | 52 +++++++++++++++++-- .../memory_management/images/heaps.pu | 31 +++++++++++ 2 files changed, 78 insertions(+), 5 deletions(-) create mode 100644 architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/heaps.pu diff --git a/architectures/firmware/sof-zephyr/rtos_layer/memory_management/heap_sharing.rst b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/heap_sharing.rst index 6819c0df..1b7d0347 100644 --- a/architectures/firmware/sof-zephyr/rtos_layer/memory_management/heap_sharing.rst +++ b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/heap_sharing.rst @@ -3,14 +3,56 @@ Heap sharing The memory heap can be: -- private - attached to one of the DSPs, +- local - used exclusively by a single DSP core, - shared - higher level memory shared across all DSP cores -The shared memories are co-managed by all DSP cores that have access to it. +.. uml:: images/heaps.pu + :caption: Memory Heaps -The data structures needed to manage shared memories are initialized by primary -core, structure location in memory map is known at the build time and access to -it is controlled by mutex. +.. note:: Introduction of MMU will require a separate local application heap per + isolated domain. + +L1 Cache Coherency +****************** + +NOTE: This section applies to Intel systems without L1 cache coherency + +A local heap is used exclusively by a single DSP core. Therefore operations on +the allocated memory buffers do not require explicit L1 cache operations nor +data cache alignment. + +All operations performed on a local heap can be executed by the associated DSP +core only. The *move-to-another-core* operation is not permitted for allocated +buffers. + +A shared heap can be configured in two ways: + +1. To provide uncache aliases of buffer addresses to the clients, +2. To provide cacheable addresses to the clients. + +Option #1 is preferred, since does not require explicit L1 cache operations +when memory is accessed by a DSP core. However, all operations directly access +L2+ memory therefore it is not suitable for a low latency high performance data +processing case. + +Option #2 provides better performance but requires explicit L1 cache operations, +which are difficult to maintain and validate, as well as data cache alignment +for both client buffers and their descriptors, which creates an overhead. This +configuration should be avoided if possible unless a coherent API is available +to share the data. + +However, a one important exception to the shared memory accessed through uncached +alias is a data buffer connected between processing components running on +different cores. Locking and cache operations price could be payed to get much +better performance of accessing the data in the buffer which may be a +significant part of light weight LL processing modules DSP cycle budget. + +Accessing Shared Memory Pool +**************************** + +The data structures needed to manage shared memories are initialized by the +primary core, structure location in memory map is known at the build time and +API is protected by the mutex. The mutex uses atomic operation behind and all processors co-managing this memory heap must support atomics. diff --git a/architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/heaps.pu b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/heaps.pu new file mode 100644 index 00000000..582b21bd --- /dev/null +++ b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/images/heaps.pu @@ -0,0 +1,31 @@ +scale max 1024 width + +node "DSP Core #0 Memory Block" as core_0 { + node "Application Heap (local)" as app_0 #lightgreen { + component "Pipelines @Core #0" as ppl_0 + component "LL Modules & Tasks @Core #0" as ll_0 + component "DP Modules & Tasks @Core #0" as dp_0 + } + + node "Application Heap (shared)" as app_shared_0 #lightyellow { + component "Shared buffers" + } + + node "System Heap (shared)" as sys_0 #lightblue { + component "Devices" + } +} + +ppl_0 -[hidden]down-> ll_0 +ll_0 -[hidden]down-> dp_0 + +node "DSP Core #1 Memory Block" as core_1 { + node "Application Heap (local)" as app_1 #lightgreen { + component "Pipelines @Core #1" as ppl_1 + component "LL Modules & Tasks @Core #1" as ll_1 + component "DP Modules & Tasks @Core #1" as dp_1 + } +} + +ppl_1 -[hidden]down-> ll_1 +ll_1 -[hidden]down-> dp_1 From 50c03ea6ffc16b2b7fc8d4e9da09d6dd663ca0ae Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Tue, 7 Feb 2023 14:35:44 -0600 Subject: [PATCH 083/150] getting_started: add information and links for HDAudio command snooping Add information provided by end-users who reversed-engineered the Windows audio driver configuration. Link: https://github.com/thesofproject/linux/issues/4176 Signed-off-by: Pierre-Louis Bossart --- getting_started/intel_debug/suggestions.rst | 41 +++++++++++++++------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/getting_started/intel_debug/suggestions.rst b/getting_started/intel_debug/suggestions.rst index 68541bc7..6c36a6b5 100644 --- a/getting_started/intel_debug/suggestions.rst +++ b/getting_started/intel_debug/suggestions.rst @@ -22,24 +22,41 @@ snd-intel-dspcfg dsp_driver=1" to ``/etc/modprobe.d/alsa-base.conf``. If no sound can be heard and jack detection is not functional, an HDaudio external codec configuration is likely. In some cases, the Linux drivers are missing configuration information and may only -enable two of the four speakers present. All of these cases are orthogonal -to SOF issues in that the SOF driver cannot compensate for codec driver -problems on its own. +enable two of the four speakers present. + +All of these cases are orthogonal to SOF issues in that the SOF driver +cannot compensate for codec driver problems on its own. The HDaudio +codec configuration is handled by the legacy HDAudio driver +(snd-hda-intel), which is not maintained directly by SOF developers. Try booting into Windows first, then reboot into Linux ****************************************************** -On some platforms, such as with an HDaudio codec connected to amplifiers -over an I2C/I2S link, the codec driver needs to perform a set of -amplifier configurations. This is often handled in Windows but not in -Linux codec drivers. A classic example of such issues is when +On some platforms, such as with an HDaudio codec connected to +amplifiers over an I2C/I2S link, the codec driver needs to perform a +set of amplifier configurations. This is often handled in Windows but +not in Linux codec drivers. A classic example of such issues is when headphone playback works, but speaker playback does not (or not on all -speakers). +speakers). Booting first in Windows then rebooting in Linux may help +setup the right configuration, but additional work is needed to patch +the Linux kernel. + +Reverse-engineer the Windows audio driver +***************************************** + +The HDaudio driver configures the codec with 'verb' commands to +e.g. setup the 'pins' or a coefficient. The exact values used are +device-specific, and in the absence of any documentation from the +codec vendor need to be reverse-engineered by snooping HDAudio +commands in a Windows environment. + +The following links provide additional information on snooping the +commands and determining what needs to be added to the Linux +kernel. These links are not maintained by SOF developers. + +* `ASUS Linux blog `_ -These types of issues also occur with the HDaudio legacy driver -and are not part of SOF bugs proper. To fix such issues, either obtain -direct support from the codec vendor, or reverse-engineer the missing -configuration by snooping HDaudio commands in a Windows environment. +* `How to sniff verbs from a Windows sound driver `_ Make sure the ME is enabled *************************** From c0a2a285c43d2f5bfe764806f6f6ef33652c4ea3 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 16 Mar 2023 15:20:44 +0200 Subject: [PATCH 084/150] getting_started: intel_debug: Update the sof-dyndbg.conf example The current version is outdated, update it to align with what we use +p to +pmf for example. Signed-off-by: Peter Ujfalusi --- getting_started/intel_debug/suggestions.rst | 58 +++++++++++++++------ 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/getting_started/intel_debug/suggestions.rst b/getting_started/intel_debug/suggestions.rst index 6c36a6b5..7e9d2d2e 100644 --- a/getting_started/intel_debug/suggestions.rst +++ b/getting_started/intel_debug/suggestions.rst @@ -114,23 +114,47 @@ file: .. code-block:: cfg - options snd_sof_intel_byt dyndbg=+p - options snd_sof_intel_bdw dyndbg=+p - options snd_sof_intel_ipc dyndbg=+p - options snd_sof_intel_hda_common dyndbg=+p - options snd_sof_intel_hda dyndbg=+p - options snd_sof dyndbg=+p - options snd_sof_pci dyndbg=+p - options snd_sof_acpi dyndbg=+p - options snd_sof_of dyndbg=+p - options snd_sof_nocodec dyndbg=+p - options soundwire_bus dyndbg=+p - options soundwire_generic_allocation dyndbg=+p - options soundwire_cadence dyndbg=+p - options soundwire_intel_init dyndbg=+p - options soundwire_intel dyndbg=+p - options snd_soc_skl_hda_dsp dyndbg=+p - options snd_intel_dspcfg dyndbg=+p + # ACPI + options snd_sof_acpi dyndbg=+pmf + options snd_sof_acpi_intel_byt dyndbg=+pmf + options snd_sof_acpi_intel_bdw dyndbg=+pmf + options snd_sof_intel_byt dyndbg=+pmf + options snd_sof_intel_bdw dyndbg=+pmf + + # PCI + options snd_sof_pci dyndbg=+pmf + options snd_sof_pci_intel_apl dyndbg=+pmf + options snd_sof_pci_intel_cnl dyndbg=+pmf + options snd_sof_pci_intel_icl dyndbg=+pmf + options snd_sof_pci_intel_tgl dyndbg=+pmf + options snd_sof_pci_intel_mtl dyndbg=+pmf + options snd_sof_pci_intel_lnl dyndbg=+pmf + + # DSP selection + options snd_intel_dspcfg dyndbg=+pmf + options snd_intel_sdw_acpi dyndbg=+pmf + + # SOF internals + options snd_sof_intel_ipc dyndbg=+pmf + options snd_sof_intel_hda_common dyndbg=+pmf + options snd_sof_intel_hda_mlink dyndbg=+pmf + options snd_sof_intel_hda dyndbg=+pmf + options snd_sof dyndbg=+pmf + options snd_sof_nocodec dyndbg=+pmf + + # HDA + options snd_hda_intel dyndbg=+pmf + options snd-hda-codec-realtek dyndbg=+pmf + options snd-hda-codec-generic dyndbg=+pmf + options snd-hda-codec-hdmi dyndbg=+pmf + options snd-hda-codec dyndbg=+pmf + + # SoundWire core + options soundwire_bus dyndbg=+pmf + options soundwire_generic_allocation dyndbg=+pmf + options soundwire_cadence dyndbg=+pmf + options soundwire_intel_init dyndbg=+pmf + options soundwire_intel dyndbg=+pmf Note that this list is only an example. From b0d207a3d26e43522891fb51c7d9f0fda0355e44 Mon Sep 17 00:00:00 2001 From: Marcin Maka Date: Wed, 29 Mar 2023 11:00:02 +0200 Subject: [PATCH 085/150] arch: fw: cleanup links in memory management overview Initial description was unbalanced. One section contained links while the other had the links moved to the Read More section below the diagram. Now all the links are moved to the Read More. External links are annotated to let the reader know that opening results in move to another website. Signed-off-by: Marcin Maka --- .../rtos_layer/memory_management/index.rst | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/architectures/firmware/sof-zephyr/rtos_layer/memory_management/index.rst b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/index.rst index c658ee02..68d4e180 100644 --- a/architectures/firmware/sof-zephyr/rtos_layer/memory_management/index.rst +++ b/architectures/firmware/sof-zephyr/rtos_layer/memory_management/index.rst @@ -11,17 +11,12 @@ Overview The memory support functionality is delivered at two levels: - - `Zephyr Memory Management Service `__, + - Zephyr Memory Management Service, which provides memory drivers, demand + paging, allocators, and heap management, - - `Memory Blocks Allocator `__, - - `Memory Management driver `__, - - `Heaps Management `__, - - `Demand Paging `__, - - - MPP Memory Management - SOF extension, - - - Memory Heaps initialization for supported memory zones, - - Memory allocation from selectable memory zones, + - MPP Memory Management - SOF extension, which provides heaps for virtual + memory mapped to physical memory on demand, and declaration of SOF specific + heaps instantiated for various memory zones, .. uml:: images/memory_management_layers.pu :caption: Example of Memory Management layers and interfaces @@ -37,3 +32,12 @@ Read More heap_sharing memory_management_driver memory_management_flows + +External Links +============== + +- `Zephyr Memory Management Service `__ +- `Memory Blocks Allocator `__ +- `Memory Management driver `__ +- `Heaps Management `__ +- `Demand Paging `__ From 4b8367202687adc72068811aa3396e4fbf698a0a Mon Sep 17 00:00:00 2001 From: Deb Taylor Date: Thu, 30 Mar 2023 17:51:06 -0400 Subject: [PATCH 086/150] Release 250 (#459) * add yaml file updates Signed-off-by: Deb * Update Release to 2.5.0 Signed-off-by: Deb --------- Signed-off-by: Deb --- release.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.rst b/release.rst index 8c971457..72fed3a1 100755 --- a/release.rst +++ b/release.rst @@ -26,7 +26,7 @@ kernel, and documentation. Download the source code as a zip or tar.gz file: Source and Binary Releases -------------------------- -The latest SOF release is v2.4.1 (Jan 2023). +The latest SOF release is v2.5.5 (Mar 2023). View new feature information and release downloads for the latest and previous releases on GitHub. Firmware and SDK tool source code and binary From 1be34ee3b9711fba910956664538173caa693944 Mon Sep 17 00:00:00 2001 From: Deb Taylor Date: Thu, 30 Mar 2023 18:03:58 -0400 Subject: [PATCH 087/150] Rel250 (#460) * add yaml file updates Signed-off-by: Deb * Fix release mistake-2.5.0 instead of 2.5.5 Signed-off-by: Deb --------- Signed-off-by: Deb --- release.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.rst b/release.rst index 72fed3a1..837838c3 100755 --- a/release.rst +++ b/release.rst @@ -26,7 +26,7 @@ kernel, and documentation. Download the source code as a zip or tar.gz file: Source and Binary Releases -------------------------- -The latest SOF release is v2.5.5 (Mar 2023). +The latest SOF release is v2.5.0 (Mar 2023). View new feature information and release downloads for the latest and previous releases on GitHub. Firmware and SDK tool source code and binary From f9b33e9af7cf67a198c423d8f5cfb568a2748895 Mon Sep 17 00:00:00 2001 From: Chunxu Li Date: Fri, 14 Apr 2023 14:32:29 +0800 Subject: [PATCH 088/150] Supported Platforms: add mt8186 mediatek platform information Add mt8186 mediatek platform information to the table. Included clock, memory and audio controller instances to the table Signed-off-by: Chunxu Li --- platforms/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/platforms/index.rst b/platforms/index.rst index 9d80e0f7..5a9a302c 100644 --- a/platforms/index.rst +++ b/platforms/index.rst @@ -31,6 +31,7 @@ Platform and board specific support is continually added to the SOF project as d "AMD Renoir", "Xtensa HiFi3", "1 @ 200-600MHz", "TBD", "20 KB LP SRAM / 1152 KB IRAM/DRAM", "1 x SP (I2S, PCM), 1 x BT (I2S, PCM), DMIC" "AMD Rembrandt", "Xtensa HiFi5", "1 @ 200-800MHz", "TBD", "1.75 MB HP SRAM / 512 KB IRAM/DRAM", "1 x SP (I2S, PCM), 1 x BT (I2S, PCM), 1 x HS(I2S, PCM), DMIC" "Mediatek mt8195", "Xtensa HiFi4", "1 @ 220 - 720MHz", "TBD", "256 KB SRAM / 16 MB DRAM", "2 x TDM Out, 1 x TDM In, DMIC" + "Mediatek mt8186", "Xtensa HiFi5", "1 @ 300 - 800MHz", "TBD", "512 KB SRAM / DRAM", "2 x I2S Out, 1 x I2S In, DMIC" When support for a new platform is being added, certain interfaces required by SOF infrastructure must be implemented. Refer to Platform API documentation From ca78c57a4c9087a0190aa8db9375f1e894967948 Mon Sep 17 00:00:00 2001 From: Jason Chen Date: Fri, 21 Apr 2023 14:09:12 +0800 Subject: [PATCH 089/150] Supported Platforms: add mt8188 mediatek platform information Add mt8188 mediatek platform information to the table. Included clock, memory and audio controller instances to the table Signed-off-by: Jason Chen --- platforms/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/platforms/index.rst b/platforms/index.rst index 5a9a302c..57930c4a 100644 --- a/platforms/index.rst +++ b/platforms/index.rst @@ -32,6 +32,7 @@ Platform and board specific support is continually added to the SOF project as d "AMD Rembrandt", "Xtensa HiFi5", "1 @ 200-800MHz", "TBD", "1.75 MB HP SRAM / 512 KB IRAM/DRAM", "1 x SP (I2S, PCM), 1 x BT (I2S, PCM), 1 x HS(I2S, PCM), DMIC" "Mediatek mt8195", "Xtensa HiFi4", "1 @ 220 - 720MHz", "TBD", "256 KB SRAM / 16 MB DRAM", "2 x TDM Out, 1 x TDM In, DMIC" "Mediatek mt8186", "Xtensa HiFi5", "1 @ 300 - 800MHz", "TBD", "512 KB SRAM / DRAM", "2 x I2S Out, 1 x I2S In, DMIC" + "Mediatek mt8188", "Xtensa HiFi5", "1 @ 26 - 800MHz", "TBD", "512 KB SRAM / 17 MB DRAM", "2 x TDM Out, 1 x TDM In, DMIC" When support for a new platform is being added, certain interfaces required by SOF infrastructure must be implemented. Refer to Platform API documentation From c8abaf2f4e0c117436a29e8d36be80f54da85403 Mon Sep 17 00:00:00 2001 From: Michal Wasko Date: Tue, 25 Apr 2023 11:03:22 +0200 Subject: [PATCH 090/150] docbuild: docker support Docker image and build script added Signed-off-by: Michal Wasko --- contribute/process/docbuild.rst | 34 ++++++++++++++++- scripts/docker_build/Dockerfile | 56 ++++++++++++++++++++++++++++ scripts/docker_build/docker-build.sh | 34 +++++++++++++++++ 3 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 scripts/docker_build/Dockerfile create mode 100644 scripts/docker_build/docker-build.sh diff --git a/contribute/process/docbuild.rst b/contribute/process/docbuild.rst index 43f4998b..f1dd8f91 100644 --- a/contribute/process/docbuild.rst +++ b/contribute/process/docbuild.rst @@ -124,6 +124,11 @@ creating drawings: drawing syntax into an image. You need to have a Java runtime environment (JRE) installed when generating documentation. +There is a sof-docs Docker image recipe that can be used as an alternative to +installing the documentation tools on local OS. If you choose to use Docker then +please skip the tools installation steps and go directly to +:ref:`run_documentation_processors` + Depending on your Linux version, install the following tools: * For Ubuntu use: @@ -202,13 +207,18 @@ another ``make html`` and the output layout and style is changed. The ``read-the-docs`` theme is installed as part of the ``requirements.txt`` list above. +.. _run_documentation_processors: + Run documentation processors **************************** The sof-docs directory contains all the .rst source files, extra tools, and Makefile for generating a local copy of the SOF technical documentation. -* Generate the HTML output by using the following commands: +You can generate the HTML documentation by using local build tools (1) or by +Docker image (2) + +1. Generate the HTML output by using the following commands (**local build**): .. code-block:: bash @@ -228,6 +238,28 @@ If your changes are not related to any UML diagram, you can build more than 10 times faster from scratch by temporarily changing the ``plantuml_output_format`` line in :git-sof-docs-mainline:`conf.py`. +2. Generate the HTML output by using the following commands (**Docker build**): + + .. code-block:: bash + + cd thesofproject + # Build both sof (Doxygen) and sof-docs UML and reStruredText + ./sof-docs/scripts/docker_build/docker-build.sh + +The docker build script will copy the sof and sof-docs source code from host +working directory to image, build the documentation and when completed copy back +output to the host (./sof-docs/_build) + +The first docker build run will take more time due to image creation and +installation of all the necessary build tools. Each next build is much faster +and can additionally be speed up by selecting only sof-docs to build: + + .. code-block:: bash + + cd thesofproject + # Re-build only sof-docs + ./sof-docs/scripts/docker_build/docker-build.sh docs + Publish content *************** diff --git a/scripts/docker_build/Dockerfile b/scripts/docker_build/Dockerfile new file mode 100644 index 00000000..070f7209 --- /dev/null +++ b/scripts/docker_build/Dockerfile @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2023 Intel Corporation. All rights reserved. +# +# Defines a docker image that can build Sound Open Firmware documentation +# +# Usage: +# create parent directory for sof and sof-docs repository (e.g. thesofproject) +# clone sof repository to thesofproject\sof folder +# clone sof-docs repository to thesofproject\sof-docs folder +# build docker image from parent directory .\thesofproject: +# > docker build -t ubuntu-sofdocs -f ./sof-docs/scripts/docker_build/Dockerfile ./ +# run the image container: +# > docker run -d --name sofdocs_container ubuntu-sofdocs sleep infinity +# copy build output from container to host: +# > docker cp sofdocs_container:/home/thesofproject/sof/doc ./sof/ +# > docker cp sofdocs_container:/home/thesofproject/sof-docs/_build ./sof-docs/ +# stop the container: +# docker stop sofdocs_container +# +# Note: The first build can take time to setup ubuntu and install tools, +# but each next one will repeat only copy and build steps. +# + +FROM dokken/ubuntu-22.04 + +# Set image working directory +WORKDIR /home/thesofproject + +RUN apt-get update + +# Install sof-docs build tools +RUN apt-get install -y python3.6 +RUN apt-get install -y doxygen python3-pip python3-wheel make \ + default-jre graphviz cmake ninja-build + +# Copy sof-docs file with dependency tools list +COPY ./sof-docs/scripts/requirements.txt /home/thesofproject/sof-docs/scripts/requirements.txt + +# Install sof-docs requirements tools +RUN pip3 install --user -r /home/thesofproject/sof-docs/scripts/requirements.txt + +# Directly install sphinx to add 'sphinx-build' to the system +RUN apt-get install -y python3-sphinx + +# Copy sof source code from host to image +COPY ./sof/ /home/thesofproject/sof/ + +# Build API documentation from SOF source (Doxygen) +RUN cmake -S sof/doc -B sof/doc -GNinja +RUN ninja -C sof/doc -v doc + +# Copy sof-docs source code from host to image +COPY ./sof-docs/ /home/thesofproject/sof-docs/ + +# Build sof-docs, ignore eventual errors to complete image creation +RUN make -C sof-docs VERBOSE=1 html; exit 0 diff --git a/scripts/docker_build/docker-build.sh b/scripts/docker_build/docker-build.sh new file mode 100644 index 00000000..e16e7507 --- /dev/null +++ b/scripts/docker_build/docker-build.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2023 Intel Corporation. All rights reserved. + +build_docs_only="FALSE" +if [ $# -eq 1 ] && [[ $1 = "docs" ]]; then + build_docs_only="TRUE" + echo "Re-build sof-docs only." +fi + +# Build documentation using docker image +docker build -t ubuntu-sofdocs -f ./sof-docs/scripts/docker_build/Dockerfile ./ + +# Run image container to copy output. +# Add sleep infinity to keep container running. +docker run -d --rm --name sofdocs_container ubuntu-sofdocs sleep infinity + +if [ $build_docs_only = "FALSE" ]; then + echo "Copy SOF Doxygen generated documentation from container to host ./sof/doc/" + docker cp sofdocs_container:/home/thesofproject/sof/doc ./sof/ +fi + +echo "Copy SOF-DOCS generated documentation from container to host ./sof-docs/_build .." +docker cp sofdocs_container:/home/thesofproject/sof-docs/_build ./sof-docs/ + +echo "Stop the sofdocs_container" +docker stop sofdocs_container + +# It is required to prevent stacking of images for each build run +echo "Remove dangling docker images" +docker image prune --force + +echo "Press key to exit..." +read -n 1 k <&1 From e772198302117b224d71dd171686a8b4a36af147 Mon Sep 17 00:00:00 2001 From: "Dobrowolski, PawelX" Date: Fri, 28 Apr 2023 09:21:38 +0200 Subject: [PATCH 091/150] fix: typo in label Signed-off-by: Dobrowolski, PawelX --- .../firmware/sof-common/components/component-module-api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/architectures/firmware/sof-common/components/component-module-api.rst b/architectures/firmware/sof-common/components/component-module-api.rst index 6441f421..15560b87 100644 --- a/architectures/firmware/sof-common/components/component-module-api.rst +++ b/architectures/firmware/sof-common/components/component-module-api.rst @@ -1,4 +1,4 @@ -.. apps-comp-world: +.. _apps-comp-world: Component & Module Interfaces ############################# From 2c3a550538acbb92b9f261a6710aba5fa7f59e70 Mon Sep 17 00:00:00 2001 From: "Dobrowolski, PawelX" Date: Wed, 19 Apr 2023 14:38:37 +0200 Subject: [PATCH 092/150] Getting Started: introduce loadable modules Add guide describing how loadable modules are build using LMDK (Loadable Module Development Kit). Signed-off-by: Dobrowolski, PawelX --- .../app_layer/images/app_layer_diagram.pu | 8 ++--- .../firmware/sof-zephyr/app_layer/index.rst | 33 ++++++++++++------- getting_started/index.rst | 9 +++++ .../loadable_modules/lmdk_user_guide.rst | 25 ++++++++++++++ 4 files changed, 60 insertions(+), 15 deletions(-) create mode 100644 getting_started/loadable_modules/lmdk_user_guide.rst diff --git a/architectures/firmware/sof-zephyr/app_layer/images/app_layer_diagram.pu b/architectures/firmware/sof-zephyr/app_layer/images/app_layer_diagram.pu index a3581f25..dea00068 100644 --- a/architectures/firmware/sof-zephyr/app_layer/images/app_layer_diagram.pu +++ b/architectures/firmware/sof-zephyr/app_layer/images/app_layer_diagram.pu @@ -7,7 +7,7 @@ package "SOF" { package "Application layer" as APP_CUSTOMIZATION { - package "Example Loadable Components" as LOADABLE_COMPONENTS { + package "Example Loadable Module" as LOADABLE_MODULE { component "3rd Party Post-Processing" as PROCESSING_3RD_PARTY component "WoV" as WOV_MODULE component "ACA" as ACA_MODULE @@ -18,7 +18,7 @@ package "SOF" { ACA_MODULE -[hidden]right- OTHER_MODULES } - package "Built-in Components" as BUILTIN_COMPONENTS { + package "Built-in Module" as BUILTIN_MODULE { component "Copier" as COPIER component "SRC" as SRC component "Mixers" as MIXERS @@ -31,7 +31,7 @@ package "SOF" { HISTORY_BUFFER -[hidden]right- PROBE } - BUILTIN_COMPONENTS -[hidden]down- LOADABLE_COMPONENTS + BUILTIN_MODULE -[hidden]down- LOADABLE_MODULE } package "System Services" as SYS_SERVICES { @@ -58,7 +58,7 @@ package "SOF" { } APP_CUSTOMIZATION -[hidden]down- SYS_SERVICES - BUILTIN_COMPONENTS .down. SS + BUILTIN_MODULE .down. SS PROCESSING_3RD_PARTY .down. SS WOV_MODULE .down. SS ACA_MODULE .down. SS diff --git a/architectures/firmware/sof-zephyr/app_layer/index.rst b/architectures/firmware/sof-zephyr/app_layer/index.rst index 0ee0f56e..fba32384 100644 --- a/architectures/firmware/sof-zephyr/app_layer/index.rst +++ b/architectures/firmware/sof-zephyr/app_layer/index.rst @@ -3,38 +3,49 @@ Application Layer ################# -Application Layer represents the built-in FW processing components, loadable FW -components and example templates with application libraries required for -components integration. Application layer content is assumed to be open source +Application Layer represents the built-in FW modules (processing components), loadable FW +modules and example templates with application libraries required for +modules integration. Application layer content is assumed to be open source and only proprietary 3rd party components should remain private. .. uml:: images/app_layer_diagram.pu :caption: Application Layer -Components in Application Layer -******************************* +Modules in Application Layer +**************************** -The built-in components are built together with base firmware and they have +The built-in modules are built together with base firmware and they have direct access to all firmware drivers and service APIs. When built-in module is enabled in configuration, it is guaranteed to exist in firmware binary. -The loadable components are built separately from base firmware and they are +The loadable modules are built separately from base firmware and they are loaded dynamically as a separate binary, depending on the host audio -configuration. +configuration. To build, use LMDK(Loadable Module Development Kit) +which is standalone kit containing all required files. -All the application layer components access base firmware services via System +All the application layer module access base firmware services are via the System Services ABI. -**NOTE:** The built-in components are utility components provided by base +**NOTE:** The built-in modules are utility components provided by the base firmware/kernel. -Examples of built-in components: +Examples of built-in modules: * Audio built-in components: Copiers, Mixers, Volume, SRC, etc. +Example how to build a loadable module: + +* Example Up-Down-Mixer build using :ref:`lmdk_user_guide` + Probe ===== The probe module is special module in FW infrastructure that allows to inject or extract data from a specified probe point. The traditional client platforms use HDA DMAs to transfer data in and out of such module. + +Loadable Modules +================ + +The loadable modules are build into separate binaries from the main SOF build. To communicate with them +is used native system agent and to control is used module api :ref:`apps-comp-world`. diff --git a/getting_started/index.rst b/getting_started/index.rst index a932ec3a..3d585a7c 100755 --- a/getting_started/index.rst +++ b/getting_started/index.rst @@ -75,3 +75,12 @@ This section provides guides for integrators and for users working with i.MX pla nxp/sof_imx_user_guide +Building loadable modules using LMDK +************************************ + +This section descibes process of building loadable modules using LMDK. + +.. toctree:: + :maxdepth: 1 + + loadable_modules/lmdk_user_guide diff --git a/getting_started/loadable_modules/lmdk_user_guide.rst b/getting_started/loadable_modules/lmdk_user_guide.rst new file mode 100644 index 00000000..b6085e01 --- /dev/null +++ b/getting_started/loadable_modules/lmdk_user_guide.rst @@ -0,0 +1,25 @@ +.. _lmdk_user_guide: + +Loadable modules build guide using LMDK +####################################### + +What is LMDK +************ + +LMDK(Loadable Module Development Kit) is a standalone package required to build loadable module. It is independent from SOF FW but contains necessary data structures to interact with it. + +How to build +************ + +To build example loadable library execute: +.. code-block:: bash + + $ cd libraries/example + $ mkdir build + $ cd build + + $ cmake -DRIMAGE_COMMAND="/path/to/rimage" -DSIGNING_KEY="/path/to/signing/key.pem" .. + $ cmake --build . + +Here RIMAGE_COMMAND is path to rimage executable binary, SIGNING_KEY is path to +signing key for rimage. `LMDK ` From c944238e412a1c05b7cf2cc2995a1972fbc1e760 Mon Sep 17 00:00:00 2001 From: Deb Taylor Date: Thu, 29 Jun 2023 13:23:42 -0600 Subject: [PATCH 093/150] Release update (#470) * add yaml file updates Signed-off-by: Deb * Update release tags for v2.6 Signed-off-by: Deb --------- Signed-off-by: Deb --- conf.py | 2 +- release.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/conf.py b/conf.py index 2ee473e9..8352df0c 100755 --- a/conf.py +++ b/conf.py @@ -81,7 +81,7 @@ # |version| and |release|, also used in various other places throughout the # built documents. -version = release = "2.4.1" +version = release = "2.5.0" # # The short X.Y version. diff --git a/release.rst b/release.rst index 837838c3..0fa459e4 100755 --- a/release.rst +++ b/release.rst @@ -26,7 +26,7 @@ kernel, and documentation. Download the source code as a zip or tar.gz file: Source and Binary Releases -------------------------- -The latest SOF release is v2.5.0 (Mar 2023). +The latest SOF release is v2.6.0 (June 2023). View new feature information and release downloads for the latest and previous releases on GitHub. Firmware and SDK tool source code and binary From e79c6f10a52e3e6e520f294cc853b432e0ac54a3 Mon Sep 17 00:00:00 2001 From: Alexander Boehm Date: Wed, 24 May 2023 13:24:15 +0200 Subject: [PATCH 094/150] logger: fix typos, long lines Apart from the title content: While using 'filtration' and 'filtering' interchangeably is not a real error, consistent use of one or the other seems better. Changed to 'filtering'. Signed-off-by: Alexander Boehm --- developer_guides/debugability/logger/index.rst | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/developer_guides/debugability/logger/index.rst b/developer_guides/debugability/logger/index.rst index fd53b7dd..a141d98a 100644 --- a/developer_guides/debugability/logger/index.rst +++ b/developer_guides/debugability/logger/index.rst @@ -204,18 +204,21 @@ Instance descriptions can have one of the following forms: - ``X.*`` - each component on selected pipeline *X* - ``X.Y`` - component on pipeline *X* with id *Y* -Trace level changes works in the same order as options given in a command line, and a new set overwrites old values. It allows you to easily enable verbose logs only for selected components and keep the lowest possible log level (critical) for others, as shown in the following example: +Trace level changes work in the same order as options given in a command line, and a new set overwrites old values. +It allows you to easily enable verbose logs only for selected components and keep the lowest possible log level (critical) for +others, as shown in the following example: sof-logger -l ldc_file -t -Fcritical=* -Fverbose="dai*, volume1.1" A similar example may be prepared for components on a particular pipeline: - sof-loggerr -l ldc_file -t -Fc=* -Fv=*1.* + sof-logger -l ldc_file -t -Fc=* -Fv=*1.* .. note:: To track a verbose message, select the "Trace verbose" option under the "Trace" menu from the firmware build. -Active trace filters are stored in the firmware runtime memory, so after a firmware restart (such as after power gating in sleep mode) filters settings will be reset. +Active trace filters are stored in the firmware runtime memory, so after a firmware restart (such as after power gating +in sleep mode) filters settings will be reset. Consider disabling power gating during your debug session by entering the following: @@ -231,7 +234,7 @@ Consider disabling power gating during your debug session by entering the follow cat /sys/devices/pci0000\:00/0000\:$(lspci -nn | grep "audio controller" | awk '{print $1;}')/power/runtime_status -The logger trace filtration affects only traces sent after the filter setup, +The logger trace filtering affects only traces sent after the filter setup, so traces already stored on the kernel side are not affected. Filters are set up incrementally, so when loggers are run twice with @@ -242,11 +245,11 @@ default state, a firmware reset is needed. Detailed description -------------------- -The filtration mechanism occurs on the firmware side so, after changing the -log level to verbose for each component, the DSP can be overhelmed by +The filtering mechanism occurs on the firmware side so, after changing the +log level to verbose for each component, the DSP can be overwhelmed by tracing. -Core functionality is provided by the DSP, so filtration does not work in +Core functionality is provided by the DSP, so filtering does not work in offline mode - during conversion in a previously saved input file. Communication between the firmware and logger is occurs through driver From 9da4405b6669aa92406dbe4795e54cb731ff519b Mon Sep 17 00:00:00 2001 From: Alexander Boehm Date: Wed, 24 May 2023 13:32:37 +0200 Subject: [PATCH 095/150] logger: restructure for better readability Moved trace filtering details to a dedicated section and rephrased third sub-point. Own section for 'power gating' notes plus re-wording of first two sentences. Signed-off-by: Alexander Boehm --- .../debugability/logger/index.rst | 55 +++++++++++-------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/developer_guides/debugability/logger/index.rst b/developer_guides/debugability/logger/index.rst index a141d98a..d3f84aeb 100644 --- a/developer_guides/debugability/logger/index.rst +++ b/developer_guides/debugability/logger/index.rst @@ -129,7 +129,7 @@ Examples .. note:: - debugfs files used by ``sof-logger`` + debugfs files used by sof-logger: - ``etrace``: direct access to the shared TRACE window of the SOF firmware - ``trace``: using DMA to stream debug trace information from SOF firmware (on @@ -214,12 +214,17 @@ A similar example may be prepared for components on a particular pipeline: sof-logger -l ldc_file -t -Fc=* -Fv=*1.* -.. note:: - To track a verbose message, select the "Trace verbose" option under the "Trace" menu from the firmware build. +Verbose and debug log levels +---------------------------- + +To enable verbose and debug trace messages, select the "Trace->Trace verbose" option in the firmware build +menuconfig (in addition to setting the proper log levels as described above). -Active trace filters are stored in the firmware runtime memory, so after a firmware restart (such as after power gating -in sleep mode) filters settings will be reset. +Disabling DSP power gating +-------------------------- +After a firmware reset (such as after power gating in suspend mode) custom filter settings will be lost. +Thus consider disabling power gating during your debug session. The way this is done is slightly different on every platform, Consider disabling power gating during your debug session by entering the following: .. code:: bash @@ -234,29 +239,31 @@ Consider disabling power gating during your debug session by entering the follow cat /sys/devices/pci0000\:00/0000\:$(lspci -nn | grep "audio controller" | awk '{print $1;}')/power/runtime_status -The logger trace filtering affects only traces sent after the filter setup, -so traces already stored on the kernel side are not affected. -Filters are set up incrementally, so when loggers are run twice with -different settings, then filters from the first run will not be restored to -the default state but will be replaced by a new one. To reset filters to the -default state, a firmware reset is needed. -Detailed description --------------------- +Trace filtering details +----------------------- + +* The filtering mechanism occurs on the firmware side so, after changing the + log level to verbose for each component, the DSP can be overwhelmed by + tracing. + +* Core functionality is provided by the DSP, so filtering does not work in + offline mode - during conversion in a previously saved input file. -The filtering mechanism occurs on the firmware side so, after changing the -log level to verbose for each component, the DSP can be overwhelmed by -tracing. +* The trace filtering affects only traces sent after the filter setup, + so traces already stored on the kernel side are not affected. If a certain log level is needed before a filter has been setup the DECLARE_TR_CTX() + macro at the beginning of the respective component's source file can be adapted. -Core functionality is provided by the DSP, so filtering does not work in -offline mode - during conversion in a previously saved input file. +* Filters are set up incrementally, so when loggers are run twice with + different settings, then filters from the first run will not be restored to + the default state but will be replaced by a new one. Active trace filters are stored in the firmware runtime memory. To reset the filters to the + default state, a firmware reset is needed. -Communication between the firmware and logger is occurs through driver -debug file systems. The logger writes new trace settings to ``sys/kernel/debug/sof/filter``. These will be used to create *IPC* messages with new -trace levels. A simple text data format is used: +* Communication between the firmware and logger occurs through the kernel debugfs. The logger writes new trace settings to ``sys/kernel/debug/sof/filter``. + These will be used to create *IPC* messages with new trace levels. A simple text data format is used: -``log1_level uuid1_id pipe1_id comp1_id; [log2_level uuid2_id pipe2_id comp2_id;]\n`` + ``log1_level uuid1_id pipe1_id comp1_id; [log2_level uuid2_id pipe2_id comp2_id;]\n`` -Any unused uuid_id should be set here to 0; other unused fields should be -set to -1. ``log_level`` must always be set to a valid value that represents ``LOG_LEVEL_*`` defined values. + Any unused uuid_id should be set here to 0; other unused fields should be + set to -1. ``log_level`` must always be set to a valid value that represents ``LOG_LEVEL_*`` defined values. From 98db4c4de00a14b8c24bd4a0238632465365a96e Mon Sep 17 00:00:00 2001 From: Alexander Boehm Date: Wed, 24 May 2023 12:02:53 +0200 Subject: [PATCH 096/150] logger: add note about dropped logs At least on i.MX8m+ sof-logger output sometimes contains errors about dropped logs, even with default verbosity settings. Increasing DMA_TRACE_LOCAL_SIZE helps, so mention that here. Signed-off-by: Alexander Boehm --- developer_guides/debugability/logger/index.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/developer_guides/debugability/logger/index.rst b/developer_guides/debugability/logger/index.rst index d3f84aeb..fcad66b9 100644 --- a/developer_guides/debugability/logger/index.rst +++ b/developer_guides/debugability/logger/index.rst @@ -150,6 +150,9 @@ Examples file and start reading from position 0 and thus be in sync with the firmware when it is resumed. + Sometimes error messages about dropped logs are printed. If that is a problem, + increasing DMA_TRACE_LOCAL_SIZE in the relevant platform.h file can be helpful. + Trace filtering *************** From c4e5285e6b2e1adc9328532d05c84b3ef9439fc3 Mon Sep 17 00:00:00 2001 From: Alexander Boehm Date: Wed, 24 May 2023 12:18:50 +0200 Subject: [PATCH 097/150] logger: add how to disable fw suspend for imx8mp Firmware suspension can be undesirable when using sof-logger, thus added how to prevent it on imx8mp. Likely can be generalized to other imx SOCs without much effort. Signed-off-by: Alexander Boehm --- developer_guides/debugability/logger/index.rst | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/developer_guides/debugability/logger/index.rst b/developer_guides/debugability/logger/index.rst index fcad66b9..17e41d1c 100644 --- a/developer_guides/debugability/logger/index.rst +++ b/developer_guides/debugability/logger/index.rst @@ -228,21 +228,23 @@ Disabling DSP power gating After a firmware reset (such as after power gating in suspend mode) custom filter settings will be lost. Thus consider disabling power gating during your debug session. The way this is done is slightly different on every platform, -Consider disabling power gating during your debug session by entering the following: +two examples follow: -.. code:: bash +1. Intel PCI based: + +.. code-block:: bash sudo su echo on >/sys/devices/pci0000\:00/0000\:$(lspci -nn | grep "audio contoller" | awk '{print $1;}')/power/control -.. note:: - The current device power status can be read by entering this command: - - .. code:: bash +2. NXP imx8mp: - cat /sys/devices/pci0000\:00/0000\:$(lspci -nn | grep "audio controller" | awk '{print $1;}')/power/runtime_status +.. code-block:: bash + sudo su + echo on>/sys/class/devlink/platform:power-domains:audiomix-pd--platform:3b6e8000.dsp/consumer/power/control +To re-enable automatic suspend use ``echo auto``, the current status can be read from the runtime_status file in these sysfs directories. Trace filtering details ----------------------- From 767dbc2a2a2d88fb0d77fd6245a8d3c5f04b01d1 Mon Sep 17 00:00:00 2001 From: Benjamin Blacher Date: Fri, 2 Jun 2023 09:36:05 +0000 Subject: [PATCH 098/150] Update install_locally to match the directory created in prepare_build_environment The directory mentioned in install_locally doesn't match the one mentioned in prepare_build_environment. This commit fixes this. --- getting_started/setup_linux/install_locally.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting_started/setup_linux/install_locally.rst b/getting_started/setup_linux/install_locally.rst index d70f9774..30df80af 100644 --- a/getting_started/setup_linux/install_locally.rst +++ b/getting_started/setup_linux/install_locally.rst @@ -16,7 +16,7 @@ Make sure you have `set up your development environment Date: Wed, 7 Jun 2023 09:04:18 +0000 Subject: [PATCH 099/150] Update install_locally Change other occurrences of ~/sof/linux to ~/work/sof/linux --- getting_started/setup_linux/install_locally.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/getting_started/setup_linux/install_locally.rst b/getting_started/setup_linux/install_locally.rst index 30df80af..ce50ec8f 100644 --- a/getting_started/setup_linux/install_locally.rst +++ b/getting_started/setup_linux/install_locally.rst @@ -116,7 +116,7 @@ If you run into issues or no longer need the custom kernel, you can remove it. .. code-block:: bash - cd ~/sof/linux + cd ~/work/sof/linux sudo rm /boot/*-$(make kernelversion) sudo rm -rf /lib/modules/$(make kernelversion) sudo update-grub @@ -125,7 +125,7 @@ If you run into issues or no longer need the custom kernel, you can remove it. .. code-block:: bash - cd ~/sof/linux + cd ~/work/sof/linux sudo rm /boot/*-$(make kernelversion)* sudo rm -rf /lib/modules/$(make kernelversion) sudo grubby --remove-kernel=/boot/vmlinuz-$(make kernelversion) From 60a41cf68d6478e9de5a7cc262900e71900b92a8 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Wed, 5 Jul 2023 10:24:21 +0300 Subject: [PATCH 100/150] getting_started: Digital mic issue: Fix arecord options Fixes broken "arecord -Dhw:0,6 -c4 -r48000 -sS32_LE -d 10 test.wav" to "arecord -Dhw:0,6 -c4 -r48000 -fS32_LE -d 10 test.wav" Link: https://github.com/thesofproject/sof-docs/issues/467 Signed-off-by: Jyri Sarha --- getting_started/intel_debug/suggestions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting_started/intel_debug/suggestions.rst b/getting_started/intel_debug/suggestions.rst index 7e9d2d2e..67594dfe 100644 --- a/getting_started/intel_debug/suggestions.rst +++ b/getting_started/intel_debug/suggestions.rst @@ -214,7 +214,7 @@ The following command can then be used to check if the microphones are active at .. code-block:: bash - arecord -Dhw:0,6 -c4 -r48000 -sS32_LE -d 10 test.wav + arecord -Dhw:0,6 -c4 -r48000 -fS32_LE -d 10 test.wav In 99% of the cases, hardware designers connect the two microphones on the PDM0 controller. Some platforms use PDM1, which cannot really be From 73ac8f55622dfb0d406f83e35bdfa319cead8bcb Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Mon, 10 Jul 2023 16:43:41 -0700 Subject: [PATCH 101/150] scripts/requirements*.txt: pillow<10 to avoid warning On July 1st, python library "Pillow" (needed by sphinxcontrib.blockdiag) released version 10.0.0 https://pypi.org/project/Pillow/#history The sof-docs build immediately started to fail with the warning "'ImageDraw' object has no attribute 'textsize'" Stick to pillow<10 for now to avoid the warning. More details in issue https://github.com/thesofproject/sof-docs/issues/472 Signed-off-by: Marc Herbert --- scripts/requirements-lax.txt | 5 +++++ scripts/requirements.txt | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/scripts/requirements-lax.txt b/scripts/requirements-lax.txt index 7287ddf0..b92ef6c4 100644 --- a/scripts/requirements-lax.txt +++ b/scripts/requirements-lax.txt @@ -58,3 +58,8 @@ sphinxcontrib.plantuml>=0.11,<0.25 # - Downgrade if successfully tested. # - Test with plantum set to "none" in conf.py. We don't want small # typo fixes to depend on UML diagrams. + +# Workaround for warning "'ImageDraw' object has no attribute 'textsize'" +# with pillow 10.0.0, see +# https://github.com/thesofproject/sof-docs/issues/472 +pillow<10 diff --git a/scripts/requirements.txt b/scripts/requirements.txt index 3d50863c..c3697fe8 100755 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -6,3 +6,9 @@ docutils==0.17.1 sphinx_rtd_theme sphinxcontrib-plantuml sphinxcontrib-blockdiag + + +# Workaround for warning "'ImageDraw' object has no attribute 'textsize'" +# with pillow 10.0.0, see +# https://github.com/thesofproject/sof-docs/issues/472 +pillow<10 From 91a4ceeff409fb34e281edbdc8da265cadbbd504 Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Mon, 10 Jul 2023 16:45:15 -0700 Subject: [PATCH 102/150] scripts/requirements-lax.txt: align with more recent requirements.txt No point accepting versions older than the officially supported versions. Fixes commit 0d8991b4114f ("Update req.txt file, update copyright, change release number") Signed-off-by: Marc Herbert --- scripts/requirements-lax.txt | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/scripts/requirements-lax.txt b/scripts/requirements-lax.txt index b92ef6c4..fb60b139 100644 --- a/scripts/requirements-lax.txt +++ b/scripts/requirements-lax.txt @@ -9,9 +9,9 @@ # PIP_IGNORE_INSTALLED=0 pip3 install --user -r scripts/requirements-lax.txt # See https://github.com/pypa/pip/issues/4222 -breathe>=4.7.3 -sphinx>=1.6.7 -docutils>=0.14 +breathe>=4.29.2 +sphinx>=4.5.0 +docutils>=0.17.1 sphinx_rtd_theme>=0.2.4 sphinxcontrib-blockdiag>=3.0.0 @@ -19,16 +19,13 @@ sphinxcontrib-blockdiag>=3.0.0 # `plantuml_output_format=none` which is required for instant builds. # https://pypi.org/project/sphinxcontrib-plantuml/0.11/ # -# - 0.24 is the last version successfully tested with -# PIP_IGNORE_INSTALLED=0 and Ubuntu 20.04 (see .github/worflows/) -# # - Note 0.9 is the minimum to fix this fatal import failure: # # sphinx.util.compat.Directive class is now deprecated. Please # use instead docutils.parsers.rst.Directive # # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=896485#12 -sphinxcontrib.plantuml>=0.11,<0.25 +sphinxcontrib.plantuml>=0.11 # Differences between these "lax" version requirements and the official # ones in requirements.txt: From 2a658def01e28225685cab3e6d5658d7bd004206 Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Mon, 10 Jul 2023 16:46:55 -0700 Subject: [PATCH 103/150] .github: upgrade "lax" build from Ubuntu 20.04 to 22.04 Ubuntu 20.04 is old, we don't want to hear about it. Signed-off-by: Marc Herbert --- .github/workflows/pull-request.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index f10d87ff..6586ba61 100755 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -32,7 +32,7 @@ jobs: supported-reqs: name: 'Supported scripts/requirements.txt' - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 @@ -81,7 +81,7 @@ jobs: deploy: needs: supported-reqs - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/publish' }} steps: # download the build result from the same workflow From 8e37a80e72a73010047905c6d42c4a7d8b6536a4 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Tue, 19 Sep 2023 14:17:13 +0300 Subject: [PATCH 104/150] intel_debug: add note that sof-tgl.ri is just one example Add note that sof-tgl.ri is just one example firmware file name. Signed-off-by: Kai Vehmanen --- getting_started/intel_debug/introduction.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/getting_started/intel_debug/introduction.rst b/getting_started/intel_debug/introduction.rst index 9842ca1c..8109bf7f 100644 --- a/getting_started/intel_debug/introduction.rst +++ b/getting_started/intel_debug/introduction.rst @@ -97,12 +97,12 @@ the following elements are present on the file system. 1. Firmware binary ------------------ -The firmware file, ``/lib/firmware/intel/sof/sof-tgl.ri``, contains -all DSP code and tables. On PCI devices, the firmware can only be -signed by an Intel production key which prevents community users from -installing their own firmware. Notable exceptions include Google -Chromebooks and Up2/Up-Extreme boards, where the *community key* is -used. +The firmware file, ``/lib/firmware/intel/sof/sof-tgl.ri`` (example +location for Intel Tiger Lake), contains all DSP code and tables. On +PCI devices, the firmware can only be signed by an Intel production +key which prevents community users from installing their own firmware. +Notable exceptions include Google Chromebooks and Up2/Up-Extreme +boards, where the *community key* is used. The Intel ME (Management Engine) is responsible for authentication of the firmware, whether it is signed by an Intel production key (consumer From 3c934c76bb2ac3172b2bad527a1cb7e8619b1e28 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Tue, 19 Sep 2023 14:17:49 +0300 Subject: [PATCH 105/150] intel_debug: add info for Intel firmware and tplg filenames Add tables documenting the firmare and topology filenames and their locations, as expected by Linux SOF driver. Signed-off-by: Kai Vehmanen --- getting_started/intel_debug/introduction.rst | 51 ++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/getting_started/intel_debug/introduction.rst b/getting_started/intel_debug/introduction.rst index 8109bf7f..78e1bbab 100644 --- a/getting_started/intel_debug/introduction.rst +++ b/getting_started/intel_debug/introduction.rst @@ -117,6 +117,39 @@ Linux kernel to query whether or not the firmware authentication is enabled, which means `dmesg` logs cannot be provided to alert the user to an ME configuration issue. +Linux SOF will look up firmware files at the following paths: + +.. list-table:: Firmware look-up paths per Intel platform + :widths: 50 50 25 + :header-rows: 1 + + * - Platform + - Firmware load path + - Notes + * - Raptor Lake and older + - /lib/firmware/intel/sof/sof-PLAT.ri + - PLAT = glk, cml, ..., rpl + * - Raptor Lake and older (community signed) + - /lib/firmware/intel/sof/community/sof-PLAT.ri + - PLAT = glk, cml, ..., rpl + * - Meteor Lake and newer + - /lib/firmware/intel/sof-ipc4/PLAT/sof-PLAT.ri + - PLAT = mtl, lnl, ... + * - Meteor Lake and newer (community signed) + - /lib/firmware/intel/sof-ipc4/PLAT/community/sof-PLAT.ri + - PLAT = mtl, lnl, ... + * - Meteor Lake and newer Loadable Module + - /lib/firmware/intel/sof-ipc4-lib/PLAT/UUID.bin + - PLAT as above, UUID = UUID of the module + * - Meteor Lake and newer Loadable Module (community signed) + - /lib/firmware/intel/sof-ipc4-lib/PLAT/community/UUID.bin + - PLAT as above, UUID = UUID of the module + +Important notices: + - The standard Linux firmware search path and order is followed. The above table covers the base "/lib/firmware" case. See https://docs.kernel.org/driver-api/firmware/fw_search_path.html for more information. + - The firmware folder and filename can be overridden with "fw_path" and "fw_filename" SOF kernel parameters. + - The loadable module library path can be overridden with "lib_path" SOF kernel parameter. + 2. Topology file ---------------- @@ -124,6 +157,24 @@ The topology file, such as ``/lib/firmware/intel/sof-tplg/sof-hda-generic-2ch.tp be instantiated by the SOF driver. The topology can be regenerated and reconfigured with tools but requires expert knowledge of the ALSA/ASoC/topology frameworks. +.. list-table:: Firmware topology file look-up paths per Intel platform + :widths: 50 50 25 + :header-rows: 1 + + * - Platform + - Topology load path + - Notes + * - Raptor Lake and older + - /lib/firmware/intel/sof-tplg/sof-CONFIG.tplg + - CONFIG = topology variant needed for detected hardware configuration + * - Meteor Lake and newer + - /lib/firmware/intel/sof-ace-tplg/sof-CONFIG.tplg + - CONFIG = topology variant needed for detected hardware configuration + +Important notices: + - The standard Linux firmware search path and order is followed. The above table covers the base "/lib/firmware" case. See https://docs.kernel.org/driver-api/firmware/fw_search_path.html for more information. + - The topology folder and filename can be overridden with "tplg_path" and "tplg_filename" `snd_sof_pci` kernel parameters. + 3. UCM file ----------- From dad39b005405d077253d0be0928983bed9f467a8 Mon Sep 17 00:00:00 2001 From: Deb Taylor Date: Thu, 28 Sep 2023 09:06:39 -0500 Subject: [PATCH 106/150] Revision update (#479) * add yaml file updates Signed-off-by: Deb * Update version numbers to 2.7.0 Signed-off-by: Deb --------- Signed-off-by: Deb --- conf.py | 2 +- release.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/conf.py b/conf.py index 8352df0c..d79c6d89 100755 --- a/conf.py +++ b/conf.py @@ -81,7 +81,7 @@ # |version| and |release|, also used in various other places throughout the # built documents. -version = release = "2.5.0" +version = release = "2.7.0" # # The short X.Y version. diff --git a/release.rst b/release.rst index 0fa459e4..1383c190 100755 --- a/release.rst +++ b/release.rst @@ -26,7 +26,7 @@ kernel, and documentation. Download the source code as a zip or tar.gz file: Source and Binary Releases -------------------------- -The latest SOF release is v2.6.0 (June 2023). +The latest SOF release is v2.7.0 (Sept 2023). View new feature information and release downloads for the latest and previous releases on GitHub. Firmware and SDK tool source code and binary From bc438c0e02ae3a02f0d3fc87b1fdc2db5412ebfd Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 26 Sep 2023 14:53:01 +0300 Subject: [PATCH 107/150] developer_guides: debugability: probes: Bring the documentation up to date The kernel print has been changed since the documentation was added and let's add a convenience 'hack' to gather the IDs that we need to pass as point ID. At the same time align the rendered page. Signed-off-by: Peter Ujfalusi --- .../debugability/probes/index.rst | 61 ++++++++++++------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/developer_guides/debugability/probes/index.rst b/developer_guides/debugability/probes/index.rst index 4f9cd559..98e6dedc 100644 --- a/developer_guides/debugability/probes/index.rst +++ b/developer_guides/debugability/probes/index.rst @@ -135,35 +135,50 @@ the last stage of extraction. Refer to the host side struct sof_probe_point_desc defined in ``sound/soc/sof/probe.h`` or struct probe_point in ``/src/include/ipc/probe.h`` from sof for the meaning of the triplets: - .. code-block:: c + .. code-block:: c - /** - * Description of probe point - */ - struct probe_point { - uint32_t buffer_id; /**< ID of buffer to which probe is attached */ - uint32_t purpose; /**< PROBE_PURPOSE_EXTRACTION or PROBE_PURPOSE_INJECTION */ - uint32_t stream_tag; /**< Stream tag of DMA via which data will be provided for injection. - * For extraction purposes, stream tag is ignored when received, - * but returned actual extraction stream tag via INFO function. - */ - } __attribute__((packed)); + /** + * Description of probe point + */ + struct probe_point { + uint32_t buffer_id; /**< ID of buffer to which probe is attached */ + uint32_t purpose; /**< PROBE_PURPOSE_EXTRACTION or PROBE_PURPOSE_INJECTION */ + uint32_t stream_tag; /**< Stream tag of DMA via which data will be provided for injection. + * For extraction purposes, stream tag is ignored when received, + * but returned actual extraction stream tag via INFO function. + */ + } __attribute__((packed)); + + In the above example, 7 stands for the ``buffer_id`` which is a monolithic + counter value that follows a component instantiation order. - In the above example, 7 stands for the ``buffer_id`` which is a monolithic - counter value that follows a component instantiation order. + One way to find out the right instance of ``buffer_id`` is to enable + dev_dbg in ``sound/sound/soc/sof/topology.c`` and search for the widget id + from the following messages: - One way to find out the right instance of ``buffer_id`` is to enable - dev_dbg in ``sound/sound/soc/sof/topology.c`` and search for the widget id - from the following messages: + .. code-block:: c - .. code-block:: c + dev_dbg(scomp->dev, + "tplg: widget %d (%s) is ready [type: %d, pipe: %d, pins: %d / %d, stream: %s]\n", + swidget->comp_id, w->name, swidget->id, index, + swidget->num_input_pins, swidget->num_output_pins, + strnlen(w->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 ? w->sname : "none"); - dev_dbg(scomp->dev, "tplg: ready widget id %d pipe %d type %d name : %s stream %s\n", - swidget->comp_id, index, swidget->id, tw->name, - strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 - ? tw->sname : "none"); + On a booted system the list can be acquired with + + .. code-block:: bash - For IPC4 system, the above example looks like this: + dmesg | grep "tplg: widget " + ... + snd_sof:sof_widget_ready: sof-audio-pci-intel-tgl 0000:00:1f.3: tplg: widget 2 (gain.1.1) is ready [type: 6, pipe: 1, pins: 1 / 1, stream: none] + snd_sof:sof_widget_ready: sof-audio-pci-intel-tgl 0000:00:1f.3: tplg: widget 3 (mixin.1.1) is ready [type: 4, pipe: 1, pins: 1 / 3, stream: none] + snd_sof:sof_widget_ready: sof-audio-pci-intel-tgl 0000:00:1f.3: tplg: widget 4 (pipeline.1) is ready [type: 32, pipe: 1, pins: 0 / 0, stream: none] + snd_sof:sof_widget_ready: sof-audio-pci-intel-tgl 0000:00:1f.3: tplg: widget 5 (codec0_in) is ready [type: 0, pipe: 1, pins: 0 / 0, stream: none] + snd_sof:sof_widget_ready: sof-audio-pci-intel-tgl 0000:00:1f.3: tplg: widget 6 (iDisp2 Tx) is ready [type: 7, pipe: 1, pins: 0 / 0, stream: none] + snd_sof:sof_widget_ready: sof-audio-pci-intel-tgl 0000:00:1f.3: tplg: widget 7 (dai-copier.HDA.Analog.playback) is ready [type: 27, pipe: 2, pins: 1 / 0, stream: Analog] + ... + + For IPC4 system, the above example looks like this (extraction from gain.1.1): .. code-block:: bash From f70388a42909591e699b0dfed21ee137e4b11d91 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 22 Sep 2023 09:54:46 +0300 Subject: [PATCH 108/150] intel_debug: introduction: Update for pathnames for IPC4 support SOF supports platforms from Tiger Lake with IPC4, update the docuementation accordingly. Update the MTL/LNL topology path to follow a generic pattern and add a note about the need for a symlink for the old path to retain backwards compatibility with released kernels. Signed-off-by: Peter Ujfalusi --- getting_started/intel_debug/introduction.rst | 31 +++++++++++++------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/getting_started/intel_debug/introduction.rst b/getting_started/intel_debug/introduction.rst index 78e1bbab..37fddd16 100644 --- a/getting_started/intel_debug/introduction.rst +++ b/getting_started/intel_debug/introduction.rst @@ -120,28 +120,35 @@ configuration issue. Linux SOF will look up firmware files at the following paths: .. list-table:: Firmware look-up paths per Intel platform - :widths: 50 50 25 + :widths: 55 5 50 25 :header-rows: 1 * - Platform + - IPC type - Firmware load path - Notes * - Raptor Lake and older + - IPC3 - /lib/firmware/intel/sof/sof-PLAT.ri - PLAT = glk, cml, ..., rpl * - Raptor Lake and older (community signed) + - IPC3 - /lib/firmware/intel/sof/community/sof-PLAT.ri - PLAT = glk, cml, ..., rpl - * - Meteor Lake and newer + * - Tiger Lake and newer + - IPC4 - /lib/firmware/intel/sof-ipc4/PLAT/sof-PLAT.ri - - PLAT = mtl, lnl, ... - * - Meteor Lake and newer (community signed) + - PLAT = tgl, adl, rpl, mtl, lnl, ... + * - Tiger Lake and newer (community signed) + - IPC4 - /lib/firmware/intel/sof-ipc4/PLAT/community/sof-PLAT.ri - - PLAT = mtl, lnl, ... - * - Meteor Lake and newer Loadable Module + - PLAT = tgl, adl, rpl, mtl, lnl, ... + * - Tiger Lake and newer Loadable Module + - IPC4 - /lib/firmware/intel/sof-ipc4-lib/PLAT/UUID.bin - PLAT as above, UUID = UUID of the module - * - Meteor Lake and newer Loadable Module (community signed) + * - Tiger Lake and newer Loadable Module (community signed) + - IPC4 - /lib/firmware/intel/sof-ipc4-lib/PLAT/community/UUID.bin - PLAT as above, UUID = UUID of the module @@ -158,20 +165,24 @@ be instantiated by the SOF driver. The topology can be regenerated and reconfigured with tools but requires expert knowledge of the ALSA/ASoC/topology frameworks. .. list-table:: Firmware topology file look-up paths per Intel platform - :widths: 50 50 25 + :widths: 50 5 50 25 :header-rows: 1 * - Platform + - IPC type - Topology load path - Notes * - Raptor Lake and older + - IPC3 - /lib/firmware/intel/sof-tplg/sof-CONFIG.tplg - CONFIG = topology variant needed for detected hardware configuration - * - Meteor Lake and newer - - /lib/firmware/intel/sof-ace-tplg/sof-CONFIG.tplg + * - Tiger Lake and newer + - IPC4 + - /lib/firmware/intel/sof-ipc4-tplg/sof-CONFIG.tplg - CONFIG = topology variant needed for detected hardware configuration Important notices: + - For compatibility reasons for **Meteor Lake and newer** ``/lib/firmware/intel/sof-ace-tplg`` must be symlinked to ``/lib/firmware/intel/sof-ipc4-tplg`` - The standard Linux firmware search path and order is followed. The above table covers the base "/lib/firmware" case. See https://docs.kernel.org/driver-api/firmware/fw_search_path.html for more information. - The topology folder and filename can be overridden with "tplg_path" and "tplg_filename" `snd_sof_pci` kernel parameters. From cd9ed3231004ff39ce6c4d7d2f3a837dd960612e Mon Sep 17 00:00:00 2001 From: Vsevolod Novikov Date: Thu, 28 Sep 2023 11:49:42 +0300 Subject: [PATCH 109/150] intel_debug: Fixed suggestions about getting ES8336 quirk default. Suggestions fixed corresponding to the reality. Also some fixes mostly regarding syntax provided by request from @deb-intel. Signed-off-by: Vsevolod Novikov --- getting_started/intel_debug/suggestions.rst | 29 ++++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/getting_started/intel_debug/suggestions.rst b/getting_started/intel_debug/suggestions.rst index 67594dfe..93e4c22e 100644 --- a/getting_started/intel_debug/suggestions.rst +++ b/getting_started/intel_debug/suggestions.rst @@ -294,12 +294,33 @@ driver: #define SOC_ES8336_HEADSET_MIC1 BIT(8) -The default quirk value for the platform can be read from +The default and actual quirk values for the platform can be obtained +from the kernel logs in the line as follows: + +.. code-block:: none + + ... + sof-essx8336 sof-essx8336: quirk mask 0x1a0 + ... + +for the unchanged mask, or: + +.. code-block:: none + + ... + sof-essx8336 sof-essx8336: Overriding quirk 0x1a0 => 0x120 + ... + +for the quirk overriding. + +The overridden quirk value can also be obtained from the /sys/module/snd_soc_sof_es8336/parameters/quirk (the value is reported -as plain integer, not hexadecimal). Changes to the default can be -added with the following option in +as a plain integer, not hexadecimal). If the quirk is not overridden, +the `-1` value is returned. + +Changes to the default can be added with the following option in e.g. /etc/modprobe.d/alsa-base.conf. Only the bits listed above can be -modified, others need to be kept as is. +modified; others need to remain as is. .. code-block:: cfg From dc090bd456e1bd1e2bd776d8f0de321f77698464 Mon Sep 17 00:00:00 2001 From: Deb Taylor Date: Tue, 19 Dec 2023 13:38:56 -0500 Subject: [PATCH 110/150] Release 2.8 updates to website (#480) * add yaml file updates Signed-off-by: Deb * update release numbers on SOF site Signed-off-by: Deb --------- Signed-off-by: Deb --- conf.py | 4 ++-- release.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/conf.py b/conf.py index d79c6d89..6d799d6a 100755 --- a/conf.py +++ b/conf.py @@ -74,14 +74,14 @@ # General information about the project. project = u'SOF Project' -copyright = u'2023, SOF Project' +copyright = u'2024, SOF Project' author = u'SOF Project developers' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. -version = release = "2.7.0" +version = release = "2.8.0" # # The short X.Y version. diff --git a/release.rst b/release.rst index 1383c190..d44da00e 100755 --- a/release.rst +++ b/release.rst @@ -26,7 +26,7 @@ kernel, and documentation. Download the source code as a zip or tar.gz file: Source and Binary Releases -------------------------- -The latest SOF release is v2.7.0 (Sept 2023). +The latest SOF release is v2.8.0 (Dec 2023). View new feature information and release downloads for the latest and previous releases on GitHub. Firmware and SDK tool source code and binary From 0d7723d5bd095f611a77d2ffe4c3c8b650819866 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 21 Dec 2023 09:10:20 +0200 Subject: [PATCH 111/150] getting_started: intel_debug: Remove snd_sof_intel_ipc from dyndbg list There were never a module named snd_sof_intel_ipc, at least I cannot find it in kernel history. Signed-off-by: Peter Ujfalusi --- getting_started/intel_debug/suggestions.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/getting_started/intel_debug/suggestions.rst b/getting_started/intel_debug/suggestions.rst index 93e4c22e..d97b5adc 100644 --- a/getting_started/intel_debug/suggestions.rst +++ b/getting_started/intel_debug/suggestions.rst @@ -135,7 +135,6 @@ file: options snd_intel_sdw_acpi dyndbg=+pmf # SOF internals - options snd_sof_intel_ipc dyndbg=+pmf options snd_sof_intel_hda_common dyndbg=+pmf options snd_sof_intel_hda_mlink dyndbg=+pmf options snd_sof_intel_hda dyndbg=+pmf From e541ab4a26be787ec9a297895d89b3fb3aefb259 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 3 Jan 2024 13:27:04 +0200 Subject: [PATCH 112/150] getting_started: intel_debug: Update the sof-dyndbg.conf example Add snd_sof_intel_hda_generic to the list of modules. Signed-off-by: Peter Ujfalusi --- getting_started/intel_debug/suggestions.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/getting_started/intel_debug/suggestions.rst b/getting_started/intel_debug/suggestions.rst index d97b5adc..5a01e805 100644 --- a/getting_started/intel_debug/suggestions.rst +++ b/getting_started/intel_debug/suggestions.rst @@ -136,6 +136,7 @@ file: # SOF internals options snd_sof_intel_hda_common dyndbg=+pmf + options snd_sof_intel_hda_generic dyndbg=+pmf options snd_sof_intel_hda_mlink dyndbg=+pmf options snd_sof_intel_hda dyndbg=+pmf options snd_sof dyndbg=+pmf From eba363461df226bd1830a9b84eff90a27b20b054 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 10 Jan 2024 15:09:25 +0200 Subject: [PATCH 113/150] intel_debug: introduction: Update the note for Meteor Lake topology path Restrict the sof-ace-tplg symlink need to Meteor Lake only and change the sentecne as suggested by @deb-intel Signed-off-by: Peter Ujfalusi --- getting_started/intel_debug/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting_started/intel_debug/introduction.rst b/getting_started/intel_debug/introduction.rst index 37fddd16..45ae7e2f 100644 --- a/getting_started/intel_debug/introduction.rst +++ b/getting_started/intel_debug/introduction.rst @@ -182,7 +182,7 @@ reconfigured with tools but requires expert knowledge of the ALSA/ASoC/topology - CONFIG = topology variant needed for detected hardware configuration Important notices: - - For compatibility reasons for **Meteor Lake and newer** ``/lib/firmware/intel/sof-ace-tplg`` must be symlinked to ``/lib/firmware/intel/sof-ipc4-tplg`` + - For compatibility reasons with respect to **Meteor Lake** ``/lib/firmware/intel/sof-ace-tplg`` must be symlinked to ``/lib/firmware/intel/sof-ipc4-tplg`` - The standard Linux firmware search path and order is followed. The above table covers the base "/lib/firmware" case. See https://docs.kernel.org/driver-api/firmware/fw_search_path.html for more information. - The topology folder and filename can be overridden with "tplg_path" and "tplg_filename" `snd_sof_pci` kernel parameters. From c1b4c7c1d985b061fdfcb18f167f0dfdcb1348ec Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Wed, 31 Jan 2024 11:14:32 -0800 Subject: [PATCH 114/150] Update google tsc members --- tsc/representatives.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tsc/representatives.rst b/tsc/representatives.rst index 9b1916da..09a53106 100644 --- a/tsc/representatives.rst +++ b/tsc/representatives.rst @@ -21,9 +21,9 @@ The TSC is currently made of the following contributors +---------------+----------------------+------------------+ | Google | Curtis Malainey | @cujomalainey | +---------------+----------------------+------------------+ -| Google | Dylan Reid | @dgreid | +| Google | Johny Lin | @johnylin76 | +---------------+----------------------+------------------+ -| Google | Ben Zhang | @bzhg | +| Google | Unseated | | +---------------+----------------------+------------------+ | AMD | Carl Wakeland | @cwakeland | +---------------+----------------------+------------------+ From 533bf84a5864864420fcc5a5049b4bb2db1d1e81 Mon Sep 17 00:00:00 2001 From: Deb Taylor Date: Fri, 23 Feb 2024 13:27:44 -0500 Subject: [PATCH 115/150] requirements.txt updates (#485) * Sync remote Signed-off-by: Deb * Update Sphinx version and change sphinxcontrib-applehelp version Signed-off-by: Deb --------- Signed-off-by: Deb --- getting_started/intel_debug/introduction.rst | 0 getting_started/intel_debug/suggestions.rst | 0 scripts/requirements.txt | 8 +++++--- tsc/representatives.rst | 0 4 files changed, 5 insertions(+), 3 deletions(-) mode change 100644 => 100755 getting_started/intel_debug/introduction.rst mode change 100644 => 100755 getting_started/intel_debug/suggestions.rst mode change 100644 => 100755 tsc/representatives.rst diff --git a/getting_started/intel_debug/introduction.rst b/getting_started/intel_debug/introduction.rst old mode 100644 new mode 100755 diff --git a/getting_started/intel_debug/suggestions.rst b/getting_started/intel_debug/suggestions.rst old mode 100644 new mode 100755 diff --git a/scripts/requirements.txt b/scripts/requirements.txt index c3697fe8..e7e9c5b6 100755 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -1,11 +1,13 @@ # This file hardcodes validated versions with '==', # see requirements-lax.txt for an alternative. -breathe==4.29.2 -sphinx==4.5.0 -docutils==0.17.1 + +sphinx>=7 +breathe +docutils sphinx_rtd_theme sphinxcontrib-plantuml sphinxcontrib-blockdiag +sphinxcontrib-applehelp # Workaround for warning "'ImageDraw' object has no attribute 'textsize'" diff --git a/tsc/representatives.rst b/tsc/representatives.rst old mode 100644 new mode 100755 From 3c8c515e6476b42ae3728b2d81b9978ab652477c Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Sat, 24 Feb 2024 00:59:57 +0000 Subject: [PATCH 116/150] Add FIXMEs to stop using blockdiag as it is orphaned See #472 for details. Signed-off-by: Marc Herbert --- .../mpp_layer/images/mpp_scheduling/edf_scheduling.diag | 3 +++ conf.py | 4 ++++ scripts/requirements.txt | 7 +++---- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/edf_scheduling.diag b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/edf_scheduling.diag index 46a3e974..b9680b22 100644 --- a/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/edf_scheduling.diag +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/edf_scheduling.diag @@ -1,3 +1,6 @@ +// FIXME: blockdiag is orphaned and not compatible with Pillow anymore: +// https://github.com/blockdiag/blockdiag/pull/171 + blockdiag edf_scheduling { node_width = 250; diff --git a/conf.py b/conf.py index 6d799d6a..d7b075d7 100755 --- a/conf.py +++ b/conf.py @@ -30,6 +30,10 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. + + +# FIXME: blockdiag is orphaned and not compatible with Pillow anymore: +# https://github.com/thesofproject/sof-docs/issues/472 extensions = ['breathe', 'sphinx.ext.graphviz', 'sphinxcontrib.plantuml', 'sphinx.ext.todo', 'sphinx.ext.extlinks', 'sphinxcontrib.blockdiag' ] diff --git a/scripts/requirements.txt b/scripts/requirements.txt index e7e9c5b6..17aff9e6 100755 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -6,11 +6,10 @@ breathe docutils sphinx_rtd_theme sphinxcontrib-plantuml -sphinxcontrib-blockdiag sphinxcontrib-applehelp -# Workaround for warning "'ImageDraw' object has no attribute 'textsize'" -# with pillow 10.0.0, see -# https://github.com/thesofproject/sof-docs/issues/472 +# blockdiag is orphaned and not compatible with pillow>=10, +# see https://github.com/thesofproject/sof-docs/issues/472 +sphinxcontrib-blockdiag pillow<10 From 424ddf43b5255b4d287709455525bdfc84084df7 Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Thu, 28 Mar 2024 09:49:45 -0700 Subject: [PATCH 117/150] ktest setup: GRUB submenu fixes (#486) The GRUB documentation used to say `GRUB_DISABLE_SUBMENU=y`, now it says `GRUB_DISABLE_SUBMENU=true` Also, the corresponding code is unreliable copy/paste/diverge: https://github.com/rhboot/grub2/commit/ee4bd79ef28e6fa4a6 This makes GRUB submenus error-prone. As a broken grub.cfg makes the system unbootable, "harden" the corresponding documentation. Signed-off-by: Marc Herbert --- .../setup_linux/setup_ktest_environment.rst | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/getting_started/setup_linux/setup_ktest_environment.rst b/getting_started/setup_linux/setup_ktest_environment.rst index 4ab236b5..2836890c 100644 --- a/getting_started/setup_linux/setup_ktest_environment.rst +++ b/getting_started/setup_linux/setup_ktest_environment.rst @@ -58,16 +58,24 @@ Set up a target sudo emacs /etc/default/grub b) Change ``GRUB_DEFAULT=[n]`` to ``GRUB_DEFAULT=saved``. - - c) Add ``GRUB_DISABLE_SUBMENU=y`` to the end of the file and save it. - This step is necessary because submenus confuse ktest. + c) You must disable GRUB submenus because they confuse ktest: + + .. code-block:: console + + echo 'GRUB_DISABLE_SUBMENU=y' | sudo tee -a /etc/default/grub.d/disable-submenu.cfg d) Update the grub configuration. .. code-block:: console - - sudo update-grub + + # Better safe than _very_ sorry + sudo cp /boot/grub/grub.cfg /boot/grub/saved_grub.cfg + + sudo update-grub + + # Make sure submenus are actually disabled + grep submenu /boot/grub/grub.cfg #. Set the default kernel. @@ -84,7 +92,7 @@ Set up a target # Print your currently booted (and known-safe) option cat /proc/cmdline # List the grub entries - awk '/^menuentry/ { print i++, '\t', $0 }' /boot/grub/grub.cfg + awk '/^menuentry|submenu/ { print i++, '\t', $0 }' /boot/grub/grub.cfg # Find the entry that matches the output of the # first command you ran, and take note of its number sudo grub-set-default [n] # Where [n] is that number @@ -135,7 +143,7 @@ Set up a target #=> saved_entry=6 # Show all, numbered kernel choices without (re)booting - awk '/^menuentry/ { print i++, '\t', $0 }' /boot/grub/grub.cfg + awk '/^menuentry|submenu/ { print i++, '\t', $0 }' /boot/grub/grub.cfg #=> 5 menuentry ... #=> 6 menuentry 'Ubuntu, with Linux 5.4.0-53-generic' --class ubuntu ... #=> 7 menuentry ... From 97e73394fd62c8f0bfcf51bb6447446abf385807 Mon Sep 17 00:00:00 2001 From: Deb Taylor Date: Mon, 1 Apr 2024 11:16:58 -0400 Subject: [PATCH 118/150] Version # updates to conf.py and release file for upcoming 2.9 release (#492) Signed-off-by: Deb --- .../mpp_layer/images/mpp_scheduling/edf_scheduling.diag | 0 conf.py | 2 +- release.rst | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/edf_scheduling.diag diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/edf_scheduling.diag b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/edf_scheduling.diag old mode 100644 new mode 100755 diff --git a/conf.py b/conf.py index d7b075d7..adfea0db 100755 --- a/conf.py +++ b/conf.py @@ -85,7 +85,7 @@ # |version| and |release|, also used in various other places throughout the # built documents. -version = release = "2.8.0" +version = release = "2.9.0" # # The short X.Y version. diff --git a/release.rst b/release.rst index d44da00e..bb4d4979 100755 --- a/release.rst +++ b/release.rst @@ -26,7 +26,7 @@ kernel, and documentation. Download the source code as a zip or tar.gz file: Source and Binary Releases -------------------------- -The latest SOF release is v2.8.0 (Dec 2023). +The latest SOF release is v2.9.0 (Mar 2024). View new feature information and release downloads for the latest and previous releases on GitHub. Firmware and SDK tool source code and binary From 7977bf560f46a220f5ed95802012e31a15bded4c Mon Sep 17 00:00:00 2001 From: Marcin Szkudlinski Date: Wed, 13 Mar 2024 13:00:52 +0100 Subject: [PATCH 119/150] rtos: io_drivers: add loopback mode description This commit adds a description of using SSP devices in loopback mode Signed-off-by: Marcin Szkudlinski --- .../rtos_layer/io_drivers/i2s/i2s_driver.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst index 110bace9..87d2bc88 100644 --- a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst @@ -108,3 +108,18 @@ stream with already running ones. "Single" I2S links may be synchronized and aggregated by sending I2sSyncData to the I2S IO Driver. + +Loopback mode +====================================== + +I2S transmitter and receiver share data pins at IP level - the Tx pin of the transmitter +is connected to the Rx pin of the receiver. This may be used for easy creation of digital +loopbacks (LBM, loopback mode) - the receiver always does see what the sender is sending. + +Please note that + + - all the parameters of transmitter and receiver, like number of channels, data rates +and format, must match each other + - the lines are connected internally, so LBM mode may be used even if the I2S pins are not +physically available + From bbabbdf4a4eb0ea81bdd71fd9776cbd0e0d7d2f1 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 15 Apr 2024 15:08:10 +0100 Subject: [PATCH 120/150] Update architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst Co-authored-by: Deb Taylor --- .../sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst index 87d2bc88..e9f411c0 100644 --- a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst @@ -112,7 +112,7 @@ the I2S IO Driver. Loopback mode ====================================== -I2S transmitter and receiver share data pins at IP level - the Tx pin of the transmitter +The I2S transmitter and receiver share data pins at the IP level. The Tx pin of the transmitter is connected to the Rx pin of the receiver. This may be used for easy creation of digital loopbacks (LBM, loopback mode) - the receiver always does see what the sender is sending. From 02055a2e51bc32f8293723f9f212c77b8f85e93b Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 15 Apr 2024 15:08:17 +0100 Subject: [PATCH 121/150] Update architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst Co-authored-by: Deb Taylor --- .../sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst index e9f411c0..ea3c6aed 100644 --- a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst @@ -116,7 +116,7 @@ The I2S transmitter and receiver share data pins at the IP level. The Tx pin of is connected to the Rx pin of the receiver. This may be used for easy creation of digital loopbacks (LBM, loopback mode) - the receiver always does see what the sender is sending. -Please note that +Please note the following: - all the parameters of transmitter and receiver, like number of channels, data rates and format, must match each other From 4217dc10d77e614bdc73212368f0e29a6c256646 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 15 Apr 2024 15:08:24 +0100 Subject: [PATCH 122/150] Update architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst Co-authored-by: Deb Taylor --- .../sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst index ea3c6aed..0a38996e 100644 --- a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst @@ -118,7 +118,7 @@ loopbacks (LBM, loopback mode) - the receiver always does see what the sender is Please note the following: - - all the parameters of transmitter and receiver, like number of channels, data rates + - all the parameters of transmitter and receiver, like number of channels, data rates, and format must match each other and format, must match each other - the lines are connected internally, so LBM mode may be used even if the I2S pins are not physically available From da759668c957dc3d018a9f22e2d63b4e296143d5 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 15 Apr 2024 15:08:31 +0100 Subject: [PATCH 123/150] Update architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst Co-authored-by: Deb Taylor --- .../firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst index 0a38996e..a27ce22e 100644 --- a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst @@ -119,7 +119,6 @@ loopbacks (LBM, loopback mode) - the receiver always does see what the sender is Please note the following: - all the parameters of transmitter and receiver, like number of channels, data rates, and format must match each other -and format, must match each other - the lines are connected internally, so LBM mode may be used even if the I2S pins are not physically available From ef2f6815da04ebaa51e7d1e186ed3654b6bfb3f9 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 15 Apr 2024 15:08:38 +0100 Subject: [PATCH 124/150] Update architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst Co-authored-by: Deb Taylor --- .../sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst index a27ce22e..109e89a3 100644 --- a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst @@ -119,6 +119,6 @@ loopbacks (LBM, loopback mode) - the receiver always does see what the sender is Please note the following: - all the parameters of transmitter and receiver, like number of channels, data rates, and format must match each other - - the lines are connected internally, so LBM mode may be used even if the I2S pins are not + - the lines are connected internally, so LBM mode may be used even if the I2S pins are not physically available physically available From 1c4790f29b77edf89b369ddfdc6600eefc8f0d96 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 15 Apr 2024 15:08:43 +0100 Subject: [PATCH 125/150] Update architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst Co-authored-by: Deb Taylor --- .../firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst index 109e89a3..ef17ecae 100644 --- a/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst +++ b/architectures/firmware/sof-zephyr/rtos_layer/io_drivers/i2s/i2s_driver.rst @@ -120,5 +120,4 @@ Please note the following: - all the parameters of transmitter and receiver, like number of channels, data rates, and format must match each other - the lines are connected internally, so LBM mode may be used even if the I2S pins are not physically available -physically available From 0671cce5bebbf089b13fac865ca96e186674ba58 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Fri, 24 May 2024 14:11:27 +0300 Subject: [PATCH 126/150] developer_guides: debugability: shell: add usage documentation Add basic introduction and usage documentation on how to use Zephyr shell feature with SOF. Signed-off-by: Kai Vehmanen --- developer_guides/debugability/index.rst | 1 + developer_guides/debugability/shell/index.rst | 119 ++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 developer_guides/debugability/shell/index.rst diff --git a/developer_guides/debugability/index.rst b/developer_guides/debugability/index.rst index 02c712ef..ed686043 100644 --- a/developer_guides/debugability/index.rst +++ b/developer_guides/debugability/index.rst @@ -12,3 +12,4 @@ Debugability probes/index ri-info/index perf-counters/index + shell/index diff --git a/developer_guides/debugability/shell/index.rst b/developer_guides/debugability/shell/index.rst new file mode 100644 index 00000000..4f0b943c --- /dev/null +++ b/developer_guides/debugability/shell/index.rst @@ -0,0 +1,119 @@ +.. _dbg-zephyr-shell: + +Zephyr Shell +############ + +Zephyr provides a shell subystem for interactive debugging and a channel +to run custom test sequences. SOF supports use of the Zephyr shell. + +The Zephyr shell is documented at: +https://docs.zephyrproject.org/latest/services/shell/index.html + +Requirements +************ + +- SOF target platform must have Zephyr support. + +- At least one shell backend (DSP memory window, serial port, RTT, ...) compatible + with target platform. + +Build SOF with Shell Support +**************************** + +Shell is typically disabled by default and the firmware needs to be +rebuilt. For common SOF targets, a build overlay is provided in SOF +upstream to easily enable shell suppot in build. + + .. code-block:: bash + + # example build for Intel Tiger Lake platform + build-sh> sof/scripts/xtensa-build-zephyr.py tgl -o app/shell_overlay.conf + +Using Shell with Intel cavstool.py +********************************** + +This section covers use with SOF targets compatible with +CONFIG_SHELL_BACKEND_ADSP_MEMORY_WINDOW backend (for example Audio DSPs +on Intel Tiger Lake and Meteor Lake). + +Running the tool with "-p" to create a pseudo terminal for the shell: + + .. code-block:: bash + + dut-sh> sudo ./cavstool.py -l -p + INFO:cavs-fw:Existing driver "snd_sof_pci_intel_tgl" found + INFO:cavs-fw:Mapped PCI bar 0 of length 16384 bytes. + INFO:cavs-fw:Selected output stream 15 (GCAP = 0xffffffff) + INFO:cavs-fw:Mapped PCI bar 4 of length 1048576 bytes. + INFO:cavs-fw:Detected cAVS 1.8+ hardware + INFO:cavs-fw:Waiting forever for firmware handoff, ROM_STATUS = 0xffffffff + INFO:cavs-fw:FW alive, ROM_STATUS = 0x5 + INFO:cavs-fw:shell PTY at: /dev/pts/4 + +The Zephyr shell is now available at pseudo terminal /dev/pts/4 (see log above) +and can be attached with any terminal program: + + .. code-block:: bash + + dut-sh> sudo minicom -p /dev/pts/4 + Welcome to minicom 2.8 + + OPTIONS: I18n + Port /dev/modem + + Press CTRL-A Z for help on special keys + + ~$ kernel uptime + Uptime: 31600 ms + ~$ kernel stacks + 0x9e0a4e78 ll_thread0 (real size 8192): unused 6752 usage 1440 / 8192 (17 %) + 0x9e0a34b8 (real size 4096): unused 4008 usage 88 / 4096 ( 2 %) + 0x9e0a3400 (real size 4096): unused 4008 usage 88 / 4096 ( 2 %) + 0x9e0a3348 (real size 4096): unused 4008 usage 88 / 4096 ( 2 %) + 0x9e0a3290 (real size 4096): unused 4008 usage 88 / 4096 ( 2 %) + 0x9e0a37d0 edf_workq (real size 8192): unused 6304 usage 1888 / 8192 (23 %) + 0x9e0a3c48 sysworkq (real size 1024): unused 728 usage 296 / 1024 (28 %) + 0x9e0a3180 shell_adsp_memory_window (real size 2048): unused 760 usage 1288 / 2048 (62 %) + 0x9e0a3080 logging (real size 4096): unused 3488 usage 608 / 4096 (14 %) + 0x9e0a38b0 idle 00 (real size 1024): unused 824 usage 200 / 1024 (19 %) + 0xbe09df80 IRQ 00 (real size 2048): unused 1712 usage 336 / 2048 (16 %) + 0xbe09e780 IRQ 01 (real size 2048): unused 0 usage 2048 / 2048 (100 %) + 0xbe09ef80 IRQ 02 (real size 2048): unused 0 usage 2048 / 2048 (100 %) + 0xbe09f780 IRQ 03 (real size 2048): unused 0 usage 2048 / 2048 (100 %) + ~$ kernel threads + Scheduler: 1 since last call + Threads: + 0x9e0a4e78 ll_thread0 + options: 0x0, priority: -16 timeout: 0 + state: pending, entry: 0xbe02e060 + stack size 8192, unused 6752, usage 1440 / 8192 (17 %) + + 0x9e0a34b8 + options: 0x0, priority: -16 timeout: 0 + state: prestart, entry: 0xbe0154cc + stack size 4096, unused 4008, usage 88 / 4096 (2 %) + + [cut] + *0x9e0a3180 shell_adsp_memory_window + options: 0x0, priority: 14 timeout: 0 + state: , entry: 0xbe01969c + stack size 2048, unused 760, usage 1288 / 2048 (62 %) + + 0x9e0a3080 logging + options: 0x0, priority: 14 timeout: 0 + state: pending, entry: 0xbe016710 + stack size 4096, unused 3488, usage 608 / 4096 (14 %) + + 0x9e0a38b0 idle 00 + options: 0x1, priority: 15 timeout: 0 + state: , entry: 0xbe054298 + stack size 1024, unused 824, usage 200 / 1024 (19 %) + ~$ + +The memory window backend does not rely on IPC, so the shell is not +dependent on the IPC version implementation. The cavstool.py is also +implemented to handle cases where the DSP is suspended to lower power +state and the memory window is not accessible to host. When the DSP +is in such state, the shell terminal will appear inactive, but it will +resume immediately after DSP resumes to active state, without need +to rerun the cavstool.py script. From a19559333845a9fb2488c1659133b0e4042fb782 Mon Sep 17 00:00:00 2001 From: Deb Taylor Date: Wed, 17 Jul 2024 17:31:07 -0500 Subject: [PATCH 127/150] update version info in conf.py and release file (#498) Signed-off-by: Taylor, Deb --- conf.py | 2 +- release.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/conf.py b/conf.py index adfea0db..6042fbe8 100755 --- a/conf.py +++ b/conf.py @@ -85,7 +85,7 @@ # |version| and |release|, also used in various other places throughout the # built documents. -version = release = "2.9.0" +version = release = "2.10.0" # # The short X.Y version. diff --git a/release.rst b/release.rst index bb4d4979..8cad490a 100755 --- a/release.rst +++ b/release.rst @@ -26,7 +26,7 @@ kernel, and documentation. Download the source code as a zip or tar.gz file: Source and Binary Releases -------------------------- -The latest SOF release is v2.9.0 (Mar 2024). +The latest SOF release is v2.10.0 (July 2024). View new feature information and release downloads for the latest and previous releases on GitHub. Firmware and SDK tool source code and binary From fb50ad2d63eb9bd3580884d377f3efd59fd80270 Mon Sep 17 00:00:00 2001 From: "Putnam, Kevin" Date: Thu, 23 May 2024 12:20:32 -0700 Subject: [PATCH 128/150] Fixes issue where search requests hang. jQuery was not being loaded automatically. Force load it in extensions. Signed-off-by: Putnam, Kevin --- conf.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/conf.py b/conf.py index 6042fbe8..fa433227 100755 --- a/conf.py +++ b/conf.py @@ -35,7 +35,8 @@ # FIXME: blockdiag is orphaned and not compatible with Pillow anymore: # https://github.com/thesofproject/sof-docs/issues/472 extensions = ['breathe', 'sphinx.ext.graphviz', 'sphinxcontrib.plantuml', - 'sphinx.ext.todo', 'sphinx.ext.extlinks', 'sphinxcontrib.blockdiag' + 'sphinx.ext.todo', 'sphinx.ext.extlinks', 'sphinxcontrib.blockdiag', + 'sphinxcontrib.jquery' ] From d382e2c50a1868cf78fb82c736b6f0dc80d96419 Mon Sep 17 00:00:00 2001 From: "Putnam, Kevin" Date: Wed, 17 Jul 2024 08:35:21 -0700 Subject: [PATCH 129/150] adds jquery to lax requirements Signed-off-by: Putnam, Kevin --- scripts/requirements-lax.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/requirements-lax.txt b/scripts/requirements-lax.txt index fb60b139..42077b41 100644 --- a/scripts/requirements-lax.txt +++ b/scripts/requirements-lax.txt @@ -14,6 +14,7 @@ sphinx>=4.5.0 docutils>=0.17.1 sphinx_rtd_theme>=0.2.4 sphinxcontrib-blockdiag>=3.0.0 +sphinxcontrib-jquery # - Version 0.11 is the first version that supports # `plantuml_output_format=none` which is required for instant builds. From 8c2a9684984769963ad0dc50a77bcf422213b739 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 11 Apr 2024 14:20:04 +0200 Subject: [PATCH 130/150] developer-guide: add LLEXT module documentation Describe LLEXT loadable module support in SOF. Signed-off-by: Guennadi Liakhovetski --- developer_guides/firmware/index.rst | 1 + developer_guides/firmware/llext_modules.rst | 108 +++++++++++++++++++ getting_started/intel_debug/introduction.rst | 1 + 3 files changed, 110 insertions(+) create mode 100644 developer_guides/firmware/llext_modules.rst diff --git a/developer_guides/firmware/index.rst b/developer_guides/firmware/index.rst index c0a0709a..ee2e75cd 100644 --- a/developer_guides/firmware/index.rst +++ b/developer_guides/firmware/index.rst @@ -12,3 +12,4 @@ Developer guides and information for firmware development. porting cmake async_messaging_best_practices + llext_modules diff --git a/developer_guides/firmware/llext_modules.rst b/developer_guides/firmware/llext_modules.rst new file mode 100644 index 00000000..4832495b --- /dev/null +++ b/developer_guides/firmware/llext_modules.rst @@ -0,0 +1,108 @@ +.. _llext_modules: + +LLEXT Modules +############# + +|SOF| support for loadable modules, using Zephyr LLEXT API. + +Zephyr LLEXT API +**************** + +Please refer to https://docs.zephyrproject.org/latest/services/llext/index.html +for detailed documentation. In short, the Zephyr Linkable Loadable Extensions +(LLEXT) API implements support for run-time loading and unloading of ELF-format +executable code and data. + +SOF use of the LLEXT API +************************ + +SOF has multiple ways to implement loadable modules. LLEXT is one of them. +With it modules are built as shared or relocatable ELF objects with an addition +of a cryptographic signature, using any user-supplied key, and a manifest. When +loaded and instantiated, Zephyr LLEXT functionality is used to dynamically +resolve module internal as well as SOF and Zephyr external code and data +references. In the future support for inter-module linking will be added. + +Accessing the base firmware from LLEXT modules +********************************************** + +LLEXT modules can access all code and data from the base firmware exported, +using the ``EXPORT_SYMBOL()`` macro. Therefore writing LLEXT modules isn't very +different from built-in ones. + +Implementing LLEXT modules +************************** + +At the moment only modules, implementing the Module Adapter API +:ref:`apps-comp-world` are supported. + +.. _multiple-adapter-modules: + +It is possible to implement multiple Module Adapter modules with a common code +base, i.e. sharing a set of source files and functions. Then a single LLEXT +object would be created, implementing multiple Module Adapter interfaces. In +that case an array of ``struct sof_module_api_build_info`` objects is needed and +the TOML file should contain those multiple module entries too. +src/audio/mixin_mixout/mixin_mixout.c is an example of such a case. + +As explained above, LLEXT modules in general look very similar to native SOF +code, with the only restriction of having no access to not-exported symbols. + +LLEXT modules should also contain a ``.buildinfo`` section, containing a +``struct sof_module_api_build_info`` object and a ``.module`` section, +containing a ``struct sof_man_module_manifest`` object. The latter should also +contain a pointer to a module entry point function, returning a pointer to the +module's ``struct module_interface`` instance. All these additions can be +performed, using ``SOF_LLEXT_MOD_ENTRY()``, ``SOF_LLEXT_MODULE_MANIFEST()`` and +``SOF_LLEXT_BUILDINFO`` helper macros. See src/audio/eq_iir/eq_iir.c for an +example. + +A TOML configuration file is needed for building of LLEXT modules too. It is +generated by the C preprocessor at build time from the same components, as would +be used for a monolithic build. For this preprocessor run a small header file is +added. It mostly just includes ``platform.toml`` and ``${module}.toml``, similar +to src/samples/audio/smart_amp_test_llext/llext.toml.h. + +Finally an additional CMakeLists.txt is needed similar to +src/samples/audio/smart_amp_test_llext/CMakeLists.txt. It contains a single call +to ``sof_llext_build()``, which is an SOF helper function, using Zephyr LLEXT +cmake support by calling ``add_llext_target()`` and ``add_llext_command()``. + +With that in place, it is also possible to switch between monolithic and modular +builds by specifying the module as "tristate" in its Kconfig and selecting "m" +for modular builds. Note, that it is possible to implement third party Module +Adapter drivers, that would be built exclusively as loadable modules. Such +modules don't have to use "tristate" in their Kconfig entries. + +Installation +************ + +As specified in +:ref:`Firmware look-up paths per Intel platform ` +the |SOF| Linux kernel driver loads SOF modules by their UUIDs, +specified in the topology. For SOF in-tree modules the process of creation and +installation of modules in a deployment tree is automated by the +xtensa-build-zephyr.py script. It copies modules to the deployment tree as +files with a "llext" extension and creates symbolic links to them named as +``${UUID}.bin``. E.g. + +.. code-block:: cfg + + B36EE4DA-006F-47F9-A06D-FECBE2D8B6CE.bin -> drc.llext + +Note, that as described :ref:`above ` multiple UUIDs +can be associated with a single module, in such cases multiple symbolic links +will be created, e.g. + +.. code-block:: cfg + + 39656EB2-3B71-4049-8D3F-F92CD5C43C09.bin -> mixin_mixout.llext + 3C56505A-24D7-418F-BDDC-C1F5A3AC2AE0.bin -> mixin_mixout.llext + +See :ref:`apps-component-overview` for more information on UUID use by SOF +component and module adapter drivers. + +It is also possible to avoid using the script by running ``west build`` to build +an SOF image and any modules, then using the cross-compiler to preprocess TOML +files and finally by running rimage to sign them. This would generate the same +result but figuring out all the command-line arguments would be rather difficult. diff --git a/getting_started/intel_debug/introduction.rst b/getting_started/intel_debug/introduction.rst index 45ae7e2f..2079812c 100755 --- a/getting_started/intel_debug/introduction.rst +++ b/getting_started/intel_debug/introduction.rst @@ -119,6 +119,7 @@ configuration issue. Linux SOF will look up firmware files at the following paths: +.. _intel_firmware_paths: .. list-table:: Firmware look-up paths per Intel platform :widths: 55 5 50 25 :header-rows: 1 From d1d9f2bafaa87cf00bbca23dacad5f5ed818d64b Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Fri, 13 Sep 2024 16:30:26 +0300 Subject: [PATCH 131/150] developer_guides: coredump-reader: Add NOTE for Zephyr Add a note that these instructions are not valid for SOF on Zephyr and add link to relevant piece of Zephyr documentation. Signed-off-by: Jyri Sarha --- developer_guides/debugability/coredump-reader/index.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/developer_guides/debugability/coredump-reader/index.rst b/developer_guides/debugability/coredump-reader/index.rst index 71661c82..1ca6d5d2 100644 --- a/developer_guides/debugability/coredump-reader/index.rst +++ b/developer_guides/debugability/coredump-reader/index.rst @@ -3,6 +3,10 @@ Coredump-reader ############### +NOTE: These instructions do not work with SOF running on Zephyr, +please refer to +https://docs.zephyrproject.org/latest/services/debugging/coredump.html + Tool for processing FW stack dumps. In verbose mode it prints the stack leading to the core dump including DSP registers and function calls. It outputs unwrapped gdb command function call addresses to human readable From 84f3890c343049642adfb9455c6b4351a8178279 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 22:17:59 +0000 Subject: [PATCH 132/150] build(deps): bump actions/download-artifact in /.github/workflows Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 3 to 4.1.7. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v3...v4.1.7) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- .github/workflows/pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100755 => 100644 .github/workflows/pull-request.yml diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml old mode 100755 new mode 100644 index 6586ba61..1f094fdf --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -87,7 +87,7 @@ jobs: # download the build result from the same workflow # https://docs.github.com/en/actions/guides/storing-workflow-data-as-artifacts - name: download HTML - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4.1.7 with: name: html path: html From 1e68b2e6300d6539e2f684ba95d8efbdee1f1fed Mon Sep 17 00:00:00 2001 From: Deb Taylor Date: Thu, 26 Sep 2024 13:22:52 -0700 Subject: [PATCH 133/150] Update files to indicate new release (#502) Signed-off-by: Taylor, Deb --- conf.py | 2 +- release.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/conf.py b/conf.py index fa433227..4e1d22c7 100755 --- a/conf.py +++ b/conf.py @@ -86,7 +86,7 @@ # |version| and |release|, also used in various other places throughout the # built documents. -version = release = "2.10.0" +version = release = "2.11.0" # # The short X.Y version. diff --git a/release.rst b/release.rst index 8cad490a..ee119d71 100755 --- a/release.rst +++ b/release.rst @@ -26,7 +26,7 @@ kernel, and documentation. Download the source code as a zip or tar.gz file: Source and Binary Releases -------------------------- -The latest SOF release is v2.10.0 (July 2024). +The latest SOF release is v2.11.0 (Sept 2024). View new feature information and release downloads for the latest and previous releases on GitHub. Firmware and SDK tool source code and binary From a0e05fafc876f82924e2784a208d4528ae1dde9f Mon Sep 17 00:00:00 2001 From: Deb Taylor Date: Thu, 26 Sep 2024 13:24:04 -0700 Subject: [PATCH 134/150] Update pull-request.yml (#503) Updating download artifact to 4.1.7 is breaking change to the publication workflow. Changing upload artifact to match. --- .github/workflows/pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 1f094fdf..11b29b37 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -74,7 +74,7 @@ jobs: # https://docs.github.com/en/actions/guides/storing-workflow-data-as-artifacts - name: upload HTML for deploy if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/publish' }} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: html path: _build/html From b7080b4b8f9b2b4ffc2fc4a8b10a2a4c16dab1e6 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Fri, 20 Sep 2024 17:54:46 +0300 Subject: [PATCH 135/150] platforms: add separate table for older platforms As this topic has been discussed in many pull requests and bugs, add documentation on which platforms are supported in SOF main and which are only supported in stable-vx.yy branches. Also add a note explainin how sof-bin releases are made, gathering binaries for for all platforms. Signed-off-by: Kai Vehmanen --- platforms/index.rst | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/platforms/index.rst b/platforms/index.rst index 57930c4a..a582511d 100644 --- a/platforms/index.rst +++ b/platforms/index.rst @@ -14,16 +14,8 @@ Platform and board specific support is continually added to the SOF project as d "Host Testbench", "PC command line", "N/A", "N/A", "N/A", "N/A Files are used to simulate audio interfaces" "Qemu", "All supported SOF HW platforms", "N/A", "N/A", "N/A", "WiP Files will be used to simulate audio interfaces" - "Intel Bay Trail / Merrifield", "Xtensa HiFi2 EP", "1 @ 50 - 400MHz", "25MHz", "96KB IRAM / 192KB DRAM", "3 x SSP (I2S, PCM)" - "Intel Cherry Trail / Braswell", "Xtensa HiFi2 EP", "1 @ 50 - 400MHz", "19.2MHz", "96KB IRAM / 192KB DRAM", "6 x SSP (I2S, PCM)" - "Intel Broadwell", "Xtensa HiFi2 EP", "1 @ 50 - 400MHz", "24MHz", "320KB IRAM / 640KB DRAM", "2 x SSP (I2S, PCM)" - "Intel Apollo Lake / Gemini Lake", "Xtensa HiFi3", "2 @ 100 - 400MHz", "19.2MHz", "128KB LP SRAM / 512KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC" - "Intel Cannon Lake / Whiskey Lake / Comet Lake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "24MHz", "64KB LP / 3008KB HP SRAM", "3 x SSP (I2S, PCM), HDA, DMIC, Soundwire" - "Intel Sue Creek", "Xtensa HiFi3", "2 @ 120 - 400MHz","24MHz", "64KB LP SRAM / 4096KB HP SRAM", "6 x SSP (I2S, PCM), DMIC" - "Intel Ice Lake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 3008KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" - "Intel Jasper Lake", "Xtensa HiFi3", "2 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 1024KB HP SRAM", "3 x SSP (I2S, PCM), HDA, DMIC, Soundwire" - "Intel Tiger Lake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 2944KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" - "Intel Alder Lake", "Xtensa HiFi3", "4 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 2944KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "Intel Tiger Lake with IPC4", "Xtensa HiFi3", "4 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 2944KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "Intel Alder Lake with IPC4", "Xtensa HiFi3", "4 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 2944KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" "NXP i.MX8", "Xtensa HiFi4", "1 @ 666MHz", "TBD", "64 KB TCM / 448 KB OCRAM / 8MB SDRAM", "1 x ESAI, 1 x SAI" "NXP i.MX8X", "Xtensa HiFi4", "1 @ 640MHz", "TBD", "64 KB TCM / 448 KB OCRAM / 8MB SDRAM", "1 x ESAI, 1 x SAI" "NXP i.MX8M", "Xtensa HiFi4", "1 @ 800MHz", "TBD", "64 KB TCM / 256 KB OCRAM / 8MB SDRAM", "1 x SAI, MICFIL" @@ -38,6 +30,32 @@ When support for a new platform is being added, certain interfaces required by SOF infrastructure must be implemented. Refer to Platform API documentation for details. +Some platforms have been supported by SOF in the past, but are no longer +supported in SOF mainline ("main" branch). Below table lists such platforms, +the last SOF major release that had support for the platform and the stable +branch to use. For every SOF release, a stable branch is created and critical +bugfixes can be submitted and released via these stable branches. + +.. csv-table:: Platforms No Longer Supported in Mainline + :header: "Platform", "Last Release", "Branch", "Architecture", "Cores/Clocks", "Platform Clock", "Memory", "Audio Interfaces" + :widths: 20, 10, 10, 20, 10, 10, 10, 20 + + "Intel Bay Trail / Merrifield", "2.2", "stable-v2.2", "Xtensa HiFi2 EP", "1 @ 50 - 400MHz", "25MHz", "96KB IRAM / 192KB DRAM", "3 x SSP (I2S, PCM)" + "Intel Cherry Trail / Braswell", "2.2", "stable-v2.2", "Xtensa HiFi2 EP", "1 @ 50 - 400MHz", "19.2MHz", "96KB IRAM / 192KB DRAM", "6 x SSP (I2S, PCM)" + "Intel Broadwell", "2.2", "stable-v2.2", "Xtensa HiFi2 EP", "1 @ 50 - 400MHz", "24MHz", "320KB IRAM / 640KB DRAM", "2 x SSP (I2S, PCM)" + "Intel Apollo Lake / Gemini Lake", "2.2", "stable-v2.2", "Xtensa HiFi3", "2 @ 100 - 400MHz", "19.2MHz", "128KB LP SRAM / 512KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC" + "Intel Cannon Lake / Whiskey Lake / Comet Lake", "2.2", "stable-v2.2", "Xtensa HiFi3", "4 @ 120 - 400MHz", "24MHz", "64KB LP / 3008KB HP SRAM", "3 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "Intel Sue Creek", "2.2", "stable-v2.2", "Xtensa HiFi3", "2 @ 120 - 400MHz","24MHz", "64KB LP SRAM / 4096KB HP SRAM", "6 x SSP (I2S, PCM), DMIC" + "Intel Ice Lake", "2.2", "stable-v2.2", "Xtensa HiFi3", "4 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 3008KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "Intel Jasper Lake", "2.2", "stable-v2.2", "Xtensa HiFi3", "2 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 1024KB HP SRAM", "3 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "Intel Tiger Lake with IPC3", "2.2", "stable-v2.2", "Xtensa HiFi3", "4 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 2944KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + "Intel Alder Lake with IPC3", "2.2", "stable-v2.2", "Xtensa HiFi3", "4 @ 120 - 400MHz", "38.4MHz", "64KB LP SRAM / 2944KB HP SRAM", "6 x SSP (I2S, PCM), HDA, DMIC, Soundwire" + +The periodic sof-bin releases + +contain latest binaries for all platforms, both from SOF main and +latest binaries from "stable-vX.YY" branches. + Minimum Platform Requirements ***************************** From 163bac3c1e9ab439723c73f64540d6acfc4b3242 Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Thu, 21 Nov 2024 12:38:45 -0800 Subject: [PATCH 136/150] admin: remove exited admin members Cleanup Signed-off-by: Curtis Malainey --- maintainers/admin.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/maintainers/admin.rst b/maintainers/admin.rst index 209858f9..44a6d491 100644 --- a/maintainers/admin.rst +++ b/maintainers/admin.rst @@ -13,8 +13,6 @@ to multiple contributors: +---------------+-------------------+---------------+ | Intel | Marcin Maka | @mmaka1 | +---------------+-------------------+---------------+ -| Intel | Pierre Bossart | @plbossart | -+---------------+-------------------+---------------+ | Intel | Ranjani Sridharan | @ranj063 | +---------------+-------------------+---------------+ | NXP | Daniel Baluta | @dbaluta | From 99916eae9a0514e1daf879851672f0275d13b504 Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Thu, 21 Nov 2024 12:39:28 -0800 Subject: [PATCH 137/150] admin: replace google side admin Signed-off-by: Curtis Malainey --- maintainers/admin.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maintainers/admin.rst b/maintainers/admin.rst index 44a6d491..450bc783 100644 --- a/maintainers/admin.rst +++ b/maintainers/admin.rst @@ -17,7 +17,7 @@ to multiple contributors: +---------------+-------------------+---------------+ | NXP | Daniel Baluta | @dbaluta | +---------------+-------------------+---------------+ -| Google | Curtis Malainey | @cujomalainey | +| Google | Johny Lin | @johnylin76 | +---------------+-------------------+---------------+ Administrators may override specific merge rules, for example merge a From e26df4f0efd5d748269819b32a6f2f552b635137 Mon Sep 17 00:00:00 2001 From: Curtis Malainey Date: Thu, 21 Nov 2024 12:40:58 -0800 Subject: [PATCH 138/150] tsc: remove cujomalainey Signed-off-by: Curtis Malainey --- tsc/representatives.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tsc/representatives.rst b/tsc/representatives.rst index 09a53106..66b7ff4d 100755 --- a/tsc/representatives.rst +++ b/tsc/representatives.rst @@ -19,12 +19,12 @@ The TSC is currently made of the following contributors +---------------+----------------------+------------------+ | NXP | Daniel Baluta | @dbaluta | +---------------+----------------------+------------------+ -| Google | Curtis Malainey | @cujomalainey | -+---------------+----------------------+------------------+ | Google | Johny Lin | @johnylin76 | +---------------+----------------------+------------------+ | Google | Unseated | | +---------------+----------------------+------------------+ +| Google | Unseated | | ++---------------+----------------------+------------------+ | AMD | Carl Wakeland | @cwakeland | +---------------+----------------------+------------------+ | AMD | Virendra Pratap Arya | @vp-arya | From ef63f8940dcf0e77cb4472f962d5b033ecbac241 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 11 Dec 2024 13:38:53 +0200 Subject: [PATCH 139/150] intel_debug: introduction: Add information about modular SOF release content The firmware supports library loading starting with Meteor Lake and the release system is prepared to offer modular SOF releases. Update the documentation of the SOF release content to reflect this. Signed-off-by: Peter Ujfalusi --- getting_started/intel_debug/introduction.rst | 57 +++++++++++++++++--- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/getting_started/intel_debug/introduction.rst b/getting_started/intel_debug/introduction.rst index 2079812c..fe66798c 100755 --- a/getting_started/intel_debug/introduction.rst +++ b/getting_started/intel_debug/introduction.rst @@ -94,7 +94,10 @@ User space and filesystem requirements Selecting the SOF driver is not enough. Audio is properly configured only if the following elements are present on the file system. -1. Firmware binary +1. Firmware +----------- + +1.1. Base firmware ------------------ The firmware file, ``/lib/firmware/intel/sof/sof-tgl.ri`` (example @@ -117,6 +120,46 @@ Linux kernel to query whether or not the firmware authentication is enabled, which means `dmesg` logs cannot be provided to alert the user to an ME configuration issue. +.. _loadable-libraries: + +1.2. Loadable libraries +----------------------- + +An IPC4 library is a container of a single or multiple modules (bundle) which +can be loaded to the firmware after it is booted up. +Library loading is supported on Meteor Lake (ACE1) or newer platforms. + +Background information: the base firmware always resides in DSP SRAM while the +loaded library is stored in DRAM memory and only the needed code is copied to +SRAM for execution. By moving modules out from the base firmware to a library +can reduce the overall SRAM use depending on the device configuration and +topology. + +See :ref:`llext_modules` for technical details. + +1.3. Monolithic and modular SOF releases +---------------------------------------- + +SOF project releases for Intel platforms are either monolithic (only a single firmware binary) or modular (base firmware and external libraries). + +1.3.1. Modular SOF releases +--------------------------- + +See :ref:`loadable-libraries` for details about library support in general. + +The released libraries are: + - **sof-PLAT-openmodules.ri** : the bundle contains modules for audio processing not included in the base firmware + - **sof-PLAT-debug.ri** : the bundle contains modules that are needed for firmware debugging and profiling. Used by developers and for bug reporting if needed + - **UUID.bin** : Mainly 3rd party libraries identified by UUID. If the library contains multiple modules then a UUID symlink must be provided for each one. + +Notes: + - The Kernel will attempt to load \*-openmodules.ri followed by \*-debug.ri from the library path after the base firmware boot if they exist. + - additional libraries referenced by topology files or drivers will be loaded based on the UUID of the module from the library path. + + +1.4 Firmware lookup paths +------------------------- + Linux SOF will look up firmware files at the following paths: .. _intel_firmware_paths: @@ -144,14 +187,14 @@ Linux SOF will look up firmware files at the following paths: - IPC4 - /lib/firmware/intel/sof-ipc4/PLAT/community/sof-PLAT.ri - PLAT = tgl, adl, rpl, mtl, lnl, ... - * - Tiger Lake and newer Loadable Module + * - Meteor Lake and newer Loadable libraries - IPC4 - - /lib/firmware/intel/sof-ipc4-lib/PLAT/UUID.bin - - PLAT as above, UUID = UUID of the module - * - Tiger Lake and newer Loadable Module (community signed) + - /lib/firmware/intel/sof-ipc4-lib/PLAT/ + - PLAT = mtl, lnl, ... + * - Meteor Lake and newer Loadable libraries (community signed) - IPC4 - - /lib/firmware/intel/sof-ipc4-lib/PLAT/community/UUID.bin - - PLAT as above, UUID = UUID of the module + - /lib/firmware/intel/sof-ipc4-lib/PLAT/community/ + - PLAT = mtl, lnl, ... Important notices: - The standard Linux firmware search path and order is followed. The above table covers the base "/lib/firmware" case. See https://docs.kernel.org/driver-api/firmware/fw_search_path.html for more information. From 6eee88fce872bf03e3c72438272b33c5dd0c0ede Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 16 Dec 2024 18:24:35 +0200 Subject: [PATCH 140/150] intel_debug: introduction: Detail description of a modular firmware release Separate the firmware lookup table for non-modular and modular SOF releases to be able to document the locations and file names the firmware will be looking for the individual files. Extend the description of the two type of SOF release and convert the list-table to a normal table for better descriptions for the configurations. Signed-off-by: Peter Ujfalusi --- getting_started/intel_debug/introduction.rst | 105 ++++++++++--------- 1 file changed, 58 insertions(+), 47 deletions(-) diff --git a/getting_started/intel_debug/introduction.rst b/getting_started/intel_debug/introduction.rst index fe66798c..11e8ca55 100755 --- a/getting_started/intel_debug/introduction.rst +++ b/getting_started/intel_debug/introduction.rst @@ -127,7 +127,7 @@ configuration issue. An IPC4 library is a container of a single or multiple modules (bundle) which can be loaded to the firmware after it is booted up. -Library loading is supported on Meteor Lake (ACE1) or newer platforms. +Library loading is supported on Meteor Lake (ACE1) or newer platforms. Background information: the base firmware always resides in DSP SRAM while the loaded library is stored in DRAM memory and only the needed code is copied to @@ -137,64 +137,75 @@ topology. See :ref:`llext_modules` for technical details. -1.3. Monolithic and modular SOF releases ----------------------------------------- +1.3. Non-modular and modular firmware releases +---------------------------------------------- -SOF project releases for Intel platforms are either monolithic (only a single firmware binary) or modular (base firmware and external libraries). +SOF project releases for Intel platforms are either a single firmware or modular firmware based. -1.3.1. Modular SOF releases ---------------------------- +1.3.1. Non-modular firmware releases +------------------------------------ -See :ref:`loadable-libraries` for details about library support in general. +The release contains single a firmware image: **sof-PLAT.ri** -The released libraries are: +1.3.2. Modular firmware releases +-------------------------------- + +Modular SOF release is technically supported with IPC4 on Meteor Lake (MTL) or newer platforms since it depends on Loadable Library support (see :ref:`loadable-libraries` for details). + +Description of files provided by a modular release: + - **sof-PLAT.ri** : The base firmware - **sof-PLAT-openmodules.ri** : the bundle contains modules for audio processing not included in the base firmware - **sof-PLAT-debug.ri** : the bundle contains modules that are needed for firmware debugging and profiling. Used by developers and for bug reporting if needed - - **UUID.bin** : Mainly 3rd party libraries identified by UUID. If the library contains multiple modules then a UUID symlink must be provided for each one. + - **UUID.bin** : On demand loadable library identified by UUID. If the library contains multiple modules then a UUID symlink must be provided for each one. -Notes: - - The Kernel will attempt to load \*-openmodules.ri followed by \*-debug.ri from the library path after the base firmware boot if they exist. - - additional libraries referenced by topology files or drivers will be loaded based on the UUID of the module from the library path. +The main firmware can be shipped as a + - single binary (**sof-PLAT.ri**) + - split release when the base firmware (**sof-PLAT.ri**), processing modules (**sof-PLAT-openmodules.ri**) and debug/developer modules (**sof-PLAT-debug.ri**) are provided as separate binaries. + - After the base firmware boot, the kernel will load the **sof-PLAT-openmodules.ri** and **sof-PLAT-debug.ri** bundles to the firmware to provide equivalent functionality as the single binary release. + +Notes: + - additional libraries referenced by topology files or drivers will be loaded based on the UUID of the module from the library path (**UUID.bin**). 1.4 Firmware lookup paths ------------------------- -Linux SOF will look up firmware files at the following paths: - -.. _intel_firmware_paths: -.. list-table:: Firmware look-up paths per Intel platform - :widths: 55 5 50 25 - :header-rows: 1 - - * - Platform - - IPC type - - Firmware load path - - Notes - * - Raptor Lake and older - - IPC3 - - /lib/firmware/intel/sof/sof-PLAT.ri - - PLAT = glk, cml, ..., rpl - * - Raptor Lake and older (community signed) - - IPC3 - - /lib/firmware/intel/sof/community/sof-PLAT.ri - - PLAT = glk, cml, ..., rpl - * - Tiger Lake and newer - - IPC4 - - /lib/firmware/intel/sof-ipc4/PLAT/sof-PLAT.ri - - PLAT = tgl, adl, rpl, mtl, lnl, ... - * - Tiger Lake and newer (community signed) - - IPC4 - - /lib/firmware/intel/sof-ipc4/PLAT/community/sof-PLAT.ri - - PLAT = tgl, adl, rpl, mtl, lnl, ... - * - Meteor Lake and newer Loadable libraries - - IPC4 - - /lib/firmware/intel/sof-ipc4-lib/PLAT/ - - PLAT = mtl, lnl, ... - * - Meteor Lake and newer Loadable libraries (community signed) - - IPC4 - - /lib/firmware/intel/sof-ipc4-lib/PLAT/community/ - - PLAT = mtl, lnl, ... +Linux SOF will look up firmware files at the following paths. + +Look-up paths per Intel platform for **non-modular firmware releases** + +.. _intel_non_modular_firmware_paths: + ++-----------------------------------------------------------+--------+------------------------------------------------+-----------+-----------------------------------+ +|Platform |IPC type|Load path |File name |Notes | ++===========================================================+========+================================================+===========+===================================+ +|Raptor Lake and older |IPC3 |/lib/firmware/intel/sof/ |sof-PLAT.ri|PLAT = glk, cml, ..., rpl | ++-----------------------------------------------------------+ +------------------------------------------------+ | | +|Raptor Lake and older (community signed) | |/lib/firmware/intel/sof/community/ | | | ++-----------------------------------------------------------+--------+------------------------------------------------+ +-----------------------------------+ +|Tiger Lake and newer |IPC4 |/lib/firmware/intel/sof-ipc4/PLAT/ | |PLAT = tgl, adl, rpl, mtl, lnl, ...| ++-----------------------------------------------------------+ +------------------------------------------------+ | | +|Tiger Lake and newer (community signed) | |/lib/firmware/intel/sof-ipc4/PLAT/community/ | | | ++-----------------------------------------------------------+--------+------------------------------------------------+-----------+-----------------------------------+ + +Look-up paths per Intel platform for **modular firmware releases (IPC4 only)** + +.. _intel_modular_firmware_paths: + ++-----------------------------------------------------------+------------------------------------------------+-----------------------------+----------------------+ +|Platform |Load path |File name |Notes | ++===========================================================+================================================+=============================+======================+ +|Meteor Lake and newer |/lib/firmware/intel/sof-ipc4/PLAT/ || || PLAT = mtl, lnl, ...| +| | || sof-PLAT.ri || [*] PLAT = ptl, ... | +| | || sof-PLAT-openmodules.ri [*]| | +| | || sof-PLAT-debug.ri [*]| | ++-----------------------------------------------------------+------------------------------------------------+ | | +|Meteor Lake and newer (community signed) |/lib/firmware/intel/sof-ipc4/PLAT/community/ | | | ++-----------------------------------------------------------+------------------------------------------------+-----------------------------+ | +|Meteor Lake and newer Loadable libraries |/lib/firmware/intel/sof-ipc4-lib/PLAT/ |UUID.bin | | ++-----------------------------------------------------------+------------------------------------------------+ | | +|Meteor Lake and newer Loadable libraries (community signed)|/lib/firmware/intel/sof-ipc4-lib/PLAT/community/| | | ++-----------------------------------------------------------+------------------------------------------------+-----------------------------+----------------------+ Important notices: - The standard Linux firmware search path and order is followed. The above table covers the base "/lib/firmware" case. See https://docs.kernel.org/driver-api/firmware/fw_search_path.html for more information. From e7485000620f3a5a54949f94a099e9a926ab44fe Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Tue, 14 Jan 2025 17:47:30 +0800 Subject: [PATCH 141/150] topology2: add split topologies description Describe what are split topologies and how to create it. Signed-off-by: Bard Liao --- developer_guides/topology2/topology2.rst | 47 ++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/developer_guides/topology2/topology2.rst b/developer_guides/topology2/topology2.rst index 0d3538b1..86b5db62 100644 --- a/developer_guides/topology2/topology2.rst +++ b/developer_guides/topology2/topology2.rst @@ -1332,6 +1332,53 @@ You can use the ``-P`` switch to convert a 2.0 configuration file to the 1.0 con alsatplg <-D args=values> -P input.conf -o output.conf +Split topologies +**************** + +Linux kernel can load multiple topologies, a topology for a single function. +This feature is useful to support SDCA setups with standardized components. And no need to create topologies +for every new product. To achieve this, you need to split the topology into multiple tplg files. +The split topology files should be named as follows: + +.. code-block:: bash + + sof---id.tplg + +Currently is only needed for the DMIC function and not needed for SDCA functions in general. +It should be mtl, lnl, etc. + +Where should be one of + +.. code-block:: bash + + sdca-jack: SDCA headphone and headset. + sdca-amp: SDCA amp, where n is the amp link numbers. + sdca-mic: SDCA host mic. + dmic-ch: PCH DMIC, where n is the number of supported channels. Currently, only 2ch and 4ch are supported. + hdmi-pcm: HDMI with PCM id starts from . The is 3 for the "sof-hda-dsp" card and 5 for other cards. + + +For example + +.. code-block:: bash + + sof-sdca-2amp-id2.tplg + sof-sdca-mic-id4.tplg + sof-arl-dmic-2ch-id5.tplg + sof-hdmi-pcm5-id7.tplg + +The split topologies are the subset of the monolithic topology. Usually, you just need to add a description with proper +macro settings to disable the features that you don't need and set the first BE ID that in the topology in the cmake file +to generate the split topologies. + +For example + +.. code-block:: bash + + "cavs-sdw\;sof-arl-sdca-2amp-id2\;PLATFORM=mtl,NUM_SDW_AMP_LINKS=2,SDW_JACK=false,\ + SDW_AMP_FEEDBACK=false,SDW_SPK_STREAM=Playback-SmartAmp,NUM_HDMIS=0" + + Topology reminders ****************** From 52be2820318f4e702a52e8784dfb3eb67cf5fb5b Mon Sep 17 00:00:00 2001 From: Christopher Turner Date: Wed, 19 Feb 2025 12:31:57 -0600 Subject: [PATCH 142/150] conf.py: remove unused html_theme_path configuration Per build warning; WARNING: Calling get_html_theme_path is deprecated. If you are calling it to define html_theme_path, you are safe to remove that code. So removing the code to get rid of warning. Signed-off-by: Christopher Turner --- conf.py | 1 - 1 file changed, 1 deletion(-) diff --git a/conf.py b/conf.py index 4e1d22c7..77018705 100755 --- a/conf.py +++ b/conf.py @@ -132,7 +132,6 @@ sys.stderr.write('Warning: sphinx_rtd_theme missing. Use pip to install it.\n') else: html_theme = "sphinx_rtd_theme" - html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] html_theme_options = { 'canonical_url': '', 'analytics_id': 'GTM-M4BL5NF', From be866f6c3d30da8245d94c743e9047a0b12ffa4c Mon Sep 17 00:00:00 2001 From: Christopher Turner Date: Wed, 19 Feb 2025 12:45:57 -0600 Subject: [PATCH 143/150] conf.py: remove display_version configuration the option for display_version for the sphinx-rtd-theme was deprecated since v3.0.0 Signed-off-by: Christopher Turner --- conf.py | 1 - 1 file changed, 1 deletion(-) diff --git a/conf.py b/conf.py index 77018705..c64f3493 100755 --- a/conf.py +++ b/conf.py @@ -136,7 +136,6 @@ 'canonical_url': '', 'analytics_id': 'GTM-M4BL5NF', 'logo_only': False, - 'display_version': True, 'prev_next_buttons_location': 'None', # Toc options 'collapse_navigation': False, From c7bf0c1e9818b7348c0e0f01e36aa4fdf43817db Mon Sep 17 00:00:00 2001 From: Christopher Turner Date: Wed, 19 Feb 2025 12:52:11 -0600 Subject: [PATCH 144/150] developer_guides: llext_modules.rst: modify broken link for Intel firmware paths update broken link to Intel firmware paths in llext_modules.rst from intel_firmware_paths to intel_modular_firmware_paths to point to correct location and fix doc build errors. Signed-off-by: Christopher Turner --- developer_guides/firmware/llext_modules.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/developer_guides/firmware/llext_modules.rst b/developer_guides/firmware/llext_modules.rst index 4832495b..e4040d54 100644 --- a/developer_guides/firmware/llext_modules.rst +++ b/developer_guides/firmware/llext_modules.rst @@ -78,7 +78,7 @@ Installation ************ As specified in -:ref:`Firmware look-up paths per Intel platform ` +:ref:`Firmware look-up paths per Intel platform ` the |SOF| Linux kernel driver loads SOF modules by their UUIDs, specified in the topology. For SOF in-tree modules the process of creation and installation of modules in a deployment tree is automated by the From e99e90f677739c6e896e43dcbeaf4538773b4640 Mon Sep 17 00:00:00 2001 From: Suraj Sonawane Date: Thu, 13 Mar 2025 16:58:52 +0530 Subject: [PATCH 145/150] build_testbench: Fix mhwaveedit command The command `mhWaveEdit audio_out.wav` was incorrect because the package installs the binary as `mhwaveedit` (all lowercase). This commit corrects the capitalization to avoid command not found errors. Signed-off-by: Suraj Sonawane --- developer_guides/testbench/build_testbench.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/developer_guides/testbench/build_testbench.rst b/developer_guides/testbench/build_testbench.rst index 3f707b10..c6173507 100644 --- a/developer_guides/testbench/build_testbench.rst +++ b/developer_guides/testbench/build_testbench.rst @@ -115,7 +115,7 @@ it can be launched to an audio editor tool such as mhWaveEdit: .. code-block:: bash paplay audio_out.wav - mhWaveEdit audio_out.wav + mhwaveedit audio_out.wav .. figure:: fig_mhwaveedit.png From 6e56ea942f94147f590b44374223d98385c3ea4d Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Mon, 24 Mar 2025 20:42:37 +0100 Subject: [PATCH 146/150] Reset unwanted executable attributes Reset executable attributes on .rst, .txt, .diag files as well as on CODEOWNERS. Signed-off-by: Dmitrii Golovanov --- CODEOWNERS | 0 algos/demux/demux.rst | 0 architectures/firmware/index.rst | 0 architectures/firmware/intel/cavs/cavs-boot/apollolake/index.rst | 0 .../firmware/intel/cavs/cavs-boot/cavs-dsp-boot-overview.rst | 0 architectures/firmware/intel/cavs/index.rst | 0 architectures/firmware/intel/index.rst | 0 architectures/firmware/sof-xtos/schedulers.rst | 0 .../mpp_layer/images/mpp_scheduling/edf_scheduling.diag | 0 .../firmware/sof-zephyr/rtos_layer/zephyr_kernel_overview.rst | 0 architectures/index.rst | 0 getting_started/build-guide/build-from-scratch.rst | 0 getting_started/build-guide/build-with-zephyr.rst | 0 getting_started/index.rst | 0 getting_started/intel_debug/introduction.rst | 0 getting_started/intel_debug/suggestions.rst | 0 getting_started/nxp/sof_imx_user_guide.rst | 0 platforms/intel-cavs/commons/work-queue.rst | 0 release.rst | 0 scripts/requirements.txt | 0 tsc/representatives.rst | 0 21 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 CODEOWNERS mode change 100755 => 100644 algos/demux/demux.rst mode change 100755 => 100644 architectures/firmware/index.rst mode change 100755 => 100644 architectures/firmware/intel/cavs/cavs-boot/apollolake/index.rst mode change 100755 => 100644 architectures/firmware/intel/cavs/cavs-boot/cavs-dsp-boot-overview.rst mode change 100755 => 100644 architectures/firmware/intel/cavs/index.rst mode change 100755 => 100644 architectures/firmware/intel/index.rst mode change 100755 => 100644 architectures/firmware/sof-xtos/schedulers.rst mode change 100755 => 100644 architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/edf_scheduling.diag mode change 100755 => 100644 architectures/firmware/sof-zephyr/rtos_layer/zephyr_kernel_overview.rst mode change 100755 => 100644 architectures/index.rst mode change 100755 => 100644 getting_started/build-guide/build-from-scratch.rst mode change 100755 => 100644 getting_started/build-guide/build-with-zephyr.rst mode change 100755 => 100644 getting_started/index.rst mode change 100755 => 100644 getting_started/intel_debug/introduction.rst mode change 100755 => 100644 getting_started/intel_debug/suggestions.rst mode change 100755 => 100644 getting_started/nxp/sof_imx_user_guide.rst mode change 100755 => 100644 platforms/intel-cavs/commons/work-queue.rst mode change 100755 => 100644 release.rst mode change 100755 => 100644 scripts/requirements.txt mode change 100755 => 100644 tsc/representatives.rst diff --git a/CODEOWNERS b/CODEOWNERS old mode 100755 new mode 100644 diff --git a/algos/demux/demux.rst b/algos/demux/demux.rst old mode 100755 new mode 100644 diff --git a/architectures/firmware/index.rst b/architectures/firmware/index.rst old mode 100755 new mode 100644 diff --git a/architectures/firmware/intel/cavs/cavs-boot/apollolake/index.rst b/architectures/firmware/intel/cavs/cavs-boot/apollolake/index.rst old mode 100755 new mode 100644 diff --git a/architectures/firmware/intel/cavs/cavs-boot/cavs-dsp-boot-overview.rst b/architectures/firmware/intel/cavs/cavs-boot/cavs-dsp-boot-overview.rst old mode 100755 new mode 100644 diff --git a/architectures/firmware/intel/cavs/index.rst b/architectures/firmware/intel/cavs/index.rst old mode 100755 new mode 100644 diff --git a/architectures/firmware/intel/index.rst b/architectures/firmware/intel/index.rst old mode 100755 new mode 100644 diff --git a/architectures/firmware/sof-xtos/schedulers.rst b/architectures/firmware/sof-xtos/schedulers.rst old mode 100755 new mode 100644 diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/edf_scheduling.diag b/architectures/firmware/sof-zephyr/mpp_layer/images/mpp_scheduling/edf_scheduling.diag old mode 100755 new mode 100644 diff --git a/architectures/firmware/sof-zephyr/rtos_layer/zephyr_kernel_overview.rst b/architectures/firmware/sof-zephyr/rtos_layer/zephyr_kernel_overview.rst old mode 100755 new mode 100644 diff --git a/architectures/index.rst b/architectures/index.rst old mode 100755 new mode 100644 diff --git a/getting_started/build-guide/build-from-scratch.rst b/getting_started/build-guide/build-from-scratch.rst old mode 100755 new mode 100644 diff --git a/getting_started/build-guide/build-with-zephyr.rst b/getting_started/build-guide/build-with-zephyr.rst old mode 100755 new mode 100644 diff --git a/getting_started/index.rst b/getting_started/index.rst old mode 100755 new mode 100644 diff --git a/getting_started/intel_debug/introduction.rst b/getting_started/intel_debug/introduction.rst old mode 100755 new mode 100644 diff --git a/getting_started/intel_debug/suggestions.rst b/getting_started/intel_debug/suggestions.rst old mode 100755 new mode 100644 diff --git a/getting_started/nxp/sof_imx_user_guide.rst b/getting_started/nxp/sof_imx_user_guide.rst old mode 100755 new mode 100644 diff --git a/platforms/intel-cavs/commons/work-queue.rst b/platforms/intel-cavs/commons/work-queue.rst old mode 100755 new mode 100644 diff --git a/release.rst b/release.rst old mode 100755 new mode 100644 diff --git a/scripts/requirements.txt b/scripts/requirements.txt old mode 100755 new mode 100644 diff --git a/tsc/representatives.rst b/tsc/representatives.rst old mode 100755 new mode 100644 From 86e7dfe546771cecdc02dc5f06be047bd6225016 Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Tue, 25 Mar 2025 10:58:38 +0100 Subject: [PATCH 147/150] docbuild: Add a note on additional libraries Add a note on additional libraries needed to build the hardcoded version of pillow package. Signed-off-by: Dmitrii Golovanov --- contribute/process/docbuild.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/contribute/process/docbuild.rst b/contribute/process/docbuild.rst index f1dd8f91..5a0c2817 100644 --- a/contribute/process/docbuild.rst +++ b/contribute/process/docbuild.rst @@ -163,6 +163,20 @@ tools: PIP_IGNORE_INSTALLED=0 pip3 install --user -r scripts/requirements-lax.txt + The hardcoded package versions might need additional libraries installed + in order to compile them. For example, to resolve the following error: + + .. code-block:: bash + + ERROR: Could not build wheels for pillow, which is required to install pyproject.toml-based projects + + you should install: + + .. code-block:: bash + + sudo apt install libjpeg-dev zlib1g-dev + + For Windows, install the needed tools manually: * Python (3.7+) from https://www.python.org/downloads/ From 49f3c6eb5da8cf020fc2d95e5a1f8f918dadda87 Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Tue, 25 Mar 2025 11:00:43 +0100 Subject: [PATCH 148/150] docbuild: Adjust HTML generation commands Adjust code snippets for HTML generation after #9788c4be changes to avoid doxygen build in source directory. Signed-off-by: Dmitrii Golovanov --- contribute/process/docbuild.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contribute/process/docbuild.rst b/contribute/process/docbuild.rst index 5a0c2817..06570e03 100644 --- a/contribute/process/docbuild.rst +++ b/contribute/process/docbuild.rst @@ -238,8 +238,8 @@ Docker image (2) cd thesofproject # API documentation (Doxygen) - cmake -S sof/doc -B sof/doc -GNinja - ninja -C sof/doc -v doc + cmake -S sof/doc -B sof/build_doxygen -GNinja + ninja -C sof/build_doxygen -v doc # UML and reStructuredText make -C sof-docs VERBOSE=1 html @@ -305,7 +305,7 @@ publishing. .. note:: In some situations it is necessary to clean all the files and build from - the very beginning. To do this, use the ``make clean`` command. + the very beginning. To do this, use the ``make -C sof-docs clean`` command. Installation troubleshooting **************************** From 7a448ff2e7228364d8255133e8f2909d43a7ebee Mon Sep 17 00:00:00 2001 From: Dmitrii Golovanov Date: Tue, 25 Mar 2025 11:18:10 +0100 Subject: [PATCH 149/150] build-guide: Use Zephyr HWMv2 board names Use Zephyr HWMv2 board names in `west build` command examples. Signed-off-by: Dmitrii Golovanov --- getting_started/build-guide/build-with-zephyr.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/getting_started/build-guide/build-with-zephyr.rst b/getting_started/build-guide/build-with-zephyr.rst index 781dc920..e3eb035d 100644 --- a/getting_started/build-guide/build-with-zephyr.rst +++ b/getting_started/build-guide/build-with-zephyr.rst @@ -163,17 +163,17 @@ Check out and build using west tool directly .. code-block:: bash - west build --build-dir build-tgl --board intel_adsp_cavs25 ./sof/app + west build --build-dir build-tgl --board intel_adsp/cavs25 ./sof/app - Note that the SOF project defines platform names that have Zephyr board counterparts. In the above example, the *Tigerlake* platform matches the ``inteL_adsp_cavs25`` Zephyr board. This is why the output directory is named ``build-tgl``; however, you may use any name you wish. + Note that the SOF project defines platform names that have Zephyr board counterparts. In the above example, the *Tigerlake* platform matches the ``intel_adsp/cavs25`` Zephyr board target (see `Zephyr HWMv2 board terminology `_). This is why the output directory is named ``build-tgl``; however, you may use any name you wish. .. note:: To add verbosity to the build output use the -v -v flags. Example: - ``west -v -v build --build-dir build-tgl --board intel_adsp_cavs25 ./sof/app`` + ``west -v -v build --build-dir build-tgl --board intel_adsp/cavs25 ./sof/app`` To perform a complete clean rebuild, use the --pristine flag. Example: - ``west -v -v build --build-dir build-tgl --pristine always --board intel_adsp_cavs25 ./sof/app`` + ``west -v -v build --build-dir build-tgl --pristine always --board intel_adsp/cavs25 ./sof/app`` The ``.elf`` file produced by the ``west build`` is missing a manifest and signature. A a result, you must sign the file using the **rimage tool** From 32b3fcaf9824dbe4886c365bed9f4d80437b6d14 Mon Sep 17 00:00:00 2001 From: Marcin Szkudlinski Date: Thu, 4 Sep 2025 14:18:47 +0200 Subject: [PATCH 150/150] Design of DP scheduling with deadline calculations this commit contains a detailed description of DP scheduling and DP deadline calculations Signed-off-by: Marcin Szkudlinski --- .../sof-zephyr/mpp_layer/dp_scheduling.rst | 614 ++++++++++++++++++ .../images/dp_scheduling/example1.pu | 34 + .../images/dp_scheduling/example1_1.pu | 34 + .../images/dp_scheduling/example1_2.pu | 34 + .../images/dp_scheduling/example1_3.pu | 40 ++ .../images/dp_scheduling/example1_4.pu | 42 ++ .../images/dp_scheduling/example1_5.pu | 41 ++ .../images/dp_scheduling/example2.pu | 34 + .../images/dp_scheduling/example2_1.pu | 40 ++ .../images/dp_scheduling/example2_1a.pu | 34 + .../images/dp_scheduling/example2_2.pu | 34 + .../images/dp_scheduling/example2_2a.pu | 34 + .../images/dp_scheduling/example2_3.pu | 40 ++ .../images/dp_scheduling/example2_4.pu | 40 ++ .../images/dp_scheduling/example2_5.pu | 40 ++ .../images/dp_scheduling/example2_6.pu | 34 + .../images/dp_scheduling/example2_7.pu | 39 ++ .../images/dp_scheduling/example3.pu | 34 + .../images/dp_scheduling/example3_1.pu | 34 + .../images/dp_scheduling/example3_2.pu | 34 + .../images/dp_scheduling/example3_3.pu | 34 + .../images/dp_scheduling/example3_4.pu | 34 + .../images/dp_scheduling/example3_5.pu | 34 + .../images/dp_scheduling/example3_6.pu | 34 + .../images/dp_scheduling/example3_7.pu | 40 ++ .../images/dp_scheduling/example4.pu | 38 ++ .../images/dp_scheduling/example4_1.pu | 38 ++ .../images/dp_scheduling/example4_2.pu | 38 ++ .../images/dp_scheduling/pic1_chains.pu | 16 + .../firmware/sof-zephyr/mpp_layer/index.rst | 1 + 30 files changed, 1617 insertions(+) create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/dp_scheduling.rst create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1_1.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1_2.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1_3.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1_4.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1_5.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_1.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_1a.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_2.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_2a.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_3.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_4.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_5.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_6.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_7.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_1.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_2.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_3.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_4.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_5.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_6.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_7.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example4.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example4_1.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example4_2.pu create mode 100644 architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/pic1_chains.pu diff --git a/architectures/firmware/sof-zephyr/mpp_layer/dp_scheduling.rst b/architectures/firmware/sof-zephyr/mpp_layer/dp_scheduling.rst new file mode 100644 index 00000000..c6adf7ff --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/dp_scheduling.rst @@ -0,0 +1,614 @@ +DP a.k.a. "Data processing" with EDF scheduling +************************************************ + +DP a.k.a. "Data processing" is an async scheduling method of data processing modules. Each module works in a separate, preemptible thread with lower priority than LL thread. It allows processing with periods longer than 1ms, on-demand processing, etc. + +Unlike in LL "low latency" method where a module started every 1ms cycle and all of LL modules together MUST finish processing 1ms, DP works async and gets CPU when a module is "ready for processing", what means: + + - on each module's input buffer there's at least IBS bytes of data and in each module's output buffer there's at least OBS bytes of free space + + OR + + - a module declared readiness by itself by an optional API call "is_ready_to_process" + +Critical part is that the module **must** finish processing before its **deadline**. A deadline is a time when the modules must provide a data chunk in order to keep next module(s) in the pipeline working. + +To ensure that all modules provide data on time - as long as CPU is not overloaded - regardless of modules' processing times and processing periods, a Earliest Deadline First (EDF) scheduling is used. https://en.wikipedia.org/wiki/Earliest_deadline_first_scheduling + +A list of all DP tasks, regardless on core the task is on, is to be iterated every time the situation of DP readiness or deadline timing may change, that include: + + - finish of processing of LL pipeline (on any core) + - finish of processing of any DP module (on any core) + +during the iteration, the following will be checked: + + - Readiness of each DP module. As mentioned before, module "is ready" when declared readiness by itself an API call or when it has at least IBS of data on each input and at least OBS free space on each out + - deadline calculation of each DP module. LFTs and Deadlines are not constant, they may change when a module consume/produce a portion of data. Therefore all LFTs and Deadlines must be re-calculated + +DEADLINE CALCULATIONS +====================== + +The most critical part is to calculate deadlines. Lets go from the beginning, there are some definitions: + +**def: buffers' Latest Feeding Time (LFT)** + +LFT is the latest time when **a buffer** must be fed with a portion of data allowing its data consumer to work and finish in its specific time + +LFT is a parameter specific to a buffer and can be calculated based on: + + - current amount of data in the buffer + - data reciever's consumption rate and period + - data source production rate and period + - data reciever's module's LST - latest start time + +so, in high level LFT is a sum of: + + - Latest start time (LST) of the data consumer (LST is defined later) + + - estimated time the consumer will drain the current data from the buffer: ``number_of_ms_in_buffer / consumer_period`` + + i.e. if there's 5ms of data in the buffer and period of the consumer is 2ms, the calculated time is ``4ms`` + + - correction for multiple source cycle + + in case the producer period < consumer period the LFT time needs to be corrected, as the producer must process more than once to provide enough data. The correction will be calculated as: ``producer_LPT * required_number_of_cycles`` where LPT is longest processing time, explained later + + ``correction = producer_LPT * ((consumer_period - number_of_ms_in_buffer) / producer_period)`` + + if correction is < 0, it should be set to zero. Note that in case producer_period >= consumer_period correction is always 0 + +finally: ``LFT = LST(consumer) + estimated_drain_time - correction`` + +**def: DP module's DEADLINE** + +a DEADLINE is the latest moment **a module** must finish processing to feed all target buffers before their LFTs. +Calculation is simple: + + - module's deadline is the nearest LFT of all target buffers + +in case te LFT of the buffer cannot be calculated - that may happen during pipeline startup or if there's no output buffer, i.e. a module like speech recognition - deadline should be set to "moment when module becomes ready + modules's period" + +**def: DP module's Longest Processing Time (LPT)** + +LPT is the longest time the module may process a portion of data, assuming it is scheduled 100% of CPU time. **LPT cannot be measured in runtime** as processing may change from cycle to cycle, etc. It can, however, be estimated based on: + +- declared (by a module vendor) number of CPU cycles required for processing. This declaration should be done separately for all combination of input/output data formats, platform, CPU type, using of HiFi etc. and either included in manifest od provided in an IPC call +- If declaration is not available, we can take "a period" as an approximation of longest possible processing time. "A period" is a value calculated using IBS and data consumption rate of a module. A module cannot possibly processing longer than its period, because it would never provide data in time (if LPT = period that means a module required 100% of CPU for processing, so it is really the worst possible case) + +*Example:* if a data rate is 48samples/msec and OBS = 480samples, the "worst case" period should be calculated 10ms + +*NOTE:* in case of sampling freq like 44.1 a round up should taken - if ration is 44.1 samples per mlisecond, 45 samples should be used for calculations + +The "worst case approximation", however a correct, is assuming that a module is a heavy one and it requires 100% of CPU time. Using it may lead to unnecessary buffering, see "delayed start" section below. + +**def: DP module's latest start time (LST)** + +LST is the latest time when **a module** must start processing a portion of data in order to meet its deadline. It can be calculated as: +``deadline - LPT`` When a module is in the middle of processing, its LST may be negative. In that case 0 should be taken to all futhure calculations. + +**Based on an above, it is clear that we do need to calculate first a deadline of the very latest module in a chain, than go back and calculate LFTs and deadline of each module separately** + +Fortunate is that the last module of a pipeline is almost always an LL module (usually DAI). For LL module deadline always is "NOW", so it is very easy to calculate LFTs for its input buffer(s). note: in case of data rates like 44.1, which cannot be divided to 1ms, a round up to 45 should be used: + + - LL module always start in 1ms periods + - LL module always consume constant number of bytes in a cycle (with an exception for frequencies like 44.1, a round up 45KHz should be taken for calculations) + + so ``LFT = NOW + number of data chunks in buffer * 1ms`` + +"NOW" in all of the calculations is "last start of LL scheduler". It makes all calculations simpler, as in the examples below (calculating CPU cycles would require taking extra care for 32bit overflows or use slow 64bit operations). Also all modules have the same timestamp as "NOW", regardless of moment in the cycle the deadlines are calculated. + +If a module is in the middle of processing, it should not release data from input buffer till the processing is finished, so the input buffer should be considered as it was at the moment the processing started, otherwise deadlines may be miscalculated. + +In case of pipeline like: + +.. uml:: images/dp_scheduling/pic1_chains.pu + +there are 2 separate deadline calculation chains: DP4 than DP3, and (independent) DP2 than DP1. **Also note that deadlines and other parameters may change, so re-calculation of all parameters should occur reasonable frequently and include all DP modules, regardless of a core it is run on** + +End of stream +============= + +When a SP module is in the middle of processing when a pipeline is stopping, it should finish processing its current chunk of data. Unformtunately there's no way to interrupt ongoing processing without risk of memory leaks etc. Therefore IPC stopping a pipeline should wait till all DP modules finish processing. + +EXAMPLE1 +========= +*data source period is longer or equal to data consumer period* +Note that in the example CPU load is very close to 100%, yet deadline calculation and EDF scheduling allow to keep the processing on time. + +for simplification lets assume: + + - the pipeline is in stable state (processing for a while, not in startup) + - no DP is currently processing + - whole CPU is dedicated to DP, like if LL is on core 0 and DPs on core 1 + +**0ms time:** + +.. uml:: images/dp_scheduling/example1.pu + +Pipeline state: + + - DP1 is ready for processing + - DP2 is ready for processing + + calculate deadlines: + + - ``buf3 LFT = 15 periods of LL2`` ==> ``DP2 deadline = 15ms`` + - ``DP2 LST = 15ms (DP2 deadline) - 9ms (DP2 LPT) = 6ms`` + - ``buf2 LFT = 6ms (DP2 LST) + 10ms (1 period in buf2) = 16ms`` ==> ``DP1 deadline = 16ms`` + + DP2 will be scheduled as it has earliest deadline, will process for 9ms + +**9ms time, DP2 finished processing but not yet released data from BUF2:** + +.. uml:: images/dp_scheduling/example1_1.pu + +Pipeline state: + + - DP1 is ready for processing + - DP2 just finished processing + + calculate deadlines: + + - ``buf3 LFT = 6 periods of LL2`` ==> ``DP2 deadline = 6ms`` + - ``DP2 LST = 6ms(DP2 deadline) - 9ms (DP2 LPT) = -3ms`` LST is negative, 0 should be used ``DP2 LST = 0`` + - ``buf2 LFT = 6ms (DP2 LST) + 10ms (1 period in buf2) = 16ms`` ==> ``DP1 deadline = 16ms`` + + DP1 will be scheduled + +**9ms time, DP2 released data from BUF2:** + +.. uml:: images/dp_scheduling/example1_2.pu + +Pipeline state: + + - DP1 is ready for processing + - DP2 is not ready for processing + + calculate deadlines: + + - ``buf3 LFT = 16 periods of LL2`` ==> ``DP2 deadline = 16ms`` + - ``DP2 LST = 16ms(DP2 deadline) - 9ms (DP2 LPT) = 7ms`` + - ``buf2 LFT = 7ms (DP2 LST) = 7ms`` ==> ``DP1 deadline = 7ms`` + + DP1 will be scheduled, will run for 5ms + +**14ms time, DP1 finished processing and released data from BUF1:** + +.. uml:: images/dp_scheduling/example1_3.pu + +Pipeline state: + + - DP1 is not ready for processing + - DP2 is ready for processing + + calculate deadlines: + + - ``buf3 LFT = 11 periods of LL2`` ==> ``DP2 deadline = 11ms`` + - ``DP2 LST = 11ms(DP2 deadline) - 9ms (DP2 LPT) = 2ms`` + - ``buf2 LFT = 2ms (DP2 LST) + 100ms (10 periods in buf2) = 102ms`` ==> ``DP1 deadline = 102ms`` + + DP2 will be scheduled + +**100ms time, 86ms passed, DP2 processed 9 times, is in the middle of 10th processing, having 5ms left:** + +.. uml:: images/dp_scheduling/example1_4.pu + +Pipeline state: + + - DP1 is ready for processing + - DP2 is ready for processing + + calculate deadlines: + + - ``buf3 LFT = 15 periods of LL2`` ==> ``DP2 deadline = 15ms`` + - ``DP2 LST = 15ms(DP2 deadline) - 9ms (DP2 LPT) = 6ms`` + - ``buf2 LFT = 6ms (DP2 LST) + 10ms (1 period in buf2) = 16ms`` ==> ``DP1 deadline = 16ms`` + + DP2 will be scheduled + +**105ms time, DP2 finished processing and released data from BUF2:** + +.. uml:: images/dp_scheduling/example1_5.pu + +Pipeline state: + + - DP1 is ready for processing + - DP2 is not ready for processing + + calculate deadlines: + + - ``buf3 LFT = 20 periods of LL2`` ==> ``DP2 deadline = 20ms`` + - ``DP2 LST = 20ms(DP2 deadline) - 9ms (DP2 LPT) = 11ms`` + - ``buf2 LFT = 11ms (DP2 LST) + 0ms = 11ms`` ==> ``DP1 deadline = 11ms`` + + DP1 will be scheduled + +EXAMPLE2 +========= +*data source period is shorter than data consumer period* + +**0ms time:** + +.. uml:: images/dp_scheduling/example2.pu + +Pipeline state: + + - DP1 is ready for processing + - DP2 is not ready for processing + + calculate deadlines: + + - ``buf3 LFT = 18 periods of LL2`` ==> ``DP2 deadline = 18ms`` + - ``DP2 LST = 18ms (DP2 deadline) - 10ms (DP2 LPT) = 8ms`` + - ``buf2 LFT = 8ms(DP2 LST) + 0 (0 complete periods of DP2 in buf2) = 8ms`` correction for multiple source cycle is = 0 + - ``DP1 deadline = 8ms`` + + DP1 will be scheduled + +**2ms time:** + +.. uml:: images/dp_scheduling/example2_1.pu + +Pipeline state: + + - DP1 is not ready for processing + - DP2 is ready for processing + + calculate deadlines: + + - ``buf3 LFT = 16 periods of LL2`` ==> ``DP2 deadline = 16ms`` + - ``DP2 LST = 16ms (DP2 deadline) - 10ms (DP2 LPT) = 6ms`` + - ``buf2 LFT = 6ms(DP2 LST) + 20 (1 complete periods of DP2 in buf2) = 26ms`` correction for multiple source cycle is < 0, so 0 is used + - ``DP1 deadline = 26ms`` + + DP2 will be scheduled + +**5ms time:** + +.. uml:: images/dp_scheduling/example2_1a.pu + +Pipeline state: + + - DP1 is ready for processing + - DP2 is in the middle of processing, still has to keep processing for 7ms. According to rules, the module should not release data from input buffer till the processing is finished, so buf2 still contains 20ms samples + + calculate deadlines: + + - ``buf3 LFT = 13 periods of LL2`` ==> ``DP2 deadline = 13ms`` + - ``DP2 LST = 13ms (DP2 deadline) - 10ms (DP2 LPT) = 3ms`` + - ``buf2 LFT = 3ms(DP2 LST) + 20 (1 complete periods of DP2 in buf2) = 23ms`` correction for multiple source cycle is < 0, so 0 is used + - ``DP1 deadline = 23ms`` + + DP2 will be scheduled and will keep processing for 7ms + +**12ms time, before releasing data from buf2 and acking data in buf3** + +.. uml:: images/dp_scheduling/example2_2a.pu + +Pipeline state: + + - DP1 is ready for processing + - DP2 finished processing, but not yet released data from buf2, so buf2 still contains 20ms samples + + calculate deadlines: + + - ``buf3 LFT = 6 periods of LL2`` ==> ``DP2 deadline = 6ms`` + - ``DP2 LST = 6ms (DP2 deadline) - 10ms (DP2 LPT) = -4ms`` LST is negative, so 0 should be used + - ``buf2 LFT = 0ms(DP2 LST) + 20ms (1 complete periods of DP2 in buf2) = 20ms`` correction for multiple source cycle is < 0, so 0 is used + - ``DP1 deadline = 20ms`` + + DP2 will be release data + +**12ms time, after releasing data from buf2 and acking data in buf3** + +.. uml:: images/dp_scheduling/example2_2.pu + +Pipeline state: + + - DP1 is ready for processing + - DP2 is not ready for processing + + calculate deadlines: + + - ``buf3 LFT = 26 periods of LL2`` ==> ``DP2 deadline = 26ms`` + - ``DP2 LST = 26ms (DP2 deadline) - 10ms (DP2 LPT) = 16ms`` + - ``buf2 LFT = 16ms(DP2 LST) + 0 (0 complete periods of DP2 in buf2) - 8ms correction (4 periods of DP2 * 2ms DP1 LPT) = 8ms`` + - ``DP1 deadline = 8ms`` + + DP1 will be scheduled + +**14ms time:** + +.. uml:: images/dp_scheduling/example2_3.pu + +Pipeline state: + + - DP1 is ready for processing + - DP2 is not ready for processing + + calculate deadlines: + + - ``buf3 LFT = 24 periods of LL2`` ==> ``DP2 deadline = 24ms`` + - ``DP2 LST = 24ms (DP2 deadline) - 10ms (DP2 LPT) = 14ms`` + - ``buf2 LFT = 14ms(DP2 LST) + 0 (0 complete periods of DP2 in buf2) - 6ms correction (3 periods of DP2 * 2ms DP1 LPT) = 8ms`` + - ``DP1 deadline = 8ms`` + + DP1 will be scheduled + +**16ms time:** + +.. uml:: images/dp_scheduling/example2_4.pu + +Pipeline state: + + - DP1 is ready for processing + - DP2 is not ready for processing + + calculate deadlines: + + - ``buf3 LFT = 22 periods of LL2`` ==> ``DP2 deadline = 22ms`` + - ``DP2 LST = 22ms (DP2 deadline) - 10ms (DP2 LPT) = 12ms`` + - ``buf2 LFT = 12ms(DP2 LST) + 0 (0 complete periods of DP2 in buf2) - 4ms correction (2 periods of DP2 * 2ms DP1 LPT) = 8ms`` + - ``DP1 deadline = 8ms`` + + DP1 will be scheduled + +**18ms time:** + +.. uml:: images/dp_scheduling/example2_5.pu + +Pipeline state: + + - DP1 is not ready for processing + - DP2 is not ready for processing + + calculate deadlines - however pointless at when no DP is ready: + + - ``buf3 LFT = 20 periods of LL2`` ==> ``DP2 deadline = 20ms`` + - ``DP2 LST = 20ms (DP2 deadline) - 10ms (DP2 LPT) = 10ms`` + - ``buf2 LFT = 10ms(DP2 LST) + 0 (0 complete periods of DP2 in buf2) - 2ms correction (2 periods of DP2 * 2ms DP1 LPT) = 8ms`` + - ``DP1 deadline = 8ms`` + + no DP will be scheduled + +**20ms time:** + +.. uml:: images/dp_scheduling/example2_6.pu + +Pipeline state: + + - DP1 is ready for processing + - DP2 is not ready for processing + + calculate deadlines - however pointless at when no DP is ready: + + - ``buf3 LFT = 18 periods of LL2`` ==> ``DP2 deadline = 18ms`` + - ``DP2 LST = 18ms (DP2 deadline) - 10ms (DP2 LPT) = 8ms`` + - ``buf2 LFT = 8ms(DP2 LST) + 0 (0 complete periods of DP2 in buf2) - 2ms correction (2 periods of DP2 * 2ms DP1 LPT) = 6ms`` + - ``DP1 deadline = 6ms`` + + DP1 will be scheduled + +**22ms time:** + +.. uml:: images/dp_scheduling/example2_7.pu + +Pipeline state: + + - DP1 is not ready for processing + - DP2 is ready for processing + + calculate deadlines + + - ``buf3 LFT = 16 periods of LL2`` ==> ``DP2 deadline = 16ms`` + - ``DP2 LST = 16ms (DP2 deadline) - 10ms (DP2 LPT) = 6ms`` + - ``buf2 LFT = 6ms(DP2 LST) +20 (1 complete period of DP2 in buf2) = 26ms`` correction for multiple source cycle is = 0 + - ``DP1 deadline = 26ms`` + + DP2 will be scheduled + + +STARTUP +========== + +Special case is "pipeline startup". When a pipeline is starting, deadlines cannot be calculated as all the modules are already late and deadlines are in the past. According to deadline calculation rules, the deadline is set to time when the module becomes ready + module's LPT. + +If a module finishes processing before its LPT. it is not guaranteed that it will do it again in any of next cycles. If it happens, the data should be held in the buffer till LPT passes. This prevents underruns in case any of future processing takes longer. This mechanism is called "delayed start". The module should stay in "delayed start" state till the next module becomes ready for the first time. + +Delayed start makes EDF scheduling possible and ensures that even when CPU load close to 100% every module have enough processing time to finish within its deadline. + +Example of a pipeline startup and 100% cpu usage +================================================ + +**0ms time:** + +.. uml:: images/dp_scheduling/example3.pu + +Pipeline state: + + - DP1 is not ready for processing, in startup delay state + - DP2 is not ready for processing, in startup delay state + + calculate deadlines + + - dedline of DP2 can't be calculated + - dedline of DP1 can't be calculated + + no DP will be scheduled + +**5ms time:** + +.. uml:: images/dp_scheduling/example3_1.pu + +Pipeline state: + + - DP1 is ready for processing, in startup delay state + - DP2 is not ready for processing, in startup delay state + + calculate deadlines + + - deadline for DP2 cant be calculated + - deadline of DP1 is fixed to 2ms (NOW + DP1 LPT) - because DP2 deadline cannot be calculated + + DP1 will be scheduled + +**7ms time:** + +.. uml:: images/dp_scheduling/example3_2.pu + +Pipeline state: + + - DP1 is not ready for processing, in startup delay state + - DP2 is not ready for processing, in startup delay state + + calculate deadlines + + - deadline for DP2 cant be calculated + - deadline for DP1 cant be calculated + + no DP will be scheduled + +**10ms time:** + +.. uml:: images/dp_scheduling/example3_3.pu + +Pipeline state: + + - DP1 is ready for processing, in startup delay state + - DP2 is not ready for processing, in startup delay state + + calculate deadlines + + - deadline for DP2 cant be calculated + - deadline of DP1 is fixed to 2ms (NOW + DP1 LPT) - because DP2 deadline cannot be calculated + + DP1 will be scheduled + +**12ms time:** + +.. uml:: images/dp_scheduling/example3_4.pu + +Pipeline state: + + - DP1 is not ready for processing, leaving startup delay state + - DP2 is ready for processing, in startup delay state + + calculate deadlines + + - deadline for DP2 is fixed to 6ms (NOW + DP2 LPT) + - ``DP2 LST = 6ms (DP2 deadline) - 6ms (DP2 LPT) = 0ms`` + - ``buf2 LFT = 0ms(DP2 LST) + 10ms (1 complete period of DP2 in buf2) = 10ms`` correction for multiple source cycle is = 0 + - ``DP1 deadline = 14ms`` + + DP2 will be scheduled + +**15ms time:** + +.. uml:: images/dp_scheduling/example3_5.pu + +Pipeline state: + + - DP1 is ready for processing + - DP2 is the middle for processing, 3ms left, in startup delay state + + calculate deadlines + + - deadline for DP2 was fixed to 6ms 3ms ago, so now it is 3ms + - ``DP2 LST = 3ms (DP2 deadline) - 6ms (DP2 LPT) = -3ms`` 0 will be used + - ``buf2 LFT = 0(DP2 LST) +10 (1 complete period of DP2 in buf2) = 10ms`` correction for multiple source cycle is = 0 + - ``DP1 deadline = 10ms`` + + DP2 will be scheduled + +**17ms time:** + +.. uml:: images/dp_scheduling/example3_6.pu + +Pipeline state: + + - DP1 is ready for processing + - DP2 is not ready for processing, leaving startup delay state + + calculate deadlines + + - ``buf3 LFT = 10 periods of LL2`` ==> ``DP2 deadline = 10ms`` + - ``DP2 LST = 10ms (DP2 deadline) - 6ms (DP2 LPT) = 4ms`` + - ``buf2 LFT = 4ms(DP2 LST) + 0 (0 complete periods of DP2 in buf2) - 2ms correction (2 periods of DP2 * 2ms DP1 LPT) = 2ms`` + - ``DP1 deadline = 2ms`` + + DP1 will be scheduled + +**19ms time:** + +.. uml:: images/dp_scheduling/example3_7.pu + +Pipeline state: + + - DP1 is ready for processing + - DP2 is not ready for processing + + calculate deadlines + + - ``buf3 LFT = 8 periods of LL2`` ==> ``DP2 deadline = 8ms`` + - ``DP2 LST = 10ms (DP2 deadline) - 6ms (DP2 LPT) = 2ms`` + - ``buf2 LFT = 2ms(DP2 LST) + 0 (0 complete periods of DP2 in buf2) - 0ms correction (0 periods of DP2 * 2ms DP1 LPT) = 2ms`` + - ``DP1 deadline = 2ms`` + + DP1 will be scheduled + + +Example of a 2 pipelines, one running and one in startup and 100% cpu usage +============================================================================ + +pipeline1 is running, DP use 80% of CPU, pipeline2 is starting. Calculating of DP1/DP2 LST and BUF1/BUF3 LFT makes no sense as they're connected to LLs + +**0ms time:** + +.. uml:: images/dp_scheduling/example4.pu + +Pipeline state: + + - DP1 is ready for processing + - DP2 is not ready for processing + + calculate deadlines + + - ``buf2 LFT = 10 periods of LL2`` ==> ``DP1 deadline = 10ms`` + - DP2 deadline cannot be calculated + + DP1 will be scheduled + +**5ms time:** + +.. uml:: images/dp_scheduling/example4_1.pu + +Pipeline state: + + - DP1 is in the middle of processing, 3ms left + - DP2 is ready for processing, in startup delay state + + calculate deadlines + + - ``buf2 LFT = 5 periods of LL2`` ==> ``DP1 deadline = 5ms`` + - DP2 deadline is fixed to ``DP2 period = 1ms`` + + DP1 will be preempted, DP2 will be scheduled + +**6ms time:** + +.. uml:: images/dp_scheduling/example4_2.pu + +Pipeline state: + + - DP1 is in the middle of processing, 3ms left + - DP2 is not ready for processing, leaving startup delay state + + calculate deadlines + + - ``buf2 LFT = 4 periods of LL2`` ==> ``DP1 deadline = 4ms`` + - ``buf4 LFT = 5 periods of LL2`` ==> ``DP2 deadline = 5ms`` + + + DP2 will be scheduled + + diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1.pu new file mode 100644 index 00000000..969188bb --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1.pu @@ -0,0 +1,34 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n100ms of data\n" as buf1 + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 100ms + LPT: 5ms +end note + +rectangle "BUF2\n\n10ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 10ms + LPT: 9ms +end note + +rectangle "BUF3\n\n15ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1_1.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1_1.pu new file mode 100644 index 00000000..b8f65e24 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1_1.pu @@ -0,0 +1,34 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n109ms of data\n" as buf1 + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 100ms + LPT: 5ms +end note + +rectangle "BUF2\n\n10ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 10ms + LPT: 9ms +end note + +rectangle "BUF3\n\n6ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1_2.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1_2.pu new file mode 100644 index 00000000..9b8798ba --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1_2.pu @@ -0,0 +1,34 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n109ms of data\n" as buf1 + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 100ms + LPT: 5ms +end note + +rectangle "BUF2\n\n0ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 10ms + LPT: 9ms +end note + +rectangle "BUF3\n\n16ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1_3.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1_3.pu new file mode 100644 index 00000000..5dd8d956 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1_3.pu @@ -0,0 +1,40 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n14ms of data\n" as buf1 +note bottom of buf1 + there was 109ms + LL1 produced 5ms + DP1 consumed 100ms + 109+5-100 = 14ms +end note + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 100ms + LPT: 5ms +end note + +rectangle "BUF2\n\n100ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 10ms + LPT: 9ms +end note + +rectangle "BUF3\n\n11ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1_4.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1_4.pu new file mode 100644 index 00000000..03ed3355 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1_4.pu @@ -0,0 +1,42 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n100ms of data\n" as buf1 + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 100ms + LPT: 5ms +end note + +rectangle "BUF2\n\n10ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 10ms + LPT: 9ms +end note + +rectangle "BUF3\n\n15ms of data\n" as buf3 + +note bottom of buf3 + there was 11ms + DP2 produced 90ms + LL2 consumed 86ms + 11+90-86 = 15ms +end note + + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1_5.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1_5.pu new file mode 100644 index 00000000..098fb792 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example1_5.pu @@ -0,0 +1,41 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n105ms of data\n" as buf1 + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 100ms + LPT: 5ms +end note + +rectangle "BUF2\n\n0ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 10ms + LPT: 9ms +end note + +rectangle "BUF3\n\n20ms of data\n" as buf3 + +note bottom of buf3 + there was 15ms + DP2 produced 10ms + LL2 consumed 5ms + 15+10-5 = 20ms +end note + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2.pu new file mode 100644 index 00000000..7677f06d --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2.pu @@ -0,0 +1,34 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n5ms of data\n" as buf1 + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 5ms + LPT: 2ms +end note + +rectangle "BUF2\n\n15ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 20ms + LPT: 10ms +end note + +rectangle "BUF3\n\n18ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_1.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_1.pu new file mode 100644 index 00000000..83dfc838 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_1.pu @@ -0,0 +1,40 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n2ms of data\n" as buf1 +note bottom of buf1 + there was 5ms + LL1 produced 2ms + DP1 consumed 5ms + 5-5+2 = 2ms +end note + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 5ms + LPT: 2ms +end note + +rectangle "BUF2\n\n20ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 20ms + LPT: 10ms +end note + +rectangle "BUF3\n\n16ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_1a.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_1a.pu new file mode 100644 index 00000000..8e1c2874 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_1a.pu @@ -0,0 +1,34 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n5ms of data\n" as buf1 + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 5ms + LPT: 2ms +end note + +rectangle "BUF2\n\n20ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 20ms + LPT: 10ms +end note + +rectangle "BUF3\n\n13ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_2.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_2.pu new file mode 100644 index 00000000..0e7440cf --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_2.pu @@ -0,0 +1,34 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n12ms of data\n" as buf1 + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 5ms + LPT: 2ms +end note + +rectangle "BUF2\n\n0ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 20ms + LPT: 10ms +end note + +rectangle "BUF3\n\n26ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_2a.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_2a.pu new file mode 100644 index 00000000..20f6e42e --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_2a.pu @@ -0,0 +1,34 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n12ms of data\n" as buf1 + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 5ms + LPT: 2ms +end note + +rectangle "BUF2\n\n20ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 20ms + LPT: 10ms +end note + +rectangle "BUF3\n\n6ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_3.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_3.pu new file mode 100644 index 00000000..a976be4f --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_3.pu @@ -0,0 +1,40 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n9ms of data\n" as buf1 +note bottom of buf1 + there was 12ms + LL1 produced 2ms + DP1 consumed 5ms + 12+2-5 = 9ms +end note + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 5ms + LPT: 2ms +end note + +rectangle "BUF2\n\n5ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 20ms + LPT: 10ms +end note + +rectangle "BUF3\n\n24ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_4.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_4.pu new file mode 100644 index 00000000..4e06b3e5 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_4.pu @@ -0,0 +1,40 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n6ms of data\n" as buf1 +note bottom of buf1 + there was 9ms + LL1 produced 2ms + DP1 consumed 5ms + 9+2-5 = 6ms +end note + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 5ms + LPT: 2ms +end note + +rectangle "BUF2\n\n10ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 20ms + LPT: 10ms +end note + +rectangle "BUF3\n\n22ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_5.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_5.pu new file mode 100644 index 00000000..c1efc9c0 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_5.pu @@ -0,0 +1,40 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n3ms of data\n" as buf1 +note bottom of buf1 + there was 6ms + LL1 produced 2ms + DP1 consumed 5ms + 9+2-5 = 3ms +end note + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 5ms + LPT: 2ms +end note + +rectangle "BUF2\n\n15ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 20ms + LPT: 10ms +end note + +rectangle "BUF3\n\n20ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_6.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_6.pu new file mode 100644 index 00000000..7677f06d --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_6.pu @@ -0,0 +1,34 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n5ms of data\n" as buf1 + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 5ms + LPT: 2ms +end note + +rectangle "BUF2\n\n15ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 20ms + LPT: 10ms +end note + +rectangle "BUF3\n\n18ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_7.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_7.pu new file mode 100644 index 00000000..b2a6ca71 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example2_7.pu @@ -0,0 +1,39 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n2ms of data\n" as buf1 +note bottom of buf1 + there was 5ms + LL1 produced 2ms + DP1 consumed 5ms + 5+2-5 = 2ms +end note +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 5ms + LPT: 2ms +end note + +rectangle "BUF2\n\n20ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 20ms + LPT: 10ms +end note + +rectangle "BUF3\n\n16ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3.pu new file mode 100644 index 00000000..92dbf045 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3.pu @@ -0,0 +1,34 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n0ms of data\n" as buf1 + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 5ms + LPT: 2ms +end note + +rectangle "BUF2\n\n0ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 10ms + LPT: 6ms +end note + +rectangle "BUF3\n\n0ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_1.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_1.pu new file mode 100644 index 00000000..0c83890a --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_1.pu @@ -0,0 +1,34 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n5ms of data\n" as buf1 + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 5ms + LPT: 2ms +end note + +rectangle "BUF2\n\n0ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 10ms + LPT: 6ms +end note + +rectangle "BUF3\n\n0ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_2.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_2.pu new file mode 100644 index 00000000..c5e7faba --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_2.pu @@ -0,0 +1,34 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n2ms of data\n" as buf1 + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 5ms + LPT: 2ms +end note + +rectangle "BUF2\n\n5ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 10ms + LPT: 6ms +end note + +rectangle "BUF3\n\n0ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_3.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_3.pu new file mode 100644 index 00000000..64b7accb --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_3.pu @@ -0,0 +1,34 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n5ms of data\n" as buf1 + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 5ms + LPT: 2ms +end note + +rectangle "BUF2\n\n5ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 10ms + LPT: 6ms +end note + +rectangle "BUF3\n\n0ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_4.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_4.pu new file mode 100644 index 00000000..858ff446 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_4.pu @@ -0,0 +1,34 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n2ms of data\n" as buf1 + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 5ms + LPT: 2ms +end note + +rectangle "BUF2\n\n10ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 10ms + LPT: 6ms +end note + +rectangle "BUF3\n\n0ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_5.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_5.pu new file mode 100644 index 00000000..d9ccd7e6 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_5.pu @@ -0,0 +1,34 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n9ms of data\n" as buf1 + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 5ms + LPT: 2ms +end note + +rectangle "BUF2\n\n10ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 10ms + LPT: 6ms +end note + +rectangle "BUF3\n\n0ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_6.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_6.pu new file mode 100644 index 00000000..f43be350 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_6.pu @@ -0,0 +1,34 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n12ms of data\n" as buf1 + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 5ms + LPT: 2ms +end note + +rectangle "BUF2\n\n0ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 10ms + LPT: 6ms +end note + +rectangle "BUF3\n\n10ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_7.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_7.pu new file mode 100644 index 00000000..5591eaae --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example3_7.pu @@ -0,0 +1,40 @@ +@startuml +left to right direction +(LL1) as mod1 #f6ed80 + +rectangle "BUF1\n\n9ms of data\n" as buf1 +note bottom of buf1 + there was 12ms + LL1 procuded 2ms + DP1 consumed 5ms + 12 + 2 - 5 = 9ms +end note + +(DP1) as mod2 #ADD1B2 + +note bottom of mod2 + period 5ms + LPT: 2ms +end note + +rectangle "BUF2\n\n5ms of data\n" as buf2 + +(DP2) as mod3 #ADD1B2 + +note bottom of mod3 + period 10ms + LPT: 6ms +end note + +rectangle "BUF3\n\n8ms of data\n" as buf3 + +(LL2) as mod4 #f6ed80 + + +mod1--> buf1 +buf1 --> mod2 +mod2-->buf2 +buf2 --> mod3 +mod3-->buf3 +buf3 --> mod4 +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example4.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example4.pu new file mode 100644 index 00000000..dfb6cd24 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example4.pu @@ -0,0 +1,38 @@ +@startuml +left to right direction + +package pipeline2{ + (LL3) #f6ed80 + rectangle "BUF3\n\n0ms of data\n" as buf3 + (DP2) #ADD1B2 + note bottom of DP2 + period 5ms + LPT: 1ms + end note + rectangle "BUF4\n\n0ms of data\n" as buf4 + (LL4) #f6ed80 +} + +package pipeline1{ + (LL1) #f6ed80 + rectangle "BUF1\n\n10ms of data\n" as buf1 + (DP1) #ADD1B2 + note bottom of DP1 + period 10ms + LPT: 8ms + end note + rectangle "BUF2\n\n10ms of data\n" as buf2 + (LL2) #f6ed80 + } + +LL1 --> buf1 +buf1 --> DP1 +DP1 --> buf2 +buf2 --> LL2 + +LL3 --> buf3 +buf3 --> DP2 +DP2 --> buf4 +buf4 --> LL4 + +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example4_1.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example4_1.pu new file mode 100644 index 00000000..627e730b --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example4_1.pu @@ -0,0 +1,38 @@ +@startuml +left to right direction + +package pipeline2{ + (LL3) #f6ed80 + rectangle "BUF3\n\n5ms of data\n" as buf3 + (DP2) #ADD1B2 + note bottom of DP2 + period 5ms + LPT: 1ms + end note + rectangle "BUF4\n\n0ms of data\n" as buf4 + (LL4) #f6ed80 +} + +package pipeline1{ + (LL1) #f6ed80 + rectangle "BUF1\n\n15ms of data\n" as buf1 + (DP1) #ADD1B2 + note bottom of DP1 + period 10ms + LPT: 8ms + end note + rectangle "BUF2\n\n5ms of data\n" as buf2 + (LL2) #f6ed80 + } + +LL1 --> buf1 +buf1 --> DP1 +DP1 --> buf2 +buf2 --> LL2 + +LL3 --> buf3 +buf3 --> DP2 +DP2 --> buf4 +buf4 --> LL4 + +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example4_2.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example4_2.pu new file mode 100644 index 00000000..9e5a49b0 --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/example4_2.pu @@ -0,0 +1,38 @@ +@startuml +left to right direction + +package pipeline2{ + (LL3) #f6ed80 + rectangle "BUF3\n\n1ms of data\n" as buf3 + (DP2) #ADD1B2 + note bottom of DP2 + period 5ms + LPT: 1ms + end note + rectangle "BUF4\n\n5ms of data\n" as buf4 + (LL4) #f6ed80 +} + +package pipeline1{ + (LL1) #f6ed80 + rectangle "BUF1\n\n16ms of data\n" as buf1 + (DP1) #ADD1B2 + note bottom of DP1 + period 10ms + LPT: 8ms + end note + rectangle "BUF2\n\n4ms of data\n" as buf2 + (LL2) #f6ed80 + } + +LL1 --> buf1 +buf1 --> DP1 +DP1 --> buf2 +buf2 --> LL2 + +LL3 --> buf3 +buf3 --> DP2 +DP2 --> buf4 +buf4 --> LL4 + +@enduml \ No newline at end of file diff --git a/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/pic1_chains.pu b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/pic1_chains.pu new file mode 100644 index 00000000..0dc0256b --- /dev/null +++ b/architectures/firmware/sof-zephyr/mpp_layer/images/dp_scheduling/pic1_chains.pu @@ -0,0 +1,16 @@ +left to right direction +(LL1) as mod1 +(DP1) as mod2 #ADD1B2 +(DP2) as mod3 #ADD1B2 +(LL2) as mod4 +(DP3) as mod5 #7D3CFF +(DP4) as mod6 #7D3CFF +(LL3) as mod7 + + +mod1-->mod2 +mod2-->mod3 +mod3-->mod4 +mod4-->mod5 +mod5-->mod6 +mod6-->mod7 diff --git a/architectures/firmware/sof-zephyr/mpp_layer/index.rst b/architectures/firmware/sof-zephyr/mpp_layer/index.rst index 67629b39..b8542887 100644 --- a/architectures/firmware/sof-zephyr/mpp_layer/index.rst +++ b/architectures/firmware/sof-zephyr/mpp_layer/index.rst @@ -14,3 +14,4 @@ to the Application layer. mpp_scheduling async_messaging lib_manager + dp_scheduling \ No newline at end of file