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
Signed-off-by: Adrian Warecki <[email protected]>
  • Loading branch information
softwarecki committed Mar 4, 2024
1 parent 0454dd9 commit 70c22c0
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 72 deletions.
82 changes: 18 additions & 64 deletions src/audio/module_adapter/module/modules.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,8 @@
#include <sof/audio/module_adapter/module/modules.h>
#include <utilities/array.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>

/* 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 @@ -60,18 +57,17 @@ static int modules_init(struct processing_module *mod)
{
uint32_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;
const 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;
byte_array_t mod_cfg;
void *system_agent;
bool is_native_sof = false;

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

struct comp_ipc_config *config = &(mod->dev->ipc_config);
const struct comp_ipc_config *config = &dev->ipc_config;

/* At this point module resources are allocated and it is moved to L2 memory. */
module_entry_point = lib_manager_allocate_module(dev->drv, config, src_cfg);
Expand All @@ -81,69 +77,25 @@ static int modules_init(struct processing_module *mod)
}
comp_info(mod->dev, "modules_init() start");

uint32_t module_id = IPC4_MOD_ID(mod->dev->ipc_config.id);
uint32_t instance_id = IPC4_INST_ID(mod->dev->ipc_config.id);
uint32_t log_handle = (uint32_t) mod->dev->drv->tctx;
/* Connect loadable module interfaces with module adapter entity. */
/* Check if native Zephyr lib is loaded */
const uint32_t module_id = IPC4_MOD_ID(dev->ipc_config.id);
const uint32_t instance_id = IPC4_INST_ID(dev->ipc_config.id);
const uint32_t log_handle = (const uint32_t)drv->tctx;

const struct sof_man_module *const module_entry =
lib_manager_get_library_manifest(module_id);
system_agent = system_agent_start(module_entry_point, module_id,
instance_id, 0, log_handle,
&mod_cfg);

