mirror of https://github.com/thesofproject/sof.git
lib_manager: modules: move native lib support to lib_manager
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 <adrian.warecki@intel.com> Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
This commit is contained in:
parent
784da5468e
commit
902b1e5817
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
byte_array_t mod_cfg = {
|
||||
.data = (uint8_t *)md->cfg.init_data,
|
||||
/* Intel modules expects DW size here */
|
||||
.size = md->cfg.size >> 2,
|
||||
};
|
||||
|
||||
system_agent = system_agent_start(module_entry_point, module_id, instance_id, 0, log_handle,
|
||||
&mod_cfg);
|
||||
|
||||
module_set_private_data(mod, system_agent);
|
||||
|
||||
md->mpd.in_buff_size = src_cfg->ibs;
|
||||
md->mpd.out_buff_size = src_cfg->obs;
|
||||
|
||||
/* Call module specific init function if exists. */
|
||||
if (mod->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(module_get_private_data(mod));
|
||||
}
|
||||
|
||||
return ret;
|
||||
mod->proc_type = MODULE_PROCESS_TYPE_SOURCE_SINK;
|
||||
return iadk_wrapper_init(system_agent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -208,7 +135,6 @@ 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()");
|
||||
|
@ -216,13 +142,10 @@ static int modules_free(struct processing_module *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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -22,9 +22,14 @@
|
|||
#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>
|
||||
#include <zephyr/llext/llext.h>
|
||||
|
||||
#if CONFIG_LIBRARY_AUTH_SUPPORT
|
||||
#include <auth/intel_auth_api.h>
|
||||
|
@ -340,7 +345,7 @@ static inline bool module_is_llext(const struct sof_man_module *mod)
|
|||
|
||||
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)
|
||||
{
|
||||
const struct sof_man_module *mod;
|
||||
const struct ipc4_base_module_cfg *base_cfg = ipc_specific_config;
|
||||
|
@ -358,8 +363,7 @@ uintptr_t lib_manager_allocate_module(struct processing_module *proc,
|
|||
}
|
||||
|
||||
if (module_is_llext(mod))
|
||||
return llext_manager_allocate_module(proc, ipc_config, ipc_specific_config,
|
||||
buildinfo);
|
||||
return llext_manager_allocate_module(proc, ipc_config, ipc_specific_config);
|
||||
|
||||
ret = lib_manager_load_module(module_id, mod);
|
||||
if (ret < 0)
|
||||
|
@ -495,12 +499,93 @@ const struct sof_man_module *lib_manager_get_module_manifest(const uint32_t modu
|
|||
}
|
||||
|
||||
#if CONFIG_INTEL_MODULES
|
||||
/*
|
||||
* \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;
|
||||
|
||||
/*
|
||||
* Variable used by llext_manager to temporary store llext handle before creation
|
||||
* a instance of processing_module.
|
||||
*/
|
||||
struct processing_module tmp_proc;
|
||||
struct comp_dev *dev;
|
||||
|
||||
/* At this point module resources are allocated and it is moved to L2 memory. */
|
||||
tmp_proc.priv.llext = NULL;
|
||||
const uint32_t module_entry_point = lib_manager_allocate_module(&tmp_proc, 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;
|
||||
}
|
||||
|
||||
dev = module_adapter_new(drv, config, spec);
|
||||
if (dev) {
|
||||
struct processing_module *mod = comp_get_drvdata(dev);
|
||||
|
||||
mod->priv.llext = tmp_proc.priv.llext;
|
||||
}
|
||||
return dev;
|
||||
}
|
||||
|
||||
static void lib_manager_module_free(struct comp_dev *dev)
|
||||
{
|
||||
struct processing_module *mod = comp_get_drvdata(dev);
|
||||
struct llext *llext = mod->priv.llext;
|
||||
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);
|
||||
|
||||
if (!llext || !llext_unload(&llext)) {
|
||||
/* 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!");
|
||||
}
|
||||
}
|
||||
|
||||
static void lib_manager_prepare_module_adapter(struct comp_driver *drv, const struct sof_uuid *uuid)
|
||||
{
|
||||
drv->type = SOF_COMP_MODULE_ADAPTER;
|
||||
drv->uid = uuid;
|
||||
drv->tctx = &lib_manager_tr;
|
||||
drv->ops.create = module_adapter_new;
|
||||
drv->ops.create = lib_manager_module_create;
|
||||
drv->ops.prepare = module_adapter_prepare;
|
||||
drv->ops.params = module_adapter_params;
|
||||
drv->ops.copy = module_adapter_copy;
|
||||
|
@ -509,7 +594,7 @@ static void lib_manager_prepare_module_adapter(struct comp_driver *drv, const st
|
|||
#endif
|
||||
drv->ops.trigger = module_adapter_trigger;
|
||||
drv->ops.reset = module_adapter_reset;
|
||||
drv->ops.free = module_adapter_free;
|
||||
drv->ops.free = lib_manager_module_free;
|
||||
drv->ops.set_large_config = module_set_large_config;
|
||||
drv->ops.get_large_config = module_get_large_config;
|
||||
drv->ops.get_attribute = module_adapter_get_attribute;
|
||||
|
@ -527,22 +612,22 @@ static void lib_manager_prepare_module_adapter(struct comp_driver *drv, const st
|
|||
|
||||
int lib_manager_register_module(const uint32_t component_id)
|
||||
{
|
||||
const struct lib_manager_mod_ctx *const ctx = lib_manager_get_mod_ctx(component_id);
|
||||
const struct sof_man_fw_desc *const desc = lib_manager_get_library_manifest(component_id);
|
||||
const uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(component_id);
|
||||
const struct sof_man_fw_desc *desc;
|
||||
const struct sof_module_api_build_info *build_info;
|
||||
struct comp_driver_info *new_drv_info;
|
||||
struct comp_driver *drv = NULL;
|
||||
struct sof_man_module *mod;
|
||||
const struct sof_man_module *mod;
|
||||
int ret;
|
||||
|
||||
/* Get library manifest based on component_id */
|
||||
if (!ctx || !ctx->base_addr)
|
||||
if (!desc) {
|
||||
tr_err(&lib_manager_tr, "Error: Couldn't find loadable module with id %u.",
|
||||
component_id);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
desc = (const struct sof_man_fw_desc *)((const char *)ctx->base_addr +
|
||||
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);
|
||||
tr_err(&lib_manager_tr, "Entry index %u out of bounds.", entry_index);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
@ -568,13 +653,44 @@ int lib_manager_register_module(const uint32_t component_id)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Fill the new_drv_info structure with already known parameters */
|
||||
/* Check already registered components */
|
||||
mod = (struct sof_man_module *)((uint8_t *)desc + SOF_MAN_MODULE_OFFSET(entry_index));
|
||||
mod = (struct sof_man_module *)((const uint8_t *)desc + SOF_MAN_MODULE_OFFSET(entry_index));
|
||||
const struct sof_uuid *uid = (struct sof_uuid *)&mod->uuid[0];
|
||||
|
||||
lib_manager_prepare_module_adapter(drv, uid);
|
||||
|
||||
/*
|
||||
* llext modules store build info structure in separate section which is not accessible now.
|
||||
*/
|
||||
if (!module_is_llext(mod)) {
|
||||
build_info = (const struct sof_module_api_build_info *)((const char *)desc -
|
||||
SOF_MAN_ELF_TEXT_OFFSET +
|
||||
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 IADK */
|
||||
if (build_info->format == IADK_MODULE_API_BUILD_INFO_FORMAT &&
|
||||
build_info->api_version_number.full == IADK_MODULE_API_CURRENT_VERSION) {
|
||||
/* Use module_adapter functions */
|
||||
drv->ops.create = module_adapter_new;
|
||||
drv->ops.prepare = module_adapter_prepare;
|
||||
} else {
|
||||
/* Check if module is NOT native */
|
||||
if (build_info->format != SOF_MODULE_API_BUILD_INFO_FORMAT ||
|
||||
build_info->api_version_number.full != SOF_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 */
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <zephyr/llext/llext.h>
|
||||
|
||||
#include <rimage/sof/user/manifest.h>
|
||||
#include <module/module/api_ver.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
|
@ -181,7 +182,7 @@ static int llext_manager_link(struct sof_man_fw_desc *desc, struct sof_man_modul
|
|||
struct llext_load_param ldr_parm = {!ctx->segment_size[SOF_MAN_SEGMENT_TEXT]};
|
||||
int ret = llext_load(&ebl.loader, mod->name, &md->llext, &ldr_parm);
|
||||
|
||||
if (ret < 0)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mod->segment[SOF_MAN_SEGMENT_TEXT].v_base_addr = ebl.loader.sects[LLEXT_MEM_TEXT].sh_addr;
|
||||
|
@ -230,7 +231,7 @@ static int llext_manager_link(struct sof_man_fw_desc *desc, struct sof_man_modul
|
|||
|
||||
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)
|
||||
{
|
||||
struct sof_man_fw_desc *desc;
|
||||
struct sof_man_module *mod;
|
||||
|
@ -238,7 +239,7 @@ uintptr_t llext_manager_allocate_module(struct processing_module *proc,
|
|||
uint32_t module_id = IPC4_MOD_ID(ipc_config->id);
|
||||
uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(module_id);
|
||||
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
|
||||
const struct sof_man_module_manifest *mod_manifest;
|
||||
const struct sof_module_api_build_info *buildinfo;
|
||||
|
||||
tr_dbg(&lib_manager_tr, "llext_manager_allocate_module(): mod_id: %#x",
|
||||
ipc_config->id);
|
||||
|
@ -252,23 +253,35 @@ uintptr_t llext_manager_allocate_module(struct processing_module *proc,
|
|||
|
||||
mod = (struct sof_man_module *)((char *)desc + SOF_MAN_MODULE_OFFSET(entry_index));
|
||||
|
||||
ret = llext_manager_link(desc, mod, module_id, &proc->priv, buildinfo, &mod_manifest);
|
||||
ret = llext_manager_link(desc, mod, module_id, &proc->priv, (const void **)&buildinfo,
|
||||
&ctx->mod_manifest);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
|
||||
/* Map .text and the rest as .data */
|
||||
ret = llext_manager_load_module(module_id, mod);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
if (!ret) {
|
||||
/* First instance: check that the module is native */
|
||||
if (buildinfo->format != SOF_MODULE_API_BUILD_INFO_FORMAT ||
|
||||
buildinfo->api_version_number.full != SOF_MODULE_API_CURRENT_VERSION) {
|
||||
tr_err(&lib_manager_tr,
|
||||
"llext_manager_allocate_module(): Unsupported module API version");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
ret = llext_manager_allocate_module_bss(module_id, mod);
|
||||
if (ret < 0) {
|
||||
tr_err(&lib_manager_tr,
|
||||
"llext_manager_allocate_module(): module allocation failed: %d", ret);
|
||||
return 0;
|
||||
/* Map .text and the rest as .data */
|
||||
ret = llext_manager_load_module(module_id, mod);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
|
||||
ret = llext_manager_allocate_module_bss(module_id, mod);
|
||||
if (ret < 0) {
|
||||
tr_err(&lib_manager_tr,
|
||||
"llext_manager_allocate_module(): module allocation failed: %d",
|
||||
ret);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return mod_manifest->module.entry_point;
|
||||
return ctx->mod_manifest->module.entry_point;
|
||||
}
|
||||
|
||||
int llext_manager_free_module(const uint32_t component_id)
|
||||
|
|
Loading…
Reference in New Issue