@@ -49,6 +49,31 @@ DECLARE_TR_CTX(userspace_proxy_tr, SOF_UUID(userspace_proxy_uuid), LOG_LEVEL_INF
4949
5050static const struct module_interface userspace_proxy_interface ;
5151
52+ #if IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
53+ #include <sof/audio/module_adapter/iadk/system_agent.h>
54+ #include <sof/schedule/dp_schedule.h>
55+
56+ static inline int user_worker_get (void )
57+ {
58+ return 0 ;
59+ }
60+ static inline void user_worker_put (void ) { }
61+
62+ struct k_work_user * userspace_proxy_register_ipc_handler (struct processing_module * mod ,
63+ struct k_event * event )
64+ {
65+ struct userspace_context * const user_ctx = mod -> user_ctx ;
66+ if (user_ctx ) {
67+ user_ctx -> dp_event = event ;
68+ user_ctx -> work_item -> event = event ;
69+
70+ assert (user_ctx -> work_item );
71+ return & user_ctx -> work_item -> work_item ;
72+ }
73+
74+ return NULL ;
75+ }
76+ #else
5277/* IPC requests targeting userspace modules are handled through a user work queue.
5378 * Each userspace module provides its own work item that carries the IPC request parameters.
5479 * The worker thread is switched into the module's memory domain and receives the work item.
@@ -106,6 +131,7 @@ static void user_worker_put(void)
106131 user_stack_free (worker .stack_ptr );
107132 }
108133}
134+ #endif
109135
110136static int user_work_item_init (struct userspace_context * user_ctx , struct k_heap * user_heap )
111137{
@@ -128,7 +154,9 @@ static int user_work_item_init(struct userspace_context *user_ctx, struct k_heap
128154
129155 k_work_user_init (& work_item -> work_item , userspace_proxy_worker_handler );
130156
157+ #if !IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
131158 work_item -> event = & worker .event ;
159+ #endif
132160 work_item -> params .context = user_ctx ;
133161 user_ctx -> work_item = work_item ;
134162
@@ -155,14 +183,19 @@ BUILD_ASSERT(IS_ALIGNED(MAILBOX_HOSTBOX_SIZE, CONFIG_MMU_PAGE_SIZE),
155183static int userspace_proxy_invoke (struct userspace_context * user_ctx , uint32_t cmd ,
156184 bool ipc_payload_access )
157185{
186+ #if IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
187+ struct k_event * const event = user_ctx -> dp_event ;
188+ #else
189+ struct k_event * const event = & worker .event ;
190+ #endif
158191 struct module_params * params = user_work_get_params (user_ctx );
159192 const uintptr_t ipc_req_buf = (uintptr_t )MAILBOX_HOSTBOX_BASE ;
160193 struct k_mem_partition ipc_part = {
161194 .start = ipc_req_buf ,
162195 .size = MAILBOX_HOSTBOX_SIZE ,
163196 .attr = user_get_partition_attr (ipc_req_buf ) | K_MEM_PARTITION_P_RO_U_RO ,
164197 };
165- int ret , ret2 ;
198+ int ret = 0 , ret2 ;
166199
167200 params -> cmd = cmd ;
168201
@@ -174,6 +207,7 @@ static int userspace_proxy_invoke(struct userspace_context *user_ctx, uint32_t c
174207 }
175208 }
176209
210+ #if !IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
177211 /* Switch worker thread to module memory domain */
178212 ret = k_mem_domain_add_thread (user_ctx -> comp_dom , worker .thread_id );
179213 if (ret < 0 ) {
@@ -193,9 +227,13 @@ static int userspace_proxy_invoke(struct userspace_context *user_ctx, uint32_t c
193227 tr_err (& userspace_proxy_tr , "Submit to queue error: %d" , ret );
194228 goto done ;
195229 }
230+ #else
231+ assert (event );
232+ k_event_post (event , DP_TASK_EVENT_IPC );
233+ #endif
196234
197235 /* Timeout value is aligned with the ipc_wait_for_compound_msg function */
198- if (!k_event_wait_safe (& worker . event , DP_TASK_EVENT_IPC_DONE , false,
236+ if (!k_event_wait_safe (event , DP_TASK_EVENT_IPC_DONE , false,
199237 Z_TIMEOUT_US (250 * 20 ))) {
200238 tr_err (& userspace_proxy_tr , "IPC processing timedout." );
201239 ret = - ETIMEDOUT ;
@@ -313,18 +351,27 @@ static int userspace_proxy_start_agent(struct userspace_context *user_ctx,
313351{
314352 const byte_array_t * const mod_cfg = (byte_array_t * )agent_params -> mod_cfg ;
315353 struct module_params * params = user_work_get_params (user_ctx );
316- int ret ;
317354
318355 params -> ext .agent .start_fn = start_fn ;
319- params -> ext .agent .params = * agent_params ;
320- params -> ext .agent .mod_cfg = * mod_cfg ;
321356
322- ret = userspace_proxy_invoke (user_ctx , USER_PROXY_MOD_CMD_AGENT_START , true);
323- if (ret )
324- return ret ;
357+ /* Start the system agent, if provided. */
358+ if (start_fn ) {
359+ params -> ext .agent .params = * agent_params ;
360+ params -> ext .agent .mod_cfg = * mod_cfg ;
325361
326- * agent_interface = params -> ext .agent .out_interface ;
327- return params -> status ;
362+ /* In case of processing modules ipc in the DP thread, the agent will be started in the
363+ * init function. At this point the DP thread does not exist yet.
364+ */
365+ #if !IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
366+ int ret = userspace_proxy_invoke (user_ctx , USER_PROXY_MOD_CMD_AGENT_START , true);
367+ if (ret )
368+ return ret ;
369+
370+ * agent_interface = params -> ext .agent .out_interface ;
371+ return params -> status ;
372+ #endif
373+ }
374+ return 0 ;
328375}
329376
330377int userspace_proxy_create (struct userspace_context * * user_ctx , const struct comp_driver * drv ,
@@ -362,14 +409,10 @@ int userspace_proxy_create(struct userspace_context **user_ctx, const struct com
362409 if (ret )
363410 goto error_dom ;
364411
365- /* Start the system agent, if provided. */
366-
367- if (start_fn ) {
368- ret = userspace_proxy_start_agent (context , start_fn , agent_params , agent_interface );
369- if (ret ) {
370- tr_err (& userspace_proxy_tr , "System agent failed with error %d." , ret );
371- goto error_work_item ;
372- }
412+ ret = userspace_proxy_start_agent (context , start_fn , agent_params , agent_interface );
413+ if (ret ) {
414+ tr_err (& userspace_proxy_tr , "System agent failed with error %d." , ret );
415+ goto error_work_item ;
373416 }
374417
375418 * user_ctx = context ;
@@ -420,6 +463,22 @@ static int userspace_proxy_init(struct processing_module *mod)
420463
421464 comp_dbg (mod -> dev , "start" );
422465
466+ #if IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
467+ /* Start the system agent, if provided. Params is already filled by
468+ * the userspace_proxy_start_agent function.
469+ */
470+ if (params -> ext .agent .start_fn ) {
471+ ret = userspace_proxy_invoke (mod -> user_ctx , USER_PROXY_MOD_CMD_AGENT_START , true);
472+ if (ret )
473+ return ret ;
474+
475+ if (params -> ext .agent .start_fn == system_agent_start )
476+ module_set_private_data (mod , params -> ext .agent .out_interface );
477+ else
478+ mod -> user_ctx -> interface = params -> ext .agent .out_interface ;
479+ }
480+ #endif
481+
423482 params -> mod = mod ;
424483 ret = userspace_proxy_invoke (mod -> user_ctx , USER_PROXY_MOD_CMD_INIT , true);
425484 if (ret )
0 commit comments