Skip to content

Commit

Permalink
lib_manager: Add libcode modules support
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
softwarecki committed Jan 12, 2024
1 parent 7f1850c commit 1211635
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/include/sof/lib_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
13 changes: 13 additions & 0 deletions src/library_manager/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
80 changes: 80 additions & 0 deletions src/library_manager/lib_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,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)
Expand Down Expand Up @@ -222,11 +287,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;
Expand Down Expand Up @@ -254,6 +328,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,
Expand Down

0 comments on commit 1211635

Please sign in to comment.