@@ -394,7 +394,6 @@ void ipc_schedule_process(struct ipc *ipc)
394394#define IPC_USER_EVENT_CMD BIT(0)
395395#define IPC_USER_EVENT_STOP BIT(1)
396396
397- static struct k_thread ipc_user_thread ;
398397static K_THREAD_STACK_DEFINE (ipc_user_stack , CONFIG_SOF_IPC_USER_THREAD_STACK_SIZE ) ;
399398
400399/**
@@ -617,6 +616,55 @@ static void ipc_user_thread_fn(void *p1, void *p2, void *p3)
617616 }
618617}
619618
619+ __cold static int ipc_user_init_thread (struct ipc_user * ipc_user )
620+ {
621+ char thread_name [] = "ll_user0" ;
622+ int ret ;
623+
624+ assert_can_be_cold ();
625+
626+ /* Allocate kernel objects for the user-space thread */
627+ ipc_user -> event = k_object_alloc (K_OBJ_EVENT );
628+ if (!ipc_user -> event ) {
629+ LOG_ERR ("user IPC event alloc failed" );
630+ return - ENOMEM ;
631+ }
632+ k_event_init (ipc_user -> event );
633+
634+ ipc_user -> thread = k_object_alloc (K_OBJ_THREAD );
635+ if (!ipc_user -> thread ) {
636+ LOG_ERR ("user IPC thread alloc failed" );
637+ ret = - ENOMEM ;
638+ goto e_event ;
639+ }
640+
641+ k_thread_create (ipc_user -> thread , ipc_user_stack ,
642+ CONFIG_SOF_IPC_USER_THREAD_STACK_SIZE ,
643+ ipc_user_thread_fn , ipc_user , NULL , NULL ,
644+ -1 , K_USER , K_FOREVER );
645+
646+ k_thread_cpu_pin (ipc_user -> thread , PLATFORM_PRIMARY_CORE_ID );
647+ k_thread_name_set (ipc_user -> thread , thread_name );
648+
649+ /*
650+ * Each userspace IPC thread must be able to wait on its private event
651+ * and signal completion on the primary core semaphore
652+ */
653+ k_thread_access_grant (ipc_user -> thread , ipc_user -> sem , ipc_user -> event );
654+ user_grant_dai_access_all (ipc_user -> thread );
655+ user_grant_dma_access_all (ipc_user -> thread );
656+ pipeline_posn_grant_access (ipc_user -> thread );
657+ k_mem_domain_add_thread (zephyr_ll_mem_domain (), ipc_user -> thread );
658+ user_ll_grant_access (ipc_user -> thread );
659+
660+ return 0 ;
661+
662+ e_event :
663+ k_object_free (ipc_user -> event );
664+
665+ return ret ;
666+ }
667+
620668__cold int ipc_user_init (void )
621669{
622670 struct ipc * ipc = ipc_get ();
@@ -671,35 +719,18 @@ __cold int ipc_user_init(void)
671719
672720 k_sem_init (ipc_user -> sem , 0 , 1 );
673721
674- /* Allocate kernel objects for the user-space thread */
675- ipc_user -> event = k_object_alloc (K_OBJ_EVENT );
676- if (!ipc_user -> event ) {
677- LOG_ERR ("user IPC event alloc failed" );
722+ ret = ipc_user_init_thread (ipc_user );
723+ if (ret < 0 ) {
724+ LOG_ERR ("user IPC thread initialization failed" );
678725 k_panic ();
679726 }
680- k_event_init (ipc_user -> event );
681-
682- k_thread_create (& ipc_user_thread , ipc_user_stack ,
683- CONFIG_SOF_IPC_USER_THREAD_STACK_SIZE ,
684- ipc_user_thread_fn , ipc_user , NULL , NULL ,
685- -1 , K_USER , K_FOREVER );
686-
687- ipc_user -> thread = & ipc_user_thread ;
688- k_thread_access_grant (& ipc_user_thread , ipc_user -> sem , ipc_user -> event );
689- user_grant_dai_access_all (& ipc_user_thread );
690- user_grant_dma_access_all (& ipc_user_thread );
691- user_access_to_mailbox (zephyr_ll_mem_domain (), & ipc_user_thread );
692- user_ll_grant_access (& ipc_user_thread );
693- pipeline_posn_grant_access (& ipc_user_thread );
694- k_mem_domain_add_thread (zephyr_ll_mem_domain (), & ipc_user_thread );
695727
696- k_thread_cpu_pin (& ipc_user_thread , PLATFORM_PRIMARY_CORE_ID );
697- k_thread_name_set (& ipc_user_thread , "ipc_user" );
728+ user_access_to_mailbox (zephyr_ll_mem_domain (), ipc_user -> thread );
698729
699730 /* Store references in ipc struct so kernel handler can forward commands */
700731 ipc -> ipc_user_pdata = ipc_user ;
701732
702- k_thread_start (& ipc_user_thread );
733+ k_thread_start (ipc_user -> thread );
703734
704735 struct task * task = zephyr_ll_task_alloc ();
705736 schedule_task_init_ll (task , SOF_UUID (ipc_uuid ), SOF_SCHEDULE_LL_TIMER ,
@@ -710,7 +741,7 @@ __cold int ipc_user_init(void)
710741 * Needed so user-space dai_common_new() can call
711742 * k_thread_access_grant(audio_thread, dai_mutex) from user context.
712743 */
713- k_thread_access_grant (& ipc_user_thread , ipc_user -> audio_thread );
744+ k_thread_access_grant (ipc_user -> thread , ipc_user -> audio_thread );
714745
715746 /* Wait for user thread startup — consumes the initial k_sem_give from thread */
716747 k_sem_take (ipc -> ipc_user_pdata -> sem , K_FOREVER );
0 commit comments