diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index 48906bada70f..885291a74200 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -247,6 +247,11 @@ void *z_impl_mod_alloc_ext(struct processing_module *mod, uint32_t flags, size_t struct module_resources *res = &mod->priv.resources; struct module_resource *container; + if (!size) { + comp_err(mod->dev, "requested allocation of 0 bytes."); + return NULL; + } + k_mutex_lock(&mod_res_lock, K_FOREVER); container = container_get(mod); @@ -255,13 +260,6 @@ void *z_impl_mod_alloc_ext(struct processing_module *mod, uint32_t flags, size_t return NULL; } - if (!size) { - comp_err(mod->dev, "requested allocation of 0 bytes."); - container_put(mod, container); - k_mutex_unlock(&mod_res_lock); - return NULL; - } - /* Allocate memory for module */ void *ptr = sof_ctx_alloc(res->alloc, flags, size, alignment); @@ -294,12 +292,33 @@ EXPORT_SYMBOL(z_impl_mod_alloc_ext); * Like comp_data_blob_handler_new() but the handler is automatically freed. */ #if CONFIG_COMP_BLOB +static bool mod_data_blob_find(void *data, void *arg) +{ + struct comp_data_blob_handler **bhp = arg; + struct module_resource *container = data; + + if (container->type != MOD_RES_BLOB_HANDLER) + return false; + + *bhp = container->bhp; + return true; +} + struct comp_data_blob_handler *z_impl_mod_data_blob_handler_new(struct processing_module *mod) { + struct module_resources *res = &mod->priv.resources; struct comp_data_blob_handler *bhp; struct module_resource *container; k_mutex_lock(&mod_res_lock, K_FOREVER); + int ret = objpool_iterate(&res->objpool, mod_data_blob_find, &bhp); + + if (!ret) { + k_mutex_unlock(&mod_res_lock); + /* data blob already exists */ + comp_warn(mod->dev, "Returning existing data blob"); + return bhp; + } container = container_get(mod); if (!container) { @@ -322,6 +341,26 @@ struct comp_data_blob_handler *z_impl_mod_data_blob_handler_new(struct processin return bhp; } EXPORT_SYMBOL(z_impl_mod_data_blob_handler_new); + +int z_impl_mod_data_blob_set(struct processing_module *mod, + enum module_cfg_fragment_position pos, uint32_t data_offset_size, + const uint8_t *fragment_in, size_t fragment_size) +{ + struct module_resources *res = &mod->priv.resources; + struct comp_data_blob_handler *bhp = NULL; + + k_mutex_lock(&mod_res_lock, K_FOREVER); + int ret = objpool_iterate(&res->objpool, mod_data_blob_find, &bhp); + k_mutex_unlock(&mod_res_lock); + + if (ret < 0) + return ret; + + if (!bhp) + return -EFAULT; + + return comp_data_blob_set(bhp, pos, data_offset_size, fragment_in, fragment_size); +} #endif /** @@ -540,6 +579,24 @@ struct comp_data_blob_handler *z_vrfy_mod_data_blob_handler_new(struct processin return z_impl_mod_data_blob_handler_new(mod); } #include + +int z_vrfy_mod_data_blob_set(struct processing_module *mod, + enum module_cfg_fragment_position pos, uint32_t data_offset_size, + const uint8_t *fragment_in, size_t fragment_size) +{ + size_t h_size = 0; + uintptr_t h_start; + + K_OOPS(K_SYSCALL_MEMORY_WRITE(mod, sizeof(*mod))); + mod_heap_info(mod, &h_size, &h_start); + if (h_size) + K_OOPS(K_SYSCALL_MEMORY_WRITE(h_start, h_size)); + if (fragment_size) + K_OOPS(K_SYSCALL_MEMORY_READ(fragment_in, fragment_size)); + + return z_impl_mod_data_blob_set(mod, pos, data_offset_size, fragment_in, fragment_size); +} +#include #endif #endif diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index 26a02b6f2c99..c067028c0255 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -309,10 +309,25 @@ static inline void mod_ipc_msg_free(struct processing_module *mod, #if CONFIG_COMP_BLOB #if defined(__ZEPHYR__) && defined(CONFIG_SOF_FULL_ZEPHYR_APPLICATION) +/** + * \brief Module-managed wrapper for comp_data_blob_handler_new_ext(). + */ __syscall struct comp_data_blob_handler *mod_data_blob_handler_new(struct processing_module *mod); +/** + * \brief Module-managed wrapper for comp_data_blob_set(). + * + * Note, that only one data blob per module is allowed. + */ +__syscall int mod_data_blob_set(struct processing_module *mod, + enum module_cfg_fragment_position pos, uint32_t data_offset_size, + const uint8_t *fragment, size_t fragment_size); #else struct comp_data_blob_handler *z_impl_mod_data_blob_handler_new(struct processing_module *mod); +int z_impl_mod_data_blob_set(struct processing_module *mod, + enum module_cfg_fragment_position pos, uint32_t data_offset_size, + const uint8_t *fragment, size_t fragment_size); #define mod_data_blob_handler_new z_impl_mod_data_blob_handler_new +#define mod_data_blob_set z_impl_mod_data_blob_set #endif void mod_data_blob_handler_free(struct processing_module *mod, struct comp_data_blob_handler *dbh); #endif