Skip to content

Phase 1 (part 3): cache helpers, component_ext.h and LL scheduler header cleanup - #11364

Draft
lgirdwood wants to merge 18 commits into
thesofproject:mainfrom
lgirdwood:kernel-user/phase1c
Draft

lgirdwood wants to merge 18 commits into
thesofproject:mainfrom
lgirdwood:kernel-user/phase1c

Conversation

@lgirdwood

Copy link
Copy Markdown
Member

Phase 1 of #11306 (kernel / user-space partition), third part: more user-space code stops including the platform memory map and the DAI, IDC and scheduling domain headers. Stacked on #11345: the first 6 commits are that PR and will drop out when it is merged.

Patches

  • Cache alias helpers in rtos/cache.h: uncache_to_cache(), cache_to_uncache() and is_uncached() are defined once instead of in every platform memory header:

    • ACE uses the Zephyr sys_cache_*_ptr_get() / sys_cache_is_ptr_cached() API, as before;
    • cAVS keeps its SRAM alias arithmetic;
    • the other Zephyr platforms have no uncached alias. They keep the identity mapping, and is_uncached() still returns 0.

    The host library keeps its own definitions.

  • sof/coherent.h: includes rtos/cache.h instead of the platform memory map.

  • comp_dai_config(): moved from component_ext.h to a new sof/audio/component_dai.h, so component_ext.h no longer includes sof/lib/dai.h and the DMA and DAI driver headers behind it.

  • CONFIG_PLATFORM_MAX_STREAMS (new): replaces the per-platform PLATFORM_MAX_STREAMS, following CONFIG_PLATFORM_MAX_CHANNELS from Phase 1 (part 2): stop user-space code depending on the platform memory map and headers #11345. The defaults equal today's values: 5 for the i.MX, MediaTek and AMD Zephyr builds, 8 for i.MX8M and qemu_xtensa, and 16 otherwise, including the host library and unit tests. Like the channel option, it has no prompt. The mixer, mux and module adapter then drop sof/platform.h.

  • LL scheduler: LL_TIMER_PERIOD_US and the user LL lock helpers (user_ll_lock_sched(), user_ll_unlock_sched(), user_ll_assert_locked()) move from ll_schedule_domain.h to ll_schedule.h. Audio code then stops including the scheduling domain header, which holds the domain driver interface and pulls in the clock headers.

  • component_ext.h: dropped from the 18 sources and headers that use nothing from it. It includes rtos/idc.h for its cross-core helpers, and only the pipeline, KPB, component.c, IPC and IDC code use those.

  • Copier: includes sof/lib/cold.h instead of sof/lib/memory.h; __cold is all it used.

  • Missing includes: three of them were hidden by the indirect includes removed here (tlv.h → rtos/string.h, intel_uaol.c → the logging header, the non-HiFi3 up/down mixer stubs → rtos/panic.h). Each gets its own patch, ahead of the patch that exposed it.

Files that still use something from the headers they no longer get indirectly now include those headers themselves.

Functional change

None. Every patch leaves the generated code unchanged.

Effect

