Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dependency: add support for loading auxiliary code as LLEXT modules #9399

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/audio/module_adapter/module/modules.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ static int modules_init(struct processing_module *mod)
void *adapter;
int ret;

uintptr_t module_entry_point = lib_manager_allocate_module(mod, config, src_cfg);
uintptr_t module_entry_point = lib_manager_allocate_module(config, src_cfg);

if (module_entry_point == 0) {
comp_err(dev, "modules_init(), lib_manager_allocate_module() failed!");
Expand Down
3 changes: 0 additions & 3 deletions src/include/module/module/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ struct module_config {
#endif
};

struct llext;

/*
* A structure containing a module's private data, intended for its exclusive use.
*
Expand All @@ -60,7 +58,6 @@ struct module_data {
void *runtime_params;
struct module_memory memory; /**< memory allocated by module */
struct module_processing_data mpd; /**< shared data comp <-> module */
struct llext *llext; /**< Zephyr loadable extension context */
#endif /* SOF_MODULE_PRIVATE */
};

Expand Down
14 changes: 13 additions & 1 deletion src/include/module/module/llext.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
{ \
.module = { \
.name = manifest_name, \
.uuid = {mod_uuid}, \
.uuid = {mod_uuid}, \
.entry_point = (uint32_t)(entry), \
.instance_max_count = instances, \
.type = { \
Expand All @@ -21,6 +21,18 @@
} \
}

#define SOF_LLEXT_AUX_MANIFEST(manifest_name, entry, mod_uuid) \
{ \
.module = { \
.name = manifest_name, \
.uuid = {mod_uuid}, \
.entry_point = (uint32_t)(entry), \
.type = { \
.load_type = SOF_MAN_MOD_TYPE_LLEXT_AUX, \
}, \
} \
}

#define SOF_LLEXT_MOD_ENTRY(name, interface) \
static const struct module_interface *name##_llext_entry(void *mod_cfg, \
void *parent_ppl, void **mod_ptr) \
Expand Down
14 changes: 10 additions & 4 deletions src/include/sof/lib_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ enum {
LIB_MANAGER_TEXT,
LIB_MANAGER_DATA,
LIB_MANAGER_RODATA,
LIB_MANAGER_BSS,
LIB_MANAGER_N_SEGMENTS,
};

Expand All @@ -95,14 +96,20 @@ struct lib_manager_segment_desc {
size_t size;
};

struct llext;

struct lib_manager_module {
unsigned int start_idx;
unsigned int start_idx; /* Index of the first driver from this module in
* the library-global driver list */
const struct sof_man_module_manifest *mod_manifest;
struct llext *llext; /* Zephyr loadable extension context */
struct lib_manager_segment_desc segment[LIB_MANAGER_N_SEGMENTS];
unsigned int n_depend;
const char **depend;
};

