Skip to content

Conversation

@lgirdwood
Copy link
Member

About

IPC2 is a MAJOR ABI update that is not fully backwards compatible with
IPC1.x (using MAJOR 3 today).

IPC2 has the following high level aims

  1. Straight forward message life cycle management. Add/deprecate/modify
    messages with minimal pain across all messengers.

  2. Provide a transition path for code that uses existing or legacy IPC
    ABI's so that it can incrementally add IPC2.x features and support.

  3. Provide high density messaging similar to vanilla C structs.

  4. Message discovery - clients can determine supported message types
    and fields at runtime.

  5. Standard metadata for all messages with optional extra metadata.

Message Header

IPC2 messages will all use a standard header that contains generic
message metadata with optional mesage metedata. This will be used
by messengers to help process the message efficiently and securely.

Messages are now catergorized into class, subclass and action in order
to cleanly integrate into the correct driver, feature and use case
infrastrcture within FW and SW.

See header.h

Messaging Enumeration

The FW extended manifest data will contain a list of supported messages
classes, subclasses and actions for this individual FW release. This
allows SW to scan the manifest and determine which driver, feature and
use cases are supported. The SW can then make decisions at runtime to
correctly support this individual FW release.

See manifest.h

Message Data Format

Each piece of data sent in a message must be tagged with an ID that the
messengers all understand. This {id, data} tuple is the basis for all IPC2
communication as it's generic and has relatively simple life cycle
requirements. i.e. tuples can be easily added, removed without breaking
breaking binary ABIs or requiring all code to be rebuilt.

IPC2 also provides a pathway for migrating legacy code to IPC2. i.e. IPC2
allows existing data messages to be sent using IPC2 with the small
addition of a 1 word header that can be initially ignored by older
messengers.

See message.h

Signed-off-by: Liam Girdwood [email protected]

About
----

IPC2 is a MAJOR ABI update that is not fully backwards compatible with
IPC1.x (using MAJOR 3 today).

IPC2 has the following high level aims

 1) Straight forward message life cycle management. Add/deprecate/modify
    messages with minimal pain across all messengers.

 2) Provide a transition path for code that uses existing or legacy IPC
    ABI's so that it can incrementally add IPC2.x features and support.

 3) Provide high density messaging similar to vanilla C structs.

 4) Message discovery - clients can determine supported message types
    and fields at runtime.

 5) Standard metadata for all messages with optional extra metadata.

Message Header
--------------

IPC2 messages will all use a standard header that contains generic
message metadata with optional mesage metedata. This will be used
by messengers to help process the message efficiently and securely.

Messages are now catergorized into class, subclass and action in order
to cleanly integrate into the correct driver, feature and use case
infrastrcture within FW and SW.

See header.h

Messaging Enumeration
---------------------

The FW extended manifest data will contain a list of supported messages
classes, subclasses and actions for this individual FW release. This
allows SW to scan the manifest and determine which driver, feature and
use cases are supported. The SW can then make decisions at runtime to
correctly support this individual FW release.

See manifest.h

Message Data Format
-------------------

Each piece of data sent in a message must be tagged with an ID that the
messengers all understand. This {id, data} tuple is the basis for all IPC2
communication as it's generic and has relatively simple life cycle
requirements. i.e. tuples can be easily added, removed without breaking
breaking binary ABIs or requiring all code to be rebuilt.

IPC2 also provides a pathway for migrating legacy code to IPC2. i.e. IPC2
allows existing data messages to be sent using IPC2 with the small
addition of a 1 word header that can be initially ignored by older
messengers.

See message.h

Signed-off-by: Liam Girdwood <[email protected]>
@lgirdwood lgirdwood added the ABI ABI change involved label Jul 20, 2020
Copy link
Contributor

@cujomalainey cujomalainey left a comment

Choose a reason for hiding this comment

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

What implications will this have for backporting?

uint32_t route : 1; /**< routing data follows */
uint32_t size : 1; /**< size follows */
uint32_t elems : 1; /**< data elems follows */
uint32_t block : 1; /**< data block follows */
Copy link
Contributor

Choose a reason for hiding this comment

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

