-
Notifications
You must be signed in to change notification settings - Fork 349
[WIP] sof: ipc: switch platform IPC to Zephyr service #10422
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -12,8 +12,9 @@ | |||||||||||
| #include <autoconf.h> | ||||||||||||
|
|
||||||||||||
| #include <zephyr/kernel.h> | ||||||||||||
| #include <zephyr/ipc/ipc_service.h> | ||||||||||||
| #include <zephyr/ipc/backends/intel_adsp_host_ipc.h> | ||||||||||||
|
|
||||||||||||
| #include <intel_adsp_ipc.h> | ||||||||||||
| #include <sof/ipc/common.h> | ||||||||||||
|
|
||||||||||||
| #include <sof/ipc/schedule.h> | ||||||||||||
|
|
@@ -58,34 +59,39 @@ LOG_MODULE_DECLARE(ipc, CONFIG_SOF_LOG_LEVEL); | |||||||||||
| * When IPC message is read fills ipc_cmd_hdr. | ||||||||||||
| */ | ||||||||||||
| static uint32_t g_last_data, g_last_ext_data; | ||||||||||||
| static struct ipc_ept sof_ipc_ept; | ||||||||||||
| static struct ipc_ept_cfg sof_ipc_ept_cfg; | ||||||||||||
|
|
||||||||||||
| BUILD_ASSERT(sizeof(struct ipc_cmd_hdr) == sizeof(uint32_t) * 2, | ||||||||||||
| "ipc_cmd_hdr must be exactly two 32-bit words"); | ||||||||||||
|
|
||||||||||||
| /** | ||||||||||||
| * @brief cAVS IPC Message Handler Callback function. | ||||||||||||
| * @brief SOF IPC receive callback for Zephyr IPC service. | ||||||||||||
| * | ||||||||||||
| * See @ref (*intel_adsp_ipc_handler_t) for function signature description. | ||||||||||||
| * @return false so BUSY on the other side will not be cleared immediately but | ||||||||||||
| * will remain set until message would have been processed by scheduled task, i.e. | ||||||||||||
| * until ipc_platform_complete_cmd() call. | ||||||||||||
| * This callback is invoked by the Zephyr IPC service backend when a compact 2-word IPC message | ||||||||||||
| * arrives from the host. It stores the raw header words in g_last_data/g_last_ext_data and | ||||||||||||
| * schedules the SOF IPC task to process the command via ipc_platform_do_cmd(). | ||||||||||||
| */ | ||||||||||||
| static bool message_handler(const struct device *dev, void *arg, uint32_t data, uint32_t ext_data) | ||||||||||||
| static void sof_ipc_receive_cb(const void *data, size_t len, void *priv) | ||||||||||||
| { | ||||||||||||
| struct ipc *ipc = (struct ipc *)arg; | ||||||||||||
|
|
||||||||||||
| struct ipc *ipc = (struct ipc *)priv; | ||||||||||||
| const uint32_t *msg = data; | ||||||||||||
| k_spinlock_key_t key; | ||||||||||||
|
|
||||||||||||
| __ASSERT(len == sizeof(uint32_t) * 2, "Unexpected IPC message length: %zu", len); | ||||||||||||
| __ASSERT(data, "IPC data pointer is NULL"); | ||||||||||||
|
|
||||||||||||
| key = k_spin_lock(&ipc->lock); | ||||||||||||
|
|
||||||||||||
| g_last_data = data; | ||||||||||||
| g_last_ext_data = ext_data; | ||||||||||||
| g_last_data = msg[0]; | ||||||||||||
| g_last_ext_data = msg[1]; | ||||||||||||
|
|
||||||||||||
| #if CONFIG_DEBUG_IPC_COUNTERS | ||||||||||||
| increment_ipc_received_counter(); | ||||||||||||
| #endif | ||||||||||||
| ipc_schedule_process(ipc); | ||||||||||||
|
|
||||||||||||
| k_spin_unlock(&ipc->lock, key); | ||||||||||||
|
|
||||||||||||
| return false; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| #ifdef CONFIG_PM_DEVICE | ||||||||||||
|
|
@@ -159,9 +165,6 @@ static int ipc_device_resume_handler(const struct device *dev, void *arg) | |||||||||||
| ipc->task_mask = 0; | ||||||||||||
| ipc->pm_prepare_D3 = false; | ||||||||||||
|
|
||||||||||||
| /* attach handlers */ | ||||||||||||
| intel_adsp_ipc_set_message_handler(INTEL_ADSP_IPC_HOST_DEV, message_handler, ipc); | ||||||||||||
|
|
||||||||||||
| /* schedule task */ | ||||||||||||
| #if CONFIG_TWB_IPC_TASK | ||||||||||||
| scheduler_twb_task_init(&ipc->ipc_task, SOF_UUID(zipc_task_uuid), | ||||||||||||
|
|
@@ -254,7 +257,9 @@ enum task_state ipc_platform_do_cmd(struct ipc *ipc) | |||||||||||
| void ipc_platform_complete_cmd(struct ipc *ipc) | ||||||||||||
| { | ||||||||||||
| ARG_UNUSED(ipc); | ||||||||||||
| intel_adsp_ipc_complete(INTEL_ADSP_IPC_HOST_DEV); | ||||||||||||
| int ret = ipc_service_release_rx_buffer(&sof_ipc_ept, NULL); | ||||||||||||
|
|
||||||||||||
| __ASSERT(ret == 0, "ipc_service_release_rx_buffer() failed: %d", ret); | ||||||||||||
|
|
||||||||||||
| #if CONFIG_DEBUG_IPC_COUNTERS | ||||||||||||
| increment_ipc_processed_counter(); | ||||||||||||
|
|
@@ -263,30 +268,31 @@ void ipc_platform_complete_cmd(struct ipc *ipc) | |||||||||||
|
|
||||||||||||
| int ipc_platform_send_msg(const struct ipc_msg *msg) | ||||||||||||
| { | ||||||||||||
| if (!intel_adsp_ipc_is_complete(INTEL_ADSP_IPC_HOST_DEV)) | ||||||||||||
| if (ipc_service_get_tx_buffer_size(&sof_ipc_ept) == 0) | ||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you could also use !ipc_platform_poll_is_host_ready() |
||||||||||||
| return -EBUSY; | ||||||||||||
|
|
||||||||||||
| /* prepare the message and copy to mailbox */ | ||||||||||||
| struct ipc_cmd_hdr *hdr = ipc_prepare_to_send(msg); | ||||||||||||
|
|
||||||||||||
| return intel_adsp_ipc_send_message(INTEL_ADSP_IPC_HOST_DEV, hdr->pri, hdr->ext); | ||||||||||||
| return ipc_service_send(&sof_ipc_ept, hdr, sizeof(*hdr)); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| void ipc_platform_send_msg_direct(const struct ipc_msg *msg) | ||||||||||||
| { | ||||||||||||
| /* prepare the message and copy to mailbox */ | ||||||||||||
| struct ipc_cmd_hdr *hdr = ipc_prepare_to_send(msg); | ||||||||||||
|
|
||||||||||||
| intel_adsp_ipc_send_message_emergency(INTEL_ADSP_IPC_HOST_DEV, hdr->pri, hdr->ext); | ||||||||||||
| (void)ipc_service_send_critical(&sof_ipc_ept, hdr, sizeof(*hdr)); | ||||||||||||
|
||||||||||||
| (void)ipc_service_send_critical(&sof_ipc_ept, hdr, sizeof(*hdr)); | |
| int ret = ipc_service_send_critical(&sof_ipc_ept, hdr, sizeof(*hdr)); | |
| if (ret != 0) { | |
| tr_err(&ipc_tr, "ipc_service_send_critical() failed: %d", ret); | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should check/report this failure (since its likely time critical).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't we return bool here?
Copilot
AI
Dec 9, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code still references INTEL_ADSP_IPC_HOST_DEV macro directly. While migrating to the generic ipc_service API, this hardcoded Intel-specific device reference limits portability. Consider abstracting this behind a platform-agnostic macro or devicetree reference to fully achieve the stated goal of allowing other vendors to integrate their own IPC backends.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider warning instead of assert