Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
111 commits
Select commit Hold shift + click to select a range
ee1a56e
(---section submitted PRs START)
kv2019i Mar 23, 2026
af11bb5
(---section submitted PRs STOP)
kv2019i Mar 23, 2026
aaaacc2
(---section: user LL infra START)
kv2019i Mar 27, 2026
937fb9c
ipc: move standalone-test check later in ipc_init()
kv2019i Feb 10, 2026
0fbee30
ipc: ipc-helper: use list_mutex to guard buffer list in userspace LL
kv2019i Feb 13, 2026
b11d04d
zephyr: lib: make sof_heap_alloc/free system calls
kv2019i May 8, 2026
0b2476a
schedule: zephyr_ll_user: make the heap accessible from user-space
kv2019i Feb 13, 2026
8a5f4b3
schedule: zephyr_ll: convert pdata->sem into a dynamic object
kv2019i Feb 13, 2026
86f6f05
schedule: zephyr_ll: replace dynamic k_sem with embedded sys_sem
kv2019i Apr 22, 2026
80c22ab
schedule: zephyr_ll_user: move user accessible heap to common partition
kv2019i Feb 13, 2026
93c7da0
app: overlays: ptl: add ll_usespace_overlay.conf
kv2019i Apr 14, 2026
f365dcc
app: overlays: ptl: disable cold/dram execution for now
kv2019i May 6, 2026
7d2643f
app: overlays: ptl: set CONFIG_SOF_ZEPHYR_LL_USER_HEAP_SIZE
kv2019i Apr 29, 2026
f516717
(---section: user LL infra STOP)
kv2019i Mar 27, 2026
8baddd9
(---section host-zephyr START)
kv2019i Feb 19, 2026
ba197f6
zephyr: userspace: sof_dma: allow circular SG lists
kv2019i Feb 19, 2026
67224a0
zephyr: lib: dma: make DMA platform data available to user-space
kv2019i Feb 13, 2026
807cc62
audio: host-zephyr: select heap when allocating host buffers
kv2019i Feb 13, 2026
b1545b1
audio: host-zephyr: pass component heap to dma_sg_alloc
kv2019i Feb 16, 2026
192fd51
audio: host-zephyr: ensure host data heap is set
kv2019i Feb 16, 2026
edbfd5d
audio: host-zephyr: make component usable from user-space
kv2019i Apr 10, 2026
b2036d5
audio: host-zephyr: use module context for allocations
kv2019i May 8, 2026
7dd7173
(---section host-zephyr STOP)
kv2019i Feb 19, 2026
1d895ff
(---section dai-zephyr START)
kv2019i Feb 19, 2026
8c2c35a
audio: dai-zephyr: make memory allocations user-space compatible
kv2019i May 5, 2026
be692b0
lib: dai: make dai_get() and dai_put() compatible with user-space
kv2019i Feb 17, 2026
075a7be
audio: dai-zephyr: convert spinlock into mutex for properties
kv2019i Feb 17, 2026
8bbb411
audio: dai-zephyr: migrate to use dai_get_properties_copy()
kv2019i Feb 18, 2026
1dde59b
dai: zephyr: replace k_mutex with sof_umutex for DAI lock
kv2019i Apr 22, 2026
f72341e
audio: dai-zephyr: use module context for allocations
kv2019i May 8, 2026
95458c5
(---section dai-zephyr STOP)
kv2019i Feb 19, 2026
d91d899
(---section audio module infra START)
kv2019i Mar 3, 2026
8a01f4d
audio: module_adapter: alloc from LL user heap if LL run in user
kv2019i May 5, 2026
a736a8c
audio: copier: export copier endpoint ops to user-space
kv2019i Feb 26, 2026
db61632
(---section schduler changes START)
kv2019i Mar 3, 2026
af015d9
schedule: zephyr_ll: add zephyr_ll_task_free()
kv2019i Feb 26, 2026
6d66cb1
schedule: zephyr_ll: add zephyr_ll_grant_access()
kv2019i Feb 26, 2026
ea08730
schedule: zephyr_ll_user: make double-mapping conditional
kv2019i Mar 4, 2026
856aee9
schedule: allocate the scheduler objects with sof_heap_alloc
kv2019i Feb 26, 2026
9e0cade
WIP: schedule: limit user-LL to core0
kv2019i Feb 26, 2026
453c7ca
zephyr: schedule: allow user-space to access scheduler list
kv2019i Feb 26, 2026
49e28e7
zephyr: wrapper: modify platform_dai_wallclock() for user-space
kv2019i Feb 26, 2026
b58042b
schedule: add scheduler_init_context() and scheduler_free_context()
kv2019i Feb 27, 2026
653e221
schedule: zephyr_ll: implement scheduler_init_context()
kv2019i Feb 26, 2026
a361339
schedule: ll_schedule_domain: add domain_thread_init/free ops
kv2019i Mar 4, 2026
5f0f5a3
schedule: zephyr_ll: implement thread_init/free domain ops
kv2019i May 5, 2026
e4f25e2
schedule: zephyr_ll: ISR check is not needed when LL in user-space
kv2019i Mar 31, 2026
7d7980d
zephyr: userspace_helper: add new sys_user_heap_init()
kv2019i Mar 31, 2026
369aca3
sched: ll_user: add independent heap size config for LL userspace
kv2019i Apr 29, 2026
7f6e7a5
(---section schduler changes END)
kv2019i Mar 3, 2026
c32f443
(---section audio-user PRs START)
kv2019i Mar 25, 2026
6efbbbf
schedule: zephyr_domain: use a different thread name for user LL
kv2019i Mar 24, 2026
eee2dfc
WIP: audio: module_adapter: use correct heap when freeing
kv2019i May 5, 2026
0abb89f
coherent: disable core debug checks for user-space builds
kv2019i Mar 20, 2026
536bcd4
audio: place component driver list in user-space accessible partition
kv2019i Mar 24, 2026
f04d942
audio: module_adapter: make adapter buffering user-space compatible
kv2019i Mar 24, 2026
157c3f2
audio: pipeline: use LL scheduler mutex for userspace pipeline triggers
kv2019i Feb 26, 2026
8213515
rtos: umutex.h: add new locking interface
kv2019i May 19, 2026
e60472c
schedule: zephyr_ll: replace k_mutex with sof_umutex for scheduler lock
kv2019i Apr 22, 2026
edd691d
audio: pipeline: change locking strategy for user LL builds
kv2019i May 12, 2026
afa27bf
audio: buffer: move dp_heap_user lifecycle to IPC and module adapter
kv2019i May 5, 2026
e7ab992
Revert "audio: buffer: move dp_heap_user lifecycle to IPC and module …
kv2019i May 5, 2026
cb1ff28
audio: host-zepher: add HOST_DMA_IPC_POSITION_UPDATES Kconfig
kv2019i May 5, 2026
3873436
audio: copier_host: make FPI sync group availble to user-space
kv2019i Mar 31, 2026
516ca47
audio: copier: avoid IRQ lock/unlock in chmap code
kv2019i Mar 31, 2026
977ec63
audio: module_adapter: avoid IRQ lock/unlock in prepare()
kv2019i Mar 31, 2026
dea3c12
audio: module_adapter: make data_blob compatible with user-space
kv2019i Apr 14, 2026
09be5f6
audio: module-adapter: make generic.c user-space compatible
kv2019i Apr 16, 2026
7bef67b
audio: module_adapter: use module context for allocations
kv2019i May 8, 2026
be3e52c
audio: module: generic: use module context for blob allocations
kv2019i May 8, 2026
40106e7
audio: make comp_drivers_get() accessible from user-space
kv2019i Apr 15, 2026
e8ae919
dai: turn dai_get_device() into a syscall
kv2019i Apr 15, 2026
430de32
audio: chain_dma: add user-space memory and scheduling support
kv2019i Apr 21, 2026
f4d4027
audio: chain-dma: use module context for allocations
kv2019i May 8, 2026
a54ab38
(---section audio user PRs STOP)
kv2019i Mar 25, 2026
db732fe
(---section: IPC user support START)
kv2019i Mar 17, 2026
c3a204f
userspace: split ipc files into user and kernel features. REVISIT memcpy
kv2019i Apr 1, 2026
9af1841
ipc4: helper: use LL scheduler lock for userspace builds
kv2019i Mar 26, 2026
4217e3f
WIP: ipc: implement user-space IPC handling for CREATE_PIPELINE
kv2019i Mar 12, 2026
bdb8931
WIP: ipc: ipc4: route PIPELINE_DELETE to user-space handler
kv2019i Mar 30, 2026
24c559e
ipc: make IPC stack thread size configurable
Apr 1, 2026
ebbcda9
ipc: ipc4: use sof_heap_alloc in ipc4_add_comp_dev()
kv2019i May 20, 2026
3bfa5e4
ipc: turn ipc_msg_reply() into a system call
kv2019i Mar 30, 2026
9216c04
ipc: ipc4: use correct API to get DMA status
kv2019i Mar 19, 2026
acf9aa1
ipc: ipc4: dai: fix direct use of DMA driver calls
kv2019i May 20, 2026
88a6d2d
ipc: use application heap for IPC pipeline and component allocations
kv2019i Mar 20, 2026
4ba796d
ipc4: make fw_reg mutex available to user-space
kv2019i Apr 15, 2026
296951d
ipc: ipc4: helper: make ipc4_search_for_drv() userspace compatible
kv2019i Mar 31, 2026
79610eb
WIP: schedule: add multi-core support for user-space LL scheduler
kv2019i Apr 22, 2026
0f234df
ipc: ipc-helper: trace context not used in user-space
kv2019i Apr 13, 2026
38cdba2
ipc: ipc4: use the core number from IPC config
kv2019i May 5, 2026
89db58f
ipc: ipc4: helper: enable limited ipc_comp_connect() in user-space
kv2019i Apr 13, 2026
cec85b6
WIP: ipc: ipc4: route MOD_CONFIG_GET/SET to user-space handler
kv2019i Apr 10, 2026
106fd7a
WIP: ipc: ipc4: route MOD_BIND/UNBIND to user-space handler
kv2019i Apr 10, 2026
ce00095
WIP: ipc: ipc4: route MOD_INIT_INSTANCE to user-space handler
kv2019i May 11, 2026
5621a4b
WIP: ipc: ipc4: route GLB_SET_PIPELINE_STATE to user-space handler
kv2019i Apr 16, 2026
540be7d
WIP: ipc: ipc4: route MOD_LARGE_CONFIG_GET/SET user-space
kv2019i Apr 16, 2026
2aacc17
(---section: IPC user support STOP)
kv2019i Mar 27, 2026
65d15e6
(---section: IPC notifications START)
kv2019i May 8, 2026
93164ee
ipc: turn ipc_msg_send() into a system call if SOF_USERSPACE_LL=y
Apr 20, 2026
57d78f6
ipc: make IPC message allocation userspace-safe
Apr 21, 2026
b60334f
ipc4: notification: make send_resource_notif() a syscall
Apr 23, 2026
3995a20
(---section: IPC notifications STOP)
kv2019i May 8, 2026
d355b9b
ipc: add a mod_alloc_ctx context to IPC context
kv2019i May 8, 2026
8586643
zephyr: lib: make vregion_alloc/free system calls
kv2019i May 19, 2026
44102ae
(---section test-case START)
kv2019i Feb 19, 2026
b910dbc
zephyr: test: userspace: add pipeline_two_components test
kv2019i Apr 22, 2026
1117cde
(---section WIP mandatory changes START)
kv2019i Feb 19, 2026
750cf80
audio: pipeline: enable position reporting for user-space pipelines
kv2019i Mar 17, 2026
bf52f08
WIP: ipc: expose coldrodata to IPC user thread
kv2019i Apr 16, 2026
04575fd
HACK: audio: collection of feature limitations to run LL in user
kv2019i Feb 26, 2026
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
27 changes: 27 additions & 0 deletions app/overlays/ptl/ll_userspace_overlay.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
CONFIG_SOF_USERSPACE_LL=y

