33// Copyright(c) 2022 Intel Corporation. All rights reserved.
44//
55// Author: Jaroslaw Stelter <jaroslaw.stelter@intel.com>
6- // Pawel Dobrowolski<pawelx.dobrowolski@intel.com>
6+ // Pawel Dobrowolski <pawelx.dobrowolski@intel.com>
7+ // Adrian Warecki <adrian.warecki@intel.com>
78
89/*
910 * Dynamic module loading functions.
1819#include <rtos/clk.h>
1920#include <rtos/sof.h>
2021#include <rtos/spinlock.h>
22+ #include <rtos/userspace_helper.h>
2123#include <sof/lib/cpu-clk-manager.h>
2224#include <sof/lib_manager.h>
2325#include <sof/llext_manager.h>
2426#include <sof/audio/module_adapter/module/generic.h>
2527#include <sof/audio/module_adapter/module/modules.h>
28+ #include <sof/audio/module_adapter/library/userspace_proxy.h>
2629#include <utilities/array.h>
2730#include <system_agent.h>
2831#include <native_system_agent.h>
@@ -492,14 +495,19 @@ const struct sof_man_module *lib_manager_get_module_manifest(const uint32_t modu
492495 * \param[in] module_entry_point - Entry point address of the module.
493496 * \param[in] agent - Function pointer to the system agent start function.
494497 * \param[out] agent_interface - Pointer to store the module interface returned by the system agent.
498+ * \param[out] userspace - Pointer to store the userspace module proxy context.
499+ * \param[out] ops - Pointer to store pointer to the module interface structure.
495500 *
496501 * \return Error code returned by the system agent, 0 on success.
497502 */
498503static int lib_manager_start_agent (const struct comp_driver * drv , const uint32_t component_id ,
504+ const struct sof_man_module * mod_manifest ,
499505 const struct ipc_config_process * args ,
500506 const uintptr_t module_entry_point ,
501507 const system_agent_start_fn agent ,
502- const void * * agent_interface )
508+ const void * * agent_interface ,
509+ struct userspace_context * * userspace ,
510+ const struct module_interface * * ops )
503511{
504512 const uint32_t module_id = IPC4_MOD_ID (component_id );
505513 const uint32_t instance_id = IPC4_INST_ID (component_id );
@@ -511,6 +519,18 @@ static int lib_manager_start_agent(const struct comp_driver *drv, const uint32_t
511519 /* Intel modules expects DW size here */
512520 mod_cfg .size = args -> size >> 2 ;
513521
522+ #if CONFIG_USERSPACE
523+ /* If drv->user_heap is allocated, it means the module is userspace. */
524+ if (drv -> user_heap ) {
525+ ret = userspace_proxy_create (userspace , drv , mod_manifest , agent ,
526+ module_entry_point , module_id , instance_id , 0 ,
527+ log_handle , & mod_cfg , agent_interface , ops );
528+ if (ret )
529+ tr_err (& lib_manager_tr , "userspace_proxy_create failed! %d" , ret );
530+ return ret ;
531+ }
532+ #endif /* CONFIG_USERSPACE */
533+
514534 ret = agent (module_entry_point , module_id , instance_id , 0 , log_handle , & mod_cfg ,
515535 agent_interface );
516536 if (ret )
@@ -580,14 +600,22 @@ static struct comp_dev *lib_manager_module_create(const struct comp_driver *drv,
580600 const struct sof_man_fw_desc * const desc = lib_manager_get_library_manifest (config -> id );
581601 const struct ipc_config_process * args = (struct ipc_config_process * )spec ;
582602 const uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX (config -> id );
583- const struct module_interface * ops = NULL ;
603+ struct userspace_context * userspace ;
604+ const struct module_interface * ops ;
584605 const struct sof_man_module * mod ;
585606 system_agent_start_fn agent ;
586607 void * adapter_priv = NULL ;
587608 const void * * agent_iface ;
588609 struct comp_dev * dev ;
589610 int ret ;
590611
612+ #ifdef CONFIG_USERSPACE
613+ if (drv -> user_heap && config -> proc_domain != COMP_PROCESSING_DOMAIN_DP ) {
614+ tr_err (& lib_manager_tr , "Userspace supports only DP modules." );
615+ return NULL ;
616+ }
617+ #endif
618+
591619 tr_dbg (& lib_manager_tr , "start" );
592620 if (!desc ) {
593621 tr_err (& lib_manager_tr , "Error: Couldn't find loadable module with id %u." ,
@@ -619,29 +647,29 @@ static struct comp_dev *lib_manager_module_create(const struct comp_driver *drv,
619647 agent = & native_system_agent_start ;
620648 agent_iface = (const void * * )& ops ;
621649 break ;
650+ #if CONFIG_INTEL_MODULES
622651 case MOD_TYPE_IADK :
623652 agent = & system_agent_start ;
624- /* processing_module_adapter_interface is already assigned to drv->adapter_ops by
625- * the lib_manager_prepare_module_adapter function.
626- */
653+ ops = & processing_module_adapter_interface ;
627654 agent_iface = (const void * * )& adapter_priv ;
628655 break ;
656+ #endif
629657 case MOD_TYPE_INVALID :
630658 goto err ;
631659 }
632660
633661 /* At this point module resources are allocated and it is moved to L2 memory. */
634662 if (agent ) {
635- ret = lib_manager_start_agent (drv , config -> id , args , module_entry_point , agent ,
636- agent_iface );
663+ ret = lib_manager_start_agent (drv , config -> id , mod , args , module_entry_point , agent ,
664+ agent_iface , & userspace , & ops );
637665 if (ret )
638666 goto err ;
639667 }
640668
641- if (ops && comp_set_adapter_ops (drv , ops ) < 0 )
669+ if (comp_set_adapter_ops (drv , ops ) < 0 )
642670 goto err ;
643671
644- dev = module_adapter_new_ext (drv , config , spec , adapter_priv , NULL );
672+ dev = module_adapter_new_ext (drv , config , spec , adapter_priv , userspace );
645673 if (!dev )
646674 goto err ;
647675
@@ -694,18 +722,16 @@ static void lib_manager_prepare_module_adapter(struct comp_driver *drv, const st
694722 drv -> ops .dai_ts_start = module_adapter_ts_start_op ;
695723 drv -> ops .dai_ts_stop = module_adapter_ts_stop_op ;
696724 drv -> ops .dai_ts_get = module_adapter_ts_get_op ;
697- #if CONFIG_INTEL_MODULES
698- drv -> adapter_ops = & processing_module_adapter_interface ;
699- #endif
700725}
701726
702727int lib_manager_register_module (const uint32_t component_id )
703728{
704- struct comp_driver_info * new_drv_info ;
705- struct comp_driver * drv = NULL ;
706729 const struct sof_man_module * mod = lib_manager_get_module_manifest (component_id );
707730 const struct sof_uuid * uid = (struct sof_uuid * )& mod -> uuid ;
708- int ret ;
731+ struct comp_driver_info * new_drv_info ;
732+ struct sys_heap * drv_heap = NULL ;
733+ struct comp_driver * drv = NULL ;
734+ int ret = - ENOMEM ;
709735
710736 if (!mod ) {
711737 tr_err (& lib_manager_tr , "Error: Couldn't find loadable module with id %u." ,
@@ -722,13 +748,23 @@ int lib_manager_register_module(const uint32_t component_id)
722748 return - ENOMEM ;
723749 }
724750
725- drv = rzalloc (SOF_MEM_FLAG_KERNEL | SOF_MEM_FLAG_COHERENT ,
726- sizeof (struct comp_driver ));
751+ #if CONFIG_USERSPACE
752+ if (mod -> type .user_mode ) {
753+ drv_heap = module_driver_heap_init ();
754+ if (!drv_heap ) {
755+ tr_err (& lib_manager_tr , "failed to allocate driver heap!" );
756+ goto cleanup ;
757+ }
758+ }
759+ #endif /* CONFIG_USERSPACE */
760+
761+ drv = module_driver_heap_rmalloc (drv_heap , SOF_MEM_FLAG_KERNEL | SOF_MEM_FLAG_COHERENT ,
762+ sizeof (struct comp_driver ));
727763 if (!drv ) {
728764 tr_err (& lib_manager_tr , "failed to allocate comp_driver" );
729- ret = - ENOMEM ;
730765 goto cleanup ;
731766 }
767+ drv -> user_heap = drv_heap ;
732768
733769 lib_manager_prepare_module_adapter (drv , uid );
734770
@@ -741,8 +777,9 @@ int lib_manager_register_module(const uint32_t component_id)
741777
742778cleanup :
743779 if (ret < 0 ) {
744- rfree (drv );
745- rfree (new_drv_info );
780+ module_driver_heap_free (drv_heap , drv );
781+ module_driver_heap_free (drv_heap , new_drv_info );
782+ module_driver_heap_remove (drv_heap );
746783 }
747784
748785 return ret ;
0 commit comments