Measured with scripts/check_kernel_includes.py on PTL, as the number of user-space sources including each header, before and after this PR (on top of #11345):

Header Before After
sof/lib/memory.h (platform memory map) 141 34
zephyr/drivers/dma.h, sof/lib/io.h 27 10
rtos/idc.h 26 11
Platform clock headers / rtos/clk.h 20 14
sof/platform.h 15 11
Any kernel-only header 143 45

What remains is mostly real kernel dependencies, which later parts need to replace with syscalls or move to the kernel:

  • the IPC4 mailbox registers (volume peak meter, pipeline registers, IPC gateway);
  • the IDC dispatchers in component_ext.h, used by the pipeline;
  • the DAI/DMA headers used by the copier and dai-zephyr.h;
  • the user LL lock and IRQ locking in the pipeline.

Testing

  • Per commit:
    • Firmware builds: tgl, tgl-h, mtl, lnl, ptl, wcl, nvl, imx8, imx8x, imx8m, imx8m_cm7, imx8ulp, imx95 and qemu_xtensa.
    • Extra CI configurations: native_sim IPC3/IPC4 stub builds, imx93 64-bit, PTL with each userspace overlay, PTL with CONFIG_SOF_USERSPACE_PROXY=n, and PTL and MTL with os_linux_overlay.conf;llext_relocatable.conf.
    • Object comparison: every object file and LLEXT module has the same non-debug section sizes as in the previous commit. The only differences are compiler-generated local names (CSWTCH, .str.N) that are numbered differently because fewer headers are included. In the ASan fuzz builds those names are stored as strings.
    • Host: the host library and cmocka build and pass.
  • Cache helpers: the patch that moves the cache alias helpers was also checked for identical section contents and relocations on tgl, ptl, imx8m, imx95 and qemu_xtensa. The only differences are platform.c, which embeds the git version, and the PTL LLEXT link addresses, which also differ between two builds of the same commit.
  • At the tip:
    • all cmocka configurations, the testbench and the tools pass;
    • the platforms that already fail on main (acp_6_0, acp_7_0, acp_7_x, mt8186, mt8188, mt8195, mt8196, mt8365) have unchanged error sets.

All of the above was run on db2b388 (main including #11346) with #11345 applied.

🤖 Generated with Claude Code

lrgirdwo and others added 18 commits October 26, 2026 14:05
__cold, __cold_rodata and the cold/hot path checks are used by most of
the audio code, but they were only available through sof/lib/memory.h,
which also pulls in the whole platform memory map. The DRAM section
variant was defined separately, and identically, in the four ACE
platform memory headers.

Move all of it to a new sof/lib/cold.h for the zephyr and posix RTOS
layers, based on CONFIG_COLD_STORE_EXECUTE_DRAM as before, and include it
from sof/lib/memory.h so existing users are unaffected. No functional
change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
PLATFORM_DCACHE_ALIGN was defined by every platform memory header, so
any code that needed to cache-align a buffer had to include the
platform memory map. Zephyr already describes the data cache line size
with CONFIG_DCACHE_LINE_SIZE, which rtos/cache.h exposes as
DCACHE_LINE_SIZE.

Define PLATFORM_DCACHE_ALIGN once in rtos/cache.h from DCACHE_LINE_SIZE
and drop the per-platform definitions of the Zephyr platforms. The host
library keeps its own definition.

This is the same value on all platforms except:
 - i.MX8, i.MX8X, i.MX8M and i.MX8ULP, which used 32 while their Zephyr
   configuration has a 128 byte cache line. The only user in these
   builds is the IPC3 buffer allocation, which is now 128 byte aligned.
 - qemu_xtensa, which used sizeof(void *) and now uses its 32 byte
   cache line; nothing in that build depends on it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
PLATFORM_MAX_CHANNELS is mostly used by audio processing code to size
per-channel state, but it was defined in every platform header, so that
code depended on sof/platform.h and through it on the platform drivers
and memory map.

Add CONFIG_PLATFORM_MAX_CHANNELS with defaults that match the existing
values (4 for the i.MX and MediaTek Zephyr builds, 8 otherwise, and 8
for the host library and unit tests, which used the library platform),
use it everywhere and drop the per-platform definitions. The option has
no prompt: some components still have state sized for at most eight
channels, so it is not meant to be changed. Log messages keep their
text. No functional change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
rtos/alloc.h and rtos/sof.h only need PLATFORM_DCACHE_ALIGN, but they
got it from sof/lib/memory.h together with the whole platform memory
map, which made almost all code depend on the platform headers. Include
rtos/cache.h, which now provides it, instead.

Include sof/lib/memory.h, sof/lib/cold.h or sof/lib/cpu.h directly in
the IDC, scheduler, logging, power management and i.MX MU code that
relied on them. No functional change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
sof/ipc/msg.h uses nothing from sof/platform.h or sof/lib/memory.h, but
including them made most audio code depend on the platform headers.
Drop them.

copier_dai.c relied on msg.h for ACE_VERSION, which selects how ALH
gateways are configured; without it the ACE 2.0+ path would silently
be compiled out. Include sof/platform.h there directly. No functional
change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Most audio components and headers only included sof/platform.h for
PLATFORM_MAX_CHANNELS, which is now CONFIG_PLATFORM_MAX_CHANNELS. Drop
the include from the files that use nothing else from it, so that they
no longer depend on the platform drivers, clocks and memory map. Files
that still use a platform definition (PLATFORM_MAX_STREAMS,
PLATFORM_PRIMARY_CORE_ID, ACE_VERSION, ...) keep it. No functional
change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
uncache_to_cache(), cache_to_uncache() and is_uncached() were defined by
each platform memory header, so code converting between the cached and
uncached alias of an address, such as sof/coherent.h, had to include the
platform memory map.

Define them once in rtos/cache.h: ACE uses the Zephyr cache API as
before, cAVS keeps its SRAM alias arithmetic, and the other Zephyr
platforms, which have no uncached alias, use the address unchanged with
is_uncached() returning 0, as they did. The host library keeps its own
definitions in the posix rtos/cache.h, and both sof/lib/memory.h variants
include rtos/cache.h so existing users are unaffected. No functional
change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
sof/coherent.h only needs PLATFORM_DCACHE_ALIGN, DCACHE_LINE_SIZE, the
cache maintenance calls and the cached/uncached alias helpers, all of
which rtos/cache.h now provides. Including sof/lib/memory.h instead made
every user of the buffer and component API depend on the platform
memory map.

Include rtos/cache.h instead. Components relied on this path for the
cold code attributes, so include sof/lib/cold.h from component.h, which
is where they are used. No functional change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
comp_dai_config() is the only part of component_ext.h that needs the
DAI driver definitions, and only the copier DAI, the static pipeline
loader and the IPC3 DAI code use it. Move it to a new
sof/audio/component_dai.h so that component_ext.h no longer includes
sof/lib/dai.h and, through it, the DMA and Zephyr DAI driver headers.

Files that used DAI or DMA definitions they got through
component_ext.h now include sof/lib/dai.h or sof/lib/dma.h directly.

No functional change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
PLATFORM_MAX_STREAMS is only used by audio processing code (mixer, mux,
module adapter) to size per-stream state, but it was defined in every
platform header, so that code depended on sof/platform.h.

Add CONFIG_PLATFORM_MAX_STREAMS with defaults that match the existing
values (5 for the i.MX, MediaTek and AMD Zephyr builds, 8 for i.MX8M
and qemu_xtensa, 16 otherwise, including the host library and unit
tests, which used the library platform), use it everywhere and drop
the per-platform definitions. Like CONFIG_PLATFORM_MAX_CHANNELS it has
no prompt. No functional change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
They only used PLATFORM_MAX_STREAMS from it, which is now a Kconfig
option. No functional change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Audio code uses LL_TIMER_PERIOD_US and, in user-space LL builds, the
user_ll_lock_sched(), user_ll_unlock_sched() and
user_ll_assert_locked() helpers, but these are declared in
ll_schedule_domain.h, which also holds the scheduling domain driver
interface and pulls in the clock and memory map headers.

Move them to ll_schedule.h, the LL scheduler API, and include it from
ll_schedule_domain.h so that existing users are unaffected. No
functional change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
The audio components and the pipeline only need the LL period and the
user LL lock helpers, which are now in ll_schedule.h, or nothing from
it at all. Include ll_schedule.h instead of ll_schedule_domain.h, or
drop the include. No functional change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
tlv.h uses memcpy_s() but relied on its users including rtos/string.h
first. No functional change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
intel_uaol.c uses LOG_MODULE_REGISTER() but got zephyr/logging/log.h
only indirectly. No functional change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
The stubs used without HiFi3 call sof_panic() but got rtos/panic.h only
indirectly. No functional change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
The aria, up/down mixer, volume, probe, UAOL, chain DMA and most of the
copier sources, the pipeline xrun code and the static pipeline module
list include sof/audio/component_ext.h but use nothing from it. It
pulls in rtos/idc.h for its cross-core helpers, and through that the
platform memory map and clock headers. Drop the includes; copier_gain.c
now includes sof/audio/component.h, which it used through it. No
functional change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
The copier sources only use __cold from sof/lib/memory.h. Include
sof/lib/cold.h instead. No functional change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants