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 ext_library {
|
||||||
struct k_spinlock lock; /* last locking CPU record */
|
struct k_spinlock lock; /* last locking CPU record */
|
||||||
struct sof_man_fw_desc *desc[LIB_MANAGER_MAX_LIBS];
|
struct sof_man_fw_desc *desc[LIB_MANAGER_MAX_LIBS];
|
||||||
|
#ifdef CONFIG_LIBCODE_MODULE_SUPPORT
|
||||||
uint32_t mods_exec_load_cnt;
|
uint32_t mods_exec_load_cnt;
|
||||||
|
#endif
|
||||||
struct ipc_lib_msg *lib_notif_pool;
|
struct ipc_lib_msg *lib_notif_pool;
|
||||||
uint32_t lib_notif_count;
|
uint32_t lib_notif_count;
|
||||||
|
|
||||||
|
|
|
@ -13,4 +13,17 @@ config LIBRARY_MANAGER
|
||||||
Externally developed modules both for SOF and Zephyr
|
Externally developed modules both for SOF and Zephyr
|
||||||
could be used if enabled.
|
could be used if enabled.
|
||||||
If unsure say N.
|
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
|
endmenu
|
||||||
|
|
|
@ -140,6 +140,71 @@ static int lib_manager_unload_module(const struct sof_man_module *const mod)
|
||||||
return 0;
|
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,
|
static void __sparse_cache *lib_manager_get_instance_bss_address(uint32_t module_id,
|
||||||
uint32_t instance_id,
|
uint32_t instance_id,
|
||||||
struct sof_man_module *mod)
|
struct sof_man_module *mod)
|
||||||
|
@ -227,11 +292,20 @@ uint32_t lib_manager_allocate_module(const struct comp_driver *drv,
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return 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),
|
ret = lib_manager_allocate_module_instance(module_id, IPC4_INST_ID(ipc_config->id),
|
||||||
base_cfg->is_pages, mod);
|
base_cfg->is_pages, mod);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
tr_err(&lib_manager_tr,
|
tr_err(&lib_manager_tr,
|
||||||
"lib_manager_allocate_module(): module allocation failed: %d", ret);
|
"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;
|
goto err;
|
||||||
}
|
}
|
||||||
return mod->entry_point;
|
return mod->entry_point;
|
||||||
|
@ -259,6 +333,12 @@ int lib_manager_free_module(const struct comp_driver *drv,
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
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);
|
ret = lib_manager_free_module_instance(module_id, IPC4_INST_ID(ipc_config->id), mod);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
tr_err(&lib_manager_tr,
|
tr_err(&lib_manager_tr,
|
||||||
|
|
Loading…
Reference in New Issue