@@ -49,6 +49,36 @@ 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+
61+ static inline void user_worker_put (void ) { }
62+
63+ struct k_work_user * userspace_proxy_register_ipc_handler (struct processing_module * mod ,
64+ struct k_event * event )
65+ {
66+ struct userspace_context * const user_ctx = mod -> user_ctx ;
67+
68+ if (user_ctx ) {
69+ tr_dbg (& userspace_proxy_tr , "Set DP event %p for module %p" ,
70+ (void * )event , (void * )mod );
71+ assert (user_ctx -> work_item );
72+
73+ user_ctx -> dp_event = event ;
74+ user_ctx -> work_item -> event = event ;
75+
76+ return & user_ctx -> work_item -> work_item ;
77+ }
78+
79+ return NULL ;
80+ }
81+ #else
5282/* IPC requests targeting userspace modules are handled through a user work queue.
5383 * Each userspace module provides its own work item that carries the IPC request parameters.
5484 * The worker thread is switched into the module's memory domain and receives the work item.
@@ -106,6 +136,7 @@ static void user_worker_put(void)
106136 user_stack_free (worker .stack_ptr );
107137 }
108138}
139+ #endif
109140
110141static int user_work_item_init (struct userspace_context * user_ctx , struct k_heap * user_heap )
111142{
@@ -128,7 +159,9 @@ static int user_work_item_init(struct userspace_context *user_ctx, struct k_heap
128159
129160 k_work_user_init (& work_item -> work_item , userspace_proxy_worker_handler );
130161
162+ #if !IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
131163 work_item -> event = & worker .event ;
164+ #endif
132165 work_item -> params .context = user_ctx ;
133166 user_ctx -> work_item = work_item ;
134167
@@ -155,14 +188,19 @@ BUILD_ASSERT(IS_ALIGNED(MAILBOX_HOSTBOX_SIZE, CONFIG_MMU_PAGE_SIZE),
155188static int userspace_proxy_invoke (struct userspace_context * user_ctx , uint32_t cmd ,
156189 bool ipc_payload_access )
157190{
191+ #if IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
192+ struct k_event * const event = user_ctx -> dp_event ;
193+ #else
194+ struct k_event * const event = & worker .event ;
195+ #endif
158196 struct module_params * params = user_work_get_params (user_ctx );
159197 const uintptr_t ipc_req_buf = (uintptr_t )MAILBOX_HOSTBOX_BASE ;
160198 struct k_mem_partition ipc_part = {
161199 .start = ipc_req_buf ,
162200 .size = MAILBOX_HOSTBOX_SIZE ,
163201 .attr = user_get_partition_attr (ipc_req_buf ) | K_MEM_PARTITION_P_RO_U_RO ,
164202 };
165- int ret , ret2 ;
203+ int ret = 0 , ret2 ;
166204
167205 params -> cmd = cmd ;
168206
@@ -174,6 +212,7 @@ static int userspace_proxy_invoke(struct userspace_context *user_ctx, uint32_t c
174212 }
175213 }
176214
215+ #if !IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
177216 /* Switch worker thread to module memory domain */
178217 ret = k_mem_domain_add_thread (user_ctx -> comp_dom , worker .thread_id );
179218 if (ret < 0 ) {
@@ -193,9 +232,13 @@ static int userspace_proxy_invoke(struct userspace_context *user_ctx, uint32_t c
193232 tr_err (& userspace_proxy_tr , "Submit to queue error: %d" , ret );
194233 goto done ;
195234 }
235+ #else
236+ assert (event );
237+ k_event_post (event , DP_TASK_EVENT_IPC );
238+ #endif
196239
197240 /* 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,
241+ if (!k_event_wait_safe (event , DP_TASK_EVENT_IPC_DONE , false,
199242 Z_TIMEOUT_US (250 * 20 ))) {
200243 tr_err (& userspace_proxy_tr , "IPC processing timedout." );
201244 ret = - ETIMEDOUT ;
@@ -313,18 +356,29 @@ static int userspace_proxy_start_agent(struct userspace_context *user_ctx,
313356{
314357 const byte_array_t * const mod_cfg = (byte_array_t * )agent_params -> mod_cfg ;
315358 struct module_params * params = user_work_get_params (user_ctx );
316- int ret ;
317359
318360 params -> ext .agent .start_fn = start_fn ;
319- params -> ext .agent .params = * agent_params ;
320- params -> ext .agent .mod_cfg = * mod_cfg ;
321361
322- ret = userspace_proxy_invoke (user_ctx , USER_PROXY_MOD_CMD_AGENT_START , true);
323- if (ret )
324- return ret ;
362+ /* Start the system agent, if provided. */
363+ if (start_fn ) {
364+ params -> ext .agent .params = * agent_params ;
365+ params -> ext .agent .params .mod_cfg = & params -> ext .agent .mod_cfg ;
366+ params -> ext .agent .mod_cfg = * mod_cfg ;
325367
326- * agent_interface = params -> ext .agent .out_interface ;
327- return params -> status ;
368+ /* In case of processing modules ipc in the DP thread, the agent will be started in
369+ * the init function. At this point the DP thread does not exist yet.
370+ */
371+ #if !IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
372+ int ret = userspace_proxy_invoke (user_ctx , USER_PROXY_MOD_CMD_AGENT_START , true);
373+
374+ if (ret )
375+ return ret ;
376+
377+ * agent_interface = params -> ext .agent .out_interface ;
378+ return params -> status ;
379+ #endif
380+ }
381+ return 0 ;
328382}
329383
330384int userspace_proxy_create (struct userspace_context * * user_ctx , const struct comp_driver * drv ,
@@ -342,6 +396,8 @@ int userspace_proxy_create(struct userspace_context **user_ctx, const struct com
342396 if (!context )
343397 return - ENOMEM ;
344398
399+ context -> dp_event = NULL ;
400+
345401 /* Allocate memory domain struct */
346402 domain = rzalloc (SOF_MEM_FLAG_KERNEL , sizeof (* domain ));
347403 if (!domain ) {
@@ -362,14 +418,10 @@ int userspace_proxy_create(struct userspace_context **user_ctx, const struct com
362418 if (ret )
363419 goto error_dom ;
364420
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- }
421+ ret = userspace_proxy_start_agent (context , start_fn , agent_params , agent_interface );
422+ if (ret ) {
423+ tr_err (& userspace_proxy_tr , "System agent failed with error %d." , ret );
424+ goto error_work_item ;
373425 }
374426
375427 * user_ctx = context ;
@@ -420,6 +472,22 @@ static int userspace_proxy_init(struct processing_module *mod)
420472
421473 comp_dbg (mod -> dev , "start" );
422474
475+ #if IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
476+ /* Start the system agent, if provided. Params is already filled by
477+ * the userspace_proxy_start_agent function.
478+ */
479+ if (params -> ext .agent .start_fn ) {
480+ ret = userspace_proxy_invoke (mod -> user_ctx , USER_PROXY_MOD_CMD_AGENT_START , true);
481+ if (ret )
482+ return ret ;
483+
484+ if (params -> ext .agent .start_fn == system_agent_start )
485+ module_set_private_data (mod , (void * )params -> ext .agent .out_interface );
486+ else
487+ mod -> user_ctx -> interface = params -> ext .agent .out_interface ;
488+ }
489+ #endif
490+
423491 params -> mod = mod ;
424492 ret = userspace_proxy_invoke (mod -> user_ctx , USER_PROXY_MOD_CMD_INIT , true);
425493 if (ret )
0 commit comments