@@ -49,6 +49,33 @@ 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+ tr_dbg (& userspace_proxy_tr , "Set DP event %p for module %p" ,
68+ (void * )event , (void * )mod );
69+ user_ctx -> dp_event = event ;
70+ user_ctx -> work_item -> event = event ;
71+
72+ assert (user_ctx -> work_item );
73+ return & user_ctx -> work_item -> work_item ;
74+ }
75+
76+ return NULL ;
77+ }
78+ #else
5279/* IPC requests targeting userspace modules are handled through a user work queue.
5380 * Each userspace module provides its own work item that carries the IPC request parameters.
5481 * The worker thread is switched into the module's memory domain and receives the work item.
@@ -106,6 +133,7 @@ static void user_worker_put(void)
106133 user_stack_free (worker .stack_ptr );
107134 }
108135}
136+ #endif
109137
110138static int user_work_item_init (struct userspace_context * user_ctx , struct k_heap * user_heap )
111139{
@@ -128,7 +156,9 @@ static int user_work_item_init(struct userspace_context *user_ctx, struct k_heap
128156
129157 k_work_user_init (& work_item -> work_item , userspace_proxy_worker_handler );
130158
159+ #if !IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
131160 work_item -> event = & worker .event ;
161+ #endif
132162 work_item -> params .context = user_ctx ;
133163 user_ctx -> work_item = work_item ;
134164
@@ -155,14 +185,19 @@ BUILD_ASSERT(IS_ALIGNED(MAILBOX_HOSTBOX_SIZE, CONFIG_MMU_PAGE_SIZE),
155185static int userspace_proxy_invoke (struct userspace_context * user_ctx , uint32_t cmd ,
156186 bool ipc_payload_access )
157187{
188+ #if IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
189+ struct k_event * const event = user_ctx -> dp_event ;
190+ #else
191+ struct k_event * const event = & worker .event ;
192+ #endif
158193 struct module_params * params = user_work_get_params (user_ctx );
159194 const uintptr_t ipc_req_buf = (uintptr_t )MAILBOX_HOSTBOX_BASE ;
160195 struct k_mem_partition ipc_part = {
161196 .start = ipc_req_buf ,
162197 .size = MAILBOX_HOSTBOX_SIZE ,
163198 .attr = user_get_partition_attr (ipc_req_buf ) | K_MEM_PARTITION_P_RO_U_RO ,
164199 };
165- int ret , ret2 ;
200+ int ret = 0 , ret2 ;
166201
167202 params -> cmd = cmd ;
168203
@@ -174,6 +209,7 @@ static int userspace_proxy_invoke(struct userspace_context *user_ctx, uint32_t c
174209 }
175210 }
176211
212+ #if !IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
177213 /* Switch worker thread to module memory domain */
178214 ret = k_mem_domain_add_thread (user_ctx -> comp_dom , worker .thread_id );
179215 if (ret < 0 ) {
@@ -193,9 +229,13 @@ static int userspace_proxy_invoke(struct userspace_context *user_ctx, uint32_t c
193229 tr_err (& userspace_proxy_tr , "Submit to queue error: %d" , ret );
194230 goto done ;
195231 }
232+ #else
233+ assert (event );
234+ k_event_post (event , DP_TASK_EVENT_IPC );
235+ #endif
196236
197237 /* 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,
238+ if (!k_event_wait_safe (event , DP_TASK_EVENT_IPC_DONE , false,
199239 Z_TIMEOUT_US (250 * 20 ))) {
200240 tr_err (& userspace_proxy_tr , "IPC processing timedout." );
201241 ret = - ETIMEDOUT ;
@@ -313,18 +353,27 @@ static int userspace_proxy_start_agent(struct userspace_context *user_ctx,
313353{
314354 const byte_array_t * const mod_cfg = (byte_array_t * )agent_params -> mod_cfg ;
315355 struct module_params * params = user_work_get_params (user_ctx );
316- int ret ;
317356
318357 params -> ext .agent .start_fn = start_fn ;
319- params -> ext .agent .params = * agent_params ;
320- params -> ext .agent .mod_cfg = * mod_cfg ;
321358
322- ret = userspace_proxy_invoke (user_ctx , USER_PROXY_MOD_CMD_AGENT_START , true);
323- if (ret )
324- return ret ;
359+ /* Start the system agent, if provided. */
360+ if (start_fn ) {
361+ params -> ext .agent .params = * agent_params ;
362+ params -> ext .agent .mod_cfg = * mod_cfg ;
325363
326- * agent_interface = params -> ext .agent .out_interface ;
327- return params -> status ;
364+ /* In case of processing modules ipc in the DP thread, the agent will be started in the
365+ * init function. At this point the DP thread does not exist yet.
366+ */
367+ #if !IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
368+ int ret = userspace_proxy_invoke (user_ctx , USER_PROXY_MOD_CMD_AGENT_START , true);
369+ if (ret )
370+ return ret ;
371+
372+ * agent_interface = params -> ext .agent .out_interface ;
373+ return params -> status ;
374+ #endif
375+ }
376+ return 0 ;
328377}
329378
330379int userspace_proxy_create (struct userspace_context * * user_ctx , const struct comp_driver * drv ,
@@ -362,14 +411,10 @@ int userspace_proxy_create(struct userspace_context **user_ctx, const struct com
362411 if (ret )
363412 goto error_dom ;
364413
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- }
414+ ret = userspace_proxy_start_agent (context , start_fn , agent_params , agent_interface );
415+ if (ret ) {
416+ tr_err (& userspace_proxy_tr , "System agent failed with error %d." , ret );
417+ goto error_work_item ;
373418 }
374419
375420 * user_ctx = context ;
@@ -420,6 +465,22 @@ static int userspace_proxy_init(struct processing_module *mod)
420465
421466 comp_dbg (mod -> dev , "start" );
422467
468+ #if IS_ENABLED (CONFIG_SOF_USERSPACE_MOD_IPC_BY_DP_THREAD )
469+ /* Start the system agent, if provided. Params is already filled by
470+ * the userspace_proxy_start_agent function.
471+ */
472+ if (params -> ext .agent .start_fn ) {
473+ ret = userspace_proxy_invoke (mod -> user_ctx , USER_PROXY_MOD_CMD_AGENT_START , true);
474+ if (ret )
475+ return ret ;
476+
477+ if (params -> ext .agent .start_fn == system_agent_start )
478+ module_set_private_data (mod , (void * )params -> ext .agent .out_interface );
479+ else
480+ mod -> user_ctx -> interface = params -> ext .agent .out_interface ;
481+ }
482+ #endif
483+
423484 params -> mod = mod ;
424485 ret = userspace_proxy_invoke (mod -> user_ctx , USER_PROXY_MOD_CMD_INIT , true);
425486 if (ret )
0 commit comments