@@ -49,6 +49,35 @@ 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+
67+ if (user_ctx ) {
68+ tr_dbg (& userspace_proxy_tr , "Set DP event %p for module %p" ,
69+ (void * )event , (void * )mod );
70+ assert (user_ctx -> work_item );
71+
72+ user_ctx -> dp_event = event ;
73+ user_ctx -> work_item -> event = event ;
74+
75+ return & user_ctx -> work_item -> work_item ;
76+ }
77+
78+ return NULL ;
79+ }
80+ #else
5281/* IPC requests targeting userspace modules are handled through a user work queue.
5382 * Each userspace module provides its own work item that carries the IPC request parameters.
5483 * The worker thread is switched into the module's memory domain and receives the work item.
@@ -106,6 +135,7 @@ static void user_worker_put(void)
106135 user_stack_free (worker .stack_ptr );
107136 }
108137}
138+ #endif
109139
110140static int user_work_item_init (struct userspace_context * user_ctx , struct k_heap * user_heap )
111141{
@@ -128,7 +158,9 @@ static int user_work_item_init(struct userspace_context *user_ctx, struct k_heap
128158
129159 k_work_user_init (& work_item -> work_item , userspace_proxy_worker_handler );
130160
161+ #if !IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
131162 work_item -> event = & worker .event ;
163+ #endif
132164 work_item -> params .context = user_ctx ;
133165 user_ctx -> work_item = work_item ;
134166
@@ -155,14 +187,19 @@ BUILD_ASSERT(IS_ALIGNED(MAILBOX_HOSTBOX_SIZE, CONFIG_MMU_PAGE_SIZE),
155187static int userspace_proxy_invoke (struct userspace_context * user_ctx , uint32_t cmd ,
156188 bool ipc_payload_access )
157189{
190+ #if IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
191+ struct k_event * const event = user_ctx -> dp_event ;
192+ #else
193+ struct k_event * const event = & worker .event ;
194+ #endif
158195 struct module_params * params = user_work_get_params (user_ctx );
159196 const uintptr_t ipc_req_buf = (uintptr_t )MAILBOX_HOSTBOX_BASE ;
160197 struct k_mem_partition ipc_part = {
161198 .start = ipc_req_buf ,
162199 .size = MAILBOX_HOSTBOX_SIZE ,
163200 .attr = user_get_partition_attr (ipc_req_buf ) | K_MEM_PARTITION_P_RO_U_RO ,
164201 };
165- int ret , ret2 ;
202+ int ret = 0 , ret2 ;
166203
167204 params -> cmd = cmd ;
168205
@@ -174,6 +211,7 @@ static int userspace_proxy_invoke(struct userspace_context *user_ctx, uint32_t c
174211 }
175212 }
176213
214+ #if !IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
177215 /* Switch worker thread to module memory domain */
178216 ret = k_mem_domain_add_thread (user_ctx -> comp_dom , worker .thread_id );
179217 if (ret < 0 ) {
@@ -193,9 +231,13 @@ static int userspace_proxy_invoke(struct userspace_context *user_ctx, uint32_t c
193231 tr_err (& userspace_proxy_tr , "Submit to queue error: %d" , ret );
194232 goto done ;
195233 }
234+ #else
235+ assert (event );
236+ k_event_post (event , DP_TASK_EVENT_IPC );
237+ #endif
196238
197239 /* 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,
240+ if (!k_event_wait_safe (event , DP_TASK_EVENT_IPC_DONE , false,
199241 Z_TIMEOUT_US (250 * 20 ))) {
200242 tr_err (& userspace_proxy_tr , "IPC processing timedout." );
201243 ret = - ETIMEDOUT ;
@@ -313,18 +355,28 @@ static int userspace_proxy_start_agent(struct userspace_context *user_ctx,
313355{
314356 const byte_array_t * const mod_cfg = (byte_array_t * )agent_params -> mod_cfg ;
315357 struct module_params * params = user_work_get_params (user_ctx );
316- int ret ;
317358
318359 params -> ext .agent .start_fn = start_fn ;
319- params -> ext .agent .params = * agent_params ;
320- params -> ext .agent .mod_cfg = * mod_cfg ;
321360
322- ret = userspace_proxy_invoke (user_ctx , USER_PROXY_MOD_CMD_AGENT_START , true);
323- if (ret )
324- return ret ;
361+ /* Start the system agent, if provided. */
362+ if (start_fn ) {
363+ params -> ext .agent .params = * agent_params ;
364+ params -> ext .agent .mod_cfg = * mod_cfg ;
325365
326- * agent_interface = params -> ext .agent .out_interface ;
327- return params -> status ;
366+ /* In case of processing modules ipc in the DP thread, the agent will be started in
367+ * the init function. At this point the DP thread does not exist yet.
368+ */
369+ #if !IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
370+ int ret = userspace_proxy_invoke (user_ctx , USER_PROXY_MOD_CMD_AGENT_START , true);
371+
372+ if (ret )
373+ return ret ;
374+
375+ * agent_interface = params -> ext .agent .out_interface ;
376+ return params -> status ;
377+ #endif
378+ }
379+ return 0 ;
328380}
329381
330382int userspace_proxy_create (struct userspace_context * * user_ctx , const struct comp_driver * drv ,
@@ -342,6 +394,8 @@ int userspace_proxy_create(struct userspace_context **user_ctx, const struct com
342394 if (!context )
343395 return - ENOMEM ;
344396
397+ context -> dp_event = NULL ;
398+
345399 /* Allocate memory domain struct */
346400 domain = rzalloc (SOF_MEM_FLAG_KERNEL , sizeof (* domain ));
347401 if (!domain ) {
@@ -362,14 +416,10 @@ int userspace_proxy_create(struct userspace_context **user_ctx, const struct com
362416 if (ret )
363417 goto error_dom ;
364418
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- }
419+ ret = userspace_proxy_start_agent (context , start_fn , agent_params , agent_interface );
420+ if (ret ) {
421+ tr_err (& userspace_proxy_tr , "System agent failed with error %d." , ret );
422+ goto error_work_item ;
373423 }
374424
375425 * user_ctx = context ;
@@ -420,6 +470,22 @@ static int userspace_proxy_init(struct processing_module *mod)
420470
421471 comp_dbg (mod -> dev , "start" );
422472
473+ #if IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
474+ /* Start the system agent, if provided. Params is already filled by
475+ * the userspace_proxy_start_agent function.
476+ */
477+ if (params -> ext .agent .start_fn ) {
478+ ret = userspace_proxy_invoke (mod -> user_ctx , USER_PROXY_MOD_CMD_AGENT_START , true);
479+ if (ret )
480+ return ret ;
481+
482+ if (params -> ext .agent .start_fn == system_agent_start )
483+ module_set_private_data (mod , (void * )params -> ext .agent .out_interface );
484+ else
485+ mod -> user_ctx -> interface = params -> ext .agent .out_interface ;
486+ }
487+ #endif
488+
423489 params -> mod = mod ;
424490 ret = userspace_proxy_invoke (mod -> user_ctx , USER_PROXY_MOD_CMD_INIT , true);
425491 if (ret )
0 commit comments