Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
6e00982
(---section submitted PRs START)
kv2019i Mar 23, 2026
91d4d4c
audio: host-zepher: add HOST_DMA_IPC_POSITION_UPDATES Kconfig
kv2019i May 21, 2026
9db6272
ipc: ipc4: helper: drop redundant locking in ipc4_search_for_drv()
kv2019i Mar 31, 2026
75c78ff
audio: component: drop redundant locking in driver list
kv2019i Jun 15, 2026
c754507
(---section submitted PRs STOP)
kv2019i Mar 23, 2026
8d4d49f
(---section: scheduler-split START)
kv2019i Jun 3, 2026
4c63261
schedule: add support for LL userspace tasks
kv2019i Jun 16, 2026
b1c8f22
schedule: allocate the scheduler objects with sof_heap_alloc()
kv2019i Feb 26, 2026
092c667
(---section: scheduler-split STTOP)
kv2019i Jun 3, 2026
9dd96f3
(---section dai-zephyr START)
kv2019i Feb 19, 2026
902c783
WIP: audio: dai-zephyr: temporarily disable spinlock for dai properties
kv2019i Jun 10, 2026
6c80230
audio: dai-zephyr: migrate to use dai_get_properties_copy()
kv2019i Feb 18, 2026
81fd9e4
(---section dai-zephyr STOP)
kv2019i Feb 19, 2026
bd8929f
(---section schduler changes START)
kv2019i Mar 3, 2026
9e39468
schedule: zephyr_ll: convert pdata->sem into a dynamic object
kv2019i Feb 13, 2026
77eac27
schedule: add scheduler_get_data_for_core()
kv2019i Jun 10, 2026
ddb43fc
schedule: zephyr_ll: add user_ll_grant_access()
kv2019i Jun 5, 2026
fdab67b
schedule: zephyr_domain: use a different thread name for user LL
kv2019i Mar 24, 2026
75e9252
coherent: disable core debug checks for user-space builds
kv2019i Mar 20, 2026
d84eab0
schedule: zephyr_ll: add user_ll_lock/unlock_sched()
kv2019i Jun 11, 2026
306be48
schedule: zephyr_ll: user ll: keep ll lock while running tasks
kv2019i Jun 16, 2026
ab2fd87
audio: pipeline: change locking strategy for user LL builds
kv2019i Jun 10, 2026
01d6950
schedule: zephyr_ll: make zephyr_ll_assert_core() user-space safe
kv2019i Jun 10, 2026
b6026cd
schedule: zephyr_ll: use correct method to get scheduler data
kv2019i Jun 9, 2026
c50c79f
schedule: zephyr_dp_sched_app: fix build with no thread names
kv2019i Jun 16, 2026
62ba5d6
(---section schduler changes END)
kv2019i Mar 3, 2026
2fedf01
(---section audio-user PRs START)
kv2019i Mar 25, 2026
22da51c
audio: pipeline-schedule: make pipeline_schedule_triggered() user safe
kv2019i Jun 10, 2026
2ebeefb
init: secondary_core_init: set up user-space LL scheduler context
kv2019i Jun 10, 2026
8e1ff1f
audio: copier: avoid IRQ lock/unlock in chmap code
kv2019i Mar 31, 2026
465fa4a
audio: module_adapter: avoid IRQ lock/unlock in prepare()
kv2019i Mar 31, 2026
68a8e8a
audio: module_adapter: make data_blob compatible with user-space
kv2019i Apr 14, 2026
36e46de
audio: module-adapter: make generic.c user-space compatible
kv2019i Apr 16, 2026
fdb793b
audio: module: generic: use module context for blob allocations
kv2019i May 8, 2026
f37a63c
audio: make comp_drivers_get() accessible from user-space
kv2019i Apr 15, 2026
f515f3b
audio: chain_dma: add user-space memory and scheduling support
kv2019i Apr 21, 2026
bb52d6e
audio: chain-dma: use module context for allocations
kv2019i May 8, 2026
1de5223
(---section audio user PRs STOP)
kv2019i Mar 25, 2026
0323db5
(---section: IPC user support START)
kv2019i Mar 17, 2026
ebfedea
ipc: move standalone-test check later in ipc_init()
kv2019i Feb 10, 2026
c090910
userspace: split ipc files into user and kernel features. REVISIT memcpy
kv2019i Apr 1, 2026
3756588
WIP: ipc: implement user-space IPC handling for CREATE_PIPELINE
kv2019i Mar 12, 2026
d55a3a9
WIP: ipc: implement user-space IPC handling for CREATE_PIPELINE
kv2019i Jun 11, 2026
1e3a146
WIP: ipc: ipc4: route PIPELINE_DELETE to user-space handler
kv2019i Mar 30, 2026
eec836d
ipc: make IPC stack thread size configurable
Apr 1, 2026
d1e0228
ipc: ipc4: use sof_heap_alloc in ipc4_add_comp_dev()
kv2019i May 20, 2026
6a751e8
ipc: turn ipc_msg_reply() into a system call
kv2019i May 29, 2026
2c25fb6
ipc: use application heap for IPC pipeline and component allocations
kv2019i Mar 20, 2026
0fffc6e
ipc: ipc-helper: trace context not used in user-space
kv2019i Apr 13, 2026
316eba8
ipc: ipc4: use the core number from IPC config
kv2019i May 5, 2026
0fb7994
WIP: ipc: ipc4: route MOD_CONFIG_GET/SET to user-space handler
kv2019i Apr 10, 2026
e10e5c2
WIP: ipc: ipc4: route MOD_BIND/UNBIND to user-space handler
kv2019i Apr 10, 2026
3799765
WIP: ipc: ipc4: route MOD_INIT_INSTANCE to user-space handler
kv2019i May 11, 2026
dd1b421
WIP: ipc: ipc4: route GLB_SET_PIPELINE_STATE to user-space handler
kv2019i Apr 16, 2026
0f83890
WIP: ipc: ipc4: route MOD_LARGE_CONFIG_GET/SET user-space
kv2019i Apr 16, 2026
4123968
ipc: add a mod_alloc_ctx context to IPC context
kv2019i May 8, 2026
145b43a
zephyr: lib: make vregion_alloc/free system calls
kv2019i Jun 9, 2026
7886a75
(---section: IPC user support STOP)
kv2019i Mar 27, 2026
f76dd71
(---section: IPC notifications START)
kv2019i May 8, 2026
d30dc47
ipc: turn ipc_msg_send() into a system call if SOF_USERSPACE_LL=y
Apr 20, 2026
ab0c7a0
ipc: make IPC message allocation userspace-safe
Apr 21, 2026
7b23e8e
ipc4: notification: make send_resource_notif() a syscall
Apr 23, 2026
d4feadb
(---section: IPC notifications STOP)
kv2019i May 8, 2026
dd1d6f7
(---section test-case START)
kv2019i Feb 19, 2026
a4fcfdd
zephyr: test: userspace: add pipeline_two_components test
kv2019i Apr 22, 2026
c483ff2
(---section WIP mandatory changes START)
kv2019i Feb 19, 2026
9b146ad
audio: pipeline: enable position reporting for user-space pipelines
kv2019i Jun 11, 2026
875e23d
schedule: zephyr_ll: fix use-after-free when freeing an active user-s…
kv2019i Jun 5, 2026
53b080c
WIP: ipc: expose coldrodata to IPC user thread
kv2019i Apr 16, 2026
72d6638
HACK: audio: collection of feature limitations to run LL in user
kv2019i Feb 26, 2026
dae518c
ipc: only add a partition if it's non-empty
lyakh May 21, 2026
f39f259
audio: pipeline: add a missing header
lyakh May 21, 2026
f5cd356
lib-manager: add 2 syscalls to handle LLEXT-related work
lyakh May 22, 2026
cbcdd23
audio: pipeline: add a missing header
lyakh Jun 17, 2026
d7dfacb
ipc: ipc4: type-cast a pointer instead of memcpy()
lyakh Jun 17, 2026
742ffcb
ipc: ipc4: fix a logging format
lyakh Jun 17, 2026
9035448
schedule: LL: limit scope of two functions
lyakh Jun 17, 2026
be8c14f
llext: add a function to map libraries to userspace
lyakh May 22, 2026
3de9cf2
lib-manager: use user heap for the driver object
lyakh May 22, 2026
6af3373
llext: map modules for userspace LL
lyakh May 22, 2026
d255b15
ipc: enable syscalls for userspace always
lyakh May 22, 2026
755a13e
ipc: remove driver copy
lyakh May 22, 2026
7c7eb1f
schedule: ll: userspace: enable LLEXT
lyakh May 22, 2026
637aa48
audio: pipeline: remove unneeded warning
lyakh Jun 10, 2026
a37cdd6
ipc: disable memory zones for IPC4
lyakh Jun 10, 2026
c0ee625
ipc: eliminate multiple memcpy() calls
lyakh Jun 10, 2026
baf5041
dma: allocate on userspace heap when running in userspace
lyakh Jun 10, 2026
282640f
schedule: ll: allocate semaphores only for used cores
lyakh Jun 10, 2026
7b00d77
schedule: ll: initialise task object to 0
lyakh Jun 10, 2026
18623a4
schedule: ll: allocate coherent memory in userspace mode too
lyakh Jun 10, 2026
633fc9f
ipc: allocate userspace IPC thread dynamically
lyakh Jun 10, 2026
dca021b
ipc: allocate userspace context uncached
lyakh Jun 10, 2026
44063bf
schedule: ll: use correct core
lyakh Jun 18, 2026
894dda5
userspace: ll: ipc: increase IPC processing timeout
lyakh Jun 15, 2026
0c4e579
schedule: ll: enable multicore userspace
lyakh Jun 10, 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
7 changes: 2 additions & 5 deletions app/overlays/ptl/ll_userspace_overlay.conf
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,12 @@ CONFIG_COLD_STORE_EXECUTE_DEBUG=n
CONFIG_SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS=n
CONFIG_SOF_TELEMETRY_IO_PERFORMANCE_MEASUREMENTS=n

# disable loadable modules (hits privilege issues in user-space now)
CONFIG_LLEXT_STORAGE_WRITABLE=n
CONFIG_LLEXT_EXPERIMENTAL=n
CONFIG_MODULES=n

# some of current boot tests interfere with user-space setup
CONFIG_SOF_BOOT_TEST_ALLOWED=n

# misc features not yet compatible with user-space
CONFIG_CROSS_CORE_STREAM=n
CONFIG_INTEL_ADSP_MIC_PRIVACY=n
CONFIG_XRUN_NOTIFICATIONS_ENABLE=n

CONFIG_MAX_THREAD_BYTES=4
21 changes: 21 additions & 0 deletions posix/include/rtos/mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,25 @@ 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;
}

#endif
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 @@ -269,6 +280,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 @@ -310,6 +340,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 @@ -324,27 +360,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 @@ -355,7 +402,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 @@ -504,6 +556,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 @@ -582,8 +635,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 @@ -643,14 +702,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 @@ -661,9 +737,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 @@ -674,8 +758,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
22 changes: 15 additions & 7 deletions src/audio/component.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,30 +38,39 @@ LOG_MODULE_REGISTER(component, CONFIG_SOF_LOG_LEVEL);

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);

DECLARE_TR_CTX(comp_tr, SOF_UUID(component_uuid), LOG_LEVEL_INFO);

int comp_register(struct comp_driver_info *drv)
{
struct comp_driver_list *drivers = comp_drivers_get();
k_spinlock_key_t key;

key = k_spin_lock(&drivers->lock);
/*
* No locking needed: the driver list is only modified at FW boot,
* where module init runs serially on the primary core, and at
* runtime from the serialized IPC thread (library load). These
* never overlap, so concurrent modification is not possible.
*/
list_item_prepend(&drv->list, &drivers->list);
k_spin_unlock(&drivers->lock, key);

return 0;
}

void comp_unregister(struct comp_driver_info *drv)
{
struct comp_driver_list *drivers = comp_drivers_get();
k_spinlock_key_t key;

key = k_spin_lock(&drivers->lock);
/* see comp_register() on why no locking is needed */
list_item_del(&drv->list);
k_spin_unlock(&drivers->lock, key);
}

int comp_set_adapter_ops(const struct comp_driver *drv, const struct module_interface *ops)
Expand Down Expand Up @@ -190,7 +199,6 @@ void sys_comp_init(struct sof *sof)
sof->comp_drivers = platform_shared_get(&cd, sizeof(cd));

list_init(&sof->comp_drivers->list);
k_spinlock_init(&sof->comp_drivers->lock);
}

void comp_get_copy_limits(struct comp_buffer *source,
Expand Down
16 changes: 15 additions & 1 deletion 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 @@ -824,7 +825,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 @@ -878,15 +881,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
user_ll_lock_sched(dev->pipeline->core);
#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
user_ll_unlock_sched(dev->pipeline->core);
#else
irq_local_enable(irq_flags);
#endif

return 0;
}
Expand Down
2 changes: 2 additions & 0 deletions src/audio/copier/host_copier.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ struct host_data {

/* stream info */
struct sof_ipc_stream_posn posn; /* TODO: update this */
#if CONFIG_HOST_DMA_IPC_POSITION_UPDATES
struct ipc_msg *msg; /**< host notification */
#endif
#if CONFIG_XRUN_NOTIFICATIONS_ENABLE
bool xrun_notification_sent;
#endif
Expand Down
Loading