Skip to content

soc/intel_adsp/ace: custom arch_spin_relax and some syscalls related changes. #88525

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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
4 changes: 4 additions & 0 deletions soc/intel/intel_adsp/ace/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ zephyr_include_directories(include)
zephyr_include_directories(include/${CONFIG_SOC})
zephyr_library_sources_ifdef(CONFIG_SOC_INTEL_COMM_WIDGET comm_widget.c)
zephyr_library_sources_ifdef(CONFIG_SOC_INTEL_COMM_WIDGET comm_widget_messages.c)
zephyr_library_sources_ifdef(
CONFIG_SOC_SERIES_INTEL_ADSP_ACE_CUSTOM_MORE_SPIN_RELAX_NOPS
spin_relax.c
)

if (CONFIG_XTENSA_MMU)
zephyr_library_sources_ifdef(CONFIG_SOC_INTEL_ACE30 mmu_ace30.c)
Expand Down
21 changes: 21 additions & 0 deletions soc/intel/intel_adsp/ace/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,24 @@ config SRAM_RETENTION_MODE
When this option is enabled, the SRAM retention mode will be
activated during the firmware boot-up process. If disabled,
the retention mode will not be activated.

config SOC_SERIES_INTEL_ADSP_ACE_CUSTOM_MORE_SPIN_RELAX_NOPS
bool "Use Intel Audio DSP specific arch_spin_relax() with more NOPs"
depends on !XTENSA_MORE_SPIN_RELAX_NOPS
default y if SMP && MP_MAX_NUM_CPUS > 1
help
Add some NOPs after failure to lock a spinlock. This gives
the bus extra time to synchronize the RCW transaction
among CPUs.

config SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS
int "Number of NOPs to be used in Intel Audio DSP specific arch_spin_relax()"
depends on SOC_SERIES_INTEL_ADSP_ACE_CUSTOM_MORE_SPIN_RELAX_NOPS
default 32 if MP_MAX_NUM_CPUS = 1
default 64 if MP_MAX_NUM_CPUS = 2
default 96 if MP_MAX_NUM_CPUS = 3
default 128 if MP_MAX_NUM_CPUS = 4
default 160 if MP_MAX_NUM_CPUS = 5
help
Specify the number of NOPs in Intel Audio DSP specific
arch_spin_relax().
14 changes: 0 additions & 14 deletions soc/intel/intel_adsp/ace/Kconfig.defconfig.series
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,6 @@ config LOG_BACKEND_ADSP

endif # LOG

config XTENSA_MORE_SPIN_RELAX_NOPS
default y if SMP && MP_MAX_NUM_CPUS > 1

if XTENSA_MORE_SPIN_RELAX_NOPS

config XTENSA_NUM_SPIN_RELAX_NOPS
default 32 if MP_MAX_NUM_CPUS = 1
default 64 if MP_MAX_NUM_CPUS = 2
default 96 if MP_MAX_NUM_CPUS = 3
default 128 if MP_MAX_NUM_CPUS = 4
default 160 if MP_MAX_NUM_CPUS = 5

endif # XTENSA_MORE_SPIN_RELAX_NOPS

if KERNEL_VM_SUPPORT

config KERNEL_VM_SIZE
Expand Down
20 changes: 20 additions & 0 deletions soc/intel/intel_adsp/ace/ace-link.ld
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ SECTIONS {

*libarch__xtensa__core.a:userspace.S.obj(.literal.xtensa_do_syscall)
*libarch__xtensa__core.a:userspace.S.obj(.text.xtensa_do_syscall)
*libarch__xtensa__core.a:ptables.c.obj(.literal.xtensa_swap_update_page_tables)
*libarch__xtensa__core.a:ptables.c.obj(.text.xtensa_swap_update_page_tables)

#ifdef CONFIG_XTENSA_SYSCALL_USE_HELPER
*libarch__xtensa__core.a:syscall_helper.c.obj(.text.xtensa_syscall_helper*)
Expand Down Expand Up @@ -503,6 +505,24 @@ SECTIONS {
.bss SEGSTART_UNCACHED (NOLOAD) :
{
_bss_start = .;

#if defined(CONFIG_ZTEST) && defined(CONFIG_SIMULATOR_XTENSA)
/* For some weird unknown reasons, the simulator really do not
* like these cpuhold_* variables to be tightly packed together.
* This results in cpuhold_spawned not being updated, and we
* will be stuck in the while loop for it to be set.
* Workaround by explicitly aligning these variables.
*/
. = ALIGN(16);
*:ztest.c.obj(.bss.cpuhold_sem)
. = ALIGN(16);
*:ztest.c.obj(.bss.cpuhold_active)
. = ALIGN(16);
*:ztest.c.obj(.bss.cpuhold_spawned)
. = ALIGN(16);
*:ztest.c.obj(.bss.cpuhold_pool_items)
#endif /* CONFIG_ZTEST && CONFIG_SIMULATOR_XTENSA */

*(.dynsbss)
*(.sbss)
*(.sbss.*)
Expand Down
33 changes: 33 additions & 0 deletions soc/intel/intel_adsp/ace/spin_relax.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2025 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <stdint.h>

#include <zephyr/toolchain.h>
#include <zephyr/sys/util_macro.h>

#ifdef CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS
void arch_spin_relax(void)
{
register uint32_t remaining = CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS;

while (remaining > 0) {
#if (CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS % 4) == 0
remaining -= 4;

/*
* Note the xcc/xt-clang likes to "truncate"
* continuous NOPs to max 4 NOPs. So this is
* the most we can do in one loop.
*/
__asm__("nop.n; nop.n; nop.n; nop.n;");
#else
remaining--;
__asm__("nop.n");
#endif
}
}
#endif /* CONFIG_SOC_SERIES_INTEL_ADSP_ACE_NUM_SPIN_RELAX_NOPS */