# Problem with DSP panics due to illegal instruction hit in user-space if cold
# store execution is enabled. Disable it for now until rootcause is found.
CONFIG_COLD_STORE_EXECUTE_DRAM=n

# temporary (but for now mandatory) settings
CONFIG_SOF_ZEPHYR_USERSPACE_MODULE_HEAP_SIZE=16384
CONFIG_SOF_ZEPHYR_LL_USER_HEAP_SIZE=0x1f000

# make the drivers work in user-space
CONFIG_SOF_USERSPACE_INTERFACE_DMA=y
CONFIG_DAI_USERSPACE=y

# disable features that don't work in user-space (at least yet)
CONFIG_COLD_STORE_EXECUTE_DEBUG=n
CONFIG_CROSS_CORE_STREAM=n
CONFIG_INTEL_ADSP_MIC_PRIVACY=n
CONFIG_XRUN_NOTIFICATIONS_ENABLE=n
CONFIG_SOF_BOOT_TEST_ALLOWED=n
CONFIG_SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS=n
CONFIG_SOF_TELEMETRY_IO_PERFORMANCE_MEASUREMENTS=n

# disable llext (hits privilege issues in user-space now)
CONFIG_LLEXT_STORAGE_WRITABLE=n
CONFIG_LLEXT_EXPERIMENTAL=n
CONFIG_MODULES=n
48 changes: 48 additions & 0 deletions posix/include/rtos/mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,52 @@ static inline int sys_mutex_unlock(struct sys_mutex *mutex)
return 0;
}

