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
2 changes: 2 additions & 0 deletions zephyr/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -620,6 +620,8 @@ zephyr_library_sources_ifdef(CONFIG_SHELL
sof_shell.c
)

zephyr_syscall_header(include/sof/lib/cpu.h)
zephyr_library_sources_ifdef(CONFIG_USERSPACE syscall/cpu.c)
zephyr_syscall_header(${SOF_SRC_PATH}/include/sof/audio/module_adapter/module/generic.h)
zephyr_syscall_header(${SOF_SRC_PATH}/include/sof/lib/fast-get.h)
zephyr_syscall_header(${SOF_SRC_PATH}/include/sof/ipc/ipc_reply.h)
Expand Down
27 changes: 27 additions & 0 deletions zephyr/include/sof/lib/cpu.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -40,13 +40,32 @@ void cpu_notify_state_exit(enum pm_state state);

#endif /* CONFIG_PM */

/*
* cpu_get_id() is exposed as a Zephyr system call so that user-mode
* threads (e.g. user-space LL pipelines) can query the current core
* id. The underlying arch_proc_id() reads a privileged special
* register (e.g. Xtensa PRID) which would fault if executed directly
* from user mode. In supervisor context the generated wrapper inlines
* the z_impl_cpu_get_id() body, so there is no overhead there.
*/
#if defined(CONFIG_SOF_FULL_ZEPHYR_APPLICATION)
__syscall int cpu_get_id(void);
#endif

/* let the compiler optimise when in single core mode */
#if CONFIG_MULTICORE && CONFIG_SMP

#if defined(CONFIG_SOF_FULL_ZEPHYR_APPLICATION)
static inline int z_impl_cpu_get_id(void)
{
return arch_proc_id();
}
#else
static inline int cpu_get_id(void)
{
return arch_proc_id();
}
#endif

static inline bool cpu_is_primary(int id)
{
Expand All@@ -73,7 +92,11 @@ int cpu_restore_secondary_cores(void);
int cpu_secondary_cores_prepare_d0ix(void);
#else

#if defined(CONFIG_SOF_FULL_ZEPHYR_APPLICATION)
static inline int z_impl_cpu_get_id(void) { return 0; };
#else
static inline int cpu_get_id(void) { return 0; };
#endif

static inline bool cpu_is_primary(int id) { return 1; };

Expand All@@ -93,6 +116,10 @@ static inline int cpu_secondary_cores_prepare_d0ix(void) { return 0; };

#endif /* CONFIG_MULTICORE && CONFIG_SMP */

#if defined(CONFIG_SOF_FULL_ZEPHYR_APPLICATION)
#include <zephyr/syscalls/cpu.h>
#endif

#endif

#endif /* __SOF_LIB_CPU_H__ */
22 changes: 22 additions & 0 deletions zephyr/syscall/cpu.c
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: BSD-3-Clause
//
// Copyright(c) 2026 Intel Corporation.

#include <sof/lib/cpu.h>
#include <zephyr/kernel.h>
#include <zephyr/internal/syscall_handler.h>

/**
* \brief Userspace verification wrapper for cpu_get_id().
*
* The system call takes no arguments and passes no pointers, so no
* access validation is required; the call is simply forwarded to the
* implementation running in supervisor context.
*
* @return Id of the DSP core executing the call.
*/
static inline int z_vrfy_cpu_get_id(void)
{
return z_impl_cpu_get_id();
}
#include <zephyr/syscalls/cpu_get_id_mrsh.c>
Loading