Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
28 changes: 22 additions & 6 deletions app/boards/intel_adsp_ace30_ptl.conf
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL=n
CONFIG_PROBE=y
CONFIG_PROBE_DMA_MAX=2
CONFIG_SOF_TELEMETRY=y
CONFIG_SOF_TELEMETRY_IO_PERFORMANCE_MEASUREMENTS=y
CONFIG_SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS=y
CONFIG_COLD_STORE_EXECUTE_DRAM=y
CONFIG_SOF_TELEMETRY_IO_PERFORMANCE_MEASUREMENTS=n
CONFIG_SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS=n
CONFIG_COLD_STORE_EXECUTE_DRAM=n

# SOF / loadable modules
CONFIG_INTEL_MODULES=y
Expand All @@ -40,10 +40,10 @@ CONFIG_SOF_LOG_LEVEL_INF=y
CONFIG_COUNTER=y
CONFIG_HEAP_MEM_POOL_SIZE=8192
CONFIG_LLEXT=y
CONFIG_LLEXT_STORAGE_WRITABLE=y
CONFIG_LLEXT_EXPERIMENTAL=y
CONFIG_LLEXT_STORAGE_WRITABLE=n
CONFIG_LLEXT_EXPERIMENTAL=n
CONFIG_LLEXT_EDK=n
CONFIG_MODULES=y
CONFIG_MODULES=n

# Zephyr / device drivers
CONFIG_DAI_INIT_PRIORITY=70
Expand Down Expand Up @@ -78,3 +78,19 @@ CONFIG_SOF_USERSPACE_PROXY=y
CONFIG_MAX_THREAD_BYTES=3

CONFIG_MAX_DOMAIN_PARTITIONS=32

# Userspace LL (was app/overlays/ptl/ll_userspace_overlay.conf)
# Run Low-Latency audio pipelines in user-space threads by default.
CONFIG_SOF_USERSPACE_LL=y
CONFIG_SOF_USERSPACE_INTERFACE_DMA=y
CONFIG_DAI_USERSPACE=y

# Settings currently required to enable user-space LL. The cold-store,
# telemetry, loadable-module and misc feature disables above/here are not
# yet user-space compatible (see the former overlay for rationale).
CONFIG_COLD_STORE_EXECUTE_DEBUG=n
CONFIG_SOF_BOOT_TEST_ALLOWED=n
CONFIG_CROSS_CORE_STREAM=n
CONFIG_INTEL_ADSP_MIC_PRIVACY=n
CONFIG_XRUN_NOTIFICATIONS_ENABLE=n
CONFIG_ZEPHYR_DP_SCHEDULER=n
41 changes: 35 additions & 6 deletions app/boards/intel_adsp_ace30_wcl.conf
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL=n
CONFIG_PROBE=y
CONFIG_PROBE_DMA_MAX=2
CONFIG_SOF_TELEMETRY=y
CONFIG_SOF_TELEMETRY_IO_PERFORMANCE_MEASUREMENTS=y
CONFIG_SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS=y
CONFIG_COLD_STORE_EXECUTE_DRAM=y
CONFIG_SOF_TELEMETRY_IO_PERFORMANCE_MEASUREMENTS=n
CONFIG_SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS=n
CONFIG_COLD_STORE_EXECUTE_DRAM=n

# SOF / loadable modules
CONFIG_INTEL_MODULES=y
Expand All @@ -39,10 +39,10 @@ CONFIG_SOF_LOG_LEVEL_INF=y
# Zephyr / OS features
CONFIG_HEAP_MEM_POOL_SIZE=8192
CONFIG_LLEXT=y
CONFIG_LLEXT_STORAGE_WRITABLE=y
CONFIG_LLEXT_EXPERIMENTAL=y
CONFIG_LLEXT_STORAGE_WRITABLE=n
CONFIG_LLEXT_EXPERIMENTAL=n
CONFIG_LLEXT_EDK=n
CONFIG_MODULES=y
CONFIG_MODULES=n

# Zephyr / device drivers
CONFIG_DAI_INIT_PRIORITY=70
Expand All @@ -64,3 +64,32 @@ CONFIG_PM_DEVICE_RUNTIME_ASYNC=n
CONFIG_LOG_BACKEND_ADSP=n
CONFIG_LOG_FLUSH_SLEEP_US=5000
CONFIG_WINSTREAM_CONSOLE=n

# Userspace base (mirrored from intel_adsp_ace30_ptl.conf)
# Required so that user-space LL (below) can actually be enabled, since
# CONFIG_SOF_USERSPACE_LL depends on CONFIG_USERSPACE.
CONFIG_USERSPACE=y
CONFIG_DYNAMIC_THREAD=y
CONFIG_DYNAMIC_THREAD_ALLOC=y
CONFIG_DYNAMIC_THREAD_PREFER_ALLOC=y
CONFIG_SOF_STACK_SIZE=8192
CONFIG_SOF_USERSPACE_PROXY=y
CONFIG_MAX_THREAD_BYTES=3
CONFIG_MAX_DOMAIN_PARTITIONS=32
CONFIG_XTENSA_MMU_NUM_L2_TABLES=128

# Userspace LL (was app/overlays/ptl/ll_userspace_overlay.conf)
# Run Low-Latency audio pipelines in user-space threads by default.
CONFIG_SOF_USERSPACE_LL=y
CONFIG_SOF_USERSPACE_INTERFACE_DMA=y
CONFIG_DAI_USERSPACE=y

# Settings currently required to enable user-space LL. The cold-store,
# telemetry, loadable-module and misc feature disables above/here are not
# yet user-space compatible (see the former overlay for rationale).
CONFIG_COLD_STORE_EXECUTE_DEBUG=n
CONFIG_SOF_BOOT_TEST_ALLOWED=n
CONFIG_CROSS_CORE_STREAM=n
CONFIG_INTEL_ADSP_MIC_PRIVACY=n
CONFIG_XRUN_NOTIFICATIONS_ENABLE=n
CONFIG_ZEPHYR_DP_SCHEDULER=n
90 changes: 80 additions & 10 deletions src/audio/pipeline/pipeline-graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <rtos/interrupt.h>
#include <rtos/symbol.h>
#include <rtos/alloc.h>
#include <rtos/userspace_helper.h>
#include <sof/lib/mm_heap.h>
#include <sof/lib/uuid.h>
#include <sof/compiler_attributes.h>
Expand Down Expand Up @@ -44,20 +45,69 @@ DECLARE_TR_CTX(pipe_tr, SOF_UUID(pipe_uuid), LOG_LEVEL_INFO);
/* lookup table to determine busy/free pipeline metadata objects */
struct pipeline_posn {
bool posn_offset[PPL_POSN_OFFSETS]; /**< available offsets */
#ifndef CONFIG_SOF_USERSPACE_LL
struct k_spinlock lock; /**< lock mechanism */
#endif
};
/* the pipeline position lookup table */
static SHARED_DATA struct pipeline_posn pipeline_posn_shared;
static APP_SYSUSER_BSS SHARED_DATA struct pipeline_posn pipeline_posn_shared;

#ifdef CONFIG_SOF_USERSPACE_LL
/* Mutex pointer in user-accessible partition so user-space threads
* can read the pointer for syscalls. Kept outside the SHARED_DATA
* struct to avoid kernel object tracking issues.
*/
static APP_SYSUSER_BSS struct k_mutex *pipeline_posn_mutex;
#endif

/**
* \brief Retrieves pipeline position structure.
* \return Pointer to pipeline position structure.
*/
static inline struct pipeline_posn *pipeline_posn_get(void)
{
#ifdef CONFIG_SOF_USERSPACE_LL
return &pipeline_posn_shared;
#else
return sof_get()->pipeline_posn;
#endif
}

/*
* Position table locking. User-space LL cannot use a spinlock (disabling
* interrupts is privileged), so it uses a mutex; the config split is kept
* here so the callers below stay identical for both configurations.
*/
#ifdef CONFIG_SOF_USERSPACE_LL
typedef int pipeline_posn_key_t;

static inline pipeline_posn_key_t pipeline_posn_lock(struct pipeline_posn *posn)
{
(void)posn;
k_mutex_lock(pipeline_posn_mutex, K_FOREVER);
return 0;
}

static inline void pipeline_posn_unlock(struct pipeline_posn *posn, pipeline_posn_key_t key)
{
(void)posn;
(void)key;
k_mutex_unlock(pipeline_posn_mutex);
}
#else
typedef k_spinlock_key_t pipeline_posn_key_t;

static inline pipeline_posn_key_t pipeline_posn_lock(struct pipeline_posn *posn)
{
return k_spin_lock(&posn->lock);
}

static inline void pipeline_posn_unlock(struct pipeline_posn *posn, pipeline_posn_key_t key)
{
k_spin_unlock(&posn->lock, key);
}
#endif

/**
* \brief Retrieves first free pipeline position offset.
* \param[in,out] posn_offset Pipeline position offset to be set.
Expand All @@ -68,9 +118,7 @@ static inline int pipeline_posn_offset_get(uint32_t *posn_offset)
struct pipeline_posn *pipeline_posn = pipeline_posn_get();
int ret = -EINVAL;
uint32_t i;
k_spinlock_key_t key;

key = k_spin_lock(&pipeline_posn->lock);
pipeline_posn_key_t key = pipeline_posn_lock(pipeline_posn);

for (i = 0; i < PPL_POSN_OFFSETS; ++i) {
if (!pipeline_posn->posn_offset[i]) {
Expand All @@ -81,8 +129,7 @@ static inline int pipeline_posn_offset_get(uint32_t *posn_offset)
}
}


k_spin_unlock(&pipeline_posn->lock, key);
pipeline_posn_unlock(pipeline_posn, key);

return ret;
}
Expand All @@ -95,20 +142,34 @@ static inline void pipeline_posn_offset_put(uint32_t posn_offset)
{
struct pipeline_posn *pipeline_posn = pipeline_posn_get();
int i = posn_offset / sizeof(struct sof_ipc_stream_posn);
k_spinlock_key_t key;

key = k_spin_lock(&pipeline_posn->lock);
pipeline_posn_key_t key = pipeline_posn_lock(pipeline_posn);

pipeline_posn->posn_offset[i] = false;

k_spin_unlock(&pipeline_posn->lock, key);
pipeline_posn_unlock(pipeline_posn, key);
}

void pipeline_posn_init(struct sof *sof)
{
sof->pipeline_posn = &pipeline_posn_shared;
#ifdef CONFIG_SOF_USERSPACE_LL
pipeline_posn_mutex = k_object_alloc(K_OBJ_MUTEX);
if (!pipeline_posn_mutex) {
pipe_cl_err("pipeline posn mutex alloc failed");
k_panic();
}
k_mutex_init(pipeline_posn_mutex);
#else
k_spinlock_init(&sof->pipeline_posn->lock);
#endif
}

#ifdef CONFIG_SOF_USERSPACE_LL
void pipeline_posn_grant_access(struct k_thread *thread)
{
k_thread_access_grant(thread, pipeline_posn_mutex);
}
#endif

/* create new pipeline - returns pipeline id or negative error */
struct pipeline *pipeline_new(struct k_heap *heap, uint32_t pipeline_id, uint32_t priority,
Expand Down Expand Up @@ -140,12 +201,21 @@ struct pipeline *pipeline_new(struct k_heap *heap, uint32_t pipeline_id, uint32_
p->pipeline_id = pipeline_id;
p->status = COMP_STATE_INIT;
p->trigger.cmd = COMP_TRIGGER_NO_ACTION;

#ifndef CONFIG_SOF_USERSPACE_LL
/*
* pipe_tr lives in the .trace_ctx section, which is not mapped into
* the sysuser partition, so it cannot be read from a user-mode thread.
* The copy is also unnecessary in that configuration: with Zephyr
* logging the pipe_*() macros use the global pipe_tr, not p->tctx.
*/
ret = memcpy_s(&p->tctx, sizeof(struct tr_ctx), &pipe_tr,
sizeof(struct tr_ctx));
if (ret < 0) {
pipe_err(p, "failed to copy trace settings");
goto free;
}
#endif

ret = pipeline_posn_offset_get(&p->posn_offset);
if (ret < 0) {
Expand Down
4 changes: 4 additions & 0 deletions src/include/sof/audio/pipeline-trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ extern struct tr_ctx pipe_tr;

#else

#if defined(__ZEPHYR__) && defined(CONFIG_SOF_USERSPACE_LL)
#error "Invalid build config: User-space cannot access trace context."
#endif

#define pipe_err(pipe_p, __e, ...) \
trace_dev_err(trace_pipe_get_tr_ctx, trace_pipe_get_id, \
trace_pipe_get_subid, pipe_p, __e, ##__VA_ARGS__)
Expand Down
8 changes: 8 additions & 0 deletions src/include/sof/audio/pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,14 @@ int pipeline_complete(struct pipeline *p, struct comp_dev *source,
*/
void pipeline_posn_init(struct sof *sof);

#ifdef CONFIG_SOF_USERSPACE_LL
/**
* \brief Grants user-space thread access to pipeline position mutex.
* \param[in] thread Thread to grant access to.
*/
void pipeline_posn_grant_access(struct k_thread *thread);
#endif

/**
* \brief Resets the pipeline and free runtime resources.
* \param[in] p pipeline.
Expand Down
6 changes: 6 additions & 0 deletions src/init/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <sof/schedule/dp_schedule.h>
#include <sof/schedule/ll_schedule.h>
#include <sof/schedule/ll_schedule_domain.h>
#include <sof/audio/pipeline.h>
#include <ipc/trace.h>
#if CONFIG_IPC_MAJOR_4
#include <ipc4/fw_reg.h>
Expand Down Expand Up @@ -232,6 +233,11 @@ __cold static int primary_core_init(int argc, char *argv[], struct sof *sof)
zephyr_ll_user_resources_init();
#endif

/* init pipeline position offsets - must be before platform_init()
* which calls ipc_init() -> ipc_user_init() that needs the posn mutex.
*/
pipeline_posn_init(sof);

/* init the platform */
if (platform_init(sof) < 0)
sof_panic(SOF_IPC_PANIC_PLATFORM);
Expand Down
1 change: 1 addition & 0 deletions src/ipc/ipc-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ __cold static int ipc_user_init_thread(struct ipc_user *ipc_user)
user_grant_dma_access_all(ipc_user->thread);
k_mem_domain_add_thread(zephyr_ll_mem_domain(), ipc_user->thread);
user_ll_grant_access(ipc_user->thread, PLATFORM_PRIMARY_CORE_ID);
pipeline_posn_grant_access(ipc_user->thread);

return 0;

Expand Down
10 changes: 9 additions & 1 deletion src/schedule/zephyr_ll.c
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,7 @@ static int zephyr_ll_task_free(void *data, struct task *task)
uint32_t flags;
struct zephyr_ll_pdata *pdata = task->priv_data;
bool must_wait, on_list = true;
int wait_ret = 0;

zephyr_ll_assert_core(sch);

Expand Down Expand Up @@ -617,10 +618,17 @@ static int zephyr_ll_task_free(void *data, struct task *task)

if (must_wait)
/* Wait for up to 100 periods */
k_sem_take(pdata->sem_p, K_USEC(LL_TIMER_PERIOD_US * 100));
wait_ret = k_sem_take(pdata->sem_p, K_USEC(LL_TIMER_PERIOD_US * 100));

/* Protect against racing with schedule_task() */
zephyr_ll_lock(sch, &flags);

if (wait_ret && task->state != SOF_TASK_STATE_FREE) {
tr_warn(&ll_tr, "task %p still active on free (state %d, semret %d)",
task, task->state, wait_ret);
zephyr_ll_task_done(sch, task);
}
Comment on lines +626 to +630

#if CONFIG_DYNAMIC_OBJECTS
zephyr_ll_task_sem_free(task);
#endif
Expand Down
3 changes: 0 additions & 3 deletions zephyr/wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,6 @@ int task_main_start(struct sof *sof)
/* init default audio components */
sys_comp_init(sof);

/* init pipeline position offsets */
pipeline_posn_init(sof);

return 0;
}

Expand Down
Loading