Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
d91d117
(---section submitted PRs START)
kv2019i Mar 23, 2026
454872a
schedule: use k_thread_cpu_pin() for CPU affinity
Jun 24, 2026
744d987
(---section submitted PRs STOP)
kv2019i Mar 23, 2026
23fc485
(---section dai-zephyr START)
kv2019i Feb 19, 2026
5dee10f
WIP: audio: dai-zephyr: temporarily disable spinlock for dai properties
kv2019i Jun 10, 2026
293450b
audio: dai-zephyr: migrate to use dai_get_properties_copy()
kv2019i Feb 18, 2026
c49319a
(---section dai-zephyr STOP)
kv2019i Feb 19, 2026
5f8e647
(---section schduler changes START)
kv2019i Mar 3, 2026
b021659
schedule: zephyr_ll: convert pdata->sem into a dynamic object
kv2019i Feb 13, 2026
c8e684d
schedule: add scheduler_get_data_for_core()
kv2019i Jun 10, 2026
2fb3069
schedule: zephyr_ll: add user_ll_grant_access()
kv2019i Jun 26, 2026
9c4d0a4
schedule: zephyr_domain: use a different thread name for user LL
kv2019i Mar 24, 2026
e2e20b2
coherent: disable core debug checks for user-space builds
kv2019i Mar 20, 2026
2dac4f9
schedule: zephyr_ll: make zephyr_ll_assert_core() user-space safe
kv2019i Jun 10, 2026
0043254
schedule: zephyr_ll: use correct method to get scheduler data
kv2019i Jun 9, 2026
cf000f5
schedule: zephyr_dp_sched_app: fix build with no thread names
kv2019i Jun 16, 2026
d7950bc
(---section schduler changes END)
kv2019i Mar 3, 2026
3ec13c6
(---section audio-user PRs START)
kv2019i Mar 25, 2026
2424e39
audio: pipeline-schedule: make pipeline_schedule_triggered() user safe
kv2019i Jun 10, 2026
c82902c
init: secondary_core_init: set up user-space LL scheduler context
kv2019i Jun 10, 2026
34d1a1d
audio: copier: avoid IRQ lock/unlock in chmap code
kv2019i Mar 31, 2026
2121575
audio: module_adapter: avoid IRQ lock/unlock in prepare()
kv2019i Mar 31, 2026
5dbb2b9
audio: make comp_drivers_get() accessible from user-space
kv2019i Apr 15, 2026
782a5d7
audio: chain_dma: add user-space memory and scheduling support
kv2019i Apr 21, 2026
0cd25d7
audio: chain-dma: use module context for allocations
kv2019i May 8, 2026
4522928
audio: chain_dma: run chain DMA in the user LL thread
kv2019i Jun 18, 2026
5ed06bc
userspace: fix debug-overlay builds
lyakh Jun 23, 2026
c183b8c
(---section audio user PRs STOP)
kv2019i Mar 25, 2026
6cc472c
(---section: IPC user support START)
kv2019i Mar 17, 2026
2d60609
ipc: move standalone-test check later in ipc_init()
kv2019i Feb 10, 2026
80ff568
ipc: add global IPC context and ll_alloc for user-space LL
kv2019i Jun 18, 2026
b6ff766
ipc4: handler: make config and pipeline-state processing context-agno…
kv2019i Jun 18, 2026
2f08635
ipc: make ipc_msg_reply and compound-message handlers syscalls
kv2019i Jun 18, 2026
9a184e7
ipc: allocate IPC objects from the user-accessible system heap
kv2019i Jun 18, 2026
38a0692
ipc: implement user-space IPC handling thread
kv2019i Jun 18, 2026
b903967
zephyr: lib: make vregion_alloc/free system calls
kv2019i Jun 25, 2026
58f9ace
(---section: IPC user support STOP)
kv2019i Mar 27, 2026
7752c94
(---section: IPC notifications START)
kv2019i May 8, 2026
f45be6c
ipc: turn ipc_msg_send() into a system call if SOF_USERSPACE_LL=y
Apr 20, 2026
4f34e1c
ipc: make IPC message allocation userspace-safe
kv2019i Jun 25, 2026
3f56fc0
ipc4: notification: make send_resource_notif() a syscall
Apr 23, 2026
68ce492
(---section: IPC notifications STOP)
kv2019i May 8, 2026
a0ae4f4
(---section test-case START)
kv2019i Feb 19, 2026
9c713e7
zephyr: test: userspace: add pipeline_two_components test
kv2019i Apr 22, 2026
731e700
(---section WIP mandatory changes START)
kv2019i Feb 19, 2026
9381720
audio: pipeline: enable position reporting for user-space pipelines
kv2019i Jul 2, 2026
2817e0c
schedule: zephyr_ll: fix use-after-free when freeing an active user-s…
kv2019i Jun 5, 2026
696f46f
WIP: ipc: expose coldrodata to IPC user thread
kv2019i Apr 16, 2026
50e6bc0
HACK: audio: collection of feature limitations to run LL in user
kv2019i Feb 26, 2026
282aa47
Revert "module: generic: remove MEM_API_CHECK_THREAD debug mechanism"
kv2019i Jul 2, 2026
9a37bcf
Revert "module: generic: add mutex to protect module_resources"
kv2019i Jul 2, 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
8 changes: 8 additions & 0 deletions src/audio/component.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ 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 &cd;
}
EXPORT_SYMBOL(comp_drivers_get);
#endif

SOF_DEFINE_REG_UUID(component);

DECLARE_TR_CTX(comp_tr, SOF_UUID(component_uuid), LOG_LEVEL_INFO);
Expand Down
Loading
Loading