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 struct system_agent_params agent_params ;
505513 byte_array_t mod_cfg ;
@@ -516,6 +524,17 @@ static int lib_manager_start_agent(const struct comp_driver *drv, const uint32_t
516524 agent_params .log_handle = (uint32_t )drv -> tctx ;
517525 agent_params .mod_cfg = & mod_cfg ;
518526
527+ #if CONFIG_SOF_USERSPACE_PROXY
528+ /* If drv->user_heap is allocated, it means the module is userspace. */
529+ if (drv -> user_heap ) {
530+ ret = userspace_proxy_create (userspace , drv , mod_manifest , agent , & agent_params ,
531+ agent_interface , ops );
532+ if (ret )
533+ tr_err (& lib_manager_tr , "userspace_proxy_create failed! %d" , ret );
534+ return ret ;
535+ }
536+ #endif /* CONFIG_SOF_USERSPACE_PROXY */
537+
519538 ret = agent (& agent_params , agent_interface );
520539 if (ret )
521540 tr_err (& lib_manager_tr , "System agent start failed %d!" , ret );
@@ -584,14 +603,22 @@ static struct comp_dev *lib_manager_module_create(const struct comp_driver *drv,
584603 const struct sof_man_fw_desc * const desc = lib_manager_get_library_manifest (config -> id );
585604 const struct ipc_config_process * args = (const struct ipc_config_process * )spec ;
586605 const uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX (config -> id );
587- const struct module_interface * ops = NULL ;
606+ struct userspace_context * userspace = NULL ;
607+ const struct module_interface * ops ;
588608 const struct sof_man_module * mod ;
589609 system_agent_start_fn agent ;
590610 void * adapter_priv = NULL ;
591611 const void * * agent_iface ;
592612 struct comp_dev * dev ;
593613 int ret ;
594614
615+ #ifdef CONFIG_SOF_USERSPACE_PROXY
616+ if (drv -> user_heap && config -> proc_domain != COMP_PROCESSING_DOMAIN_DP ) {
617+ tr_err (& lib_manager_tr , "Userspace supports only DP modules." );
618+ return NULL ;
619+ }
620+ #endif
621+
595622 tr_dbg (& lib_manager_tr , "start" );
596623 if (!desc ) {
597624 tr_err (& lib_manager_tr , "Error: Couldn't find loadable module with id %u." ,
@@ -623,35 +650,39 @@ static struct comp_dev *lib_manager_module_create(const struct comp_driver *drv,
623650 agent = & native_system_agent_start ;
624651 agent_iface = (const void * * )& ops ;
625652 break ;
653+ #if CONFIG_INTEL_MODULES
626654 case MOD_TYPE_IADK :
627655 agent = & system_agent_start ;
628- /* processing_module_adapter_interface is already assigned to drv->adapter_ops by
629- * the lib_manager_prepare_module_adapter function.
630- */
656+ ops = & processing_module_adapter_interface ;
631657 agent_iface = (const void * * )& adapter_priv ;
632658 break ;
659+ #endif
633660 case MOD_TYPE_INVALID :
634661 goto err ;
635662 }
636663
637664 /* At this point module resources are allocated and it is moved to L2 memory. */
638665 if (agent ) {
639- ret = lib_manager_start_agent (drv , config -> id , args , module_entry_point , agent ,
640- agent_iface );
666+ ret = lib_manager_start_agent (drv , config -> id , mod , args , module_entry_point , agent ,
667+ agent_iface , & userspace , & ops );
641668 if (ret )
642669 goto err ;
643670 }
644671
645- if (ops && comp_set_adapter_ops (drv , ops ) < 0 )
672+ if (comp_set_adapter_ops (drv , ops ) < 0 )
646673 goto err ;
647674
648- dev = module_adapter_new_ext (drv , config , spec , adapter_priv , NULL );
675+ dev = module_adapter_new_ext (drv , config , spec , adapter_priv , userspace );
649676 if (!dev )
650677 goto err ;
651678
652679 return dev ;
653680
654681err :
682+ #if CONFIG_SOF_USERSPACE_PROXY
683+ if (userspace )
684+ userspace_proxy_destroy (drv , userspace );
685+ #endif /* CONFIG_SOF_USERSPACE_PROXY */
655686 lib_manager_free_module (config -> id );
656687 return NULL ;
657688}
@@ -698,18 +729,16 @@ static void lib_manager_prepare_module_adapter(struct comp_driver *drv, const st
698729 drv -> ops .dai_ts_start = module_adapter_ts_start_op ;
699730 drv -> ops .dai_ts_stop = module_adapter_ts_stop_op ;
700731 drv -> ops .dai_ts_get = module_adapter_ts_get_op ;
701- #if CONFIG_INTEL_MODULES
702- drv -> adapter_ops = & processing_module_adapter_interface ;
703- #endif
704732}
705733
706734int lib_manager_register_module (const uint32_t component_id )
707735{
708- struct comp_driver_info * new_drv_info ;
709- struct comp_driver * drv = NULL ;
710736 const struct sof_man_module * mod = lib_manager_get_module_manifest (component_id );
711737 const struct sof_uuid * uid = (struct sof_uuid * )& mod -> uuid ;
712- int ret ;
738+ struct comp_driver_info * new_drv_info ;
739+ struct sys_heap * drv_heap = NULL ;
740+ struct comp_driver * drv = NULL ;
741+ int ret = - ENOMEM ;
713742
714743 if (!mod ) {
715744 tr_err (& lib_manager_tr , "Error: Couldn't find loadable module with id %u." ,
@@ -726,13 +755,23 @@ int lib_manager_register_module(const uint32_t component_id)
726755 return - ENOMEM ;
727756 }
728757
729- drv = rzalloc (SOF_MEM_FLAG_KERNEL | SOF_MEM_FLAG_COHERENT ,
730- sizeof (struct comp_driver ));
758+ #if CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP
759+ if (mod -> type .user_mode ) {
760+ drv_heap = module_driver_heap_init ();
761+ if (!drv_heap ) {
762+ tr_err (& lib_manager_tr , "failed to allocate driver heap!" );
763+ goto cleanup ;
764+ }
765+ }
766+ #endif /* CONFIG_SOF_USERSPACE_USE_DRIVER_HEAP */
767+
768+ drv = module_driver_heap_rmalloc (drv_heap , SOF_MEM_FLAG_KERNEL | SOF_MEM_FLAG_COHERENT ,
769+ sizeof (struct comp_driver ));
731770 if (!drv ) {
732771 tr_err (& lib_manager_tr , "failed to allocate comp_driver" );
733- ret = - ENOMEM ;
734772 goto cleanup ;
735773 }
774+ drv -> user_heap = drv_heap ;
736775
737776 lib_manager_prepare_module_adapter (drv , uid );
738777
@@ -745,8 +784,9 @@ int lib_manager_register_module(const uint32_t component_id)
745784
746785cleanup :
747786 if (ret < 0 ) {
748- rfree (drv );
749787 rfree (new_drv_info );
788+ module_driver_heap_free (drv_heap , drv );
789+ module_driver_heap_remove (drv_heap );
750790 }
751791
752792 return ret ;
0 commit comments