Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
622537c
(---section submitted PRs START)
kv2019i Mar 23, 2026
4295bd8
ipc: ipc4: helper: drop redundant locking in ipc4_search_for_drv()
kv2019i Mar 31, 2026
96781d3
audio: component: drop redundant locking in driver list
kv2019i Jun 15, 2026
2fcbf38
schedule: add support for LL userspace tasks
kv2019i Jun 16, 2026
7c95a30
schedule: allocate the scheduler objects with sof_heap_alloc()
kv2019i Jun 24, 2026
854e194
(---section submitted PRs STOP)
kv2019i Mar 23, 2026
f2930de
(---section dai-zephyr START)
kv2019i Feb 19, 2026
a5e095d
WIP: audio: dai-zephyr: temporarily disable spinlock for dai properties
kv2019i Jun 10, 2026
81731c8
audio: dai-zephyr: migrate to use dai_get_properties_copy()
kv2019i Feb 18, 2026
5f7d8d9
(---section dai-zephyr STOP)
kv2019i Feb 19, 2026
910c2b6
(---section schduler changes START)
kv2019i Mar 3, 2026
b38e213
schedule: zephyr_ll: convert pdata->sem into a dynamic object
kv2019i Feb 13, 2026
12f3fef
schedule: add scheduler_get_data_for_core()
kv2019i Jun 10, 2026
2f971f3
schedule: zephyr_ll: add user_ll_grant_access()
kv2019i Jun 5, 2026
7c60798
schedule: zephyr_domain: use a different thread name for user LL
kv2019i Mar 24, 2026
3e56c4d
coherent: disable core debug checks for user-space builds
kv2019i Mar 20, 2026
e2e3c7c
schedule: zephyr_ll: add user_ll_lock/unlock_sched()
kv2019i Jun 11, 2026
c910b90
schedule: zephyr_ll: user ll: keep ll lock while running tasks
kv2019i Jun 16, 2026
27692d9
audio: pipeline: change locking strategy for user LL builds
kv2019i Jun 10, 2026
b15b445
schedule: zephyr_ll: make zephyr_ll_assert_core() user-space safe
kv2019i Jun 10, 2026
b61d479
schedule: zephyr_ll: use correct method to get scheduler data
kv2019i Jun 9, 2026
3bd8529
schedule: zephyr_dp_sched_app: fix build with no thread names
kv2019i Jun 16, 2026
2336c29
(---section schduler changes END)
kv2019i Mar 3, 2026
54001a3
(---section audio-user PRs START)
kv2019i Mar 25, 2026
885a630
audio: pipeline-schedule: make pipeline_schedule_triggered() user safe
kv2019i Jun 10, 2026
8637712
init: secondary_core_init: set up user-space LL scheduler context
kv2019i Jun 10, 2026
ffb0ce8
audio: copier: avoid IRQ lock/unlock in chmap code
kv2019i Mar 31, 2026
b3c347f
audio: module_adapter: avoid IRQ lock/unlock in prepare()
kv2019i Mar 31, 2026
08bd8d9
audio: make comp_drivers_get() accessible from user-space
kv2019i Apr 15, 2026
6eaef27
audio: chain_dma: add user-space memory and scheduling support
kv2019i Apr 21, 2026
7da60be
audio: chain-dma: use module context for allocations
kv2019i May 8, 2026
4e6eace
audio: chain_dma: run chain DMA in the user LL thread
kv2019i Jun 18, 2026
def58b2
(---section audio user PRs STOP)
kv2019i Mar 25, 2026
87ccd59
(---section: IPC user support START)
kv2019i Mar 17, 2026
5bca065
ipc: move standalone-test check later in ipc_init()
kv2019i Feb 10, 2026
2a5049c
ipc: add global IPC context and ll_alloc for user-space LL
kv2019i Jun 18, 2026
5f5e02d
ipc4: handler: make config and pipeline-state processing context-agno…
kv2019i Jun 18, 2026
65d0fc3
ipc: make ipc_msg_reply and compound-message handlers syscalls
kv2019i Jun 18, 2026
9ff0e60
ipc: allocate IPC objects from the user-accessible system heap
kv2019i Jun 18, 2026
c8d9d7b
ipc: implement user-space IPC handling thread
kv2019i Jun 18, 2026
e19e04b
zephyr: lib: make vregion_alloc/free system calls
kv2019i Jun 25, 2026
5a47d04
(---section: IPC user support STOP)
kv2019i Mar 27, 2026
bf51bec
(---section: IPC notifications START)
kv2019i May 8, 2026
2e9cf40
ipc: turn ipc_msg_send() into a system call if SOF_USERSPACE_LL=y
Apr 20, 2026
9adb180
ipc: make IPC message allocation userspace-safe
kv2019i Jun 25, 2026
8690a60
ipc4: notification: make send_resource_notif() a syscall
Apr 23, 2026
96b9d56
(---section: IPC notifications STOP)
kv2019i May 8, 2026
9229c44
(---section test-case START)
kv2019i Feb 19, 2026
271e288
zephyr: test: userspace: add pipeline_two_components test
kv2019i Apr 22, 2026
91bf41e
(---section WIP mandatory changes START)
kv2019i Feb 19, 2026
3f96f2c
audio: pipeline: enable position reporting for user-space pipelines
kv2019i Jun 11, 2026
90f047e
schedule: zephyr_ll: fix use-after-free when freeing an active user-s…
kv2019i Jun 5, 2026
a421cda
WIP: ipc: expose coldrodata to IPC user thread
kv2019i Apr 16, 2026
9b0dde8
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
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
112 changes: 76 additions & 36 deletions 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 @@ -61,13 +63,13 @@ struct chain_dma_data {

/* local host DMA config */
struct sof_dma *dma_host;
struct dma_chan_data *chan_host;
int chan_host_index;
struct dma_config z_config_host;
struct dma_block_config dma_block_cfg_host;

/* local link DMA config */
struct sof_dma *dma_link;
struct dma_chan_data *chan_link;
int chan_link_index;
struct dma_config z_config_link;
struct dma_block_config dma_block_cfg_link;

Expand All @@ -79,12 +81,12 @@ static int chain_host_start(struct comp_dev *dev)
struct chain_dma_data *cd = comp_get_drvdata(dev);
int err;

err = dma_start(cd->chan_host->dma->z_dev, cd->chan_host->index);
err = sof_dma_start(cd->dma_host, cd->chan_host_index);
if (err < 0)
return err;

comp_info(dev, "dma_start() host chan_index = %u",
cd->chan_host->index);
cd->chan_host_index);
return 0;
}

Expand All @@ -93,12 +95,12 @@ static int chain_link_start(struct comp_dev *dev)
struct chain_dma_data *cd = comp_get_drvdata(dev);
int err;

err = dma_start(cd->chan_link->dma->z_dev, cd->chan_link->index);
err = sof_dma_start(cd->dma_link, cd->chan_link_index);
if (err < 0)
return err;

comp_info(dev, "dma_start() link chan_index = %u",
cd->chan_link->index);
cd->chan_link_index);
return 0;
}

Expand All @@ -107,12 +109,12 @@ static int chain_link_stop(struct comp_dev *dev)
struct chain_dma_data *cd = comp_get_drvdata(dev);
int err;

err = dma_stop(cd->chan_link->dma->z_dev, cd->chan_link->index);
err = sof_dma_stop(cd->dma_link, cd->chan_link_index);
if (err < 0)
return err;

comp_info(dev, "dma_stop() link chan_index = %u",
cd->chan_link->index);
cd->chan_link_index);

return 0;
}
Expand All @@ -122,12 +124,12 @@ static int chain_host_stop(struct comp_dev *dev)
struct chain_dma_data *cd = comp_get_drvdata(dev);
int err;

err = dma_stop(cd->chan_host->dma->z_dev, cd->chan_host->index);
err = sof_dma_stop(cd->dma_host, cd->chan_host_index);
if (err < 0)
return err;

comp_info(dev, "dma_stop() host chan_index = %u",
cd->chan_host->index);
cd->chan_host_index);

return 0;
}
Expand Down Expand Up @@ -165,7 +167,7 @@ static enum task_state chain_task_run(void *data)
/* Link DMA can return -EPIPE and current status if xrun occurs, then it is not critical
* and flow shall continue. Other error values will be treated as critical.
*/
ret = dma_get_status(cd->chan_link->dma->z_dev, cd->chan_link->index, &stat);
ret = sof_dma_get_status(cd->dma_link, cd->chan_link_index, &stat);
switch (ret) {
case 0:
#if CONFIG_XRUN_NOTIFICATIONS_ENABLE
Expand All @@ -189,7 +191,7 @@ static enum task_state chain_task_run(void *data)
link_read_pos = stat.read_position;

/* Host DMA does not report xruns. All error values will be treated as critical. */
ret = dma_get_status(cd->chan_host->dma->z_dev, cd->chan_host->index, &stat);
ret = sof_dma_get_status(cd->dma_host, cd->chan_host_index, &stat);
if (ret < 0) {
tr_err(&chain_dma_tr, "dma_get_status() error, ret = %d", ret);
return SOF_TASK_STATE_COMPLETED;
Expand All @@ -207,14 +209,14 @@ static enum task_state chain_task_run(void *data)
*/
const size_t increment = MIN(host_free_bytes, link_avail_bytes);

ret = dma_reload(cd->chan_host->dma->z_dev, cd->chan_host->index, 0, 0, increment);
ret = sof_dma_reload(cd->dma_host, cd->chan_host_index, increment);
if (ret < 0) {
tr_err(&chain_dma_tr,
"dma_reload() host error, ret = %d", ret);
return SOF_TASK_STATE_COMPLETED;
}

ret = dma_reload(cd->chan_link->dma->z_dev, cd->chan_link->index, 0, 0, increment);
ret = sof_dma_reload(cd->dma_link, cd->chan_link_index, increment);
if (ret < 0) {
tr_err(&chain_dma_tr,
"dma_reload() link error, ret = %d", ret);
Expand All @@ -230,9 +232,8 @@ static enum task_state chain_task_run(void *data)
const size_t half_buff_size = buff_size / 2;

if (!cd->first_data_received && host_avail_bytes > half_buff_size) {
ret = dma_reload(cd->chan_link->dma->z_dev,
cd->chan_link->index, 0, 0,
MIN(host_avail_bytes, link_free_bytes));
ret = sof_dma_reload(cd->dma_link, cd->chan_link_index,
MIN(host_avail_bytes, link_free_bytes));
if (ret < 0) {
tr_err(&chain_dma_tr,
"dma_reload() link error, ret = %d", ret);
Expand All @@ -246,8 +247,8 @@ static enum task_state chain_task_run(void *data)
host_read_pos,
buff_size);

ret = dma_reload(cd->chan_host->dma->z_dev, cd->chan_host->index,
0, 0, transferred);
ret = sof_dma_reload(cd->dma_host, cd->chan_host_index,
transferred);
if (ret < 0) {
tr_err(&chain_dma_tr,
"dma_reload() host error, ret = %d", ret);
Expand All @@ -256,8 +257,8 @@ static enum task_state chain_task_run(void *data)

if (host_avail_bytes >= half_buff_size &&
link_free_bytes >= half_buff_size) {
ret = dma_reload(cd->chan_link->dma->z_dev, cd->chan_link->index,
0, 0, half_buff_size);
ret = sof_dma_reload(cd->dma_link, cd->chan_link_index,
half_buff_size);
if (ret < 0) {
tr_err(&chain_dma_tr,
"dma_reload() link error, ret = %d", ret);
Expand Down Expand Up @@ -345,6 +346,7 @@ static int chain_task_pause(struct comp_dev *dev)
return 0;

cd->first_data_received = false;

if (cd->stream_direction == SOF_IPC_STREAM_PLAYBACK) {
ret = chain_host_stop(dev);
ret2 = chain_link_stop(dev);
Expand All @@ -367,9 +369,9 @@ __cold static void chain_release(struct comp_dev *dev)

assert_can_be_cold();

dma_release_channel(cd->chan_host->dma->z_dev, cd->chan_host->index);
sof_dma_release_channel(cd->dma_host, cd->chan_host_index);
sof_dma_put(cd->dma_host);
dma_release_channel(cd->chan_link->dma->z_dev, cd->chan_link->index);
sof_dma_release_channel(cd->dma_link, cd->chan_link_index);
sof_dma_put(cd->dma_link);

if (cd->dma_buffer) {
Expand Down Expand Up @@ -457,53 +459,52 @@ __cold static int chain_init(struct comp_dev *dev, void *addr, size_t length)

/* get host DMA channel */
channel = cd->host_connector_node_id.f.v_index;
channel = dma_request_channel(cd->dma_host->z_dev, &channel);
channel = sof_dma_request_channel(cd->dma_host, channel);
if (channel < 0) {
comp_err(dev, "host dma_request_channel() failed for %u",
cd->host_connector_node_id.f.v_index);
return channel;
}

cd->chan_host = &cd->dma_host->chan[channel];
cd->chan_host_index = channel;

err = dma_config(cd->dma_host->z_dev, cd->chan_host->index, dma_cfg_host);
err = sof_dma_config(cd->dma_host, cd->chan_host_index, dma_cfg_host);
if (err < 0) {
comp_err(dev, "host dma_config() failed for %d", channel);
goto error_host;
}

/* get link DMA channel */
channel = cd->link_connector_node_id.f.v_index;
channel = dma_request_channel(cd->dma_link->z_dev, &channel);
channel = sof_dma_request_channel(cd->dma_link, channel);
if (channel < 0) {
comp_err(dev, "link dma_request_channel() failed for %u",
cd->link_connector_node_id.f.v_index);
err = channel;
goto error_host;
}

cd->chan_link = &cd->dma_link->chan[channel];
cd->chan_link_index = channel;

err = dma_config(cd->dma_link->z_dev, cd->chan_link->index, dma_cfg_link);
err = sof_dma_config(cd->dma_link, cd->chan_link_index, dma_cfg_link);
if (err < 0) {
comp_err(dev, "link dma_config() failed for %d", channel);
goto error_link;
}
return 0;

error_link:
dma_release_channel(cd->dma_link->z_dev, cd->chan_link->index);
cd->chan_link = NULL;
sof_dma_release_channel(cd->dma_link, cd->chan_link_index);
error_host:
dma_release_channel(cd->dma_host->z_dev, cd->chan_host->index);
cd->chan_host = NULL;
sof_dma_release_channel(cd->dma_host, cd->chan_host_index);
return err;
}

__cold static int chain_task_init(struct comp_dev *dev, uint8_t host_dma_id, uint8_t link_dma_id,
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 @@ -553,8 +554,8 @@ __cold static int chain_task_init(struct comp_dev *dev, uint8_t host_dma_id, uin
}

/* retrieve DMA buffer address alignment */
ret = dma_get_attribute(cd->dma_host->z_dev, DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT,
&addr_align);
ret = sof_dma_get_attribute(cd->dma_host, DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT,
&addr_align);
if (ret < 0) {
comp_err(dev,
"could not get dma buffer address alignment, err = %d", ret);
Expand Down Expand Up @@ -582,8 +583,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 +650,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 +685,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 +706,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
Loading
Loading