Skip to content

Commit

Permalink
lib_manager: modules: move native lib support to lib_manager
Browse files Browse the repository at this point in the history
Moved module type identification to lib_manager. Since llext modules place
the buildinfo structure in a separate section, API version verification has
been moved to llext_manager. Thanks to these changes, the Processing Module
Adapter is used only by IADK modules as intended. This commit also fixes an
issue with the modules_free function not being called for native modules.

Signed-off-by: Adrian Warecki <[email protected]>
Signed-off-by: Guennadi Liakhovetski <[email protected]>
  • Loading branch information
softwarecki committed Apr 3, 2024
1 parent e2691db commit fa58e36
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 138 deletions.
127 changes: 25 additions & 102 deletions src/audio/module_adapter/module/modules.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,8 @@
#include <utilities/array.h>
#include <iadk_module_adapter.h>
#include <system_agent.h>
#include <native_system_agent.h>
#include <api_version.h>
#include <sof/lib_manager.h>
#include <sof/audio/module_adapter/module/module_interface.h>
#include <module/module/api_ver.h>
#include <zephyr/llext/llext.h>

/* Intel module adapter is an extension to SOF module adapter component that allows to integrate
* modules developed under IADK (Intel Audio Development Kit) Framework. IADK modules uses uniform
Expand Down Expand Up @@ -51,63 +47,6 @@ DECLARE_SOF_RT_UUID("modules", intel_uuid, 0xee2585f2, 0xe7d8, 0x43dc,
0x90, 0xab, 0x42, 0x24, 0xe0, 0x0c, 0x3e, 0x84);
DECLARE_TR_CTX(intel_codec_tr, SOF_UUID(intel_uuid), LOG_LEVEL_INFO);

static int modules_new(struct processing_module *mod, const void *buildinfo,
uintptr_t module_entry_point)
{
struct module_data *md = &mod->priv;
struct comp_dev *dev = mod->dev;
struct comp_driver *drv = (struct comp_driver *)dev->drv;
uint32_t module_id = IPC4_MOD_ID(dev->ipc_config.id);
uint32_t instance_id = IPC4_INST_ID(dev->ipc_config.id);
uint32_t log_handle = (uint32_t) dev->drv->tctx;
/* Connect loadable module interfaces with module adapter entity. */
/* Check if native Zephyr lib is loaded */
void *system_agent;

const struct sof_module_api_build_info *mod_buildinfo;

if (buildinfo) {
mod_buildinfo = buildinfo;
} else {
const struct sof_man_module *const module_entry =
lib_manager_get_module_manifest(module_id);

if (!module_entry) {
comp_err(dev, "modules_new(): Failed to load manifest");
return -ENODATA;
}

mod_buildinfo =
(struct sof_module_api_build_info *)
(module_entry->segment[SOF_MAN_SEGMENT_TEXT].v_base_addr);
}

byte_array_t mod_cfg = {
.data = (uint8_t *)md->cfg.init_data,
/* Intel modules expects DW size here */
.size = md->cfg.size >> 2,
};

/* Check if module is FDK */
if (mod_buildinfo->format == IADK_MODULE_API_BUILD_INFO_FORMAT &&
mod_buildinfo->api_version_number.full == IADK_MODULE_API_CURRENT_VERSION) {
system_agent = system_agent_start(module_entry_point, module_id, instance_id, 0,
log_handle, &mod_cfg);

module_set_private_data(mod, system_agent);
} else if (mod_buildinfo->format == SOF_MODULE_API_BUILD_INFO_FORMAT &&
mod_buildinfo->api_version_number.full == SOF_MODULE_API_CURRENT_VERSION) {
/* The module is native: start agent for sof loadable */
mod->is_native_sof = true;
drv->adapter_ops = native_system_agent_start(module_entry_point, module_id,
instance_id, 0, log_handle, &mod_cfg);
} else {
return -ENOEXEC;
}

return 0;
}

/**
* \brief modules_init.
* \param[in] mod - processing module pointer.
Expand All @@ -121,51 +60,39 @@ static int modules_init(struct processing_module *mod)
struct comp_dev *dev = mod->dev;
const struct comp_driver *const drv = dev->drv;
const struct ipc4_base_module_cfg *src_cfg = &md->cfg.base_cfg;
struct comp_ipc_config *config = &(dev->ipc_config);
/* At this point module resources are allocated and it is moved to L2 memory. */
const void *buildinfo = NULL;
int ret;
uintptr_t module_entry_point = lib_manager_allocate_module(mod, config, src_cfg,
&buildinfo);
const struct comp_ipc_config *config = &(dev->ipc_config);
void *system_agent;

uintptr_t module_entry_point = lib_manager_allocate_module(mod, config, src_cfg);

if (module_entry_point == 0) {
comp_err(dev, "modules_init(), lib_manager_allocate_module() failed!");
return -EINVAL;
}