/* provide a no-op implementation for zephyr/sys/sem.h */

struct sys_sem {
};

static inline int sys_sem_init(struct sys_sem *sem, unsigned int initial_count,
unsigned int limit)
{
return 0;
}

static inline int sys_sem_give(struct sys_sem *sem)
{
return 0;
}

static inline int sys_sem_take(struct sys_sem *sem, k_timeout_t timeout)
{
return 0;
}

/**
* @brief User-space accessible mutex stub for host/testbench builds.
*/
struct sof_umutex {
struct k_mutex mutex; /**< Inline k_mutex for POSIX (no dynamic alloc needed) */
};

static inline int sof_umutex_init(struct sof_umutex *umutex)
{
return k_mutex_init(&umutex->mutex);
}

static inline int sof_umutex_lock(struct sof_umutex *umutex, k_timeout_t timeout)
{
return k_mutex_lock(&umutex->mutex, timeout);
}

static inline int sof_umutex_unlock(struct sof_umutex *umutex)
{
return k_mutex_unlock(&umutex->mutex);
}

static inline void sof_umutex_free(struct sof_umutex *umutex)
{
/* No-op on POSIX — no kernel objects to free */
}

#endif
13 changes: 13 additions & 0 deletions posix/include/rtos/umutex.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: BSD-3-Clause
//
// Copyright(c) 2026 Intel Corporation.
//

#ifndef __POSIX_RTOS_UMUTEX_H__
#define __POSIX_RTOS_UMUTEX_H__

#include <rtos/mutex.h>

/* sof_umutex type and operations are defined in rtos/mutex.h for POSIX */

#endif /* __POSIX_RTOS_UMUTEX_H__ */
8 changes: 8 additions & 0 deletions src/audio/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ config HOST_DMA_STREAM_SYNCHRONIZATION
for each group, different than the default one determined by the system tick frequency.
This feature will allow host lower power consumption in scenarios with deep buffering.

config HOST_DMA_IPC_POSITION_UPDATES
bool "Support for stream position updates via IPC messages"
default y if IPC_MAJOR_3
help
Support firmware functionality to report stream position updates
by sending a IPC message whenever one period of audio is transfferred.
Most platforms provide more efficient ways to query the DMA status.

config COMP_CHAIN_DMA
bool "Chain DMA component"
depends on IPC_MAJOR_4
Expand Down
94 changes: 93 additions & 1 deletion src/audio/chain_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
#include <ipc/dai.h>
#include <ipc4/gateway.h>
#include <sof/schedule/ll_schedule.h>
#include <sof/schedule/ll_schedule_domain.h>
#include <sof/schedule/schedule.h>
#include <rtos/alloc.h>
#include <rtos/task.h>
#include <sof/lib/dma.h>
#include <sof/lib/memory.h>
Expand Down Expand Up @@ -59,6 +61,15 @@ struct chain_dma_data {
bool xrun_notification_sent;
#endif

#ifdef CONFIG_SOF_USERSPACE_LL
/** Kernel workqueue scheduling for chain DMA in userspace builds.
* Chain DMA needs kernel context for DMA operations, so it cannot
* run on the user-space LL timer thread.
*/
struct k_work_delayable dma_work;
bool stopped;
#endif

/* local host DMA config */
struct sof_dma *dma_host;
struct dma_chan_data *chan_host;
Expand Down Expand Up @@ -268,6 +279,25 @@ static enum task_state chain_task_run(void *data)
return SOF_TASK_STATE_RESCHEDULE;
}

#ifdef CONFIG_SOF_USERSPACE_LL
/** Kernel workqueue handler for chain DMA periodic task.
* Runs chain_task_run() in kernel context and reschedules if needed.
*/
static void chain_dma_work_handler(struct k_work *work)
{
struct k_work_delayable *dwork = k_work_delayable_from_work(work);
struct chain_dma_data *cd = CONTAINER_OF(dwork, struct chain_dma_data, dma_work);
enum task_state state;

if (cd->stopped)
return;

state = chain_task_run(cd);
if (state == SOF_TASK_STATE_RESCHEDULE && !cd->stopped)
k_work_reschedule(dwork, K_USEC(LL_TIMER_PERIOD_US));
}
#endif

