Skip to content

Commit fc52897

Browse files
committed
ptl: mmu: Enable module data processing in userspace
Introduce support for loading userspace modules. Allow the DP thread to process audio data in userspace. Signed-off-by: Jaroslaw Stelter <Jaroslaw.Stelter@intel.com> Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
1 parent 04d9b90 commit fc52897

File tree

3 files changed

+71
-30
lines changed

3 files changed

+71
-30
lines changed

src/audio/module_adapter/module/modules.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <sof/audio/module_adapter/module/generic.h>
99
#include <sof/audio/module_adapter/module/modules.h>
10+
#include <rtos/userspace_helper.h>
1011
#include <utilities/array.h>
1112
#include <iadk_module_adapter.h>
1213
#include <sof/lib_manager.h>
@@ -201,7 +202,7 @@ static int modules_reset(struct processing_module *mod)
201202
}
202203

203204
/* Processing Module Adapter API*/
204-
const struct module_interface processing_module_adapter_interface = {
205+
APP_TASK_DATA const struct module_interface processing_module_adapter_interface = {
205206
.init = modules_init,
206207
.prepare = modules_prepare,
207208
.process = modules_process,

src/audio/module_adapter/module_adapter.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <rtos/symbol.h>
2727
#include <limits.h>
2828
#include <stdint.h>
29+
#include <rtos/userspace_helper.h>
2930

3031
LOG_MODULE_REGISTER(module_adapter, CONFIG_SOF_LOG_LEVEL);
3132

@@ -165,10 +166,11 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv,
165166
err:
166167
#if CONFIG_IPC_MAJOR_4
167168
if (mod)
168-
rfree(mod->priv.cfg.input_pins);
169-
#endif
170-
rfree(mod);
171-
rfree(dev);
169+
module_driver_heap_free(drv->user_heap, mod->priv.cfg.input_pins);
170+
#endif /* CONFIG_IPC_MAJOR_4 */
171+
172+
module_driver_heap_free(drv->user_heap, mod);
173+
module_driver_heap_free(drv->user_heap, dev);
172174
return NULL;
173175
}
174176
EXPORT_SYMBOL(module_adapter_new);
@@ -1253,6 +1255,7 @@ void module_adapter_free(struct comp_dev *dev)
12531255
{
12541256
int ret;
12551257
struct processing_module *mod = comp_mod(dev);
1258+
const struct comp_driver *drv = dev->drv;
12561259
struct list_item *blist, *_blist;
12571260

12581261
comp_dbg(dev, "start");
@@ -1275,12 +1278,12 @@ void module_adapter_free(struct comp_dev *dev)
12751278
mod_free_all(mod);
12761279

12771280
#if CONFIG_IPC_MAJOR_4
1278-
rfree(mod->priv.cfg.input_pins);
1281+
module_driver_heap_free(drv->user_heap, mod->priv.cfg.input_pins);
12791282
#endif
12801283

1281-
rfree(mod->stream_params);
1282-
rfree(mod);
1283-
rfree(dev);
1284+
module_driver_heap_free(drv->user_heap, mod->stream_params);
1285+
module_driver_heap_free(drv->user_heap, mod);
1286+
module_driver_heap_free(drv->user_heap, dev);
12841287
}
12851288
EXPORT_SYMBOL(module_adapter_free);
12861289

src/library_manager/lib_manager.c

Lines changed: 58 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
// Copyright(c) 2022 Intel Corporation. All rights reserved.
44
//
55
// Author: Jaroslaw Stelter <jaroslaw.stelter@intel.com>
6-
// Pawel Dobrowolski<pawelx.dobrowolski@intel.com>
6+
// Pawel Dobrowolski <pawelx.dobrowolski@intel.com>
7+
// Adrian Warecki <adrian.warecki@intel.com>
78

89
/*
910
* Dynamic module loading functions.
@@ -18,11 +19,13 @@
1819
#include <rtos/clk.h>
1920
#include <rtos/sof.h>
2021
#include <rtos/spinlock.h>
22+
#include <rtos/userspace_helper.h>
2123
#include <sof/lib/cpu-clk-manager.h>
2224
#include <sof/lib_manager.h>
2325
#include <sof/llext_manager.h>
2426
#include <sof/audio/module_adapter/module/generic.h>
2527
#include <sof/audio/module_adapter/module/modules.h>
28+
#include <sof/audio/module_adapter/library/userspace_proxy.h>
2629
#include <utilities/array.h>
2730
#include <system_agent.h>
2831
#include <native_system_agent.h>
@@ -492,14 +495,19 @@ const struct sof_man_module *lib_manager_get_module_manifest(const uint32_t modu
492495
* \param[in] module_entry_point - Entry point address of the module.
493496
* \param[in] agent - Function pointer to the system agent start function.
494497
* \param[out] agent_interface - Pointer to store the module interface returned by the system agent.
498+
* \param[out] userspace - Pointer to store the userspace module proxy context.
499+
* \param[out] ops - Pointer to store pointer to the module interface structure.
495500
*
496501
* \return Error code returned by the system agent, 0 on success.
497502
*/
498503
static int lib_manager_start_agent(const struct comp_driver *drv, const uint32_t component_id,
504+
const struct sof_man_module *mod_manifest,
499505
const struct ipc_config_process *args,
500506
const uintptr_t module_entry_point,
501507
const system_agent_start_fn agent,
502-
const void **agent_interface)
508+
const void **agent_interface,
509+
struct userspace_context **userspace,
510+
const struct module_interface **ops)
503511
{
504512
const uint32_t module_id = IPC4_MOD_ID(component_id);
505513
const uint32_t instance_id = IPC4_INST_ID(component_id);
@@ -511,6 +519,18 @@ static int lib_manager_start_agent(const struct comp_driver *drv, const uint32_t
511519
/* Intel modules expects DW size here */
512520
mod_cfg.size = args->size >> 2;
513521

522+
#if CONFIG_USERSPACE
523+
/* If drv->user_heap is allocated, it means the module is userspace. */
524+
if (drv->user_heap) {
525+
ret = userspace_proxy_create(userspace, drv, mod_manifest, agent,
526+
module_entry_point, module_id, instance_id, 0,
527+
log_handle, &mod_cfg, agent_interface, ops);
528+
if (ret)
529+
tr_err(&lib_manager_tr, "userspace_proxy_create failed! %d", ret);
530+
return ret;
531+
}
532+
#endif /* CONFIG_USERSPACE */
533+
514534
ret = agent(module_entry_point, module_id, instance_id, 0, log_handle, &mod_cfg,
515535
agent_interface);
516536
if (ret)
@@ -580,14 +600,22 @@ static struct comp_dev *lib_manager_module_create(const struct comp_driver *drv,
580600
const struct sof_man_fw_desc *const desc = lib_manager_get_library_manifest(config->id);
581601
const struct ipc_config_process *args = (struct ipc_config_process *)spec;
582602
const uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(config->id);
583-
const struct module_interface *ops = NULL;
603+
struct userspace_context *userspace;
604+
const struct module_interface *ops;
584605
const struct sof_man_module *mod;
585606
system_agent_start_fn agent;
586607
void *adapter_priv = NULL;
587608
const void **agent_iface;
588609
struct comp_dev *dev;
589610
int ret;
590611

612+
#ifdef CONFIG_USERSPACE
613+
if (drv->user_heap && config->proc_domain != COMP_PROCESSING_DOMAIN_DP) {
614+
tr_err(&lib_manager_tr, "Userspace supports only DP modules.");
615+
return NULL;
616+
}
617+
#endif
618+
591619
tr_dbg(&lib_manager_tr, "start");
592620
if (!desc) {
593621
tr_err(&lib_manager_tr, "Error: Couldn't find loadable module with id %u.",
@@ -619,29 +647,29 @@ static struct comp_dev *lib_manager_module_create(const struct comp_driver *drv,
619647
agent = &native_system_agent_start;
620648
agent_iface = (const void **)&ops;
621649
break;
650+
#if CONFIG_INTEL_MODULES
622651
case MOD_TYPE_IADK:
623652
agent = &system_agent_start;
624-
/* processing_module_adapter_interface is already assigned to drv->adapter_ops by
625-
* the lib_manager_prepare_module_adapter function.
626-
*/
653+
ops = &processing_module_adapter_interface;
627654
agent_iface = (const void **)&adapter_priv;
628655
break;
656+
#endif
629657
case MOD_TYPE_INVALID:
630658
goto err;
631659
}
632660

633661
/* At this point module resources are allocated and it is moved to L2 memory. */
634662
if (agent) {
635-
ret = lib_manager_start_agent(drv, config->id, args, module_entry_point, agent,
636-
agent_iface);
663+
ret = lib_manager_start_agent(drv, config->id, mod, args, module_entry_point, agent,
664+
agent_iface, &userspace, &ops);
637665
if (ret)
638666
goto err;
639667
}
640668

641-
if (ops && comp_set_adapter_ops(drv, ops) < 0)
669+
if (comp_set_adapter_ops(drv, ops) < 0)
642670
goto err;
643671

644-
dev = module_adapter_new_ext(drv, config, spec, adapter_priv, NULL);
672+
dev = module_adapter_new_ext(drv, config, spec, adapter_priv, userspace);
645673
if (!dev)
646674
goto err;
647675

@@ -694,18 +722,16 @@ static void lib_manager_prepare_module_adapter(struct comp_driver *drv, const st
694722
drv->ops.dai_ts_start = module_adapter_ts_start_op;
695723
drv->ops.dai_ts_stop = module_adapter_ts_stop_op;
696724
drv->ops.dai_ts_get = module_adapter_ts_get_op;
697-
#if CONFIG_INTEL_MODULES
698-
drv->adapter_ops = &processing_module_adapter_interface;
699-
#endif
700725
}
701726

702727
int lib_manager_register_module(const uint32_t component_id)
703728
{
704-
struct comp_driver_info *new_drv_info;
705-
struct comp_driver *drv = NULL;
706729
const struct sof_man_module *mod = lib_manager_get_module_manifest(component_id);
707730
const struct sof_uuid *uid = (struct sof_uuid *)&mod->uuid;
708-
int ret;
731+
struct comp_driver_info *new_drv_info;
732+
struct sys_heap *drv_heap = NULL;
733+
struct comp_driver *drv = NULL;
734+
int ret = -ENOMEM;
709735

710736
if (!mod) {
711737
tr_err(&lib_manager_tr, "Error: Couldn't find loadable module with id %u.",
@@ -722,13 +748,23 @@ int lib_manager_register_module(const uint32_t component_id)
722748
return -ENOMEM;
723749
}
724750

725-
drv = rzalloc(SOF_MEM_FLAG_KERNEL | SOF_MEM_FLAG_COHERENT,
726-
sizeof(struct comp_driver));
751+
#if CONFIG_USERSPACE
752+
if (mod->type.user_mode) {
753+
drv_heap = module_driver_heap_init();
754+
if (!drv_heap) {
755+
tr_err(&lib_manager_tr, "failed to allocate driver heap!");
756+
goto cleanup;
757+
}
758+
}
759+
#endif /* CONFIG_USERSPACE */
760+
761+
drv = module_driver_heap_rmalloc(drv_heap, SOF_MEM_FLAG_KERNEL | SOF_MEM_FLAG_COHERENT,
762+
sizeof(struct comp_driver));
727763
if (!drv) {
728764
tr_err(&lib_manager_tr, "failed to allocate comp_driver");
729-
ret = -ENOMEM;
730765
goto cleanup;
731766
}
767+
drv->user_heap = drv_heap;
732768

733769
lib_manager_prepare_module_adapter(drv, uid);
734770

@@ -741,8 +777,9 @@ int lib_manager_register_module(const uint32_t component_id)
741777

742778
cleanup:
743779
if (ret < 0) {
744-
rfree(drv);
745-
rfree(new_drv_info);
780+
module_driver_heap_free(drv_heap, drv);
781+
module_driver_heap_free(drv_heap, new_drv_info);
782+
module_driver_heap_remove(drv_heap);
746783
}
747784

748785
return ret;

0 commit comments

Comments
 (0)