/* At this point module resources are allocated and it is moved to L2 memory. */
comp_info(dev, "modules_init() start");

if (!module_get_private_data(mod) &&
drv->adapter_ops == &processing_module_adapter_interface) {
/* First load */
ret = modules_new(mod, buildinfo, module_entry_point);
if (ret < 0)
return ret;
}
const uint32_t module_id = IPC4_MOD_ID(config->id);
const uint32_t instance_id = IPC4_INST_ID(config->id);
const uint32_t log_handle = (uint32_t)drv->tctx;

md->mpd.in_buff_size = src_cfg->ibs;
md->mpd.out_buff_size = src_cfg->obs;
byte_array_t mod_cfg = {
.data = (uint8_t *)md->cfg.init_data,
/* Intel modules expects DW size here */
.size = md->cfg.size >> 2,
};

/* Call module specific init function if exists. */
if (mod->is_native_sof) {
const struct module_interface *mod_in = drv->adapter_ops;
system_agent = system_agent_start(module_entry_point, module_id, instance_id, 0, log_handle,
&mod_cfg);

/* The order of preference */
if (mod_in->process)
mod->proc_type = MODULE_PROCESS_TYPE_SOURCE_SINK;
else if (mod_in->process_audio_stream)
mod->proc_type = MODULE_PROCESS_TYPE_STREAM;
else if (mod_in->process_raw_data)
mod->proc_type = MODULE_PROCESS_TYPE_RAW;
else
return -EINVAL;
module_set_private_data(mod, system_agent);

ret = mod_in->init(mod);
} else {
mod->proc_type = MODULE_PROCESS_TYPE_SOURCE_SINK;
ret = iadk_wrapper_init(module_get_private_data(mod));
}
md->mpd.in_buff_size = src_cfg->ibs;
md->mpd.out_buff_size = src_cfg->obs;

return ret;
mod->proc_type = MODULE_PROCESS_TYPE_SOURCE_SINK;
return iadk_wrapper_init(system_agent);
}

/**
Expand Down Expand Up @@ -208,21 +135,17 @@ static int modules_process(struct processing_module *mod,
static int modules_free(struct processing_module *mod)
{
struct comp_dev *dev = mod->dev;
struct module_data *md = &mod->priv;
int ret;

comp_info(dev, "modules_free()");
ret = iadk_wrapper_free(module_get_private_data(mod));
if (ret)
comp_err(dev, "modules_free(): iadk_wrapper_free failed with error: %d", ret);


if (!md->llext || !llext_unload(&md->llext)) {
/* Free module resources allocated in L2 memory. */
ret = lib_manager_free_module(dev->ipc_config.id);
if (ret < 0)
comp_err(dev, "modules_free(), lib_manager_free_module() failed!");
}
/* Free module resources allocated in L2 memory. */
ret = lib_manager_free_module(dev->ipc_config.id);
if (ret < 0)
comp_err(dev, "modules_free(), lib_manager_free_module() failed!");

return ret;
}
Expand Down
1 change: 1 addition & 0 deletions src/audio/module_adapter/module_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ LOG_MODULE_REGISTER(module_adapter, CONFIG_SOF_LOG_LEVEL);
* \brief Create a module adapter component.
* \param[in] drv - component driver pointer.
* \param[in] config - component ipc descriptor pointer.
* \param[in] spec - passdowned data from driver.
*
* \return: a pointer to newly created module adapter component on success. NULL on error.
*/
Expand Down
3 changes: 0 additions & 3 deletions src/include/module/module/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,6 @@ struct processing_module {
*/
bool stream_copy_single_to_single;

/* flag to insure that module is loadable */
bool is_native_sof;

/* total processed data after stream started */
uint64_t total_data_consumed;
uint64_t total_data_produced;
Expand Down
5 changes: 4 additions & 1 deletion src/include/sof/lib_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,11 @@ struct ipc_lib_msg {
struct list_item list;
};

struct sof_man_module_manifest;

struct lib_manager_mod_ctx {
void *base_addr;
const struct sof_man_module_manifest *mod_manifest;
size_t segment_size[3];
};

Expand Down Expand Up @@ -166,7 +169,7 @@ struct processing_module;
*/
uintptr_t lib_manager_allocate_module(struct processing_module *proc,
const struct comp_ipc_config *ipc_config,
const void *ipc_specific_config, const void **buildinfo);
const void *ipc_specific_config);

/*
* \brief Free module
Expand Down
2 changes: 1 addition & 1 deletion src/include/sof/llext_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct comp_ipc_config;

uintptr_t llext_manager_allocate_module(struct processing_module *proc,
const struct comp_ipc_config *ipc_config,
const void *ipc_specific_config, const void **buildinfo);
const void *ipc_specific_config);

int llext_manager_free_module(const uint32_t component_id);

Expand Down
Loading

0 comments on commit fa58e36

Please sign in to comment.