struct lib_manager_mod_ctx {
void *base_addr;
void *base_addr; /* library storage address (DRAM) */
unsigned int n_mod;
struct lib_manager_module *mod;
};
Expand Down Expand Up @@ -188,8 +195,7 @@ struct processing_module;
* Function is responsible to allocate module in available free memory and assigning proper address.
* (WIP) These feature will contain module validation and proper memory management.
*/
uintptr_t lib_manager_allocate_module(struct processing_module *proc,
const struct comp_ipc_config *ipc_config,
uintptr_t lib_manager_allocate_module(const struct comp_ipc_config *ipc_config,
const void *ipc_specific_config);

/*
Expand Down
12 changes: 7 additions & 5 deletions src/include/sof/llext_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,23 @@ struct comp_ipc_config;

static inline bool module_is_llext(const struct sof_man_module *mod)
{
return mod->type.load_type == SOF_MAN_MOD_TYPE_LLEXT;
return mod->type.load_type == SOF_MAN_MOD_TYPE_LLEXT ||
mod->type.load_type == SOF_MAN_MOD_TYPE_LLEXT_AUX;
}

uintptr_t llext_manager_allocate_module(struct processing_module *proc,
const struct comp_ipc_config *ipc_config,
uintptr_t llext_manager_allocate_module(const struct comp_ipc_config *ipc_config,
const void *ipc_specific_config);

int llext_manager_free_module(const uint32_t component_id);

int llext_manager_add_library(uint32_t module_id);

bool comp_is_llext(struct comp_dev *comp);
#else
#define module_is_llext(mod) false
#define llext_manager_allocate_module(proc, ipc_config, ipc_specific_config) 0
#define llext_manager_allocate_module(ipc_config, ipc_specific_config) 0
#define llext_manager_free_module(component_id) 0
#define llext_unload(ext) 0
#define llext_manager_add_library(module_id) 0
#define comp_is_llext(comp) false
#endif

Expand Down
45 changes: 21 additions & 24 deletions src/library_manager/lib_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,7 @@ static int lib_manager_free_module_instance(uint32_t module_id, uint32_t instanc
return sys_mm_drv_unmap_region((__sparse_force void *)va_base, bss_size);
}

uintptr_t lib_manager_allocate_module(struct processing_module *proc,
const struct comp_ipc_config *ipc_config,
uintptr_t lib_manager_allocate_module(const struct comp_ipc_config *ipc_config,
const void *ipc_specific_config)
{
const struct sof_man_module *mod;
Expand All @@ -356,7 +355,7 @@ uintptr_t lib_manager_allocate_module(struct processing_module *proc,
}

if (module_is_llext(mod))
return llext_manager_allocate_module(proc, ipc_config, ipc_specific_config);
return llext_manager_allocate_module(ipc_config, ipc_specific_config);

ret = lib_manager_load_module(module_id, mod);
if (ret < 0)
Expand Down Expand Up @@ -419,8 +418,7 @@ int lib_manager_free_module(const uint32_t component_id)

#define PAGE_SZ 4096 /* equals to MAN_PAGE_SIZE used by rimage */

uintptr_t lib_manager_allocate_module(struct processing_module *proc,
const struct comp_ipc_config *ipc_config,
uintptr_t lib_manager_allocate_module(const struct comp_ipc_config *ipc_config,
const void *ipc_specific_config, const void **buildinfo)
{
tr_err(&lib_manager_tr, "Dynamic module allocation is not supported");
Expand Down Expand Up @@ -510,12 +508,10 @@ static struct comp_dev *lib_manager_module_create(const struct comp_driver *drv,
* Variable used by llext_manager to temporary store llext handle before creation
* a instance of processing_module.
*/
struct processing_module tmp_proc;
struct comp_dev *dev;

/* At this point module resources are allocated and it is moved to L2 memory. */
tmp_proc.priv.llext = NULL;
const uint32_t module_entry_point = lib_manager_allocate_module(&tmp_proc, config,
const uint32_t module_entry_point = lib_manager_allocate_module(config,
args->data);

if (!module_entry_point) {
Expand All @@ -540,33 +536,26 @@ static struct comp_dev *lib_manager_module_create(const struct comp_driver *drv,
}

dev = module_adapter_new(drv, config, spec);
if (dev) {
struct processing_module *mod = comp_mod(dev);

mod->priv.llext = tmp_proc.priv.llext;
} else {
if (!dev)
lib_manager_free_module(module_id);
}

return dev;
}

static void lib_manager_module_free(struct comp_dev *dev)
{
struct processing_module *mod = comp_mod(dev);
struct llext *llext = mod->priv.llext;
const struct comp_ipc_config *const config = &mod->dev->ipc_config;
const uint32_t module_id = config->id;
int ret;

/* This call invalidates dev, mod and config pointers! */
module_adapter_free(dev);

if (!llext || !llext_unload(&llext)) {
/* Free module resources allocated in L2 memory. */
ret = lib_manager_free_module(module_id);
if (ret < 0)
comp_err(dev, "lib_manager_free_module() failed!");
}
/* Free module resources allocated in L2 memory. */
ret = lib_manager_free_module(module_id);
if (ret < 0)
comp_err(dev, "lib_manager_free_module() failed!");
}

static void lib_manager_prepare_module_adapter(struct comp_driver *drv, const struct sof_uuid *uuid)
Expand Down Expand Up @@ -1044,14 +1033,22 @@ int lib_manager_load_library(uint32_t dma_id, uint32_t lib_id, uint32_t type)
rfree((__sparse_force void *)man_tmp_buffer);

cleanup:
#if CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL
core_kcps_adjust(cpu_get_id(), -(CLK_MAX_CPU_HZ / 1000));
#endif
rfree((void *)dma_ext->dma_addr);
lib_manager_dma_deinit(dma_ext, dma_id);
rfree(dma_ext);
_ext_lib->runtime_data = NULL;

uint32_t module_id = lib_id << LIB_MANAGER_LIB_ID_SHIFT;
const struct sof_man_module *mod = lib_manager_get_module_manifest(module_id);

if (module_is_llext(mod) && !ret)
/* LLEXT libraries need to be initialized upon loading */
ret = llext_manager_add_library(lib_id);

#if CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL
core_kcps_adjust(cpu_get_id(), -(CLK_MAX_CPU_HZ / 1000));
#endif

if (!ret)
tr_info(&ipc_tr, "loaded library id: %u", lib_id);

Expand Down
Loading
Loading