if (!module_entry) {
comp_err(dev, "modules_init(): Failed to load manifest");
return -ENOMEM;
if (!system_agent) {
lib_manager_free_module(module_id);
comp_err(dev, "modules_init(), system_agent_start failed!");
return -EFAULT;
}

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

/* 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
/* Check if module is native */
if (mod_buildinfo->format == SOF_MODULE_API_BUILD_INFO_FORMAT &&
mod_buildinfo->api_version_number.full == SOF_MODULE_API_CURRENT_VERSION) {
/* If start agent for sof loadable */
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;

module_set_private_data(mod, system_agent);
md->mpd.in_buff_size = src_cfg->ibs;
md->mpd.out_buff_size = src_cfg->obs;

int ret;

/* Call module specific init function if exists. */
if (is_native_sof) {
const struct module_interface *mod_in = drv->adapter_ops;

/* 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;

ret = mod_in->init(mod);
} else {
mod->proc_type = MODULE_PROCESS_TYPE_SOURCE_SINK;
ret = iadk_wrapper_init(system_agent);
}

return ret;
return iadk_wrapper_init(system_agent);
}

/**
Expand Down Expand Up @@ -192,11 +144,13 @@ static int modules_free(struct processing_module *mod)

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);

/* 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!");
comp_err(dev, "modules_free(), lib_manager_free_module failed with error: %d", ret);

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
4 changes: 2 additions & 2 deletions src/include/sof/lib_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,12 @@ void lib_manager_init(void);
/*
* \brief Register module on driver list
*
* param[in] desc - module manifest descriptor
* param[in] component_id - component id
*
* Creates new comp_driver_info and initialize it for module from library
* Adds new module to sof_get()->comp_drivers list
*/
int lib_manager_register_module(const struct sof_man_module *const mod);
int lib_manager_register_module(const uint32_t component_id);

/*
* \brief Allocate module
Expand Down
2 changes: 1 addition & 1 deletion src/ipc/ipc4/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1002,7 +1002,7 @@ const struct comp_driver *ipc4_get_comp_drv(int module_id)
#if CONFIG_LIBRARY_MANAGER
if (!drv) {
/* New module not registered yet. */
lib_manager_register_module(mod);
lib_manager_register_module(module_id);
drv = ipc4_get_drv(mod->uuid);
}
#endif
Expand Down
119 changes: 114 additions & 5 deletions src/library_manager/lib_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
#include <sof/llext_manager.h>
#include <sof/audio/module_adapter/module/generic.h>
#include <sof/audio/module_adapter/module/modules.h>
#include <utilities/array.h>
#include <native_system_agent.h>
#include <api_version.h>
#include <module/module/api_ver.h>

#include <zephyr/cache.h>
#include <zephyr/drivers/mm/system_mm.h>
Expand Down Expand Up @@ -477,7 +481,6 @@ const struct sof_man_module *lib_manager_get_library_manifest(const uint32_t mod
return NULL;

desc = (const struct sof_man_fw_desc *)((const char *)ctx->desc + SOF_MAN_ELF_TEXT_OFFSET);

if (entry_index >= desc->header.num_module_entries) {
tr_err(&lib_manager_tr, "Entry index %d out of bounds.", entry_index);
return NULL;
Expand All @@ -488,13 +491,91 @@ const struct sof_man_module *lib_manager_get_library_manifest(const uint32_t mod
}

#if CONFIG_INTEL_MODULES
int lib_manager_register_module(const struct sof_man_module *const mod)
/*
* \brief Load module code, allocate its instance and 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.
*/
static struct comp_dev *lib_manager_module_create(const struct comp_driver *drv,
const struct comp_ipc_config *config,
const void *spec)
{
const struct ipc_config_process *args = (struct ipc_config_process *)spec;
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;
byte_array_t mod_cfg;

/* At this point module resources are allocated and it is moved to L2 memory. */
const uint32_t module_entry_point = lib_manager_allocate_module(drv, config, args->data);
if (!module_entry_point) {
tr_err(&lib_manager_tr,
"lib_manager_module_create(), lib_manager_allocate_module() failed!");
return NULL;
}
tr_info(&lib_manager_tr, "lib_manager_module_create() start");

mod_cfg.data = (uint8_t *)args->data;
/* Intel modules expects DW size here */
mod_cfg.size = args->size >> 2;

((struct comp_driver *)drv)->adapter_ops = native_system_agent_start(module_entry_point,
module_id, instance_id,
0, log_handle,
&mod_cfg);

if (!drv->adapter_ops) {
lib_manager_free_module(module_id);
tr_err(&lib_manager_tr,
"lib_manager_module_create(), native_system_agent_start failed!");
return NULL;
}

return module_adapter_new(drv, config, spec);
}


static void lib_manager_module_free(struct comp_dev *dev)
{
struct processing_module *mod = comp_get_drvdata(dev);
const struct comp_ipc_config *const config = &(mod->dev->ipc_config);
const uint32_t module_id = config->id;
int ret;

/* This call invalidates dev, mod and config pointers! */
module_adapter_free(dev);

/* Free module resources allocated in L2 memory. */
ret = lib_manager_free_module(module_id);
if (ret < 0)
comp_err(dev, "modules_free(), lib_manager_free_module() failed!");
}

int lib_manager_register_module(const uint32_t component_id)
{
/* allocate new comp_driver_info */
const struct lib_manager_mod_ctx *const ctx = lib_manager_get_mod_ctx(component_id);
const uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(component_id);
const struct sof_module_api_build_info *build_info;
struct comp_driver_info *new_drv_info;
const struct sof_man_fw_desc *desc;
const struct sof_man_module *mod;
struct comp_driver *drv = NULL;
int ret;

/* Get library manifest based on component_id */
if (!ctx || !ctx->desc)
return -ENOENT;

desc = (const struct sof_man_fw_desc *)((const char *)ctx->desc + SOF_MAN_ELF_TEXT_OFFSET);
if (entry_index >= desc->header.num_module_entries) {
tr_err(&lib_manager_tr, "Entry index %d out of bounds.", entry_index);
return -ENOENT;
}

/* allocate new comp_driver_info */
new_drv_info = rmalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0,
SOF_MEM_CAPS_RAM | SOF_MEM_FLAG_COHERENT,
sizeof(struct comp_driver_info));
Expand All @@ -515,13 +596,41 @@ int lib_manager_register_module(const struct sof_man_module *const mod)
ret = -ENOMEM;
goto cleanup;
}

mod = (const struct sof_man_module *)((const char *)desc +
SOF_MAN_MODULE_OFFSET(entry_index));

/* Fill the new_drv_info structure with already known parameters */
/* Check already registered components */
const struct sof_uuid *const uid = (const struct sof_uuid *)&mod->uuid[0];

declare_dynamic_module_adapter(drv, SOF_COMP_MODULE_ADAPTER, uid, &lib_manager_tr);

build_info = (const struct sof_module_api_build_info *)((const char *)ctx->desc +
mod->segment[SOF_MAN_SEGMENT_TEXT].file_offset);

tr_info(&lib_manager_tr,
"lib_manager_register_module(): Module API version: %u.%u.%u, format: 0x%x",
build_info->api_version_number.fields.major,
build_info->api_version_number.fields.middle,
build_info->api_version_number.fields.minor,
build_info->format);

/* Check if module is native */
if (build_info->format == SOF_MODULE_API_BUILD_INFO_FORMAT &&
build_info->api_version_number.full == SOF_MODULE_API_CURRENT_VERSION) {
/* Use lib_manager shim functions */
drv->ops.create = &lib_manager_module_create;
drv->ops.free = &lib_manager_module_free;
} else {
/* Check if module is not FDK */
if (build_info->format != IADK_MODULE_API_BUILD_INFO_FORMAT ||
build_info->api_version_number.full != IADK_MODULE_API_CURRENT_VERSION) {
tr_err(&lib_manager_tr,
"lib_manager_register_module(): Unsupported module API version");
return -ENOEXEC;
}
}

/* Fill the new_drv_info structure with already known parameters */
new_drv_info->drv = drv;

/* Register new driver in the list */
Expand Down

0 comments on commit 70c22c0

Please sign in to comment.