static int chain_task_start(struct comp_dev *dev)
{
struct chain_dma_data *cd = comp_get_drvdata(dev);
Expand Down Expand Up @@ -309,6 +339,12 @@ static int chain_task_start(struct comp_dev *dev)
}
}

#ifdef CONFIG_SOF_USERSPACE_LL
cd->stopped = false;
k_work_init_delayable(&cd->dma_work, chain_dma_work_handler);
k_work_reschedule(&cd->dma_work, K_NO_WAIT);
cd->chain_task.state = SOF_TASK_STATE_QUEUED;
#else
ret = schedule_task_init_ll(&cd->chain_task, SOF_UUID(chain_dma_uuid),
SOF_SCHEDULE_LL_TIMER, SOF_TASK_PRI_HIGH,
chain_task_run, cd, 0, 0);
Expand All @@ -323,27 +359,38 @@ static int chain_task_start(struct comp_dev *dev)
schedule_task_free(&cd->chain_task);
goto error_task;
}
#endif

pm_policy_state_lock_get(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES);

return 0;

#ifndef CONFIG_SOF_USERSPACE_LL
error_task:
chain_host_stop(dev);
chain_link_stop(dev);

return ret;
#endif
}

static int chain_task_pause(struct comp_dev *dev)
{
struct chain_dma_data *cd = comp_get_drvdata(dev);
int ret, ret2;

#ifdef CONFIG_SOF_USERSPACE_LL
if (cd->chain_task.state == SOF_TASK_STATE_FREE)
return 0;

cd->stopped = true;
cd->first_data_received = false;
#else
if (cd->chain_task.state == SOF_TASK_STATE_FREE)
return 0;

cd->first_data_received = false;
#endif
if (cd->stream_direction == SOF_IPC_STREAM_PLAYBACK) {
ret = chain_host_stop(dev);
ret2 = chain_link_stop(dev);
Expand All @@ -354,7 +401,12 @@ static int chain_task_pause(struct comp_dev *dev)
if (!ret)
ret = ret2;

#ifdef CONFIG_SOF_USERSPACE_LL
k_work_cancel_delayable_sync(&cd->dma_work, &(struct k_work_sync){});
cd->chain_task.state = SOF_TASK_STATE_FREE;
#else
schedule_task_free(&cd->chain_task);
#endif
pm_policy_state_lock_put(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES);

return ret;
Expand Down Expand Up @@ -503,6 +555,7 @@ __cold static int chain_task_init(struct comp_dev *dev, uint8_t host_dma_id, uin
uint32_t fifo_size)
{
struct chain_dma_data *cd = comp_get_drvdata(dev);
struct mod_alloc_ctx *alloc_ctx = NULL;
uint32_t addr_align;
size_t buff_size;
void *buff_addr;
Expand Down Expand Up @@ -581,8 +634,14 @@ __cold static int chain_task_init(struct comp_dev *dev, uint8_t host_dma_id, uin
}

fifo_size = ALIGN_UP_INTERNAL(fifo_size, addr_align);

#ifdef CONFIG_SOF_USERSPACE_LL
alloc_ctx = ipc_get()->ll_alloc;
#endif

/* allocate not shared buffer */
cd->dma_buffer = buffer_alloc(NULL, fifo_size, SOF_MEM_FLAG_USER | SOF_MEM_FLAG_DMA,
cd->dma_buffer = buffer_alloc(alloc_ctx, fifo_size,
SOF_MEM_FLAG_USER | SOF_MEM_FLAG_DMA,
addr_align, BUFFER_USAGE_NOT_SHARED);

if (!cd->dma_buffer) {
Expand Down Expand Up @@ -642,14 +701,31 @@ __cold static struct comp_dev *chain_task_create(const struct comp_driver *drv,
if (host_dma_id >= max_chain_number)
return NULL;

#ifdef CONFIG_SOF_USERSPACE_LL
dev = sof_heap_alloc(sof_sys_user_heap_get(),
SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT,
sizeof(*dev), 0);
if (!dev)
return NULL;

memset(dev, 0, sizeof(*dev));
comp_init(drv, dev, sizeof(*dev));
#else
dev = comp_alloc(drv, sizeof(*dev));
if (!dev)
return NULL;
#endif

#ifdef CONFIG_SOF_USERSPACE_LL
cd = sof_heap_alloc(sof_sys_user_heap_get(), SOF_MEM_FLAG_USER, sizeof(*cd), 0);
#else
cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd));
#endif
if (!cd)
goto error;

memset(cd, 0, sizeof(*cd));

cd->first_data_received = false;
cd->cs = scs ? 2 : 4;
cd->chain_task.state = SOF_TASK_STATE_INIT;
Expand All @@ -660,9 +736,17 @@ __cold static struct comp_dev *chain_task_create(const struct comp_driver *drv,
if (!ret)
return dev;

#ifdef CONFIG_SOF_USERSPACE_LL
sof_heap_free(sof_sys_user_heap_get(), cd);
#else
rfree(cd);
#endif
error:
#ifdef CONFIG_SOF_USERSPACE_LL
sof_heap_free(sof_sys_user_heap_get(), dev);
#else
comp_free_device(dev);
#endif
return NULL;
}

Expand All @@ -673,8 +757,16 @@ __cold static void chain_task_free(struct comp_dev *dev)
assert_can_be_cold();

chain_release(dev);
#ifdef CONFIG_SOF_USERSPACE_LL
sof_heap_free(sof_sys_user_heap_get(), cd);
#else
rfree(cd);
#endif
#ifdef CONFIG_SOF_USERSPACE_LL
sof_heap_free(sof_sys_user_heap_get(), dev);
#else
comp_free_device(dev);
#endif
}

static const struct comp_driver comp_chain_dma = {
Expand Down
10 changes: 9 additions & 1 deletion src/audio/component.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,15 @@

LOG_MODULE_REGISTER(component, CONFIG_SOF_LOG_LEVEL);

static SHARED_DATA struct comp_driver_list cd;
static APP_SYSUSER_BSS SHARED_DATA struct comp_driver_list cd;

#ifdef CONFIG_SOF_USERSPACE_LL
struct comp_driver_list *comp_drivers_get(void)
{
return platform_shared_get(&cd, sizeof(cd));
}
EXPORT_SYMBOL(comp_drivers_get);
#endif

SOF_DEFINE_REG_UUID(component);

Expand Down
20 changes: 17 additions & 3 deletions src/audio/copier/copier.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <rtos/interrupt.h>
#include <sof/ipc/msg.h>
#include <sof/ipc/topology.h>
#include <sof/schedule/ll_schedule_domain.h>
#include <rtos/interrupt.h>
#include <rtos/timer.h>
#include <rtos/cache.h>
Expand Down Expand Up @@ -823,7 +824,9 @@ __cold static int set_chmap(struct comp_dev *dev, const void *data, size_t data_
pcm_converter_func process;
pcm_converter_func converters[IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT];
int i;
#ifndef CONFIG_SOF_USERSPACE_LL
uint32_t irq_flags;
#endif

assert_can_be_cold();

Expand Down Expand Up @@ -877,15 +880,26 @@ __cold static int set_chmap(struct comp_dev *dev, const void *data, size_t data_
}
}

/* Atomically update chmap, process and converters */
/* Atomically update chmap, process and converters.
* In user-space builds irq_local_disable() is privileged,
* use the LL scheduler lock instead.
*/
#ifdef CONFIG_SOF_USERSPACE_LL
zephyr_ll_lock_sched(cpu_get_id());
#else
irq_local_disable(irq_flags);
#endif

cd->dd[0]->chmap = chmap_cfg->channel_map;
cd->dd[0]->process = process;
for (i = 0; i < IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT; i++)
cd->converter[i] = converters[i];

#ifdef CONFIG_SOF_USERSPACE_LL
zephyr_ll_unlock_sched(cpu_get_id());
#else
irq_local_enable(irq_flags);
#endif

return 0;
}
Expand Down Expand Up @@ -1189,7 +1203,7 @@ __cold static int copier_unbind(struct processing_module *mod, struct bind_info
return 0;
}

static struct module_endpoint_ops copier_endpoint_ops = {
static APP_SYSUSER_DATA const struct module_endpoint_ops copier_endpoint_ops = {
.get_total_data_processed = copier_get_processed_data,
.position = copier_position,
.dai_ts_config = copier_dai_ts_config_op,
Expand All @@ -1200,7 +1214,7 @@ static struct module_endpoint_ops copier_endpoint_ops = {
.trigger = copier_comp_trigger
};

static const struct module_interface copier_interface = {
static APP_SYSUSER_DATA const struct module_interface copier_interface = {
.init = copier_init,
.prepare = copier_prepare,
.process_audio_stream = copier_process,
Expand Down
Loading
Loading