2222#include <sof/llext_manager.h>
2323#include <sof/audio/module_adapter/module/generic.h>
2424#include <sof/audio/module_adapter/module/modules.h>
25+ #include <utilities/array.h>
26+ #include <native_system_agent.h>
27+ #include <api_version.h>
28+ #include <module/module/api_ver.h>
2529
2630#include <zephyr/cache.h>
2731#include <zephyr/drivers/mm/system_mm.h>
@@ -477,7 +481,6 @@ const struct sof_man_module *lib_manager_get_library_manifest(const uint32_t mod
477481 return NULL ;
478482
479483 desc = (const struct sof_man_fw_desc * )((const char * )ctx -> desc + SOF_MAN_ELF_TEXT_OFFSET );
480-
481484 if (entry_index >= desc -> header .num_module_entries ) {
482485 tr_err (& lib_manager_tr , "Entry index %d out of bounds." , entry_index );
483486 return NULL ;
@@ -488,13 +491,91 @@ const struct sof_man_module *lib_manager_get_library_manifest(const uint32_t mod
488491}
489492
490493#if CONFIG_INTEL_MODULES
491- int lib_manager_register_module (const struct sof_man_module * const mod )
494+ /*
495+ * \brief Load module code, allocate its instance and create a module adapter component.
496+ * \param[in] drv - component driver pointer.
497+ * \param[in] config - component ipc descriptor pointer.
498+ * \param[in] spec - passdowned data from driver.
499+ *
500+ * \return: a pointer to newly created module adapter component on success. NULL on error.
501+ */
502+ static struct comp_dev * lib_manager_module_create (const struct comp_driver * drv ,
503+ const struct comp_ipc_config * config ,
504+ const void * spec )
505+ {
506+ const struct ipc_config_process * args = (struct ipc_config_process * )spec ;
507+ const uint32_t module_id = IPC4_MOD_ID (config -> id );
508+ const uint32_t instance_id = IPC4_INST_ID (config -> id );
509+ const uint32_t log_handle = (uint32_t )drv -> tctx ;
510+ byte_array_t mod_cfg ;
511+
512+ /* At this point module resources are allocated and it is moved to L2 memory. */
513+ const uint32_t module_entry_point = lib_manager_allocate_module (drv , config , args -> data );
514+ if (!module_entry_point ) {
515+ tr_err (& lib_manager_tr ,
516+ "lib_manager_module_create(), lib_manager_allocate_module() failed!" );
517+ return NULL ;
518+ }
519+ tr_info (& lib_manager_tr , "lib_manager_module_create() start" );
520+
521+ mod_cfg .data = (uint8_t * )args -> data ;
522+ /* Intel modules expects DW size here */
523+ mod_cfg .size = args -> size >> 2 ;
524+
525+ ((struct comp_driver * )drv )-> adapter_ops = native_system_agent_start (module_entry_point ,
526+ module_id , instance_id ,
527+ 0 , log_handle ,
528+ & mod_cfg );
529+
530+ if (!drv -> adapter_ops ) {
531+ lib_manager_free_module (module_id );
532+ tr_err (& lib_manager_tr ,
533+ "lib_manager_module_create(), native_system_agent_start failed!" );
534+ return NULL ;
535+ }
536+
537+ return module_adapter_new (drv , config , spec );
538+ }
539+
540+
541+ static void lib_manager_module_free (struct comp_dev * dev )
542+ {
543+ struct processing_module * mod = comp_get_drvdata (dev );
544+ const struct comp_ipc_config * const config = & (mod -> dev -> ipc_config );
545+ const uint32_t module_id = config -> id ;
546+ int ret ;
547+
548+ /* This call invalidates dev, mod and config pointers! */
549+ module_adapter_free (dev );
550+
551+ /* Free module resources allocated in L2 memory. */
552+ ret = lib_manager_free_module (module_id );
553+ if (ret < 0 )
554+ comp_err (dev , "modules_free(), lib_manager_free_module() failed!" );
555+ }
556+
557+ int lib_manager_register_module (const uint32_t component_id )
492558{
493- /* allocate new comp_driver_info */
559+ const struct lib_manager_mod_ctx * const ctx = lib_manager_get_mod_ctx (component_id );
560+ const uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX (component_id );
561+ const struct sof_module_api_build_info * build_info ;
494562 struct comp_driver_info * new_drv_info ;
563+ const struct sof_man_fw_desc * desc ;
564+ const struct sof_man_module * mod ;
495565 struct comp_driver * drv = NULL ;
496566 int ret ;
497567
568+ /* Get library manifest based on component_id */
569+ if (!ctx || !ctx -> desc )
570+ return - ENOENT ;
571+
572+ desc = (const struct sof_man_fw_desc * )((const char * )ctx -> desc + SOF_MAN_ELF_TEXT_OFFSET );
573+ if (entry_index >= desc -> header .num_module_entries ) {
574+ tr_err (& lib_manager_tr , "Entry index %d out of bounds." , entry_index );
575+ return - ENOENT ;
576+ }
577+
578+ /* allocate new comp_driver_info */
498579 new_drv_info = rmalloc (SOF_MEM_ZONE_RUNTIME_SHARED , 0 ,
499580 SOF_MEM_CAPS_RAM | SOF_MEM_FLAG_COHERENT ,
500581 sizeof (struct comp_driver_info ));
@@ -515,13 +596,41 @@ int lib_manager_register_module(const struct sof_man_module *const mod)
515596 ret = - ENOMEM ;
516597 goto cleanup ;
517598 }
599+
600+ mod = (const struct sof_man_module * )((const char * )desc +
601+ SOF_MAN_MODULE_OFFSET (entry_index ));
518602
519- /* Fill the new_drv_info structure with already known parameters */
520- /* Check already registered components */
521603 const struct sof_uuid * const uid = (const struct sof_uuid * )& mod -> uuid [0 ];
522604
523605 declare_dynamic_module_adapter (drv , SOF_COMP_MODULE_ADAPTER , uid , & lib_manager_tr );
524606
607+ build_info = (const struct sof_module_api_build_info * )((const char * )ctx -> desc +
608+ mod -> segment [SOF_MAN_SEGMENT_TEXT ].file_offset );
609+
610+ tr_info (& lib_manager_tr ,
611+ "lib_manager_register_module(): Module API version: %u.%u.%u, format: 0x%x" ,
612+ build_info -> api_version_number .fields .major ,
613+ build_info -> api_version_number .fields .middle ,
614+ build_info -> api_version_number .fields .minor ,
615+ build_info -> format );
616+
617+ /* Check if module is native */
618+ if (build_info -> format == SOF_MODULE_API_BUILD_INFO_FORMAT &&
619+ build_info -> api_version_number .full == SOF_MODULE_API_CURRENT_VERSION ) {
620+ /* Use lib_manager shim functions */
621+ drv -> ops .create = & lib_manager_module_create ;
622+ drv -> ops .free = & lib_manager_module_free ;
623+ } else {
624+ /* Check if module is not FDK */
625+ if (build_info -> format != IADK_MODULE_API_BUILD_INFO_FORMAT ||
626+ build_info -> api_version_number .full != IADK_MODULE_API_CURRENT_VERSION ) {
627+ tr_err (& lib_manager_tr ,
628+ "lib_manager_register_module(): Unsupported module API version" );
629+ return - ENOEXEC ;
630+ }
631+ }
632+
633+ /* Fill the new_drv_info structure with already known parameters */
525634 new_drv_info -> drv = drv ;
526635
527636 /* Register new driver in the list */
0 commit comments