Skip to content

Commit 752cbf2

Browse files
committed
llext: add support for files with multiple modules
Some components like mixin-mixout implement multiple modules internally. They should be handled by LLEXT as a single ELF object, including for use-counting. But at the SOF level they implement multiple module adapter drivers. Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
1 parent e2a1493 commit 752cbf2

File tree

1 file changed

+16
-8
lines changed

1 file changed

+16
-8
lines changed

src/library_manager/llext_manager.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -241,12 +241,13 @@ uintptr_t llext_manager_allocate_module(struct processing_module *proc,
241241
const void *ipc_specific_config)
242242
{
243243
struct sof_man_fw_desc *desc;
244-
struct sof_man_module *mod;
244+
struct sof_man_module *mod, *mod_array;
245245
int ret;
246246
uint32_t module_id = IPC4_MOD_ID(ipc_config->id);
247247
uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(module_id);
248248
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
249249
const struct sof_module_api_build_info *buildinfo;
250+
const struct sof_man_module_manifest *mod_manifest;
250251

251252
tr_dbg(&lib_manager_tr, "llext_manager_allocate_module(): mod_id: %#x",
252253
ipc_config->id);
@@ -258,10 +259,12 @@ uintptr_t llext_manager_allocate_module(struct processing_module *proc,
258259
return 0;
259260
}
260261

261-
mod = (struct sof_man_module *)((char *)desc + SOF_MAN_MODULE_OFFSET(entry_index));
262+
mod_array = (struct sof_man_module *)((char *)desc + SOF_MAN_MODULE_OFFSET(0));
263+
mod = mod_array + entry_index;
262264

263-
ret = llext_manager_link(desc, mod, module_id, &proc->priv, (const void **)&buildinfo,
264-
&ctx->mod_manifest);
265+
/* LLEXT linking is only needed once for all the modules in the library */
266+
ret = llext_manager_link(desc, mod_array, module_id, &proc->priv, (const void **)&buildinfo,
267+
&mod_manifest);
265268
if (ret < 0)
266269
return 0;
267270

@@ -274,6 +277,9 @@ uintptr_t llext_manager_allocate_module(struct processing_module *proc,
274277
return -ENOEXEC;
275278
}
276279

280+
/* ctx->mod_manifest points to the array of module manifests */
281+
ctx->mod_manifest = mod_manifest;
282+
277283
/* Map .text and the rest as .data */
278284
ret = llext_manager_load_module(module_id, mod);
279285
if (ret < 0)
@@ -288,24 +294,26 @@ uintptr_t llext_manager_allocate_module(struct processing_module *proc,
288294
}
289295
}
290296

291-
return ctx->mod_manifest->module.entry_point;
297+
return ctx->mod_manifest[entry_index].module.entry_point;
292298
}
293299

294300
int llext_manager_free_module(const uint32_t component_id)
295301
{
296302
const struct sof_man_module *mod;
297303
const uint32_t module_id = IPC4_MOD_ID(component_id);
304+
const unsigned int base_module_id = LIB_MANAGER_GET_LIB_ID(module_id) <<
305+
LIB_MANAGER_LIB_ID_SHIFT;
298306
int ret;
299307

300308
tr_dbg(&lib_manager_tr, "llext_manager_free_module(): mod_id: %#x", component_id);
301309

302-
mod = lib_manager_get_module_manifest(module_id);
310+
mod = lib_manager_get_module_manifest(base_module_id);
303311

304-
ret = llext_manager_unload_module(module_id, mod);
312+
ret = llext_manager_unload_module(base_module_id, mod);
305313
if (ret < 0)
306314
return ret;
307315

308-
ret = llext_manager_free_module_bss(module_id, mod);
316+
ret = llext_manager_free_module_bss(base_module_id, mod);
309317
if (ret < 0) {
310318
tr_err(&lib_manager_tr,
311319
"llext_manager_free_module(): free module bss failed: %d", ret);

0 commit comments

Comments
 (0)