mirror of https://github.com/thesofproject/sof.git
lib_manager: Add libcode modules support
A loadable library can contain a several modules marked as lib_code. This modules contains code shared by a multiple modules. Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
This commit is contained in:
parent
6cf723fc7d
commit
fec50da244
|
@ -81,7 +81,9 @@ struct ipc_lib_msg {
|
|||
struct ext_library {
|
||||
struct k_spinlock lock; /* last locking CPU record */
|
||||
struct sof_man_fw_desc *desc[LIB_MANAGER_MAX_LIBS];
|
||||
#ifdef CONFIG_LIBCODE_MODULE_SUPPORT
|
||||
uint32_t mods_exec_load_cnt;
|
||||
#endif
|
||||
struct ipc_lib_msg *lib_notif_pool;
|
||||
uint32_t lib_notif_count;
|
||||
|
||||
|
|
|
@ -13,4 +13,17 @@ config LIBRARY_MANAGER
|
|||
Externally developed modules both for SOF and Zephyr
|
||||
could be used if enabled.
|
||||
If unsure say N.
|
||||
|
||||
|
||||
config LIBCODE_MODULE_SUPPORT
|
||||
bool "Add support for libcode modules"
|
||||
default n
|
||||
depends on LIBRARY_MANAGER
|
||||
help
|
||||
A loadable library can contain a several modules marked
|
||||
as lib_code. This modules contains code shared by
|
||||
a multiple modules. This option adds support for modules
|
||||
of this type.
|
||||
If unsure say N.
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -140,6 +140,71 @@ static int lib_manager_unload_module(const struct sof_man_module *const mod)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LIBCODE_MODULE_SUPPORT
|
||||
/* There are modules marked as lib_code. This is code shared between several modules inside
|
||||
* the library. Load all lib_code modules with first none lib_code module load.
|
||||
*/
|
||||
static int lib_manager_load_libcode_modules(const uint32_t module_id,
|
||||
const struct sof_man_fw_desc *const desc)
|
||||
{
|
||||
struct ext_library *const ext_lib = ext_lib_get();
|
||||
const struct sof_man_module *module_entry = (struct sof_man_module *)
|
||||
((char *)desc + SOF_MAN_MODULE_OFFSET(0));
|
||||
const uint32_t lib_id = LIB_MANAGER_GET_LIB_ID(module_id);
|
||||
int ret, idx;
|
||||
|
||||
if (++ext_lib->mods_exec_load_cnt > 1)
|
||||
return 0;
|
||||
|
||||
for (idx = 0; idx < desc->header.num_module_entries; ++idx, ++module_entry) {
|
||||
if (module_entry->type.lib_code) {
|
||||
ret = lib_manager_load_module(lib_id << LIB_MANAGER_LIB_ID_SHIFT | idx,
|
||||
module_entry);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
for (--idx, --module_entry; idx >= 0; --idx, --module_entry) {
|
||||
if (module_entry->type.lib_code) {
|
||||
ret = lib_manager_unload_module(module_entry);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* There are modules marked as lib_code. This is code shared between several modules inside
|
||||
* the library. Unload all lib_code modules with last none lib_code module unload.
|
||||
*/
|
||||
static int lib_manager_unload_libcode_modules(const uint32_t module_id,
|
||||
const struct sof_man_fw_desc *const desc)
|
||||
{
|
||||
struct ext_library *const ext_lib = ext_lib_get();
|
||||
const struct sof_man_module *module_entry = (struct sof_man_module *)
|
||||
((char *)desc + SOF_MAN_MODULE_OFFSET(0));
|
||||
int ret, idx;
|
||||
|
||||
if (--ext_lib->mods_exec_load_cnt > 0)
|
||||
return 0;
|
||||
|
||||
for (idx = 0; idx < desc->header.num_module_entries; ++idx, ++module_entry) {
|
||||
if (module_entry->type.lib_code) {
|
||||
ret = lib_manager_unload_module(module_entry);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_LIBCODE_MODULE_SUPPORT */
|
||||
|
||||
static void __sparse_cache *lib_manager_get_instance_bss_address(uint32_t module_id,
|
||||
uint32_t instance_id,
|
||||
struct sof_man_module *mod)
|
||||
|
@ -227,11 +292,20 @@ uint32_t lib_manager_allocate_module(const struct comp_driver *drv,
|
|||
if (ret < 0)
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_LIBCODE_MODULE_SUPPORT
|
||||
ret = lib_manager_load_libcode_modules(module_id, desc);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
#endif /* CONFIG_LIBCODE_MODULE_SUPPORT */
|
||||
|
||||
ret = lib_manager_allocate_module_instance(module_id, IPC4_INST_ID(ipc_config->id),
|
||||
base_cfg->is_pages, mod);
|
||||
if (ret < 0) {
|
||||
tr_err(&lib_manager_tr,
|
||||
"lib_manager_allocate_module(): module allocation failed: %d", ret);
|
||||
#ifdef CONFIG_LIBCODE_MODULE_SUPPORT
|
||||
lib_manager_unload_libcode_modules(module_id, desc);
|
||||
#endif /* CONFIG_LIBCODE_MODULE_SUPPORT */
|
||||
goto err;
|
||||
}
|
||||
return mod->entry_point;
|
||||
|
@ -259,6 +333,12 @@ int lib_manager_free_module(const struct comp_driver *drv,
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
#ifdef CONFIG_LIBCODE_MODULE_SUPPORT
|
||||
ret = lib_manager_unload_libcode_modules(module_id, desc);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
#endif /* CONFIG_LIBCODE_MODULE_SUPPORT */
|
||||
|
||||
ret = lib_manager_free_module_instance(module_id, IPC4_INST_ID(ipc_config->id), mod);
|
||||
if (ret < 0) {
|
||||
tr_err(&lib_manager_tr,
|
||||
|
|
Loading…
Reference in New Issue