Repository navigation
ASoC: SOF: IPC4 message abstraction and API change - #3334
Conversation
| * The msg_total_size should be passed as msg_bytes for function expecting | ||
| * a message size and underlaying code should take this into account. | ||
| */ | ||
| sdev->ipc->max_payload_size += sizeof(struct sof_ipc4_msg); |
There was a problem hiding this comment.
I have missed the setup of the reply placeholder, this should be added after line 227:
ipc4_msg = msg->reply_data;
ipc4_msg->data_ptr = msg->reply_data + sizeof(struct sof_ipc4_msg);So that the data_ptr points to the memory right after the header.
Or I could have two separate allocations for the message struct then the data section?
| * The msg_total_size should be passed as msg_bytes for function expecting | ||
| * a message size and underlaying code should take this into account. | ||
| */ | ||
| sdev->ipc->max_payload_size += sizeof(struct sof_ipc4_msg); |
There was a problem hiding this comment.
I dont understand this @ujfalusi . The max payload for me refers to the MAX size of the mailbox. Why would we include the header and extension in it?
There was a problem hiding this comment.
This was exactly my concern.
I guess I can modify things that the msg_bytes is the optional data size which goes via the mailbox, but then the msg_bytes is kind of half backed as we still have the u64 header, which is a message by itself in some cases.
dc6464d to
251f692
Compare
|
Changes since v1:
|
251f692 to
f03d30a
Compare
|
Changes since v2:
|
| static int ipc4_tx_wait_done(struct snd_sof_ipc *ipc, struct snd_sof_ipc_msg *msg, | ||
| void *reply_data) | ||
| { | ||
| struct sof_ipc4_msg *ipc4_msg = msg->reply_data; |
There was a problem hiding this comment.
@ujfalusi I'm not able to appreciate why we need to do this. Maybe I'm missing the point. There's struct sof_ipc_msg that we use to pass the IPC message to be sent. What is the purpose of the sof_ipc4_msg? we dont have a sof_ipc3_msg similar to sof_ipc4_msg isnt it? So why is ipc4 special?
There was a problem hiding this comment.
@ranj063, all ipc3 messages start with struct sof_ipc_cmd_hdr followed by the payload, if any. When we receive the reply or notification then the header is behind of the msg->reply_data.
In IPC3 we pass the whole message, including the header via mailbox.
IPC4 on the other hand is a 'split' protocol in this sense. The header is not passed via the mailbox, it is written to registers and the mailbox is only used in case there is additional data for the message.
We could do an asymmetric handling of IPC4, but I don't think it helps the reader by using the struct sof_ipc4_msg for TX and spreading out the reply, notification into struct sof_ipc_msg
Users of the IPC interface should not be using the struct sof_ipc_msg as it is internal to the IPC 'subsystem' of SOF, we should have a simple interface of "send this message and give me the reply here" and on the notification side it should be that, "here, we have received this message".
Ideally only the low level and high level should know how to deal with the pointer, in the middle layer we just pass things.
I consider the ipc4_tx_wait_done() here a low(ish) level functionality as it does error checking, but it should be possible to abstract it away to only wait w/o knowing anything about the content.
There was a problem hiding this comment.
Oh, I see now.
The RX for notification is handled completely differently than the reply in IPC3. The reply is copied to reply_data while the notification is not, the IPC3 RX function itself reads the message from the mailbox (first the header only, then the whole message when it knows the size).
Hrm, It might be better to rename the reply_data and reply_size to rx_data and rx_size and use it for both reply and notifications/events.
We are serializing things, so while a reply is handled it is guarantied that a notification will not change the rx_data.
That would make it a bit more well defined and we would save on kmalloc() for notifications as a bonus?
f03d30a to
ddf78b3
Compare
|
Changes since v3:
|
ddf78b3 to
81316e8
Compare
|
Changes since v4:
|
81316e8 to
206f032
Compare
|
Changes since v5:
|
The message and reply size can be checked earlier to fail early in case the requested size can not be sent due to it's length. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
The sof_ipc4_tx_message (and _unlocked) does not have support for async operations. There is no need to allocate a buffer and copy each message to it to be sent to the DSP, we can use the passed message data pointer directly. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
The struct sof_ipc4_msg encapsulates an IPC4 message for easier handling. In IPC4 the header (u64) is treated differently compared to IPC3. IPC4 gives the option that the header can bypass the mailbox memory where only the optional data part of the message is sent. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
IPC4 related code must use the struct sof_ipc4_msg to pass the message to be sent to the firmware. Similarly on message reception, the platform code must make sure that the ipc4 message container is updated before calling the handler. For message sending the msg_data is mandatory and must point to the ipc4 message container while the msg_bytes is the size of the optional data part of the message (data_bytes == ipc4_msg->data_size). On message reception, platform code is responsible to update the ipc4 struct's header (primary and extension) before calling the handler. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
The header parameter is not used anymore and now it can be dropped from the parameter list of tx_message(). Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Neither the header or the extension is used by the underlying code, they can be dropped from the snd_sof_ipc_msg struct. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
7326973
206f032 to
7326973
Compare
| /* check for FW boot completion */ | ||
| if (sdev->fw_state == SOF_FW_BOOT_IN_PROGRESS) { | ||
| err = sof_ops(sdev)->fw_ready(sdev, msg); | ||
| err = sof_ops(sdev)->fw_ready(sdev, ipc4_msg->primary); |
There was a problem hiding this comment.
Can you help to add debug log for default case to notify unsupported reply ? thanks!
There was a problem hiding this comment.
Right, should I add a new patch on top or a new PR? We can only print the primary and extension for now, but we should have similar logging as with IPC3.
There was a problem hiding this comment.
@RanderWang, something like this?
ujfalusi@41ebbc9
There was a problem hiding this comment.
you can create a new PR if you like
Hi,
Create a container struct to encompass the IPC4 message (the header and the optional data part) so that we can simplify the API and make it possible later on to have generic ops among different IPC versions.
Note: I'm not sure about the new msg_bytes/reply_bytes definition for IPC4, I felt that passing 0 as msg_bytes when there is a message (there must be always) but we don't have the optional data, strange, but it can be justified, if it is preferred.