diff --git a/src/ipc/ipc-common.c b/src/ipc/ipc-common.c index d05895a3f13a..831ba9e8d47d 100644 --- a/src/ipc/ipc-common.c +++ b/src/ipc/ipc-common.c @@ -437,15 +437,6 @@ int ipc_user_forward_cmd(uint32_t primary, uint32_t extension, unsigned int core pdata->ipc_msg_ext = extension; pdata->ipc = ipc; - /* - * Forwarding the first IPC to this core, wait for its userspace IPC - * thread to start - */ - if (pdata->init_needed[core]) { - pdata->init_needed[core] = false; - k_sem_take(pdata->sem, K_FOREVER); - } - /* Prevent host completion until user thread finishes */ key = k_spin_lock(&ipc->lock); ipc->task_mask |= IPC_TASK_IN_THREAD; @@ -598,9 +589,6 @@ __cold int ipc_user_init_secondary(unsigned int core) } k_thread_access_grant(ipc_user->thread[core], ipc_user->audio_thread[core]); - ipc_user->init_needed[core] = true; - - /* Wait for user thread startup — consumes the initial k_sem_give from thread */ return 0; } @@ -619,7 +607,7 @@ __cold static void ipc_user_init(void) struct ipc_user *ipc_user = sof_heap_alloc(sof_sys_user_heap_get(), SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, sizeof(*ipc_user), 0); - int ret; + int ret, core; if (!ipc_user) { LOG_ERR("user IPC pdata alloc failed"); @@ -628,6 +616,11 @@ __cold static void ipc_user_init(void) assert_can_be_cold(); + for (core = 0; core < CONFIG_CORE_COUNT; core++) { + if (core != PLATFORM_PRIMARY_CORE_ID) + ipc_user->init_needed[core] = true; + } + ipc_user->sem = k_object_alloc(K_OBJ_SEM); if (!ipc_user->sem) { LOG_ERR("user IPC sem alloc failed"); diff --git a/src/ipc/ipc4/handler-kernel.c b/src/ipc/ipc4/handler-kernel.c index 03c2e6c81e86..041b0fba14f2 100644 --- a/src/ipc/ipc4/handler-kernel.c +++ b/src/ipc/ipc4/handler-kernel.c @@ -328,6 +328,23 @@ __cold static int ipc4_module_process_d0ix(struct ipc4_message_request *ipc4) return 0; } +/* block until core has powered-up (in user-ll builds) */ +__cold static void ipc_sec_core_sync_boot(uint32_t core_id) +{ +#ifdef CONFIG_SOF_USERSPACE_LL + struct ipc *ipc = ipc_get(); + struct ipc_user *ipc_user = ipc->ipc_user_pdata; + + assert(core_id != PLATFORM_PRIMARY_CORE_ID); + + if (ipc_user->init_needed[core_id]) { + /* wait for IPC thread (ipc_user_thread_fn()) */ + k_sem_take(ipc_user->sem, K_FOREVER); + ipc_user->init_needed[core_id] = false; + } +#endif +} + /* enable/disable cores according to the state mask */ __cold static int ipc4_module_process_dx(struct ipc4_message_request *ipc4) { @@ -385,6 +402,7 @@ __cold static int ipc4_module_process_dx(struct ipc4_message_request *ipc4) ipc_cmd_err(&ipc_tr, "failed to enable core %d", core_id); return IPC4_FAILURE; } + ipc_sec_core_sync_boot(core_id); } else { cpu_disable_core(core_id); if (cpu_is_core_enabled(core_id)) {