diff --git a/src/ipc/ipc-zephyr.c b/src/ipc/ipc-zephyr.c index 460089414cf7..52f0494273ba 100644 --- a/src/ipc/ipc-zephyr.c +++ b/src/ipc/ipc-zephyr.c @@ -12,8 +12,9 @@ #include #include +#include +#include -#include #include #include @@ -58,25 +59,32 @@ 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(); @@ -84,8 +92,6 @@ static bool message_handler(const struct device *dev, void *arg, uint32_t data, 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) 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)); } int ipc_platform_poll_is_host_ready(void) { - return intel_adsp_ipc_is_complete(INTEL_ADSP_IPC_HOST_DEV); + return ipc_service_get_tx_buffer_size(&sof_ipc_ept) > 0; } int platform_ipc_init(struct ipc *ipc) { + int ret; + ipc_set_drvdata(ipc, NULL); /* schedule task */ @@ -300,8 +306,15 @@ int platform_ipc_init(struct ipc *ipc) #endif /* configure interrupt - work is done internally by Zephyr API */ - /* attach handlers */ - intel_adsp_ipc_set_message_handler(INTEL_ADSP_IPC_HOST_DEV, message_handler, ipc); + sof_ipc_ept_cfg.name = "sof_ipc"; + sof_ipc_ept_cfg.prio = 0; + sof_ipc_ept_cfg.cb.received = sof_ipc_receive_cb; + sof_ipc_ept_cfg.priv = ipc; + + ret = ipc_service_register_endpoint(INTEL_ADSP_IPC_HOST_DEV, + &sof_ipc_ept, &sof_ipc_ept_cfg); + if (ret < 0) + return ret; #ifdef CONFIG_PM intel_adsp_ipc_set_suspend_handler(INTEL_ADSP_IPC_HOST_DEV, ipc_device_suspend_handler, ipc); diff --git a/west.yml b/west.yml index 0bd10446385e..0111d2accd7e 100644 --- a/west.yml +++ b/west.yml @@ -43,7 +43,7 @@ manifest: - name: zephyr repo-path: zephyr - revision: 769ba82aa5ec482af0c4649ba075065e901fbe69 + revision: pull/100682/head remote: zephyrproject # Import some projects listed in zephyr/west.yml@revision