Skip to content

Commit 34628b3

Browse files
committed
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>
1 parent bfa5e4d commit 34628b3

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed

src/include/sof/lib_manager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ struct ipc_lib_msg {
8181
struct ext_library {
8282
struct k_spinlock lock; /* last locking CPU record */
8383
struct sof_man_fw_desc *desc[LIB_MANAGER_MAX_LIBS];
84+
#ifdef CONFIG_LIBCODE_MODULE_SUPPORT
8485
uint32_t mods_exec_load_cnt;
86+
#endif
8587
struct ipc_lib_msg *lib_notif_pool;
8688
uint32_t lib_notif_count;
8789

src/library_manager/Kconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,17 @@ config LIBRARY_MANAGER
1313
Externally developed modules both for SOF and Zephyr
1414
could be used if enabled.
1515
If unsure say N.
16+
17+
18+
config LIBCODE_MODULE_SUPPORT
19+
bool "Add support for libcode modules"
20+
default n
21+
depends on LIBRARY_MANAGER
22+
help
23+
A loadable library can contain a several modules marked
24+
as lib_code. This modules contains code shared by
25+
a multiple modules. This option adds support for modules
26+
of this type.
27+
If unsure say N.
28+
1629
endmenu

src/library_manager/lib_manager.c

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,71 @@ static int lib_manager_unload_module(const struct sof_man_module *const mod)
138138
return 0;
139139
}
140140

141+
#ifdef CONFIG_LIBCODE_MODULE_SUPPORT
142+
/* There are modules marked as lib_code. This is code shared between several modules inside
143+
* the library. Load all lib_code modules with first none lib_code module load.
144+
*/
145+
static int lib_manager_load_libcode_modules(const uint32_t module_id,
146+
const struct sof_man_fw_desc *const desc)
147+
{
148+
struct ext_library *const ext_lib = ext_lib_get();
149+
const struct sof_man_module *module_entry = (struct sof_man_module *)
150+
((char *)desc + SOF_MAN_MODULE_OFFSET(0));
151+
const uint32_t lib_id = LIB_MANAGER_GET_LIB_ID(module_id);
152+
int ret, idx;
153+
154+
if (++ext_lib->mods_exec_load_cnt > 1)
155+
return 0;
156+
157+
for (idx = 0; idx < desc->header.num_module_entries; ++idx, ++module_entry) {
158+
if (module_entry->type.lib_code) {
159+
ret = lib_manager_load_module(lib_id << LIB_MANAGER_LIB_ID_SHIFT | idx,
160+
module_entry);
161+
if (ret < 0)
162+
goto err;
163+
}
164+
}
165+
166+
return 0;
167+
168+
err:
169+
for (--idx, --module_entry; idx >= 0; --idx, --module_entry) {
170+
if (module_entry->type.lib_code) {
171+
ret = lib_manager_unload_module(module_entry);
172+
if (ret < 0)
173+
goto err;
174+
}
175+
}
176+
177+
return ret;
178+
}
179+
180+
/* There are modules marked as lib_code. This is code shared between several modules inside
181+
* the library. Unload all lib_code modules with last none lib_code module unload.
182+
*/
183+
static int lib_manager_unload_libcode_modules(const uint32_t module_id,
184+
const struct sof_man_fw_desc *const desc)
185+
{
186+
struct ext_library *const ext_lib = ext_lib_get();
187+
const struct sof_man_module *module_entry = (struct sof_man_module *)
188+
((char *)desc + SOF_MAN_MODULE_OFFSET(0));
189+
int ret, idx;
190+
191+
if (--ext_lib->mods_exec_load_cnt > 0)
192+
return 0;
193+
194+
for (idx = 0; idx < desc->header.num_module_entries; ++idx, ++module_entry) {
195+
if (module_entry->type.lib_code) {
196+
ret = lib_manager_unload_module(module_entry);
197+
if (ret < 0)
198+
return ret;
199+
}
200+
}
201+
202+
return 0;
203+
}
204+
#endif /* CONFIG_LIBCODE_MODULE_SUPPORT */
205+
141206
static void __sparse_cache *lib_manager_get_instance_bss_address(uint32_t module_id,
142207
uint32_t instance_id,
143208
struct sof_man_module *mod)
@@ -225,11 +290,20 @@ uint32_t lib_manager_allocate_module(const struct comp_driver *drv,
225290
if (ret < 0)
226291
return 0;
227292

293+
#ifdef CONFIG_LIBCODE_MODULE_SUPPORT
294+
ret = lib_manager_load_libcode_modules(module_id, desc);
295+
if (ret < 0)
296+
goto err;
297+
#endif /* CONFIG_LIBCODE_MODULE_SUPPORT */
298+
228299
ret = lib_manager_allocate_module_instance(module_id, IPC4_INST_ID(ipc_config->id),
229300
base_cfg->is_pages, mod);
230301
if (ret < 0) {
231302
tr_err(&lib_manager_tr,
232303
"lib_manager_allocate_module(): module allocation failed: %d", ret);
304+
#ifdef CONFIG_LIBCODE_MODULE_SUPPORT
305+
lib_manager_unload_libcode_modules(module_id, desc);
306+
#endif /* CONFIG_LIBCODE_MODULE_SUPPORT */
233307
goto err;
234308
}
235309
return mod->entry_point;
@@ -257,6 +331,12 @@ int lib_manager_free_module(const struct comp_driver *drv,
257331
if (ret < 0)
258332
return ret;
259333

334+
#ifdef CONFIG_LIBCODE_MODULE_SUPPORT
335+
ret = lib_manager_unload_libcode_modules(module_id, desc);
336+
if (ret < 0)
337+
return ret;
338+
#endif /* CONFIG_LIBCODE_MODULE_SUPPORT */
339+
260340
ret = lib_manager_free_module_instance(module_id, IPC4_INST_ID(ipc_config->id), mod);
261341
if (ret < 0) {
262342
tr_err(&lib_manager_tr,

0 commit comments

Comments
 (0)