is this mutually exclusive to any other values?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes - I did think about use cases where you could have a legacy C struct and some new tuples but that added a bit more complexity. It would be better in this situation (where legacy C structures have to be extended fro new features) to just change to the IPC2 struct for the new feature.
"ack" and "nak" are also mutually exclusive - I will mark these up in the comments.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm just wondering if maybe we should make those mutually exclusive field n bit enum fields for safety

uint32_t num_actions; /**< number of actions in this subclass */

/* action data follows here */
struct sof_ipc2_action actions[0]; /**< actions - size is num_actions */
Copy link
Contributor

Choose a reason for hiding this comment

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

why not define this as flexible array? Or does that break packing?

Copy link
Member Author

Choose a reason for hiding this comment

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

I have not yet checked the packing, only just compiled the headers - this could be a flex array.

* to perform this action. Tuples are uint16_t. Structure is aligned on
* word.
*/
struct sof_ipc2_action {
Copy link
Contributor

Choose a reason for hiding this comment

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

are there going to be helpers to help traverse these items? it seems you need to go all the way to the bottom to get the next top level element.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point - we can currently get to next class, subclass and action by adding "size" to the current ptr. The use case would be the :

  1. common high level code would read each class ID only and send the class data to each driver - e.g. audio class to audio driver, sensing class to sensor driver.
  2. feature driver (like audio) would then read each subclass ID and forward each subclass to the correct feature logic to parse the actions i.e. PCM subclass to pcm code, control subclass to kcontrol code.
  3. use case file (like pcm.c) parses each action

@lgirdwood
Copy link
Member Author

What implications will this have for backporting?

The MAJOR ABI update is really just the mandatory prefixing of this 1 word struct on all messages.

struct sof_ipc2_hdr {
	uint32_t klass : 8;		/**< class ID */
	uint32_t subklass : 8;		/**< subclass ID */
	uint32_t action : 8;		/**< action ID */
	uint32_t ack : 1;		/**< message is a reply - success */
	uint32_t nack : 1;		/**< message is a reply - fail */
	uint32_t priority : 1;		/**< 0 normal, 1 high */
	uint32_t datagram : 1;		/**< is datagram - no reply needed */
	uint32_t route : 1;		/**< routing data follows */
	uint32_t size : 1;		/**< size follows */
	uint32_t elems : 1;		/**< data elems follows */
	uint32_t block : 1;		/**< data block follows */
} __attribute__((packed));

The driver will support both IPC MAJOR ABI versions and would detect correct version from FW manifest. i.e. old FW binaries will be able to use new kernels (using MAJOR 3)

FW will only use one IPC MAJOR ABI at runtime. If IPC2 needs back ported to older FW releases (say to back port a new feature to an old FW release) , my intention is to make it as simple as possible i.e.

diff --git a/src/include/ipc/header.h b/src/include/ipc/header.h
index 436b150a..153bc379 100644
--- a/src/include/ipc/header.h
+++ b/src/include/ipc/header.h
@@ -207,6 +207,7 @@ struct sof_ipc_hdr {
  * arrays.
  */
 struct sof_ipc_cmd_hdr {
+ #if CONFIG_IPC2
+       struct sof_ipc2_hdr ipc2;       /**< Ignored by FW, set to const value for driver */
+ #endif
        uint32_t size;                  /**< size of structure */
        uint32_t cmd;                   /**< SOF_IPC_GLB_ + cmd */
 } __attribute__((packed));
diff --git a/src/include/ipc2/manifest.h b/src/include/ipc2/manifest.h

FW would ignore the new IPC2 header for all features except the new back ported feature. The driver would know it would have a mixed IPC based on the FW manifest data (generated by rimage - new version would need to be used here too).

  1. Driver reads manifest and see it uses ABI MAJOR 4 (aka IPC2)
  2. Driver parses classes and see SOF_IPC_CLASS_PDATA_SOF1 and new feature class.
  3. New feature is handled via IPC2 driver code. All other features use IPC1 driver code with header removed/added at common messaging layer when SOF_IPC_CLASS_PDATA_SOF1 is true.

@lgirdwood lgirdwood closed this Mar 28, 2021
@lgirdwood lgirdwood deleted the branch master March 28, 2021 13:44
@paulstelian97
Copy link
Collaborator

I assume this one needs to be reopened.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ABI ABI change involved

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants