Skip to content
Merged
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
7 changes: 7 additions & 0 deletions src/include/sof/lib/dai-zephyr.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,13 @@ void dai_release_llp_slot(struct dai_data *dd);
* \brief Retrieve a pointer to the Zephyr device structure for a DAI of a given type and index.
*/
const struct device *dai_get_device(uint32_t type, uint32_t index);

/**
* \brief Retrieve the list of all DAI devices.
* \param count Pointer to store the number of devices in the list.
* \return Pointer to the array of device pointers.
*/
const struct device **dai_get_device_list(size_t *count);
/** @}*/

#endif /* __SOF_LIB_DAI_ZEPHYR_H__ */
8 changes: 8 additions & 0 deletions src/lib/dai.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,14 @@ const struct device *zephyr_dev[] = {
#endif
};

const struct device **dai_get_device_list(size_t *count)
{
__ASSERT_NO_MSG(count);
*count = ARRAY_SIZE(zephyr_dev);

return zephyr_dev;
}

/* convert sof_ipc_dai_type to Zephyr dai_type */
static int sof_dai_type_to_zephyr(uint32_t type)
{
Expand Down
2 changes: 2 additions & 0 deletions src/schedule/zephyr_domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,8 @@ static int zephyr_domain_register_user(struct ll_schedule_domain *domain,

k_mem_domain_add_thread(zephyr_ll_mem_domain(), thread);
k_thread_access_grant(thread, dt->sem, domain->lock, zephyr_domain->timer);
user_grant_dai_access_all(thread);
user_grant_dma_access_all(thread);
Comment on lines 338 to +340
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These calls are unconditional, but the implementations in userspace_helper.c are built only under CONFIG_USERSPACE && CONFIG_SOF_USERSPACE_LL (and currently the header declarations are not similarly guarded). This can lead to unresolved symbols in configurations where this file is compiled but CONFIG_SOF_USERSPACE_LL (or even CONFIG_USERSPACE) is off. Guard these calls with the same Kconfig option(s), and/or provide static inline no-op stubs in the header for non-enabled configurations.

Suggested change
k_thread_access_grant(thread, dt->sem, domain->lock, zephyr_domain->timer);
user_grant_dai_access_all(thread);
user_grant_dma_access_all(thread);
k_thread_access_grant(thread, dt->sem, domain->lock, zephyr_domain->timer);
#if CONFIG_USERSPACE && CONFIG_SOF_USERSPACE_LL
user_grant_dai_access_all(thread);
user_grant_dma_access_all(thread);
#endif

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a valid concern, but this code is already guarded by CONFIG_SOF_USERSPACE_LL and that depends on CONFIG_USERSPACE, so this is sufficient.

tr_dbg(&ll_tr, "granted LL access to thread %p (core %d)", thread, core);

k_thread_start(thread);
Expand Down
14 changes: 14 additions & 0 deletions zephyr/include/rtos/userspace_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,20 @@ static inline uint32_t user_get_partition_attr(uintptr_t ptr)
return sys_cache_is_ptr_cached(UINT_TO_POINTER(ptr)) ? XTENSA_MMU_CACHED_WB : 0;
}

/**
* Grant DAI device access to a user-space thread.
*
* @param thread user-space thread for which DAI access is granted
*/
void user_grant_dai_access_all(struct k_thread *thread);
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These APIs are declared for all CONFIG_USERSPACE builds, but the implementations are under CONFIG_SOF_USERSPACE_LL in the .c file. To keep the public API consistent and avoid configuration-dependent link issues, either (1) wrap these declarations with #ifdef CONFIG_SOF_USERSPACE_LL to match the implementation, or (2) provide static inline no-op stubs when CONFIG_SOF_USERSPACE_LL is disabled.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is on purpose. One will get linker errors if trying to use these in the wrong config and this should be sufficient.


/**
* Grant DMA device access to a user-space thread.
*
* @param thread user-space thread for which DMA access is granted
*/
void user_grant_dma_access_all(struct k_thread *thread);
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These APIs are declared for all CONFIG_USERSPACE builds, but the implementations are under CONFIG_SOF_USERSPACE_LL in the .c file. To keep the public API consistent and avoid configuration-dependent link issues, either (1) wrap these declarations with #ifdef CONFIG_SOF_USERSPACE_LL to match the implementation, or (2) provide static inline no-op stubs when CONFIG_SOF_USERSPACE_LL is disabled.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is on purpose. One will get linker errors if trying to use these in the wrong config and this should be sufficient.


#else

static inline int user_access_to_mailbox(struct k_mem_domain *domain, k_tid_t thread_id)
Expand Down
35 changes: 35 additions & 0 deletions zephyr/lib/userspace_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,22 @@
#include <stdint.h>

#include <rtos/alloc.h>
#include <rtos/sof.h>
#include <rtos/userspace_helper.h>
#include <sof/audio/module_adapter/module/generic.h>
#include <sof/audio/module_adapter/library/userspace_proxy.h>
#include <sof/lib/mailbox.h>
#include <sof/lib/dai.h>
#include <sof/lib/dma.h>

#define MODULE_DRIVER_HEAP_CACHED CONFIG_SOF_ZEPHYR_HEAP_CACHED

/* Zephyr includes */
#include <zephyr/kernel.h>
#include <zephyr/app_memory/app_memdomain.h>
#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(userspace_helper, CONFIG_SOF_LOG_LEVEL);

#if CONFIG_USERSPACE

Expand Down Expand Up @@ -88,6 +94,8 @@ int user_memory_attach_common_partition(struct k_mem_domain *dom)
return k_mem_domain_add_partition(dom, &common_partition);
}

#ifdef CONFIG_SOF_USERSPACE_LL

int user_access_to_mailbox(struct k_mem_domain *domain, k_tid_t thread_id)
Comment on lines +97 to 99
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

user_access_to_mailbox() is now compiled only when CONFIG_SOF_USERSPACE_LL is enabled, but it appears to be a general userspace helper (and is still declared under #if CONFIG_USERSPACE in the header). This creates a concrete risk of link failures or missing functionality in CONFIG_USERSPACE=y builds that don’t enable CONFIG_SOF_USERSPACE_LL. Consider moving the #ifdef CONFIG_SOF_USERSPACE_LL guard so it only wraps the new DAI/DMA grant helpers (not user_access_to_mailbox()), or alternatively provide stubs / adjust header declarations so the build remains consistent across configurations.

Copilot uses AI. Check for mistakes.
{
struct k_mem_partition mem_partition;
Expand Down Expand Up @@ -128,6 +136,33 @@ int user_access_to_mailbox(struct k_mem_domain *domain, k_tid_t thread_id)
return 0;
}

void user_grant_dai_access_all(struct k_thread *thread)
{
const struct device **devices;
size_t count;
size_t i;

devices = dai_get_device_list(&count);

for (i = 0; i < count; i++)
k_thread_access_grant(thread, devices[i]);

LOG_DBG("Granted DAI access to thread %p for %zu devices", thread, count);
}

void user_grant_dma_access_all(struct k_thread *thread)
{
const struct dma_info *info = dma_info_get();
struct sof_dma *d;

for (d = info->dma_array; d < info->dma_array + info->num_dmas; d++) {
k_thread_access_grant(thread, d->z_dev);
LOG_DBG("Granted DMA device access: %s to thread %p", d->z_dev->name, thread);
}
}

#endif /* CONFIG_SOF_USERSPACE_LL */

#else /* CONFIG_USERSPACE */

void *user_stack_allocate(size_t stack_size, uint32_t options)
Expand Down